End-to-end tests against the pasture; profiles, follows, search, votes, reactions
tests/e2e (Playwright for .NET 1.61.0 on xunit v3, the Chromium 1228 already cached, never downloaded, never in CI) runs the published app against SocialPub's pasture and its town: run.sh publishes it with the Pasture environment (wwwroot/appsettings.Pasture.json, published only then; the deploy fails if it ever ships) and serves it as https://decepub.test. The tests sign in through the real login page and persona chooser, check that every request goes only to decepub.test and privapub.test with the right credential on the right API, render one post of each kind from each platform as its author wrote it, and check every action on the other side of the wire (town.sh stored): favourites, boosts and replies with their undoing, follows from a profile, votes, reactions. Each test is also a cell of the town's report (out/client.jsonl). They found two PrivaPub bugs fixed there (a blocked author's status answered null; sensitive remote media invented a content warning) and a reply addressed to nobody. New in the app, all checked by those tests: - profiles at /account/{id}: header, bio, fields, counts, the account's posts as posts, posts and replies, or media, and follow, unfollow, cancel a request, mute and block (AccountService); post authors and notifications open them in the app; - search at /search: accounts, posts and hashtags, a handle or an address resolved by PrivaPub; - poll voting on the card, and emoji reactions shown and given with one tap; before a persona's first reaction or vote it is told once that both are public (PublicNoticeService, the owner's decision); - follow requests answered from their notification. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
This commit is contained in:
1 parent
0f68e74e38
commit
011bafb6af
39 files changed
+2074
-17
No files matched your search
@@ -43,7 +43,32 @@ dotnet run # dev server: https://loc
|
||||
dotnet publish decePubClient.csproj -c Release -o publish # static site lands in publish/wwwroot
|
||||
```
|
||||
|
||||
`global.json` pins SDK 10.0.100 with `rollForward: latestFeature`. There are no tests and no linter.
|
||||
`global.json` pins SDK 10.0.100 with `rollForward: latestFeature`. There is no linter.
|
||||
|
||||
## Testing: end to end against the pasture
|
||||
|
||||
`tests/e2e` (Playwright for .NET 1.61.0 on xunit v3) runs the published app in Chromium against SocialPub's pasture: a
|
||||
private fediverse of PrivaPub and its peers (GoToSocial, Mastodon, Misskey, Sharkey, Akkoma, Lemmy) seeded with a fake
|
||||
community, the town (see `../SocialPub/CLAUDE.md`, "The town"). Never in CI: it needs podman and the pasture.
|
||||
|
||||
```sh
|
||||
../SocialPub/tools/pasture/run.sh up gts mastodon misskey sharkey akkoma lemmy # PASTURE_PORT if 6971 is taken
|
||||
../SocialPub/tools/pasture/town.sh seed village
|
||||
tests/e2e/run.sh [--filter ...] # publishes with WasmApplicationEnvironmentName=Pasture, serves https://decepub.test, runs
|
||||
```
|
||||
|
||||
- **The app under test is the deploy's own build** with the environment baked in: Blazor on .NET 10 ignores the
|
||||
`Blazor-Environment` header, so `wwwroot/appsettings.Pasture.json` (API `https://privapub.test`) is chosen at publish
|
||||
time and published only then; the deploy fails if it ever ships.
|
||||
- Chromium resolves `*.test` to Caddy on `127.0.0.1:6443` (`--host-resolver-rules`) and ignores the pasture CA. The
|
||||
tests use the Chromium headless shell 1228 cached in `~/.cache/ms-playwright` and never install a browser.
|
||||
- **Guards on every test** (`Support/Browser.cs`): the app talks only to its own site and to PrivaPub, a root JWT never
|
||||
goes to `/api` nor a persona token to `/clientapi`, no 5xx, no Blazor error bar.
|
||||
- **The tests ask the town** (`Support/Pasture.cs`) which accounts exist and what each object holds (`town.sh expect`),
|
||||
and check the other side of the wire through `town.sh stored`. Each render and action test is also a cell of the
|
||||
town's report (`out/client.jsonl`).
|
||||
- Cards carry `data-uri` (their ActivityPub id) and the empty feed `data-feed-empty`, for the tests.
|
||||
- The root project globs `**/*.cs`, so it excludes `tests/**` (`DefaultItemExcludes`), and Tailwind does not scan it.
|
||||
|
||||
## CSS: Tailwind 4 + daisyUI 5, vendored, offline
|
||||
|
||||
@@ -183,8 +208,16 @@ supplies:
|
||||
- **Services** (`Services/`): `TimelineService` (every feed as `FeedPage`s of `FeedPost`s, paged by `max_id`/`min_id`;
|
||||
circles are read as ids from `/clientapi` and hydrated through `/api/v1/statuses?id[]=`; located posts come from
|
||||
`/clientapi/post/nearby` and have no Mastodon actions), `StatusService` (publish, favourite, boost, bookmark, delete,
|
||||
threads, mute, block; located and group posts go through `/clientapi/post/insert`), `MediaService` (uploads),
|
||||
threads, mute, block, poll votes, emoji reactions through Pleroma's `/api/v1/pleroma/statuses/:id/reactions`;
|
||||
located and group posts go through `/clientapi/post/insert`), `AccountService` (profiles, relationships, follow,
|
||||
block, mute, follow requests, `/api/v2/search`, whose handles and URLs PrivaPub resolves), `MediaService` (uploads),
|
||||
`GroupService`, `InstanceService` and `ProvenanceService`.
|
||||
- **Reactions and votes are public** (owner decision, PrivaPub's ROADMAP): before a persona's first reaction or poll
|
||||
vote, `PublicNoticeService` asks it once (`PublicNoticeHost` in `MainLayout`) and remembers the persona in
|
||||
localStorage (`PublicActionNotices`). Anything else that makes a persona's act visible to others gets the same notice.
|
||||
- **Profiles and search** (`Pages/Profile.razor` at `/account/{id}`, `Pages/Search.razor` at `/search?q=`): a card's
|
||||
author and a notification's account open the profile in the app; "Open original" is the only way to the remote site.
|
||||
A card in a fixed-height flex column with `overflow-hidden` needs `flex-none`, or it collapses to nothing.
|
||||
- **Mastodon DTOs** are client-side, in `Models/Mastodon/` (snake_case). `/clientapi` DTOs come from
|
||||
`PrivaPub.ClientModels`.
|
||||
- **Where a post is** (`InstanceService.Locate`, `Models/FeedPost.cs`): its own place (Pixelfed's, `privapub.place`),
|
||||
|
||||
Reference in new issue
Block a user