/** * Moderation Approval Flow E2E Tests * * Tests the complete submission approval process. */ import { test, expect } from '@playwright/test'; import { ModerationQueuePage } from '../../helpers/page-objects/ModerationQueuePage'; import { ParkCreationPage } from '../../helpers/page-objects/ParkCreationPage'; import { generateParkData, generateTestId } from '../../fixtures/test-data'; import { queryDatabase, cleanupTestData, waitForVersion } from '../../fixtures/database'; test.describe('Submission Approval Flow', () => { test.afterAll(async () => { await cleanupTestData(); }); test('should approve park submission and create entity', async ({ browser }) => { // Step 1: Create submission as regular user const userContext = await browser.newContext({ storageState: '.auth/user.json' }); const userPage = await userContext.newPage(); const parkData = generateParkData({ name: `Test Park ${generateTestId()}`, }); const parkCreationPage = new ParkCreationPage(userPage); await parkCreationPage.goto(); await parkCreationPage.fillBasicInfo(parkData.name, parkData.description); await parkCreationPage.submitForm(); await parkCreationPage.expectSuccess(); await userContext.close(); // Step 2: Approve as moderator const modContext = await browser.newContext({ storageState: '.auth/moderator.json' }); const modPage = await modContext.newPage(); const moderationPage = new ModerationQueuePage(modPage); await moderationPage.goto(); // Find the submission await moderationPage.expectSubmissionVisible(parkData.name); // Claim it await moderationPage.claimSubmission(0); // Approve it await moderationPage.approveSubmission('Looks good!'); // Step 3: Verify entity created in database await modPage.waitForTimeout(2000); // Give DB time to process const parks = await queryDatabase('parks', (qb) => qb.select('*').eq('name', parkData.name) ); expect(parks).toHaveLength(1); expect(parks[0].is_test_data).toBe(true); // Step 4: Verify version created const versions = await queryDatabase('park_versions', (qb) => qb.select('*').eq('park_id', parks[0].id).eq('version_number', 1) ); expect(versions).toHaveLength(1); expect(versions[0].change_type).toBe('created'); // Step 5: Verify submission marked as approved const submissions = await queryDatabase('content_submissions', (qb) => qb.select('*').eq('entity_type', 'park').contains('submission_data', { name: parkData.name }) ); expect(submissions[0].status).toBe('approved'); expect(submissions[0].approved_by).toBeTruthy(); expect(submissions[0].approved_at).toBeTruthy(); // Step 6: Verify lock released expect(submissions[0].assigned_to).toBeNull(); expect(submissions[0].locked_until).toBeNull(); await modContext.close(); }); test('should show change comparison for edits', async ({ browser }) => { // This test would require: // 1. Creating and approving a park // 2. Editing the park // 3. Viewing the edit in moderation queue // 4. Verifying change comparison displays // Left as TODO - requires more complex setup }); test('should send notification to submitter on approval', async ({ browser }) => { // This test would verify that Novu notification is sent // Left as TODO - requires Novu testing setup }); test('should prevent approval without lock', async ({ browser }) => { // Create submission as user const userContext = await browser.newContext({ storageState: '.auth/user.json' }); const userPage = await userContext.newPage(); const parkData = generateParkData({ name: `Test Park ${generateTestId()}`, }); const parkCreationPage = new ParkCreationPage(userPage); await parkCreationPage.goto(); await parkCreationPage.fillBasicInfo(parkData.name, parkData.description); await parkCreationPage.submitForm(); await parkCreationPage.expectSuccess(); await userContext.close(); // Try to approve as moderator WITHOUT claiming const modContext = await browser.newContext({ storageState: '.auth/moderator.json' }); const modPage = await modContext.newPage(); const moderationPage = new ModerationQueuePage(modPage); await moderationPage.goto(); // Approve button should be disabled or not visible const approveButton = modPage.locator('button:has-text("Approve")').first(); await expect(approveButton).toBeDisabled(); await modContext.close(); }); }); test.describe('Bulk Approval', () => { test('should approve all items in submission', async ({ browser }) => { // TODO: Test approving all submission items at once }); test('should allow selective item approval', async ({ browser }) => { // TODO: Test approving only specific items from a submission }); });