Refactored frontend directory
Some checks failed
Chore App Build, Test, and Push Docker Images / build-and-push (push) Failing after 2m46s

This commit is contained in:
2026-04-25 00:40:15 -04:00
parent db846f4e31
commit 127378797c
263 changed files with 88 additions and 79 deletions

View File

@@ -0,0 +1,86 @@
// spec: e2e/plans/parent-notifications.plan.md §1
import { test, expect, type Page } from '@playwright/test'
function pushToggle(page: Page) {
return page
.locator('.toggle-field-row')
.filter({ has: page.locator('.toggle-field-label', { hasText: 'Push Notifications' }) })
.locator('button.toggle-btn')
}
test.describe('Push subscription registration', () => {
// -------------------------------------------------------------------------
// 1.3 No subscription POST when notification permission not granted
// -------------------------------------------------------------------------
test('No subscription POST is sent when notification permission is not granted', async ({
page,
}) => {
// Do NOT grant notifications permission
let postCaptured = false
await page.route('**/api/push-subscription', async (route) => {
if (route.request().method() === 'POST') {
postCaptured = true
}
await route.continue()
})
await page.goto('/parent/profile')
const toggle = pushToggle(page)
await expect(toggle).toBeVisible({ timeout: 5000 })
const isDisabled = await toggle.isDisabled().catch(() => false)
if (!isDisabled) {
// Try to click the toggle — it may prompt for permission but deny it
await toggle.click().catch(() => {})
await page
.getByRole('button', { name: 'Save' })
.click()
.catch(() => {})
await page.waitForTimeout(1000)
}
expect(postCaptured).toBe(false)
})
// -------------------------------------------------------------------------
// 1.4 Backend rejects unauthenticated subscription POST (401)
// -------------------------------------------------------------------------
test('Backend rejects unauthenticated subscription POST with 401', async ({ page }) => {
// Navigate first, then use credentials:'omit' to strip cookies and verify
// the backend enforces auth.
await page.goto('/parent/profile')
const status = await page.evaluate(async () => {
const res = await fetch('/api/push-subscription', {
method: 'POST',
credentials: 'omit',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
endpoint: 'https://fcm.googleapis.com/fcm/send/fake-endpoint',
keys: { p256dh: 'fake-key', auth: 'fake-auth' },
}),
})
return res.status
})
expect(status).toBe(401)
})
// -------------------------------------------------------------------------
// 1.5 Backend rejects unauthenticated subscription DELETE (401)
// -------------------------------------------------------------------------
test('Backend rejects unauthenticated subscription DELETE with 401', async ({ page }) => {
await page.goto('/parent/profile')
const status = await page.evaluate(async () => {
const res = await fetch('/api/push-subscription', {
method: 'DELETE',
credentials: 'omit',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
endpoint: 'https://fcm.googleapis.com/fcm/send/fake-endpoint',
}),
})
return res.status
})
expect(status).toBe(401)
})
})