Compare commits

..

No commits in common. "c50263f760f3817b45d662de63dec3fc6f26339d" and "ae5a986f250a37c52f6f3c54eecfdafdf850b24a" have entirely different histories.

4 changed files with 38 additions and 89 deletions

View File

@ -100,20 +100,7 @@ export default function Page() {
key={guestBeingEdited?.id} key={guestBeingEdited?.id}
groups={groups} groups={groups}
onCreate={(newGuest) => { onCreate={(newGuest) => {
setGuests(prevGuests => { setGuests([newGuest!, ...guests]);
const index = prevGuests.findIndex(g => g.id === newGuest?.id);
if (index !== -1) {
// Replace existing guest
return [
newGuest!,
...prevGuests.slice(0, index),
...prevGuests.slice(index + 1)
];
} else {
// Add new guest at the start
return [newGuest!, ...prevGuests];
}
});
setGuestBeingEdited(undefined) ; setGuestBeingEdited(undefined) ;
}} }}
guest={guestBeingEdited} guest={guestBeingEdited}

View File

@ -41,7 +41,7 @@ export class AbstractApi<T extends Entity> implements Api<T> {
}); });
} }
update(serializable: Serializable<T>, object: T, callback: (updatedObject: T) => void): void { update(serializable: Serializable<T>, object: T, callback: () => void): void {
const endpoint = object.id ? `/api/${getSlug()}/${serializable.apiPath()}/${object.id}` : `/api/${getSlug()}/${serializable.apiPath()}`; const endpoint = object.id ? `/api/${getSlug()}/${serializable.apiPath()}/${object.id}` : `/api/${getSlug()}/${serializable.apiPath()}`;
fetch(endpoint, { fetch(endpoint, {
@ -52,10 +52,7 @@ export class AbstractApi<T extends Entity> implements Api<T> {
'Accept': 'application/json', 'Accept': 'application/json',
'X-CSRF-TOKEN': getCsrfToken(), 'X-CSRF-TOKEN': getCsrfToken(),
} }
}).then((response) => response.json()) }).then(callback)
.then((data) => {
callback(serializable.fromJson(data));
})
.catch((error) => console.error(error)); .catch((error) => console.error(error));
} }

View File

@ -44,9 +44,9 @@ export default function GuestFormDialog({ groups, onCreate, onHide, guest, visib
guest.group!.id = group; guest.group!.id = group;
guest.status = status; guest.status = status;
api.update(serializer, guest, (updatedGuest) => { api.update(serializer, guest, () => {
resetForm(); resetForm();
onCreate && onCreate(updatedGuest); onCreate && onCreate(guest);
}); });
} else { } else {
api.create(serializer, new Guest(undefined, name, undefined, status, [], groups.find((g) => g.id === group)), (newGuest)=> { api.create(serializer, new Guest(undefined, name, undefined, status, [], groups.find((g) => g.id === group)), (newGuest)=> {
@ -62,8 +62,8 @@ export default function GuestFormDialog({ groups, onCreate, onHide, guest, visib
<Dialog header="Add guest" visible={visible} style={{ width: '60vw' }} onHide={onHide}> <Dialog header="Add guest" visible={visible} style={{ width: '60vw' }} onHide={onHide}>
<div className="card flex justify-evenly py-5"> <div className="card flex justify-evenly py-5">
<FloatLabel> <FloatLabel>
<InputText id="name" className='rounded-sm' value={name} onChange={(e) => setName(e.target.value)} /> <InputText id="username" className='rounded-sm' value={name} onChange={(e) => setName(e.target.value)} />
<label htmlFor="name">Name</label> <label htmlFor="username">Username</label>
</FloatLabel> </FloatLabel>
<FloatLabel> <FloatLabel>
<Dropdown id="group" className='rounded-sm min-w-32' value={group} onChange={(e) => setGroup(e.target.value)} options={ <Dropdown id="group" className='rounded-sm min-w-32' value={group} onChange={(e) => setGroup(e.target.value)} options={

View File

@ -10,8 +10,8 @@ const mockGuestsAPI = ({ page }: { page: Page }) => {
"status": "tentative", "status": "tentative",
"name": "Kristofer Rohan DVM", "name": "Kristofer Rohan DVM",
"group": { "group": {
"id": "ee44ffb9-1147-4842-a378-9eaeb0f0871a", "id": "2fcb8b22-6b07-4c34-92e3-a2535dbc5b14",
"name": "Pam's family", "name": "Childhood friends",
} }
}, },
{ {
@ -19,8 +19,8 @@ const mockGuestsAPI = ({ page }: { page: Page }) => {
"status": "invited", "status": "invited",
"name": "Olevia Quigley Jr.", "name": "Olevia Quigley Jr.",
"group": { "group": {
"id": "c8bda6ca-d8af-4bb8-b2bf-e6ec1c21b1e6", "id": "da8edf26-3e1e-4cbb-b985-450c49fffe01",
"name": "Pam's work", "name": "Work",
} }
}, },
]; ];
@ -28,37 +28,18 @@ const mockGuestsAPI = ({ page }: { page: Page }) => {
await route.fulfill({ json }) await route.fulfill({ json })
} else if (route.request().method() === 'POST') { } else if (route.request().method() === 'POST') {
const json = { const json = {
"id": "ff58aa2d-643d-4c29-be9c-50e10ae6853c", "id":"ff58aa2d-643d-4c29-be9c-50e10ae6853c",
"name": "John Snow", "name":"John Snow",
"status": "invited", "status":"invited",
"group": { "group": {
"id": "c8bda6ca-d8af-4bb8-b2bf-e6ec1c21b1e6", "id": "da8edf26-3e1e-4cbb-b985-450c49fffe01",
"name": "Pam's work", "name": "Work",
} }
}; };
await route.fulfill({ json }); await route.fulfill({ json });
} }
}) })
page.route("*/**/api/default/guests/*", async route => {
if (route.request().method() === 'PUT') {
const json = {
"id": "ff58aa2d-643d-4c29-be9c-50e10ae6853c",
"name": "John Fire",
"status": "declined",
"group": {
"id": "ee44ffb9-1147-4842-a378-9eaeb0f0871a",
"name": "Pam's family",
}
}
await route.fulfill({ json });
} else if (route.request().method() === 'DELETE') {
const json = {}
await route.fulfill({ json });
}
});
} }
const mockGroupsAPI = ({ page }: { page: Page }) => { const mockGroupsAPI = ({ page }: { page: Page }) => {
@ -100,9 +81,8 @@ const mockGroupsAPI = ({ page }: { page: Page }) => {
}) })
} }
test('should allow CRUD on guests', async ({ page }) => { test('should display the list of guests', async ({ page }) => {
await mockGuestsAPI({ page }); await mockGuestsAPI({ page });
await mockGroupsAPI({ page });
await page.goto('/default/dashboard/guests'); await page.goto('/default/dashboard/guests');
@ -112,64 +92,49 @@ test('should allow CRUD on guests', async ({ page }) => {
await expect(page.getByRole('tab', { name: 'Groups' })).toBeVisible(); await expect(page.getByRole('tab', { name: 'Groups' })).toBeVisible();
await expect(page.getByRole('tab', { name: 'Invitations' })).toBeVisible(); await expect(page.getByRole('tab', { name: 'Invitations' })).toBeVisible();
// List all guests
await expect(page.getByText('There are 2 elements in the list')).toBeVisible(); await expect(page.getByText('There are 2 elements in the list')).toBeVisible();
await expect(page.getByRole('row')).toHaveCount(3); // 1 header row + 2 data rows await expect(page.getByRole('row')).toHaveCount(3); // 1 header row + 2 data rows
await expect(page.getByRole('row').nth(1).getByRole('cell', { name: 'Kristofer Rohan DVM' })).toBeVisible(); await expect(page.getByRole('row').nth(1).getByRole('cell', { name: 'Kristofer Rohan DVM' })).toBeVisible();
await expect(page.getByRole('row').nth(1).getByRole('cell', { name: "Pam's family" })).toBeVisible(); await expect(page.getByRole('row').nth(1).getByRole('cell', { name: 'Childhood friends' })).toBeVisible();
await expect(page.getByRole('row').nth(1).getByRole('cell', { name: 'Tentative' })).toBeVisible(); await expect(page.getByRole('row').nth(1).getByRole('cell', { name: 'Tentative' })).toBeVisible();
await expect(page.getByRole('row').nth(1).locator('svg')).toHaveCount(2); await expect(page.getByRole('row').nth(1).locator('svg')).toHaveCount(2);
await expect(page.getByRole('row').nth(2).getByRole('cell', { name: 'Olevia Quigley Jr.' })).toBeVisible(); await expect(page.getByRole('row').nth(2).getByRole('cell', { name: 'Olevia Quigley Jr.' })).toBeVisible();
await expect(page.getByRole('row').nth(2).getByRole('cell', { name: "Pam's work" })).toBeVisible(); await expect(page.getByRole('row').nth(2).getByRole('cell', { name: 'Work' })).toBeVisible();
await expect(page.getByRole('row').nth(2).getByRole('cell', { name: 'Invited' })).toBeVisible(); await expect(page.getByRole('row').nth(2).getByRole('cell', { name: 'Invited' })).toBeVisible();
await expect(page.getByRole('row').nth(2).locator('svg')).toHaveCount(2); await expect(page.getByRole('row').nth(2).locator('svg')).toHaveCount(2);
});
// Add a new guest test('should allow creating a new guest', async ({ page }) => {
await mockGuestsAPI({ page });
await mockGroupsAPI({ page });
await page.goto('/default/dashboard/guests');
await expect(page.getByText('There are 2 elements in the list')).toBeVisible();
await page.getByRole('button', { name: 'Add new' }).click(); await page.getByRole('button', { name: 'Add new' }).click();
await page.getByRole('dialog').getByLabel('Name').fill('John Snow'); await page.getByRole('dialog').getByLabel('Name').fill('John Snow');
await page.locator('#group').click(); await page.keyboard.press('Tab');
await page.getByRole('option', { name: "Pam's work" }).click(); await page.keyboard.press('ArrowDown');
await page.keyboard.press('ArrowDown');
await page.keyboard.press('Enter');
await page.locator('#status').click(); await page.keyboard.press('Tab');
await page.getByRole('option', { name: 'Invited' }).click(); await page.keyboard.press('ArrowDown');
await page.keyboard.press('ArrowDown');
await page.keyboard.press('Enter');
await page.getByRole('dialog').getByRole('button', { name: 'Create' }).click(); await page.getByRole('dialog').getByRole('button', { name: 'Create' }).click();
await expect(page.getByText('There are 3 elements in the list')).toBeVisible(); await expect(page.getByText('There are 3 elements in the list')).toBeVisible();
await expect(page.getByRole('row').nth(1).getByRole('cell', { name: 'John Snow' })).toBeVisible(); await expect(page.getByRole('row').nth(1).getByRole('cell', { name: 'John Snow' })).toBeVisible();
await expect(page.getByRole('row').nth(1).getByRole('cell', { name: "Pam\'s work" })).toBeVisible(); await expect(page.getByRole('row').nth(1).getByRole('cell', { name: 'Work' })).toBeVisible();
await expect(page.getByRole('row').nth(1).getByRole('cell', { name: 'Invited' })).toBeVisible(); await expect(page.getByRole('row').nth(1).getByRole('cell', { name: 'Invited' })).toBeVisible();
await expect(page.getByRole('row').nth(1).locator('svg')).toHaveCount(2); await expect(page.getByRole('row').nth(1).locator('svg')).toHaveCount(2);
// Edit the just-added John Snow
await page.getByRole('row').nth(1).locator('svg').nth(1).click(); // Click edit icon
const dialog = page.getByRole('dialog');
await expect(dialog.getByLabel('Name')).toHaveValue('John Snow');
await dialog.getByLabel('Name').fill('John Fire');
await dialog.locator('#group').click();
await page.getByRole('option', { name: "Pam's family" }).click();
await dialog.locator('#status').click();
await page.getByRole('option', { name: 'Declined' }).click();
await dialog.getByRole('button', { name: 'Update' }).click();
await expect(page.getByRole('row').nth(1).getByRole('cell', { name: 'John Fire' })).toBeVisible();
await expect(page.getByRole('row').nth(1).getByRole('cell', { name: 'Pam\'s Family' })).toBeVisible();
await expect(page.getByRole('row').nth(1).getByRole('cell', { name: 'Declined' })).toBeVisible();
await expect(page.getByText('There are 3 elements in the list')).toBeVisible();
// Delete John Fire
await page.getByRole('row').nth(1).locator('svg').nth(0).click(); // Click delete icon
await expect(page.getByText('There are 2 elements in the list')).toBeVisible();
}); });
test('should display the list of groups', async ({ page }) => { test('should display the list of groups', async ({ page }) => {