fix test, update PLAN

This commit is contained in:
2026-10-24 22:14:17 -06:00
parent 24fedee769
commit 500dffee63
2 changed files with 46 additions and 28 deletions
@@ -1,5 +1,12 @@
# Plan: New Activity Screen on alertSearch # Plan: New Activity Screen on alertSearch
## Status
Built in the app, the notification service and endorser-ch. The last change,
leaving a person's own gives and offers out of their
`personalPlanContributions`, is in endorser-ch's Unreleased CHANGELOG section
and ships with its next release; Playwright spec 50 depends on it.
## Goal ## Goal
The New Activity screen (`/new-activity`, `src/views/NewActivityView.vue`) The New Activity screen (`/new-activity`, `src/views/NewActivityView.vue`)
@@ -16,7 +23,7 @@ list's length.
| Bucket | Server | What it holds | Needs | | Bucket | Server | What it holds | Needs |
|---|---|---|---| |---|---|---|---|
| `claims` | endorser `/api/v2/report/alertSearch` | Claims by others with you as `toEntity` or `fromEntity` (offers, gives, every other claim type) | — | | `claims` | endorser `/api/v2/report/alertSearch` | Claims by others with you as `toEntity` or `fromEntity` (offers, gives, every other claim type) | — |
| `personalPlanContributions` | endorser | Gives and offers to or from projects you issued or are agent of (your own claims included) | — | | `personalPlanContributions` | endorser | Gives and offers by others to or from projects you issued or are agent of | — |
| `trackedPlanUpdates` | endorser | Edits to starred projects | `planHandleIds` | | `trackedPlanUpdates` | endorser | Edits to starred projects | `planHandleIds` |
| `trackedPlanClaims` | endorser | Gives and offers to or from starred projects | `planHandleIds` | | `trackedPlanClaims` | endorser | Gives and offers to or from starred projects | `planHandleIds` |
| `plansNearby` | endorser | Projects created or edited in the search area | `location` | | `plansNearby` | endorser | Projects created or edited in the search area | `location` |
@@ -282,14 +289,13 @@ App (`crowd-funder-for-time-pwa`):
for the offer's project, a WebAssembly explanation on the start-up error for the offer's project, a WebAssembly explanation on the start-up error
screen, test warm-up, retry and reporter). screen, test warm-up, retry and reporter).
- [x] Release the app after endorser-ch is deployed, since detail rows read - [x] Release the app after endorser-ch is deployed, since detail rows read
`claim` from `alertSearch` — next: release (Trent) `claim` from `alertSearch`.
Notification service (`notification-wakeup-service`): Notification service (`notification-wakeup-service`):
- [x] Service changes 1–6, `c` in the SMS link and FCM data, tests, README, - [x] Service changes 1–6, `c` in the SMS link and FCM data, tests, README,
CHANGELOG. CHANGELOG.
- [x] Deploy to test and production — next: deploy, or tick this if done - [x] Deploy to test and production.
(Trent)
endorser-ch: endorser-ch:
@@ -300,25 +306,23 @@ endorser-ch:
existing offers without moving `changeSeq`; test, CHANGELOG. existing offers without moving `changeSeq`; test, CHANGELOG.
- [x] Commit the `isPartOf` change: `CHANGELOG.md`, `sql/README.md`, - [x] Commit the `isPartOf` change: `CHANGELOG.md`, `sql/README.md`,
`sql/V23__offer_is_part_of_to_entity.sqlite3`, `claim.service.js`, `sql/V23__offer_is_part_of_to_entity.sqlite3`, `claim.service.js`,
`endorser.db.service.js`, `test/controller-endorser-6-plans-totals.js` — `endorser.db.service.js`, `test/controller-endorser-6-plans-totals.js`.
next: commit (Trent)
- [x] Deploy to test, then production, running Flyway on the main DB so V23 - [x] Deploy to test, then production, running Flyway on the main DB so V23
applies — next: deploy (Trent) applies.
- [ ] Leave a person's own gives and offers out of their - [x] Leave a person's own gives and offers out of their
`personalPlanContributions` (the query includes them when a person `personalPlanContributions`:
contributes to their own project) — next: implement after the deploys above (agent) - endorser-ch: `AND j.issuer != ?`, bound to the requesting DID, on both
- endorser-ch: add `AND j.issuer != ?`, bound to the requesting DID, to halves of the `UNION` in `jwtsForUserPlanContributions`
both halves of the `UNION` in `jwtsForUserPlanContributions`
(`endorser.db.service.js`), as `jwtsWithDidAfterId` does. (`endorser.db.service.js`), as `jwtsWithDidAfterId` does.
- endorser-ch test in `controller-endorser-6-plans-totals.js`: user 1's own - endorser-ch test in `controller-endorser-6-plans-totals.js`: user 1's own
offer to user 1's plan is absent from user 1's offer to user 1's plan is absent from user 1's
`personalPlanContributions`, and user 2's offer is present. `personalPlanContributions`, and user 2's offer is present.
- App spec 50 "Record an offer": record the offer as User 1 - App spec 50 "Record an offer": User 0 seeds New Activity on Home, User 1
(`importUserFromAccount(page, "01")`) on a project User 0 owns, then records the offer on a project User 0 owns, then User 0 checks the
switch to User 0 to check the `personalPlanContributions` tile and list. `personalPlanContributions` tile and list. "Affirm delivery" gets User 1
"Affirm delivery" then gets User 1 as giver and the project as recipient. as giver and the project as recipient.
- endorser-ch CHANGELOG entry; the notification service needs no change, - endorser-ch CHANGELOG entry (Unreleased); the notification service needs
since its counts come from the same query. no change, since its counts come from the same query.
## Out of scope ## Out of scope
@@ -351,3 +355,7 @@ Closed decisions:
- 2026-10-16: detail pages query `alertSearch` themselves and do not reuse - 2026-10-16: detail pages query `alertSearch` themselves and do not reuse
Home's rows; an in-memory hand-off would be a second path that every Home's rows; an in-memory hand-off would be a second path that every
entry other than a fresh, uncapped Home tile skips. entry other than a fresh, uncapped Home tile skips.
- 2026-10-24: `personalPlanContributions` leaves out the requester's own
gives and offers, matching `claims`, which already left out the requester's
own claims. Before this, a person who offered to their own project saw it
counted as new activity. The plan was closed and moved to history.
+20 -10
View File
@@ -1,5 +1,5 @@
import { test, expect, Page } from '@playwright/test'; import { test, expect, Page } from '@playwright/test';
import { importUser, importUserFromAccount } from './testUtils'; import { importUser, importUserFromAccount, switchToUser, waitForNewActivityLoaded } from './testUtils';
test('Record an offer', async ({ page }) => { test('Record an offer', async ({ page }) => {
test.setTimeout(60000); test.setTimeout(60000);
@@ -14,17 +14,26 @@ test('Record an offer', async ({ page }) => {
// Switch to user 0 // Switch to user 0
// await importUser(page); // await importUser(page);
// Become User Zero // Become User Zero
await importUserFromAccount(page, "00"); const userZeroDid = await importUserFromAccount(page, "00");
// Select a project // this Home visit records where User Zero's New Activity starts
await page.goto('./discover'); await page.goto('./');
await page.getByTestId('closeOnboardingAndFinish').click(); await page.getByTestId('closeOnboardingAndFinish').click();
await page.locator('ul#listDiscoverResults li:nth-child(1)').click(); await waitForNewActivityLoaded(page);
// Record an offer // Select a project User Zero owns, since New Activity leaves out a person's
// The line that used to sit here waited for a button with the text 'Edit'. It // own offers to their projects
// never waited (isVisible() returns at once) and never matched (that button await page.goto('./projects');
// carries title="Edit", no text, and renders only for the project's issuer). await page.locator('ul#listProjects li').first().click();
// The project id is read from the URL, so wait for the navigation to land. // The project id is read from the URL, so wait for the navigation to land.
await page.waitForURL(/\/project\//); await page.waitForURL(/\/project\//);
const projectUrl = page.url();
// Become User One, who records the offer to User Zero's project
await importUserFromAccount(page, "01");
// onboarding is per identity, and its dialog would cover the Projects page
await page.goto('./');
await page.getByTestId('closeOnboardingAndFinish').click();
await expect(page.locator('.dialog-overlay')).toBeHidden();
await page.goto(projectUrl);
await expect(page.getByTestId('offerButton')).toBeVisible(); await expect(page.getByTestId('offerButton')).toBeVisible();
await page.getByTestId('offerButton').click(); await page.getByTestId('offerButton').click();
await page.getByTestId('inputDescription').fill(description); await page.getByTestId('inputDescription').fill(description);
@@ -74,7 +83,8 @@ test('Record an offer', async ({ page }) => {
await page.getByTestId('editClaimButton').click(); await page.getByTestId('editClaimButton').click();
const newAmount = page.getByTestId('inputOfferAmount'); const newAmount = page.getByTestId('inputOfferAmount');
await expect(newAmount).toHaveValue((randomNonZeroNumber + 1).toString()); await expect(newAmount).toHaveValue((randomNonZeroNumber + 1).toString());
// go to the home page and check that the offer is shown as new // as the project owner, go to the home page and check that the offer is shown as new
await switchToUser(page, userZeroDid);
await page.goto('./'); await page.goto('./');
const offerNumElem = page.getByTestId('newActivityNumber-personalPlanContributions'); const offerNumElem = page.getByTestId('newActivityNumber-personalPlanContributions');
// extract the number and check that it's greater than 0 or "50+" // extract the number and check that it's greater than 0 or "50+"