fix: scope map object zone links
This commit is contained in:
parent
44cc376e1b
commit
34c818b035
@ -280,9 +280,26 @@ async function getMapItems(db, householdId, locationId) {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function insertObjects(db, mapId, objects) {
|
async function getActiveZoneIds(db, householdId, locationId) {
|
||||||
|
const result = await db.query(
|
||||||
|
`SELECT id
|
||||||
|
FROM store_location_zones
|
||||||
|
WHERE household_id = $1
|
||||||
|
AND store_location_id = $2
|
||||||
|
AND is_active = TRUE`,
|
||||||
|
[householdId, locationId]
|
||||||
|
);
|
||||||
|
|
||||||
|
return new Set(result.rows.map((row) => Number(row.id)));
|
||||||
|
}
|
||||||
|
|
||||||
|
async function insertObjects(db, mapId, objects, validZoneIds = null) {
|
||||||
for (let index = 0; index < objects.length; index += 1) {
|
for (let index = 0; index < objects.length; index += 1) {
|
||||||
const object = sanitizeObjectPayload(objects[index], index);
|
const object = sanitizeObjectPayload(objects[index], index);
|
||||||
|
const scopedZoneId =
|
||||||
|
object.zone_id && validZoneIds && !validZoneIds.has(Number(object.zone_id))
|
||||||
|
? null
|
||||||
|
: object.zone_id;
|
||||||
await db.query(
|
await db.query(
|
||||||
`INSERT INTO location_map_objects
|
`INSERT INTO location_map_objects
|
||||||
(
|
(
|
||||||
@ -303,7 +320,7 @@ async function insertObjects(db, mapId, objects) {
|
|||||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13::jsonb)`,
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13::jsonb)`,
|
||||||
[
|
[
|
||||||
mapId,
|
mapId,
|
||||||
object.zone_id,
|
scopedZoneId,
|
||||||
object.type,
|
object.type,
|
||||||
object.label,
|
object.label,
|
||||||
object.x,
|
object.x,
|
||||||
@ -442,8 +459,9 @@ exports.saveDraft = async (householdId, locationId, userId, payload = {}) => {
|
|||||||
try {
|
try {
|
||||||
await client.query("BEGIN");
|
await client.query("BEGIN");
|
||||||
const map = await upsertDraftMap(client, householdId, locationId, userId, payload.map || {});
|
const map = await upsertDraftMap(client, householdId, locationId, userId, payload.map || {});
|
||||||
|
const validZoneIds = await getActiveZoneIds(client, householdId, locationId);
|
||||||
await client.query("DELETE FROM location_map_objects WHERE location_map_id = $1", [map.id]);
|
await client.query("DELETE FROM location_map_objects WHERE location_map_id = $1", [map.id]);
|
||||||
await insertObjects(client, map.id, Array.isArray(payload.objects) ? payload.objects : []);
|
await insertObjects(client, map.id, Array.isArray(payload.objects) ? payload.objects : [], validZoneIds);
|
||||||
await client.query("COMMIT");
|
await client.query("COMMIT");
|
||||||
return exports.getMapState(householdId, locationId, true);
|
return exports.getMapState(householdId, locationId, true);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
76
backend/tests/location-map.model.test.js
Normal file
76
backend/tests/location-map.model.test.js
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
jest.mock("../db/pool", () => ({
|
||||||
|
connect: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const pool = require("../db/pool");
|
||||||
|
const LocationMap = require("../models/location-map.model");
|
||||||
|
|
||||||
|
function createClient() {
|
||||||
|
return {
|
||||||
|
query: jest.fn(),
|
||||||
|
release: jest.fn(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("location-map.model", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("unlinks saved map objects from zones outside the current location", async () => {
|
||||||
|
const client = createClient();
|
||||||
|
pool.connect.mockResolvedValue(client);
|
||||||
|
const getMapStateSpy = jest.spyOn(LocationMap, "getMapState").mockResolvedValue({
|
||||||
|
draft_map: { id: 900 },
|
||||||
|
draft_objects: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
client.query.mockImplementation(async (sql) => {
|
||||||
|
if (sql === "BEGIN" || sql === "COMMIT") {
|
||||||
|
return { rows: [], rowCount: 0 };
|
||||||
|
}
|
||||||
|
if (String(sql).includes("INSERT INTO location_maps")) {
|
||||||
|
return {
|
||||||
|
rows: [
|
||||||
|
{
|
||||||
|
id: 900,
|
||||||
|
household_id: 1,
|
||||||
|
store_location_id: 10,
|
||||||
|
name: "Store Map",
|
||||||
|
width: 1000,
|
||||||
|
height: 700,
|
||||||
|
status: "draft",
|
||||||
|
version: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (String(sql).includes("FROM store_location_zones")) {
|
||||||
|
return { rows: [{ id: 501 }] };
|
||||||
|
}
|
||||||
|
return { rows: [], rowCount: 0 };
|
||||||
|
});
|
||||||
|
|
||||||
|
await LocationMap.saveDraft(1, 10, 42, {
|
||||||
|
objects: [
|
||||||
|
{ zone_id: 501, label: "Valid zone" },
|
||||||
|
{ zone_id: 999, label: "Foreign zone" },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const insertCalls = client.query.mock.calls.filter(([sql]) =>
|
||||||
|
String(sql).includes("INSERT INTO location_map_objects")
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(insertCalls).toHaveLength(2);
|
||||||
|
expect(insertCalls[0][1][1]).toBe(501);
|
||||||
|
expect(insertCalls[1][1][1]).toBeNull();
|
||||||
|
expect(client.query).toHaveBeenCalledWith(
|
||||||
|
expect.stringContaining("FROM store_location_zones"),
|
||||||
|
[1, 10]
|
||||||
|
);
|
||||||
|
expect(getMapStateSpy).toHaveBeenCalledWith(1, 10, true);
|
||||||
|
expect(client.query).toHaveBeenCalledWith("COMMIT");
|
||||||
|
expect(client.release).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue
Block a user