Fix scoped active wash restoration
This commit is contained in:
+110
@@ -8704,6 +8704,116 @@ paths:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SelfServeLaneStatus'
|
||||
|
||||
/modules/self-serve/lane/wash/my-active-wash:
|
||||
get:
|
||||
tags:
|
||||
- Modules
|
||||
summary: Get the authenticated customer's active self-serve wash
|
||||
description: |
|
||||
Returns the current authenticated customer's open self-serve wash session,
|
||||
if one exists. Regular customers must only receive their own active wash
|
||||
details from this endpoint.
|
||||
operationId: getMyActiveSelfServeWash
|
||||
responses:
|
||||
'200':
|
||||
description: Authenticated customer's active wash details resolved
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
lane_id:
|
||||
type: integer
|
||||
nullable: true
|
||||
in_progress:
|
||||
type: boolean
|
||||
session:
|
||||
type: object
|
||||
nullable: true
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
lane_id:
|
||||
type: integer
|
||||
nullable: true
|
||||
department_id:
|
||||
type: integer
|
||||
nullable: true
|
||||
status:
|
||||
type: string
|
||||
reg:
|
||||
type: string
|
||||
customer_number:
|
||||
type: integer
|
||||
nullable: true
|
||||
vehicle_id:
|
||||
type: integer
|
||||
nullable: true
|
||||
vehicle_type_id:
|
||||
type: integer
|
||||
nullable: true
|
||||
included_minutes:
|
||||
type: integer
|
||||
nullable: true
|
||||
machine_type_id:
|
||||
type: integer
|
||||
nullable: true
|
||||
machine_relay_enabled:
|
||||
type: boolean
|
||||
machine_relay_enabled_at:
|
||||
type: string
|
||||
nullable: true
|
||||
machine_start_triggered:
|
||||
type: boolean
|
||||
machine_start_triggered_at:
|
||||
type: string
|
||||
nullable: true
|
||||
wash_started_at:
|
||||
type: string
|
||||
nullable: true
|
||||
created_at:
|
||||
type: string
|
||||
updated_at:
|
||||
type: string
|
||||
nullable: true
|
||||
customer:
|
||||
type: object
|
||||
nullable: true
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
nullable: true
|
||||
customer_number:
|
||||
type: integer
|
||||
nullable: true
|
||||
display_name:
|
||||
type: string
|
||||
nullable: true
|
||||
email:
|
||||
type: string
|
||||
nullable: true
|
||||
phone_country_code:
|
||||
type: integer
|
||||
nullable: true
|
||||
phone:
|
||||
type: string
|
||||
nullable: true
|
||||
vehicle:
|
||||
type: object
|
||||
nullable: true
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
customer_id:
|
||||
type: integer
|
||||
type:
|
||||
type: integer
|
||||
reg:
|
||||
type: string
|
||||
reference:
|
||||
type: string
|
||||
nullable: true
|
||||
|
||||
/modules/self-serve/lane/wash/in-progress:
|
||||
get:
|
||||
tags:
|
||||
|
||||
@@ -654,18 +654,28 @@ const fetchSelfServeData = async () => {
|
||||
await fetchSelfServeDataInternal(departmentId, vehicleTypeSelect.value || null, laneId, normalizedReg);
|
||||
};
|
||||
|
||||
const getServerActiveWashCandidates = () => {
|
||||
const SERVER_ACTIVE_WASH_ENDPOINT = "/modules/self-serve/lane/wash/my-active-wash";
|
||||
|
||||
const findServerActiveWashCandidate = (laneId: number | string | null) => {
|
||||
const normalizedLaneId = normalizeLaneId(laneId);
|
||||
if (!normalizedLaneId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const departments = Array.isArray(guestDepartments.value) ? guestDepartments.value : [];
|
||||
return departments.flatMap((department: any) => {
|
||||
for (const department of departments) {
|
||||
const lanes = Array.isArray(department?.lanes) ? department.lanes : [];
|
||||
return lanes
|
||||
.map((lane: any) => ({
|
||||
const lane = lanes.find((candidateLane: any) => normalizeLaneId(candidateLane?.id) === normalizedLaneId);
|
||||
if (lane) {
|
||||
return {
|
||||
department,
|
||||
lane,
|
||||
laneId: normalizeLaneId(lane?.id),
|
||||
}))
|
||||
.filter((candidate: any) => candidate.laneId);
|
||||
});
|
||||
laneId: normalizedLaneId,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return { laneId: normalizedLaneId };
|
||||
};
|
||||
|
||||
const isAuthenticatedCustomerActiveWash = (details: any, customerNumber: number) => {
|
||||
@@ -769,31 +779,24 @@ const fetchServerActiveWash = async () => {
|
||||
return null;
|
||||
}
|
||||
|
||||
const candidates = getServerActiveWashCandidates();
|
||||
if (candidates.length === 0) {
|
||||
const response = await SessionUser.request(SERVER_ACTIVE_WASH_ENDPOINT, "GET");
|
||||
const details = unwrapApiData(response);
|
||||
if (!isAuthenticatedCustomerActiveWash(details, customerNumber)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const responses = await Promise.allSettled(
|
||||
candidates.map(async (candidate: any) => {
|
||||
const response = await SessionUser.request("/modules/self-serve/lane/wash/in-progress", "GET", {
|
||||
lane_id: candidate.laneId,
|
||||
});
|
||||
return {
|
||||
...candidate,
|
||||
details: unwrapApiData(response),
|
||||
};
|
||||
})
|
||||
);
|
||||
const laneId = normalizeLaneId(details?.lane_id ?? details?.session?.lane_id);
|
||||
const activeWashCandidate = findServerActiveWashCandidate(laneId);
|
||||
const activeWash = {
|
||||
...(activeWashCandidate || {}),
|
||||
details,
|
||||
};
|
||||
|
||||
const activeMatches = responses
|
||||
.filter((entry): entry is PromiseFulfilledResult<any> => entry.status === "fulfilled")
|
||||
.map((entry) => entry.value)
|
||||
.filter((entry) => isAuthenticatedCustomerActiveWash(entry.details, customerNumber))
|
||||
.filter((entry) => !isRecentlyCompletedActiveWash(entry))
|
||||
.sort((left, right) => activeWashTimestamp(right.details) - activeWashTimestamp(left.details));
|
||||
if (isRecentlyCompletedActiveWash(activeWash)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return activeMatches[0] || null;
|
||||
return activeWash;
|
||||
};
|
||||
|
||||
const applyServerActiveWash = async (activeWash: any) => {
|
||||
|
||||
@@ -6506,6 +6506,26 @@ export async function mockApi(page, options = {}) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pathname.endsWith("/modules/self-serve/lane/wash/my-active-wash") && method === "GET") {
|
||||
const customerNumber = Number(options.sessionData?.customer_number || 0);
|
||||
const details = Object.values(selfServe.inProgressByLaneId || {}).find((entry) => {
|
||||
const entryCustomerNumber = Number(entry?.session?.customer_number ?? entry?.customer?.customer_number ?? 0);
|
||||
return Boolean(entry?.in_progress) && customerNumber > 0 && entryCustomerNumber === customerNumber;
|
||||
});
|
||||
await route.fulfill(
|
||||
json({
|
||||
data: details || {
|
||||
lane_id: null,
|
||||
in_progress: false,
|
||||
session: null,
|
||||
customer: null,
|
||||
vehicle: null,
|
||||
},
|
||||
})
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pathname.endsWith("/modules/self-serve/lane/wash/in-progress") && method === "GET") {
|
||||
const laneId = parsedUrl.searchParams.get("lane_id");
|
||||
const details = selfServe.inProgressByLaneId?.[String(laneId || "")] || null;
|
||||
|
||||
@@ -826,7 +826,7 @@ describe("MyWashStart", () => {
|
||||
it("retries server active wash restore when the authenticated customer number arrives after mount", async () => {
|
||||
mocks.sessionCustomerNumber.value = null;
|
||||
mocks.sessionRequest.mockImplementation(async (path, method, payload) => {
|
||||
if (path === "/modules/self-serve/lane/wash/in-progress" && method === "GET" && payload?.lane_id === 7) {
|
||||
if (path === "/modules/self-serve/lane/wash/my-active-wash" && method === "GET") {
|
||||
return {
|
||||
data: {
|
||||
data: {
|
||||
@@ -882,9 +882,7 @@ describe("MyWashStart", () => {
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
await flushPromises();
|
||||
|
||||
expect(mocks.sessionRequest).toHaveBeenCalledWith("/modules/self-serve/lane/wash/in-progress", "GET", {
|
||||
lane_id: 7,
|
||||
});
|
||||
expect(mocks.sessionRequest).toHaveBeenCalledWith("/modules/self-serve/lane/wash/my-active-wash", "GET");
|
||||
expect(mocks.fetchWashSummary).toHaveBeenCalledWith({ session_id: 805, vehicle_type: 2 }, false);
|
||||
expect(mocks.startElapsedTimer).toHaveBeenCalled();
|
||||
expect(
|
||||
@@ -1155,7 +1153,10 @@ describe("MyWashStart", () => {
|
||||
};
|
||||
mocks.guestDepartments.value = [mocks.nearestDepartment.value, odense];
|
||||
mocks.sessionRequest.mockImplementation(async (path, method, payload) => {
|
||||
if (path === "/modules/self-serve/lane/wash/in-progress" && method === "GET" && payload?.lane_id === 9) {
|
||||
if (
|
||||
(path === "/modules/self-serve/lane/wash/my-active-wash" && method === "GET") ||
|
||||
(path === "/modules/self-serve/lane/wash/in-progress" && method === "GET" && payload?.lane_id === 9)
|
||||
) {
|
||||
return {
|
||||
data: {
|
||||
data: {
|
||||
@@ -1199,12 +1200,10 @@ describe("MyWashStart", () => {
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
await flushPromises();
|
||||
|
||||
expect(mocks.sessionRequest).toHaveBeenCalledWith("/modules/self-serve/lane/wash/in-progress", "GET", {
|
||||
expect(mocks.sessionRequest).toHaveBeenCalledWith("/modules/self-serve/lane/wash/my-active-wash", "GET");
|
||||
expect(mocks.sessionRequest).not.toHaveBeenCalledWith("/modules/self-serve/lane/wash/in-progress", "GET", {
|
||||
lane_id: 7,
|
||||
});
|
||||
expect(mocks.sessionRequest).toHaveBeenCalledWith("/modules/self-serve/lane/wash/in-progress", "GET", {
|
||||
lane_id: 9,
|
||||
});
|
||||
expect(mocks.fetchWashSummary).toHaveBeenCalledWith({ session_id: 704, vehicle_type: 2 }, false);
|
||||
expect(mocks.startElapsedTimer).toHaveBeenCalled();
|
||||
expect(mocks.saveProgress).toHaveBeenCalledWith("serverActiveWash");
|
||||
@@ -1226,7 +1225,7 @@ describe("MyWashStart", () => {
|
||||
})
|
||||
);
|
||||
mocks.sessionRequest.mockImplementation(async (path, method, payload) => {
|
||||
if (path === "/modules/self-serve/lane/wash/in-progress" && method === "GET" && payload?.lane_id === 7) {
|
||||
if (path === "/modules/self-serve/lane/wash/my-active-wash" && method === "GET") {
|
||||
return {
|
||||
data: {
|
||||
data: {
|
||||
@@ -1270,9 +1269,7 @@ describe("MyWashStart", () => {
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
await flushPromises();
|
||||
|
||||
expect(mocks.sessionRequest).toHaveBeenCalledWith("/modules/self-serve/lane/wash/in-progress", "GET", {
|
||||
lane_id: 7,
|
||||
});
|
||||
expect(mocks.sessionRequest).toHaveBeenCalledWith("/modules/self-serve/lane/wash/my-active-wash", "GET");
|
||||
expect(mocks.fetchWashSummary).not.toHaveBeenCalled();
|
||||
expect(mocks.startElapsedTimer).not.toHaveBeenCalled();
|
||||
expect(mocks.saveProgress).not.toHaveBeenCalledWith("serverActiveWash");
|
||||
|
||||
Reference in New Issue
Block a user