NEO-139: address review — trim-path tests and Bruno folder note.

Add whitespace-only 404 and padded-path playerId echo tests; document seq 4 standing side effect in faction-standing folder docs.
pull/179/head
VinPropane 2026-06-16 17:26:40 -04:00
parent cc7786ba3a
commit 0fe182565e
4 changed files with 43 additions and 4 deletions

View File

@ -1,3 +1,8 @@
meta { meta {
name: faction-standing name: faction-standing
} }
docs {
Run seq 13 on a fresh dev player for neutral standing defaults.
Seq 4 (operator chain) leaves Grid Operators standing at 15 — re-run seq 2 only after server restart or standing reset, or expect non-zero values.
}

View File

@ -58,7 +58,7 @@ Client-readable standing snapshot for all frozen factions.
- **API:** `FactionStandingApi.MapFactionStandingApi``GET /game/players/{id}/faction-standing`. - **API:** `FactionStandingApi.MapFactionStandingApi``GET /game/players/{id}/faction-standing`.
- **DTOs:** `FactionStandingSnapshotResponse`, `FactionStandingRowJson` (`schemaVersion` 1). - **DTOs:** `FactionStandingSnapshotResponse`, `FactionStandingRowJson` (`schemaVersion` 1).
- **Gate:** `IPositionStateStore.TryGetPosition`**404** for unknown player. - **Gate:** `IPositionStateStore.TryGetPosition`**404** for unknown player.
- **Tests:** `FactionStandingApiTests` (3 cases); **819** tests green. - **Tests:** `FactionStandingApiTests` (5 cases: 404 unknown/whitespace-only, trim-path echo, defaults, post-rep); **821** tests green.
- **Bruno:** `Get faction standing default.bru`, `unknown player.bru`, `after operator chain.bru`. - **Bruno:** `Get faction standing default.bru`, `unknown player.bru`, `after operator chain.bru`.
- **Docs:** `server/README.md` Faction standing read section; E7.M3 module + alignment register updated. - **Docs:** `server/README.md` Faction standing read section; E7.M3 module + alignment register updated.

View File

@ -4,6 +4,8 @@
**Scope:** Branch `NEO-139-e7m3-get-faction-standing-http-read` — commits `5fc780c``3f08812` vs `main` **Scope:** Branch `NEO-139-e7m3-get-faction-standing-http-read` — commits `5fc780c``3f08812` vs `main`
**Base:** `main` **Base:** `main`
Follow-up: suggestion + applicable nits below are **done** (strikethrough + **Done.**).
## Verdict ## Verdict
**Approve with nits** **Approve with nits**
@ -29,14 +31,14 @@ None.
## Suggestions ## Suggestions
1. **Add trim-path integration test.** The plan §4 prototype scenario table lists “GET with trimmed id → **200**; body **`playerId`** echoes trimmed path” (skill/gig snapshot precedent). The handler trims (`id.Trim()`) but no test exercises whitespace-padded path segments or asserts echoed **`playerId`**. A small fourth `[Fact]` would lock the contract. 1. ~~**Add trim-path integration test.** The plan §4 prototype scenario table lists “GET with trimmed id → **200**; body **`playerId`** echoes trimmed path” (skill/gig snapshot precedent). The handler trims (`id.Trim()`) but no test exercises whitespace-padded path segments or asserts echoed **`playerId`**. A small fourth `[Fact]` would lock the contract.~~ **Done.** Added `GetFactionStanding_ShouldReturnOk_WhenPathIdHasLeadingAndTrailingWhitespace` and `GetFactionStanding_ShouldReturnNotFound_WhenPathIdIsWhitespaceOnly` in `FactionStandingApiTests.cs`.
## Nits ## Nits
- Nit: Empty or whitespace-only `{id}` returns **404** (trim → empty) but is not covered by tests — low risk given identical gate to other snapshot APIs. - ~~Nit: Empty or whitespace-only `{id}` returns **404** (trim → empty) but is not covered by tests — low risk given identical gate to other snapshot APIs.~~ **Done.** Whitespace-only path covered by `GetFactionStanding_ShouldReturnNotFound_WhenPathIdIsWhitespaceOnly`.
- Nit: **`BuildSnapshot`** (throws on failure) is exposed for reuse while HTTP uses **`TryBuildSnapshot`** — fine; no direct unit tests call **`BuildSnapshot`** today. - Nit: **`BuildSnapshot`** (throws on failure) is exposed for reuse while HTTP uses **`TryBuildSnapshot`** — fine; no direct unit tests call **`BuildSnapshot`** today.
- Nit: **`FactionStandingApiTests`** duplicates a **`RewardRouterTestDependencies`** helper record also seen in reward-router tests — acceptable for now; extract only if a third caller appears. - Nit: **`FactionStandingApiTests`** duplicates a **`RewardRouterTestDependencies`** helper record also seen in reward-router tests — acceptable for now; extract only if a third caller appears.
- Nit: Bruno **`Get faction standing default.bru`** (seq 2) documents Postgres/restart caveats; re-running the folder on a warm in-memory server after seq 4 can leave standing at **15** — docs already warn; optional one-line note in folder README if authors hit flaky local runs. - ~~Nit: Bruno **`Get faction standing default.bru`** (seq 2) documents Postgres/restart caveats; re-running the folder on a warm in-memory server after seq 4 can leave standing at **15** — docs already warn; optional one-line note in folder README if authors hit flaky local runs.~~ **Done.** `faction-standing/folder.bru` docs note seq 4 side effect and seq 2 re-run caveat.
## Verification ## Verification

View File

@ -33,6 +33,38 @@ public sealed class FactionStandingApiTests
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
} }
[Fact]
public async Task GetFactionStanding_ShouldReturnNotFound_WhenPathIdIsWhitespaceOnly()
{
// Arrange
await using var factory = new InMemoryWebApplicationFactory();
var client = factory.CreateClient();
// Act
var response = await client.GetAsync("/game/players/%20%20/faction-standing");
// Assert
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
[Fact]
public async Task GetFactionStanding_ShouldReturnOk_WhenPathIdHasLeadingAndTrailingWhitespace()
{
// Arrange
await using var factory = new InMemoryWebApplicationFactory();
var client = factory.CreateClient();
// Act
var response = await client.GetAsync("/game/players/%20dev-local-1%20/faction-standing");
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var body = await response.Content.ReadFromJsonAsync<FactionStandingSnapshotResponse>();
Assert.NotNull(body);
Assert.Equal("dev-local-1", body!.PlayerId);
Assert.Equal(FactionStandingSnapshotResponse.CurrentSchemaVersion, body.SchemaVersion);
}
[Fact] [Fact]
public async Task GetFactionStanding_ShouldReturnSchemaV1_WithNeutralStanding_ForPrototypeFactions() public async Task GetFactionStanding_ShouldReturnSchemaV1_WithNeutralStanding_ForPrototypeFactions()
{ {