From df32f35ba9dcf99d53cd31e22bfa1ed13dff5ad3 Mon Sep 17 00:00:00 2001 From: saltbo Date: Mon, 13 Apr 2026 21:01:37 -0400 Subject: [PATCH] refactor(test): separate unit and integration tests Rename 19 integration test files from *.test.ts to *.integration.test.ts. Configure vitest projects to run them independently with separate coverage thresholds. CI now reports unit and integration coverage as separate flags to Codecov. Unit tests: pure function calls, mocked dependencies, no DB Integration tests: createTestApp() with in-memory DB + HTTP requests Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/ci.yml | 10 ++- ...{auth.test.ts => auth.integration.test.ts} | 0 ...{auth.test.ts => auth.integration.test.ts} | 0 ....ts => auth-providers.integration.test.ts} | 0 ...t.ts => auth-username.integration.test.ts} | 0 ...{auth.test.ts => auth.integration.test.ts} | 0 ...st.ts => email-config.integration.test.ts} | 0 ...lth.test.ts => health.integration.test.ts} | 0 ...st.ts => invite-codes.integration.test.ts} | 0 ...t.ts => objects-quota.integration.test.ts} | 0 ...ts.test.ts => objects.integration.test.ts} | 0 ...tas.test.ts => quotas.integration.test.ts} | 0 ...s.test.ts => storages.integration.test.ts} | 0 ...tem.test.ts => system.integration.test.ts} | 0 ...sers.test.ts => users.integration.test.ts} | 0 ...mail.test.ts => email.integration.test.ts} | 0 ...ite.test.ts => invite.integration.test.ts} | 0 ...ter.test.ts => matter.integration.test.ts} | 0 .../{org.test.ts => org.integration.test.ts} | 0 ...ge.test.ts => storage.integration.test.ts} | 0 vitest.config.ts | 87 ++++++++++++------- 21 files changed, 67 insertions(+), 30 deletions(-) rename server/{auth.test.ts => auth.integration.test.ts} (100%) rename server/middleware/{auth.test.ts => auth.integration.test.ts} (100%) rename server/routes/{auth-providers.test.ts => auth-providers.integration.test.ts} (100%) rename server/routes/{auth-username.test.ts => auth-username.integration.test.ts} (100%) rename server/routes/{auth.test.ts => auth.integration.test.ts} (100%) rename server/routes/{email-config.test.ts => email-config.integration.test.ts} (100%) rename server/routes/{health.test.ts => health.integration.test.ts} (100%) rename server/routes/{invite-codes.test.ts => invite-codes.integration.test.ts} (100%) rename server/routes/{objects-quota.test.ts => objects-quota.integration.test.ts} (100%) rename server/routes/{objects.test.ts => objects.integration.test.ts} (100%) rename server/routes/{quotas.test.ts => quotas.integration.test.ts} (100%) rename server/routes/{storages.test.ts => storages.integration.test.ts} (100%) rename server/routes/{system.test.ts => system.integration.test.ts} (100%) rename server/routes/{users.test.ts => users.integration.test.ts} (100%) rename server/services/{email.test.ts => email.integration.test.ts} (100%) rename server/services/{invite.test.ts => invite.integration.test.ts} (100%) rename server/services/{matter.test.ts => matter.integration.test.ts} (100%) rename server/services/{org.test.ts => org.integration.test.ts} (100%) rename server/services/{storage.test.ts => storage.integration.test.ts} (100%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a9a2febb..472a6faa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,11 +24,19 @@ jobs: run: npm ci - run: npm run lint - run: npm run typecheck - - run: npm test -- --coverage + - run: npx vitest run --project unit --coverage - uses: codecov/codecov-action@v5 if: always() with: files: coverage/coverage-final.json + flags: unit + fail_ci_if_error: false + - run: npx vitest run --project integration --coverage + - uses: codecov/codecov-action@v5 + if: always() + with: + files: coverage/coverage-final.json + flags: integration fail_ci_if_error: false - run: mkdir -p dist - run: npm run test:cf diff --git a/server/auth.test.ts b/server/auth.integration.test.ts similarity index 100% rename from server/auth.test.ts rename to server/auth.integration.test.ts diff --git a/server/middleware/auth.test.ts b/server/middleware/auth.integration.test.ts similarity index 100% rename from server/middleware/auth.test.ts rename to server/middleware/auth.integration.test.ts diff --git a/server/routes/auth-providers.test.ts b/server/routes/auth-providers.integration.test.ts similarity index 100% rename from server/routes/auth-providers.test.ts rename to server/routes/auth-providers.integration.test.ts diff --git a/server/routes/auth-username.test.ts b/server/routes/auth-username.integration.test.ts similarity index 100% rename from server/routes/auth-username.test.ts rename to server/routes/auth-username.integration.test.ts diff --git a/server/routes/auth.test.ts b/server/routes/auth.integration.test.ts similarity index 100% rename from server/routes/auth.test.ts rename to server/routes/auth.integration.test.ts diff --git a/server/routes/email-config.test.ts b/server/routes/email-config.integration.test.ts similarity index 100% rename from server/routes/email-config.test.ts rename to server/routes/email-config.integration.test.ts diff --git a/server/routes/health.test.ts b/server/routes/health.integration.test.ts similarity index 100% rename from server/routes/health.test.ts rename to server/routes/health.integration.test.ts diff --git a/server/routes/invite-codes.test.ts b/server/routes/invite-codes.integration.test.ts similarity index 100% rename from server/routes/invite-codes.test.ts rename to server/routes/invite-codes.integration.test.ts diff --git a/server/routes/objects-quota.test.ts b/server/routes/objects-quota.integration.test.ts similarity index 100% rename from server/routes/objects-quota.test.ts rename to server/routes/objects-quota.integration.test.ts diff --git a/server/routes/objects.test.ts b/server/routes/objects.integration.test.ts similarity index 100% rename from server/routes/objects.test.ts rename to server/routes/objects.integration.test.ts diff --git a/server/routes/quotas.test.ts b/server/routes/quotas.integration.test.ts similarity index 100% rename from server/routes/quotas.test.ts rename to server/routes/quotas.integration.test.ts diff --git a/server/routes/storages.test.ts b/server/routes/storages.integration.test.ts similarity index 100% rename from server/routes/storages.test.ts rename to server/routes/storages.integration.test.ts diff --git a/server/routes/system.test.ts b/server/routes/system.integration.test.ts similarity index 100% rename from server/routes/system.test.ts rename to server/routes/system.integration.test.ts diff --git a/server/routes/users.test.ts b/server/routes/users.integration.test.ts similarity index 100% rename from server/routes/users.test.ts rename to server/routes/users.integration.test.ts diff --git a/server/services/email.test.ts b/server/services/email.integration.test.ts similarity index 100% rename from server/services/email.test.ts rename to server/services/email.integration.test.ts diff --git a/server/services/invite.test.ts b/server/services/invite.integration.test.ts similarity index 100% rename from server/services/invite.test.ts rename to server/services/invite.integration.test.ts diff --git a/server/services/matter.test.ts b/server/services/matter.integration.test.ts similarity index 100% rename from server/services/matter.test.ts rename to server/services/matter.integration.test.ts diff --git a/server/services/org.test.ts b/server/services/org.integration.test.ts similarity index 100% rename from server/services/org.test.ts rename to server/services/org.integration.test.ts diff --git a/server/services/storage.test.ts b/server/services/storage.integration.test.ts similarity index 100% rename from server/services/storage.test.ts rename to server/services/storage.integration.test.ts diff --git a/vitest.config.ts b/vitest.config.ts index a99dc5d7..c9b60537 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -1,38 +1,67 @@ import path from 'node:path' import { defineConfig } from 'vitest/config' +const aliases = { + '@': path.resolve(__dirname, './src'), + '@shared': path.resolve(__dirname, './shared'), + '@server': path.resolve(__dirname, './server'), +} + +const coverageConfig = { + provider: 'v8' as const, + include: ['server/**/*.ts', 'shared/**/*.ts', 'src/lib/**/*.ts', 'src/i18n/**/*.ts'], + exclude: [ + 'server/entry-*.ts', + 'server/**/*.test.ts', + 'server/**/*.integration.test.ts', + 'server/**/*.cf-test.ts', + 'server/test/**', + 'server/platform/**', + 'server/db/**', + 'shared/**/*.test.ts', + 'src/**/*.test.ts', + 'src/i18n/index.ts', + ], + reporter: ['text', 'json'] as const, +} + export default defineConfig({ test: { globals: true, - include: ['server/**/*.test.ts', 'shared/**/*.test.ts', 'src/**/*.test.ts'], - coverage: { - provider: 'v8', - include: ['server/**/*.ts', 'shared/**/*.ts', 'src/lib/**/*.ts', 'src/i18n/**/*.ts'], - exclude: [ - 'server/entry-*.ts', - 'server/**/*.test.ts', - 'server/**/*.cf-test.ts', - 'server/test/**', - 'server/platform/**', - 'server/db/**', - 'shared/**/*.test.ts', - 'src/**/*.test.ts', - 'src/i18n/index.ts', - ], - reporter: ['text', 'json'], - thresholds: { - statements: 90, - branches: 80, - functions: 90, - lines: 90, + projects: [ + { + resolve: { alias: aliases }, + test: { + name: 'unit', + include: ['server/**/*.test.ts', 'shared/**/*.test.ts', 'src/**/*.test.ts'], + exclude: ['**/*.integration.test.ts', '**/*.cf-test.ts'], + coverage: { + ...coverageConfig, + thresholds: { + statements: 50, + branches: 40, + functions: 50, + lines: 50, + }, + }, + }, }, - }, - }, - resolve: { - alias: { - '@': path.resolve(__dirname, './src'), - '@shared': path.resolve(__dirname, './shared'), - '@server': path.resolve(__dirname, './server'), - }, + { + resolve: { alias: aliases }, + test: { + name: 'integration', + include: ['server/**/*.integration.test.ts'], + coverage: { + ...coverageConfig, + thresholds: { + statements: 90, + branches: 80, + functions: 90, + lines: 90, + }, + }, + }, + }, + ], }, })