// Spec: docs/specs/wave-based-slack-onboarding.md // Test plan: docs/specs/wave-based-slack-onboarding-tests.md §8 // // Static-source / filesystem assertions for the dead-code removal & // archival checklist. These don't require booting any handler — they // grep the working tree. // // SCAFFOLD: the whole suite is `.skip`ed until removal is done. As each // chunk lands, unskip the matching `it`. import { describe, it, expect } from 'vitest' import { readFileSync, existsSync, readdirSync } from 'node:fs' import { resolve } from 'node:path' const repoRoot = resolve(import.meta.dirname, '../../..') function read(rel) { const path = resolve(repoRoot, rel) return existsSync(path) ? readFileSync(path, 'utf-8') : null } function walk(dir, out = []) { for (const entry of readdirSync(resolve(repoRoot, dir), { withFileTypes: true })) { const rel = `${dir}/${entry.name}` if (entry.isDirectory()) { if (entry.name === 'node_modules' || entry.name.startsWith('.')) continue if (entry.name === '_archive') continue walk(rel, out) } else if (/\.(js|ts|vue|mjs)$/.test(entry.name)) { out.push(rel) } } return out } describe('Slack onboarding — dead code removal (§8)', () => { it('no admin.users.invite calls anywhere (8.1)', () => { const files = walk('server').concat(walk('app')) const hits = files.filter((f) => { const src = read(f) return src && /admin\.users\.invite/.test(src) }) expect(hits).toEqual([]) }) it('inviteUserToSlack removed from slack.ts (8.2)', () => { const src = read('server/utils/slack.ts') expect(src).not.toMatch(/\binviteUserToSlack\b/) }) it('findUserByEmail is callable (public or via wrapper) (8.3)', () => { const src = read('server/utils/slack.ts') ?? '' // Either the keyword `private` is removed from its declaration, // OR a public wrapper exists. const declLine = src.split('\n').find((l) => /findUserByEmail/.test(l)) ?? '' const isPrivate = /\bprivate\b/.test(declLine) const hasPublicWrapper = /export\s+(async\s+)?function\s+findUserByEmail/.test(src) || /findUserByEmail\s*[:=]\s*async/.test(src) expect(isPrivate && !hasPublicWrapper).toBe(false) }) it('notifyNewMember retained (8.4)', () => { const src = read('server/utils/slack.ts') ?? '' expect(src).toMatch(/\bnotifyNewMember\b/) }) it('checkSlackJoins archived, not at original path (8.5)', () => { expect(existsSync(resolve(repoRoot, 'server/utils/checkSlackJoins.js'))).toBe(false) // Any unloaded path is acceptable; check a couple of plausible ones. const archived = existsSync(resolve(repoRoot, 'server/utils/_archive/checkSlackJoins.js')) || existsSync(resolve(repoRoot, 'server/_archive/utils/checkSlackJoins.js')) expect(archived).toBe(true) }) it('no active cron/Nitro registration triggers checkSlackJoins (8.6)', () => { const candidates = [ 'nitro.config.ts', 'nitro.config.js', 'nuxt.config.ts', 'nuxt.config.js' ].map(read).filter(Boolean) const tasksDir = resolve(repoRoot, 'server/tasks') const taskFiles = existsSync(tasksDir) ? walk('server/tasks') : [] const allSrc = candidates.concat(taskFiles.map(read).filter(Boolean)).join('\n') expect(allSrc).not.toMatch(/checkSlackJoins/) }) it('adminAlerts no longer queries the legacy invite-status field (8.7)', () => { const src = read('server/utils/adminAlerts.js') ?? '' expect(src).not.toMatch(new RegExp('slackInvite' + 'Status')) }) it('adminAlerts.test.js drops the removed branch (8.8)', () => { const src = read('tests/server/utils/adminAlerts.test.js') ?? '' expect(src).not.toMatch(new RegExp('slackInvite' + 'Status')) expect(src).not.toMatch(/detectSlackInviteFailed/) }) it('check-slack-joins.test.js archived alongside source (8.9)', () => { expect(existsSync(resolve(repoRoot, 'tests/server/tasks/check-slack-joins.test.js'))).toBe(false) }) it('zero references to the legacy invite-status field repo-wide (8.10)', () => { const files = walk('server').concat(walk('app')).concat(walk('tests')) const hits = files.filter((f) => { const src = read(f) return src && new RegExp('slackInvite' + 'Status').test(src) }) expect(hits).toEqual([]) }) it.todo('migration / cleanup story for dev/staging documented (8.11)') it.todo('notifyNewMember invitationStatus arg uses canonical value at all call sites (8.12)') })