feat: add functions to validate today's timestamps and update pending status logic
All checks were successful
Chore App Build, Test, and Push Docker Images / build-and-push (push) Successful in 2m20s

This commit is contained in:
2026-05-03 12:26:21 -04:00
parent ce3d1b3d54
commit 2e1a0ab2fa
4 changed files with 46 additions and 22 deletions

View File

@@ -2,20 +2,20 @@
"cookies": [ "cookies": [
{ {
"name": "refresh_token", "name": "refresh_token",
"value": "mY6Ehfjz0l0gIgI1-zrA_HMfYQiNmgnNy6g7v2GoT3M", "value": "pGEIC6CXp8cemhcGtW276YUSMY6zSzOVlhDL-bNhrYk",
"domain": "localhost", "domain": "localhost",
"path": "/api/auth", "path": "/api/auth",
"expires": 1785468152.319767, "expires": 1785601199.302565,
"httpOnly": true, "httpOnly": true,
"secure": true, "secure": true,
"sameSite": "Strict" "sameSite": "Strict"
}, },
{ {
"name": "access_token", "name": "access_token",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImUyZS1jY0B0ZXN0LmNvbSIsInVzZXJfaWQiOiI0YmI3ZTQ3ZS0wNGYxLTQyMDctYjZjYy0yNDM3NDVlOGQ0ZDMiLCJ0b2tlbl92ZXJzaW9uIjowLCJleHAiOjE3Nzc3MDI5NTJ9.614NMFQB7JcIJ4k4cqKyxlpcyHmt2Hn4PbjCbvLMJ2A", "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImUyZS1jY0B0ZXN0LmNvbSIsInVzZXJfaWQiOiJhNzljMGEzOS1jYmNlLTQzMmQtYTQ1Yy02YjY2N2Q5ZDg3ODMiLCJ0b2tlbl92ZXJzaW9uIjowLCJleHAiOjE3Nzc4MzU5OTl9.3Aucvm-BqEldAY3FG7Th2Y3-AEdUttqAMM6Z2wC56b8",
"domain": "localhost", "domain": "localhost",
"path": "/", "path": "/",
"expires": 1777702952.31857, "expires": 1777835999.301909,
"httpOnly": true, "httpOnly": true,
"secure": true, "secure": true,
"sameSite": "Lax" "sameSite": "Lax"
@@ -27,11 +27,11 @@
"localStorage": [ "localStorage": [
{ {
"name": "authSyncEvent", "name": "authSyncEvent",
"value": "{\"type\":\"logout\",\"at\":1777692151952}" "value": "{\"type\":\"logout\",\"at\":1777825199047}"
}, },
{ {
"name": "parentAuth", "name": "parentAuth",
"value": "{\"expiresAt\":1777864952730}" "value": "{\"expiresAt\":1777997999649}"
} }
] ]
} }

View File

@@ -2,20 +2,20 @@
"cookies": [ "cookies": [
{ {
"name": "refresh_token", "name": "refresh_token",
"value": "fmbL31vJQXFd7NDUWy7eGlRZZoGh0BZipf8CqFOb8zw", "value": "iFMh4JztGf12rfM3hYnVAxUTxCCaqvf8fXuNt4AcX5E",
"domain": "localhost", "domain": "localhost",
"path": "/api/auth", "path": "/api/auth",
"expires": 1785468152.214735, "expires": 1785601199.525198,
"httpOnly": true, "httpOnly": true,
"secure": true, "secure": true,
"sameSite": "Strict" "sameSite": "Strict"
}, },
{ {
"name": "access_token", "name": "access_token",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImUyZS1kZWxldGVAdGVzdC5jb20iLCJ1c2VyX2lkIjoiNzc2YjBkYjctYzYyNy00ODBiLTkzZDYtMTRlMTE4MDQ3NTE5IiwidG9rZW5fdmVyc2lvbiI6MCwiZXhwIjoxNzc3NzAyOTUyfQ.I4sfKTo0nsJgKvwDRSztxtyZpWw-oN1y3L4yCtr_CRo", "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImUyZS1kZWxldGVAdGVzdC5jb20iLCJ1c2VyX2lkIjoiNjMwMjY4MzMtOTMwYi00Y2Y4LThkMWQtNGRmYmM4YjZhNDNiIiwidG9rZW5fdmVyc2lvbiI6MCwiZXhwIjoxNzc3ODM1OTk5fQ.puE7cpjjfxckURcACEIQRDTdySwJm0gaIwKPAoeg6e4",
"domain": "localhost", "domain": "localhost",
"path": "/", "path": "/",
"expires": 1777702952.21406, "expires": 1777835999.524669,
"httpOnly": true, "httpOnly": true,
"secure": true, "secure": true,
"sameSite": "Lax" "sameSite": "Lax"
@@ -27,11 +27,11 @@
"localStorage": [ "localStorage": [
{ {
"name": "authSyncEvent", "name": "authSyncEvent",
"value": "{\"type\":\"logout\",\"at\":1777692151844}" "value": "{\"type\":\"logout\",\"at\":1777825199229}"
}, },
{ {
"name": "parentAuth", "name": "parentAuth",
"value": "{\"expiresAt\":1777864952556}" "value": "{\"expiresAt\":1777997999821}"
} }
] ]
} }

View File

@@ -2,20 +2,20 @@
"cookies": [ "cookies": [
{ {
"name": "refresh_token", "name": "refresh_token",
"value": "YitpHdwm093Mavj6iTYmJOLGLOIKoozGkmYXgmJMTBM", "value": "o8DJDh2Vlh2aC6VLSIEdO9pY74AceX8kLDiBhzyJ1i4",
"domain": "localhost", "domain": "localhost",
"path": "/api/auth", "path": "/api/auth",
"expires": 1785468147.453462, "expires": 1785601195.078177,
"httpOnly": true, "httpOnly": true,
"secure": true, "secure": true,
"sameSite": "Strict" "sameSite": "Strict"
}, },
{ {
"name": "access_token", "name": "access_token",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImUyZUB0ZXN0LmNvbSIsInVzZXJfaWQiOiI4ZGNmOWU5Ni1lM2I3LTRkNzYtOWQ1NS01NmE4MjU5ZWQ5NzUiLCJ0b2tlbl92ZXJzaW9uIjowLCJleHAiOjE3Nzc3MDI5NDd9.zSetTnajvus3N5uJDBqxRYXfLksoU9ZmkWzqCS0GUvc", "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImUyZUB0ZXN0LmNvbSIsInVzZXJfaWQiOiI5OWQwMzUxZC03YTg1LTQ4ZDUtOTgzZC01YWJlZTMxOGFhZDMiLCJ0b2tlbl92ZXJzaW9uIjowLCJleHAiOjE3Nzc4MzU5OTV9.QKaquZmzjFHwx08IgGVCyrQeBw2M5-8yVKc30_b9GFM",
"domain": "localhost", "domain": "localhost",
"path": "/", "path": "/",
"expires": 1777702947.452943, "expires": 1777835995.077514,
"httpOnly": true, "httpOnly": true,
"secure": true, "secure": true,
"sameSite": "Lax" "sameSite": "Lax"
@@ -27,11 +27,11 @@
"localStorage": [ "localStorage": [
{ {
"name": "authSyncEvent", "name": "authSyncEvent",
"value": "{\"type\":\"logout\",\"at\":1777692147220}" "value": "{\"type\":\"logout\",\"at\":1777825194855}"
}, },
{ {
"name": "parentAuth", "name": "parentAuth",
"value": "{\"expiresAt\":1777864947663}" "value": "{\"expiresAt\":1777997995266}"
} }
] ]
} }

View File

@@ -45,6 +45,28 @@ async function openEditModal(page: Page, card: Locator): Promise<void> {
await expect(page.getByRole('button', { name: 'Save' })).toBeVisible() await expect(page.getByRole('button', { name: 'Save' })).toBeVisible()
} }
async function seedPendingReward(
request: APIRequestContext,
childId: string,
rewardId: string,
rewardCost: number,
): Promise<void> {
await request.put(`/api/child/${childId}/edit`, { data: { points: rewardCost } })
const requestResp = await request.post(`/api/child/${childId}/request-reward`, {
data: { reward_id: rewardId },
})
if (requestResp.status() === 409) {
await request.post(`/api/child/${childId}/cancel-request-reward`, {
data: { reward_id: rewardId },
})
await request.post(`/api/child/${childId}/request-reward`, {
data: { reward_id: rewardId },
})
}
}
test.describe('Reward edit cost', () => { test.describe('Reward edit cost', () => {
test.describe.configure({ mode: 'serial' }) test.describe.configure({ mode: 'serial' })
@@ -172,9 +194,8 @@ test.describe('Reward edit cost', () => {
page, page,
request, request,
}) => { }) => {
// Give child enough points to satisfy the original reward cost, then create a pending request // Ensure a fresh pending request exists for this test.
await request.put(`/api/child/${childId}/edit`, { data: { points: REWARD_COST } }) await seedPendingReward(request, childId, rewardId, REWARD_COST)
await request.post(`/api/child/${childId}/request-reward`, { data: { reward_id: rewardId } })
await page.goto(`/parent/${childId}`) await page.goto(`/parent/${childId}`)
const card = rewardSection(page).locator('.item-card').filter({ hasText: REWARD_NAME }) const card = rewardSection(page).locator('.item-card').filter({ hasText: REWARD_NAME })
@@ -197,8 +218,11 @@ test.describe('Reward edit cost', () => {
test('Editing a pending reward — confirming the warning opens the override modal', async ({ test('Editing a pending reward — confirming the warning opens the override modal', async ({
page, page,
request,
}) => { }) => {
// Pending state was established in the previous test; navigate fresh // Seed pending state in this test to avoid cross-test coupling.
await seedPendingReward(request, childId, rewardId, REWARD_COST)
await page.goto(`/parent/${childId}`) await page.goto(`/parent/${childId}`)
const card = rewardSection(page).locator('.item-card').filter({ hasText: REWARD_NAME }) const card = rewardSection(page).locator('.item-card').filter({ hasText: REWARD_NAME })
await card.waitFor({ state: 'visible' }) await card.waitFor({ state: 'visible' })