Files
calendar/packages/features/form-builder/lib/formbuilder/test/testUtils.ts
T
fc592a17ac feat: Add 'Disable on Prefill' option for fields (#15715)
* feat:add prefilcheck check box in the field creation

* chore:formatted the li8 translations

* feat:add e2e test case for this feature

* refactor:reanmed the key from prefilledCheck to disableOnPrefill and moved the readOnly logic to formbuilderField

* chore:fixed the type check

* fix:if prefilled has error. do not disabble it

* chore:removed the e2e tests for prefill in e2e

* chore:revert back to old changes

* chore:remove unwanted code frome2e

* Support name field as well

* refactor:handled the feedback changes. still unit test cases pending

* feat: add unit tests for  disable field on prefill logic

* chore: resolved the type check and typos

* chore:renamed the files and type clean up

* Apply suggestions from code review

* chore:renaming test files and moving the disableonprefill hook to formbuilderFeild.

* refactor: add unit test for serach params and form values check and minor code formatting and file name changes

* fix: validating the input value partially at the intialising phase. so that form response values and  from ui values are same and making sure invalid data not sent to backend on submit.

* chore:fix the type check issue

* fix: field value valdiation at initilisation and add the  unit test cases for that change

* chore:add comments to the tests

* chore:resolve type check

* chore: moved the tests to the formBuilder

* Simplify codebase by ensuring select and multiselect changes the value when no option is found

* Relocate and refactor tests

* handle special cases

* Dont disable for dirty fields

* Update schema.prisma

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: Hariom <hariombalhara@gmail.com>
2024-08-18 17:34:59 +00:00

185 lines
5.8 KiB
TypeScript

import { fireEvent, waitFor, screen } from "@testing-library/react";
import { vi } from "vitest";
import type { z } from "zod";
import type { fieldsSchema } from "@calcom/features/form-builder/schema";
type RhfForm = {
fields: z.infer<typeof fieldsSchema>;
};
type RhfFormFields = RhfForm["fields"];
export type RhfFormField = RhfFormFields[number];
export type FieldType = RhfFormField["type"];
export interface QuestionProps {
questionType: string;
identifier: string;
label: string;
disableOnPrefill?: boolean;
}
export interface FormBuilderProps {
formProp: string;
title: string;
description: string;
addFieldLabel: string;
disabled: boolean;
LockedIcon: false | JSX.Element;
dataStore: {
options: Record<string, { label: string; value: string; inputPlaceholder?: string }[]>;
};
disableOnPrefill?: boolean;
}
export interface FormBuildFieldProps {
field: Omit<RhfFormField, "editable" | "label"> & {
// Label is optional because radioInput doesn't have a label
label?: string;
value: string;
};
readOnly: boolean;
}
export const mockProps: FormBuilderProps = {
formProp: "formProp",
title: "FormBuilder Title",
description: "FormBuilder Description",
addFieldLabel: "Add Field",
disabled: false,
LockedIcon: false,
dataStore: { options: {} },
disableOnPrefill: false,
};
export const mockFieldProps: FormBuildFieldProps = {
field: {
type: "text",
name: "test-text-n",
variant: "text",
placeholder: "text-test-p",
required: false,
label: "text-test-l",
disableOnPrefill: false,
value: "",
},
readOnly: false,
};
export const setMockMatchMedia = () => {
Object.defineProperty(window, "matchMedia", {
value: vi.fn().mockImplementation((query) => ({
matches: false,
media: query,
onchange: null,
addEventListener: vi.fn(),
removeEventListener: vi.fn(),
dispatchEvent: vi.fn(),
})),
});
};
export const setMockIntersectionObserver = () => {
Object.defineProperty(window, "IntersectionObserver", {
value: vi.fn().mockImplementation(() => ({
observe: vi.fn(),
unobserve: vi.fn(),
disconnect: vi.fn(),
takeRecords: vi.fn(() => []),
})),
});
};
export const clickDisablePrefillBasedOnUserInput = (disableOnPrefill?: boolean) => {
if (typeof disableOnPrefill === "boolean") {
// Get the checkbox element
const checkbox = getDisablePrefillCheckbox(disableOnPrefill) as HTMLInputElement;
// Determine if the checkbox's current state differs from the `disableOnPrefill` prop
const isChecked = checkbox ? checkbox.checked : false;
// Click the checkbox only if its current state differs from the `disableOnPrefill` value
if (isChecked !== disableOnPrefill) {
fireEvent.click(checkbox);
}
}
};
export const getDisablePrefillCheckbox = (disableOnPrefill?: boolean) => {
if (typeof disableOnPrefill === "boolean") {
const checkbox = screen.getByRole("checkbox", { name: /disable_input_if_prefilled/i });
return checkbox;
}
};
export const checkForDisablePreFillCheckox = (disableOnPrefill?: boolean) => {
const checkbox = getDisablePrefillCheckbox(disableOnPrefill);
expect(checkbox).toBeInTheDocument();
};
export const questionUtils = {
addQuestion: async (props: QuestionProps) => {
fireEvent.click(screen.getByTestId("add-field"));
checkForDisablePreFillCheckox(props?.disableOnPrefill);
fireEvent.keyDown(screen.getByTestId("test-field-type"), { key: "ArrowDown", code: "ArrowDown" });
fireEvent.click(screen.getByTestId(`select-option-${props.questionType}`));
fireEvent.change(screen.getAllByRole("textbox")[0], { target: { value: props.identifier } });
fireEvent.change(screen.getAllByRole("textbox")[1], { target: { value: props.label } });
clickDisablePrefillBasedOnUserInput(props?.disableOnPrefill);
fireEvent.click(screen.getByTestId("field-add-save"));
await waitFor(() => {
expect(screen.queryByTestId(`field-${props.identifier}`)).toBeInTheDocument();
});
},
editQuestion: async (props: {
identifier: string;
existingQuestionId: string;
disableOnPrefill?: boolean;
}) => {
fireEvent.click(screen.getByTestId("edit-field-action"));
checkForDisablePreFillCheckox(props?.disableOnPrefill);
fireEvent.change(screen.getAllByRole("textbox")[0], { target: { value: props.identifier } });
clickDisablePrefillBasedOnUserInput(props?.disableOnPrefill);
fireEvent.click(screen.getByTestId("field-add-save"));
await waitFor(() => {
expect(screen.queryByTestId(`field-${props.identifier}`)).toBeInTheDocument();
expect(screen.queryByTestId(`field-${props.existingQuestionId}`)).not.toBeInTheDocument();
});
},
deleteQuestion: async (existingQuestionId: string) => {
expect(screen.queryByTestId(`field-${existingQuestionId}`)).toBeInTheDocument();
fireEvent.click(screen.getByTestId("delete-field-action"));
await waitFor(() => {
expect(screen.queryByTestId(`field-${existingQuestionId}`)).not.toBeInTheDocument();
});
},
hideQuestion: async () => {
fireEvent.click(screen.getByTestId("toggle-field"));
await waitFor(() => {
expect(screen.queryByText(/hidden/i)).toBeInTheDocument();
});
},
requiredAndOptionalQuestion: async () => {
expect(screen.queryByTestId("required")).toBeInTheDocument();
fireEvent.click(screen.getByTestId("edit-field-action"));
fireEvent.click(screen.getAllByRole("radio")[1]);
fireEvent.click(screen.getByTestId("field-add-save"));
await waitFor(() => {
expect(screen.getByTestId("optional")).toBeInTheDocument();
});
},
expectedValueForDisablePreFillCheckox: async (expectedValue: boolean) => {
fireEvent.click(screen.getByTestId("edit-field-action"));
const checkbox = getDisablePrefillCheckbox(expectedValue) as HTMLInputElement;
await expect(checkbox?.checked).toBe(expectedValue);
},
};