diff --git a/playwright.config.ts b/playwright.config.ts index aab6177..16d9a37 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -1,5 +1,6 @@ import type { PlaywrightTestConfig } from '@playwright/test'; +export const TIMEZONE = 'America/Los_Angeles'; const config: PlaywrightTestConfig = { webServer: [ { @@ -18,11 +19,12 @@ const config: PlaywrightTestConfig = { }, // timeout: 10000, testDir: 'tests', - testMatch:'*spec.ts', + testMatch: '*spec.ts', use: { locale: 'en-US', - timezoneId: 'America/Los_Angeles' - }, + timezoneId: TIMEZONE, + baseURL: 'http://localhost:5173' + } }; export default config; diff --git a/prisma/utils.ts b/prisma/utils.ts index 548c2bc..8dd27d4 100644 --- a/prisma/utils.ts +++ b/prisma/utils.ts @@ -79,6 +79,13 @@ export default class SeedUtils { return; } const { householdId } = user; + + const deleteDates = this.#prisma.availabilityDate.deleteMany({ + where: { + householdId + } + }); + // delete all kids const deleteKids = this.#prisma.householdChild.deleteMany({ where: { @@ -137,7 +144,8 @@ export default class SeedUtils { deleteFriendReqs1, deleteFriendReqs2, deleteFriends1, - deleteFriends2 + deleteFriends2, + deleteDates ]); // delete all adults await this.#prisma.user.deleteMany({ @@ -249,7 +257,7 @@ export default class SeedUtils { const phone = this.userIndToPhone(userInd); - await this.#prisma.user.upsert({ + return await this.#prisma.user.upsert({ where: { phone }, @@ -260,4 +268,10 @@ export default class SeedUtils { } }); } + + async createAvailabilityDate(data: Prisma.AvailabilityDateCreateInput) { + return await this.#prisma.availabilityDate.create({ + data + }); + } } diff --git a/tests/calendar.spec.ts b/tests/calendar.spec.ts index f33fc48..c953548 100644 --- a/tests/calendar.spec.ts +++ b/tests/calendar.spec.ts @@ -1,7 +1,5 @@ /* -1. mark as busy -2. mark as unspecified -3. mark as valid available +TODO: 4. mark as invalid available 5. updating availRange in editor changes displayed editor value @@ -11,8 +9,165 @@ b. BUSY? - Clear btn c. AVAILABLE? */ -/* -create profile -create kid -save basic info -*/ + +import { expect } from '@playwright/test'; +import type { DateTime } from 'luxon'; +import { TIMEZONE } from '../playwright.config'; +import { startOfToday } from '../src/lib/logics/_shared/date'; +import { test } from './test'; +import { AvailabilityStatus } from '@prisma/client'; + +const host = 'http://localhost:5173'; + +test.describe('Calendar', () => { + let today: DateTime; + let user22: { householdId: number | null } | null; + test.beforeAll(async ({ utils }) => { + await Promise.all([ + utils.deleteUserAndHousehold('+12015550020'), + utils.deleteUserAndHousehold('+12015550021'), + utils.deleteUserAndHousehold('+12015550022') + ]); + + [, , user22] = await Promise.all([ + utils.createUserWithKid(20), + utils.createUserWithKid(21), + utils.createUserWithKid(22), + utils.createActiveSession(20), + utils.createActiveSession(21), + utils.createActiveSession(22) + ]); + + today = startOfToday(TIMEZONE); + }); + + test('Mark as busy', async ({ page, context }) => { + await context.addCookies([ + { + name: 'session', + value: 'user20session', + url: host + } + ]); + await page.goto('/calendar'); + await page.waitForURL('/calendar'); + + const date = today.plus({ days: 3 }); + await page + .locator('tr', { has: page.locator(`text="${date.month}/${date.day}"`) }) + .getByText('Busy', { exact: true }) + .click(); + + // UI changed + await expect( + page + .locator('tr', { has: page.locator(`text="${date.month}/${date.day}"`) }) + .locator('td:nth-child(3)') + ).toContainText('Busy'); + + await page.reload(); + + // actually saved to db + await expect( + page + .locator('tr', { has: page.locator(`text="${date.month}/${date.day}"`) }) + .locator('td:nth-child(3)') + ).toContainText('Busy'); + }); + + test('Mark as valid available', async ({ page, context }) => { + await context.addCookies([ + { + name: 'session', + value: 'user21session', + url: host + } + ]); + await page.goto('/calendar'); + await page.waitForURL('/calendar'); + await page.waitForSelector('table#schedule'); + + expect(await page.locator('.editorCell').isVisible()).toBeFalsy(); + + const date = today.plus({ days: 4 }); + const monthDay = `${date.month}/${date.day}`; + await page + .locator('tr', { has: page.locator(`text="${monthDay}"`) }) + .getByText('edit', { exact: true }) + .click(); + + expect(await page.locator('.editorCell').isVisible()).toBeTruthy(); + + await page.keyboard.type('2-3'); + + await page.getByRole('button', { name: 'Save' }).click(); + + // UI changed + // editor closes + await page.locator('.editorCell').waitFor({ + state: 'detached' + }); + + // cell display changes + await expect( + page.locator('tr', { has: page.locator(`text="${monthDay}"`) }).locator('td:nth-child(3)') + ).toContainText('2pm-3pm'); + + await page.reload(); + + // actually saved to db + await expect( + page.locator('tr', { has: page.locator(`text="${monthDay}"`) }).locator('td:nth-child(3)') + ).toContainText('2pm-3pm'); + }); + + test('Mark as unspecified', async ({ utils, page, context }) => { + test.skip(!user22?.householdId, 'Failed to create user22'); + + const date = today.plus({ days: 5 }); + await utils.createAvailabilityDate({ + date: date.toJSDate(), + status: AvailabilityStatus.BUSY, + household: { + connect: { + id: user22!.householdId! + } + } + }); + + await context.addCookies([ + { + name: 'session', + value: 'user22session', + url: host + } + ]); + await page.goto('/calendar'); + await page.waitForURL('/calendar'); + await page.waitForSelector('table#schedule'); + await expect( + page + .locator('tr', { has: page.locator(`text="${date.month}/${date.day}"`) }) + .locator('td:nth-child(3)') + ).toContainText('Busy'); + + await page + .locator('tr', { has: page.locator(`text="${date.month}/${date.day}"`) }) + .getByText('Clear', { exact: true }) + .click(); + + await expect( + page + .locator('tr', { has: page.locator(`text="${date.month}/${date.day}"`) }) + .locator('td:nth-child(3)') + ).toContainText('Unspecified'); + + await page.reload(); + + await expect( + page + .locator('tr', { has: page.locator(`text="${date.month}/${date.day}"`) }) + .locator('td:nth-child(3)') + ).toContainText('Unspecified'); + }); +});