meta {
  name: GET inventory
  type: http
  seq: 1
}

docs {
  NEO-55: per-player inventory read model; join with GET /game/world/item-definitions for stackMax and slot kinds.
  Order-independent: validates fixed slot arrays and slot JSON shape only (not empty-grid assumptions).
}

get {
  url: {{baseUrl}}/game/players/{{playerId}}/inventory
  body: none
  auth: none
}

tests {
  test("returns 200 JSON with schema v1 and fixed slot arrays", function () {
    expect(res.getStatus()).to.equal(200);
    expect(res.getHeader("content-type")).to.contain("application/json");
    const body = res.getBody();
    expect(body.schemaVersion).to.equal(1);
    expect(body.playerId).to.equal(bru.getEnvVar("playerId") || bru.getVar("playerId"));
    expect(body.bagSlots).to.be.an("array");
    expect(body.bagSlots.length).to.equal(24);
    expect(body.equipmentSlots).to.be.an("array");
    expect(body.equipmentSlots.length).to.equal(1);
  });

  test("empty slots omit itemId; occupied slots include itemId and positive quantity", function () {
    const body = res.getBody();
    const assertSlotShape = (slot) => {
      expect(slot.slotIndex).to.be.a("number");
      expect(slot.quantity).to.be.a("number");
      expect(slot.quantity).to.be.at.least(0);
      if (slot.quantity === 0) {
        expect(slot.itemId).to.equal(undefined);
      } else {
        expect(slot.itemId).to.be.a("string");
        expect(slot.itemId.length).to.be.at.least(1);
      }
    };
    for (const slot of body.bagSlots) {
      assertSlotShape(slot);
    }
    assertSlotShape(body.equipmentSlots[0]);
  });
}
