feat(admin): rename series route and add tags review page
Rename /admin/series-management to /admin/series so it follows the /admin/<section> convention; the breadcrumb's auto-derived parent link is now a real route (was a dead /admin/series link). Add an /admin/tags page to review pending TagSuggestions — list, approve (creates the Tag), reject — backed by new admin endpoints and a tagSuggestionReviewSchema. Resolves the dead /admin/tags alert link.
This commit is contained in:
parent
7beb86b430
commit
151481f1ec
9 changed files with 358 additions and 9 deletions
|
|
@ -2,7 +2,7 @@ import { test, expect } from './helpers/fixtures.js'
|
|||
|
||||
test.describe('Admin series management page', () => {
|
||||
test('series list loads for admin', async ({ adminPage }) => {
|
||||
await adminPage.goto('/admin/series-management')
|
||||
await adminPage.goto('/admin/series')
|
||||
await expect(adminPage.getByRole('heading', { name: 'Series', level: 1 })).toBeVisible({
|
||||
timeout: 15000,
|
||||
})
|
||||
|
|
@ -12,9 +12,9 @@ test.describe('Admin series management page', () => {
|
|||
|
||||
test.describe('Admin series access control', () => {
|
||||
test('non-admin redirect', async ({ page }) => {
|
||||
await page.goto('/admin/series-management')
|
||||
await page.goto('/admin/series')
|
||||
await page.waitForURL((url) => !url.pathname.startsWith('/admin'))
|
||||
expect(page.url()).not.toContain('/admin/series-management')
|
||||
expect(page.url()).not.toContain('/admin/series')
|
||||
})
|
||||
})
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ test.describe('Admin series CRUD', () => {
|
|||
|
||||
await adminPage.getByRole('button', { name: 'Create Series' }).click()
|
||||
|
||||
await adminPage.waitForURL('**/admin/series-management', { timeout: 15000 })
|
||||
await adminPage.waitForURL('**/admin/series', { timeout: 15000 })
|
||||
|
||||
const card = adminPage.locator('.series-card', { hasText: title })
|
||||
await expect(card).toBeVisible({ timeout: 10000 })
|
||||
|
|
|
|||
57
e2e/admin-tags.spec.js
Normal file
57
e2e/admin-tags.spec.js
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
import { test, expect } from './helpers/fixtures.js'
|
||||
|
||||
test.describe('Admin tags page', () => {
|
||||
test('page loads for admin', async ({ adminPage }) => {
|
||||
await adminPage.goto('/admin/tags')
|
||||
await expect(adminPage.getByRole('heading', { name: 'Tags', level: 1 })).toBeVisible({
|
||||
timeout: 15000,
|
||||
})
|
||||
})
|
||||
|
||||
test('approve and reject pending suggestions', async ({ adminPage }) => {
|
||||
const suffix = Date.now().toString().slice(-6)
|
||||
const approveLabel = `e2e-tag-approve-${suffix}`
|
||||
const rejectLabel = `e2e-tag-reject-${suffix}`
|
||||
|
||||
// Load the page first so the csrf-token cookie is set, then seed two
|
||||
// pending suggestions via the authed member endpoint (state-changing
|
||||
// requests require the double-submit CSRF header — see middleware/01.csrf.js).
|
||||
await adminPage.goto('/admin/tags')
|
||||
const cookies = await adminPage.context().cookies()
|
||||
const csrf = cookies.find((c) => c.name === 'csrf-token')?.value
|
||||
|
||||
await adminPage.request.post('/api/tags/suggest', {
|
||||
headers: { 'x-csrf-token': csrf },
|
||||
data: { label: approveLabel, pool: 'craft' },
|
||||
})
|
||||
await adminPage.request.post('/api/tags/suggest', {
|
||||
headers: { 'x-csrf-token': csrf },
|
||||
data: { label: rejectLabel, pool: 'cooperative' },
|
||||
})
|
||||
|
||||
await adminPage.reload()
|
||||
await adminPage.waitForLoadState('networkidle')
|
||||
|
||||
const approveRow = adminPage.locator('tr', { hasText: approveLabel })
|
||||
await expect(approveRow).toBeVisible({ timeout: 10000 })
|
||||
await approveRow.getByRole('button', { name: 'Approve' }).click()
|
||||
await expect(adminPage.locator('tr', { hasText: approveLabel })).toHaveCount(0, {
|
||||
timeout: 10000,
|
||||
})
|
||||
|
||||
const rejectRow = adminPage.locator('tr', { hasText: rejectLabel })
|
||||
await expect(rejectRow).toBeVisible()
|
||||
await rejectRow.getByRole('button', { name: 'Reject' }).click()
|
||||
await expect(adminPage.locator('tr', { hasText: rejectLabel })).toHaveCount(0, {
|
||||
timeout: 10000,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test.describe('Admin tags access control', () => {
|
||||
test('non-admin redirect', async ({ page }) => {
|
||||
await page.goto('/admin/tags')
|
||||
await page.waitForURL((url) => !url.pathname.startsWith('/admin'))
|
||||
expect(page.url()).not.toContain('/admin/tags')
|
||||
})
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue