diff --git a/cypress/fixtures/reservation-list/work-bestrepresentation.json b/cypress/fixtures/reservation-list/work-bestrepresentation.json new file mode 100644 index 0000000000..3f07f736b5 --- /dev/null +++ b/cypress/fixtures/reservation-list/work-bestrepresentation.json @@ -0,0 +1,50 @@ +{ + "data": { + "manifestation": { + "ownerWork": { + "manifestations": { + "bestRepresentation": { + "pid": "870970-basis:22629344", + "titles": { + "full": [ + "Best representation of dummy title" + ] + }, + "abstract": [ + "Dummy Some abstract ..." + ], + "edition": { + "summary": "3. udgave, 1. oplag (2019)", + "publicationYear": { + "display": "2006" + } + }, + "materialTypes": [ + { + "specific": "Dummy bog" + } + ], + "series": [ + { + "numberInSeries": { + "number": [ + 1 + ] + }, + "title": "Detektivbureau Nr. 2" + } + ], + "creators": [ + { + "display": "Dummy Jens Jensen" + }, + { + "display": "Dummy Some Corporation" + } + ] + } + } + } + } + } +} diff --git a/src/apps/loan-list/materials/utils/material-fetch-hoc.tsx b/src/apps/loan-list/materials/utils/material-fetch-hoc.tsx index 1111f42274..12be138543 100644 --- a/src/apps/loan-list/materials/utils/material-fetch-hoc.tsx +++ b/src/apps/loan-list/materials/utils/material-fetch-hoc.tsx @@ -1,5 +1,9 @@ import React, { useEffect, useState, ComponentType, FC } from "react"; -import { useGetManifestationViaMaterialByFaustQuery } from "../../../../core/dbc-gateway/generated/graphql"; +import { + ManifestationBasicDetailsFragment, + useGetManifestationViaBestRepresentationByFaustQuery, + useGetManifestationViaMaterialByFaustQuery +} from "../../../../core/dbc-gateway/generated/graphql"; import { Product } from "../../../../core/publizon/model"; import { BasicDetailsType } from "../../../../core/utils/types/basic-details-type"; import { mapManifestationToBasicDetailsType } from "../../../../core/utils/helpers/list-mapper"; @@ -35,21 +39,33 @@ const fetchMaterial = if (item?.faust) { const [material, setMaterial] = useState(); - const { isSuccess: isSuccessManifestation, data } = - useGetManifestationViaMaterialByFaustQuery({ + let manifestation: ManifestationBasicDetailsFragment | null = null; + if (item.reservationIds && item.reservationIds.length > 1) { + const { isSuccess, data } = + useGetManifestationViaBestRepresentationByFaustQuery({ + faust: item.faust + }); + if (isSuccess && data?.manifestation) { + manifestation = + data.manifestation.ownerWork.manifestations.bestRepresentation; + } + } else { + const { isSuccess, data } = useGetManifestationViaMaterialByFaustQuery({ faust: item.faust }); + if (isSuccess && data?.manifestation) { + manifestation = data.manifestation; + } + } useEffect(() => { - if (data && isSuccessManifestation && data.manifestation) { - setMaterial(mapManifestationToBasicDetailsType(data)); - } else { - // todo error handling, missing in figma + if (manifestation) { + setMaterial(mapManifestationToBasicDetailsType(manifestation)); } - }, [isSuccessManifestation, data]); + }, [manifestation]); // in cases where the material is not found we return null, else we would load forever - if (data && data.manifestation === null) return null; + if (manifestation === null) return null; // if the fallback component is provided we can show it while the data is loading if (!material) return FallbackComponent ? : null; diff --git a/src/apps/reservation-list/list/reservation-list.test.ts b/src/apps/reservation-list/list/reservation-list.test.ts index b1fcde8931..08bfaa59ea 100644 --- a/src/apps/reservation-list/list/reservation-list.test.ts +++ b/src/apps/reservation-list/list/reservation-list.test.ts @@ -806,6 +806,89 @@ describe("Reservation list", () => { .should("exist") .should("have.text", "At the moment you have 0 reservations"); }); + + it("Reservations list shows parallel reservation", () => { + cy.intercept( + "GET", + "**/external/v1/agencyid/patrons/patronid/reservations/v2**", + { + statusCode: 200, + body: [ + { + reservationId: 67804976, + recordId: "46985591", + state: "reserved", + pickupBranch: "DK-775100", + pickupDeadline: null, + expiryDate: "2022-09-21", + dateOfReservation: "2022-06-14T09:00:50.059", + numberInQueue: 1, + periodical: null, + pickupNumber: null, + ilBibliographicRecord: null, + // We have two reservations with the same transactionId which makes + // it a parallel reservation. + transactionId: "c6742151-f4a7-4655-a94f-7bd6a0009431", + reservationType: "parallel" + }, + { + reservationId: 67804977, + recordId: "46985592", + state: "reserved", + pickupBranch: "DK-775100", + pickupDeadline: null, + expiryDate: "2022-09-21", + dateOfReservation: "2022-06-14T09:00:50.059", + numberInQueue: 1, + periodical: null, + pickupNumber: null, + ilBibliographicRecord: null, + transactionId: "c6742151-f4a7-4655-a94f-7bd6a0009431", + reservationType: "parallel" + } + ] + } + ).as("physical_reservations"); + + cy.intercept("GET", "**/v1/user/**", { + statusCode: 200, + body: { + reservations: [], + code: 101, + message: "OK" + } + }).as("digital_reservations"); + + cy.visit( + "/iframe.html?path=/story/apps-reservation-list--reservation-list-entry" + ); + + cy.interceptRest({ + aliasName: "work-bestrepresentation", + httpMethod: "POST", + url: "**/next/**", + fixtureFilePath: "reservation-list/work-bestrepresentation.json" + }); + + cy.getBySel("list-reservation-container") + .find(".list-reservation") + // Even though we return multiple reservations they are parallel and + // should be represented as one. + .should("have.length", 1) + .get(".list-reservation__header") + // The title should be the one returned by the best representation + // fixture. + .should("contain", "Best representation of dummy title") + // Open the modal to see the details. + .click(); + + cy.getBySel("modal") + // Modal should be open. + .should("exist") + .find(".modal-details__title") + // Details should also contain the best representation title. + .should("contain", "Best representation of dummy title"); + }); }); export default {}; diff --git a/src/core/utils/helpers/list-mapper.ts b/src/core/utils/helpers/list-mapper.ts index b457314dd8..eb380182fb 100644 --- a/src/core/utils/helpers/list-mapper.ts +++ b/src/core/utils/helpers/list-mapper.ts @@ -1,7 +1,7 @@ import { head, keys, values } from "lodash"; import { LoanV2, ReservationDetailsV2 } from "../../fbs/model"; import { FaustId } from "../types/ids"; -import { GetManifestationViaMaterialByFaustQuery } from "../../dbc-gateway/generated/graphql"; +import { ManifestationBasicDetailsFragment } from "../../dbc-gateway/generated/graphql"; import { BasicDetailsType } from "../types/basic-details-type"; import { Product, Loan, Reservation } from "../../publizon/model"; import { LoanType } from "../types/loan-type"; @@ -122,7 +122,7 @@ export const mapProductToBasicDetailsType = (material: Product) => { // so digital/physical loans/reservations can use the same components, // as their UI is often quite similar export const mapManifestationToBasicDetailsType = ( - material: GetManifestationViaMaterialByFaustQuery + material: ManifestationBasicDetailsFragment ) => { const { edition, @@ -133,7 +133,7 @@ export const mapManifestationToBasicDetailsType = ( creators, series, languages - } = material?.manifestation || {}; + } = material; const isoCode = languages?.main?.[0]?.isoCode ?? ""; const description = abstract ? abstract[0] : ""; const {