diff --git a/packages/elements-react/src/theme/default/components/card/current-identifier-button.test.ts b/packages/elements-react/src/theme/default/components/card/current-identifier-button.test.ts new file mode 100644 index 00000000..819fd8c9 --- /dev/null +++ b/packages/elements-react/src/theme/default/components/card/current-identifier-button.test.ts @@ -0,0 +1,93 @@ +// Copyright © 2024 Ory Corp +// SPDX-License-Identifier: Apache-2.0 + +import { FlowType, UiNode } from "@ory/client-fetch" +import { getBackButtonNode } from "./current-identifier-button" + +test("getBackButtonNode should return the correct node for FlowType.Login", () => { + const nodes = [ + { + attributes: { name: "identifier" }, + group: "identifier_first", + }, + { + attributes: { name: "email" }, + group: "default", + }, + ] as UiNode[] + + const result = getBackButtonNode(FlowType.Login, nodes) + expect(result).toEqual({ + attributes: { name: "identifier" }, + group: "identifier_first", + }) +}) + +test("getBackButtonNode should return the correct node for FlowType.Registration", () => { + const nodes: UiNode[] = [ + { + attributes: { name: "traits.email" }, + group: "default", + }, + { + attributes: { name: "traits.username" }, + group: "default", + }, + ] as UiNode[] + + const result = getBackButtonNode(FlowType.Registration, nodes) + expect(result).toEqual({ + attributes: { name: "traits.email" }, + group: "default", + }) +}) + +test("getBackButtonNode should return the correct node for FlowType.Recovery", () => { + const nodes: UiNode[] = [ + { + attributes: { name: "email" }, + group: "default", + }, + { + attributes: { name: "other" }, + group: "default", + }, + ] as UiNode[] + + const result = getBackButtonNode(FlowType.Recovery, nodes) + expect(result).toEqual({ + attributes: { name: "email" }, + group: "default", + }) +}) + +test("getBackButtonNode should return the correct node for FlowType.Verification", () => { + const nodes: UiNode[] = [ + { + attributes: { name: "email" }, + group: "default", + }, + { + attributes: { name: "traits.username" }, + group: "default", + }, + ] as UiNode[] + + const result = getBackButtonNode(FlowType.Verification, nodes) + expect(result).toEqual({ + attributes: { name: "email" }, + group: "default", + }) +}) + +test("getBackButtonNode should return undefined if no matching node is found", () => { + const nodes: UiNode[] = [ + { + attributes: { name: "non-matching" }, + group: "non-matching-group", + }, + ] as unknown[] as UiNode[] + + const result = getBackButtonNode(FlowType.Login, nodes) + expect(result).toBeUndefined() +}) diff --git a/packages/elements-react/src/theme/default/components/card/current-identifier-button.tsx b/packages/elements-react/src/theme/default/components/card/current-identifier-button.tsx index a0bffd66..7982cfbe 100644 --- a/packages/elements-react/src/theme/default/components/card/current-identifier-button.tsx +++ b/packages/elements-react/src/theme/default/components/card/current-identifier-button.tsx @@ -17,27 +17,7 @@ export function DefaultCurrentIdentifierButton() { return null } - let nodeBackButton: UiNode | undefined - switch (flowType) { - case FlowType.Login: - nodeBackButton = ui.nodes.find( - (node) => - "name" in node.attributes && - node.attributes.name === "identifier" && - node.group === "identifier_first", - ) - break - case FlowType.Registration: - nodeBackButton = guessRegistrationBackButton(ui.nodes) - break - case FlowType.Recovery: - case FlowType.Verification: - // Re-use the email node for displaying the email - nodeBackButton = ui.nodes.find( - (n) => "name" in n.attributes && n.attributes.name === "email", - ) - break - } + const nodeBackButton = getBackButtonNode(flowType, ui.nodes) if ( nodeBackButton?.attributes.node_type !== "input" || @@ -64,12 +44,39 @@ export function DefaultCurrentIdentifierButton() { ) } +export function getBackButtonNode( + flowType: FlowType, + nodes: UiNode[], +): UiNode | undefined { + let nodeBackButton: UiNode | undefined + switch (flowType) { + case FlowType.Login: + nodeBackButton = nodes.find( + (node) => + "name" in node.attributes && + node.attributes.name === "identifier" && + node.group === "identifier_first", + ) + break + case FlowType.Registration: + nodeBackButton = guessRegistrationBackButton(nodes) + break + case FlowType.Recovery: + case FlowType.Verification: + // Re-use the email node for displaying the email + nodeBackButton = nodes.find( + (n) => "name" in n.attributes && n.attributes.name === "email", + ) + break + } + return nodeBackButton +} + const backButtonCandiates = [ "traits.email", "traits.username", "traits.phone_number", ] - /** * Guesses the back button for registration flows *