Files

61 lines
2.6 KiB
TypeScript

import { expect, test } from './support/test.ts';
import { parseActionLog } from '@when/db';
import { readAppointment, readQueuedWorkflows } from './support/database.ts';
import { CHAT_MEETING, seedAppointment } from './support/seed.ts';
test('a guest with the cancel token sees the appointment', async ({ page }) => {
const appointment = await seedAppointment({ status: 'pending' });
await page.goto(`/appointment/${appointment.id}?token=${appointment.cancel_token}`);
await expect(page.getByRole('heading', { name: 'Pending', exact: true })).toBeVisible();
await expect(page.getByRole('heading', { name: CHAT_MEETING.title })).toBeVisible();
});
test('a guest cancels a confirmed appointment', async ({ page }) => {
const appointment = await seedAppointment({ status: 'confirmed' });
await page.goto(`/appointment/${appointment.id}?token=${appointment.cancel_token}`);
await page.getByRole('button', { name: 'Appointment actions' }).click();
await page.getByRole('menuitem', { name: 'Cancel' }).click();
const dialog = page.getByRole('dialog', { name: 'Cancel appointment', exact: true });
const reason = dialog.getByLabel('Reason (required)', { exact: true });
await expect(reason).toHaveAttribute('required', '');
await expect(reason).toHaveAttribute('maxlength', '500');
const initialReason = await reason.inputValue();
await expect(dialog.getByText(`${initialReason.length}/500`, { exact: true })).toBeVisible();
await reason.fill('Something came up');
await expect(dialog.getByText('17/500', { exact: true })).toBeVisible();
await dialog.getByRole('button', { name: 'Cancel', exact: true }).click();
await expect(page.getByRole('heading', { name: 'Cancelled', exact: true })).toBeVisible();
// The action explanation is stored in history, not the general appointment note.
const row = await readAppointment(appointment.id);
expect(row.status).toBe('cancelled');
expect(parseActionLog(row.action_log).at(-1)).toMatchObject({
action: 'cancel',
actor: 'guest',
payload: { note: 'Something came up' }
});
expect(
readQueuedWorkflows(`${appointment.id}:cancelled-by-guest:${row.ics_sequence}`)
).toHaveLength(1);
});
test('a guest without a token cannot see the appointment', async ({ page }) => {
const appointment = await seedAppointment({ status: 'pending' });
const response = await page.goto(`/appointment/${appointment.id}`);
expect(response?.status()).toBe(404);
});
test('a guest with the wrong token cannot see the appointment', async ({ page }) => {
const appointment = await seedAppointment({ status: 'pending' });
const response = await page.goto(`/appointment/${appointment.id}?token=not-the-token`);
expect(response?.status()).toBe(404);
});