From b336b0510b8bb48adf8f38d7e2102ac4cc3e4486 Mon Sep 17 00:00:00 2001 From: Tanuj Date: Mon, 3 Aug 2026 13:44:17 +1000 Subject: [PATCH 1/4] Create ACCEPTED invites for seeded participant users --- .../ParticipantsController.test.ts | 2 ++ application/common/testing/seed.ts | 30 ++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/application/backend/src/controllers/ParticipantsController.test.ts b/application/backend/src/controllers/ParticipantsController.test.ts index 168ac58e..97176eff 100644 --- a/application/backend/src/controllers/ParticipantsController.test.ts +++ b/application/backend/src/controllers/ParticipantsController.test.ts @@ -750,6 +750,7 @@ describe('InvitesController', () => { const invite = await prisma.invite.findFirstOrThrow({ where: { email: TestUsers.PARTICIPANT_UNANSWERED.email, + studyId: TestStudies.TEST_STUDY_2.id, }, }) @@ -805,6 +806,7 @@ describe('InvitesController', () => { const invite = await prisma.invite.findFirstOrThrow({ where: { email: TestUsers.PARTICIPANT_UNANSWERED.email, + studyId: TestStudies.TEST_STUDY_2.id, }, }) diff --git a/application/common/testing/seed.ts b/application/common/testing/seed.ts index 9133257c..e4b31784 100644 --- a/application/common/testing/seed.ts +++ b/application/common/testing/seed.ts @@ -194,7 +194,15 @@ export async function seedTests(prisma: PrismaClient) { participantType: 'STANDARD', }, }) - + await prisma.invite.create({ + data: { + email: TestUsers.PARTICIPANT_UNANSWERED.email, + status: InviteStatus.ACCEPTED, + studyId: testStudy.id, + expiresAt: new Date('2026-01-01'), + sentAt: new Date('2025-12-15'), + }, + }) await prisma.alternativeContact.create({ data: { participantProfileId: TestUsers.PARTICIPANT_UNANSWERED.id, @@ -232,6 +240,16 @@ export async function seedTests(prisma: PrismaClient) { }, }) + await prisma.invite.create({ + data: { + email: TestUsers.PARTICIPANT_COMPLETED.email, + status: InviteStatus.ACCEPTED, + studyId: testStudy.id, + expiresAt: new Date('2026-01-01'), + sentAt: new Date('2025-12-15'), + }, + }) + //Dependent Profile (no user) await prisma.participantProfile.create({ data: { @@ -290,6 +308,16 @@ export async function seedTests(prisma: PrismaClient) { }, }) + await prisma.invite.create({ + data: { + email: TestUsers.GUARDIAN_2.email, + status: InviteStatus.ACCEPTED, + studyId: testStudy.id, + expiresAt: new Date('2026-01-01'), + sentAt: new Date('2025-12-15'), + }, + }) + const testSurveyVersion = await prisma.surveyVersion.create({ data: { id: 800, From 45de691ec63e4e33046fe840358180a44cec06e8 Mon Sep 17 00:00:00 2001 From: Tanuj Date: Mon, 3 Aug 2026 13:53:52 +1000 Subject: [PATCH 2/4] Also create ACCEPTED invites for participants enrolled in FE_TEST_STUDY --- application/common/testing/seed.ts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/application/common/testing/seed.ts b/application/common/testing/seed.ts index e4b31784..da251f3d 100644 --- a/application/common/testing/seed.ts +++ b/application/common/testing/seed.ts @@ -523,6 +523,16 @@ export async function seedTests(prisma: PrismaClient) { }, }) + await prisma.invite.create({ + data: { + email: TestUsers.GUARDIAN_2.email, + status: InviteStatus.ACCEPTED, + studyId: frontendTestStudy.id, + expiresAt: new Date('2026-01-01'), + sentAt: new Date('2025-12-15'), + }, + }) + await prisma.participantProfile.update({ where: { id: participantUnansweredProfile.id, @@ -541,6 +551,16 @@ export async function seedTests(prisma: PrismaClient) { }, }) + await prisma.invite.create({ + data: { + email: TestUsers.PARTICIPANT_UNANSWERED.email, + status: InviteStatus.ACCEPTED, + studyId: frontendTestStudy.id, + expiresAt: new Date('2026-01-01'), + sentAt: new Date('2025-12-15'), + }, + }) + await prisma.surveyVersionAnswers.create({ data: { versionId: frontendTestSurveryVersion.id, From 66f9a4e7044e308b351d55054c71a351fa87627d Mon Sep 17 00:00:00 2001 From: Tanuj Date: Wed, 5 Aug 2026 15:29:13 +1000 Subject: [PATCH 3/4] Refactor seed data to Prisma nested writes and add invites to dev seed --- application/backend/prisma/seed/seed.ts | 48 ++- application/common/testing/seed.ts | 401 +++++++++++------------- 2 files changed, 236 insertions(+), 213 deletions(-) diff --git a/application/backend/prisma/seed/seed.ts b/application/backend/prisma/seed/seed.ts index 297fa4f2..de1a9ab7 100644 --- a/application/backend/prisma/seed/seed.ts +++ b/application/backend/prisma/seed/seed.ts @@ -1,4 +1,4 @@ -import { PrismaClient } from '@prisma/client' +import { InviteStatus, PrismaClient } from '@prisma/client' import { hashPassword } from '../../src/authentication' import { SurveyStep } from '../../../common/types/survey' import { createDefaultAnswers, recalculateAnswers } from '../../src/utils/answers' @@ -99,6 +99,16 @@ const main = async () => { }, }, }) + // Invite for Michael (kept separate because Invite has no direct relation to User in the schema) + await prisma.invite.create({ + data: { + email: 'michaelwilson@example.com', + status: InviteStatus.ACCEPTED, + studyId: shortStudy.id, + expiresAt: new Date('2026-01-01'), + sentAt: new Date('2025-12-15'), + }, + }) await prisma.user.upsert({ where: { email: 'sallywilson@example.com' }, @@ -150,6 +160,15 @@ const main = async () => { }, }, }) + await prisma.invite.create({ + data: { + email: 'sallywilson@example.com', + status: InviteStatus.ACCEPTED, + studyId: shortStudy.id, + expiresAt: new Date('2026-01-01'), + sentAt: new Date('2025-12-15'), + }, + }) await prisma.participantProfile.upsert({ where: { @@ -245,6 +264,15 @@ const main = async () => { }, }, }) + await prisma.invite.create({ + data: { + email: 'alicejohnson@example.com', + status: InviteStatus.ACCEPTED, + studyId: shortStudy.id, + expiresAt: new Date('2026-01-01'), + sentAt: new Date('2025-12-15'), + }, + }) // Ensure a Study record exists const defaultStudy = await prisma.study.create({ @@ -411,6 +439,24 @@ const main = async () => { }, }, }) + await prisma.invite.create({ + data: { + email: String(process.env.EXAMPLE_PARTICIPANT_EMAIL), + status: InviteStatus.ACCEPTED, + studyId: defaultStudy.id, + expiresAt: new Date('2026-01-01'), + sentAt: new Date('2025-12-15'), + }, + }) + await prisma.invite.create({ + data: { + email: String(process.env.EXAMPLE_PARTICIPANT_EMAIL), + status: InviteStatus.ACCEPTED, + studyId: shortStudy.id, + expiresAt: new Date('2026-01-01'), + sentAt: new Date('2025-12-15'), + }, + }) console.log('Added the following users:', exampleUser) const judithShortAnswers = await prisma.surveyVersionAnswers.findFirstOrThrow({ diff --git a/application/common/testing/seed.ts b/application/common/testing/seed.ts index da251f3d..04a0f11d 100644 --- a/application/common/testing/seed.ts +++ b/application/common/testing/seed.ts @@ -128,70 +128,108 @@ export async function seedTests(prisma: PrismaClient) { }, }) - //User with unanswered survey - await prisma.user.create({ + // Survey versions - created before participants so they can be nested inside profile creation + const testSurveyVersion = await prisma.surveyVersion.create({ data: { - id: TestUsers.PARTICIPANT_UNANSWERED.id, - email: TestUsers.PARTICIPANT_UNANSWERED.email, - firstName: 'Test', - lastName: 'User', - password: hashPassword(TestUsers.PARTICIPANT_UNANSWERED.password), - role: Role.Participant, - organisations: { - connect: { - id: 1, - }, - }, + id: 800, + status: 'PUBLISHED', + versionNumber: 1, + data: ExampleSurveyStepData as SurveyStep[], + studyId: testStudy.id, }, }) - //Second guardian user - await prisma.user.create({ + await prisma.surveyVersion.create({ data: { - id: TestUsers.GUARDIAN_2.id, - email: TestUsers.GUARDIAN_2.email, - firstName: 'Second', - lastName: 'Guardian', - password: hashPassword(TestUsers.GUARDIAN_2.password), - role: Role.Participant, + status: 'DRAFT', + versionNumber: 2, + data: ExampleSurveyStepData as SurveyStep[], + studyId: testStudy.id, }, }) - //User with completed survey - await prisma.user.create({ + + // Published survey for study 2 + const study2survey = await prisma.surveyVersion.create({ data: { - id: TestUsers.PARTICIPANT_COMPLETED.id, - email: TestUsers.PARTICIPANT_COMPLETED.email, - firstName: 'Test', - lastName: 'User', - password: hashPassword(TestUsers.PARTICIPANT_COMPLETED.password), - role: Role.Participant, + status: 'PUBLISHED', + versionNumber: 1, + data: [ + { + title: 'Study2step', + text: '', + elements: [ + { + type: 'question-checkbox', + data: { + text: 'Hello', + value: null, + }, + }, + ], + }, + ] as SurveyStep[], + studyId: secondTestStudy.id, }, }) - const participantUnansweredProfile = await prisma.participantProfile.create({ - data: { + // User with unanswered survey - nested writes for user + profile + study + nextOfKin + surveys + // Invite is a separate call after because Invite has no direct relation to User in the schema + await prisma.user.upsert({ + where: { email: TestUsers.PARTICIPANT_UNANSWERED.email }, + update: {}, + create: { id: TestUsers.PARTICIPANT_UNANSWERED.id, - firstName: 'Unanswered', + email: TestUsers.PARTICIPANT_UNANSWERED.email, + firstName: 'Test', lastName: 'User', - addressLine: '123 smith st', - dob: '1980-01-24', - mobile: '0412345678', - postcode: '1234', - preferredContact: 'EMAIL', - state: 'VIC', - suburb: 'M', - studies: { - create: { - participantId: `PID-TEST1-${TestUsers.PARTICIPANT_UNANSWERED.id}`, - study: { - connect: { - id: testStudy.id, + password: hashPassword(TestUsers.PARTICIPANT_UNANSWERED.password), + role: Role.Participant, + organisations: { connect: { id: 1 } }, + profiles: { + create: [ + { + id: TestUsers.PARTICIPANT_UNANSWERED.id, + firstName: 'Unanswered', + lastName: 'User', + addressLine: '123 smith st', + dob: '1980-01-24', + mobile: '0412345678', + postcode: '1234', + preferredContact: 'EMAIL', + state: 'VIC', + suburb: 'M', + participantType: 'STANDARD', + studies: { + create: { + participantId: `PID-TEST1-${TestUsers.PARTICIPANT_UNANSWERED.id}`, + study: { connect: { id: testStudy.id } }, + }, + }, + nextOfKin: { + create: { + email: 'alt@email.com', + firstName: 'Alt', + lastName: 'Cont', + }, + }, + surveys: { + create: [ + { + versionId: testSurveyVersion.id, + answers: [ + { status: 'review_required', answers: [] }, + { status: 'review_required', answers: [null, null] }, + ], + }, + { + versionId: study2survey.id, + answers: [{ status: 'review_required', answers: [null] }], + }, + ], }, }, - }, + ], }, - userId: TestUsers.PARTICIPANT_UNANSWERED.id, - participantType: 'STANDARD', }, }) await prisma.invite.create({ @@ -203,43 +241,57 @@ export async function seedTests(prisma: PrismaClient) { sentAt: new Date('2025-12-15'), }, }) - await prisma.alternativeContact.create({ - data: { - participantProfileId: TestUsers.PARTICIPANT_UNANSWERED.id, - email: 'alt@email.com', - firstName: 'Alt', - lastName: 'Cont', - }, - }) - await prisma.participantProfile.create({ - data: { + // User with completed survey + await prisma.user.upsert({ + where: { email: TestUsers.PARTICIPANT_COMPLETED.email }, + update: {}, + create: { id: TestUsers.PARTICIPANT_COMPLETED.id, - firstName: 'Completed', + email: TestUsers.PARTICIPANT_COMPLETED.email, + firstName: 'Test', lastName: 'User', - addressLine: '123 smith st', - dob: '1980-01-23', - mobile: '0412345678', - postcode: '1234', - preferredContact: 'EMAIL', - state: 'VIC', - suburb: 'Melbourne', - studies: { - create: { - participantId: `PID-TEST1-${TestUsers.PARTICIPANT_COMPLETED.id}`, - study: { - connect: { - id: testStudy.id, + password: hashPassword(TestUsers.PARTICIPANT_COMPLETED.password), + role: Role.Participant, + profiles: { + create: [ + { + id: TestUsers.PARTICIPANT_COMPLETED.id, + firstName: 'Completed', + lastName: 'User', + addressLine: '123 smith st', + dob: '1980-01-23', + mobile: '0412345678', + postcode: '1234', + preferredContact: 'EMAIL', + state: 'VIC', + suburb: 'Melbourne', + familyId: 100, + participantType: 'GUARDIAN', + studies: { + create: { + participantId: `PID-TEST1-${TestUsers.PARTICIPANT_COMPLETED.id}`, + study: { connect: { id: testStudy.id } }, + }, + }, + surveys: { + create: { + versionId: testSurveyVersion.id, + answers: [ + { status: 'viewed', answers: [] }, + { + status: 'completed', + answers: [false, 'Choice 2'], + last_updated: '2024-12-02T23:45:27.815Z', + }, + ], + }, }, }, - }, + ], }, - userId: TestUsers.PARTICIPANT_COMPLETED.id, - familyId: 100, - participantType: 'GUARDIAN', }, }) - await prisma.invite.create({ data: { email: TestUsers.PARTICIPANT_COMPLETED.email, @@ -250,7 +302,7 @@ export async function seedTests(prisma: PrismaClient) { }, }) - //Dependent Profile (no user) + // Dependent Profile (no user - so profile.create with nested studies + surveys) await prisma.participantProfile.create({ data: { id: TestUsers.DEPENDENT.id, @@ -263,51 +315,81 @@ export async function seedTests(prisma: PrismaClient) { preferredContact: 'EMAIL', state: 'VIC', suburb: 'Melbourne', + familyId: 100, + userId: null, + participantType: 'DEPENDENT_AGE', studies: { create: { participantId: `PID-TEST1-${TestUsers.DEPENDENT.id}`, - study: { - connect: { - id: testStudy.id, + study: { connect: { id: testStudy.id } }, + }, + }, + surveys: { + create: { + versionId: testSurveyVersion.id, + answers: [ + { status: 'viewed', answers: [] }, + { + status: 'review_required', + answers: [null, null], + last_updated: '2024-12-02T23:45:27.815Z', }, - }, + ], }, }, - familyId: 100, - userId: null, - participantType: 'DEPENDENT_AGE', }, }) - //Second guardian - await prisma.participantProfile.create({ - data: { + // Second guardian user + await prisma.user.upsert({ + where: { email: TestUsers.GUARDIAN_2.email }, + update: {}, + create: { id: TestUsers.GUARDIAN_2.id, + email: TestUsers.GUARDIAN_2.email, firstName: 'Second', lastName: 'Guardian', - addressLine: '123 smith st', - dob: '1990-01-23', - mobile: '0412345678', - postcode: '1234', - preferredContact: 'EMAIL', - state: 'VIC', - suburb: 'Melbourne', - studies: { - create: { - participantId: `PID-TEST1-${TestUsers.GUARDIAN_2.id}`, - study: { - connect: { - id: testStudy.id, + password: hashPassword(TestUsers.GUARDIAN_2.password), + role: Role.Participant, + profiles: { + create: [ + { + id: TestUsers.GUARDIAN_2.id, + firstName: 'Second', + lastName: 'Guardian', + addressLine: '123 smith st', + dob: '1990-01-23', + mobile: '0412345678', + postcode: '1234', + preferredContact: 'EMAIL', + state: 'VIC', + suburb: 'Melbourne', + familyId: 100, + participantType: 'GUARDIAN', + studies: { + create: { + participantId: `PID-TEST1-${TestUsers.GUARDIAN_2.id}`, + study: { connect: { id: testStudy.id } }, + }, + }, + surveys: { + create: { + versionId: testSurveyVersion.id, + answers: [ + { status: 'viewed', answers: [] }, + { + status: 'review_required', + answers: [null, null], + last_updated: '2024-12-02T23:45:27.815Z', + }, + ], + }, }, }, - }, + ], }, - familyId: 100, - userId: TestUsers.GUARDIAN_2.id, - participantType: 'GUARDIAN', }, }) - await prisma.invite.create({ data: { email: TestUsers.GUARDIAN_2.email, @@ -318,111 +400,6 @@ export async function seedTests(prisma: PrismaClient) { }, }) - const testSurveyVersion = await prisma.surveyVersion.create({ - data: { - id: 800, - status: 'PUBLISHED', - versionNumber: 1, - data: ExampleSurveyStepData as SurveyStep[], - studyId: testStudy.id, - }, - }) - - await prisma.surveyVersion.create({ - data: { - status: 'DRAFT', - versionNumber: 2, - data: ExampleSurveyStepData as SurveyStep[], - studyId: testStudy.id, - }, - }) - // publish a survey for study 2 - const study2survey = await prisma.surveyVersion.create({ - data: { - status: 'PUBLISHED', - versionNumber: 1, - data: [ - { - title: 'Study2step', - text: '', - elements: [ - { - type: 'question-checkbox', - data: { - text: 'Hello', - value: null, - }, - }, - ], - }, - ] as SurveyStep[], - studyId: secondTestStudy.id, - }, - }) - - await prisma.surveyVersionAnswers.create({ - data: { - versionId: testSurveyVersion.id, - profileId: TestUsers.PARTICIPANT_UNANSWERED.id, - answers: [ - { status: 'review_required', answers: [] }, - { status: 'review_required', answers: [null, null] }, - ], - }, - }) - await prisma.surveyVersionAnswers.create({ - data: { - versionId: study2survey.id, - profileId: TestUsers.PARTICIPANT_UNANSWERED.id, - answers: [{ status: 'review_required', answers: [null] }], - }, - }) - - await prisma.surveyVersionAnswers.create({ - data: { - versionId: testSurveyVersion.id, - profileId: TestUsers.PARTICIPANT_COMPLETED.id, - answers: [ - { status: 'viewed', answers: [] }, - { - status: 'completed', - answers: [false, 'Choice 2'], - last_updated: '2024-12-02T23:45:27.815Z', - }, - ], - }, - }) - - await prisma.surveyVersionAnswers.create({ - data: { - versionId: testSurveyVersion.id, - profileId: TestUsers.DEPENDENT.id, - answers: [ - { status: 'viewed', answers: [] }, - { - status: 'review_required', - answers: [null, null], - last_updated: '2024-12-02T23:45:27.815Z', - }, - ], - }, - }) - - await prisma.surveyVersionAnswers.create({ - data: { - versionId: testSurveyVersion.id, - profileId: TestUsers.GUARDIAN_2.id, - answers: [ - { status: 'viewed', answers: [] }, - { - status: 'review_required', - answers: [null, null], - last_updated: '2024-12-02T23:45:27.815Z', - }, - ], - }, - }) - // Seed a user and password reset token await prisma.user.create({ data: { @@ -535,7 +512,7 @@ export async function seedTests(prisma: PrismaClient) { await prisma.participantProfile.update({ where: { - id: participantUnansweredProfile.id, + id: TestUsers.PARTICIPANT_UNANSWERED.id, }, data: { studies: { From 34cd6aeae3856a0955d322724715af70e4e63e87 Mon Sep 17 00:00:00 2001 From: Tanuj Date: Thu, 6 Aug 2026 11:35:32 +1000 Subject: [PATCH 4/4] Nest invite creation under study.create in both seed files --- application/backend/prisma/seed/seed.ts | 95 +++++++-------- application/common/testing/seed.ts | 153 ++++++++++-------------- 2 files changed, 110 insertions(+), 138 deletions(-) diff --git a/application/backend/prisma/seed/seed.ts b/application/backend/prisma/seed/seed.ts index de1a9ab7..c19bba89 100644 --- a/application/backend/prisma/seed/seed.ts +++ b/application/backend/prisma/seed/seed.ts @@ -20,9 +20,38 @@ const main = async () => { }) const ShortSurveyStepData = require('./shortSurveyData.json') + // Short Study - nested ACCEPTED invites for the four participants seeded below (Michael, Sally, Alice, Judith) const shortStudy = await prisma.study.create({ data: { name: 'Short Study', + invites: { + create: [ + { + email: 'michaelwilson@example.com', + status: InviteStatus.ACCEPTED, + expiresAt: new Date('2026-01-01'), + sentAt: new Date('2025-12-15'), + }, + { + email: 'sallywilson@example.com', + status: InviteStatus.ACCEPTED, + expiresAt: new Date('2026-01-01'), + sentAt: new Date('2025-12-15'), + }, + { + email: 'alicejohnson@example.com', + status: InviteStatus.ACCEPTED, + expiresAt: new Date('2026-01-01'), + sentAt: new Date('2025-12-15'), + }, + { + email: String(process.env.EXAMPLE_PARTICIPANT_EMAIL), + status: InviteStatus.ACCEPTED, + expiresAt: new Date('2026-01-01'), + sentAt: new Date('2025-12-15'), + }, + ], + }, }, }) console.log('Short Study created:', shortStudy) @@ -49,6 +78,7 @@ const main = async () => { const baseAnswers = createDefaultAnswers(ShortSurveyStepData) + // Michael - nested writes for user + profile + nextOfKin + studies + surveys const michael = await prisma.user.upsert({ where: { email: 'michaelwilson@example.com' }, update: {}, @@ -99,17 +129,7 @@ const main = async () => { }, }, }) - // Invite for Michael (kept separate because Invite has no direct relation to User in the schema) - await prisma.invite.create({ - data: { - email: 'michaelwilson@example.com', - status: InviteStatus.ACCEPTED, - studyId: shortStudy.id, - expiresAt: new Date('2026-01-01'), - sentAt: new Date('2025-12-15'), - }, - }) - + // Sally - same nested pattern as Michael, second guardian on Short Study await prisma.user.upsert({ where: { email: 'sallywilson@example.com' }, update: {}, @@ -160,16 +180,7 @@ const main = async () => { }, }, }) - await prisma.invite.create({ - data: { - email: 'sallywilson@example.com', - status: InviteStatus.ACCEPTED, - studyId: shortStudy.id, - expiresAt: new Date('2026-01-01'), - sentAt: new Date('2025-12-15'), - }, - }) - + // Johnny - dependent profile (no user account, so no invite) linked to Short Study await prisma.participantProfile.upsert({ where: { individualId: 'IND-ABC-003', @@ -212,6 +223,7 @@ const main = async () => { }, }) + // Alice - Participant user on Short Study const alice = await prisma.user.upsert({ where: { email: 'alicejohnson@example.com' }, update: {}, @@ -264,22 +276,22 @@ const main = async () => { }, }, }) - await prisma.invite.create({ - data: { - email: 'alicejohnson@example.com', - status: InviteStatus.ACCEPTED, - studyId: shortStudy.id, - expiresAt: new Date('2026-01-01'), - sentAt: new Date('2025-12-15'), - }, - }) - - // Ensure a Study record exists + // Seed Study - nested ACCEPTED invite for Judith below (she is also on Short Study, that invite is nested above) const defaultStudy = await prisma.study.create({ data: { name: 'Seed Study', redcapURL: process.env.REDCAP_API_URL, redcapToken: process.env.REDCAP_API_TOKEN, + invites: { + create: [ + { + email: String(process.env.EXAMPLE_PARTICIPANT_EMAIL), + status: InviteStatus.ACCEPTED, + expiresAt: new Date('2026-01-01'), + sentAt: new Date('2025-12-15'), + }, + ], + }, }, }) @@ -373,6 +385,7 @@ const main = async () => { const exampleAnswers = createDefaultAnswers(SeedSurveyStepData) exampleAnswers[1].answers[0] = false //For DUO testing + // Judith - example participant registered on both Short Study and Seed Study const exampleUser = await prisma.user.upsert({ where: { email: String(process.env.EXAMPLE_PARTICIPANT_EMAIL) }, update: {}, @@ -439,24 +452,6 @@ const main = async () => { }, }, }) - await prisma.invite.create({ - data: { - email: String(process.env.EXAMPLE_PARTICIPANT_EMAIL), - status: InviteStatus.ACCEPTED, - studyId: defaultStudy.id, - expiresAt: new Date('2026-01-01'), - sentAt: new Date('2025-12-15'), - }, - }) - await prisma.invite.create({ - data: { - email: String(process.env.EXAMPLE_PARTICIPANT_EMAIL), - status: InviteStatus.ACCEPTED, - studyId: shortStudy.id, - expiresAt: new Date('2026-01-01'), - sentAt: new Date('2025-12-15'), - }, - }) console.log('Added the following users:', exampleUser) const judithShortAnswers = await prisma.surveyVersionAnswers.findFirstOrThrow({ diff --git a/application/common/testing/seed.ts b/application/common/testing/seed.ts index 04a0f11d..aa140b68 100644 --- a/application/common/testing/seed.ts +++ b/application/common/testing/seed.ts @@ -23,6 +23,7 @@ export async function seedTests(prisma: PrismaClient) { await prisma.$executeRaw`SELECT setval(pg_get_serial_sequence('"Organisation"', 'id'), 2, false) FROM "Organisation";` // Create four studies + // Test Study - nested ACCEPTED invites for the three participants below (UNANSWERED, COMPLETED, GUARDIAN_2), plus fixture invites in various states for testing invite lifecycle const testStudy = await prisma.study.create({ data: { name: TestStudies.TEST_STUDY.name, @@ -30,6 +31,53 @@ export async function seedTests(prisma: PrismaClient) { redcapToken: 'ABC', redcapURL: 'http://redcaptest.com', contactUsEmail: 'test@contactus.com', + invites: { + create: [ + { + email: TestUsers.PARTICIPANT_UNANSWERED.email, + status: InviteStatus.ACCEPTED, + expiresAt: new Date('2026-01-01'), + sentAt: new Date('2025-12-15'), + }, + { + email: TestUsers.PARTICIPANT_COMPLETED.email, + status: InviteStatus.ACCEPTED, + expiresAt: new Date('2026-01-01'), + sentAt: new Date('2025-12-15'), + }, + { + email: TestUsers.GUARDIAN_2.email, + status: InviteStatus.ACCEPTED, + expiresAt: new Date('2026-01-01'), + sentAt: new Date('2025-12-15'), + }, + { + email: TestInvites.INVITE_PENDING.email, + status: InviteStatus.PENDING, + expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000), // 1 day in the future + }, + { + email: TestInvites.INVITE_ACCEPTED.email, + status: InviteStatus.ACCEPTED, + expiresAt: new Date(Date.now() - 24 * 60 * 60 * 1000), // 1 day in the past + }, + { + email: TestInvites.INVITE_REVOKED.email, + status: InviteStatus.REVOKED, + expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000), // 1 day in the future + }, + { + email: TestInvites.INVITE_EXPIRED.email, + status: InviteStatus.EXPIRED, + expiresAt: new Date(Date.now() - 24 * 60 * 60 * 1000), // 1 day in the past + }, + { + email: TestInvites.INVITE_2_PENDING.email, + status: InviteStatus.PENDING, + expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000), // 1 day in the future + }, + ], + }, }, }) @@ -43,10 +91,27 @@ export async function seedTests(prisma: PrismaClient) { }) // This study will have a survey, a participant user and draft answers (mostly for frontend multistudy testing) + // Nested ACCEPTED invites for GUARDIAN_2 and PARTICIPANT_UNANSWERED (both linked to this study below) const frontendTestStudy = await prisma.study.create({ data: { name: TestStudies.FE_TEST_STUDY.name, id: TestStudies.FE_TEST_STUDY.id, + invites: { + create: [ + { + email: TestUsers.GUARDIAN_2.email, + status: InviteStatus.ACCEPTED, + expiresAt: new Date('2026-01-01'), + sentAt: new Date('2025-12-15'), + }, + { + email: TestUsers.PARTICIPANT_UNANSWERED.email, + status: InviteStatus.ACCEPTED, + expiresAt: new Date('2026-01-01'), + sentAt: new Date('2025-12-15'), + }, + ], + }, }, }) @@ -173,7 +238,6 @@ export async function seedTests(prisma: PrismaClient) { }) // User with unanswered survey - nested writes for user + profile + study + nextOfKin + surveys - // Invite is a separate call after because Invite has no direct relation to User in the schema await prisma.user.upsert({ where: { email: TestUsers.PARTICIPANT_UNANSWERED.email }, update: {}, @@ -232,16 +296,6 @@ export async function seedTests(prisma: PrismaClient) { }, }, }) - await prisma.invite.create({ - data: { - email: TestUsers.PARTICIPANT_UNANSWERED.email, - status: InviteStatus.ACCEPTED, - studyId: testStudy.id, - expiresAt: new Date('2026-01-01'), - sentAt: new Date('2025-12-15'), - }, - }) - // User with completed survey await prisma.user.upsert({ where: { email: TestUsers.PARTICIPANT_COMPLETED.email }, @@ -292,16 +346,6 @@ export async function seedTests(prisma: PrismaClient) { }, }, }) - await prisma.invite.create({ - data: { - email: TestUsers.PARTICIPANT_COMPLETED.email, - status: InviteStatus.ACCEPTED, - studyId: testStudy.id, - expiresAt: new Date('2026-01-01'), - sentAt: new Date('2025-12-15'), - }, - }) - // Dependent Profile (no user - so profile.create with nested studies + surveys) await prisma.participantProfile.create({ data: { @@ -390,16 +434,6 @@ export async function seedTests(prisma: PrismaClient) { }, }, }) - await prisma.invite.create({ - data: { - email: TestUsers.GUARDIAN_2.email, - status: InviteStatus.ACCEPTED, - studyId: testStudy.id, - expiresAt: new Date('2026-01-01'), - sentAt: new Date('2025-12-15'), - }, - }) - // Seed a user and password reset token await prisma.user.create({ data: { @@ -421,43 +455,6 @@ export async function seedTests(prisma: PrismaClient) { }, }) - // Setup invites - await prisma.invite.createMany({ - data: [ - { - email: TestInvites.INVITE_PENDING.email, - status: InviteStatus.PENDING, - studyId: testStudy.id, - expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000), // 1 day in the future - }, - { - email: TestInvites.INVITE_ACCEPTED.email, - status: InviteStatus.ACCEPTED, - studyId: testStudy.id, - expiresAt: new Date(Date.now() - 24 * 60 * 60 * 1000), // 1 day in the past - }, - { - email: TestInvites.INVITE_REVOKED.email, - status: InviteStatus.REVOKED, - studyId: testStudy.id, - expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000), // 1 day in the future - }, - { - email: TestInvites.INVITE_EXPIRED.email, - status: InviteStatus.EXPIRED, - studyId: testStudy.id, - expiresAt: new Date(Date.now() - 24 * 60 * 60 * 1000), // 1 day in the past - }, - // Pending invites for testing - { - email: TestInvites.INVITE_2_PENDING.email, - status: InviteStatus.PENDING, - studyId: testStudy.id, - expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000), // 1 day in the future - }, - ], - }) - // Frontend multistudy test seed data const frontendTestSurveryVersion = await prisma.surveyVersion.create({ data: { @@ -500,16 +497,6 @@ export async function seedTests(prisma: PrismaClient) { }, }) - await prisma.invite.create({ - data: { - email: TestUsers.GUARDIAN_2.email, - status: InviteStatus.ACCEPTED, - studyId: frontendTestStudy.id, - expiresAt: new Date('2026-01-01'), - sentAt: new Date('2025-12-15'), - }, - }) - await prisma.participantProfile.update({ where: { id: TestUsers.PARTICIPANT_UNANSWERED.id, @@ -528,16 +515,6 @@ export async function seedTests(prisma: PrismaClient) { }, }) - await prisma.invite.create({ - data: { - email: TestUsers.PARTICIPANT_UNANSWERED.email, - status: InviteStatus.ACCEPTED, - studyId: frontendTestStudy.id, - expiresAt: new Date('2026-01-01'), - sentAt: new Date('2025-12-15'), - }, - }) - await prisma.surveyVersionAnswers.create({ data: { versionId: frontendTestSurveryVersion.id,