feat: update reward version to 1.0.13 and modify dialog button labels for clarity
All checks were successful
Chore App Build, Test, and Push Docker Images / build-and-push (push) Successful in 2m31s

This commit is contained in:
2026-05-01 23:32:17 -04:00
parent e77254eabf
commit 8308d205e8
12 changed files with 223 additions and 93 deletions

View File

@@ -2,20 +2,20 @@
"cookies": [
{
"name": "refresh_token",
"value": "FZULMCV2SqB1TurS_72i4vCGjYXmL4rQzTvtKFODS-c",
"value": "mY6Ehfjz0l0gIgI1-zrA_HMfYQiNmgnNy6g7v2GoT3M",
"domain": "localhost",
"path": "/api/auth",
"expires": 1784993494.828813,
"expires": 1785468152.319767,
"httpOnly": true,
"secure": true,
"sameSite": "Strict"
},
{
"name": "access_token",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImUyZS1jY0B0ZXN0LmNvbSIsInVzZXJfaWQiOiJiMTkyZDgzZS1mMTQyLTRhZjQtYjAyNC02YzdiNzFmNzFlYjYiLCJ0b2tlbl92ZXJzaW9uIjowLCJleHAiOjE3NzcyMTgzOTR9.7JsdzTZDZd8qErp-GiAaYfU92jCb1L5ROGZXpEaz-dc",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImUyZS1jY0B0ZXN0LmNvbSIsInVzZXJfaWQiOiI0YmI3ZTQ3ZS0wNGYxLTQyMDctYjZjYy0yNDM3NDVlOGQ0ZDMiLCJ0b2tlbl92ZXJzaW9uIjowLCJleHAiOjE3Nzc3MDI5NTJ9.614NMFQB7JcIJ4k4cqKyxlpcyHmt2Hn4PbjCbvLMJ2A",
"domain": "localhost",
"path": "/",
"expires": 1777218394.827404,
"expires": 1777702952.31857,
"httpOnly": true,
"secure": true,
"sameSite": "Lax"
@@ -27,13 +27,13 @@
"localStorage": [
{
"name": "authSyncEvent",
"value": "{\"type\":\"logout\",\"at\":1777217494503}"
"value": "{\"type\":\"logout\",\"at\":1777692151952}"
},
{
"name": "parentAuth",
"value": "{\"expiresAt\":1777390295394}"
"value": "{\"expiresAt\":1777864952730}"
}
]
}
]
}
}

View File

@@ -2,20 +2,20 @@
"cookies": [
{
"name": "refresh_token",
"value": "tTh7qrpLh9RjQNVxmjhfQi0VOQwbLa4PJ8xfjlMC9P8",
"value": "fmbL31vJQXFd7NDUWy7eGlRZZoGh0BZipf8CqFOb8zw",
"domain": "localhost",
"path": "/api/auth",
"expires": 1784993494.703215,
"expires": 1785468152.214735,
"httpOnly": true,
"secure": true,
"sameSite": "Strict"
},
{
"name": "access_token",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImUyZS1kZWxldGVAdGVzdC5jb20iLCJ1c2VyX2lkIjoiMGY4YzE2YzUtN2ZlNy00ZGZiLWE4ZmMtMTc3NjQ5MDkxOWI4IiwidG9rZW5fdmVyc2lvbiI6MCwiZXhwIjoxNzc3MjE4Mzk0fQ.zSLSZsWZb9N1En9mWCqXxM9d__U7JldwT8pCKaoxzUc",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImUyZS1kZWxldGVAdGVzdC5jb20iLCJ1c2VyX2lkIjoiNzc2YjBkYjctYzYyNy00ODBiLTkzZDYtMTRlMTE4MDQ3NTE5IiwidG9rZW5fdmVyc2lvbiI6MCwiZXhwIjoxNzc3NzAyOTUyfQ.I4sfKTo0nsJgKvwDRSztxtyZpWw-oN1y3L4yCtr_CRo",
"domain": "localhost",
"path": "/",
"expires": 1777218394.702339,
"expires": 1777702952.21406,
"httpOnly": true,
"secure": true,
"sameSite": "Lax"
@@ -27,13 +27,13 @@
"localStorage": [
{
"name": "authSyncEvent",
"value": "{\"type\":\"logout\",\"at\":1777217494445}"
"value": "{\"type\":\"logout\",\"at\":1777692151844}"
},
{
"name": "parentAuth",
"value": "{\"expiresAt\":1777390295182}"
"value": "{\"expiresAt\":1777864952556}"
}
]
}
]
}
}

View File

@@ -2,20 +2,20 @@
"cookies": [
{
"name": "refresh_token",
"value": "iBgMbKeAn8p8X9iS6eumIZHEqKN0yqMKZ09V6nk7s-U",
"value": "YitpHdwm093Mavj6iTYmJOLGLOIKoozGkmYXgmJMTBM",
"domain": "localhost",
"path": "/api/auth",
"expires": 1784993490.715252,
"expires": 1785468147.453462,
"httpOnly": true,
"secure": true,
"sameSite": "Strict"
},
{
"name": "access_token",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImUyZUB0ZXN0LmNvbSIsInVzZXJfaWQiOiJhM2ZlZjRmNS01MTc4LTRlYWEtOWU0NC1jZjk2MGJiMGQ3ZTkiLCJ0b2tlbl92ZXJzaW9uIjowLCJleHAiOjE3NzcyMTgzOTB9.PtdzVvtN6rMWPOTS6OfGc8tVSrihktnT2GhVIwKollc",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImUyZUB0ZXN0LmNvbSIsInVzZXJfaWQiOiI4ZGNmOWU5Ni1lM2I3LTRkNzYtOWQ1NS01NmE4MjU5ZWQ5NzUiLCJ0b2tlbl92ZXJzaW9uIjowLCJleHAiOjE3Nzc3MDI5NDd9.zSetTnajvus3N5uJDBqxRYXfLksoU9ZmkWzqCS0GUvc",
"domain": "localhost",
"path": "/",
"expires": 1777218390.714722,
"expires": 1777702947.452943,
"httpOnly": true,
"secure": true,
"sameSite": "Lax"
@@ -27,13 +27,13 @@
"localStorage": [
{
"name": "authSyncEvent",
"value": "{\"type\":\"logout\",\"at\":1777217490520}"
"value": "{\"type\":\"logout\",\"at\":1777692147220}"
},
{
"name": "parentAuth",
"value": "{\"expiresAt\":1777390290893}"
"value": "{\"expiresAt\":1777864947663}"
}
]
}
]
}
}

View File

@@ -108,8 +108,8 @@ test.describe('Reward Notification — In-App Denial', () => {
await expect(card).toHaveClass(/item-ready/, { timeout: 3000 })
await card.click()
// Look for a Deny button in the dialog
const denyBtn = page.getByRole('button', { name: /deny/i })
// Look for the reject action in the dialog
const denyBtn = page.getByRole('button', { name: 'Reject', exact: true })
await expect(denyBtn).toBeVisible({ timeout: 5000 })
await denyBtn.click()
await expect(denyBtn).not.toBeVisible({ timeout: 5000 })
@@ -127,7 +127,7 @@ test.describe('Reward Notification — In-App Denial', () => {
await card.click()
await expect(card).toHaveClass(/item-ready/, { timeout: 3000 })
await card.click()
const denyBtn = page.getByRole('button', { name: /deny/i })
const denyBtn = page.getByRole('button', { name: 'Reject', exact: true })
await expect(denyBtn).toBeVisible({ timeout: 5000 })
await denyBtn.click()
await expect(denyBtn).not.toBeVisible({ timeout: 5000 })

View File

@@ -59,7 +59,9 @@ async function createReward(
for (const r of (await pre.json()).rewards ?? []) {
if (r.name === name) await request.delete(`/api/reward/${r.id}`)
}
await request.put('/api/reward/add', { data: { name, description: 'E2E pending-warn test', cost } })
await request.put('/api/reward/add', {
data: { name, description: 'E2E pending-warn test', cost },
})
const list = await request.get('/api/reward/list')
return (await list.json()).rewards?.find((r: any) => r.name === name)?.id ?? ''
}
@@ -160,9 +162,7 @@ test.describe('Pending reward warning dialog', () => {
test('Pending reward card shows PENDING banner', async ({ page }) => {
await page.goto(`/parent/${childId}`)
const card = rewardSection(page)
.locator('.item-card')
.filter({ hasText: PENDING_REWARD_NAME })
const card = rewardSection(page).locator('.item-card').filter({ hasText: PENDING_REWARD_NAME })
await card.waitFor({ state: 'visible' })
await expect(card.locator('.pending')).toHaveText('PENDING')
})
@@ -177,12 +177,12 @@ test.describe('Pending reward warning dialog', () => {
await activateItem(card)
// Pending reward warning dialog appears (has a "No" button)
await expect(page.getByRole('button', { name: 'No', exact: true })).toBeVisible()
await page.getByRole('button', { name: 'No', exact: true }).click()
// Pending reward warning dialog appears
await expect(page.getByRole('button', { name: 'Reject', exact: true })).toBeVisible()
await page.getByRole('button', { name: 'Reject', exact: true }).click()
// Dialog dismissed; task confirmation dialog must NOT have appeared
await expect(page.getByRole('button', { name: 'No', exact: true })).not.toBeVisible()
await expect(page.getByRole('button', { name: 'Reject', exact: true })).not.toBeVisible()
await expect(page.getByRole('button', { name: 'Cancel' })).not.toBeVisible()
// Points unchanged
await expect(page.locator('.points .value')).toHaveText(String(pointsBefore))
@@ -204,8 +204,8 @@ test.describe('Pending reward warning dialog', () => {
await activateItem(card)
// Pending reward warning dialog
await expect(page.getByRole('button', { name: 'No', exact: true })).toBeVisible()
await page.getByRole('button', { name: 'Yes' }).click()
await expect(page.getByRole('button', { name: 'Reject', exact: true })).toBeVisible()
await page.getByRole('button', { name: 'Approve', exact: true }).click()
// After confirming, the task confirmation dialog appears (has "Cancel" button)
await expect(page.getByRole('button', { name: 'Cancel' })).toBeVisible({ timeout: 3000 })
@@ -219,7 +219,9 @@ test.describe('Pending reward warning dialog', () => {
// ── kindness ──────────────────────────────────────────────────────────────
test('Kindness activation — Cancel on pending dialog leaves state unchanged', async ({ page }) => {
test('Kindness activation — Cancel on pending dialog leaves state unchanged', async ({
page,
}) => {
await page.goto(`/parent/${childId}`)
const card = kindnessSection(page).locator('.item-card').filter({ hasText: KIND_NAME })
await card.waitFor({ state: 'visible' })
@@ -227,10 +229,10 @@ test.describe('Pending reward warning dialog', () => {
await activateItem(card)
await expect(page.getByRole('button', { name: 'No', exact: true })).toBeVisible()
await page.getByRole('button', { name: 'No', exact: true }).click()
await expect(page.getByRole('button', { name: 'Reject', exact: true })).toBeVisible()
await page.getByRole('button', { name: 'Reject', exact: true }).click()
await expect(page.getByRole('button', { name: 'No', exact: true })).not.toBeVisible()
await expect(page.getByRole('button', { name: 'Reject', exact: true })).not.toBeVisible()
await expect(page.getByRole('button', { name: 'Cancel' })).not.toBeVisible()
await expect(page.locator('.points .value')).toHaveText(String(pointsBefore))
})
@@ -245,8 +247,8 @@ test.describe('Pending reward warning dialog', () => {
await activateItem(card)
await expect(page.getByRole('button', { name: 'No', exact: true })).toBeVisible()
await page.getByRole('button', { name: 'Yes' }).click()
await expect(page.getByRole('button', { name: 'Reject', exact: true })).toBeVisible()
await page.getByRole('button', { name: 'Approve', exact: true }).click()
await expect(page.getByRole('button', { name: 'Cancel' })).toBeVisible({ timeout: 3000 })
await page.getByRole('button', { name: 'Yes' }).click()
@@ -266,10 +268,10 @@ test.describe('Pending reward warning dialog', () => {
await activateItem(card)
await expect(page.getByRole('button', { name: 'No', exact: true })).toBeVisible()
await page.getByRole('button', { name: 'No', exact: true }).click()
await expect(page.getByRole('button', { name: 'Reject', exact: true })).toBeVisible()
await page.getByRole('button', { name: 'Reject', exact: true }).click()
await expect(page.getByRole('button', { name: 'No', exact: true })).not.toBeVisible()
await expect(page.getByRole('button', { name: 'Reject', exact: true })).not.toBeVisible()
await expect(page.getByRole('button', { name: 'Cancel' })).not.toBeVisible()
await expect(page.locator('.points .value')).toHaveText(String(pointsBefore))
})
@@ -284,8 +286,8 @@ test.describe('Pending reward warning dialog', () => {
await activateItem(card)
await expect(page.getByRole('button', { name: 'No', exact: true })).toBeVisible()
await page.getByRole('button', { name: 'Yes' }).click()
await expect(page.getByRole('button', { name: 'Reject', exact: true })).toBeVisible()
await page.getByRole('button', { name: 'Approve', exact: true }).click()
await expect(page.getByRole('button', { name: 'Cancel' })).toBeVisible({ timeout: 3000 })
await page.getByRole('button', { name: 'Yes' }).click()
@@ -320,10 +322,10 @@ test.describe('Pending reward warning dialog', () => {
await activateItem(otherCard)
// Pending reward warning dialog appears when another reward has a pending request
await expect(page.getByRole('button', { name: 'No', exact: true })).toBeVisible()
await page.getByRole('button', { name: 'No', exact: true }).click()
await expect(page.getByRole('button', { name: 'Reject', exact: true })).toBeVisible()
await page.getByRole('button', { name: 'Reject', exact: true }).click()
await expect(page.getByRole('button', { name: 'No', exact: true })).not.toBeVisible()
await expect(page.getByRole('button', { name: 'Reject', exact: true })).not.toBeVisible()
await expect(page.getByRole('button', { name: 'Cancel' })).not.toBeVisible()
await expect(page.locator('.points .value')).toHaveText(String(pointsBefore))
// PENDING banner still visible — reward request was not cancelled
@@ -346,11 +348,11 @@ test.describe('Pending reward warning dialog', () => {
await activateItem(otherCard)
await expect(page.getByRole('button', { name: 'No', exact: true })).toBeVisible()
await page.getByRole('button', { name: 'Yes' }).click()
await expect(page.getByRole('button', { name: 'Reject', exact: true })).toBeVisible()
await page.getByRole('button', { name: 'Approve', exact: true }).click()
// Pending dialog closes; reward confirm does NOT auto-open (other reward must be re-clicked)
await expect(page.getByRole('button', { name: 'No', exact: true })).not.toBeVisible()
await expect(page.getByRole('button', { name: 'Reject', exact: true })).not.toBeVisible()
await expect(page.getByRole('button', { name: 'Cancel' })).not.toBeVisible()
// The pending reward request was cancelled — PENDING banner should disappear

View File

@@ -152,7 +152,7 @@ test.describe('Reward redemption', () => {
await activateItem(card)
await expect(page.getByRole('button', { name: 'Yes' })).toBeVisible()
await page.getByRole('button', { name: 'Cancel' }).click()
await page.getByRole('button', { name: 'No', exact: true }).click()
await expect(page.getByRole('button', { name: 'Yes' })).not.toBeVisible()
await expect(page.locator('.points .value')).toHaveText(String(before))

View File

@@ -187,11 +187,11 @@ test.describe('Reward edit cost', () => {
await card.getByTitle('Edit custom value').click()
// PendingRewardDialog should appear warning about the pending state
await expect(page.locator('.modal-message')).toContainText('pending')
await expect(page.getByText(/currently pending/i)).toBeVisible()
// Clicking "No" closes the dialog without opening the override modal
await page.getByRole('button', { name: 'No', exact: true }).click()
await expect(page.locator('.modal-message')).not.toBeVisible()
// Clicking "Reject" closes the dialog without opening the override modal
await page.getByRole('button', { name: 'Reject', exact: true }).click()
await expect(page.getByText(/currently pending/i)).not.toBeVisible()
await expect(page.getByRole('button', { name: 'Save' })).not.toBeVisible()
})
@@ -209,10 +209,10 @@ test.describe('Reward edit cost', () => {
await card.getByTitle('Edit custom value').click()
// PendingRewardDialog visible
await expect(page.locator('.modal-message')).toContainText('pending')
await expect(page.getByText(/currently pending/i)).toBeVisible()
// Confirming cancels the pending request and opens the override modal
await page.getByRole('button', { name: 'Yes' }).click()
await page.getByRole('button', { name: 'Approve', exact: true }).click()
await expect(page.getByRole('button', { name: 'Save' })).toBeVisible({ timeout: 5000 })
await page.getByRole('button', { name: 'Cancel' }).click()
})