Merge pull request #46 from ViPro-Technologies/chore/bruno-api-collection

chore: add Bruno API collection and testing-expectations for HTTP
pull/49/head
VinPropane 2026-04-18 19:57:45 -04:00 committed by GitHub
commit 37f44a4944
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 253 additions and 1 deletions

View File

@ -1,5 +1,5 @@
---
description: Unit vs integration tests; integration when data persistence/mutation exists; C# xUnit; Godot client unit tests with script changes (NEO-12 harness + gdscript.yml CI).
description: Unit vs integration tests; integration when data persistence/mutation exists; C# xUnit; Bruno .bru requests when server HTTP endpoints change; Godot client unit tests with script changes (NEO-12 harness + gdscript.yml CI).
alwaysApply: true
---
@ -13,6 +13,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.
## Integration testing (data manipulation)

View File

@ -0,0 +1,5 @@
{
"version": "1",
"name": "Neon Sprawl Server",
"type": "collection"
}

View File

@ -0,0 +1,11 @@
meta {
name: GET health
type: http
seq: 2
}
get {
url: {{baseUrl}}/health
body: none
auth: none
}

View File

@ -0,0 +1,11 @@
meta {
name: GET /
type: http
seq: 1
}
get {
url: {{baseUrl}}/
body: none
auth: none
}

View File

@ -0,0 +1,4 @@
vars {
baseUrl: http://localhost:5253
playerId: dev-local-1
}

View File

@ -0,0 +1,22 @@
meta {
name: POST interact - prototype_terminal
type: http
seq: 8
}
post {
url: {{baseUrl}}/game/players/{{playerId}}/interact
body: json
auth: none
}
headers {
content-type: application/json
}
body:json {
{
"schemaVersion": 1,
"interactableId": "prototype_terminal"
}
}

View File

@ -0,0 +1,22 @@
meta {
name: POST interact - unknown interactable
type: http
seq: 9
}
post {
url: {{baseUrl}}/game/players/{{playerId}}/interact
body: json
auth: none
}
headers {
content-type: application/json
}
body:json {
{
"schemaVersion": 1,
"interactableId": "not_in_registry"
}
}

View File

@ -0,0 +1,11 @@
meta {
name: GET player position (unknown player)
type: http
seq: 4
}
get {
url: {{baseUrl}}/game/players/no-such-player-id/position
body: none
auth: none
}

View File

@ -0,0 +1,11 @@
meta {
name: GET player position
type: http
seq: 3
}
get {
url: {{baseUrl}}/game/players/{{playerId}}/position
body: none
auth: none
}

View File

@ -0,0 +1,26 @@
meta {
name: POST move - near prototype terminal (setup interact)
type: http
seq: 7
}
post {
url: {{baseUrl}}/game/players/{{playerId}}/move
body: json
auth: none
}
headers {
content-type: application/json
}
body:json {
{
"schemaVersion": 1,
"target": {
"x": 0.5,
"y": 0.9,
"z": 0.5
}
}
}

View File

@ -0,0 +1,25 @@
meta {
name: POST move-stream
type: http
seq: 6
}
post {
url: {{baseUrl}}/game/players/{{playerId}}/move-stream
body: json
auth: none
}
headers {
content-type: application/json
}
body:json {
{
"schemaVersion": 1,
"targets": [
{ "x": -4.8, "y": 0.9, "z": -5 },
{ "x": -4.2, "y": 0.9, "z": -5 }
]
}
}

View File

@ -0,0 +1,26 @@
meta {
name: POST move
type: http
seq: 5
}
post {
url: {{baseUrl}}/game/players/{{playerId}}/move
body: json
auth: none
}
headers {
content-type: application/json
}
body:json {
{
"schemaVersion": 1,
"target": {
"x": -4.5,
"y": 0.9,
"z": -5
}
}
}

View File

@ -0,0 +1,11 @@
meta {
name: GET player target state
type: http
seq: 10
}
get {
url: {{baseUrl}}/game/players/{{playerId}}/target
body: none
auth: none
}

View File

@ -0,0 +1,22 @@
meta {
name: POST target select - clear lock
type: http
seq: 12
}
post {
url: {{baseUrl}}/game/players/{{playerId}}/target/select
body: json
auth: none
}
headers {
content-type: application/json
}
body:json {
{
"schemaVersion": 1,
"targetId": null
}
}

View File

@ -0,0 +1,22 @@
meta {
name: POST target select - prototype_target_alpha
type: http
seq: 11
}
post {
url: {{baseUrl}}/game/players/{{playerId}}/target/select
body: json
auth: none
}
headers {
content-type: application/json
}
body:json {
{
"schemaVersion": 1,
"targetId": "prototype_target_alpha"
}
}

View File

@ -0,0 +1,22 @@
meta {
name: POST target select - unknown target
type: http
seq: 13
}
post {
url: {{baseUrl}}/game/players/{{playerId}}/target/select
body: json
auth: none
}
headers {
content-type: application/json
}
body:json {
{
"schemaVersion": 1,
"targetId": "not_in_registry"
}
}