From eac95f0c2772a871bb11320c383d9c9e8980ca45 Mon Sep 17 00:00:00 2001 From: VinPropane Date: Mon, 27 Apr 2026 20:27:53 -0400 Subject: [PATCH] chore: group Bruno hotbar-loadout and ability-cast under subfolders --- .cursor/rules/testing-expectations.md | 2 +- .../Post cast bad schema.bru} | 2 +- .../Post cast happy.bru} | 2 +- .../Post cast loadout mismatch.bru} | 2 +- .../Post cast missing player.bru} | 2 +- .../Post hotbar bind slot0 pulse.bru} | 2 +- .../Get loadout missing player.bru} | 2 +- .../Get loadout.bru} | 2 +- .../Post loadout bad schema.bru} | 2 +- .../Post loadout bind.bru} | 2 +- client/README.md | 2 +- docs/manual-qa/NEO-31.md | 10 +++++----- docs/plans/NEO-31-implementation-plan.md | 14 +++++++------- 13 files changed, 23 insertions(+), 23 deletions(-) rename bruno/neon-sprawl-server/{ability-cast-post-bad-schema.bru => ability-cast/Post cast bad schema.bru} (90%) rename bruno/neon-sprawl-server/{ability-cast-post.bru => ability-cast/Post cast happy.bru} (94%) rename bruno/neon-sprawl-server/{ability-cast-post-loadout-mismatch.bru => ability-cast/Post cast loadout mismatch.bru} (91%) rename bruno/neon-sprawl-server/{ability-cast-post-missing-player.bru => ability-cast/Post cast missing player.bru} (89%) rename bruno/neon-sprawl-server/{ability-cast-preset-slot0.bru => ability-cast/Post hotbar bind slot0 pulse.bru} (89%) rename bruno/neon-sprawl-server/{hotbar-loadout-get-missing-player.bru => hotbar-loadout/Get loadout missing player.bru} (84%) rename bruno/neon-sprawl-server/{hotbar-loadout-get.bru => hotbar-loadout/Get loadout.bru} (94%) rename bruno/neon-sprawl-server/{hotbar-loadout-post-bad-schema.bru => hotbar-loadout/Post loadout bad schema.bru} (90%) rename bruno/neon-sprawl-server/{hotbar-loadout-post.bru => hotbar-loadout/Post loadout bind.bru} (95%) diff --git a/.cursor/rules/testing-expectations.md b/.cursor/rules/testing-expectations.md index 57c208b..c2d69e5 100644 --- a/.cursor/rules/testing-expectations.md +++ b/.cursor/rules/testing-expectations.md @@ -14,7 +14,7 @@ alwaysApply: true - **Names:** **`MethodName_ShouldExpectedOutcome_WhenScenario`**; see [C# style — Test method naming convention](csharp-style.md#test-method-naming-convention). - **No test project yet:** It is acceptable to ship a small change without a suite only while the server is mostly scaffolding. When you add the **first** testable module, **add a `NeonSprawl.Server.Tests` (or equivalent) project** and start covering that area; do not leave new core logic permanently untested. - **Bug fixes:** Prefer a **regression test** when the fix is non-obvious or has broken before. -- **HTTP endpoints:** Any change set that **adds or changes** a route or wire contract on **`NeonSprawl.Server`** (new `MapGet` / `MapPost`, path change, request/response JSON shape, status codes) must **add or update** the **Bruno** collection under **`bruno/neon-sprawl-server/`** so the API stays manually exercisable from the repo: at least one **.bru** request per new/changed route (happy path plus a representative **4xx/404** case when the server defines one). Prefer **Bruno `tests` blocks** on those requests for simple smoke checks (status + key JSON fields) when the behavior is stable enough not to churn every edit. If Bruno is unsuitable for a given endpoint (e.g. streaming-only), say so briefly in the PR or plan instead of silently omitting coverage. +- **HTTP endpoints:** Any change set that **adds or changes** a route or wire contract on **`NeonSprawl.Server`** (new `MapGet` / `MapPost`, path change, request/response JSON shape, status codes) must **add or update** the **Bruno** collection under **`bruno/neon-sprawl-server/`** so the API stays manually exercisable from the repo: at least one **.bru** request per new/changed route (happy path plus a representative **4xx/404** case when the server defines one). **Group** requests in **subfolders** by area (same pattern as `targeting/`, `position/`, `interaction/`, `hotbar-loadout/`, `ability-cast/`). Prefer **Bruno `tests` blocks** on those requests for simple smoke checks (status + key JSON fields) when the behavior is stable enough not to churn every edit. If Bruno is unsuitable for a given endpoint (e.g. streaming-only), say so briefly in the PR or plan instead of silently omitting coverage. ## Integration testing (data manipulation) diff --git a/bruno/neon-sprawl-server/ability-cast-post-bad-schema.bru b/bruno/neon-sprawl-server/ability-cast/Post cast bad schema.bru similarity index 90% rename from bruno/neon-sprawl-server/ability-cast-post-bad-schema.bru rename to bruno/neon-sprawl-server/ability-cast/Post cast bad schema.bru index f32a9db..cc55b1b 100644 --- a/bruno/neon-sprawl-server/ability-cast-post-bad-schema.bru +++ b/bruno/neon-sprawl-server/ability-cast/Post cast bad schema.bru @@ -1,5 +1,5 @@ meta { - name: ability-cast post bad schema + name: POST ability cast bad schema type: http seq: 22 } diff --git a/bruno/neon-sprawl-server/ability-cast-post.bru b/bruno/neon-sprawl-server/ability-cast/Post cast happy.bru similarity index 94% rename from bruno/neon-sprawl-server/ability-cast-post.bru rename to bruno/neon-sprawl-server/ability-cast/Post cast happy.bru index e30940d..39ad219 100644 --- a/bruno/neon-sprawl-server/ability-cast-post.bru +++ b/bruno/neon-sprawl-server/ability-cast/Post cast happy.bru @@ -1,5 +1,5 @@ meta { - name: ability-cast post happy + name: POST ability cast happy type: http seq: 21 } diff --git a/bruno/neon-sprawl-server/ability-cast-post-loadout-mismatch.bru b/bruno/neon-sprawl-server/ability-cast/Post cast loadout mismatch.bru similarity index 91% rename from bruno/neon-sprawl-server/ability-cast-post-loadout-mismatch.bru rename to bruno/neon-sprawl-server/ability-cast/Post cast loadout mismatch.bru index 87e889d..81e0341 100644 --- a/bruno/neon-sprawl-server/ability-cast-post-loadout-mismatch.bru +++ b/bruno/neon-sprawl-server/ability-cast/Post cast loadout mismatch.bru @@ -1,5 +1,5 @@ meta { - name: ability-cast post loadout mismatch + name: POST ability cast loadout mismatch type: http seq: 24 } diff --git a/bruno/neon-sprawl-server/ability-cast-post-missing-player.bru b/bruno/neon-sprawl-server/ability-cast/Post cast missing player.bru similarity index 89% rename from bruno/neon-sprawl-server/ability-cast-post-missing-player.bru rename to bruno/neon-sprawl-server/ability-cast/Post cast missing player.bru index 88235ce..a765d2a 100644 --- a/bruno/neon-sprawl-server/ability-cast-post-missing-player.bru +++ b/bruno/neon-sprawl-server/ability-cast/Post cast missing player.bru @@ -1,5 +1,5 @@ meta { - name: ability-cast post missing player + name: POST ability cast missing player type: http seq: 23 } diff --git a/bruno/neon-sprawl-server/ability-cast-preset-slot0.bru b/bruno/neon-sprawl-server/ability-cast/Post hotbar bind slot0 pulse.bru similarity index 89% rename from bruno/neon-sprawl-server/ability-cast-preset-slot0.bru rename to bruno/neon-sprawl-server/ability-cast/Post hotbar bind slot0 pulse.bru index 0095c85..4e6322d 100644 --- a/bruno/neon-sprawl-server/ability-cast-preset-slot0.bru +++ b/bruno/neon-sprawl-server/ability-cast/Post hotbar bind slot0 pulse.bru @@ -1,5 +1,5 @@ meta { - name: ability-cast preset slot0 pulse + name: POST hotbar bind slot0 pulse (cast preset) type: http seq: 20 } diff --git a/bruno/neon-sprawl-server/hotbar-loadout-get-missing-player.bru b/bruno/neon-sprawl-server/hotbar-loadout/Get loadout missing player.bru similarity index 84% rename from bruno/neon-sprawl-server/hotbar-loadout-get-missing-player.bru rename to bruno/neon-sprawl-server/hotbar-loadout/Get loadout missing player.bru index 9b97978..c94ed16 100644 --- a/bruno/neon-sprawl-server/hotbar-loadout-get-missing-player.bru +++ b/bruno/neon-sprawl-server/hotbar-loadout/Get loadout missing player.bru @@ -1,5 +1,5 @@ meta { - name: hotbar-loadout get missing player + name: GET hotbar loadout missing player type: http seq: 2 } diff --git a/bruno/neon-sprawl-server/hotbar-loadout-get.bru b/bruno/neon-sprawl-server/hotbar-loadout/Get loadout.bru similarity index 94% rename from bruno/neon-sprawl-server/hotbar-loadout-get.bru rename to bruno/neon-sprawl-server/hotbar-loadout/Get loadout.bru index 52e7617..9836605 100644 --- a/bruno/neon-sprawl-server/hotbar-loadout-get.bru +++ b/bruno/neon-sprawl-server/hotbar-loadout/Get loadout.bru @@ -1,5 +1,5 @@ meta { - name: hotbar-loadout get + name: GET hotbar loadout type: http seq: 1 } diff --git a/bruno/neon-sprawl-server/hotbar-loadout-post-bad-schema.bru b/bruno/neon-sprawl-server/hotbar-loadout/Post loadout bad schema.bru similarity index 90% rename from bruno/neon-sprawl-server/hotbar-loadout-post-bad-schema.bru rename to bruno/neon-sprawl-server/hotbar-loadout/Post loadout bad schema.bru index 5421180..bc7ca46 100644 --- a/bruno/neon-sprawl-server/hotbar-loadout-post-bad-schema.bru +++ b/bruno/neon-sprawl-server/hotbar-loadout/Post loadout bad schema.bru @@ -1,5 +1,5 @@ meta { - name: hotbar-loadout post bad schema + name: POST hotbar loadout bad schema type: http seq: 4 } diff --git a/bruno/neon-sprawl-server/hotbar-loadout-post.bru b/bruno/neon-sprawl-server/hotbar-loadout/Post loadout bind.bru similarity index 95% rename from bruno/neon-sprawl-server/hotbar-loadout-post.bru rename to bruno/neon-sprawl-server/hotbar-loadout/Post loadout bind.bru index b7bc2ac..4443859 100644 --- a/bruno/neon-sprawl-server/hotbar-loadout-post.bru +++ b/bruno/neon-sprawl-server/hotbar-loadout/Post loadout bind.bru @@ -1,5 +1,5 @@ meta { - name: hotbar-loadout post bind + name: POST hotbar loadout bind type: http seq: 3 } diff --git a/client/README.md b/client/README.md index c09a16e..b47d147 100644 --- a/client/README.md +++ b/client/README.md @@ -213,7 +213,7 @@ pwsh -File scripts/install-git-hooks.ps1 This installs: -- **pre-commit**: blocks commits when `client/scripts/*.gd` changes lack matching `client/test/*_test.gd` updates, or when server route/contract files change without corresponding `server/NeonSprawl.Server.Tests/` and `bruno/neon-sprawl-server/*.bru` updates. +- **pre-commit**: blocks commits when `client/scripts/*.gd` changes lack matching `client/test/*_test.gd` updates, or when server route/contract files change without corresponding `server/NeonSprawl.Server.Tests/` and `bruno/neon-sprawl-server/**/*.bru` updates. - **pre-push**: runs **`gdlint client/scripts client/test`** and **`gdformat --check client/scripts client/test`**. The pre-push hook prefers **`.venv-gd/bin/`** (Unix) or **`.venv-gd/Scripts/`** (Windows venv) when present; without that venv or a global install, the hook **fails** and blocks the push — same as CI. diff --git a/docs/manual-qa/NEO-31.md b/docs/manual-qa/NEO-31.md index 1a44ba1..245a5b0 100644 --- a/docs/manual-qa/NEO-31.md +++ b/docs/manual-qa/NEO-31.md @@ -12,15 +12,15 @@ - [ ] Start server: `cd server/NeonSprawl.Server && dotnet run`. - [ ] `curl -s http://localhost:5253/health` returns JSON with `status: ok`. -- [ ] Run Bruno collection (or at least): `ability-cast-preset-slot0` (seq **20**) then `ability-cast-post` (seq **21**) — expect cast `accepted: true`. -- [ ] `ability-cast-post-bad-schema` → HTTP **400**. -- [ ] `ability-cast-post-missing-player` → HTTP **404**. -- [ ] **`ability-cast-post-loadout-mismatch`** (seq **24**): run **`ability-cast-preset-slot0`** in the same session first so slot 0 is `prototype_pulse`; then expect `accepted: false` and `reasonCode == "loadout_mismatch"`. +- [ ] Run Bruno collection (or at least): `ability-cast/Post hotbar bind slot0 pulse` (seq **20**) then `ability-cast/Post cast happy` (seq **21**) — expect cast `accepted: true`. +- [ ] `ability-cast/Post cast bad schema` → HTTP **400**. +- [ ] `ability-cast/Post cast missing player` → HTTP **404**. +- [ ] **`ability-cast/Post cast loadout mismatch`** (seq **24**): run **`ability-cast/Post hotbar bind slot0 pulse`** in the same session first so slot 0 is `prototype_pulse`; then expect `accepted: false` and `reasonCode == "loadout_mismatch"`. ## 2) Client — bound slot - [ ] With server running, open main scene; confirm hotbar hydrated (NEO-29). -- [ ] Bind slot **0** to `prototype_pulse` (Bruno `hotbar-loadout-post` or equivalent `curl`) if not already. +- [ ] Bind slot **0** to `prototype_pulse` (Bruno `hotbar-loadout/Post loadout bind` or equivalent `curl`) if not already. - [ ] Press **1** (InputMap `hotbar_slot_1`): Godot Output shows a line starting with **`ability_cast_requested`** including `slot=0`, `ability_id=prototype_pulse`, and `targetId=` matching current HUD lock (`null` / `—` when cleared, or the locked id after Tab). - [ ] Server log or network trace shows **one** `POST …/ability-cast` per key press (no spam while key held; Godot `is_action_pressed` fires once per press). diff --git a/docs/plans/NEO-31-implementation-plan.md b/docs/plans/NEO-31-implementation-plan.md index db1bbc8..8b760e9 100644 --- a/docs/plans/NEO-31-implementation-plan.md +++ b/docs/plans/NEO-31-implementation-plan.md @@ -47,7 +47,7 @@ 4. **Tests** — **Server:** xUnit suite posting valid/invalid bodies (unknown player, empty slot, ability mismatch). **Client:** GdUnit suite with mock HTTP verifying URL/method/body for bound vs unbound paths and correct target id propagation from a stub target state provider. -5. **Bruno (`bruno/neon-sprawl-server/`)** — Add `.bru` requests mirroring the existing **hotbar-loadout** pattern (`{{baseUrl}}`, `dev-local-1`): at minimum **happy-path cast POST**, **bad schema / missing player**, and **loadout mismatch or empty slot** so manual API checks and collection runs stay aligned with server xUnit coverage. +5. **Bruno (`bruno/neon-sprawl-server/ability-cast/`)** — Add `.bru` requests mirroring the **hotbar-loadout** folder pattern (`{{baseUrl}}`, `dev-local-1`): at minimum **happy-path cast POST**, **bad schema / missing player**, and **loadout mismatch** so manual API checks and collection runs stay aligned with server xUnit coverage. Hotbar API requests live under **`bruno/neon-sprawl-server/hotbar-loadout/`**. 6. **Docs / backlog hygiene (light)** — After behavior exists, optionally refresh [E1_M4_AbilityInputScaffold.md](../decomposition/modules/E1_M4_AbilityInputScaffold.md) implementation snapshot + Linear table row for E1M4-02 (still optional if timeboxed). @@ -61,11 +61,11 @@ | `client/scripts/ability_cast_client.gd` | Thin HTTP client for cast POST (injection pattern matches hotbar client). | | `client/test/ability_cast_client_test.gd` | Mock-transport tests for payload formation and unbound-slot no-op. | | `docs/manual-qa/NEO-31.md` | Manual QA checklist (slot keys, bound vs unbound, target id from HUD lock). | -| `bruno/neon-sprawl-server/ability-cast-preset-slot0.bru` | POST hotbar bind slot 0 → `prototype_pulse` so cast happy/mismatch requests have deterministic loadout state. | -| `bruno/neon-sprawl-server/ability-cast-post.bru` | Happy-path `POST …/ability-cast` (run after preset when exercising alone). | -| `bruno/neon-sprawl-server/ability-cast-post-bad-schema.bru` | Wrong `schemaVersion` → HTTP 400. | -| `bruno/neon-sprawl-server/ability-cast-post-missing-player.bru` | Unknown player path → HTTP 404. | -| `bruno/neon-sprawl-server/ability-cast-post-loadout-mismatch.bru` | Wrong ability for slot 0 → `loadout_mismatch` (requires preset in same run). | +| `bruno/neon-sprawl-server/ability-cast/Post hotbar bind slot0 pulse.bru` | POST hotbar bind slot 0 → `prototype_pulse` so cast happy/mismatch requests have deterministic loadout state. | +| `bruno/neon-sprawl-server/ability-cast/Post cast happy.bru` | Happy-path `POST …/ability-cast` (run after preset when exercising alone). | +| `bruno/neon-sprawl-server/ability-cast/Post cast bad schema.bru` | Wrong `schemaVersion` → HTTP 400. | +| `bruno/neon-sprawl-server/ability-cast/Post cast missing player.bru` | Unknown player path → HTTP 404. | +| `bruno/neon-sprawl-server/ability-cast/Post cast loadout mismatch.bru` | Wrong ability for slot 0 → `loadout_mismatch` (requires preset in same run). | ## Files to modify @@ -84,7 +84,7 @@ | `AbilityCastApiTests.cs` | POST success when loadout matches; denies with stable `reasonCode` for bad player, wrong slot/ability, empty binding. | | `ability_cast_client_test.gd` | Client builds JSON with `targetId` from injected target state; unbound slot does not call `request`; bound slot emits exactly one POST body. | | Manual `docs/manual-qa/NEO-31.md` | Human verification of keys, logs, and HUD target id alignment. | -| Bruno `ability-cast-*.bru` | Embedded `tests { … }` blocks assert status + JSON fields for quick regression (same style as `hotbar-loadout-post.bru`). | +| Bruno `ability-cast/*.bru` | Embedded `tests { … }` blocks assert status + JSON fields for quick regression (same style as `hotbar-loadout/Post loadout bind.bru`). | ## Open questions / risks