Merge pull request 'Fix minor UI bugs and test guest CRUD' (#281) from improve-specs-guests into main
Reviewed-on: #281
This commit is contained in:
commit
2ebd9796e3
@ -100,7 +100,20 @@ export default function Page() {
|
|||||||
key={guestBeingEdited?.id}
|
key={guestBeingEdited?.id}
|
||||||
groups={groups}
|
groups={groups}
|
||||||
onCreate={(newGuest) => {
|
onCreate={(newGuest) => {
|
||||||
setGuests([newGuest!, ...guests]);
|
setGuests(prevGuests => {
|
||||||
|
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}
|
||||||
|
@ -41,7 +41,7 @@ export class AbstractApi<T extends Entity> implements Api<T> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
update(serializable: Serializable<T>, object: T, callback: () => void): void {
|
update(serializable: Serializable<T>, object: T, callback: (updatedObject: T) => 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,7 +52,10 @@ export class AbstractApi<T extends Entity> implements Api<T> {
|
|||||||
'Accept': 'application/json',
|
'Accept': 'application/json',
|
||||||
'X-CSRF-TOKEN': getCsrfToken(),
|
'X-CSRF-TOKEN': getCsrfToken(),
|
||||||
}
|
}
|
||||||
}).then(callback)
|
}).then((response) => response.json())
|
||||||
|
.then((data) => {
|
||||||
|
callback(serializable.fromJson(data));
|
||||||
|
})
|
||||||
.catch((error) => console.error(error));
|
.catch((error) => console.error(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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, () => {
|
api.update(serializer, guest, (updatedGuest) => {
|
||||||
resetForm();
|
resetForm();
|
||||||
onCreate && onCreate(guest);
|
onCreate && onCreate(updatedGuest);
|
||||||
});
|
});
|
||||||
} 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="username" className='rounded-sm' value={name} onChange={(e) => setName(e.target.value)} />
|
<InputText id="name" className='rounded-sm' value={name} onChange={(e) => setName(e.target.value)} />
|
||||||
<label htmlFor="username">Username</label>
|
<label htmlFor="name">Name</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={
|
||||||
|
@ -10,8 +10,8 @@ const mockGuestsAPI = ({ page }: { page: Page }) => {
|
|||||||
"status": "tentative",
|
"status": "tentative",
|
||||||
"name": "Kristofer Rohan DVM",
|
"name": "Kristofer Rohan DVM",
|
||||||
"group": {
|
"group": {
|
||||||
"id": "2fcb8b22-6b07-4c34-92e3-a2535dbc5b14",
|
"id": "ee44ffb9-1147-4842-a378-9eaeb0f0871a",
|
||||||
"name": "Childhood friends",
|
"name": "Pam's family",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -19,8 +19,8 @@ const mockGuestsAPI = ({ page }: { page: Page }) => {
|
|||||||
"status": "invited",
|
"status": "invited",
|
||||||
"name": "Olevia Quigley Jr.",
|
"name": "Olevia Quigley Jr.",
|
||||||
"group": {
|
"group": {
|
||||||
"id": "da8edf26-3e1e-4cbb-b985-450c49fffe01",
|
"id": "c8bda6ca-d8af-4bb8-b2bf-e6ec1c21b1e6",
|
||||||
"name": "Work",
|
"name": "Pam's work",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@ -28,18 +28,37 @@ 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": "da8edf26-3e1e-4cbb-b985-450c49fffe01",
|
"id": "c8bda6ca-d8af-4bb8-b2bf-e6ec1c21b1e6",
|
||||||
"name": "Work",
|
"name": "Pam's 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 }) => {
|
||||||
@ -81,8 +100,9 @@ const mockGroupsAPI = ({ page }: { page: Page }) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
test('should display the list of guests', async ({ page }) => {
|
test('should allow CRUD on guests', async ({ page }) => {
|
||||||
await mockGuestsAPI({ page });
|
await mockGuestsAPI({ page });
|
||||||
|
await mockGroupsAPI({ page });
|
||||||
|
|
||||||
await page.goto('/default/dashboard/guests');
|
await page.goto('/default/dashboard/guests');
|
||||||
|
|
||||||
@ -92,49 +112,64 @@ test('should display the list of 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: 'Childhood friends' })).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: '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: 'Work' })).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: '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);
|
||||||
});
|
|
||||||
|
|
||||||
test('should allow creating a new guest', async ({ page }) => {
|
// Add a new guest
|
||||||
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.keyboard.press('Tab');
|
await page.locator('#group').click();
|
||||||
await page.keyboard.press('ArrowDown');
|
await page.getByRole('option', { name: "Pam's work" }).click();
|
||||||
await page.keyboard.press('ArrowDown');
|
|
||||||
await page.keyboard.press('Enter');
|
|
||||||
|
|
||||||
await page.keyboard.press('Tab');
|
await page.locator('#status').click();
|
||||||
await page.keyboard.press('ArrowDown');
|
await page.getByRole('option', { name: 'Invited' }).click();
|
||||||
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: 'Work' })).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: '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 }) => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user