@agilant/toga-blox 1.0.93 → 1.0.95
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/BaseInput/BaseCheckbox.d.ts +10 -0
- package/dist/components/BaseInput/BaseCheckbox.js +9 -0
- package/dist/components/BaseInput/BaseInput.d.ts +4 -0
- package/dist/components/BaseInput/BaseInput.js +100 -0
- package/dist/components/BaseInput/BaseInput.stories.d.ts +12 -0
- package/dist/components/BaseInput/BaseInput.stories.js +375 -0
- package/dist/components/BaseInput/BaseInput.test.d.ts +1 -0
- package/dist/components/BaseInput/BaseInput.test.js +560 -0
- package/dist/components/BaseInput/BaseInput.types.d.ts +139 -0
- package/dist/components/BaseInput/BaseInput.types.js +1 -0
- package/dist/components/BaseInput/BaseMultiSelect.d.ts +33 -0
- package/dist/components/BaseInput/BaseMultiSelect.js +68 -0
- package/dist/components/BaseInput/BaseRadio.d.ts +18 -0
- package/dist/components/BaseInput/BaseRadio.js +7 -0
- package/dist/components/BaseInput/BaseSelect.d.ts +41 -0
- package/dist/components/BaseInput/BaseSelect.js +83 -0
- package/dist/components/BaseInput/BaseTextInput.d.ts +27 -0
- package/dist/components/BaseInput/BaseTextInput.js +45 -0
- package/dist/components/BaseInput/BaseTextareaInput.d.ts +27 -0
- package/dist/components/BaseInput/BaseTextareaInput.js +36 -0
- package/dist/components/BaseInput/BaseToggle.d.ts +24 -0
- package/dist/components/BaseInput/BaseToggle.js +8 -0
- package/dist/components/BaseInput/DisabledSelect.d.ts +7 -0
- package/dist/components/BaseInput/DisabledSelect.js +6 -0
- package/dist/components/BaseInput/components/BaseErrorMessage.d.ts +8 -0
- package/dist/components/BaseInput/components/BaseErrorMessage.js +5 -0
- package/dist/components/BaseInput/components/CharacterLimitMessage.d.ts +9 -0
- package/dist/components/BaseInput/components/CharacterLimitMessage.js +7 -0
- package/dist/components/BaseInput/components/DropDownIndicator.d.ts +6 -0
- package/dist/components/BaseInput/components/DropDownIndicator.js +5 -0
- package/dist/components/BaseInput/components/MultiValueRemove.d.ts +4 -0
- package/dist/components/BaseInput/components/MultiValueRemove.js +7 -0
- package/dist/components/BaseInput/components/Option.d.ts +2 -0
- package/dist/components/BaseInput/components/Option.js +19 -0
- package/dist/components/BaseInput/components/SingleValue.d.ts +4 -0
- package/dist/components/BaseInput/components/SingleValue.js +14 -0
- package/dist/components/SearchInput/SearchInput.stories.js +0 -4
- package/dist/components/ToggleButton/ToggleButton.js +2 -2
- package/dist/utils/formatePhoneNumber.d.ts +2 -0
- package/dist/utils/formatePhoneNumber.js +14 -0
- package/dist/utils/fromatTableData.d.ts +46 -0
- package/dist/utils/fromatTableData.js +81 -0
- package/dist/utils/getColSPanClass.d.ts +2 -0
- package/dist/utils/getColSPanClass.js +15 -0
- package/package.json +2 -1
|
@@ -0,0 +1,560 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { render, screen, fireEvent } from "@testing-library/react";
|
|
3
|
+
import { describe, expect, test, vi } from "vitest";
|
|
4
|
+
import { FormProvider, useForm } from "react-hook-form";
|
|
5
|
+
import BaseInput from "./BaseInput";
|
|
6
|
+
// Mock Functions
|
|
7
|
+
const mockOnChange = vi.fn();
|
|
8
|
+
const mockOnBlur = vi.fn();
|
|
9
|
+
// Correctly Mock `react-hook-form`
|
|
10
|
+
vi.mock("react-hook-form", async (importOriginal) => {
|
|
11
|
+
const actual = await importOriginal();
|
|
12
|
+
return {
|
|
13
|
+
...(typeof actual === "object" ? actual : {}),
|
|
14
|
+
Controller: ({ render }) => {
|
|
15
|
+
return render({
|
|
16
|
+
field: {
|
|
17
|
+
onChange: (value) => {
|
|
18
|
+
console.log("Mocked onChange received:", value);
|
|
19
|
+
mockOnChange(value);
|
|
20
|
+
},
|
|
21
|
+
value: "",
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
},
|
|
25
|
+
useForm: () => ({
|
|
26
|
+
control: {},
|
|
27
|
+
register: vi.fn(),
|
|
28
|
+
handleSubmit: vi.fn(),
|
|
29
|
+
setValue: vi.fn((name, value) => {
|
|
30
|
+
if (name === "testValue") {
|
|
31
|
+
mockOnChange(value);
|
|
32
|
+
}
|
|
33
|
+
}),
|
|
34
|
+
formState: { errors: {}, dirtyFields: {} },
|
|
35
|
+
getValues: vi.fn(() => "mockValue"),
|
|
36
|
+
watch: vi.fn(),
|
|
37
|
+
}),
|
|
38
|
+
useFormContext: () => ({
|
|
39
|
+
control: {},
|
|
40
|
+
setValue: vi.fn((name, value) => {
|
|
41
|
+
if (name === "testValue") {
|
|
42
|
+
mockOnChange(value);
|
|
43
|
+
}
|
|
44
|
+
}),
|
|
45
|
+
getValues: vi.fn(() => "mockValue"),
|
|
46
|
+
watch: vi.fn(),
|
|
47
|
+
formState: {
|
|
48
|
+
errors: {
|
|
49
|
+
testValue: { message: "This field is required." },
|
|
50
|
+
},
|
|
51
|
+
dirtyFields: { testValue: true },
|
|
52
|
+
},
|
|
53
|
+
}),
|
|
54
|
+
FormProvider: actual.FormProvider,
|
|
55
|
+
};
|
|
56
|
+
});
|
|
57
|
+
// Helper function to wrap components in `FormProvider`
|
|
58
|
+
const renderWithForm = (ui) => {
|
|
59
|
+
const Wrapper = ({ children }) => {
|
|
60
|
+
const methods = useForm();
|
|
61
|
+
return _jsx(FormProvider, { ...methods, children: children });
|
|
62
|
+
};
|
|
63
|
+
return render(ui, { wrapper: Wrapper });
|
|
64
|
+
};
|
|
65
|
+
// Common `defaultProps` for `BaseTextInput`
|
|
66
|
+
const getDefaultProps = () => ({
|
|
67
|
+
uuid: "123",
|
|
68
|
+
defaultValue: "Default Value",
|
|
69
|
+
valueKey: "testValue",
|
|
70
|
+
control: {},
|
|
71
|
+
onBlur: mockOnBlur,
|
|
72
|
+
inputLabel: "Test Input",
|
|
73
|
+
placeholder: "Enter text",
|
|
74
|
+
isRequired: true,
|
|
75
|
+
showRequiredIndicator: true,
|
|
76
|
+
inputClasses: "border",
|
|
77
|
+
field: {
|
|
78
|
+
uuid: "123",
|
|
79
|
+
label: "Test Input",
|
|
80
|
+
valueKey: "testValue",
|
|
81
|
+
inputType: "text",
|
|
82
|
+
placeholder: "Enter text",
|
|
83
|
+
isRequired: true,
|
|
84
|
+
defaultValue: "Default Value",
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
// Test Suite for `BaseInput`
|
|
88
|
+
describe("BaseInput Component", () => {
|
|
89
|
+
describe("BaseTextInput", () => {
|
|
90
|
+
test("renders text input field", () => {
|
|
91
|
+
renderWithForm(_jsx(BaseInput, { ...getDefaultProps(), inputType: "text" }));
|
|
92
|
+
expect(screen.getByPlaceholderText("Enter text")).toBeInTheDocument();
|
|
93
|
+
});
|
|
94
|
+
test("calls onChange when input value is changed", async () => {
|
|
95
|
+
renderWithForm(_jsx(BaseInput, { ...getDefaultProps(), inputType: "text" }));
|
|
96
|
+
const input = screen.getByPlaceholderText("Enter text");
|
|
97
|
+
fireEvent.change(input, { target: { value: "Test Input" } });
|
|
98
|
+
expect(mockOnChange).toHaveBeenCalled();
|
|
99
|
+
expect(mockOnChange).toHaveBeenCalledWith("Test Input");
|
|
100
|
+
});
|
|
101
|
+
test("triggers onBlur event when input loses focus", () => {
|
|
102
|
+
renderWithForm(_jsx(BaseInput, { ...getDefaultProps(), inputType: "text" }));
|
|
103
|
+
const input = screen.getByPlaceholderText("Enter text");
|
|
104
|
+
fireEvent.blur(input);
|
|
105
|
+
expect(mockOnBlur).toHaveBeenCalled();
|
|
106
|
+
});
|
|
107
|
+
test("displays required asterisk when field is required", () => {
|
|
108
|
+
renderWithForm(_jsx(BaseInput, { ...getDefaultProps(), inputType: "text" }));
|
|
109
|
+
expect(screen.getByText("*")).toBeInTheDocument();
|
|
110
|
+
});
|
|
111
|
+
test("shows error message when validation fails", async () => {
|
|
112
|
+
const errorProps = {
|
|
113
|
+
...getDefaultProps(),
|
|
114
|
+
isRequired: true,
|
|
115
|
+
};
|
|
116
|
+
renderWithForm(_jsx(BaseInput, { ...errorProps, inputType: "text" }));
|
|
117
|
+
const input = screen.getByPlaceholderText("Enter text");
|
|
118
|
+
// Trigger validation by blurring the input field
|
|
119
|
+
fireEvent.blur(input);
|
|
120
|
+
// Wait for error message to appear
|
|
121
|
+
expect(await screen.findByText("This field is required.")).toBeInTheDocument();
|
|
122
|
+
});
|
|
123
|
+
test("applies error styles when field has an error", async () => {
|
|
124
|
+
const errorProps = {
|
|
125
|
+
...getDefaultProps(),
|
|
126
|
+
isRequired: true,
|
|
127
|
+
};
|
|
128
|
+
renderWithForm(_jsx(BaseInput, { ...errorProps, inputType: "text" }));
|
|
129
|
+
const input = screen.getByPlaceholderText("Enter text");
|
|
130
|
+
// Trigger validation
|
|
131
|
+
fireEvent.blur(input);
|
|
132
|
+
// Check if error class is applied
|
|
133
|
+
await screen.findByText("This field is required.");
|
|
134
|
+
expect(input).toHaveClass("border-red-500");
|
|
135
|
+
});
|
|
136
|
+
test("applies dirty styles when field is modified", async () => {
|
|
137
|
+
const dirtyProps = {
|
|
138
|
+
...getDefaultProps(),
|
|
139
|
+
isRequired: true,
|
|
140
|
+
};
|
|
141
|
+
renderWithForm(_jsx(BaseInput, { ...dirtyProps, inputType: "text" }));
|
|
142
|
+
const input = screen.getByPlaceholderText("Enter text");
|
|
143
|
+
// Modify input value
|
|
144
|
+
fireEvent.change(input, { target: { value: "New Value" } });
|
|
145
|
+
// Check if dirty class is applied
|
|
146
|
+
expect(input).toHaveClass("border-red-500");
|
|
147
|
+
});
|
|
148
|
+
test("does not show required asterisk when `showRequiredIndicator` is false", () => {
|
|
149
|
+
const propsWithoutIndicator = {
|
|
150
|
+
...getDefaultProps(),
|
|
151
|
+
showRequiredIndicator: false,
|
|
152
|
+
};
|
|
153
|
+
renderWithForm(_jsx(BaseInput, { ...propsWithoutIndicator, inputType: "text" }));
|
|
154
|
+
expect(screen.queryByText("*")).not.toBeInTheDocument();
|
|
155
|
+
});
|
|
156
|
+
test("does not call onChange when non-numeric input is entered and hasTypeCheck is 'number'", async () => {
|
|
157
|
+
// Create props with `hasTypeCheck: "number"`
|
|
158
|
+
const numberProps = {
|
|
159
|
+
...getDefaultProps(),
|
|
160
|
+
hasTypeCheck: "number",
|
|
161
|
+
};
|
|
162
|
+
renderWithForm(_jsx(BaseInput, { ...numberProps, inputType: "text" }));
|
|
163
|
+
const input = screen.getByPlaceholderText("Enter text");
|
|
164
|
+
// Clear previous mock calls
|
|
165
|
+
mockOnChange.mockClear();
|
|
166
|
+
// Try entering non-numeric characters
|
|
167
|
+
fireEvent.change(input, { target: { value: "abc" } });
|
|
168
|
+
// Ensure `onChange` was NOT called
|
|
169
|
+
expect(mockOnChange).not.toHaveBeenCalled();
|
|
170
|
+
});
|
|
171
|
+
test("formats phone number when valueType is 'phone'", () => {
|
|
172
|
+
const phoneProps = {
|
|
173
|
+
...getDefaultProps(),
|
|
174
|
+
valueType: "phone",
|
|
175
|
+
};
|
|
176
|
+
renderWithForm(_jsx(BaseInput, { ...phoneProps, inputType: "text" }));
|
|
177
|
+
const input = screen.getByPlaceholderText("Enter text");
|
|
178
|
+
fireEvent.change(input, { target: { value: "1234567890" } });
|
|
179
|
+
expect(mockOnChange).toHaveBeenCalledWith("(123) 456-7890"); // Assuming formatPhoneNumber formats it this way
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
describe("BaseTextareaInput", () => {
|
|
183
|
+
const getTextareaProps = () => ({
|
|
184
|
+
...getDefaultProps(),
|
|
185
|
+
inputType: "textArea",
|
|
186
|
+
textAreaHeight: "small",
|
|
187
|
+
characterLimit: 200,
|
|
188
|
+
field: {
|
|
189
|
+
uuid: "123",
|
|
190
|
+
label: "Test Input",
|
|
191
|
+
valueKey: "testValue",
|
|
192
|
+
inputType: "textArea",
|
|
193
|
+
placeholder: "Enter text",
|
|
194
|
+
isRequired: true,
|
|
195
|
+
defaultValue: "Default Value",
|
|
196
|
+
},
|
|
197
|
+
});
|
|
198
|
+
test("renders textarea field", () => {
|
|
199
|
+
renderWithForm(_jsx(BaseInput, { ...getTextareaProps() }));
|
|
200
|
+
expect(screen.getByPlaceholderText("Enter text")).toBeInTheDocument();
|
|
201
|
+
});
|
|
202
|
+
test("calls onChange when textarea value is changed", async () => {
|
|
203
|
+
renderWithForm(_jsx(BaseInput, { ...getTextareaProps() }));
|
|
204
|
+
const textarea = screen.getByPlaceholderText("Enter text");
|
|
205
|
+
fireEvent.change(textarea, { target: { value: "New Value" } });
|
|
206
|
+
expect(mockOnChange).toHaveBeenCalled();
|
|
207
|
+
});
|
|
208
|
+
// test("displays character limit message when input exceeds limit", async () => {
|
|
209
|
+
// const longText = "A".repeat(201); // Exceeding limit
|
|
210
|
+
// renderWithForm(
|
|
211
|
+
// <BaseInput {...getTextareaProps()} requireUuidField={true} />
|
|
212
|
+
// );
|
|
213
|
+
// const textarea = screen.getByPlaceholderText("Enter text");
|
|
214
|
+
// fireEvent.change(textarea, { target: { value: longText } });
|
|
215
|
+
// expect(await screen.findByText("200/200")).toBeInTheDocument();
|
|
216
|
+
// });
|
|
217
|
+
// test("triggers onBlur event when textarea loses focus", async () => {
|
|
218
|
+
// renderWithForm(<BaseInput {...getTextareaProps()} />);
|
|
219
|
+
// const textarea = await screen.findByPlaceholderText("Enter text");
|
|
220
|
+
// expect(textarea).toBeInTheDocument(); // Confirm it exists
|
|
221
|
+
// fireEvent.blur(textarea);
|
|
222
|
+
// expect(mockOnBlur).toHaveBeenCalled();
|
|
223
|
+
// });
|
|
224
|
+
test("shows error message when validation fails", async () => {
|
|
225
|
+
const errorProps = {
|
|
226
|
+
...getTextareaProps(),
|
|
227
|
+
isRequired: true,
|
|
228
|
+
};
|
|
229
|
+
renderWithForm(_jsx(BaseInput, { ...errorProps }));
|
|
230
|
+
const textarea = screen.getByPlaceholderText("Enter text");
|
|
231
|
+
fireEvent.blur(textarea);
|
|
232
|
+
expect(await screen.findByText("This field is required.")).toBeInTheDocument();
|
|
233
|
+
});
|
|
234
|
+
test("applies error styles when textarea has an error", async () => {
|
|
235
|
+
const errorProps = {
|
|
236
|
+
...getTextareaProps(),
|
|
237
|
+
isRequired: true,
|
|
238
|
+
};
|
|
239
|
+
renderWithForm(_jsx(BaseInput, { ...errorProps }));
|
|
240
|
+
const textarea = screen.getByPlaceholderText("Enter text");
|
|
241
|
+
fireEvent.blur(textarea);
|
|
242
|
+
await screen.findByText("This field is required.");
|
|
243
|
+
expect(textarea).toHaveClass("border-red-500");
|
|
244
|
+
});
|
|
245
|
+
test("does not show required asterisk when `showRequiredIndicator` is false", () => {
|
|
246
|
+
const propsWithoutIndicator = {
|
|
247
|
+
...getTextareaProps(),
|
|
248
|
+
showRequiredIndicator: false,
|
|
249
|
+
};
|
|
250
|
+
renderWithForm(_jsx(BaseInput, { ...propsWithoutIndicator }));
|
|
251
|
+
expect(screen.queryByText("*")).not.toBeInTheDocument();
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
describe("BaseCheckboxInput", () => {
|
|
255
|
+
const getCheckboxProps = () => ({
|
|
256
|
+
...getDefaultProps(),
|
|
257
|
+
inputType: "checkbox",
|
|
258
|
+
defaultValue: false,
|
|
259
|
+
checkboxBorderColorOnChecked: "border-green-500",
|
|
260
|
+
checkboxBackgroundColor: "bg-green-500",
|
|
261
|
+
field: {
|
|
262
|
+
uuid: "123",
|
|
263
|
+
label: "Test Checkbox",
|
|
264
|
+
valueKey: "testCheckbox",
|
|
265
|
+
inputType: "checkbox",
|
|
266
|
+
isRequired: true,
|
|
267
|
+
defaultValue: false,
|
|
268
|
+
},
|
|
269
|
+
});
|
|
270
|
+
test("renders checkbox field", () => {
|
|
271
|
+
renderWithForm(_jsx(BaseInput, { ...getCheckboxProps() }));
|
|
272
|
+
expect(screen.getByRole("checkbox")).toBeInTheDocument();
|
|
273
|
+
});
|
|
274
|
+
test("calls onChange when checkbox is checked", () => {
|
|
275
|
+
renderWithForm(_jsx(BaseInput, { ...getCheckboxProps() }));
|
|
276
|
+
const checkbox = screen.getByRole("checkbox");
|
|
277
|
+
fireEvent.click(checkbox);
|
|
278
|
+
expect(mockOnChange).toHaveBeenCalled();
|
|
279
|
+
expect(mockOnChange).toHaveBeenCalledWith(true); // Checkbox should be checked
|
|
280
|
+
});
|
|
281
|
+
test("calls onChange when checkbox is unchecked", () => {
|
|
282
|
+
renderWithForm(_jsx(BaseInput, { ...getCheckboxProps() }));
|
|
283
|
+
const checkbox = screen.getByRole("checkbox");
|
|
284
|
+
fireEvent.click(checkbox); // Check
|
|
285
|
+
fireEvent.click(checkbox); // Uncheck
|
|
286
|
+
expect(mockOnChange).toHaveBeenCalled();
|
|
287
|
+
});
|
|
288
|
+
test("applies correct styles when checkbox is checked", () => {
|
|
289
|
+
renderWithForm(_jsx(BaseInput, { ...getCheckboxProps() }));
|
|
290
|
+
const checkbox = screen.getByRole("checkbox");
|
|
291
|
+
fireEvent.click(checkbox);
|
|
292
|
+
expect(checkbox).toHaveClass("border-green-500");
|
|
293
|
+
expect(checkbox).toHaveClass("bg-green-500");
|
|
294
|
+
});
|
|
295
|
+
test("checkbox starts with default value (unchecked)", () => {
|
|
296
|
+
const props = { ...getCheckboxProps(), defaultValue: false };
|
|
297
|
+
renderWithForm(_jsx(BaseInput, { ...props }));
|
|
298
|
+
const checkbox = screen.getByRole("checkbox");
|
|
299
|
+
expect(checkbox).not.toBeChecked(); // Should start unchecked
|
|
300
|
+
});
|
|
301
|
+
test("does not show required asterisk when `showRequiredIndicator` is false", () => {
|
|
302
|
+
const propsWithoutIndicator = {
|
|
303
|
+
...getCheckboxProps(),
|
|
304
|
+
showRequiredIndicator: false,
|
|
305
|
+
};
|
|
306
|
+
renderWithForm(_jsx(BaseInput, { ...propsWithoutIndicator }));
|
|
307
|
+
expect(screen.queryByText("*")).not.toBeInTheDocument();
|
|
308
|
+
});
|
|
309
|
+
});
|
|
310
|
+
describe("BaseToggleInput", () => {
|
|
311
|
+
const getToggleProps = () => ({
|
|
312
|
+
...getDefaultProps(),
|
|
313
|
+
inputType: "toggle",
|
|
314
|
+
defaultValue: false,
|
|
315
|
+
toggleTextPosition: "right",
|
|
316
|
+
toggleTextSize: "sm",
|
|
317
|
+
toggleActiveColorBackground: "bg-blue-600",
|
|
318
|
+
toggleInactiveColorBackground: "bg-blue-300",
|
|
319
|
+
toggleActiveColorBorder: "border-blue-500",
|
|
320
|
+
toggleInactiveColorBorder: "border-blue-300",
|
|
321
|
+
toggleActiveTextColor: "text-blue-800",
|
|
322
|
+
toggleInactiveTextColor: "text-blue-600",
|
|
323
|
+
toggleAdditionalClasses: `w-1/4`,
|
|
324
|
+
toggleHasDivider: false,
|
|
325
|
+
toggleFontFamily: "font-omnes-regular",
|
|
326
|
+
toggleActiveLabel: "Yes",
|
|
327
|
+
toggleInactiveLabel: "No",
|
|
328
|
+
toggleSmallToggle: true,
|
|
329
|
+
toggleBorderStyle: true,
|
|
330
|
+
field: {
|
|
331
|
+
uuid: "123",
|
|
332
|
+
label: "Test Toggle",
|
|
333
|
+
valueKey: "testToggle",
|
|
334
|
+
inputType: "toggle",
|
|
335
|
+
isRequired: true,
|
|
336
|
+
defaultValue: false,
|
|
337
|
+
},
|
|
338
|
+
});
|
|
339
|
+
test("renders toggle field", () => {
|
|
340
|
+
renderWithForm(_jsx(BaseInput, { ...getToggleProps() }));
|
|
341
|
+
expect(screen.getByRole("checkbox")).toBeInTheDocument();
|
|
342
|
+
});
|
|
343
|
+
test("calls onChange when toggle is clicked", () => {
|
|
344
|
+
renderWithForm(_jsx(BaseInput, { ...getToggleProps() }));
|
|
345
|
+
const toggleCheckbox = screen.getByRole("checkbox");
|
|
346
|
+
fireEvent.click(toggleCheckbox);
|
|
347
|
+
expect(mockOnChange).toHaveBeenCalled();
|
|
348
|
+
expect(mockOnChange).toHaveBeenCalledWith(true); // ✅ Toggle should be switched ON
|
|
349
|
+
});
|
|
350
|
+
test("calls onChange when toggle is clicked again", () => {
|
|
351
|
+
renderWithForm(_jsx(BaseInput, { ...getToggleProps() }));
|
|
352
|
+
const toggleCheckbox = screen.getByRole("checkbox");
|
|
353
|
+
fireEvent.click(toggleCheckbox); // Switch ON
|
|
354
|
+
fireEvent.click(toggleCheckbox); // Switch OFF
|
|
355
|
+
expect(mockOnChange).toHaveBeenCalled();
|
|
356
|
+
expect(mockOnChange.mock.calls.length).toBeGreaterThan(1);
|
|
357
|
+
});
|
|
358
|
+
test("applies correct styles when toggle is inactive", () => {
|
|
359
|
+
renderWithForm(_jsx(BaseInput, { ...getToggleProps() }));
|
|
360
|
+
const toggleCheckbox = screen.getByRole("checkbox");
|
|
361
|
+
expect(toggleCheckbox).not.toBeChecked();
|
|
362
|
+
});
|
|
363
|
+
test("toggle starts with default value (OFF)", () => {
|
|
364
|
+
const props = { ...getToggleProps(), defaultValue: false };
|
|
365
|
+
renderWithForm(_jsx(BaseInput, { ...props }));
|
|
366
|
+
const toggleCheckbox = screen.getByRole("checkbox");
|
|
367
|
+
expect(toggleCheckbox).not.toBeChecked();
|
|
368
|
+
});
|
|
369
|
+
test("does not show required asterisk when `showRequiredIndicator` is false", () => {
|
|
370
|
+
const propsWithoutIndicator = {
|
|
371
|
+
...getToggleProps(),
|
|
372
|
+
showRequiredIndicator: false,
|
|
373
|
+
};
|
|
374
|
+
renderWithForm(_jsx(BaseInput, { ...propsWithoutIndicator }));
|
|
375
|
+
expect(screen.queryByText("*")).not.toBeInTheDocument();
|
|
376
|
+
});
|
|
377
|
+
});
|
|
378
|
+
describe("DisabledSelect", () => {
|
|
379
|
+
const getDisabledSelectProps = () => ({
|
|
380
|
+
...getDefaultProps(),
|
|
381
|
+
inputType: "disabledSelect",
|
|
382
|
+
disabledSelectText: "Disabled Option",
|
|
383
|
+
labelTextClasses: "text-gray-500",
|
|
384
|
+
});
|
|
385
|
+
test("renders DisabledSelect with correct text", () => {
|
|
386
|
+
renderWithForm(_jsx(BaseInput, { ...getDisabledSelectProps() }));
|
|
387
|
+
expect(screen.getByText("Disabled Option")).toBeInTheDocument();
|
|
388
|
+
});
|
|
389
|
+
test("applies provided text classes", () => {
|
|
390
|
+
renderWithForm(_jsx(BaseInput, { ...getDisabledSelectProps() }));
|
|
391
|
+
const container = screen
|
|
392
|
+
.getByText("Disabled Option")
|
|
393
|
+
.closest("div");
|
|
394
|
+
expect(container).toHaveClass("text-gray-500");
|
|
395
|
+
});
|
|
396
|
+
test("contains an SVG icon", () => {
|
|
397
|
+
renderWithForm(_jsx(BaseInput, { ...getDisabledSelectProps() }));
|
|
398
|
+
const icon = document.querySelector("svg");
|
|
399
|
+
expect(icon).toBeInTheDocument();
|
|
400
|
+
});
|
|
401
|
+
test("should not be clickable", () => {
|
|
402
|
+
renderWithForm(_jsx(BaseInput, { ...getDisabledSelectProps() }));
|
|
403
|
+
// Get the div containing the text
|
|
404
|
+
const textDiv = screen.getByText("Disabled Option");
|
|
405
|
+
const container = textDiv.closest("div")?.parentElement?.parentElement;
|
|
406
|
+
fireEvent.click(container);
|
|
407
|
+
// Ensure the parent div has the correct class
|
|
408
|
+
expect(container).toHaveClass("hover:cursor-not-allowed");
|
|
409
|
+
});
|
|
410
|
+
});
|
|
411
|
+
describe("BaseRadioInput", () => {
|
|
412
|
+
const getRadioProps = () => ({
|
|
413
|
+
valueKey: "testRadio",
|
|
414
|
+
defaultValue: "option1",
|
|
415
|
+
inputType: "radio",
|
|
416
|
+
control: {},
|
|
417
|
+
options: [
|
|
418
|
+
{ value: "option1", label: "Option 1" },
|
|
419
|
+
{ value: "option2", label: "Option 2" },
|
|
420
|
+
{ value: "option3", label: "Option 3" },
|
|
421
|
+
],
|
|
422
|
+
field: {
|
|
423
|
+
uuid: "123",
|
|
424
|
+
label: "Test Radio",
|
|
425
|
+
valueKey: "testRadio",
|
|
426
|
+
inputType: "radio",
|
|
427
|
+
isRequired: true,
|
|
428
|
+
defaultValue: false,
|
|
429
|
+
},
|
|
430
|
+
});
|
|
431
|
+
test("renders radio options", () => {
|
|
432
|
+
renderWithForm(_jsx(BaseInput, { ...getRadioProps() }));
|
|
433
|
+
screen.debug();
|
|
434
|
+
const radioButtons = screen.getAllByRole("radio");
|
|
435
|
+
expect(radioButtons).toHaveLength(3);
|
|
436
|
+
// Validate options
|
|
437
|
+
expect(screen.getByText("Option 1")).toBeInTheDocument();
|
|
438
|
+
expect(screen.getByText("Option 2")).toBeInTheDocument();
|
|
439
|
+
expect(screen.getByText("Option 3")).toBeInTheDocument();
|
|
440
|
+
});
|
|
441
|
+
test("sets default selected radio button", () => {
|
|
442
|
+
renderWithForm(_jsx(BaseInput, { ...getRadioProps() }));
|
|
443
|
+
const option1 = screen.getAllByRole("radio")[0];
|
|
444
|
+
// Check if the radio button has the expected checked styles
|
|
445
|
+
expect(option1).toHaveClass("checked:border-blue-600");
|
|
446
|
+
expect(option1).toHaveClass("checked:bg-blue-600");
|
|
447
|
+
});
|
|
448
|
+
test("changes selection when a different radio button is clicked", () => {
|
|
449
|
+
renderWithForm(_jsx(BaseInput, { ...getRadioProps() }));
|
|
450
|
+
const radioButtons = screen.getAllByRole("radio");
|
|
451
|
+
// Select option 2
|
|
452
|
+
fireEvent.click(radioButtons[1]);
|
|
453
|
+
expect(mockOnChange).toHaveBeenCalledWith("option2");
|
|
454
|
+
});
|
|
455
|
+
test("only one radio button remains selected at a time", () => {
|
|
456
|
+
renderWithForm(_jsx(BaseInput, { ...getRadioProps() }));
|
|
457
|
+
const radioButtons = screen.getAllByRole("radio");
|
|
458
|
+
// Initially, option 1 should have checked styles
|
|
459
|
+
expect(radioButtons[0]).toHaveClass("checked:border-blue-600");
|
|
460
|
+
expect(radioButtons[0]).toHaveClass("checked:bg-blue-600");
|
|
461
|
+
// Click option 2
|
|
462
|
+
fireEvent.click(radioButtons[1]);
|
|
463
|
+
// Now, option 2 should have checked styles
|
|
464
|
+
expect(radioButtons[1]).toHaveClass("checked:border-blue-600");
|
|
465
|
+
expect(radioButtons[1]).toHaveClass("checked:bg-blue-600");
|
|
466
|
+
});
|
|
467
|
+
});
|
|
468
|
+
describe("BaseSelect", () => {
|
|
469
|
+
const mockSetValue = vi.fn();
|
|
470
|
+
// Common Props for Select Input
|
|
471
|
+
const getSelectProps = () => ({
|
|
472
|
+
valueKey: "testSelect",
|
|
473
|
+
inputType: "select",
|
|
474
|
+
control: {},
|
|
475
|
+
options: [
|
|
476
|
+
{ uuid: "1", name: "Option 1" },
|
|
477
|
+
{ uuid: "2", name: "Option 2" },
|
|
478
|
+
{ uuid: "3", name: "Option 3" },
|
|
479
|
+
],
|
|
480
|
+
field: {
|
|
481
|
+
uuid: "123",
|
|
482
|
+
label: "Test Select",
|
|
483
|
+
valueKey: "testSelect",
|
|
484
|
+
inputType: "select",
|
|
485
|
+
isRequired: true,
|
|
486
|
+
defaultValue: false,
|
|
487
|
+
},
|
|
488
|
+
placeholder: "Select an option",
|
|
489
|
+
defaultValue: { uuid: "1", name: "Option 1" },
|
|
490
|
+
isSearchable: true,
|
|
491
|
+
setValue: mockSetValue,
|
|
492
|
+
getValues: () => null,
|
|
493
|
+
});
|
|
494
|
+
test("renders select input field", async () => {
|
|
495
|
+
renderWithForm(_jsx(BaseInput, { ...getSelectProps() }));
|
|
496
|
+
expect(screen.getByText("Select an option")).toBeInTheDocument();
|
|
497
|
+
});
|
|
498
|
+
test("displays available options when clicked", async () => {
|
|
499
|
+
renderWithForm(_jsx(BaseInput, { ...getSelectProps() }));
|
|
500
|
+
const selectInput = screen.getByText("Select an option");
|
|
501
|
+
// Open dropdown
|
|
502
|
+
fireEvent.mouseDown(selectInput);
|
|
503
|
+
// Wait for options to appear
|
|
504
|
+
expect(await screen.findByText("Option 1")).toBeInTheDocument();
|
|
505
|
+
expect(await screen.findByText("Option 2")).toBeInTheDocument();
|
|
506
|
+
expect(await screen.findByText("Option 3")).toBeInTheDocument();
|
|
507
|
+
});
|
|
508
|
+
});
|
|
509
|
+
describe("BaseMultiSelect", () => {
|
|
510
|
+
const getMultiSelectProps = () => ({
|
|
511
|
+
valueKey: "testMultiSelect",
|
|
512
|
+
inputType: "multiSelect",
|
|
513
|
+
control: {},
|
|
514
|
+
defaultValue: [],
|
|
515
|
+
options: [
|
|
516
|
+
{ uuid: "1", name: "Option 1" },
|
|
517
|
+
{ uuid: "2", name: "Option 2" },
|
|
518
|
+
{ uuid: "3", name: "Option 3" },
|
|
519
|
+
],
|
|
520
|
+
placeholder: "Select multiple options",
|
|
521
|
+
isRequired: true,
|
|
522
|
+
isSearchable: true,
|
|
523
|
+
field: {
|
|
524
|
+
uuid: "123",
|
|
525
|
+
label: "Test Multi-Select",
|
|
526
|
+
valueKey: "testMultiSelect",
|
|
527
|
+
inputType: "multiSelect",
|
|
528
|
+
placeholder: "Select multiple options",
|
|
529
|
+
isRequired: true,
|
|
530
|
+
defaultValue: [],
|
|
531
|
+
},
|
|
532
|
+
});
|
|
533
|
+
test("renders multi-select dropdown with label", () => {
|
|
534
|
+
renderWithForm(_jsx(BaseInput, { ...getMultiSelectProps() }));
|
|
535
|
+
expect(screen.getByText("Select multiple options")).toBeInTheDocument();
|
|
536
|
+
});
|
|
537
|
+
test("displays available options when clicked", async () => {
|
|
538
|
+
renderWithForm(_jsx(BaseInput, { ...getMultiSelectProps() }));
|
|
539
|
+
// Open dropdown
|
|
540
|
+
const selectInput = screen.getByText("Select multiple options");
|
|
541
|
+
fireEvent.mouseDown(selectInput);
|
|
542
|
+
// Wait for options to appear
|
|
543
|
+
const option1 = await screen.findByText("Option 1");
|
|
544
|
+
const option2 = await screen.findByText("Option 2");
|
|
545
|
+
expect(option1).toBeInTheDocument();
|
|
546
|
+
expect(option2).toBeInTheDocument();
|
|
547
|
+
});
|
|
548
|
+
test("allows searching for options", async () => {
|
|
549
|
+
renderWithForm(_jsx(BaseInput, { ...getMultiSelectProps() }));
|
|
550
|
+
// Open dropdown
|
|
551
|
+
fireEvent.mouseDown(screen.getByText("Select multiple options"));
|
|
552
|
+
// Type search query
|
|
553
|
+
const searchInput = screen.getByRole("combobox");
|
|
554
|
+
fireEvent.change(searchInput, { target: { value: "Option 2" } });
|
|
555
|
+
// Verify filtered result
|
|
556
|
+
expect(await screen.findByText("Option 2")).toBeInTheDocument();
|
|
557
|
+
expect(screen.queryByText("Option 1")).not.toBeInTheDocument();
|
|
558
|
+
});
|
|
559
|
+
});
|
|
560
|
+
});
|