unic / unic/ai-developer-hub

Add server-action tests for assignLicense, bulk import users + licenses

Open
#47 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

priority:medium tests
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) in src/actions/assignments.ts
  • bulkImportUsers in src/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/ and tests/integration/ contain no assignments.test.ts, users.test.ts, or bulk-import tests.
  • src/actions/assignments.ts:assignLicense — validates input with assignmentSchema, 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.ts
  • tests/integration/actions/users-bulk-import.test.ts
  • tests/integration/actions/license-bulk-assign.test.ts

For each, cover at minimum:

assignments.test.ts
  • Happy path: assignLicense creates a row, increments usage, writes change_history entry.
  • 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 apiKey provided, 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 typecheck pass.

Verification

  1. Run pnpm test:integration tests/integration/actions/ against a clean Neon test branch.
  2. Mutate assignLicense to skip the max-licenses check → confirm the capacity test fails. Revert.
  3. Mutate bulkImportUsers to skip dedupe → confirm the dedupe test fails. Revert.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.