Refactored frontend directory
Some checks failed
Chore App Build, Test, and Push Docker Images / build-and-push (push) Failing after 2m46s
Some checks failed
Chore App Build, Test, and Push Docker Images / build-and-push (push) Failing after 2m46s
This commit is contained in:
@@ -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)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user