This commit is contained in:
@@ -33,7 +33,15 @@ async function save() {
|
|||||||
message.value = '';
|
message.value = '';
|
||||||
error.value = '';
|
error.value = '';
|
||||||
try {
|
try {
|
||||||
Object.assign(settings, await updateAdminSettings(settings, csrfToken()));
|
const payload = {
|
||||||
|
...settings,
|
||||||
|
general: {
|
||||||
|
...settings.general,
|
||||||
|
publicContactEmail: settings.general.publicContactEmail || undefined,
|
||||||
|
publicContactPhone: settings.general.publicContactPhone || undefined,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
Object.assign(settings, await updateAdminSettings(payload, csrfToken()));
|
||||||
message.value = 'Settings saved.';
|
message.value = 'Settings saved.';
|
||||||
} catch (requestError) {
|
} catch (requestError) {
|
||||||
error.value = requestError.message;
|
error.value = requestError.message;
|
||||||
|
|||||||
@@ -4,7 +4,10 @@ async function request(path, options = {}) {
|
|||||||
const response = await fetch(`${apiBaseUrl}${path}`, {
|
const response = await fetch(`${apiBaseUrl}${path}`, {
|
||||||
credentials: 'include',
|
credentials: 'include',
|
||||||
...options,
|
...options,
|
||||||
headers: { 'content-type': 'application/json', ...options.headers },
|
headers: {
|
||||||
|
...(options.body ? { 'content-type': 'application/json' } : {}),
|
||||||
|
...options.headers,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
const payload = await response.json().catch(() => null);
|
const payload = await response.json().catch(() => null);
|
||||||
if (!response.ok) throw new Error(payload?.error?.message ?? 'Saved view request failed.');
|
if (!response.ok) throw new Error(payload?.error?.message ?? 'Saved view request failed.');
|
||||||
|
|||||||
@@ -179,3 +179,41 @@ test("signs in and publishes a listing after adding an inventory image", async (
|
|||||||
.getByText(`${createdInventoryId} · ACTIVE`),
|
.getByText(`${createdInventoryId} · ACTIVE`),
|
||||||
).toBeVisible();
|
).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("manages settings, saved views, and export controls", async ({ page }) => {
|
||||||
|
const email = process.env.INITIAL_ADMIN_EMAIL;
|
||||||
|
const password = process.env.INITIAL_ADMIN_PASSWORD;
|
||||||
|
|
||||||
|
test.skip(
|
||||||
|
!email || !password,
|
||||||
|
"Set INITIAL_ADMIN_EMAIL and INITIAL_ADMIN_PASSWORD for the local authenticated workflow.",
|
||||||
|
);
|
||||||
|
|
||||||
|
await page.goto("/login");
|
||||||
|
await page.getByLabel("Email").fill(email);
|
||||||
|
await page.getByLabel("Password").fill(password);
|
||||||
|
await page.getByRole("button", { name: "Sign in" }).click();
|
||||||
|
await expect(page).toHaveURL(/\/admin$/);
|
||||||
|
await expect(
|
||||||
|
page.getByRole("link", { name: "Download inventory JSON" }),
|
||||||
|
).toHaveAttribute("download", "inventory.json");
|
||||||
|
|
||||||
|
await page.goto("/admin/settings");
|
||||||
|
await expect(page.getByRole("heading", { name: "Settings" })).toBeVisible();
|
||||||
|
await page.getByLabel("Maximum images per item").fill("12");
|
||||||
|
await page.getByRole("button", { name: "Save settings" }).click();
|
||||||
|
await expect(page.getByRole("status")).toContainText("Settings saved.");
|
||||||
|
|
||||||
|
await page.goto("/admin/saved-views");
|
||||||
|
await expect(
|
||||||
|
page.getByRole("heading", { name: "Saved views", exact: true }),
|
||||||
|
).toBeVisible();
|
||||||
|
const viewName = `Browser view ${Date.now()}`;
|
||||||
|
await page.getByLabel("Name").fill(viewName);
|
||||||
|
await page.getByLabel("Filters (JSON)").fill('{"status":"ACTIVE"}');
|
||||||
|
await page.getByRole("button", { name: "Save view" }).click();
|
||||||
|
const savedView = page.getByRole("listitem").filter({ hasText: viewName });
|
||||||
|
await expect(savedView).toBeVisible();
|
||||||
|
await savedView.getByRole("button", { name: "Delete" }).click();
|
||||||
|
await expect(savedView).toHaveCount(0);
|
||||||
|
});
|
||||||
|
|||||||
@@ -159,6 +159,7 @@ Remaining roadmap areas are approved external provider credentials/adapters, bro
|
|||||||
- Completed asynchronous inventory JSON exports can be downloaded through `GET /api/v1/admin/exports/jobs/:id/download`.
|
- Completed asynchronous inventory JSON exports can be downloaded through `GET /api/v1/admin/exports/jobs/:id/download`.
|
||||||
- PostgreSQL restore verification and image snapshot restore scripts are implemented and covered by shell tests as part of the deployment drill workflow.
|
- PostgreSQL restore verification and image snapshot restore scripts are implemented and covered by shell tests as part of the deployment drill workflow.
|
||||||
- `npm audit --omit=dev` currently reports zero production vulnerabilities. Re-run the audit after dependency changes and review development-dependency findings separately before production releases.
|
- `npm audit --omit=dev` currently reports zero production vulnerabilities. Re-run the audit after dependency changes and review development-dependency findings separately before production releases.
|
||||||
|
- Authenticated E2E coverage now verifies both the core catalog workflow and the Settings, Saved Views, and export-controls workflow.
|
||||||
|
|
||||||
## Local Commands
|
## Local Commands
|
||||||
|
|
||||||
|
|||||||
@@ -69,6 +69,10 @@ Core workflows:
|
|||||||
9. Record sale
|
9. Record sale
|
||||||
10. View dashboard
|
10. View dashboard
|
||||||
|
|
||||||
|
The authenticated browser suite currently covers the core catalog workflow and
|
||||||
|
the Settings, Saved Views, and export-controls workflow. Both require the local
|
||||||
|
admin credentials and services described in the repository setup docs.
|
||||||
|
|
||||||
## Accessibility
|
## Accessibility
|
||||||
|
|
||||||
Run automated accessibility checks and maintain manual keyboard/assistive technology coverage for critical workflows.
|
Run automated accessibility checks and maintain manual keyboard/assistive technology coverage for critical workflows.
|
||||||
|
|||||||
Reference in New Issue
Block a user