Best-effort lookup of an activating member's email in the Slack workspace. On a hit, flips slackInvited:true and stamps slackInvitedAt without sending a fresh invite. Races against a 3s timeout and swallows all errors so activation never blocks on Slack. - Promotes SlackService.findUserByEmail from private to public so the helper can call it without a wrapper. - New activity-log action: slack_access_auto_detected (actor = subject). - Idempotent: short-circuits when slackInvited is already true. Callers wired in next commit.
67 lines
2.2 KiB
JavaScript
67 lines
2.2 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 slackInviteStatus (1.2)', () => {
|
|
expect(Member.schema.path('slackInviteStatus')).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()
|
|
})
|
|
})
|