diff --git a/src/app/label-data-validation/__tests__/page.test.tsx b/src/app/label-data-validation/__tests__/page.test.tsx
index c33d5de4..f2fdc46e 100644
--- a/src/app/label-data-validation/__tests__/page.test.tsx
+++ b/src/app/label-data-validation/__tests__/page.test.tsx
@@ -67,7 +67,7 @@ describe("LabelDataValidationPage Functionality", () => {
});
});
-describe("LabelDataValidationPage and OrganizationsForm Integration", () => {
+describe("LabelDataValidationPage and Forms Integration", () => {
it("marks the Organizations step as Completed or Incomplete when fields are Verified", () => {
render();
@@ -91,9 +91,7 @@ describe("LabelDataValidationPage and OrganizationsForm Integration", () => {
expect(targetSpan).not.toHaveClass("Mui-completed");
});
-});
-describe("LabelDataValidationPage and BaseInformationForm Integration", () => {
it("marks the Base Information step as Completed or Incomplete when fields are Verified", async () => {
render();
@@ -129,4 +127,38 @@ describe("LabelDataValidationPage and BaseInformationForm Integration", () => {
expect(targetSpan).not.toHaveClass("Mui-completed");
});
+
+ it("marks the Cautions step as Completed or Incomplete when fields are Verified", async () => {
+ render();
+
+ const spans = screen.getAllByText("cautions.stepTitle", {
+ exact: true,
+ });
+ const targetSpan = spans.find((span) =>
+ span.classList.contains("MuiStepLabel-label"),
+ );
+ expect(targetSpan).not.toHaveClass("Mui-completed");
+
+ const button = targetSpan!.closest("button");
+ await act(async () => {
+ fireEvent.click(button!);
+ });
+
+ const verifyButtons = screen.getAllByTestId(/verify-row-btn-cautions-\d+/);
+ expect(verifyButtons.length).toBeGreaterThanOrEqual(1);
+
+ for (const button of verifyButtons) {
+ await act(async () => {
+ fireEvent.click(button);
+ });
+ }
+
+ expect(targetSpan).toHaveClass("Mui-completed");
+
+ await act(async () => {
+ fireEvent.click(verifyButtons[0]);
+ });
+
+ expect(targetSpan).not.toHaveClass("Mui-completed");
+ });
});
diff --git a/src/components/__tests__/BaseInformationForm.test.tsx b/src/components/__tests__/BaseInformationForm.test.tsx
index 3ed1eba7..069e438a 100644
--- a/src/components/__tests__/BaseInformationForm.test.tsx
+++ b/src/components/__tests__/BaseInformationForm.test.tsx
@@ -1,4 +1,4 @@
-import { DEFAULT_BASE_INFORMATION, LabelData } from "@/types/types";
+import { DEFAULT_LABEL_DATA, LabelData } from "@/types/types";
import { render, screen } from "@testing-library/react";
import { useEffect, useState } from "react";
import { FormProvider, useForm } from "react-hook-form";
@@ -31,14 +31,7 @@ const Wrapper = ({
describe("BaseInformationForm Rendering", () => {
it("should render all fields with correct components", () => {
- render(
- ,
- );
+ render();
const verifiedFields = ["name", "registrationNumber", "lotNumber", "npk"];
const quantityFields = ["weight", "density", "volume"];
diff --git a/src/components/__tests__/CautionsForm.test.tsx b/src/components/__tests__/CautionsForm.test.tsx
new file mode 100644
index 00000000..b443c219
--- /dev/null
+++ b/src/components/__tests__/CautionsForm.test.tsx
@@ -0,0 +1,39 @@
+import { DEFAULT_LABEL_DATA } from "@/types/types";
+import { render, screen } from "@testing-library/react";
+import { useEffect, useState } from "react";
+import { FormProvider, useForm } from "react-hook-form";
+import CautionsForm from "../CautionsForm";
+
+const Wrapper = ({
+ initialData,
+ onStateChange,
+}: {
+ initialData: any;
+ onStateChange?: (data: any) => void;
+}) => {
+ const [labelData, setLabelData] = useState(initialData);
+ const methods = useForm({
+ defaultValues: labelData,
+ });
+
+ useEffect(() => {
+ if (onStateChange) {
+ onStateChange(labelData);
+ }
+ }, [labelData, onStateChange]);
+
+ return (
+
+
+
+ );
+};
+
+describe("CautionsForm Rendering", () => {
+ it("should render the VerifiedBilingualTable for cautions", () => {
+ render();
+
+ expect(screen.getByTestId("cautions-form")).toBeInTheDocument();
+ expect(screen.getByTestId("table-container-cautions")).toBeInTheDocument();
+ });
+});
diff --git a/src/components/__tests__/OrganizationsForm.test.tsx b/src/components/__tests__/OrganizationsForm.test.tsx
index 4dc49404..2fd3d36c 100644
--- a/src/components/__tests__/OrganizationsForm.test.tsx
+++ b/src/components/__tests__/OrganizationsForm.test.tsx
@@ -42,6 +42,7 @@ describe("OrganizationsForm Rendering", () => {
initialData={{
organizations: [DEFAULT_ORGANIZATION, DEFAULT_ORGANIZATION],
baseInformation: DEFAULT_BASE_INFORMATION,
+ cautions: [],
}}
/>,
);
@@ -67,8 +68,8 @@ describe("OrganizationsForm Rendering", () => {
render(
,
);
@@ -84,8 +85,8 @@ describe("OrganizationsForm Functionality", () => {
render(
,
);
@@ -226,8 +227,8 @@ describe("OrganizationsForm Functionality", () => {
render(
,
);
@@ -261,8 +262,8 @@ describe("OrganizationsForm Functionality", () => {
render(
,
@@ -319,8 +320,8 @@ describe("OrganizationsForm Functionality", () => {
render(
,
);
@@ -335,8 +336,8 @@ describe("OrganizationsForm Edge Cases", () => {
render(
,
);
diff --git a/src/components/__tests__/VerifiedBilingualTable.test.tsx b/src/components/__tests__/VerifiedBilingualTable.test.tsx
new file mode 100644
index 00000000..a7b35d97
--- /dev/null
+++ b/src/components/__tests__/VerifiedBilingualTable.test.tsx
@@ -0,0 +1,240 @@
+import { BilingualField } from "@/types/types";
+import { fireEvent, render, screen, waitFor } from "@testing-library/react";
+import { FormProvider, useForm } from "react-hook-form";
+import VerifiedBilingualTable from "../VerifiedBilingualTable";
+
+const Wrapper = ({
+ path = "bilingualFields",
+ defaultValues = {
+ bilingualFields: [
+ { en: "English Text", fr: "French Text", verified: false },
+ ],
+ },
+ onSubmit = jest.fn(),
+}: {
+ path?: string;
+ defaultValues?: {
+ bilingualFields: { en: string; fr: string; verified: boolean }[];
+ };
+ onSubmit?: (data: { bilingualFields: BilingualField[] }) => void;
+}) => {
+ const methods = useForm({
+ defaultValues,
+ mode: "onSubmit",
+ });
+
+ return (
+
+
+
+ );
+};
+
+describe("VerifiedBilingualTable rendering and functionality", () => {
+ it("renders with default values", () => {
+ render();
+
+ expect(
+ screen.getByTestId("table-header-english-bilingualFields"),
+ ).toHaveTextContent("verifiedBilingualTable.english");
+ expect(
+ screen.getByTestId("table-header-french-bilingualFields"),
+ ).toHaveTextContent("verifiedBilingualTable.french");
+ expect(
+ screen.getByTestId("table-header-actions-bilingualFields"),
+ ).toHaveTextContent("verifiedBilingualTable.actions");
+
+ const rows = screen.getAllByTestId(/table-row-bilingualFields-\d+/);
+ expect(rows.length).toBe(1);
+
+ const englishInputBase = screen.getByTestId(
+ "input-english-bilingualFields-0",
+ );
+ const englishInput = englishInputBase.querySelector(
+ "textarea",
+ ) as HTMLTextAreaElement;
+ const frenchInputBase = screen.getByTestId(
+ "input-french-bilingualFields-0",
+ );
+ const frenchInput = frenchInputBase.querySelector(
+ "textarea",
+ ) as HTMLTextAreaElement;
+
+ expect(englishInput.value).toBe("English Text");
+ expect(frenchInput.value).toBe("French Text");
+ });
+
+ it("adds a new row when Add button is clicked", () => {
+ render();
+
+ fireEvent.click(screen.getByTestId("add-row-btn-bilingualFields"));
+
+ const rows = screen.getAllByTestId(/table-row-bilingualFields-\d+/);
+ expect(rows.length).toBe(2);
+
+ const englishInputBase = screen.getByTestId(
+ "input-english-bilingualFields-1",
+ );
+ const englishInput = englishInputBase.querySelector(
+ "textarea",
+ ) as HTMLTextAreaElement;
+ const frenchInputBase = screen.getByTestId(
+ "input-french-bilingualFields-1",
+ );
+ const frenchInput = frenchInputBase.querySelector(
+ "textarea",
+ ) as HTMLTextAreaElement;
+
+ expect(englishInput.value).toBe("");
+ expect(frenchInput.value).toBe("");
+ });
+
+ it("deletes a row when Delete button is clicked", () => {
+ render();
+
+ fireEvent.click(screen.getByTestId("delete-row-btn-bilingualFields-0"));
+
+ const rows = screen.queryAllByTestId(/table-row-bilingualFields-\d+/);
+ expect(rows.length).toBe(0);
+ });
+
+ it("marks all rows as verified when Verify All button is clicked", () => {
+ render();
+
+ fireEvent.click(screen.getByTestId("verify-all-btn-bilingualFields"));
+
+ const verifyButtons = screen.getAllByTestId(
+ /verify-row-btn-bilingualFields-\d+/,
+ );
+ verifyButtons.forEach((button) => {
+ const icon = button.querySelector("svg");
+ expect(icon).toHaveClass("text-green-500");
+ });
+
+ const inputs = screen.getAllByTestId(
+ /input-(english|french)-bilingualFields-\d+/,
+ );
+ inputs.forEach((baseInput) => {
+ const textarea = baseInput.querySelector(
+ "textarea",
+ ) as HTMLTextAreaElement;
+ expect(textarea).toBeDisabled();
+ });
+
+ const deleteButtons = screen.getAllByTestId(
+ /delete-row-btn-bilingualFields-\d+/,
+ );
+ deleteButtons.forEach((button) => {
+ expect(button).toBeDisabled();
+ });
+ });
+
+ it("marks all rows as unverified when Unverify All button is clicked", () => {
+ const defaultValues = {
+ bilingualFields: [
+ { en: "Verified English 1", fr: "Verified French 1", verified: true },
+ { en: "Verified English 2", fr: "Verified French 2", verified: true },
+ ],
+ };
+
+ render();
+
+ const verifyButtonsBefore = screen.getAllByTestId(
+ /verify-row-btn-bilingualFields-\d+/,
+ );
+ verifyButtonsBefore.forEach((button) => {
+ const icon = button.querySelector("svg");
+ expect(icon).toHaveClass("text-green-500");
+ });
+
+ const inputsBefore = screen.getAllByTestId(
+ /input-(english|french)-bilingualFields-\d+/,
+ );
+ inputsBefore.forEach((baseInput) => {
+ const textarea = baseInput.querySelector(
+ "textarea",
+ ) as HTMLTextAreaElement;
+ expect(textarea).toBeDisabled();
+ });
+
+ const deleteButtonsBefore = screen.getAllByTestId(
+ /delete-row-btn-bilingualFields-\d+/,
+ );
+ deleteButtonsBefore.forEach((button) => {
+ expect(button).toBeDisabled();
+ });
+
+ fireEvent.click(screen.getByTestId("unverify-all-btn-bilingualFields"));
+
+ const verifyButtonsAfter = screen.getAllByTestId(
+ /verify-row-btn-bilingualFields-\d+/,
+ );
+ verifyButtonsAfter.forEach((button) => {
+ const icon = button.querySelector("svg");
+ expect(icon).not.toHaveClass("text-green-500");
+ });
+
+ const inputsAfter = screen.getAllByTestId(
+ /input-(english|french)-bilingualFields-\d+/,
+ );
+ inputsAfter.forEach((baseInput) => {
+ const textarea = baseInput.querySelector(
+ "textarea",
+ ) as HTMLTextAreaElement;
+ expect(textarea).not.toBeDisabled();
+ });
+
+ const deleteButtonsAfter = screen.getAllByTestId(
+ /delete-row-btn-bilingualFields-\d+/,
+ );
+ deleteButtonsAfter.forEach((button) => {
+ expect(button).not.toBeDisabled();
+ });
+ });
+
+ it("submits correct data on form submit", async () => {
+ const onSubmit = jest.fn();
+ render();
+
+ const englishTextarea = screen
+ .getByTestId("input-english-bilingualFields-0")
+ .querySelector("textarea") as HTMLTextAreaElement;
+
+ const frenchTextarea = screen
+ .getByTestId("input-french-bilingualFields-0")
+ .querySelector("textarea") as HTMLTextAreaElement;
+
+ fireEvent.change(englishTextarea, {
+ target: { value: "Updated English Text" },
+ });
+ fireEvent.change(frenchTextarea, {
+ target: { value: "Updated French Text" },
+ });
+
+ fireEvent.click(screen.getByTestId("submit-button"));
+
+ await waitFor(() => {
+ expect(onSubmit.mock.calls[0][0]).toEqual(
+ expect.objectContaining({
+ bilingualFields: [
+ {
+ en: "Updated English Text",
+ fr: "Updated French Text",
+ verified: false,
+ },
+ ],
+ }),
+ );
+ });
+ });
+});