2.1 KiB
Manual QA — NEO-42 (craft / refine → refine skill XP, activity)
Reference: implementation plan, NEO-38 (skill progression grant), NEO-41 (gather analogue).
Preconditions
- Run
NeonSprawl.Serverfromserver/NeonSprawl.Server(dotnet run; defaulthttp://localhost:5253). - Player
dev-local-1(default seed).
BASE=http://localhost:5253
ID=dev-local-1
Automated coverage
RefineActivitySkillXpGrantTests exercises the NEO-38 grant path with disk prototype_skills.json (refine allows activity) and a stub registry where refine disallows activity.
Control: direct POST grant (same stack as E3.M2 hook)
Move once so GET …/skill-progression is not 404:
curl -sS -i -X POST "${BASE}/game/players/${ID}/move" \
-H "Content-Type: application/json" \
-d '{"schemaVersion":1,"target":{"x":0.5,"y":0.9,"z":0.5}}'
Baseline:
curl -sS "${BASE}/game/players/${ID}/skill-progression"
Apply refine + activity (mirrors what RefineActivitySkillXpGrant does internally):
curl -sS -i -X POST "${BASE}/game/players/${ID}/skill-progression" \
-H "Content-Type: application/json" \
-d '{"schemaVersion":1,"skillId":"refine","amount":10,"sourceKind":"activity"}'
Expect HTTP 200, granted": true, and refine xp increased (repeat POST to see cumulative XP).
Deny path (catalog guard)
With default catalog, trainer is allowed for refine but book_or_item is not:
curl -sS -i -X POST "${BASE}/game/players/${ID}/skill-progression" \
-H "Content-Type: application/json" \
-d '{"schemaVersion":1,"skillId":"refine","amount":5,"sourceKind":"book_or_item"}'
Expect HTTP 200, granted": false, reasonCode":"source_kind_not_allowed".
E3.M2 follow-up
When recipe/refine execution exists, confirm one server-side call to RefineActivitySkillXpGrant.GrantOnSuccessfulCraftOrRefine on success only, then GET …/skill-progression shows expected refine xp.