@lookiero/checkout 0.1.2 → 0.2.1

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 (130) hide show
  1. package/dist/infrastructure/delivery/_mock/bootstrap.mock.js +2 -1
  2. package/dist/infrastructure/delivery/bootstrap.d.ts +2 -1
  3. package/dist/infrastructure/delivery/bootstrap.js +3 -2
  4. package/dist/infrastructure/projection/react/useViewBookedSizeReplaceableProductVariantsForCheckoutItem.js +2 -1
  5. package/dist/infrastructure/projection/react/useViewFirstAvailableCheckoutByCustomerId.js +2 -1
  6. package/dist/infrastructure/projection/react/useViewIsCheckoutAccessibleByCustomerId.js +2 -1
  7. package/dist/infrastructure/projection/react/useViewUiSettingByKey.js +3 -1
  8. package/dist/infrastructure/ui/Root.js +8 -10
  9. package/dist/infrastructure/ui/components/atoms/spinner/Spinner.js +9 -0
  10. package/dist/infrastructure/ui/routing/CheckoutAccessibilityMiddleware.js +4 -4
  11. package/dist/infrastructure/ui/routing/CheckoutMiddleware.js +12 -9
  12. package/dist/infrastructure/ui/routing/Routing.js +11 -14
  13. package/dist/infrastructure/ui/views/intro/Intro.js +5 -7
  14. package/dist/infrastructure/ui/views/item/Item.js +6 -8
  15. package/dist/infrastructure/ui/views/summary/Summary.js +5 -7
  16. package/package.json +7 -5
  17. package/.eslintignore +0 -7
  18. package/.eslintrc +0 -72
  19. package/.expo-shared/assets.json +0 -4
  20. package/.github/CODEOWNERS +0 -1
  21. package/.github/actions/version/action.yaml +0 -32
  22. package/.github/dependabot.yaml +0 -10
  23. package/.github/workflows/build.yaml +0 -71
  24. package/.github/workflows/publish.yaml +0 -52
  25. package/.husky/pre-commit +0 -4
  26. package/.husky/prepare-commit-msg +0 -26
  27. package/.husky/prepush +0 -12
  28. package/.lintstagedrc.json +0 -4
  29. package/.nvmrc +0 -1
  30. package/.prettierignore +0 -2
  31. package/.prettierrc.json +0 -6
  32. package/@types/aurora-next.d.ts +0 -1
  33. package/app.config.js +0 -4
  34. package/app.json +0 -31
  35. package/assets/adaptive-icon.png +0 -0
  36. package/assets/favicon.png +0 -0
  37. package/assets/icon.png +0 -0
  38. package/assets/splash.png +0 -0
  39. package/babel.config.js +0 -6
  40. package/dist/infrastructure/ui/components/atoms/spiner/Spinner.js +0 -11
  41. package/dist/infrastructure/ui/test/render.d.ts +0 -19
  42. package/dist/infrastructure/ui/test/render.js +0 -14
  43. package/jest.config.js +0 -9
  44. package/jest.setup.js +0 -3
  45. package/src/Expo.tsx +0 -59
  46. package/src/domain/checkoutBooking/command/bookSizeReplaceableProductVariantsForCheckoutItem.test.ts +0 -26
  47. package/src/domain/checkoutBooking/command/bookSizeReplaceableProductVariantsForCheckoutItem.ts +0 -35
  48. package/src/domain/checkoutBooking/model/checkoutBooking.test.ts +0 -30
  49. package/src/domain/checkoutBooking/model/checkoutBooking.ts +0 -33
  50. package/src/domain/checkoutBooking/model/checkoutBookingBooked.test.ts +0 -23
  51. package/src/domain/checkoutBooking/model/checkoutBookingBooked.ts +0 -23
  52. package/src/domain/checkoutBooking/model/checkoutBookings.ts +0 -8
  53. package/src/domain/uiSetting/command/updateUiSetting.test.ts +0 -19
  54. package/src/domain/uiSetting/command/updateUiSetting.ts +0 -25
  55. package/src/domain/uiSetting/model/uiSetting.test.ts +0 -26
  56. package/src/domain/uiSetting/model/uiSetting.ts +0 -24
  57. package/src/domain/uiSetting/model/uiSettingUpdated.test.ts +0 -17
  58. package/src/domain/uiSetting/model/uiSettingUpdated.ts +0 -21
  59. package/src/domain/uiSetting/model/uiSettings.ts +0 -8
  60. package/src/index.ts +0 -44
  61. package/src/infrastructure/delivery/_mock/bootstrap.mock.ts +0 -38
  62. package/src/infrastructure/delivery/_mock/checkout.mock.ts +0 -81
  63. package/src/infrastructure/delivery/bootstrap.ts +0 -42
  64. package/src/infrastructure/delivery/http/fetchHttpClient.test.ts +0 -51
  65. package/src/infrastructure/delivery/http/fetchHttpClient.ts +0 -41
  66. package/src/infrastructure/delivery/http/httpClient.ts +0 -18
  67. package/src/infrastructure/domain/checkoutBooking/model/httpCheckoutBookings.test.ts +0 -45
  68. package/src/infrastructure/domain/checkoutBooking/model/httpCheckoutBookings.ts +0 -34
  69. package/src/infrastructure/domain/react/useBookSizeReplaceableProductVariantsForCheckoutItem.test.ts +0 -38
  70. package/src/infrastructure/domain/react/useBookSizeReplaceableProductVariantsForCheckoutItem.ts +0 -46
  71. package/src/infrastructure/domain/react/useSetCheckoutIntroShown.test.ts +0 -34
  72. package/src/infrastructure/domain/react/useSetCheckoutIntroShown.ts +0 -30
  73. package/src/infrastructure/domain/react/useUpdateUiSetting.test.ts +0 -31
  74. package/src/infrastructure/domain/react/useUpdateUiSetting.ts +0 -45
  75. package/src/infrastructure/domain/uiSetting/model/storageUiSettings.test.ts +0 -50
  76. package/src/infrastructure/domain/uiSetting/model/storageUiSettings.ts +0 -52
  77. package/src/infrastructure/persistence/asyncStorageStorage.ts +0 -13
  78. package/src/infrastructure/persistence/storage.ts +0 -9
  79. package/src/infrastructure/persistence/uiSettingData.ts +0 -7
  80. package/src/infrastructure/projection/httpBookedSizeReplaceableProductVariantsForCheckoutItemView.test.ts +0 -65
  81. package/src/infrastructure/projection/httpBookedSizeReplaceableProductVariantsForCheckoutItemView.ts +0 -102
  82. package/src/infrastructure/projection/httpFirstAvailableCheckoutByCustomerIdView.test.ts +0 -99
  83. package/src/infrastructure/projection/httpFirstAvailableCheckoutByCustomerIdView.ts +0 -128
  84. package/src/infrastructure/projection/httpIsCheckoutEnabledByCustomerIdView.test.ts +0 -32
  85. package/src/infrastructure/projection/httpIsCheckoutEnabledByCustomerIdView.ts +0 -27
  86. package/src/infrastructure/projection/react/useViewBookedSizeReplaceableProductVariantsForCheckoutItem.test.ts +0 -51
  87. package/src/infrastructure/projection/react/useViewBookedSizeReplaceableProductVariantsForCheckoutItem.ts +0 -25
  88. package/src/infrastructure/projection/react/useViewCheckoutIntroShown.test.ts +0 -41
  89. package/src/infrastructure/projection/react/useViewCheckoutIntroShown.ts +0 -9
  90. package/src/infrastructure/projection/react/useViewFirstAvailableCheckoutByCustomerId.test.ts +0 -28
  91. package/src/infrastructure/projection/react/useViewFirstAvailableCheckoutByCustomerId.ts +0 -22
  92. package/src/infrastructure/projection/react/useViewIsCheckoutAccessibleByCustomerId.test.ts +0 -44
  93. package/src/infrastructure/projection/react/useViewIsCheckoutAccessibleByCustomerId.ts +0 -24
  94. package/src/infrastructure/projection/react/useViewUiSettingByKey.test.ts +0 -30
  95. package/src/infrastructure/projection/react/useViewUiSettingByKey.ts +0 -24
  96. package/src/infrastructure/projection/storageUiSettingByKeyView.test.ts +0 -32
  97. package/src/infrastructure/projection/storageUiSettingByKeyView.ts +0 -37
  98. package/src/infrastructure/ui/Root.tsx +0 -53
  99. package/src/infrastructure/ui/components/atoms/spiner/Spinner.style.ts +0 -12
  100. package/src/infrastructure/ui/components/atoms/spiner/Spinner.tsx +0 -35
  101. package/src/infrastructure/ui/routing/CheckoutAccessibilityMiddleware.test.tsx +0 -70
  102. package/src/infrastructure/ui/routing/CheckoutAccessibilityMiddleware.tsx +0 -31
  103. package/src/infrastructure/ui/routing/CheckoutMiddleware.test.tsx +0 -100
  104. package/src/infrastructure/ui/routing/CheckoutMiddleware.tsx +0 -52
  105. package/src/infrastructure/ui/routing/Routing.tsx +0 -64
  106. package/src/infrastructure/ui/routing/router/Router.native.ts +0 -1
  107. package/src/infrastructure/ui/routing/router/Router.ts +0 -1
  108. package/src/infrastructure/ui/routing/routes.ts +0 -6
  109. package/src/infrastructure/ui/settings/UISettings.ts +0 -5
  110. package/src/infrastructure/ui/test/render.tsx +0 -47
  111. package/src/infrastructure/ui/views/intro/Intro.test.tsx +0 -15
  112. package/src/infrastructure/ui/views/intro/Intro.tsx +0 -27
  113. package/src/infrastructure/ui/views/item/Item.tsx +0 -31
  114. package/src/infrastructure/ui/views/summary/Summary.tsx +0 -27
  115. package/src/projection/bookedSizeReplaceableProductVariants/viewBookedSizeReplaceableProductVariantsForCheckoutItem.test.ts +0 -40
  116. package/src/projection/bookedSizeReplaceableProductVariants/viewBookedSizeReplaceableProductVariantsForCheckoutItem.ts +0 -85
  117. package/src/projection/checkout/viewFirstAvailableCheckoutByCustomerId.test.ts +0 -22
  118. package/src/projection/checkout/viewFirstAvailableCheckoutByCustomerId.ts +0 -149
  119. package/src/projection/checkout/viewIsCheckoutAccessibleByCustomerId.test.ts +0 -54
  120. package/src/projection/checkout/viewIsCheckoutAccessibleByCustomerId.ts +0 -46
  121. package/src/projection/checkout/viewIsCheckoutEnabledByCustomerId.test.ts +0 -20
  122. package/src/projection/checkout/viewIsCheckoutEnabledByCustomerId.ts +0 -51
  123. package/src/projection/uiSetting/viewUiSettingByKey.test.ts +0 -22
  124. package/src/projection/uiSetting/viewUiSettingByKey.ts +0 -55
  125. package/tsconfig.build.json +0 -16
  126. package/tsconfig.json +0 -19
  127. package/webpack.config.js +0 -17
  128. /package/dist/infrastructure/ui/components/atoms/{spiner → spinner}/Spinner.d.ts +0 -0
  129. /package/dist/infrastructure/ui/components/atoms/{spiner → spinner}/Spinner.style.d.ts +0 -0
  130. /package/dist/infrastructure/ui/components/atoms/{spiner → spinner}/Spinner.style.js +0 -0
@@ -1,28 +0,0 @@
1
- import { bootstrap } from "@lookiero/messaging-react";
2
- import { renderHook } from "@testing-library/react-hooks";
3
- import {
4
- CheckoutProjection,
5
- viewFirstAvailableCheckoutByCustomerIdHandler,
6
- VIEW_FIRST_AVAILABLE_CHECKOUT_BY_CUSTOMER_ID,
7
- } from "../../../projection/checkout/viewFirstAvailableCheckoutByCustomerId";
8
- import { useViewFirstAvailableCheckoutByCustomerId as sut } from "./useViewFirstAvailableCheckoutByCustomerId";
9
-
10
- const customerId = "29790d24-b139-4ab8-b618-d796d101e974";
11
- const checkoutProjection: CheckoutProjection = { id: "75574065-5838-42de-9924-c712f7854347" };
12
- const view = jest.fn().mockReturnValue(checkoutProjection);
13
- const { Component: Messaging } = bootstrap({ id: "Checkout" })
14
- .query(VIEW_FIRST_AVAILABLE_CHECKOUT_BY_CUSTOMER_ID, viewFirstAvailableCheckoutByCustomerIdHandler, { view })
15
- .build();
16
-
17
- describe("useViewFirstAvailableCheckoutByCustomerId integration hook", () => {
18
- it("returns success as the query status and the result itself after rendering the hook", async () => {
19
- const { result, waitFor } = renderHook(() => sut({ customerId }), { wrapper: Messaging });
20
-
21
- await waitFor(() => {
22
- const [projection, status] = result.current;
23
-
24
- expect(projection).toStrictEqual(checkoutProjection);
25
- expect(status).toBe("success");
26
- });
27
- });
28
- });
@@ -1,22 +0,0 @@
1
- import { useQuery, UseQueryFunctionResult } from "@lookiero/messaging-react";
2
- import {
3
- CheckoutProjection,
4
- viewFirstAvailableCheckoutByCustomerId,
5
- } from "../../../projection/checkout/viewFirstAvailableCheckoutByCustomerId";
6
-
7
- interface UseViewFirstAvailableCheckoutByCustomerIdFunctionArgs {
8
- readonly customerId: string;
9
- }
10
-
11
- interface UseViewFirstAvailableCheckoutByCustomerIdFunction {
12
- (args: UseViewFirstAvailableCheckoutByCustomerIdFunctionArgs): UseQueryFunctionResult<CheckoutProjection>;
13
- }
14
-
15
- const useViewFirstAvailableCheckoutByCustomerId: UseViewFirstAvailableCheckoutByCustomerIdFunction = ({ customerId }) =>
16
- useQuery({
17
- query: viewFirstAvailableCheckoutByCustomerId({ customerId }),
18
- contextId: "Checkout",
19
- options: { staleTime: Infinity, retry: false },
20
- });
21
-
22
- export { useViewFirstAvailableCheckoutByCustomerId };
@@ -1,44 +0,0 @@
1
- import { bootstrap } from "@lookiero/messaging-react";
2
- import { renderHook } from "@testing-library/react-hooks";
3
- import {
4
- CheckoutProjection,
5
- viewFirstAvailableCheckoutByCustomerIdHandler,
6
- VIEW_FIRST_AVAILABLE_CHECKOUT_BY_CUSTOMER_ID,
7
- } from "../../../projection/checkout/viewFirstAvailableCheckoutByCustomerId";
8
- import {
9
- viewIsCheckoutAccessibleByCustomerIdHandler,
10
- VIEW_IS_CHECKOUT_ACCESSIBLE_BY_CUSTOMER_ID,
11
- } from "../../../projection/checkout/viewIsCheckoutAccessibleByCustomerId";
12
- import {
13
- viewIsCheckoutEnabledByCustomerIdHandler,
14
- VIEW_IS_CHECKOUT_ENABLED_BY_CUSTOMER_ID,
15
- } from "../../../projection/checkout/viewIsCheckoutEnabledByCustomerId";
16
- import { useViewIsCheckoutAccessibleByCustomerId as sut } from "./useViewIsCheckoutAccessibleByCustomerId";
17
-
18
- const customerId = "29790d24-b139-4ab8-b618-d796d101e974";
19
- const checkoutProjection: CheckoutProjection = { id: "75574065-5838-42de-9924-c712f7854347" };
20
- const firstAvailableCheckoutByCustomerIdViewMock = jest.fn().mockReturnValue(checkoutProjection);
21
- const isCheckoutAccessibleByCustomerIdViewMock = jest.fn().mockReturnValue(checkoutProjection);
22
-
23
- const { Component: Messaging } = bootstrap({ id: "Checkout" })
24
- .query(VIEW_FIRST_AVAILABLE_CHECKOUT_BY_CUSTOMER_ID, viewFirstAvailableCheckoutByCustomerIdHandler, {
25
- view: firstAvailableCheckoutByCustomerIdViewMock,
26
- })
27
- .query(VIEW_IS_CHECKOUT_ENABLED_BY_CUSTOMER_ID, viewIsCheckoutEnabledByCustomerIdHandler, {
28
- view: isCheckoutAccessibleByCustomerIdViewMock,
29
- })
30
- .query(VIEW_IS_CHECKOUT_ACCESSIBLE_BY_CUSTOMER_ID, viewIsCheckoutAccessibleByCustomerIdHandler, {})
31
- .build();
32
-
33
- describe("useViewIsCheckoutAccessibleByCustomerId integration hook", () => {
34
- it("returns success as the query status and the result itself after rendering the hook", async () => {
35
- const { result, waitFor } = renderHook(() => sut({ customerId }), { wrapper: Messaging });
36
-
37
- await waitFor(() => {
38
- const [projection, status] = result.current;
39
-
40
- expect(projection).toBe(true);
41
- expect(status).toBe("success");
42
- });
43
- });
44
- });
@@ -1,24 +0,0 @@
1
- import { useQuery, UseQueryFunctionResult } from "@lookiero/messaging-react";
2
- import {
3
- IsCheckoutAccessibleByCustomerIdProjection,
4
- viewIsCheckoutAccessibleByCustomerId,
5
- } from "../../../projection/checkout/viewIsCheckoutAccessibleByCustomerId";
6
-
7
- interface UseViewIsCheckoutAccessibleByCustomerIdFunctionArgs {
8
- readonly customerId: string | undefined;
9
- }
10
-
11
- interface UseViewIsCheckoutAccessibleByCustomerIdFunction {
12
- (
13
- args: UseViewIsCheckoutAccessibleByCustomerIdFunctionArgs,
14
- ): UseQueryFunctionResult<IsCheckoutAccessibleByCustomerIdProjection>;
15
- }
16
-
17
- const useViewIsCheckoutAccessibleByCustomerId: UseViewIsCheckoutAccessibleByCustomerIdFunction = ({ customerId }) =>
18
- useQuery({
19
- query: viewIsCheckoutAccessibleByCustomerId({ customerId }),
20
- contextId: "Checkout",
21
- options: { staleTime: Infinity },
22
- });
23
-
24
- export { useViewIsCheckoutAccessibleByCustomerId };
@@ -1,30 +0,0 @@
1
- import { bootstrap } from "@lookiero/messaging-react";
2
- import { renderHook } from "@testing-library/react-hooks";
3
- import {
4
- UiSettingProjection,
5
- viewUiSettingByKeyHandler,
6
- VIEW_UI_SETTING_BY_KEY,
7
- } from "../../../projection/uiSetting/viewUiSettingByKey";
8
- import { useViewUiSettingByKey as sut } from "./useViewUiSettingByKey";
9
-
10
- const uiSettingKey = "ui_setting_key";
11
- const uiSettingProjection: UiSettingProjection = {
12
- id: "this-should-be-a-uuid",
13
- key: uiSettingKey,
14
- value: "ui_setting_value",
15
- };
16
- const view = jest.fn().mockReturnValue(uiSettingProjection);
17
- const { Component: Messaging } = bootstrap().query(VIEW_UI_SETTING_BY_KEY, viewUiSettingByKeyHandler, { view }).build();
18
-
19
- describe("useViewUiSettingByKey integration hook", () => {
20
- it("returns success as the query status and the result itself after rendering the hook", async () => {
21
- const { result, waitFor } = renderHook(() => sut({ key: uiSettingKey }), { wrapper: Messaging });
22
-
23
- await waitFor(() => {
24
- const [projection, status] = result.current;
25
-
26
- expect(projection).toStrictEqual(uiSettingProjection);
27
- expect(status).toBe("success");
28
- });
29
- });
30
- });
@@ -1,24 +0,0 @@
1
- import { DomainEvent, MessageName } from "@lookiero/messaging";
2
- import { useQuery, UseQueryFunctionResult } from "@lookiero/messaging-react";
3
- import { UiSettingUpdated, UI_SETTING_UPDATED } from "../../../domain/uiSetting/model/uiSettingUpdated";
4
- import { UiSettingProjection, viewUiSettingByKey } from "../../../projection/uiSetting/viewUiSettingByKey";
5
-
6
- interface UseViewUiSettingByKeyFunctionArgs {
7
- readonly key: string;
8
- }
9
-
10
- interface UseViewUiSettingByKeyFunction {
11
- (args: UseViewUiSettingByKeyFunctionArgs): UseQueryFunctionResult<UiSettingProjection>;
12
- }
13
-
14
- const isUiSettingUpdated = (event: DomainEvent<MessageName>): event is UiSettingUpdated =>
15
- event.name === UI_SETTING_UPDATED;
16
-
17
- const useViewUiSettingByKey: UseViewUiSettingByKeyFunction = ({ key }) =>
18
- useQuery({
19
- query: viewUiSettingByKey({ key }),
20
- invalidation: isUiSettingUpdated,
21
- options: { staleTime: Infinity },
22
- });
23
-
24
- export { useViewUiSettingByKey };
@@ -1,32 +0,0 @@
1
- import { UiSettingDto } from "../persistence/uiSettingData";
2
- import { storageUiSettingByKeyView as sut } from "./storageUiSettingByKeyView";
3
-
4
- const uiSettingKey = "ui_setting_key";
5
- const uiSetting: UiSettingDto = { id: "this-should-be-a-uuid", key: uiSettingKey, value: "ui_setting_value" };
6
-
7
- const readMock = jest.fn();
8
- const view = sut({ read: readMock });
9
-
10
- describe("storageUiSettingByKeyView", () => {
11
- it("returns a UiSetting projection", async () => {
12
- readMock.mockReturnValue(Promise.resolve(uiSetting));
13
-
14
- const returnedUiSetting = await view({ key: uiSettingKey });
15
-
16
- expect(returnedUiSetting).toStrictEqual(uiSetting);
17
- });
18
-
19
- it("returns undefined when ui setting key does not exist", async () => {
20
- readMock.mockReturnValue(Promise.resolve(undefined));
21
-
22
- const returnedUiSetting = await view({ key: uiSettingKey });
23
-
24
- expect(returnedUiSetting).toBeUndefined();
25
- });
26
-
27
- it("throws for an unsuccessfull response", async () => {
28
- readMock.mockRejectedValue("error");
29
-
30
- await expect(view({ key: uiSettingKey })).rejects.toThrow();
31
- });
32
- });
@@ -1,37 +0,0 @@
1
- import { UiSettingByKeyView, UiSettingProjection } from "../../projection/uiSetting/viewUiSettingByKey";
2
- import { ReadFunction } from "../persistence/storage";
3
- import { UiSettingDto } from "../persistence/uiSettingData";
4
-
5
- interface ToUiSettingProjectionFunction {
6
- (uiSettingDto: UiSettingDto): UiSettingProjection;
7
- }
8
-
9
- const toUiSettingProjection: ToUiSettingProjectionFunction = (uiSettingDto) => ({
10
- id: uiSettingDto.id,
11
- key: uiSettingDto.key,
12
- value: uiSettingDto.value,
13
- });
14
-
15
- interface StorageUiSettingByKeyView extends UiSettingByKeyView {}
16
-
17
- interface StorageUiSettingByKeyViewFunctionArgs {
18
- readonly read: ReadFunction<UiSettingDto>;
19
- }
20
-
21
- interface StorageUiSettingByKeyViewFunction {
22
- (args: StorageUiSettingByKeyViewFunctionArgs): StorageUiSettingByKeyView;
23
- }
24
-
25
- const storageUiSettingByKeyView: StorageUiSettingByKeyViewFunction =
26
- ({ read }) =>
27
- async ({ key }) => {
28
- try {
29
- const uiSettingDto = await read(key);
30
-
31
- return uiSettingDto ? toUiSettingProjection(uiSettingDto) : undefined;
32
- } catch (ignored) {
33
- throw new Error("Could not fetch the uiSetting");
34
- }
35
- };
36
-
37
- export { storageUiSettingByKeyView };
@@ -1,53 +0,0 @@
1
- import { inMemoryFetchTranslation } from "@lookiero/i18n";
2
- import { ReactIntl } from "@lookiero/i18n-react";
3
- import { MessagingRoot } from "@lookiero/messaging-react/bootstrap";
4
- import { FC, useCallback } from "react";
5
- import { Platform } from "react-native";
6
- import { Spinner } from "./components/atoms/spiner/Spinner";
7
- import { Router } from "./routing/router/Router";
8
- import { Routing } from "./routing/Routing";
9
-
10
- const translationData: Record<string, Record<string, string>> = {
11
- en: { intro: "Intro view's title" },
12
- es: { intro: "Título de la vista Intro" },
13
- };
14
- const fetchTranslation = inMemoryFetchTranslation({ translationData });
15
-
16
- interface RootFunctionArgs {
17
- readonly Messaging: MessagingRoot;
18
- }
19
-
20
- interface RootFunction {
21
- (args: RootFunctionArgs): FC<RootProps>;
22
- }
23
-
24
- interface RootProps {
25
- readonly locale?: string;
26
- readonly customerId: string | undefined;
27
- readonly onNotAccessible: () => void;
28
- }
29
-
30
- const root: RootFunction =
31
- ({ Messaging }) =>
32
- // eslint-disable-next-line react/display-name, react/prop-types
33
- ({ locale = "en", customerId, onNotAccessible }) => {
34
- const handleOnI18nError = useCallback(() => void 0, []);
35
-
36
- return (
37
- <ReactIntl.I18n
38
- locale={locale}
39
- fetchTranslation={fetchTranslation}
40
- loader={<Spinner />}
41
- onError={handleOnI18nError}
42
- contextId="CheckoutI18n"
43
- >
44
- <Messaging includeReactQueryDevTools={Platform.OS === "web"}>
45
- <Router>
46
- <Routing customerId={customerId} onNotAccessible={onNotAccessible} />
47
- </Router>
48
- </Messaging>
49
- </ReactIntl.I18n>
50
- );
51
- };
52
-
53
- export { RootProps, root };
@@ -1,12 +0,0 @@
1
- import { StyleSheet } from "react-native";
2
-
3
- const style = StyleSheet.create({
4
- container: {
5
- display: "flex",
6
- flex: 1,
7
- alignItems: "center",
8
- justifyContent: "center",
9
- },
10
- });
11
-
12
- export { style };
@@ -1,35 +0,0 @@
1
- import { FC } from "react";
2
- import { View } from "react-native";
3
- import { style } from "./Spinner.style";
4
-
5
- const Spinner: FC = () => (
6
- <View style={style.container}>
7
- <svg
8
- xmlns="http://www.w3.org/2000/svg"
9
- width="30px"
10
- height="30px"
11
- viewBox="0 0 100 100"
12
- preserveAspectRatio="xMidYMid"
13
- >
14
- <circle cx="50" cy="50" r="32" stroke="#000000" strokeWidth="6" strokeLinecap="round" fill="none">
15
- <animateTransform
16
- attributeName="transform"
17
- type="rotate"
18
- repeatCount="indefinite"
19
- dur="1.5384615384615383s"
20
- values="0 50 50;180 50 50;720 50 50"
21
- keyTimes="0;0.5;1"
22
- ></animateTransform>
23
- <animate
24
- attributeName="stroke-dasharray"
25
- repeatCount="indefinite"
26
- dur="1.5384615384615383s"
27
- values="42.22300526424682 158.83892456549995;176.93449825017714 24.127431579569617;42.22300526424682 158.83892456549995"
28
- keyTimes="0;0.5;1"
29
- ></animate>
30
- </circle>
31
- </svg>
32
- </View>
33
- );
34
-
35
- export { Spinner };
@@ -1,70 +0,0 @@
1
- import { render, RenderResult } from "@testing-library/react-native";
2
- import { Text } from "react-native";
3
- import { MemoryRouter, Route, Routes } from "react-router-native";
4
- import { useViewIsCheckoutAccessibleByCustomerId } from "../../projection/react/useViewIsCheckoutAccessibleByCustomerId";
5
- import { CheckoutAccessibilityMiddleware } from "./CheckoutAccessibilityMiddleware";
6
-
7
- jest.mock("../../projection/react/useViewIsCheckoutAccessibleByCustomerId", () => ({
8
- useViewIsCheckoutAccessibleByCustomerId: jest.fn(),
9
- }));
10
-
11
- const customerId = "29790d24-b139-4ab8-b618-d796d101e974";
12
- const checkoutRouteText = "checkout-route-component";
13
- const loaderText = "loader-component";
14
-
15
- interface RenderCheckoutAccessibilityMiddlewareArgs {
16
- readonly onNotAccessible?: () => void;
17
- }
18
-
19
- interface RenderCheckoutAccessibilityMiddlewareFunction {
20
- (args?: RenderCheckoutAccessibilityMiddlewareArgs): RenderResult;
21
- }
22
-
23
- const renderCheckoutAccessibilityMiddleware: RenderCheckoutAccessibilityMiddlewareFunction = ({
24
- onNotAccessible = () => void 0,
25
- } = {}) =>
26
- render(
27
- <MemoryRouter initialEntries={["/"]}>
28
- <Routes>
29
- <Route
30
- path="/"
31
- element={
32
- <CheckoutAccessibilityMiddleware
33
- customerId={customerId}
34
- onNotAccessible={onNotAccessible}
35
- loader={<Text>{loaderText}</Text>}
36
- />
37
- }
38
- >
39
- <Route path="/" element={<Text>{checkoutRouteText}</Text>} />
40
- </Route>
41
- </Routes>
42
- </MemoryRouter>,
43
- );
44
-
45
- describe("CheckoutAccessibilityMiddleware component", () => {
46
- it("renders a loader while processing viewIsCheckoutAccessibleByCustomerId use-case", async () => {
47
- (useViewIsCheckoutAccessibleByCustomerId as jest.Mock).mockReturnValue([undefined, "loading"]);
48
- const { findByText } = renderCheckoutAccessibilityMiddleware();
49
- const loader = await findByText(loaderText);
50
-
51
- expect(loader).toBeTruthy();
52
- });
53
-
54
- it("renders its Outlet's content if it is accessible", async () => {
55
- (useViewIsCheckoutAccessibleByCustomerId as jest.Mock).mockReturnValue([true, "success"]);
56
- const { findByText } = renderCheckoutAccessibilityMiddleware();
57
- const checkoutContent = await findByText(checkoutRouteText);
58
-
59
- expect(checkoutContent).toBeTruthy();
60
- });
61
-
62
- it("calls onNotAccessible callback if it is not accessible", async () => {
63
- (useViewIsCheckoutAccessibleByCustomerId as jest.Mock).mockReturnValue([false, "success"]);
64
- const onNotAccessibleFn = jest.fn();
65
- const { toJSON } = renderCheckoutAccessibilityMiddleware({ onNotAccessible: onNotAccessibleFn });
66
-
67
- expect(toJSON()).toBeNull();
68
- expect(onNotAccessibleFn).toHaveBeenCalled();
69
- });
70
- });
@@ -1,31 +0,0 @@
1
- import { FC, useEffect, useRef } from "react";
2
- import { Outlet } from "react-router-native";
3
- import { useViewIsCheckoutAccessibleByCustomerId } from "../../projection/react/useViewIsCheckoutAccessibleByCustomerId";
4
- import { Spinner } from "../components/atoms/spiner/Spinner";
5
-
6
- interface CheckoutAccessibilityMiddlewareProps {
7
- readonly customerId: string | undefined;
8
- readonly onNotAccessible: () => void;
9
- readonly loader?: JSX.Element;
10
- }
11
-
12
- const CheckoutAccessibilityMiddleware: FC<CheckoutAccessibilityMiddlewareProps> = ({
13
- customerId,
14
- onNotAccessible,
15
- loader = <Spinner />,
16
- }) => {
17
- const [accessible] = useViewIsCheckoutAccessibleByCustomerId({ customerId });
18
-
19
- const onNotAccessibleRef = useRef(onNotAccessible);
20
- onNotAccessibleRef.current = onNotAccessible;
21
-
22
- useEffect(() => {
23
- if (accessible === false) {
24
- onNotAccessibleRef.current();
25
- }
26
- }, [accessible, onNotAccessible]);
27
-
28
- return accessible === undefined ? loader : accessible ? <Outlet /> : null;
29
- };
30
-
31
- export { CheckoutAccessibilityMiddleware };
@@ -1,100 +0,0 @@
1
- import { render, RenderResult } from "@testing-library/react-native";
2
- import { Text } from "react-native";
3
- import { generatePath, MemoryRouter, Route, Routes } from "react-router-native";
4
- import { v4 as uuid } from "uuid";
5
- import { CheckoutItemStatus } from "../../../projection/checkout/viewFirstAvailableCheckoutByCustomerId";
6
- import { startedCheckoutWithItems } from "../../delivery/_mock/checkout.mock";
7
- import { useViewFirstAvailableCheckoutByCustomerId } from "../../projection/react/useViewFirstAvailableCheckoutByCustomerId";
8
- import { useViewCheckoutIntroShown } from "../../projection/react/useViewCheckoutIntroShown";
9
- import { CheckoutMiddleware } from "./CheckoutMiddleware";
10
-
11
- import { Routes as CheckoutRoutes } from "./routes";
12
-
13
- jest.mock("../../projection/react/useViewCheckoutIntroShown", () => ({
14
- useViewCheckoutIntroShown: jest.fn(),
15
- }));
16
- jest.mock("../../projection/react/useViewFirstAvailableCheckoutByCustomerId", () => ({
17
- useViewFirstAvailableCheckoutByCustomerId: jest.fn(),
18
- }));
19
-
20
- const customerId = "29790d24-b139-4ab8-b618-d796d101e974";
21
- const loaderText = "loader-component";
22
- const introRouteText = "intro-route-component";
23
- const itemRouteText = "item-route-component";
24
- const summaryRouteText = "summary-route-component";
25
-
26
- interface RenderCheckoutMiddlewareArgs {
27
- readonly route: string;
28
- }
29
-
30
- interface RenderCheckoutMiddlewareFunction {
31
- (args: RenderCheckoutMiddlewareArgs): RenderResult;
32
- }
33
-
34
- const renderCheckoutMiddleware: RenderCheckoutMiddlewareFunction = ({ route }) =>
35
- render(
36
- <MemoryRouter initialEntries={[route]}>
37
- <Routes>
38
- <Route
39
- path={CheckoutRoutes.CHECKOUT}
40
- element={<CheckoutMiddleware customerId={customerId} loader={<Text>{loaderText}</Text>} />}
41
- >
42
- <Route path={CheckoutRoutes.INTRO} element={<Text>{introRouteText}</Text>} />
43
- <Route path={CheckoutRoutes.ITEM} element={<Text>{itemRouteText}</Text>} />
44
- <Route path={CheckoutRoutes.SUMMARY} element={<Text>{summaryRouteText}</Text>} />
45
- </Route>
46
- </Routes>
47
- </MemoryRouter>,
48
- );
49
-
50
- const routes: string[] = [
51
- CheckoutRoutes.CHECKOUT,
52
- CheckoutRoutes.INTRO,
53
- generatePath(CheckoutRoutes.ITEM, { id: uuid() }),
54
- CheckoutRoutes.SUMMARY,
55
- ];
56
-
57
- describe("CheckoutMiddleware component", () => {
58
- test.each(routes)("renders a loader while processing dependant use-cases in route: %s", async (route) => {
59
- (useViewCheckoutIntroShown as jest.Mock).mockReturnValue([undefined, "loading"]);
60
- (useViewFirstAvailableCheckoutByCustomerId as jest.Mock).mockReturnValue([undefined, "loading"]);
61
-
62
- const { findByText } = renderCheckoutMiddleware({ route });
63
- const loader = await findByText(loaderText);
64
-
65
- expect(loader).toBeTruthy();
66
- });
67
-
68
- test.each(routes)("renders the intro view if it should be visible with initial route: %s", async (route) => {
69
- const checkoutMock = startedCheckoutWithItems({ status: [CheckoutItemStatus.INITIAL, CheckoutItemStatus.INITIAL] });
70
- (useViewCheckoutIntroShown as jest.Mock).mockReturnValue([true, "success"]);
71
- (useViewFirstAvailableCheckoutByCustomerId as jest.Mock).mockReturnValue([checkoutMock, "success"]);
72
-
73
- const { findByText } = renderCheckoutMiddleware({ route });
74
- const intro = await findByText(introRouteText);
75
-
76
- expect(intro).toBeTruthy();
77
- });
78
-
79
- test.each(routes)("renders the item view if it should be visible with initial route: %s", async (route) => {
80
- const checkoutMock = startedCheckoutWithItems({ status: [CheckoutItemStatus.KEPT, CheckoutItemStatus.INITIAL] });
81
- (useViewCheckoutIntroShown as jest.Mock).mockReturnValue([false, "success"]);
82
- (useViewFirstAvailableCheckoutByCustomerId as jest.Mock).mockReturnValue([checkoutMock, "success"]);
83
-
84
- const { findByText } = renderCheckoutMiddleware({ route });
85
- const item = await findByText(itemRouteText);
86
-
87
- expect(item).toBeTruthy();
88
- });
89
-
90
- test.each(routes)("renders the summary view if it should be visible with initial route: %s", async (route) => {
91
- const checkoutMock = startedCheckoutWithItems({ status: [CheckoutItemStatus.KEPT, CheckoutItemStatus.RETURNED] });
92
- (useViewCheckoutIntroShown as jest.Mock).mockReturnValue([false, "success"]);
93
- (useViewFirstAvailableCheckoutByCustomerId as jest.Mock).mockReturnValue([checkoutMock, "success"]);
94
-
95
- const { findByText } = renderCheckoutMiddleware({ route });
96
- const summary = await findByText(summaryRouteText);
97
-
98
- expect(summary).toBeTruthy();
99
- });
100
- });
@@ -1,52 +0,0 @@
1
- import { QueryStatus } from "@lookiero/messaging-react";
2
- import { FC } from "react";
3
- import { generatePath, Navigate, Outlet, useMatch } from "react-router";
4
- import {
5
- CheckoutItemProjection,
6
- CheckoutItemStatus,
7
- } from "../../../projection/checkout/viewFirstAvailableCheckoutByCustomerId";
8
- import { useViewFirstAvailableCheckoutByCustomerId } from "../../projection/react/useViewFirstAvailableCheckoutByCustomerId";
9
- import { useViewCheckoutIntroShown } from "../../projection/react/useViewCheckoutIntroShown";
10
- import { Spinner } from "../components/atoms/spiner/Spinner";
11
- import { Routes } from "./routes";
12
-
13
- interface CheckoutMiddlewareProps {
14
- readonly customerId: string;
15
- readonly loader?: JSX.Element;
16
- }
17
-
18
- const CheckoutMiddleware: FC<CheckoutMiddlewareProps> = ({ customerId, loader = <Spinner /> }) => {
19
- const [checkoutIntroShown, checkoutIntroShownStatus] = useViewCheckoutIntroShown();
20
- const [checkout, checkoutStatus] = useViewFirstAvailableCheckoutByCustomerId({ customerId });
21
- const firstItemWithoutCustomerDecision: CheckoutItemProjection | undefined = checkout?.items.find((item) =>
22
- [CheckoutItemStatus.EXPIRED, CheckoutItemStatus.INITIAL].includes(item.status),
23
- );
24
-
25
- const isIntroRoute = useMatch(Routes.INTRO);
26
- const isItemRoute = useMatch(Routes.ITEM);
27
- const isSummaryRoute = useMatch(Routes.SUMMARY);
28
-
29
- const dependenciesLoaded = checkoutIntroShownStatus === QueryStatus.SUCCESS && checkoutStatus === QueryStatus.SUCCESS;
30
-
31
- if (!dependenciesLoaded) {
32
- return loader;
33
- }
34
-
35
- if (checkoutIntroShown) {
36
- if (!isIntroRoute) {
37
- return <Navigate replace to={Routes.INTRO} />;
38
- }
39
- } else {
40
- if (firstItemWithoutCustomerDecision && !isItemRoute) {
41
- return <Navigate replace to={generatePath(Routes.ITEM, { id: firstItemWithoutCustomerDecision.id })} />;
42
- }
43
-
44
- if (firstItemWithoutCustomerDecision === undefined && !isSummaryRoute) {
45
- return <Navigate replace to={Routes.SUMMARY} />;
46
- }
47
- }
48
-
49
- return <Outlet />;
50
- };
51
-
52
- export { CheckoutMiddleware };
@@ -1,64 +0,0 @@
1
- import { FC, lazy, Suspense } from "react";
2
- import { Navigate, useRoutes } from "react-router-native";
3
- import { Spinner } from "../components/atoms/spiner/Spinner";
4
- import { CheckoutAccessibilityMiddleware } from "./CheckoutAccessibilityMiddleware";
5
- import { CheckoutMiddleware } from "./CheckoutMiddleware";
6
- import { Routes } from "./routes";
7
-
8
- const Intro = lazy(() => import("../views/intro/Intro").then((module) => ({ default: module.Intro })));
9
- const Item = lazy(() => import("../views/item/Item").then((module) => ({ default: module.Item })));
10
- const Summary = lazy(() => import("../views/summary/Summary").then((module) => ({ default: module.Summary })));
11
-
12
- interface RoutingProps {
13
- readonly customerId: string | undefined;
14
- readonly onNotAccessible: () => void;
15
- }
16
-
17
- const Routing: FC<RoutingProps> = ({ customerId, onNotAccessible }) => {
18
- const routes = useRoutes([
19
- {
20
- path: Routes.CHECKOUT,
21
- element: <CheckoutAccessibilityMiddleware customerId={customerId} onNotAccessible={onNotAccessible} />,
22
- children: [
23
- {
24
- path: Routes.CHECKOUT,
25
- element: <CheckoutMiddleware customerId={customerId as string} />,
26
- children: [
27
- {
28
- path: Routes.INTRO,
29
- element: (
30
- <Suspense fallback={<Spinner />}>
31
- <Intro />
32
- </Suspense>
33
- ),
34
- },
35
- {
36
- path: Routes.ITEM,
37
- element: (
38
- <Suspense fallback={<Spinner />}>
39
- <Item />
40
- </Suspense>
41
- ),
42
- },
43
- {
44
- path: Routes.SUMMARY,
45
- element: (
46
- <Suspense fallback={<Spinner />}>
47
- <Summary />
48
- </Suspense>
49
- ),
50
- },
51
- ],
52
- },
53
- ],
54
- },
55
- {
56
- path: "*",
57
- element: <Navigate replace to={Routes.CHECKOUT} />,
58
- },
59
- ]);
60
-
61
- return routes;
62
- };
63
-
64
- export { Routing };