import { test } from 'node:test' import assert from 'node:assert/strict' import { state } from '../server/state.js' import { hasStudyAccess, isStudyUserCompleted, getAccessibleStudySlugs, markStudyCompletedIfDone, scheduleReengagementEmails, } from '../server/study-helpers.js' function setup() { state.cachedSiteContent = { studies: [{ slug: 'mini', sections: [{ id: 'a' }, { id: 'b' }] }, { slug: 'other', sections: [{ id: 'x' }] }], } } test('completing every lesson marks the study completed and keeps access after leaving', () => { setup() const user = { id: 'u1', enrolledStudySlugs: ['mini'] } assert.equal(markStudyCompletedIfDone(user, 'mini', ['a']), false) assert.equal(markStudyCompletedIfDone(user, 'mini', ['a', 'b']), true) assert.ok(isStudyUserCompleted(user, 'mini')) user.enrolledStudySlugs = [] // student leaves assert.ok(hasStudyAccess(user, 'mini')) assert.ok(!hasStudyAccess(user, 'other')) assert.deepEqual(getAccessibleStudySlugs(user), ['mini']) }) test('completion is sticky when a lesson is added later, and not marked twice', () => { setup() const user = { id: 'u2', enrolledStudySlugs: ['mini'] } markStudyCompletedIfDone(user, 'mini', ['a', 'b']) state.cachedSiteContent.studies[0].sections.push({ id: 'c' }) assert.equal(markStudyCompletedIfDone(user, 'mini', ['a', 'b']), false) assert.ok(isStudyUserCompleted(user, 'mini')) assert.deepEqual(user.completedStudySlugs, ['mini']) }) test('unknown or empty studies are never marked completed', () => { setup() const user = { id: 'u3', enrolledStudySlugs: [] } assert.equal(markStudyCompletedIfDone(user, 'nope', ['a']), false) state.cachedSiteContent.studies.push({ slug: 'empty', sections: [] }) assert.equal(markStudyCompletedIfDone(user, 'empty', []), false) }) test('re-engagement emails skip students whose only study is finished', async () => { setup() const sent = [] state.studyUsers = [{ id: 'u4', username: 'a@b.co', studyRemindersEnabled: true, lastLoginAt: new Date(Date.now() - 40 * 864e5).toISOString(), enrolledStudySlugs: ['mini'], completedStudySlugs: ['mini'], reengagementSentAt: {}, }, { id: 'u5', username: 'c@d.co', studyRemindersEnabled: true, lastLoginAt: new Date(Date.now() - 40 * 864e5).toISOString(), enrolledStudySlugs: ['mini'], reengagementSentAt: {}, }] await scheduleReengagementEmails(async (email) => { sent.push(email) }) assert.deepEqual(sent, ['c@d.co']) })