Skip to content

Commit

Permalink
Merge pull request #796 from danskernesdigitalebibliotek/DDFLSBP-318-…
Browse files Browse the repository at this point in the history
…tilfoje-konfiguration-af-soge-vs-visningsprofil

Expanding fetching system for FBI to handle multiple urls
  • Loading branch information
spaceo authored Jan 16, 2024
2 parents 72b39fa + c73e842 commit fba97ef
Show file tree
Hide file tree
Showing 18 changed files with 180 additions and 28 deletions.
2 changes: 1 addition & 1 deletion cypress/support/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Cypress.Commands.add(
fixtureFilePath,
statusCode = 200
}: InterceptGraphqlParams) => {
cy.intercept("POST", "**/next/graphql", (req) => {
cy.intercept("POST", "**/next*/graphql", (req) => {
if (hasOperationName(req, operationName)) {
if (fixtureFilePath) {
req.reply({ fixture: fixtureFilePath, statusCode });
Expand Down
2 changes: 1 addition & 1 deletion src/apps/dashboard/dashboard.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1276,7 +1276,7 @@ describe("Dashboard", () => {
}
).as("reservations");

cy.intercept("POST", "**/next/**", {
cy.intercept("POST", "**/next*/**", {
statusCode: 200,
body: {
data: {
Expand Down
2 changes: 1 addition & 1 deletion src/apps/favorites-list/favorites-list.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ describe("Favorites list", () => {
});

cy.interceptRest({
url: "**/next/**",
url: "**/next*/**",
httpMethod: "POST",
fixtureFilePath: "favorites-list/work.json",
aliasName: "work"
Expand Down
2 changes: 1 addition & 1 deletion src/apps/fee-list/fee-list.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ describe("Fee list", () => {
]
}).as("fees");

cy.intercept("POST", "**/next/**", {
cy.intercept("POST", "**/next*/**", {
statusCode: 200,
body: {
data: {
Expand Down
2 changes: 1 addition & 1 deletion src/apps/loan-list/list/loan-list.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ describe("Loan list", () => {
})
.as("cover");

cy.intercept("POST", "**/next/**", {
cy.intercept("POST", "**/next*/**", {
statusCode: 200,
body: {
data: {
Expand Down
2 changes: 1 addition & 1 deletion src/apps/loan-list/modal/modals.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ describe("Modals", () => {
]
}).as("loans");

cy.intercept("POST", "**/next/**", {
cy.intercept("POST", "**/next*/**", {
statusCode: 200,
body: {
data: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ describe("Reservation list pagination", () => {
}
}).as("digital_reservations");

cy.intercept("POST", "**/next/**", {
cy.intercept("POST", "**/next*/**", {
statusCode: 200,
body: {
data: {
Expand Down
4 changes: 2 additions & 2 deletions src/apps/reservation-list/list/reservation-list.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ describe("Reservation list", () => {
cy.interceptRest({
aliasName: "work",
httpMethod: "POST",
url: "**/next/**",
url: "**/next*/**",
fixtureFilePath: "reservation-list/work.json"
});

Expand Down Expand Up @@ -850,7 +850,7 @@ describe("Reservation list", () => {
cy.interceptRest({
aliasName: "work-bestrepresentation",
httpMethod: "POST",
url: "**/next/**",
url: "**/next*/**",
fixtureFilePath: "reservation-list/work-bestrepresentation.json"
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ describe("Delete reservation modal", () => {
]
}).as("get-reservations");

cy.intercept("POST", "**/next/**", {
cy.intercept("POST", "**/next*/**", {
statusCode: 200,
body: {
data: {
Expand Down Expand Up @@ -281,7 +281,7 @@ describe("Delete reservation modal", () => {
cy.interceptRest({
aliasName: "get-manifestation",
httpMethod: "POST",
url: "**/next/**",
url: "**/next*/**",
fixtureFilePath: "reservation-list/work-bestrepresentation.json"
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ describe("Reservation details modal", () => {
cy.interceptRest({
aliasName: "work",
httpMethod: "POST",
url: "**/next/**",
url: "**/next*/**",
fixtureFilePath: "reservation-list/work.json"
});

Expand Down Expand Up @@ -628,7 +628,7 @@ describe("Reservation details modal", () => {
cy.interceptRest({
aliasName: "work",
httpMethod: "POST",
url: "**/next/**",
url: "**/next*/**",
fixtureFilePath: "reservation-list/work.json"
});

Expand Down Expand Up @@ -727,7 +727,7 @@ describe("Reservation details modal", () => {
cy.interceptRest({
aliasName: "work",
httpMethod: "POST",
url: "**/next/**",
url: "**/next*/**",
fixtureFilePath: "reservation-list/work-bestrepresentation.json"
});

Expand Down
2 changes: 1 addition & 1 deletion src/apps/search-header/search-header.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ describe("Search header app", () => {
beforeEach(() => {
cy.fixture("search-header-data.json")
.then((result) => {
cy.intercept("POST", "**/next/graphql", {
cy.intercept("POST", "**/next*/graphql", {
statusCode: 200,
body: result
});
Expand Down
2 changes: 1 addition & 1 deletion src/apps/search-result/search-result.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ describe("Search Result", () => {
// Intercept graphql search query.
cy.fixture("search-result/fbi-api.json")
.then((result) => {
cy.intercept("POST", "**/next/graphql**", result);
cy.intercept("POST", "**/next*/graphql**", result);
})
.as("Graphql search query");
// Intercept all images from Cloudinary.
Expand Down
13 changes: 7 additions & 6 deletions src/core/dbc-gateway/graphql-fetcher.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import { QueryFunctionContext } from "react-query";
import FetchFailedCriticalError from "../fetchers/FetchFailedCriticalError";
import { getToken, TOKEN_LIBRARY_KEY, TOKEN_USER_KEY } from "../token";
import {
getServiceBaseUrl,
serviceUrlKeys
} from "../utils/reduxMiddleware/extractServiceBaseUrls";
import DbcGateWayHttpError from "./DbcGateWayHttpError";
import { getQueryUrlFromContext } from "./helper";

export const fetcher = <TData, TVariables>(
query: string,
variables?: TVariables
) => {
return (): Promise<TData> => {
return (context?: QueryFunctionContext): Promise<TData> => {
// Resolve the url based on the query name if present.
const url = getQueryUrlFromContext(context);

// The whole concept of agency id, profile and and bearer token needs to be refined.
// First version is with a library token.
const token = getToken(TOKEN_USER_KEY) || getToken(TOKEN_LIBRARY_KEY);
Expand All @@ -22,7 +23,7 @@ export const fetcher = <TData, TVariables>(
? ({ Authorization: `Bearer ${token}` } as object)
: {};

return fetch(getServiceBaseUrl(serviceUrlKeys.fbi), {
return fetch(url, {
method: "POST",
...{
headers: {
Expand Down
102 changes: 102 additions & 0 deletions src/core/dbc-gateway/helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { QueryFunctionContext } from "react-query";
import { beforeAll, vi } from "vitest";
import { getServiceBaseUrl } from "../utils/reduxMiddleware/extractServiceBaseUrls";
import queryMap from "./queryMap";

type Baseurl = typeof queryMap[keyof typeof queryMap];

export const resolveBaseUrl = (query?: string) => {
if (!query) {
return getServiceBaseUrl(queryMap.default) as Baseurl;
}

return getServiceBaseUrl(
queryMap[query as keyof typeof queryMap] || queryMap.default
) as Baseurl;
};

export const getQueryUrlFromContext = (
context: QueryFunctionContext | undefined
) => {
// Get the default base url if no context.
if (!context) {
return resolveBaseUrl();
}

const { queryKey } = context;
const [queryName] = queryKey;
return resolveBaseUrl(queryName as string);
};

export default {};

/* ********************************* Vitest Section ********************************* */
if (import.meta.vitest) {
const { describe, expect, it } = import.meta.vitest;

describe("DBC Gateway Requests", () => {
beforeAll(() => {
vi.mock("../utils/reduxMiddleware/extractServiceBaseUrls", async () => {
const urls = {
fbiBaseUrl: "i-am-fbi-url",
fbiSearchBaseUrl: "i-am-fbi-search-url",
fbiMaterialBaseUrl: "i-am-fbi-material-url"
} as const;

const actual = await vi.importActual(
"../utils/reduxMiddleware/extractServiceBaseUrls"
);

return {
...(typeof actual === "object" ? actual : {}),
getServiceBaseUrl: (apiBaseUrlKey: keyof typeof urls) => {
return urls[apiBaseUrlKey] ?? urls.fbiBaseUrl;
}
};
});
});

it("should resolve baseurl based on query name", () => {
expect(resolveBaseUrl("complexSearchWithPagination")).toEqual(
"i-am-fbi-search-url"
);
expect(resolveBaseUrl("complexSearchWithPaginationWorkAccess")).toEqual(
"i-am-fbi-search-url"
);
expect(resolveBaseUrl("intelligentFacets")).toEqual(
"i-am-fbi-search-url"
);
expect(resolveBaseUrl("recommendFromFaust")).toEqual(
"i-am-fbi-search-url"
);
expect(resolveBaseUrl("searchFacet")).toEqual("i-am-fbi-search-url");
expect(resolveBaseUrl("searchWithPagination")).toEqual(
"i-am-fbi-search-url"
);
expect(resolveBaseUrl("suggestionsFromQueryString")).toEqual(
"i-am-fbi-search-url"
);
expect(resolveBaseUrl("getInfomedia")).toEqual("i-am-fbi-material-url");
expect(
resolveBaseUrl("getManifestationViaBestRepresentationByFaust")
).toEqual("i-am-fbi-material-url");
expect(resolveBaseUrl("getManifestationViaMaterialByFaust")).toEqual(
"i-am-fbi-material-url"
);
expect(resolveBaseUrl("getMaterial")).toEqual("i-am-fbi-material-url");
expect(resolveBaseUrl("getReviewManifestations")).toEqual(
"i-am-fbi-material-url"
);
expect(resolveBaseUrl("getSmallWork")).toEqual("i-am-fbi-material-url");
expect(resolveBaseUrl("openOrder")).toEqual("i-am-fbi-material-url");
});

it("should resolve default to the fbi base url if the query is unknown", () => {
expect(resolveBaseUrl("someUnknownQuery")).toEqual("i-am-fbi-url");
});

it("should resolve default to the fbi base url if no query has been specified", () => {
expect(resolveBaseUrl()).toEqual("i-am-fbi-url");
});
});
}
23 changes: 23 additions & 0 deletions src/core/dbc-gateway/queryMap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { serviceUrlKeys } from "../utils/reduxMiddleware/extractServiceBaseUrls";

// This map is for mapping query names to FBI service base urls.
export default {
// Search requests.
complexSearchWithPagination: serviceUrlKeys.fbiSearch,
complexSearchWithPaginationWorkAccess: serviceUrlKeys.fbiSearch,
intelligentFacets: serviceUrlKeys.fbiSearch,
recommendFromFaust: serviceUrlKeys.fbiSearch,
searchFacet: serviceUrlKeys.fbiSearch,
searchWithPagination: serviceUrlKeys.fbiSearch,
suggestionsFromQueryString: serviceUrlKeys.fbiSearch,
// Material requests.
getInfomedia: serviceUrlKeys.fbiMaterial,
getManifestationViaBestRepresentationByFaust: serviceUrlKeys.fbiMaterial,
getManifestationViaMaterialByFaust: serviceUrlKeys.fbiMaterial,
getMaterial: serviceUrlKeys.fbiMaterial,
getReviewManifestations: serviceUrlKeys.fbiMaterial,
getSmallWork: serviceUrlKeys.fbiMaterial,
openOrder: serviceUrlKeys.fbiMaterial,
// All other requests.
default: serviceUrlKeys.fbi
} as const;
10 changes: 10 additions & 0 deletions src/core/storybook/serviceUrlArgs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,17 @@ export default {
},
[serviceUrlKeys.fbi]: {
name: "Base url for the FBI API",
defaultValue: "https://fbi-api.dbc.dk/next-present/graphql",
control: { type: "text" }
},
[serviceUrlKeys.fbiSearch]: {
name: "Base url for the FBI API (search)",
defaultValue: "https://fbi-api.dbc.dk/next/graphql",
control: { type: "text" }
},
[serviceUrlKeys.fbiMaterial]: {
name: "Base url for the FBI API (material)",
defaultValue: "https://fbi-api.dbc.dk/next-present/graphql",
control: { type: "text" }
}
};
26 changes: 20 additions & 6 deletions src/core/utils/reduxMiddleware/extractServiceBaseUrls.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,35 @@
import { EnhancedStore } from "@reduxjs/toolkit";
import { Middleware } from "redux";

type Api = "publizon" | "fbs" | "dplCms" | "cover" | "materialList" | "fbi";
type Api =
| "publizon"
| "fbs"
| "dplCms"
| "cover"
| "materialList"
| "fbi"
| "fbiSearch"
| "fbiMaterial";

export type ApiBaseUrlKey = `${Api}BaseUrl`;

export const serviceUrlKeys: Record<Api, ApiBaseUrlKey> = {
export type ServiceBaseUrls =
| Record<Api, ApiBaseUrlKey>
| Record<string, never>;

type ServiceBaseUrlKey = keyof ServiceBaseUrls;

export const serviceUrlKeys = {
fbs: "fbsBaseUrl",
publizon: "publizonBaseUrl",
dplCms: "dplCmsBaseUrl",
cover: "coverBaseUrl",
materialList: "materialListBaseUrl",
fbi: "fbiBaseUrl"
fbi: "fbiBaseUrl",
fbiSearch: "fbiSearchBaseUrl",
fbiMaterial: "fbiMaterialBaseUrl"
} as const;

type ServiceBaseUrls = Record<Api, ApiBaseUrlKey> | Record<string, never>;
type ServiceBaseUrlKey = keyof typeof serviceBaseUrls;

// ServiceBaseUrls "store". We use this to store the base urls for the different services.
let serviceBaseUrls: ServiceBaseUrls = {};

Expand Down
2 changes: 2 additions & 0 deletions src/core/utils/types/global-url-props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ interface GlobalUrlEntryPropsInterface {
coverBaseUrl: string;
materialBaseUrl: string;
fbiBaseUrl: string;
fbiSearchBaseUrl: string;
fbiMaterialBaseUrl: string;
authUrl: string;
ereolenHomepageUrl: string;
}
Expand Down

0 comments on commit fba97ef

Please sign in to comment.