diff --git a/package.json b/package.json index dafd68ae..4018acac 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,7 @@ "@types/make-fetch-happen": "^10.0.1", "@types/minimist": "^1.2.2", "@types/node": "^18.15.3", - "@types/react": "18.0.9", + "@types/react": "^18.0.35", "@types/react-dom": "^18.0.11", "@types/yauzl": "^2.10.0", "concurrently": "^7.6.0", @@ -91,7 +91,7 @@ "lint-staged": "^11.0.0", "prettier": "^2.3.0", "properties-parser": "^0.3.1", - "react": "18.1.0", + "react": "^18.2.0", "react-dom": "^18.2.0", "rimraf": "^3.0.2", "scripting-tools": "^0.19.13", diff --git a/src/account/index.ts b/src/account/index.ts index 180ee07e..f07638bb 100644 --- a/src/account/index.ts +++ b/src/account/index.ts @@ -3,6 +3,7 @@ import Fallback from "keycloakify/account/Fallback"; export default Fallback; export { getKcContext } from "keycloakify/account/kcContext/getKcContext"; +export { createGetKcContext } from "keycloakify/account/kcContext/createGetKcContext"; export { createUseI18n } from "keycloakify/account/i18n/i18n"; export type { PageProps } from "keycloakify/account/pages/PageProps"; diff --git a/src/account/kcContext/createGetKcContext.ts b/src/account/kcContext/createGetKcContext.ts new file mode 100644 index 00000000..dcfce627 --- /dev/null +++ b/src/account/kcContext/createGetKcContext.ts @@ -0,0 +1,106 @@ +import type { DeepPartial } from "keycloakify/tools/DeepPartial"; +import { deepAssign } from "keycloakify/tools/deepAssign"; +import type { ExtendKcContext } from "./getKcContextFromWindow"; +import { getKcContextFromWindow } from "./getKcContextFromWindow"; +import { pathJoin } from "keycloakify/bin/tools/pathJoin"; +import { pathBasename } from "keycloakify/tools/pathBasename"; +import { mockTestingResourcesCommonPath } from "keycloakify/bin/mockTestingResourcesPath"; +import { symToStr } from "tsafe/symToStr"; +import { kcContextMocks, kcContextCommonMock } from "keycloakify/account/kcContext/kcContextMocks"; +import { id } from "tsafe/id"; +import { accountThemePageIds } from "keycloakify/bin/keycloakify/generateFtl/pageId"; + +export function createGetKcContext(params?: { + mockData?: readonly DeepPartial>[]; +}) { + const { mockData } = params ?? {}; + + function getKcContext["pageId"] = ExtendKcContext["pageId"]>(params?: { + mockPageId?: PageId; + storyParams?: DeepPartial, { pageId: PageId }>>; + }): { kcContext: Extract, { pageId: PageId }> | undefined } { + const { mockPageId, storyParams } = params ?? {}; + + const realKcContext = getKcContextFromWindow(); + + if (mockPageId !== undefined && realKcContext === undefined) { + //TODO maybe trow if no mock fo custom page + + console.log( + [ + `%cKeycloakify: ${symToStr({ mockPageId })} set to ${mockPageId}.`, + `If assets are missing make sure you have built your Keycloak theme at least once.` + ].join(" "), + "background: red; color: yellow; font-size: medium" + ); + + const kcContextDefaultMock = kcContextMocks.find(({ pageId }) => pageId === mockPageId); + + const partialKcContextCustomMock = (() => { + const out: DeepPartial> = {}; + + const mockDataPick = mockData?.find(({ pageId }) => pageId === mockPageId); + + if (mockDataPick !== undefined) { + deepAssign({ + "target": out, + "source": mockDataPick + }); + } + + if (storyParams !== undefined) { + deepAssign({ + "target": out, + "source": storyParams + }); + } + + return Object.keys(out).length === 0 ? undefined : out; + })(); + + if (kcContextDefaultMock === undefined && partialKcContextCustomMock === undefined) { + console.warn( + [ + `WARNING: You declared the non build in page ${mockPageId} but you didn't `, + `provide mock data needed to debug the page outside of Keycloak as you are trying to do now.`, + `Please check the documentation of the getKcContext function` + ].join("\n") + ); + } + + const kcContext: any = {}; + + deepAssign({ + "target": kcContext, + "source": kcContextDefaultMock !== undefined ? kcContextDefaultMock : { "pageId": mockPageId, ...kcContextCommonMock } + }); + + if (partialKcContextCustomMock !== undefined) { + deepAssign({ + "target": kcContext, + "source": partialKcContextCustomMock + }); + } + + return { kcContext }; + } + + if (realKcContext === undefined) { + return { "kcContext": undefined }; + } + + if (id(accountThemePageIds).indexOf(realKcContext.pageId) < 0 && !("account" in realKcContext)) { + return { "kcContext": undefined }; + } + + { + const { url } = realKcContext; + + url.resourcesCommonPath = pathJoin(url.resourcesPath, pathBasename(mockTestingResourcesCommonPath)); + } + + return { "kcContext": realKcContext as any }; + } + + return { getKcContext }; +} diff --git a/src/account/kcContext/getKcContext.ts b/src/account/kcContext/getKcContext.ts index eab7d508..00d0717d 100644 --- a/src/account/kcContext/getKcContext.ts +++ b/src/account/kcContext/getKcContext.ts @@ -1,78 +1,19 @@ import type { DeepPartial } from "keycloakify/tools/DeepPartial"; -import { deepAssign } from "keycloakify/tools/deepAssign"; import type { ExtendKcContext } from "./getKcContextFromWindow"; -import { getKcContextFromWindow } from "./getKcContextFromWindow"; -import { pathJoin } from "keycloakify/bin/tools/pathJoin"; -import { pathBasename } from "keycloakify/tools/pathBasename"; -import { mockTestingResourcesCommonPath } from "keycloakify/bin/mockTestingResourcesPath"; -import { symToStr } from "tsafe/symToStr"; -import { kcContextMocks, kcContextCommonMock } from "keycloakify/account/kcContext/kcContextMocks"; -import { id } from "tsafe/id"; -import { accountThemePageIds } from "keycloakify/bin/keycloakify/generateFtl/pageId"; +import { createGetKcContext } from "./createGetKcContext"; +/** @deprecated: Use createGetKcContext instead */ export function getKcContext(params?: { mockPageId?: ExtendKcContext["pageId"]; mockData?: readonly DeepPartial>[]; }): { kcContext: ExtendKcContext | undefined } { const { mockPageId, mockData } = params ?? {}; - const realKcContext = getKcContextFromWindow(); + const { getKcContext } = createGetKcContext({ + mockData + }); - if (mockPageId !== undefined && realKcContext === undefined) { - //TODO maybe trow if no mock fo custom page + const { kcContext } = getKcContext({ mockPageId }); - console.log( - [ - `%cKeycloakify: ${symToStr({ mockPageId })} set to ${mockPageId}.`, - `If assets are missing make sure you have built your Keycloak theme at least once.` - ].join(" "), - "background: red; color: yellow; font-size: medium" - ); - - const kcContextDefaultMock = kcContextMocks.find(({ pageId }) => pageId === mockPageId); - - const partialKcContextCustomMock = mockData?.find(({ pageId }) => pageId === mockPageId); - - if (kcContextDefaultMock === undefined && partialKcContextCustomMock === undefined) { - console.warn( - [ - `WARNING: You declared the non build in page ${mockPageId} but you didn't `, - `provide mock data needed to debug the page outside of Keycloak as you are trying to do now.`, - `Please check the documentation of the getKcContext function` - ].join("\n") - ); - } - - const kcContext: any = {}; - - deepAssign({ - "target": kcContext, - "source": kcContextDefaultMock !== undefined ? kcContextDefaultMock : { "pageId": mockPageId, ...kcContextCommonMock } - }); - - if (partialKcContextCustomMock !== undefined) { - deepAssign({ - "target": kcContext, - "source": partialKcContextCustomMock - }); - } - - return { kcContext }; - } - - if (realKcContext === undefined) { - return { "kcContext": undefined }; - } - - if (id(accountThemePageIds).indexOf(realKcContext.pageId) < 0 && !("account" in realKcContext)) { - return { "kcContext": undefined }; - } - - { - const { url } = realKcContext; - - url.resourcesCommonPath = pathJoin(url.resourcesPath, pathBasename(mockTestingResourcesCommonPath)); - } - - return { "kcContext": realKcContext }; + return { kcContext }; } diff --git a/src/login/index.ts b/src/login/index.ts index 153bec90..63c91df3 100644 --- a/src/login/index.ts +++ b/src/login/index.ts @@ -4,6 +4,7 @@ export default Fallback; export { useDownloadTerms } from "keycloakify/login/lib/useDownloadTerms"; export { getKcContext } from "keycloakify/login/kcContext/getKcContext"; +export { createGetKcContext } from "keycloakify/login/kcContext/createGetKcContext"; export { createUseI18n } from "keycloakify/login/i18n/i18n"; export type { PageProps } from "keycloakify/login/pages/PageProps"; diff --git a/src/login/kcContext/createGetKcContext.ts b/src/login/kcContext/createGetKcContext.ts new file mode 100644 index 00000000..92b30e15 --- /dev/null +++ b/src/login/kcContext/createGetKcContext.ts @@ -0,0 +1,164 @@ +import type { KcContext, Attribute } from "./KcContext"; +import { kcContextMocks, kcContextCommonMock } from "./kcContextMocks"; +import type { DeepPartial } from "keycloakify/tools/DeepPartial"; +import { deepAssign } from "keycloakify/tools/deepAssign"; +import { id } from "tsafe/id"; +import { exclude } from "tsafe/exclude"; +import { assert } from "tsafe/assert"; +import type { ExtendKcContext } from "./getKcContextFromWindow"; +import { getKcContextFromWindow } from "./getKcContextFromWindow"; +import { pathJoin } from "keycloakify/bin/tools/pathJoin"; +import { pathBasename } from "keycloakify/tools/pathBasename"; +import { mockTestingResourcesCommonPath } from "keycloakify/bin/mockTestingResourcesPath"; +import { symToStr } from "tsafe/symToStr"; +import { loginThemePageIds } from "keycloakify/bin/keycloakify/generateFtl/pageId"; + +export function createGetKcContext(params?: { + mockData?: readonly DeepPartial>[]; +}) { + const { mockData } = params ?? {}; + + function getKcContext["pageId"] = ExtendKcContext["pageId"]>(params?: { + mockPageId?: PageId; + storyParams?: DeepPartial, { pageId: PageId }>>; + }): { kcContext: Extract, { pageId: PageId }> | undefined } { + const { mockPageId, storyParams } = params ?? {}; + + const realKcContext = getKcContextFromWindow(); + + if (mockPageId !== undefined && realKcContext === undefined) { + //TODO maybe trow if no mock fo custom page + + console.log( + [ + `%cKeycloakify: ${symToStr({ mockPageId })} set to ${mockPageId}.`, + `If assets are missing make sure you have built your Keycloak theme at least once.` + ].join(" "), + "background: red; color: yellow; font-size: medium" + ); + + const kcContextDefaultMock = kcContextMocks.find(({ pageId }) => pageId === mockPageId); + + const partialKcContextCustomMock = (() => { + const out: DeepPartial> = {}; + + const mockDataPick = mockData?.find(({ pageId }) => pageId === mockPageId); + + if (mockDataPick !== undefined) { + deepAssign({ + "target": out, + "source": mockDataPick + }); + } + + if (storyParams !== undefined) { + deepAssign({ + "target": out, + "source": storyParams + }); + } + + return Object.keys(out).length === 0 ? undefined : out; + })(); + + if (kcContextDefaultMock === undefined && partialKcContextCustomMock === undefined) { + console.warn( + [ + `WARNING: You declared the non build in page ${mockPageId} but you didn't `, + `provide mock data needed to debug the page outside of Keycloak as you are trying to do now.`, + `Please check the documentation of the getKcContext function` + ].join("\n") + ); + } + + const kcContext: any = {}; + + deepAssign({ + "target": kcContext, + "source": kcContextDefaultMock !== undefined ? kcContextDefaultMock : { "pageId": mockPageId, ...kcContextCommonMock } + }); + + if (partialKcContextCustomMock !== undefined) { + deepAssign({ + "target": kcContext, + "source": partialKcContextCustomMock + }); + + if ( + partialKcContextCustomMock.pageId === "register-user-profile.ftl" || + partialKcContextCustomMock.pageId === "update-user-profile.ftl" || + partialKcContextCustomMock.pageId === "idp-review-user-profile.ftl" + ) { + assert( + kcContextDefaultMock?.pageId === "register-user-profile.ftl" || + kcContextDefaultMock?.pageId === "update-user-profile.ftl" || + kcContextDefaultMock?.pageId === "idp-review-user-profile.ftl" + ); + + const { attributes } = kcContextDefaultMock.profile; + + id(kcContext).profile.attributes = []; + id(kcContext).profile.attributesByName = {}; + + const partialAttributes = [ + ...((partialKcContextCustomMock as DeepPartial).profile?.attributes ?? []) + ].filter(exclude(undefined)); + + attributes.forEach(attribute => { + const partialAttribute = partialAttributes.find(({ name }) => name === attribute.name); + + const augmentedAttribute: Attribute = {} as any; + + deepAssign({ + "target": augmentedAttribute, + "source": attribute + }); + + if (partialAttribute !== undefined) { + partialAttributes.splice(partialAttributes.indexOf(partialAttribute), 1); + + deepAssign({ + "target": augmentedAttribute, + "source": partialAttribute + }); + } + + id(kcContext).profile.attributes.push(augmentedAttribute); + id(kcContext).profile.attributesByName[augmentedAttribute.name] = augmentedAttribute; + }); + + partialAttributes + .map(partialAttribute => ({ "validators": {}, ...partialAttribute })) + .forEach(partialAttribute => { + const { name } = partialAttribute; + + assert(name !== undefined, "If you define a mock attribute it must have at least a name"); + + id(kcContext).profile.attributes.push(partialAttribute as any); + id(kcContext).profile.attributesByName[name] = partialAttribute as any; + }); + } + } + + return { kcContext }; + } + + if (realKcContext === undefined) { + return { "kcContext": undefined }; + } + + if (id(loginThemePageIds).indexOf(realKcContext.pageId) < 0 && !("login" in realKcContext)) { + return { "kcContext": undefined }; + } + + { + const { url } = realKcContext; + + url.resourcesCommonPath = pathJoin(url.resourcesPath, pathBasename(mockTestingResourcesCommonPath)); + } + + return { "kcContext": realKcContext as any }; + } + + return { getKcContext }; +} diff --git a/src/login/kcContext/getKcContext.ts b/src/login/kcContext/getKcContext.ts index 82d01789..3058721c 100644 --- a/src/login/kcContext/getKcContext.ts +++ b/src/login/kcContext/getKcContext.ts @@ -1,136 +1,19 @@ -import type { KcContext, Attribute } from "./KcContext"; -import { kcContextMocks, kcContextCommonMock } from "./kcContextMocks"; import type { DeepPartial } from "keycloakify/tools/DeepPartial"; -import { deepAssign } from "keycloakify/tools/deepAssign"; -import { id } from "tsafe/id"; -import { exclude } from "tsafe/exclude"; -import { assert } from "tsafe/assert"; import type { ExtendKcContext } from "./getKcContextFromWindow"; -import { getKcContextFromWindow } from "./getKcContextFromWindow"; -import { pathJoin } from "keycloakify/bin/tools/pathJoin"; -import { pathBasename } from "keycloakify/tools/pathBasename"; -import { mockTestingResourcesCommonPath } from "keycloakify/bin/mockTestingResourcesPath"; -import { symToStr } from "tsafe/symToStr"; -import { loginThemePageIds } from "keycloakify/bin/keycloakify/generateFtl/pageId"; +import { createGetKcContext } from "./createGetKcContext"; +/** @deprecated: Use createGetKcContext instead */ export function getKcContext(params?: { mockPageId?: ExtendKcContext["pageId"]; mockData?: readonly DeepPartial>[]; }): { kcContext: ExtendKcContext | undefined } { const { mockPageId, mockData } = params ?? {}; - const realKcContext = getKcContextFromWindow(); + const { getKcContext } = createGetKcContext({ + mockData + }); - if (mockPageId !== undefined && realKcContext === undefined) { - //TODO maybe trow if no mock fo custom page + const { kcContext } = getKcContext({ mockPageId }); - console.log( - [ - `%cKeycloakify: ${symToStr({ mockPageId })} set to ${mockPageId}.`, - `If assets are missing make sure you have built your Keycloak theme at least once.` - ].join(" "), - "background: red; color: yellow; font-size: medium" - ); - - const kcContextDefaultMock = kcContextMocks.find(({ pageId }) => pageId === mockPageId); - - const partialKcContextCustomMock = mockData?.find(({ pageId }) => pageId === mockPageId); - - if (kcContextDefaultMock === undefined && partialKcContextCustomMock === undefined) { - console.warn( - [ - `WARNING: You declared the non build in page ${mockPageId} but you didn't `, - `provide mock data needed to debug the page outside of Keycloak as you are trying to do now.`, - `Please check the documentation of the getKcContext function` - ].join("\n") - ); - } - - const kcContext: any = {}; - - deepAssign({ - "target": kcContext, - "source": kcContextDefaultMock !== undefined ? kcContextDefaultMock : { "pageId": mockPageId, ...kcContextCommonMock } - }); - - if (partialKcContextCustomMock !== undefined) { - deepAssign({ - "target": kcContext, - "source": partialKcContextCustomMock - }); - - if ( - partialKcContextCustomMock.pageId === "register-user-profile.ftl" || - partialKcContextCustomMock.pageId === "update-user-profile.ftl" || - partialKcContextCustomMock.pageId === "idp-review-user-profile.ftl" - ) { - assert( - kcContextDefaultMock?.pageId === "register-user-profile.ftl" || - kcContextDefaultMock?.pageId === "update-user-profile.ftl" || - kcContextDefaultMock?.pageId === "idp-review-user-profile.ftl" - ); - - const { attributes } = kcContextDefaultMock.profile; - - id(kcContext).profile.attributes = []; - id(kcContext).profile.attributesByName = {}; - - const partialAttributes = [ - ...((partialKcContextCustomMock as DeepPartial).profile?.attributes ?? []) - ].filter(exclude(undefined)); - - attributes.forEach(attribute => { - const partialAttribute = partialAttributes.find(({ name }) => name === attribute.name); - - const augmentedAttribute: Attribute = {} as any; - - deepAssign({ - "target": augmentedAttribute, - "source": attribute - }); - - if (partialAttribute !== undefined) { - partialAttributes.splice(partialAttributes.indexOf(partialAttribute), 1); - - deepAssign({ - "target": augmentedAttribute, - "source": partialAttribute - }); - } - - id(kcContext).profile.attributes.push(augmentedAttribute); - id(kcContext).profile.attributesByName[augmentedAttribute.name] = augmentedAttribute; - }); - - partialAttributes - .map(partialAttribute => ({ "validators": {}, ...partialAttribute })) - .forEach(partialAttribute => { - const { name } = partialAttribute; - - assert(name !== undefined, "If you define a mock attribute it must have at least a name"); - - id(kcContext).profile.attributes.push(partialAttribute as any); - id(kcContext).profile.attributesByName[name] = partialAttribute as any; - }); - } - } - - return { kcContext }; - } - - if (realKcContext === undefined) { - return { "kcContext": undefined }; - } - - if (id(loginThemePageIds).indexOf(realKcContext.pageId) < 0 && !("login" in realKcContext)) { - return { "kcContext": undefined }; - } - - { - const { url } = realKcContext; - - url.resourcesCommonPath = pathJoin(url.resourcesPath, pathBasename(mockTestingResourcesCommonPath)); - } - - return { "kcContext": realKcContext }; + return { kcContext }; } diff --git a/test/lib/createGetKcContext.spec.ts b/test/lib/createGetKcContext.spec.ts new file mode 100644 index 00000000..dab5cb28 --- /dev/null +++ b/test/lib/createGetKcContext.spec.ts @@ -0,0 +1,249 @@ +import { createGetKcContext } from "keycloakify/login/kcContext/createGetKcContext"; +import type { ExtendKcContext } from "keycloakify/login/kcContext/getKcContextFromWindow"; +import type { KcContext } from "keycloakify/login/kcContext"; +import { same } from "evt/tools/inDepth"; +import { assert } from "tsafe/assert"; +import type { Equals } from "tsafe"; +import { kcContextMocks, kcContextCommonMock } from "keycloakify/login/kcContext/kcContextMocks"; +import { deepClone } from "keycloakify/tools/deepClone"; +import { expect, it, describe } from "vitest"; + +describe("createGetKcContext", () => { + const authorizedMailDomains = ["example.com", "another-example.com", "*.yet-another-example.com", "*.example.com", "hello-world.com"]; + + const displayName = "this is an overwritten common value"; + + const aNonStandardValue1 = "a non standard value 1"; + const aNonStandardValue2 = "a non standard value 2"; + + type KcContextExtension = + | { + pageId: "register.ftl"; + authorizedMailDomains: string[]; + } + | { + pageId: "info.ftl"; + aNonStandardValue1: string; + } + | { + pageId: "my-extra-page-1.ftl"; + } + | { + pageId: "my-extra-page-2.ftl"; + aNonStandardValue2: string; + }; + + const getKcContextProxy = (params: { mockPageId: ExtendKcContext["pageId"] }) => { + const { mockPageId } = params; + + const { getKcContext } = createGetKcContext({ + "mockData": [ + { + "pageId": "login.ftl", + "realm": { displayName } + }, + { + "pageId": "info.ftl", + aNonStandardValue1 + }, + { + "pageId": "register.ftl", + authorizedMailDomains + }, + { + "pageId": "my-extra-page-2.ftl", + aNonStandardValue2 + } + ] + }); + + const { kcContext } = getKcContext({ + mockPageId + }); + + return { kcContext }; + }; + it("has proper API for login.ftl", () => { + const pageId = "login.ftl"; + + const { kcContext } = getKcContextProxy({ "mockPageId": pageId }); + + assert(kcContext?.pageId === pageId); + + assert>(); + + expect( + same( + //NOTE: deepClone for printIfExists or other functions... + deepClone(kcContext), + (() => { + const mock = deepClone(kcContextMocks.find(({ pageId: pageId_i }) => pageId_i === pageId)!); + + mock.realm.displayName = displayName; + + return mock; + })() + ) + ).toBe(true); + }); + + it("has a proper API for info.ftl", () => { + const pageId = "info.ftl"; + + const { kcContext } = getKcContextProxy({ "mockPageId": pageId }); + + assert(kcContext?.pageId === pageId); + + //NOTE: I don't understand the need to add: pageId: typeof pageId; ... + assert< + Equals< + typeof kcContext, + KcContext.Info & { + pageId: typeof pageId; + aNonStandardValue1: string; + } + > + >(); + + expect( + same( + deepClone(kcContext), + (() => { + const mock = deepClone(kcContextMocks.find(({ pageId: pageId_i }) => pageId_i === pageId)!); + + Object.assign(mock, { aNonStandardValue1 }); + + return mock; + })() + ) + ).toBe(true); + }); + it("has a proper API for register.ftl", () => { + const pageId = "register.ftl"; + + const { kcContext } = getKcContextProxy({ "mockPageId": pageId }); + + assert(kcContext?.pageId === pageId); + + //NOTE: I don't understand the need to add: pageId: typeof pageId; ... + assert< + Equals< + typeof kcContext, + KcContext.Register & { + pageId: typeof pageId; + authorizedMailDomains: string[]; + } + > + >(); + + expect( + same( + deepClone(kcContext), + (() => { + const mock = deepClone(kcContextMocks.find(({ pageId: pageId_i }) => pageId_i === pageId)!); + + Object.assign(mock, { authorizedMailDomains }); + + return mock; + })() + ) + ).toBe(true); + }); + it("has a proper API for my-extra-page-2.ftl", () => { + const pageId = "my-extra-page-2.ftl"; + + const { kcContext } = getKcContextProxy({ "mockPageId": pageId }); + + assert(kcContext?.pageId === pageId); + + assert< + Equals< + typeof kcContext, + KcContext.Common & { + pageId: typeof pageId; + aNonStandardValue2: string; + } + > + >(); + + kcContext.aNonStandardValue2; + + expect( + same( + deepClone(kcContext), + (() => { + const mock = deepClone(kcContextCommonMock); + + Object.assign(mock, { pageId, aNonStandardValue2 }); + + return mock; + })() + ) + ).toBe(true); + }); + it("has a proper API for my-extra-page-1.ftl", () => { + const pageId = "my-extra-page-1.ftl"; + + console.log("We expect a warning here =>"); + + const { kcContext } = getKcContextProxy({ "mockPageId": pageId }); + + assert(kcContext?.pageId === pageId); + + assert>(); + + expect( + same( + deepClone(kcContext), + (() => { + const mock = deepClone(kcContextCommonMock); + + Object.assign(mock, { pageId }); + + return mock; + })() + ) + ).toBe(true); + }); + it("returns the proper mock for login.ftl", () => { + const pageId = "login.ftl"; + + const { getKcContext } = createGetKcContext(); + + const { kcContext } = getKcContext({ + "mockPageId": pageId + }); + + assert>(); + + assert(same(deepClone(kcContext), deepClone(kcContextMocks.find(({ pageId: pageId_i }) => pageId_i === pageId)!))); + }); + it("returns undefined when no mock is specified", () => { + const { getKcContext } = createGetKcContext(); + + const { kcContext } = getKcContext(); + + assert>(); + + assert(kcContext === undefined); + }); + + it("mock are properly overwriten", () => { + const { getKcContext } = createGetKcContext(); + + const displayName = "myDisplayName"; + + const { kcContext } = getKcContext({ + "mockPageId": "login.ftl", + "storyParams": { + "realm": { + displayName + } + } + }); + + assert>(); + + assert(kcContext?.realm.displayName === displayName); + }); +}); diff --git a/test/lib/getKcContext.spec.ts b/test/lib/getKcContext.spec.ts index 20023fff..bd53690b 100644 --- a/test/lib/getKcContext.spec.ts +++ b/test/lib/getKcContext.spec.ts @@ -213,7 +213,7 @@ describe("getKcContext", () => { assert(same(deepClone(kcContext), deepClone(kcContextMocks.find(({ pageId: pageId_i }) => pageId_i === pageId)!))); }); - it("returns the proper mock for login.ftl", () => { + it("returns undefined when no mock is specified", () => { const { kcContext } = getKcContext(); assert>(); diff --git a/yarn.lock b/yarn.lock index 1a545dbf..f91c2e80 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2873,7 +2873,7 @@ dependencies: "@types/react" "*" -"@types/react@*": +"@types/react@*", "@types/react@^18.0.35": version "18.0.35" resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.35.tgz#192061cb1044fe01f2d3a94272cd35dd50502741" integrity sha512-6Laome31HpetaIUGFWl1VQ3mdSImwxtFZ39rh059a1MNnKGqBpC88J6NJ8n/Is3Qx7CefDGLgf/KhN/sYCf7ag== @@ -2882,15 +2882,6 @@ "@types/scheduler" "*" csstype "^3.0.2" -"@types/react@18.0.9": - version "18.0.9" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.9.tgz#d6712a38bd6cd83469603e7359511126f122e878" - integrity sha512-9bjbg1hJHUm4De19L1cHiW0Jvx3geel6Qczhjd0qY5VKVE2X5+x77YxAepuCwVh4vrgZJdgEJw48zrhRIeF4Nw== - dependencies: - "@types/prop-types" "*" - "@types/scheduler" "*" - csstype "^3.0.2" - "@types/retry@*": version "0.12.2" resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.2.tgz#ed279a64fa438bb69f2480eda44937912bb7480a" @@ -9629,14 +9620,7 @@ react-sizeme@^3.0.1: shallowequal "^1.1.0" throttle-debounce "^3.0.1" -react@18.1.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/react/-/react-18.1.0.tgz#6f8620382decb17fdc5cc223a115e2adbf104890" - integrity sha512-4oL8ivCz5ZEPyclFQXaNksK3adutVS8l2xzZU0cqEFrE9Sb7fC0EFK5uEk74wIreL1DERyjvsU915j1pcT2uEQ== - dependencies: - loose-envify "^1.1.0" - -react@^18.0: +react@^18.0, react@^18.2.0: version "18.2.0" resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== @@ -11456,9 +11440,9 @@ upath@^1.1.1: integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== update-browserslist-db@^1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" - integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== + version "1.0.11" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940" + integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== dependencies: escalade "^3.1.1" picocolors "^1.0.0"