Skip to content

Commit

Permalink
Add button to migration data (#1319)
Browse files Browse the repository at this point in the history
* refactor: check if migrationOrderFields is empty array

* test: fix test for order migrationOrderFields and add test when migrationOrderFields is empty array

* refactor: add button on the migration data component

* refactor: remove redirect-vorabcheck route

* refactor: improve props name

* Update app/components/__test__/MigrationDataOverview.test.tsx

Co-authored-by: Pram Gurusinga <[email protected]>

* Update app/components/__test__/MigrationDataOverview.test.tsx

Co-authored-by: Pram Gurusinga <[email protected]>

* refactor: rename orderFields to sortedFields

* refactor: improve test description

* refactor: rename data to userData

---------

Co-authored-by: Pram Gurusinga <[email protected]>
  • Loading branch information
aaschlote and pgurusinga authored Oct 18, 2024
1 parent 7791a02 commit f385b33
Show file tree
Hide file tree
Showing 11 changed files with 152 additions and 64 deletions.
43 changes: 27 additions & 16 deletions app/components/MigrationDataOverview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,18 @@ import type { Context } from "~/flows/contexts";
import { type Translations } from "~/services/cms/index.server";
import { getTranslationByKey } from "~/services/translations/getTranslationByKey";
import { lookupOrKey } from "~/util/lookupOrKey";
import Button from "./Button";
import Heading from "./Heading";

type MigrationDataProps = {
readonly migrationData?: Context;
readonly userData?: Context;
readonly translations: Translations;
readonly migrationOrderFields?: string[];
readonly sortedFields?: string[];
readonly buttonUrl?: string;
};

const MIGRATION_BUTTON_TEXT_TRANSLATION = "migrationButtonText";

type ValueOfContext = Context[keyof Context];

const renderMigrationValue = (
Expand All @@ -34,34 +38,35 @@ const renderMigrationValue = (
return translation;
};

const getOrderFieldsData = (
migrationData: Context,
migrationOrderFields?: string[],
const getSortedFieldsUserData = (
userData: Context,
sortedFields?: string[],
) => {
if (typeof migrationOrderFields === "undefined") {
return migrationData;
if (typeof sortedFields === "undefined" || sortedFields.length === 0) {
return userData;
}

return migrationOrderFields.reduce((orderedData, key) => {
if (key in migrationData) {
orderedData[key] = migrationData[key];
return sortedFields.reduce((sortedUserData, key) => {
if (key in userData) {
sortedUserData[key] = userData[key];
}
return orderedData;
return sortedUserData;
}, {} as Context);
};

export default function MigrationDataOverview({
translations,
migrationData,
migrationOrderFields,
userData,
sortedFields,
buttonUrl,
}: MigrationDataProps) {
if (!migrationData || Object.keys(migrationData).length === 0) return null;
if (!userData || Object.keys(userData).length === 0) return null;

const data = getOrderFieldsData(migrationData, migrationOrderFields);
const sortedFieldsUserData = getSortedFieldsUserData(userData, sortedFields);

return (
<div className="space-y-16 bg-white pt-32 pb-44 px-32">
{Object.entries(data).map(([itemKey, itemValue]) => (
{Object.entries(sortedFieldsUserData).map(([itemKey, itemValue]) => (
<div key={itemKey} className="first:pt-0 scroll-my-40">
<Heading
text={getTranslationByKey(itemKey, translations)}
Expand All @@ -72,6 +77,12 @@ export default function MigrationDataOverview({
{renderMigrationValue(translations, itemValue, itemKey)}
</div>
))}

{buttonUrl && (
<Button href={buttonUrl} look="tertiary" size="large" className="w-fit">
{getTranslationByKey(MIGRATION_BUTTON_TEXT_TRANSLATION, translations)}
</Button>
)}
</div>
);
}
116 changes: 101 additions & 15 deletions app/components/__test__/MigrationDataOverview.test.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import { render } from "@testing-library/react";
import MigrationDataOverview from "../MigrationDataOverview";

// eslint-disable-next-line react/display-name
vi.mock("~/components/Button", () => ({
default: () => <div>Mock Button</div>,
}));

describe("MigrationDataOverview", () => {
it("should not render in case is missing migration data", () => {
it("should not render in case is missing migration userData", () => {
const { container } = render(<MigrationDataOverview translations={{}} />);

expect(container).toBeEmptyDOMElement();
});

it("should render the component based on the migration data and translations", () => {
const migrationData = {
it("should render the component based on the migration userData and translations", () => {
const migrationUserData = {
bereich: "verspaetet",
};

Expand All @@ -21,7 +26,7 @@ describe("MigrationDataOverview", () => {
const { container, getByText } = render(
<MigrationDataOverview
translations={translations}
migrationData={migrationData}
userData={migrationUserData}
/>,
);

Expand All @@ -31,7 +36,7 @@ describe("MigrationDataOverview", () => {
});

it("should render the component based on the migration data and the specific translation with .value", () => {
const migrationData = {
const migrationUserData = {
startAirport: "BER",
};

Expand All @@ -43,7 +48,7 @@ describe("MigrationDataOverview", () => {
const { container, getByText } = render(
<MigrationDataOverview
translations={translations}
migrationData={migrationData}
userData={migrationUserData}
/>,
);

Expand All @@ -52,8 +57,8 @@ describe("MigrationDataOverview", () => {
expect(getByText(translations["startAirport.value"])).toBeInTheDocument();
});

it("should render the component based on the migration data when it contains nested objects and translations", () => {
const migrationData = {
it("should render the component based on the migration userData when it contains nested objects and translations", () => {
const migrationUserData = {
zustaendigesAmtsgericht: {
bezeichnung: "Amtsgericht Frankfurt am Main",
strasseMitHausnummer: "Gerichtsstraße 2",
Expand All @@ -68,7 +73,7 @@ describe("MigrationDataOverview", () => {
const { container, getByText } = render(
<MigrationDataOverview
translations={translations}
migrationData={migrationData}
userData={migrationUserData}
/>,
);

Expand All @@ -77,18 +82,57 @@ describe("MigrationDataOverview", () => {
getByText(translations["zustaendigesAmtsgericht"]),
).toBeInTheDocument();
expect(
getByText(migrationData["zustaendigesAmtsgericht"].bezeichnung),
getByText(migrationUserData["zustaendigesAmtsgericht"].bezeichnung),
).toBeInTheDocument();
expect(
getByText(migrationData["zustaendigesAmtsgericht"].strasseMitHausnummer),
getByText(
migrationUserData["zustaendigesAmtsgericht"].strasseMitHausnummer,
),
).toBeInTheDocument();
expect(
getByText(migrationData["zustaendigesAmtsgericht"].plzUndStadt),
getByText(migrationUserData["zustaendigesAmtsgericht"].plzUndStadt),
).toBeInTheDocument();
});

it("should render the component order the fields bases on the props migrationOrderFields", () => {
const migrationData = {
it("should render the component with fields sorted according to the sortedFields array", () => {
const migrationUserData = {
bereich: "verspaetet",
startAirport: "BER",
endAirport: "FRA",
};

const translations = {
bereich: "Problem",
"bereich.verspaetet": "Verspätete Beförderung",
startAirport: "Startflughafen",
"startAirport.value": "Berlin Brandenburg Flughafen (BER)",
endAirport: "Zielflughafen",
"endAirport.value": "Frankfurt Flughafen (FRA)",
};

const { queryAllByTestId } = render(
<MigrationDataOverview
translations={translations}
userData={migrationUserData}
sortedFields={["startAirport", "endAirport", "bereich"]}
/>,
);

expect(queryAllByTestId("migration-field-value")[0].textContent).toEqual(
translations["startAirport"],
);

expect(queryAllByTestId("migration-field-value")[1].textContent).toEqual(
translations["endAirport"],
);

expect(queryAllByTestId("migration-field-value")[2].textContent).toEqual(
translations["bereich"],
);
});

it("should render the component and order the fields based on the migrationUserData prop in case the sortedFields prop is an empty array.", () => {
const migrationUserData = {
bereich: "verspaetet",
startAirport: "BER",
endAirport: "FRA",
Expand All @@ -106,7 +150,8 @@ describe("MigrationDataOverview", () => {
const { queryAllByTestId } = render(
<MigrationDataOverview
translations={translations}
migrationData={migrationData}
userData={migrationUserData}
sortedFields={[]}
/>,
);

Expand All @@ -122,4 +167,45 @@ describe("MigrationDataOverview", () => {
translations["endAirport"],
);
});

it("should render a Mock Button in case props buttonUrl has value", () => {
const migrationUserData = {
bereich: "verspaetet",
};

const translations = {
bereich: "Problem",
"bereich.verspaetet": "Verspätete Beförderung",
};

const { queryByText } = render(
<MigrationDataOverview
translations={translations}
userData={migrationUserData}
buttonUrl="any button url"
/>,
);

expect(queryByText("Mock Button")).toBeInTheDocument();
});

it("should not render a Mock Button in case props buttonUrl is not defined", () => {
const migrationUserData = {
bereich: "verspaetet",
};

const translations = {
bereich: "Problem",
"bereich.verspaetet": "Verspätete Beförderung",
};

const { queryByText } = render(
<MigrationDataOverview
translations={translations}
userData={migrationUserData}
/>,
);

expect(queryByText("Mock Button")).not.toBeInTheDocument();
});
});
3 changes: 2 additions & 1 deletion app/flows/flows.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import { prozesskostenhilfeFormular } from "./prozesskostenhilfeFormular";

export type FlowMigration = {
source: FlowId;
orderFields: string[];
sortedFields: string[];
buttonUrl?: string;
};

export type Flow = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ const happyPathSteps = [
"grundvoraussetzungen/prozessfaehig",
"grundvoraussetzungen/ausgleichszahlung",
"grundvoraussetzungen/zahlungsaufforderung",
"grundvoraussetzungen/daten-uebernahme",
"streitwert-kosten/gerichtskosten",
];

const cases = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,8 @@
"guard": "grundvoraussetzungenDone"
}
],
"BACK": "redirect-vorabcheck"
"BACK": "zahlungsaufforderung"
}
},
"redirect-vorabcheck": { "on": {} }
}
}
}
3 changes: 2 additions & 1 deletion app/flows/fluggastrechteFormular/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export const fluggastrechtFlow = {
cmsSlug: "form-flow-pages",
migration: {
source: "/fluggastrechte/vorabcheck",
orderFields: [
sortedFields: [
"bereich",
"startAirport",
"endAirport",
Expand All @@ -51,6 +51,7 @@ export const fluggastrechtFlow = {
"ersatzflugStartenZweiStunden",
"ersatzflugLandenVierStunden",
],
buttonUrl: "/fluggastrechte/vorabcheck/start",
},
stringReplacements: (context: FluggastrechtContext) => ({
...getStartAirportName(context),
Expand Down

This file was deleted.

8 changes: 4 additions & 4 deletions app/routes/shared/components/FormFlowPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,13 @@ export function FormFlowPage() {
csrf,
formElements,
heading,
migrationData,
migration,
navItems,
postFormContent,
preHeading,
stepData,
translations,
navigationA11yLabels,
migrationOrderFields,
} = useLoaderData<typeof loader>();
const stepId = splatFromParams(useParams());
const { pathname } = useLocation();
Expand Down Expand Up @@ -58,9 +57,10 @@ export function FormFlowPage() {
</div>

<MigrationDataOverview
migrationData={migrationData}
userData={migration.userData}
translations={translations}
migrationOrderFields={migrationOrderFields}
sortedFields={migration.sortedFields}
buttonUrl={migration.buttonUrl}
/>
{arraySummaryData && Object.keys(arraySummaryData).length != 0 && (
<div className="!mt-24">
Expand Down
16 changes: 11 additions & 5 deletions app/routes/shared/formular.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,11 +247,17 @@ export const loader = async ({
formElements,
heading: cmsContent.heading,
meta,
migrationData,
migrationOrderFields:
"migration" in currentFlow
? currentFlow.migration.orderFields
: undefined,
migration: {
userData: migrationData,
sortedFields:
"migration" in currentFlow
? currentFlow.migration.sortedFields
: undefined,
buttonUrl:
"migration" in currentFlow
? currentFlow.migration.buttonUrl
: undefined,
},
navItems,
postFormContent: cmsContent.postFormContent,
preHeading: cmsContent.preHeading,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const mockMigrationFlowDestination: Flow = {
cmsSlug: "form-flow-pages",
migration: {
source: "/fluggastrechte/vorabcheck",
orderFields: [],
sortedFields: [],
},
config: {},
guards: {},
Expand Down
Loading

0 comments on commit f385b33

Please sign in to comment.