@jobber/components-native 0.101.3 → 0.101.4

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.
Files changed (182) hide show
  1. package/dist/package.json +19 -11
  2. package/dist/src/ActionItem/ActionItem.test.js +81 -0
  3. package/dist/src/ActionItem/ActionItemGroup.test.js +25 -0
  4. package/dist/src/ActionItem/components/ActionItemContainer.test.js +24 -0
  5. package/dist/src/ActionLabel/ActionLabel.test.js +81 -0
  6. package/dist/src/ActivityIndicator/ActivityIndicator.test.js +23 -0
  7. package/dist/src/AtlantisContext/AtlantisContext.test.js +35 -0
  8. package/dist/src/AtlantisThemeContext/AtlantisThemeContext.test.js +65 -0
  9. package/dist/src/AtlantisThemeContext/buildThemedStyles.test.js +43 -0
  10. package/dist/src/AutoLink/AutoLink.test.js +133 -0
  11. package/dist/src/AutoLink/components/Link/Link.test.js +18 -0
  12. package/dist/src/Banner/Banner.test.js +98 -0
  13. package/dist/src/BottomSheet/BottomSheet.test.js +105 -0
  14. package/dist/src/BottomSheet/components/BottomSheetOption/BottomSheetOption.test.js +19 -0
  15. package/dist/src/BottomSheet/hooks/useBottomSheetBackHandler.test.js +68 -0
  16. package/dist/src/Button/Button.test.js +228 -0
  17. package/dist/src/Button/components/InternalButtonLoading/InternalButtonLoading.test.js +25 -0
  18. package/dist/src/ButtonGroup/ButtonGroup.test.js +153 -0
  19. package/dist/src/Card/Card.test.js +80 -0
  20. package/dist/src/Card/components/InternalCardHeader.test.js +18 -0
  21. package/dist/src/Checkbox/Checkbox.test.js +135 -0
  22. package/dist/src/Checkbox/CheckboxGroup.test.js +197 -0
  23. package/dist/src/Checkbox/CheckboxGroupReducer.test.js +25 -0
  24. package/dist/src/Chip/Chip.test.js +69 -0
  25. package/dist/src/Content/Content.test.js +250 -0
  26. package/dist/src/ContentOverlay/ContentOverlay.test.js +297 -0
  27. package/dist/src/ContentOverlay/computeContentOverlayBehavior.test.js +197 -0
  28. package/dist/src/ContentOverlay/hooks/useBottomSheetModalBackHandler.test.js +62 -0
  29. package/dist/src/ContentOverlay/hooks/useKeyboardVisibility.test.js +41 -0
  30. package/dist/src/ContentOverlay/hooks/useViewLayoutHeight.test.js +62 -0
  31. package/dist/src/Disclosure/Disclosure.test.js +64 -0
  32. package/dist/src/Divider/Divider.test.js +65 -0
  33. package/dist/src/EmptyState/EmptyState.test.js +82 -0
  34. package/dist/src/ErrorMessageWrapper/ErrorMessageWrapper.test.js +29 -0
  35. package/dist/src/Flex/Flex.test.js +104 -0
  36. package/dist/src/Form/Form.test.js +393 -0
  37. package/dist/src/Form/components/FormErrorBanner/FormErrorBanner.test.js +41 -0
  38. package/dist/src/Form/components/FormMessage/FormMessage.test.js +73 -0
  39. package/dist/src/Form/components/FormMessageBanner/FormMessageBanner.test.js +30 -0
  40. package/dist/src/Form/components/FormSaveButton/FormSaveButton.test.js +82 -0
  41. package/dist/src/Form/context/AtlantisFormContext.test.js +28 -0
  42. package/dist/src/Form/hooks/useScrollToError/useScrollToError.test.js +89 -0
  43. package/dist/src/FormField/FormField.test.js +81 -0
  44. package/dist/src/FormatFile/FormatFile.test.js +212 -0
  45. package/dist/src/FormatFile/FormatFileThumbnail.test.js +192 -0
  46. package/dist/src/FormatFile/components/FormatFileBottomSheet/FormatFileBottomSheet.test.js +74 -0
  47. package/dist/src/FormatFile/components/MediaView/MediaView.test.js +202 -0
  48. package/dist/src/FormatFile/utils/parseFile.test.js +188 -0
  49. package/dist/src/Glimmer/Glimmer.test.js +61 -0
  50. package/dist/src/Heading/Heading.test.js +61 -0
  51. package/dist/src/Icon/Icon.test.js +40 -0
  52. package/dist/src/IconButton/IconButton.test.js +38 -0
  53. package/dist/src/InputCurrency/InputCurrency.test.js +106 -0
  54. package/dist/src/InputDate/InputDate.test.js +184 -0
  55. package/dist/src/InputEmail/InputEmail.test.js +27 -0
  56. package/dist/src/InputFieldWrapper/InputFieldWrapper.test.js +279 -0
  57. package/dist/src/InputFieldWrapper/components/ClearAction/ClearAction.test.js +9 -0
  58. package/dist/src/InputFieldWrapper/components/Prefix/Prefix.test.js +130 -0
  59. package/dist/src/InputFieldWrapper/components/Suffix/Suffix.test.js +51 -0
  60. package/dist/src/InputNumber/InputNumber.test.js +220 -0
  61. package/dist/src/InputPassword/InputPassword.test.js +63 -0
  62. package/dist/src/InputPressable/InputPressable.test.js +138 -0
  63. package/dist/src/InputSearch/InputSearch.test.js +54 -0
  64. package/dist/src/InputText/InputText.test.js +652 -0
  65. package/dist/src/InputText/context/InputAccessoriesProvider.test.js +71 -0
  66. package/dist/src/InputTime/InputTime.test.js +199 -0
  67. package/dist/src/InputTime/utils/utils.test.js +32 -0
  68. package/dist/src/ProgressBar/ProgressBar.test.js +89 -0
  69. package/dist/src/Select/Select.test.js +183 -0
  70. package/dist/src/Select/components/SelectDefaultPicker/SelectDefaultPicker.test.js +51 -0
  71. package/dist/src/Select/components/SelectInternalPicker/SelectInternalPicker.test.js +72 -0
  72. package/dist/src/StatusLabel/StatusLabel.test.js +51 -0
  73. package/dist/src/Switch/Switch.test.js +60 -0
  74. package/dist/src/Switch/components/BaseSwitch/BaseSwitch.test.js +61 -0
  75. package/dist/src/Text/Text.test.js +161 -0
  76. package/dist/src/TextList/TextList.test.js +16 -0
  77. package/dist/src/ThumbnailList/ThumbnailList.test.js +72 -0
  78. package/dist/src/Toast/Toast.test.js +51 -0
  79. package/dist/src/Typography/Typography.test.js +225 -0
  80. package/dist/src/hooks/useAtlantisI18n/useAtlantisI18n.test.js +103 -0
  81. package/dist/src/utils/meta/meta.test.js +83 -0
  82. package/dist/tsconfig.build.json +5 -1
  83. package/dist/tsconfig.build.tsbuildinfo +1 -1
  84. package/dist/tsconfig.eslint.json +14 -0
  85. package/dist/tsconfig.json +3 -4
  86. package/dist/types/src/ActionItem/ActionItem.test.d.ts +1 -0
  87. package/dist/types/src/ActionItem/ActionItemGroup.test.d.ts +1 -0
  88. package/dist/types/src/ActionItem/components/ActionItemContainer.test.d.ts +1 -0
  89. package/dist/types/src/ActionLabel/ActionLabel.test.d.ts +1 -0
  90. package/dist/types/src/ActivityIndicator/ActivityIndicator.test.d.ts +1 -0
  91. package/dist/types/src/AtlantisContext/AtlantisContext.test.d.ts +1 -0
  92. package/dist/types/src/AtlantisThemeContext/AtlantisThemeContext.test.d.ts +1 -0
  93. package/dist/types/src/AtlantisThemeContext/buildThemedStyles.test.d.ts +1 -0
  94. package/dist/types/src/AutoLink/AutoLink.test.d.ts +1 -0
  95. package/dist/types/src/AutoLink/components/Link/Link.test.d.ts +1 -0
  96. package/dist/types/src/Banner/Banner.test.d.ts +1 -0
  97. package/dist/types/src/BottomSheet/BottomSheet.test.d.ts +1 -0
  98. package/dist/types/src/BottomSheet/components/BottomSheetOption/BottomSheetOption.test.d.ts +1 -0
  99. package/dist/types/src/BottomSheet/hooks/useBottomSheetBackHandler.test.d.ts +1 -0
  100. package/dist/types/src/Button/Button.test.d.ts +1 -0
  101. package/dist/types/src/Button/components/InternalButtonLoading/InternalButtonLoading.test.d.ts +1 -0
  102. package/dist/types/src/ButtonGroup/ButtonGroup.test.d.ts +1 -0
  103. package/dist/types/src/Card/Card.test.d.ts +1 -0
  104. package/dist/types/src/Card/components/InternalCardHeader.test.d.ts +1 -0
  105. package/dist/types/src/Checkbox/Checkbox.test.d.ts +1 -0
  106. package/dist/types/src/Checkbox/CheckboxGroup.test.d.ts +1 -0
  107. package/dist/types/src/Checkbox/CheckboxGroupReducer.test.d.ts +1 -0
  108. package/dist/types/src/Chip/Chip.test.d.ts +1 -0
  109. package/dist/types/src/Content/Content.test.d.ts +1 -0
  110. package/dist/types/src/ContentOverlay/BottomSheetKeyboardAwareScrollView.d.ts +2 -1
  111. package/dist/types/src/ContentOverlay/ContentOverlay.test.d.ts +1 -0
  112. package/dist/types/src/ContentOverlay/computeContentOverlayBehavior.test.d.ts +1 -0
  113. package/dist/types/src/ContentOverlay/hooks/useBottomSheetModalBackHandler.test.d.ts +1 -0
  114. package/dist/types/src/ContentOverlay/hooks/useKeyboardVisibility.test.d.ts +1 -0
  115. package/dist/types/src/ContentOverlay/hooks/useViewLayoutHeight.test.d.ts +1 -0
  116. package/dist/types/src/Disclosure/Disclosure.test.d.ts +1 -0
  117. package/dist/types/src/Divider/Divider.test.d.ts +1 -0
  118. package/dist/types/src/EmptyState/EmptyState.test.d.ts +1 -0
  119. package/dist/types/src/ErrorMessageWrapper/ErrorMessageWrapper.test.d.ts +1 -0
  120. package/dist/types/src/Flex/Flex.test.d.ts +1 -0
  121. package/dist/types/src/Form/Form.test.d.ts +1 -0
  122. package/dist/types/src/Form/components/FormErrorBanner/FormErrorBanner.test.d.ts +1 -0
  123. package/dist/types/src/Form/components/FormMessage/FormMessage.test.d.ts +1 -0
  124. package/dist/types/src/Form/components/FormMessageBanner/FormMessageBanner.test.d.ts +1 -0
  125. package/dist/types/src/Form/components/FormSaveButton/FormSaveButton.test.d.ts +1 -0
  126. package/dist/types/src/Form/context/AtlantisFormContext.test.d.ts +1 -0
  127. package/dist/types/src/Form/hooks/useScrollToError/useScrollToError.test.d.ts +1 -0
  128. package/dist/types/src/FormField/FormField.test.d.ts +1 -0
  129. package/dist/types/src/FormatFile/FormatFile.test.d.ts +1 -0
  130. package/dist/types/src/FormatFile/FormatFileThumbnail.test.d.ts +1 -0
  131. package/dist/types/src/FormatFile/components/FormatFileBottomSheet/FormatFileBottomSheet.test.d.ts +1 -0
  132. package/dist/types/src/FormatFile/components/MediaView/MediaView.test.d.ts +1 -0
  133. package/dist/types/src/FormatFile/utils/parseFile.test.d.ts +1 -0
  134. package/dist/types/src/Glimmer/Glimmer.test.d.ts +1 -0
  135. package/dist/types/src/Heading/Heading.test.d.ts +1 -0
  136. package/dist/types/src/Icon/Icon.test.d.ts +1 -0
  137. package/dist/types/src/IconButton/IconButton.test.d.ts +1 -0
  138. package/dist/types/src/InputCurrency/InputCurrency.test.d.ts +1 -0
  139. package/dist/types/src/InputDate/InputDate.test.d.ts +1 -0
  140. package/dist/types/src/InputEmail/InputEmail.test.d.ts +1 -0
  141. package/dist/types/src/InputFieldWrapper/InputFieldWrapper.test.d.ts +1 -0
  142. package/dist/types/src/InputFieldWrapper/components/ClearAction/ClearAction.test.d.ts +1 -0
  143. package/dist/types/src/InputFieldWrapper/components/Prefix/Prefix.test.d.ts +1 -0
  144. package/dist/types/src/InputFieldWrapper/components/Suffix/Suffix.test.d.ts +1 -0
  145. package/dist/types/src/InputNumber/InputNumber.test.d.ts +1 -0
  146. package/dist/types/src/InputPassword/InputPassword.test.d.ts +1 -0
  147. package/dist/types/src/InputPressable/InputPressable.test.d.ts +1 -0
  148. package/dist/types/src/InputSearch/InputSearch.test.d.ts +1 -0
  149. package/dist/types/src/InputText/InputText.test.d.ts +1 -0
  150. package/dist/types/src/InputText/context/InputAccessoriesProvider.test.d.ts +1 -0
  151. package/dist/types/src/InputTime/InputTime.test.d.ts +1 -0
  152. package/dist/types/src/InputTime/utils/utils.test.d.ts +1 -0
  153. package/dist/types/src/ProgressBar/ProgressBar.test.d.ts +1 -0
  154. package/dist/types/src/Select/Select.test.d.ts +1 -0
  155. package/dist/types/src/Select/components/SelectDefaultPicker/SelectDefaultPicker.test.d.ts +1 -0
  156. package/dist/types/src/Select/components/SelectInternalPicker/SelectInternalPicker.test.d.ts +1 -0
  157. package/dist/types/src/StatusLabel/StatusLabel.test.d.ts +1 -0
  158. package/dist/types/src/Switch/Switch.test.d.ts +1 -0
  159. package/dist/types/src/Switch/components/BaseSwitch/BaseSwitch.test.d.ts +1 -0
  160. package/dist/types/src/Text/Text.test.d.ts +1 -0
  161. package/dist/types/src/TextList/TextList.test.d.ts +1 -0
  162. package/dist/types/src/ThumbnailList/ThumbnailList.test.d.ts +1 -0
  163. package/dist/types/src/Toast/Toast.test.d.ts +1 -0
  164. package/dist/types/src/Typography/Typography.test.d.ts +1 -0
  165. package/dist/types/src/hooks/useAtlantisI18n/useAtlantisI18n.test.d.ts +1 -0
  166. package/dist/types/src/utils/meta/meta.test.d.ts +1 -0
  167. package/package.json +19 -11
  168. package/src/Button/Button.test.tsx +6 -2
  169. package/src/ContentOverlay/hooks/useViewLayoutHeight.test.ts +3 -3
  170. package/src/Divider/Divider.stories.tsx +1 -1
  171. package/src/Flex/Flex.test.tsx +1 -1
  172. package/src/Form/Form.test.tsx +3 -1
  173. package/src/FormField/FormField.test.tsx +5 -1
  174. package/src/Heading/__snapshots__/Heading.test.tsx.snap +1 -1
  175. package/src/InputDate/InputDate.test.tsx +7 -1
  176. package/src/InputText/InputText.test.tsx +2 -1
  177. package/src/InputTime/InputTime.test.tsx +7 -1
  178. package/src/Select/Select.test.tsx +1 -1
  179. package/src/StatusLabel/__snapshots__/StatusLabel.test.tsx.snap +8 -8
  180. package/src/Text/__snapshots__/Text.test.tsx.snap +2 -2
  181. package/src/ThumbnailList/__snapshots__/ThumbnailList.test.tsx.snap +1 -1
  182. package/src/Typography/__snapshots__/Typography.test.tsx.snap +4 -4
@@ -0,0 +1,71 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { fireEvent, render } from "@testing-library/react-native";
11
+ import React, { useContext, useEffect } from "react";
12
+ import { Keyboard, Platform } from "react-native";
13
+ import { InputAccessoriesContext } from "./InputAccessoriesContext";
14
+ import { InputAccessoriesProvider } from "./InputAccessoriesProvider";
15
+ import { InputText } from "../InputText";
16
+ const mockUseFormController = jest.fn();
17
+ jest.mock("../../hooks", () => {
18
+ return {
19
+ useFormController: (...args) => mockUseFormController(...args),
20
+ };
21
+ });
22
+ const actualUseFormController = jest.requireActual("../../hooks").useFormController;
23
+ describe("InputAccessories", () => {
24
+ beforeEach(() => {
25
+ Platform.OS = "ios";
26
+ });
27
+ afterEach(() => {
28
+ // restore the spy created with spyOn
29
+ jest.resetAllMocks();
30
+ });
31
+ const inputOneName = "testInput1";
32
+ const inputTwoName = "testInput2";
33
+ const mockInputOneFocus = jest.fn();
34
+ const mockInputTwoFocus = jest.fn();
35
+ function InputWrapper({ focusedInput }) {
36
+ const { register, setFocusedInput, unregister } = useContext(InputAccessoriesContext);
37
+ useEffect(() => {
38
+ register(inputOneName, () => mockInputOneFocus());
39
+ register(inputTwoName, () => mockInputTwoFocus());
40
+ setFocusedInput(focusedInput);
41
+ return () => {
42
+ unregister(inputOneName);
43
+ unregister(inputTwoName);
44
+ setFocusedInput("");
45
+ };
46
+ }, [register, setFocusedInput, unregister, focusedInput]);
47
+ return (React.createElement(React.Fragment, null,
48
+ React.createElement(InputText, { testID: inputOneName, name: inputOneName, onFocus: mockInputOneFocus, value: "" }),
49
+ React.createElement(InputText, { testID: inputTwoName, onFocus: mockInputTwoFocus, value: "" })));
50
+ }
51
+ function SetupInputAccessoriesTest(focusedInput) {
52
+ mockUseFormController.mockImplementation(({ name, value, validations }) => {
53
+ const { field, error } = actualUseFormController({
54
+ name: name || inputTwoName,
55
+ value,
56
+ validations,
57
+ });
58
+ return { field, error };
59
+ });
60
+ return render(React.createElement(InputWrapper, { focusedInput: focusedInput }), {
61
+ wrapper: InputAccessoriesProvider,
62
+ });
63
+ }
64
+ it("pressing done dismisses the keyboard", () => __awaiter(void 0, void 0, void 0, function* () {
65
+ const keyboardDismissSpy = jest.spyOn(Keyboard, "dismiss");
66
+ const { getByTestId } = SetupInputAccessoriesTest(inputOneName);
67
+ const doneButton = getByTestId("ATL-InputAccessory-Done");
68
+ yield fireEvent.press(doneButton);
69
+ expect(keyboardDismissSpy).toHaveBeenCalled();
70
+ }));
71
+ });
@@ -0,0 +1,199 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import React from "react";
11
+ import { fireEvent, render, waitFor } from "@testing-library/react-native";
12
+ import { FormProvider, useForm } from "react-hook-form";
13
+ import { Keyboard } from "react-native";
14
+ import { InputTime } from "./InputTime";
15
+ import * as atlantisContext from "../AtlantisContext/AtlantisContext";
16
+ import { Button } from "../Button";
17
+ const keyboardDismissSpy = jest.spyOn(Keyboard, "dismiss");
18
+ afterEach(() => {
19
+ jest.spyOn(atlantisContext, "useAtlantisContext").mockRestore();
20
+ });
21
+ describe("Visuals", () => {
22
+ const placeholder = "Start time";
23
+ const expectedTime = "11:00 AM";
24
+ const value = new Date(2022, 2, 2, 11, 0);
25
+ const handleChange = jest.fn();
26
+ const setup = (showIcon = true) => render(React.createElement(InputTime, { placeholder: placeholder, value: value, onChange: handleChange, showIcon: showIcon }));
27
+ it("should show a timer prefix icon", () => {
28
+ const screen = setup();
29
+ const timerIcon = screen.getByTestId("timer");
30
+ expect(timerIcon).toBeDefined();
31
+ expect(timerIcon.type).toBe("RNSVGSvgView");
32
+ });
33
+ it("should not show a timer icon if showIcon is false", () => {
34
+ const screen = setup(false);
35
+ const timerIcon = screen.queryByTestId("timer");
36
+ expect(timerIcon).toBeNull();
37
+ });
38
+ it("should show a formatted time", () => {
39
+ const screen = setup();
40
+ expect(screen.getByText(expectedTime, { includeHiddenElements: true })).toBeDefined();
41
+ });
42
+ it("should be clearable when there's a value", () => {
43
+ const screen = setup();
44
+ const clearAction = screen.getByLabelText("Clear input");
45
+ expect(clearAction).toBeDefined();
46
+ fireEvent.press(clearAction);
47
+ expect(handleChange).toHaveBeenCalledWith(undefined);
48
+ });
49
+ });
50
+ describe("String value", () => {
51
+ const handleChange = jest.fn();
52
+ it("should show a formatted time", () => {
53
+ const expectedTime = "11:00 AM";
54
+ const value = new Date(2022, 2, 2, 11, 0).toISOString();
55
+ const screen = render(React.createElement(InputTime, { value: value, onChange: handleChange }));
56
+ expect(screen.getByText(expectedTime, { includeHiddenElements: true })).toBeDefined();
57
+ });
58
+ });
59
+ describe("With emptyValueLabel", () => {
60
+ const handleChange = jest.fn();
61
+ it("should show the emptyValueLabel when there's no value", () => {
62
+ const label = "Unscheduled";
63
+ const screen = render(React.createElement(InputTime, { name: "test", emptyValueLabel: label }));
64
+ expect(screen.getByText(label, { includeHiddenElements: true })).toBeDefined();
65
+ expect(screen.queryByLabelText("Clear input", { includeHiddenElements: true })).toBeNull();
66
+ });
67
+ it("should not show the emptyValueLabel when there's a value", () => {
68
+ const label = "Unscheduled";
69
+ const screen = render(React.createElement(InputTime, { emptyValueLabel: label, value: new Date(), onChange: handleChange }));
70
+ expect(screen.queryByText(label)).toBeNull();
71
+ expect(screen.getByLabelText("Clear input")).toBeDefined();
72
+ });
73
+ });
74
+ // eslint-disable-next-line max-statements
75
+ describe("Time picker", () => {
76
+ const placeholder = "Tap me";
77
+ const handleChange = jest.fn();
78
+ const getType = jest.fn().mockReturnValue(undefined);
79
+ function renderTimePicker(value) {
80
+ const screen = render(React.createElement(InputTime, { placeholder: placeholder, onChange: handleChange, value: value, type: getType() }));
81
+ fireEvent.press(screen.getByLabelText(placeholder));
82
+ expect(screen.getByTestId("inputTime-Picker")).toBeDefined();
83
+ return screen;
84
+ }
85
+ it("should not show a time picker", () => {
86
+ const screen = render(React.createElement(InputTime, { name: "test" }));
87
+ expect(screen.queryByTestId("inputTime-Picker")).toBeNull();
88
+ });
89
+ it("should fire the onChange with the current value after canceling a time selection", () => {
90
+ const value = new Date();
91
+ const screen = renderTimePicker(value);
92
+ fireEvent.press(screen.getByLabelText("Cancel"));
93
+ expect(handleChange).toHaveBeenCalledWith(value);
94
+ });
95
+ it("should fire the onChange after confirming a time selection", () => {
96
+ const screen = renderTimePicker();
97
+ fireEvent.press(screen.getByLabelText("Confirm"));
98
+ expect(handleChange).toHaveBeenCalledWith(expect.any(Date));
99
+ });
100
+ it("should dismiss the keyboard when the time picker is opened", () => {
101
+ renderTimePicker();
102
+ expect(keyboardDismissSpy).toHaveBeenCalled();
103
+ });
104
+ it("should be a time picker", () => {
105
+ const screen = renderTimePicker();
106
+ expect(screen.getByTestId("inputTime-Picker").props.mode).toBe("time");
107
+ });
108
+ describe("Locale", () => {
109
+ it("should be set to 12 hours", () => {
110
+ const screen = renderTimePicker();
111
+ expect(screen.getByTestId("inputTime-Picker").props.locale).toBe("en_US");
112
+ });
113
+ it("should be set to 24 hours", () => {
114
+ jest.spyOn(atlantisContext, "useAtlantisContext").mockReturnValue(Object.assign(Object.assign({}, atlantisContext.atlantisContextDefaultValues), { timeZone: "UTC", timeFormat: "HH:mm" }));
115
+ const screen = renderTimePicker();
116
+ expect(screen.getByTestId("inputTime-Picker").props.locale).toBe("en_GB");
117
+ });
118
+ });
119
+ it("should set the minute interval to 5 by default", () => {
120
+ const screen = renderTimePicker();
121
+ expect(screen.getByTestId("inputTime-Picker").props.minuteInterval).toBe(5);
122
+ });
123
+ it("should set the minute interval to 5 when the type is scheduling", () => {
124
+ getType.mockReturnValueOnce("scheduling");
125
+ const screen = renderTimePicker();
126
+ expect(screen.getByTestId("inputTime-Picker").props.minuteInterval).toBe(5);
127
+ });
128
+ it("should set the minute interval to 1 when the type is granular", () => {
129
+ getType.mockReturnValueOnce("granular");
130
+ const screen = renderTimePicker();
131
+ expect(screen.getByTestId("inputTime-Picker").props.minuteInterval).toBe(1);
132
+ });
133
+ });
134
+ const mockOnSubmit = jest.fn();
135
+ const saveButtonText = "Submit";
136
+ const requiredError = "This is required";
137
+ function SimpleFormWithProvider({ children, defaultValues, }) {
138
+ const formMethods = useForm({
139
+ reValidateMode: "onChange",
140
+ defaultValues,
141
+ mode: "onTouched",
142
+ });
143
+ return (React.createElement(FormProvider, Object.assign({}, formMethods),
144
+ children,
145
+ React.createElement(Button, { onPress: formMethods.handleSubmit(values => mockOnSubmit(values)), label: saveButtonText, accessibilityLabel: saveButtonText })));
146
+ }
147
+ describe("Form controlled", () => {
148
+ const pickerName = "timePicker";
149
+ const expectedTime = "11:00 AM";
150
+ const value = new Date(2022, 2, 2, 11, 0);
151
+ const handleChange = jest.fn();
152
+ const setup = () => render(React.createElement(SimpleFormWithProvider, { defaultValues: { [pickerName]: value } },
153
+ React.createElement(InputTime, { name: pickerName, onChange: handleChange, validations: { required: requiredError } })));
154
+ it("should show the initial value", () => __awaiter(void 0, void 0, void 0, function* () {
155
+ const screen = setup();
156
+ expect(screen.getByText(expectedTime, { includeHiddenElements: true })).toBeDefined();
157
+ }));
158
+ it("should update the value", () => __awaiter(void 0, void 0, void 0, function* () {
159
+ const screen = setup();
160
+ fireEvent.press(screen.getByText(expectedTime, { includeHiddenElements: true }));
161
+ const expectedNewTime = "10:00 AM";
162
+ fireEvent(screen.getByTestId("inputTime-Picker"), "onConfirm", new Date(2022, 2, 2, 10, 0));
163
+ expect(screen.getByText(expectedNewTime, { includeHiddenElements: true })).toBeDefined();
164
+ }));
165
+ it("should show the required message", () => __awaiter(void 0, void 0, void 0, function* () {
166
+ const screen = setup();
167
+ const clearAction = screen.getByLabelText("Clear input");
168
+ expect(clearAction).toBeDefined();
169
+ fireEvent.press(clearAction);
170
+ yield waitFor(() => {
171
+ expect(screen.getByText(requiredError, { includeHiddenElements: true })).toBeDefined();
172
+ });
173
+ }));
174
+ it("should clear the input with null value when it is in a form", () => __awaiter(void 0, void 0, void 0, function* () {
175
+ const screen = setup();
176
+ const clearAction = screen.getByLabelText("Clear input");
177
+ expect(clearAction).toBeDefined();
178
+ fireEvent.press(clearAction);
179
+ expect(handleChange).toHaveBeenCalledWith(null);
180
+ }));
181
+ });
182
+ describe("Timezone conversion", () => {
183
+ const placeholder = "Start time";
184
+ const value = new Date(2022, 2, 2, 11, 0);
185
+ const handleChange = jest.fn();
186
+ const setup = () => render(React.createElement(InputTime, { placeholder: placeholder, value: value, onChange: handleChange }));
187
+ it("should display the time in the account timezone", () => __awaiter(void 0, void 0, void 0, function* () {
188
+ jest.spyOn(atlantisContext, "useAtlantisContext").mockReturnValue(Object.assign(Object.assign({}, atlantisContext.atlantisContextDefaultValues), { timeZone: "America/Los_Angeles" }));
189
+ const screen = setup();
190
+ const expectedTimezonedTime = "3:00 AM";
191
+ expect(screen.getByText(expectedTimezonedTime, { includeHiddenElements: true })).toBeDefined();
192
+ }));
193
+ it("should have the correct offset on the time picker", () => __awaiter(void 0, void 0, void 0, function* () {
194
+ jest.spyOn(atlantisContext, "useAtlantisContext").mockReturnValue(Object.assign(Object.assign({}, atlantisContext.atlantisContextDefaultValues), { timeZone: "America/Los_Angeles" }));
195
+ const screen = setup();
196
+ fireEvent.press(screen.getByLabelText(placeholder));
197
+ expect(screen.getByTestId("inputTime-Picker").props.timeZoneOffsetInMinutes).toBe(-8 * 60);
198
+ }));
199
+ });
@@ -0,0 +1,32 @@
1
+ import { set } from "date-fns";
2
+ import { getTimeZoneOffsetInMinutes, roundUpToNearestMinutes } from ".";
3
+ describe("roundUpToNearestMinutes", () => {
4
+ it.each([
5
+ [15, { hours: 1, minutes: 28, expectedMinutes: 30 }],
6
+ [15, { hours: 2, minutes: 3, expectedMinutes: 15 }],
7
+ [30, { hours: 11, minutes: 2, expectedMinutes: 30 }],
8
+ [30, { hours: 11, minutes: 32, expectedHours: 12, expectedMinutes: 0 }],
9
+ [60, { hours: 11, minutes: 59, expectedHours: 12, expectedMinutes: 0 }],
10
+ [60, { hours: 10, minutes: 1, expectedHours: 11, expectedMinutes: 0 }],
11
+ ])("should round up the time to the nearest %s mins", (increment, { hours, minutes, expectedMinutes, expectedHours }) => {
12
+ const timeToUpdate = set(new Date(2022, 5, 27), { hours, minutes });
13
+ const time = roundUpToNearestMinutes(timeToUpdate, increment);
14
+ expect(time.getHours()).toBe(expectedHours || hours);
15
+ expect(time.getMinutes()).toBe(expectedMinutes);
16
+ });
17
+ });
18
+ describe("getTimeZoneOffsetInMinutes", () => {
19
+ const DSTDate = new Date(2022, 6, 5);
20
+ const nonDSTDate = new Date(2022, 10, 7);
21
+ it.each([
22
+ ["America/Edmonton", -6, DSTDate],
23
+ ["America/Edmonton", -7, nonDSTDate],
24
+ ["Africa/Johannesburg", 2, DSTDate],
25
+ ["America/Los_Angeles", -7, DSTDate],
26
+ ["Asia/Manila", 8, DSTDate],
27
+ ["Asia/Manila", 8, nonDSTDate],
28
+ ])("should convert %s to the correct timezone offset for %s", (timezone, expectedOffset, date) => {
29
+ const timeZoneOffset = getTimeZoneOffsetInMinutes(timezone, date);
30
+ expect(timeZoneOffset).toBe(expectedOffset * 60);
31
+ });
32
+ });
@@ -0,0 +1,89 @@
1
+ import React from "react";
2
+ import { render, screen } from "@testing-library/react-native";
3
+ import { ProgressBar } from ".";
4
+ const defaultSetupProps = {
5
+ total: 0,
6
+ current: 0,
7
+ inProgress: 0,
8
+ loading: false,
9
+ };
10
+ function renderProgressBarComponent({ total, current, inProgress, }) {
11
+ return render(React.createElement(ProgressBar, { total: total, current: current, inProgress: inProgress }));
12
+ }
13
+ it("renders blue inProgress bar when 1 or more jobs is in progress", () => {
14
+ const bar = renderProgressBarComponent(Object.assign(Object.assign({}, defaultSetupProps), { inProgress: 1 })).toJSON();
15
+ expect(bar).toMatchSnapshot();
16
+ });
17
+ it("renders green CompletedProgress bar when 1 or more jobs is completed", () => {
18
+ const current = 1;
19
+ const bar = renderProgressBarComponent(Object.assign(Object.assign({}, defaultSetupProps), { current: current, total: 2 }));
20
+ expect(bar).toMatchSnapshot();
21
+ expect(bar.getByLabelText("1 of 2 complete")).toBeDefined();
22
+ });
23
+ describe("with stepped variation", () => {
24
+ beforeEach(() => {
25
+ render(React.createElement(ProgressBar, { total: 4, current: 2, inProgress: 1, variation: "stepped" }));
26
+ });
27
+ it("renders the correct number of completed steps", () => {
28
+ const completedSteps = screen.getAllByTestId("progress-step-completed");
29
+ expect(completedSteps).toHaveLength(2);
30
+ });
31
+ it("renders the correct number of incomplete steps", () => {
32
+ const inCompleteSteps = screen.getAllByTestId("progress-step-incomplete");
33
+ expect(inCompleteSteps).toHaveLength(1);
34
+ });
35
+ it("renders the correct number of inProgress steps", () => {
36
+ const stepElements = screen.getAllByTestId("progress-step-in-progress");
37
+ expect(stepElements).toHaveLength(1);
38
+ });
39
+ });
40
+ describe("ProgressBar (native) - UNSAFE_style", () => {
41
+ it("applies UNSAFE_style.container to the outer wrapper", () => {
42
+ const containerStyle = { padding: 12, backgroundColor: "papayawhip" };
43
+ render(React.createElement(ProgressBar, { total: 100, current: 40, UNSAFE_style: { container: containerStyle } }));
44
+ const progressBar = screen.getByRole("progressbar");
45
+ expect(progressBar.props.style).toEqual(expect.objectContaining(containerStyle));
46
+ });
47
+ it("applies UNSAFE_style.progressBarContainer and track in progress variation", () => {
48
+ const progressBarContainer = { height: 22, borderRadius: 10 };
49
+ const track = { backgroundColor: "#eee" };
50
+ render(React.createElement(ProgressBar, { total: 100, current: 30, UNSAFE_style: {
51
+ progressBarContainer,
52
+ track,
53
+ } }));
54
+ const progressContainer = screen.getByTestId("progressbar-container");
55
+ expect(progressContainer.props.style).toEqual(expect.arrayContaining([expect.objectContaining(progressBarContainer)]));
56
+ const trackView = screen.getByTestId("progressbar-track");
57
+ expect(trackView.props.style).toEqual(expect.arrayContaining([expect.objectContaining(track)]));
58
+ });
59
+ it("applies UNSAFE_style.inProgressFill and fill in progress variation", () => {
60
+ const inProgressFill = { backgroundColor: "#f59e0b" };
61
+ const fill = { backgroundColor: "#10b981" };
62
+ render(React.createElement(ProgressBar, { total: 100, current: 30, inProgress: 10, UNSAFE_style: {
63
+ inProgressFill,
64
+ fill,
65
+ } }));
66
+ const inProgressView = screen.getByTestId("progressbar-inprogress");
67
+ const fillView = screen.getByTestId("progressbar-fill");
68
+ expect(inProgressView.props.style).toEqual(expect.arrayContaining([expect.objectContaining(inProgressFill)]));
69
+ expect(fillView.props.style).toEqual(expect.arrayContaining([expect.objectContaining(fill)]));
70
+ });
71
+ it("applies UNSAFE_style.progressBarContainer and step in stepped variation", () => {
72
+ const progressBarContainer = { height: 12 };
73
+ const step = { backgroundColor: "#d1d5db" };
74
+ render(React.createElement(ProgressBar, { variation: "stepped", total: 4, current: 2, inProgress: 1, UNSAFE_style: { progressBarContainer, step } }));
75
+ const steppedContainer = screen.getByTestId("progressbar-container");
76
+ expect(steppedContainer.props.style).toEqual(expect.arrayContaining([expect.objectContaining(progressBarContainer)]));
77
+ // Steps are rendered with testIDs depending on state; collect all steps by known IDs
78
+ const stepNodes = [
79
+ ...screen.getAllByTestId("progress-step-completed"),
80
+ ...screen.getAllByTestId("progress-step-in-progress"),
81
+ ...screen.getAllByTestId("progress-step-incomplete"),
82
+ ];
83
+ // At least one step should exist and contain the custom style
84
+ expect(stepNodes.length).toBeGreaterThan(0);
85
+ stepNodes.forEach(node => {
86
+ expect(node.props.style).toEqual(expect.arrayContaining([expect.objectContaining(step)]));
87
+ });
88
+ });
89
+ });
@@ -0,0 +1,183 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import React from "react";
11
+ import { fireEvent, render } from "@testing-library/react-native";
12
+ import { tokens } from "@jobber/design";
13
+ import { AccessibilityInfo } from "react-native";
14
+ import { Option, Select } from ".";
15
+ import { SelectInternalPicker } from "./components/SelectInternalPicker";
16
+ const A11yInfoSpy = jest.spyOn(AccessibilityInfo, "isScreenReaderEnabled");
17
+ const onChange = jest.fn();
18
+ beforeEach(() => {
19
+ A11yInfoSpy.mockImplementation(() => Promise.resolve(false));
20
+ });
21
+ afterEach(() => {
22
+ jest.resetAllMocks();
23
+ });
24
+ const defaultPlaceholder = "Select an option";
25
+ describe("Select", () => {
26
+ it("renders a Select", () => {
27
+ const component = render(React.createElement(Select, { onChange: onChange },
28
+ React.createElement(Option, { value: "one" }, "one"),
29
+ React.createElement(Option, { value: "2" }, "2")));
30
+ expect(component.getByTestId("arrowDown")).toBeDefined();
31
+ expect(component.getByText(defaultPlaceholder, {
32
+ includeHiddenElements: true,
33
+ })).toBeDefined();
34
+ });
35
+ it("renders a Select with a label", () => {
36
+ const label = "Press me";
37
+ const { getByText } = render(React.createElement(Select, { onChange: onChange, label: label },
38
+ React.createElement(Option, { value: "1" }, "1"),
39
+ React.createElement(Option, { value: "2" }, "2")));
40
+ expect(getByText(label, { includeHiddenElements: true })).toBeDefined();
41
+ });
42
+ it("renders a Select with a placeholder", () => {
43
+ const placeholder = "I am a placeholder";
44
+ const { getByText } = render(React.createElement(Select, { onChange: onChange, placeholder: placeholder },
45
+ React.createElement(Option, { value: "1" }, "1"),
46
+ React.createElement(Option, { value: "2" }, "2")));
47
+ expect(getByText(placeholder, { includeHiddenElements: true })).toBeDefined();
48
+ });
49
+ it("renders a Select with assistive text", () => {
50
+ const assistiveText = "You need to pick something";
51
+ const { getByText } = render(React.createElement(Select, { onChange: onChange, assistiveText: assistiveText },
52
+ React.createElement(Option, { value: "1" }, "1"),
53
+ React.createElement(Option, { value: "2" }, "2")));
54
+ expect(getByText(assistiveText, { includeHiddenElements: true })).toBeDefined();
55
+ });
56
+ it("renders a disabled Select", () => {
57
+ const labelText = "labelText";
58
+ const { getByText } = render(React.createElement(Select, { label: labelText, onChange: onChange, disabled: true },
59
+ React.createElement(Option, { value: "1" }, "1"),
60
+ React.createElement(Option, { value: "2" }, "2")));
61
+ expect(getByText(labelText, { includeHiddenElements: true }).props.style).toContainEqual({
62
+ color: tokens["color-disabled"],
63
+ });
64
+ });
65
+ it("renders a Select with a value provided", () => {
66
+ const expectedValue = "That should be me";
67
+ const { getByText } = render(React.createElement(Select, { onChange: onChange, value: "2" },
68
+ React.createElement(Option, { value: "1" }, "1"),
69
+ React.createElement(Option, { value: "2" }, expectedValue)));
70
+ expect(getByText(expectedValue, { includeHiddenElements: true })).toBeDefined();
71
+ });
72
+ it("renders a Select with a defaultValue provided", () => {
73
+ const expectedValue = "It's the 3rd value";
74
+ const { getByText } = render(React.createElement(Select, { onChange: onChange, defaultValue: "3" },
75
+ React.createElement(Option, { value: "1" }, "1"),
76
+ React.createElement(Option, { value: "2" }, "2"),
77
+ React.createElement(Option, { value: "3" }, expectedValue)));
78
+ expect(getByText(expectedValue, { includeHiddenElements: true })).toBeDefined();
79
+ });
80
+ it("renders a Select with custom testID", () => {
81
+ const testID = "testID";
82
+ const { getByTestId } = render(React.createElement(Select, { onChange: onChange, testID: testID },
83
+ React.createElement(Option, { value: "1" }, "1"),
84
+ React.createElement(Option, { value: "2" }, "2")));
85
+ expect(getByTestId(`ATL-${testID}-Select`)).toBeDefined();
86
+ });
87
+ it("renders an accessibilityLabel if provided", () => {
88
+ const { getByLabelText } = render(React.createElement(Select, { onChange: onChange, label: "label", accessibilityLabel: "accessibilityLabel" },
89
+ React.createElement(Option, { value: "1" }, "1"),
90
+ React.createElement(Option, { value: "2" }, "2")));
91
+ expect(getByLabelText("accessibilityLabel")).toBeTruthy();
92
+ });
93
+ it("fires the onChange callback", () => {
94
+ const { getByTestId } = render(React.createElement(Select, { onChange: onChange, value: "2" },
95
+ React.createElement(Option, { value: "1" }, "1"),
96
+ React.createElement(Option, { value: "2" }, "2")));
97
+ const select = getByTestId("ATL-Select").findByType(SelectInternalPicker);
98
+ expect(select).toBeTruthy();
99
+ fireEvent(select, "onChange", "1");
100
+ expect(onChange).toHaveBeenCalledWith("1");
101
+ });
102
+ });
103
+ describe("when Select is invalid", () => {
104
+ const labelText = "labelText";
105
+ it("renders an invalid Select", () => {
106
+ const { getByText } = render(React.createElement(Select, { onChange: onChange, invalid: true, label: labelText },
107
+ React.createElement(Option, { value: "1" }, "1"),
108
+ React.createElement(Option, { value: "2" }, "2")));
109
+ expect(getByText(labelText, { includeHiddenElements: true }).props.style).toContainEqual({
110
+ color: tokens["color-critical"],
111
+ });
112
+ });
113
+ it("renders an invalid Select with placeholder", () => {
114
+ const placeholder = "Place me in the holder";
115
+ const { getByText } = render(React.createElement(Select, { label: labelText, onChange: onChange, invalid: true, placeholder: placeholder },
116
+ React.createElement(Option, { value: "1" }, "1"),
117
+ React.createElement(Option, { value: "2" }, "2")));
118
+ expect(getByText(placeholder, { includeHiddenElements: true })).toBeDefined();
119
+ expect(getByText(labelText, { includeHiddenElements: true }).props.style).toContainEqual({
120
+ color: tokens["color-critical"],
121
+ });
122
+ });
123
+ });
124
+ describe("when validations are passed to the component", () => {
125
+ describe("validations fail", () => {
126
+ let tree;
127
+ const labelText = "labelText";
128
+ const errorMsg = "Too short";
129
+ beforeEach(() => {
130
+ tree = render(React.createElement(Select, { label: labelText, onChange: onChange, value: "Watermelon", validations: {
131
+ minLength: { value: 60, message: errorMsg },
132
+ } },
133
+ React.createElement(Option, { value: "Apple" }, "Apple"),
134
+ React.createElement(Option, { value: "Watermelon" }, "Watermelon")));
135
+ });
136
+ it("renders the error message when there is an error", () => __awaiter(void 0, void 0, void 0, function* () {
137
+ const select = tree
138
+ .getByTestId("ATL-Select")
139
+ .findByType(SelectInternalPicker);
140
+ fireEvent(select, "onChange", "Apple");
141
+ expect(yield tree.findByText(errorMsg, { includeHiddenElements: true })).toBeTruthy();
142
+ }));
143
+ it("shows the invalid colours", () => __awaiter(void 0, void 0, void 0, function* () {
144
+ const select = tree
145
+ .getByTestId("ATL-Select")
146
+ .findByType(SelectInternalPicker);
147
+ fireEvent(select, "onChange", "Apple");
148
+ expect((yield tree.findByText(labelText, { includeHiddenElements: true }))
149
+ .props.style).toContainEqual({
150
+ color: tokens["color-critical"],
151
+ });
152
+ }));
153
+ });
154
+ describe("validations passes", () => {
155
+ let tree;
156
+ const labelText = "labelText";
157
+ const errorMsg = "Not too short";
158
+ beforeEach(() => {
159
+ tree = render(React.createElement(Select, { label: labelText, onChange: onChange, value: "Watermelon", validations: {
160
+ minLength: { value: 4, message: errorMsg },
161
+ } },
162
+ React.createElement(Option, { value: "Apple" }, "Apple"),
163
+ React.createElement(Option, { value: "Watermelon" }, "Watermelon")));
164
+ });
165
+ it("does not render any error messages", () => {
166
+ const select = tree
167
+ .getByTestId("ATL-Select")
168
+ .findByType(SelectInternalPicker);
169
+ expect(select).toBeTruthy();
170
+ fireEvent(select, "onChange", "Apple");
171
+ expect(tree.queryByText(errorMsg)).toBeNull();
172
+ });
173
+ it("has non-critical colours", () => {
174
+ const select = tree
175
+ .getByTestId("ATL-Select")
176
+ .findByType(SelectInternalPicker);
177
+ fireEvent(select, "onChange", "Apple");
178
+ expect(tree.getByText(labelText, { includeHiddenElements: true }).props.style).toContainEqual({
179
+ color: tokens["color-text--secondary"],
180
+ });
181
+ });
182
+ });
183
+ });
@@ -0,0 +1,51 @@
1
+ import React from "react";
2
+ import { fireEvent, render } from "@testing-library/react-native";
3
+ import { AccessibilityInfo, View } from "react-native";
4
+ import { SelectDefaultPicker } from "./SelectDefaultPicker";
5
+ import { Text } from "../../../Text";
6
+ const A11yInfoSpy = jest.spyOn(AccessibilityInfo, "isScreenReaderEnabled");
7
+ const handleChange = jest.fn();
8
+ function MockPicker() {
9
+ return React.createElement("MockPicker");
10
+ }
11
+ const MockPickerItem = () => React.createElement(React.Fragment, null);
12
+ jest.mock("@react-native-picker/picker", () => ({ Picker: MockPicker }));
13
+ MockPicker.Item = MockPickerItem;
14
+ beforeEach(() => {
15
+ A11yInfoSpy.mockImplementation(() => Promise.resolve(false));
16
+ });
17
+ afterEach(() => {
18
+ jest.resetAllMocks();
19
+ });
20
+ const childText = "Click me";
21
+ function setup() {
22
+ return render(React.createElement(View, { testID: "SelectDefaultPicker" },
23
+ React.createElement(SelectDefaultPicker, { onChange: handleChange, options: [
24
+ { value: "1", label: "First option" },
25
+ { value: "2", label: "Second option" },
26
+ ] },
27
+ React.createElement(Text, null, childText))));
28
+ }
29
+ describe("SelectDefaultPicker", () => {
30
+ it("opens the picker", () => {
31
+ const screen = setup();
32
+ fireEvent.press(screen.getByText(childText));
33
+ expect(screen.getByTestId("SelectDefaultPicker").findByType(MockPicker)).toBeDefined();
34
+ });
35
+ it("closes the picker", () => {
36
+ const screen = setup();
37
+ fireEvent.press(screen.getByText(childText));
38
+ fireEvent.press(screen.getByText("Done"));
39
+ expect(screen.getByTestId("SelectDefaultPicker").findAllByType(MockPicker)).toEqual([]);
40
+ });
41
+ it("fires the onChange", () => {
42
+ const screen = setup();
43
+ fireEvent.press(screen.getByText(childText));
44
+ const menu = screen
45
+ .getByTestId("SelectDefaultPicker")
46
+ .findByType(MockPicker);
47
+ expect(menu).toBeDefined();
48
+ fireEvent(menu, "onValueChange", "2");
49
+ expect(handleChange).toHaveBeenCalledWith("2");
50
+ });
51
+ });