meta { name: GET quest progress after gather intro complete type: http seq: 8 } docs { NEO-129: accept gather intro, complete via alpha gathers, GET quest-progress asserts completionRewardSummary; second GET unchanged. Pre-request resets resource nodes, inventory, and gather quest progress so the test is self-contained within a full collection run. } script:pre-request { const { resetGatherIntroSpine } = require("./scripts/bruno-dev-fixture-helper"); await resetGatherIntroSpine(bru); const axios = require("axios"); const baseUrl = bru.getEnvVar("baseUrl") || bru.getVar("baseUrl"); const playerId = bru.getEnvVar("playerId") || bru.getVar("playerId"); const headers = { "Content-Type": "application/json" }; const gatherQuestId = "prototype_quest_gather_intro"; const alphaNodeId = "prototype_resource_node_alpha"; function gatherRow(body) { return body.quests.find((x) => x.questId === gatherQuestId); } async function getQuestProgress() { const response = await axios.get( `${baseUrl}/game/players/${playerId}/quest-progress`, { validateStatus: () => true }, ); if (response.status !== 200) { throw new Error(`quest-progress GET failed: ${response.status}`); } return response.data; } async function moveNearAlpha() { await axios.post( `${baseUrl}/game/players/${playerId}/move`, { schemaVersion: 1, target: { x: 10, y: 0.9, z: -6 }, }, { headers }, ); } async function tryGatherAlpha() { const interact = await axios.post( `${baseUrl}/game/players/${playerId}/interact`, { schemaVersion: 1, interactableId: alphaNodeId, }, { headers, validateStatus: () => true }, ); if (interact.status !== 200) { throw new Error(`gather interact HTTP ${interact.status}: ${JSON.stringify(interact.data)}`); } if (interact.data?.allowed === true) { return; } if (interact.data?.reasonCode === "node_depleted") { return; } if (interact.data?.reasonCode === "out_of_range") { await moveNearAlpha(); const retry = await axios.post( `${baseUrl}/game/players/${playerId}/interact`, { schemaVersion: 1, interactableId: alphaNodeId, }, { headers, validateStatus: () => true }, ); if (retry.status !== 200) { throw new Error(`gather interact retry HTTP ${retry.status}: ${JSON.stringify(retry.data)}`); } if (retry.data?.allowed === true || retry.data?.reasonCode === "node_depleted") { return; } throw new Error(`gather interact denied after move: ${JSON.stringify(retry.data)}`); } throw new Error(`gather interact denied: ${JSON.stringify(interact.data)}`); } const accept = await axios.post( `${baseUrl}/game/players/${playerId}/quests/${gatherQuestId}/accept`, { schemaVersion: 1 }, { headers, validateStatus: () => true }, ); if (accept.status !== 200 || accept.data?.accepted !== true) { throw new Error(`gather intro accept failed: ${accept.status} ${JSON.stringify(accept.data)}`); } await moveNearAlpha(); let progress = await getQuestProgress(); let row = gatherRow(progress); for (let attempt = 0; attempt < 8; attempt += 1) { progress = await getQuestProgress(); row = gatherRow(progress); if (row?.status === "completed" && row.completionRewardSummary) { break; } await tryGatherAlpha(); } progress = await getQuestProgress(); row = gatherRow(progress); if (!row || row.status !== "completed" || !row.completionRewardSummary) { throw new Error( `expected gather intro completed with summary, got ${JSON.stringify(row)}`, ); } bru.setVar( "firstGatherCompletionRewardSummary", JSON.stringify(row.completionRewardSummary), ); } get { url: {{baseUrl}}/game/players/{{playerId}}/quest-progress body: none auth: none } tests { test("gather intro row is completed with completionRewardSummary", function () { expect(res.getStatus()).to.equal(200); const body = res.getBody(); const row = body.quests.find((x) => x.questId === "prototype_quest_gather_intro"); expect(row).to.be.an("object"); expect(row.status).to.equal("completed"); expect(row.completionRewardSummary).to.be.an("object"); expect(row.completionRewardSummary.itemGrants).to.eql([]); expect(row.completionRewardSummary.skillXpGrants).to.eql([ { skillId: "salvage", amount: 25 }, ]); }); test("second GET completionRewardSummary matches first GET", function () { const body = res.getBody(); const row = body.quests.find((x) => x.questId === "prototype_quest_gather_intro"); const firstSummary = JSON.parse(bru.getVar("firstGatherCompletionRewardSummary")); expect(row.completionRewardSummary).to.eql(firstSummary); }); test("active and not_started rows omit completionRewardSummary", function () { const body = res.getBody(); for (const row of body.quests) { if (row.status === "not_started" || row.status === "active") { expect(row.completionRewardSummary).to.equal(undefined); } } }); }