Tasks 2 to 4 of the plan. Nine `collection.find(...)` dereferences become findOrFail, so a missing row fails as a named assertion naming what was wanted and how many rows were searched, rather than "Cannot read properties of undefined" pointing at test plumbing. Where the old code followed the lookup with expect(x).toBeTruthy(), that assertion is dropped: findOrFail already guarantees it, and with a better message. The expect timeout goes from Playwright's default 5s to 10s. It costs nothing on a green run — it bounds how long a failing assertion waits, not how long a passing one takes — and #239 died reporting exactly Timeout: 5000ms on a runner that also builds, migrates and runs three other suites. The admin-save happy path comes back from the #245 skip. It is the only end-to-end check that adding an item reaches the database rather than merely firing a toast, and it passed both full parallel runs and in isolation. filters.spec.ts:216 is deliberately untouched: its .find() searches CSS class names on a string array, not test data, and has no missing-row failure mode. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
100 lines
3.4 KiB
TypeScript
100 lines
3.4 KiB
TypeScript
import { test, expect, createItem, uniqueSuffix, findOrFail } from './fixtures';
|
|
|
|
test.describe('Disabling a customer account', () => {
|
|
test('an admin can disable an account and the customer is told at sign-in', async ({
|
|
page,
|
|
customer,
|
|
admin,
|
|
adminCustomers,
|
|
authModal
|
|
}) => {
|
|
await admin.open('Customers');
|
|
await expect(adminCustomers.row(customer.email)).toBeVisible();
|
|
await expect(adminCustomers.status(customer.email, 'ACTIVE')).toBeVisible();
|
|
|
|
await adminCustomers.disable(customer.email);
|
|
await expect(page.getByText('Account disabled')).toBeVisible();
|
|
await expect(adminCustomers.status(customer.email, 'DISABLED')).toBeVisible();
|
|
|
|
// A generic credential error would send a real customer round the
|
|
// password-reset loop forever.
|
|
await authModal.gotoLogIn();
|
|
await authModal.logIn(customer.email, customer.password);
|
|
await expect(page.getByText(/disabled/i)).toBeVisible();
|
|
});
|
|
|
|
test('an existing session stops working immediately', async ({
|
|
page,
|
|
request,
|
|
customer,
|
|
accountModal
|
|
}) => {
|
|
// Still signed in from registration, in this same browser context.
|
|
await accountModal.open();
|
|
await expect(accountModal.emailText(customer.email)).toBeVisible();
|
|
|
|
const customers = await (await request.get('/api/admin/customers')).json();
|
|
const id = findOrFail(
|
|
customers,
|
|
(c: { email: string }) => c.email === customer.email,
|
|
`the customer ${customer.email}`
|
|
).id;
|
|
await request.post(`/api/admin/customers/${id}/disable`);
|
|
|
|
// The cookie is unchanged, so this proves the server rejects it rather
|
|
// than the browser having discarded it.
|
|
await page.goto('/account');
|
|
await expect(page).toHaveURL(/\/login/);
|
|
});
|
|
|
|
test('re-enabling restores sign-in', async ({
|
|
page,
|
|
request,
|
|
customer,
|
|
admin,
|
|
adminCustomers,
|
|
authModal,
|
|
header
|
|
}) => {
|
|
const customers = await (await request.get('/api/admin/customers')).json();
|
|
const id = findOrFail(
|
|
customers,
|
|
(c: { email: string }) => c.email === customer.email,
|
|
`the customer ${customer.email}`
|
|
).id;
|
|
await request.post(`/api/admin/customers/${id}/disable`);
|
|
|
|
await admin.open('Customers');
|
|
await expect(adminCustomers.row(customer.email)).toBeVisible();
|
|
await adminCustomers.reEnable(customer.email);
|
|
await expect(page.getByText('Account re-enabled')).toBeVisible();
|
|
|
|
await authModal.gotoLogIn();
|
|
await authModal.logIn(customer.email, customer.password);
|
|
await header.waitForSignedIn();
|
|
});
|
|
|
|
test('the confirmation warns that held items will be released', async ({
|
|
page,
|
|
request,
|
|
customer,
|
|
admin,
|
|
adminCustomers
|
|
}) => {
|
|
const item = await createItem(request, { name: `Held ${uniqueSuffix()}`, price: '40' });
|
|
expect((await page.request.post(`/api/cart/items/${item.id}`)).status()).toBe(201);
|
|
|
|
await admin.open('Customers');
|
|
await expect(adminCustomers.row(customer.email)).toBeVisible();
|
|
await adminCustomers.disableButton(customer.email).click();
|
|
|
|
// The consequence has to be visible at the moment of the decision.
|
|
await expect(page.getByText(/1 reserved item/)).toBeVisible();
|
|
await adminCustomers.confirmDialog.getByRole('button', { name: 'Disable' }).click();
|
|
await expect(page.getByText('Account disabled')).toBeVisible();
|
|
|
|
const released = await (await request.get(`/api/items/${item.id}`)).json();
|
|
expect(released.status).toBe('available');
|
|
});
|
|
});
|