NEO-70: Fix Bruno craft tests for shared Postgres CI state.
Clear refined stock for insufficient_materials deny; spine tolerates node_depleted gathers, reuses persisted scrap, and asserts refine XP delta.pull/104/head
parent
8ebe83d701
commit
db7c443b50
|
|
@ -5,20 +5,30 @@ meta {
|
|||
}
|
||||
|
||||
docs {
|
||||
NEO-70: craft without seeded materials denies with insufficient_materials. Requires empty bag (run before spine or on fresh server).
|
||||
NEO-70: make_field_stim_mk0 without refined_plate_stock denies with insufficient_materials. Pre-request clears refined stock (inventory POST setup only) so the deny is stable after dotnet test / prior Bruno requests.
|
||||
}
|
||||
|
||||
script:pre-request {
|
||||
const { getInventory, sumItemQuantity } = require("./scripts/inventory-api-helper.js");
|
||||
const inventory = await getInventory(bru);
|
||||
const scrap = sumItemQuantity(inventory, "scrap_metal_bulk");
|
||||
const refined = sumItemQuantity(inventory, "refined_plate_stock");
|
||||
if (scrap >= 5 || refined > 0) {
|
||||
throw new Error(
|
||||
`expected empty craft inputs before insufficient_materials test; scrap=${scrap} refined=${refined} — restart server or run this request before spine`,
|
||||
);
|
||||
const { getInventory, sumItemQuantity, postMutation } = require("./scripts/inventory-api-helper.js");
|
||||
|
||||
async function clearItem(itemId) {
|
||||
let qty = sumItemQuantity(await getInventory(bru), itemId);
|
||||
while (qty > 0) {
|
||||
const removeQty = Math.min(qty, 99);
|
||||
const response = await postMutation(bru, {
|
||||
schemaVersion: 1,
|
||||
mutationKind: "remove",
|
||||
itemId,
|
||||
quantity: removeQty,
|
||||
});
|
||||
if (response.status !== 200 || response.data?.applied !== true) {
|
||||
throw new Error(`clear ${itemId} failed: ${response.status} ${JSON.stringify(response.data)}`);
|
||||
}
|
||||
qty = sumItemQuantity(await getInventory(bru), itemId);
|
||||
}
|
||||
}
|
||||
bru.setVar("scrapBeforeInsufficientDeny", scrap);
|
||||
|
||||
await clearItem("refined_plate_stock");
|
||||
}
|
||||
|
||||
post {
|
||||
|
|
@ -34,7 +44,7 @@ headers {
|
|||
body:json {
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"recipeId": "refine_scrap_standard"
|
||||
"recipeId": "make_field_stim_mk0"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
meta {
|
||||
name: POST craft deny inventory full
|
||||
type: http
|
||||
seq: 5
|
||||
seq: 3
|
||||
}
|
||||
|
||||
docs {
|
||||
|
|
|
|||
|
|
@ -5,15 +5,28 @@ meta {
|
|||
}
|
||||
|
||||
docs {
|
||||
NEO-70 prototype spine: gather scrap from four prototype resource nodes (delta 5 + gamma 3 + beta 2 + alpha 1 = 11 scrap), craft refine_scrap_efficient (10→2 refined_plate_stock), then make_field_stim_mk0. No inventory POST shortcuts.
|
||||
NEO-70 prototype spine: accumulate >=11 scrap_metal_bulk (gather when nodes allow, reuse persisted inventory after dotnet test), refine_scrap_efficient when refined_plate_stock < 2, then make_field_stim_mk0. No inventory POST shortcuts for spine materials.
|
||||
}
|
||||
|
||||
script:pre-request {
|
||||
const axios = require("axios");
|
||||
const { getInventory, sumItemQuantity } = require("./scripts/inventory-api-helper.js");
|
||||
const baseUrl = bru.getEnvVar("baseUrl") || bru.getVar("baseUrl");
|
||||
const playerId = bru.getEnvVar("playerId") || bru.getVar("playerId");
|
||||
const jsonHeaders = { headers: { "Content-Type": "application/json" } };
|
||||
|
||||
const progressionBefore = await axios.get(`${baseUrl}/game/players/${playerId}/skill-progression`);
|
||||
const refineBefore = progressionBefore.data.skills.find((row) => row.id === "refine");
|
||||
bru.setVar("refineXpBeforeSpine", refineBefore ? refineBefore.xp : 0);
|
||||
|
||||
async function currentScrap() {
|
||||
return sumItemQuantity(await getInventory(bru), "scrap_metal_bulk");
|
||||
}
|
||||
|
||||
async function currentRefined() {
|
||||
return sumItemQuantity(await getInventory(bru), "refined_plate_stock");
|
||||
}
|
||||
|
||||
async function moveNear(x, z) {
|
||||
await axios.post(
|
||||
`${baseUrl}/game/players/${playerId}/move`,
|
||||
|
|
@ -22,15 +35,22 @@ script:pre-request {
|
|||
);
|
||||
}
|
||||
|
||||
async function gather(interactableId) {
|
||||
async function tryGather(interactableId) {
|
||||
const response = await axios.post(
|
||||
`${baseUrl}/game/players/${playerId}/interact`,
|
||||
{ schemaVersion: 1, interactableId },
|
||||
jsonHeaders,
|
||||
);
|
||||
if (response.status !== 200 || response.data?.allowed !== true) {
|
||||
throw new Error(`gather ${interactableId} failed: ${response.status} ${JSON.stringify(response.data)}`);
|
||||
if (response.status !== 200) {
|
||||
throw new Error(`gather ${interactableId} HTTP ${response.status}`);
|
||||
}
|
||||
if (response.data?.allowed === true) {
|
||||
return;
|
||||
}
|
||||
if (response.data?.reasonCode === "node_depleted") {
|
||||
return;
|
||||
}
|
||||
throw new Error(`gather ${interactableId} denied: ${JSON.stringify(response.data)}`);
|
||||
}
|
||||
|
||||
async function craft(recipeId) {
|
||||
|
|
@ -45,16 +65,30 @@ script:pre-request {
|
|||
return response.data;
|
||||
}
|
||||
|
||||
await moveNear(16, -2);
|
||||
await gather("prototype_urban_bulk_delta");
|
||||
await moveNear(10, -2);
|
||||
await gather("prototype_bio_mat_gamma");
|
||||
await moveNear(16, -6);
|
||||
await gather("prototype_subsurface_vein_beta");
|
||||
await moveNear(10, -6);
|
||||
await gather("prototype_resource_node_alpha");
|
||||
const gatherPlan = [
|
||||
{ id: "prototype_urban_bulk_delta", x: 16, z: -2 },
|
||||
{ id: "prototype_bio_mat_gamma", x: 10, z: -2 },
|
||||
{ id: "prototype_subsurface_vein_beta", x: 16, z: -6 },
|
||||
{ id: "prototype_resource_node_alpha", x: 10, z: -6 },
|
||||
];
|
||||
|
||||
await craft("refine_scrap_efficient");
|
||||
let scrap = await currentScrap();
|
||||
for (const node of gatherPlan) {
|
||||
if (scrap >= 11) {
|
||||
break;
|
||||
}
|
||||
await moveNear(node.x, node.z);
|
||||
await tryGather(node.id);
|
||||
scrap = await currentScrap();
|
||||
}
|
||||
|
||||
if (scrap < 11) {
|
||||
throw new Error(`spine needs >=11 scrap_metal_bulk, have ${scrap} after optional gathers`);
|
||||
}
|
||||
|
||||
if ((await currentRefined()) < 2) {
|
||||
await craft("refine_scrap_efficient");
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
|
|
@ -111,7 +145,8 @@ tests {
|
|||
test("refine skill XP increased after spine crafts", function () {
|
||||
const progression = bru.getVar("spineProgression");
|
||||
const refine = progression.skills.find((row) => row.id === "refine");
|
||||
const before = bru.getVar("refineXpBeforeSpine");
|
||||
expect(refine).to.be.an("object");
|
||||
expect(refine.xp).to.be.at.least(20);
|
||||
expect(refine.xp - before).to.be.at.least(20);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,5 +3,5 @@ meta {
|
|||
}
|
||||
|
||||
docs {
|
||||
NEO-70 craft HTTP. Run order: deny requests first (seq 1–4), then spine last (seq 5). Spine uses gather interact (no inventory POST shortcuts). Deny setup requests may use inventory POST only where noted. On persistent Postgres dev stores, run insufficient_materials before spine or restart the server so dev-local-1 bag is empty.
|
||||
NEO-70 craft HTTP. Run order within folder: deny requests (seq 1–4) then spine (seq 5). Full collection runs after dotnet test on shared Postgres — insufficient-materials clears refined stock; spine reuses persisted scrap and tolerates node_depleted gathers. Deny setup requests may use inventory POST only where noted.
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue