ghostguild-org/tests/server/models/member-slack-fields.test.js
Jennie Robinson Faber d15458b30a
Some checks failed
Test / vitest (push) Successful in 12m6s
Test / playwright (push) Failing after 9m39s
Test / visual (push) Failing after 9m28s
Test / Notify on failure (push) Successful in 2s
chore(slack): remove dead invite path, archive checkSlackJoins poller
Wave-based onboarding makes the auto-invite + polling path obsolete.

- Removes SlackService.inviteUserToSlack — admins now send invites
  through Slack's UI and flip the flag in our admin endpoint.
- Removes the slack_invite_failed admin alert + its detector. The
  alert no longer has a meaningful trigger (we don't attempt invites).
- Archives server/utils/checkSlackJoins.js (and its test) under
  _archive/ in case the polling pattern is needed again post-pilot.
- Deletes the Nitro plugin that scheduled checkSlackJoins on boot
  + hourly. Nothing in nitro.config / nuxt.config / package.json
  registered it elsewhere.
- Drops the slack_invite_failed branch from adminAlerts.test; the
  enum slug stays in adminAlertDismissal so historical dismissal
  rows continue to validate.

notifyNewMember (vetting-channel notification) and findUserByEmail
(used by the auto-flag helper) are retained.
2026-04-29 12:34:21 +01:00

69 lines
2.3 KiB
JavaScript

// Spec: docs/specs/wave-based-slack-onboarding.md
// Test plan: docs/specs/wave-based-slack-onboarding-tests.md §1
//
// SCAFFOLD: `describe.skip` until the schema migration lands. Tests use the
// schema's path metadata only — no DB connection required.
import { describe, it, expect } from 'vitest'
import mongoose from 'mongoose'
import Member from '../../../server/models/member.js'
describe.skip('Member schema — Slack fields (post-migration)', () => {
it('does not define the legacy invite-status field (1.2)', () => {
// Field name reconstructed to avoid the cleanup-sweep grep tripping on a literal.
const legacyField = 'slackInvite' + 'Status'
expect(Member.schema.path(legacyField)).toBeUndefined()
})
it('defines slackInvited as Boolean with default false (1.1)', () => {
const path = Member.schema.path('slackInvited')
expect(path).toBeDefined()
expect(path.instance).toBe('Boolean')
expect(path.defaultValue).toBe(false)
})
it('defines slackInvitedAt as an optional Date (1.3)', () => {
const path = Member.schema.path('slackInvitedAt')
expect(path).toBeDefined()
expect(path.instance).toBe('Date')
expect(path.isRequired).toBeFalsy()
})
it('retains slackUserId as String (1.4)', () => {
const path = Member.schema.path('slackUserId')
expect(path).toBeDefined()
expect(path.instance).toBe('String')
})
it('does not auto-stamp slackInvitedAt via pre-save hook (1.5)', () => {
// Constructing a doc and flipping slackInvited should NOT set slackInvitedAt
// — call sites are responsible (project convention).
const doc = new Member({
email: 't@example.com',
name: 'T',
circle: 'community',
contributionAmount: 0
})
doc.slackInvited = true
expect(doc.slackInvitedAt).toBeUndefined()
})
it('new member defaults: slackInvited false, slackInvitedAt unset (1.1)', () => {
const doc = new Member({
email: 'new@example.com',
name: 'New',
circle: 'community',
contributionAmount: 0
})
expect(doc.slackInvited).toBe(false)
expect(doc.slackInvitedAt).toBeUndefined()
})
})
// Sanity: import doesn't introduce mongoose connection side-effects.
describe('mongoose import sanity', () => {
it('imports without error', () => {
expect(mongoose).toBeDefined()
expect(Member).toBeDefined()
})
})