Add server-action tests for assignLicense, bulk import users + licenses
Nobody has claimed this yet.
- Dominant language
- HTML
- Stars
- 0
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
Problem
Three of the highest-traffic, most data-changing server actions have no direct test coverage:
assignLicense(and the related update/revoke paths) insrc/actions/assignments.tsbulkImportUsersinsrc/actions/users.ts- The bulk-license-assignment flow used by feature 004
These actions touch payments-adjacent data (license counts vs ai_tools.maxLicenses, encrypted API keys, audit history) and are exposed through admin UI flows that are easy to regress. Adding fast Vitest coverage prevents future PRs from silently breaking constraints.
Evidence
tests/unit/andtests/integration/contain noassignments.test.ts,users.test.ts, or bulk-import tests.src/actions/assignments.ts:assignLicense— validates input withassignmentSchema, checks max-licenses, encrypts API key, writes assignment + history rows.src/actions/users.ts:bulkImportUsers— accepts a CSV/JSON payload (see project spec 011), validates with Zod, dedupes against existing users, writes users + invite tokens.
Proposed approach
Use the existing integration-test harness (Vitest + real Neon test branch). Place new files at:
tests/integration/actions/assignments.test.tstests/integration/actions/users-bulk-import.test.tstests/integration/actions/license-bulk-assign.test.ts
For each, cover at minimum:
assignments.test.ts
- Happy path:
assignLicensecreates a row, increments usage, writeschange_historyentry. - Validation: bad email / bad tier id →
{ success: false, fieldErrors }. - Capacity: tool with
maxLicenses = 0→ rejected without creating a row. - Auth: non-admin caller → rejected by
requireAdmin. - Encryption: with
apiKeyprovided, the stored ciphertext decrypts back to the input.
users-bulk-import.test.ts
- 10-row valid CSV → 10 users created, 10 invite tokens issued, no duplicates.
- Mixed-case email duplicates within payload → deduped per the spec's rule.
- One invalid row + nine valid → either entire-batch reject or partial success per the action's contract (mirror current behaviour).
- Existing user collision → action returns the configured per-row error.
license-bulk-assign.test.ts
- N rows assigning to N users on a tool with capacity → all succeed.
- N+1 rows on a tool with capacity N → the (N+1)th is rejected, others succeed (or whole batch fails — match current behaviour).
- Per-row API-key encryption.
For all three: stub Resend (@/lib/email) and any other external side-effects. Reuse the test-DB setup pattern from tests/integration/sync/.
Acceptance criteria
- Three new test files exist under
tests/integration/actions/. - Each file has at least 4 tests covering happy + validation + auth + edge cases.
- All tests pass under
pnpm test:integration. - No real emails are sent (Resend mocked).
-
pnpm lint && pnpm typecheckpass.
Verification
- Run
pnpm test:integration tests/integration/actions/against a clean Neon test branch. - Mutate
assignLicenseto skip the max-licenses check → confirm the capacity test fails. Revert. - Mutate
bulkImportUsersto skip dedupe → confirm the dedupe test fails. Revert.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with src/actions/assignments.ts and src/actions/users.ts, then read the bulk-license flow for feature 004 and the setup pattern in tests/integration/sync/. Run pnpm test:integration tests/integration/actions/ against a clean Neon test branch, stubbing @/lib/email and other external side effects. Done means the three named test files cover happy, validation, auth, capacity, deduplication, encryption, and batch-edge behavior, with integration tests, lint, and typecheck passing.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- backend, databases, testing-qa
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100