@evenicanpm/storefront-core 1.7.0 → 1.8.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 (23) hide show
  1. package/package.json +4 -3
  2. package/src/components-v2/T/__tests__/T.test.tsx +91 -0
  3. package/src/components-v2/accordion/__tests__/accordion-header.test.tsx +28 -0
  4. package/src/components-v2/carousel/__tests__/carousel.test.tsx +208 -0
  5. package/src/components-v2/carousel-cards/carousel-card-1/__tests__/carousel-card-1.test.tsx +81 -0
  6. package/src/components-v2/categories/__tests__/category-menu.test.tsx +115 -0
  7. package/src/components-v2/flex-box/__tests__/flex-box.test.tsx +88 -0
  8. package/src/components-v2/header/__tests__/header.test.tsx +122 -0
  9. package/src/components-v2/icons/__tests__/icons.test.tsx +53 -0
  10. package/src/components-v2/mobile-navigation/__tests__/mobile-navigation-bar.test.tsx +94 -0
  11. package/src/components-v2/nav-link/__tests__/nav-link.test.tsx +75 -0
  12. package/src/components-v2/navbar/__tests__/navbar.test.tsx +96 -0
  13. package/src/components-v2/product-cards/__tests__/product-cards.test.tsx +91 -0
  14. package/src/components-v2/product-dialog/__tests__/product-dialog.test.tsx +129 -0
  15. package/src/components-v2/product-dimensions/__tests__/product-dimensions.test.tsx +130 -0
  16. package/src/components-v2/product-quantity-buttons/__tests__/product-quantity-buttons.test.tsx +77 -0
  17. package/src/components-v2/product-quantity-variants/__tests__/product-quantity-variants.test.tsx +109 -0
  18. package/src/components-v2/products-view/__tests__/products-view.test.tsx +147 -0
  19. package/src/components-v2/progress/__tests__/progress.test.tsx +62 -0
  20. package/src/components-v2/scrollbar/__tests__/scrollbar.test.tsx +93 -0
  21. package/src/components-v2/search-bar/__tests__/search-bar.test.tsx +142 -0
  22. package/src/components-v2/section/__tests__/section.test.tsx +100 -0
  23. package/src/components-v2/side-nav/__tests__/side-nav.test.tsx +156 -0
@@ -0,0 +1,130 @@
1
+ import { render } from "@testing-library/react";
2
+ import type { ReactNode } from "react";
3
+ import { vi } from "vitest";
4
+ import ProductDimensions from "../index";
5
+ import type { ProductDimensionValueInventoryAvailability } from "@msdyn365-commerce/retail-proxy";
6
+
7
+ vi.mock("next-intl", () => ({
8
+ useTranslations: () => (key: string) => key,
9
+ }));
10
+
11
+ vi.mock(
12
+ "@evenicanpm/storefront-core/src/components-v2/product-dimensions/compound/dimensions",
13
+ () => ({
14
+ Dimensions: Object.assign(
15
+ ({ children }: { children: ReactNode }) => (
16
+ <div data-testid="dimensions">{children}</div>
17
+ ),
18
+ {
19
+ Group: Object.assign(
20
+ ({ children }: { children: ReactNode }) => (
21
+ <div data-testid="dimension-group">{children}</div>
22
+ ),
23
+ {
24
+ Label: () => <div data-testid="dimension-label">Dimension</div>,
25
+ List: () => (
26
+ <ul data-testid="dimension-list">
27
+ <li>Value</li>
28
+ </ul>
29
+ ),
30
+ Error: () => <div data-testid="dimension-error">Error</div>,
31
+ },
32
+ ),
33
+ },
34
+ ),
35
+ }),
36
+ );
37
+
38
+ describe("ProductDimensions", () => {
39
+ const mockDimension: ProductDimensionValueInventoryAvailability = {
40
+ DimensionTypeValue: 1,
41
+ DimensionValue: {
42
+ RecordId: 1,
43
+ Value: "Red",
44
+ },
45
+ };
46
+
47
+ const mockDimensionGroups: ProductDimensionValueInventoryAvailability[][] = [
48
+ [mockDimension],
49
+ ];
50
+
51
+ const mockSelectDimensions: Record<
52
+ number,
53
+ ProductDimensionValueInventoryAvailability
54
+ > = {};
55
+
56
+ const mockHandleChangeVariant = vi.fn();
57
+
58
+ it("renders product dimensions", () => {
59
+ const { container } = render(
60
+ <ProductDimensions
61
+ dimensionGroups={mockDimensionGroups}
62
+ selectDimensions={mockSelectDimensions}
63
+ handleChangeVariant={mockHandleChangeVariant}
64
+ />,
65
+ );
66
+ expect(container.querySelector("[data-testid='dimensions']")).toBeTruthy();
67
+ });
68
+
69
+ it("renders multiple dimension groups", () => {
70
+ const multipleDimensions: ProductDimensionValueInventoryAvailability[][] = [
71
+ [mockDimension],
72
+ [{ ...mockDimension, DimensionValue: { RecordId: 2, Value: "Large" } }],
73
+ ];
74
+
75
+ const { container } = render(
76
+ <ProductDimensions
77
+ dimensionGroups={multipleDimensions}
78
+ selectDimensions={mockSelectDimensions}
79
+ handleChangeVariant={mockHandleChangeVariant}
80
+ />,
81
+ );
82
+ expect(container.querySelector("[data-testid='dimensions']")).toBeTruthy();
83
+ });
84
+
85
+ it("passes handleChangeVariant callback", () => {
86
+ const { container } = render(
87
+ <ProductDimensions
88
+ dimensionGroups={mockDimensionGroups}
89
+ selectDimensions={mockSelectDimensions}
90
+ handleChangeVariant={mockHandleChangeVariant}
91
+ />,
92
+ );
93
+ expect(container.firstChild).toBeTruthy();
94
+ });
95
+
96
+ it("shows dimension error when provided", () => {
97
+ const { container } = render(
98
+ <ProductDimensions
99
+ dimensionGroups={mockDimensionGroups}
100
+ selectDimensions={mockSelectDimensions}
101
+ handleChangeVariant={mockHandleChangeVariant}
102
+ showDimensionError={true}
103
+ />,
104
+ );
105
+ expect(container.firstChild).toBeTruthy();
106
+ });
107
+
108
+ it("renders with selected dimensions", () => {
109
+ const selectedDimensions = { 0: mockDimension };
110
+ const { container } = render(
111
+ <ProductDimensions
112
+ dimensionGroups={mockDimensionGroups}
113
+ selectDimensions={selectedDimensions}
114
+ handleChangeVariant={mockHandleChangeVariant}
115
+ />,
116
+ );
117
+ expect(container.querySelector("[data-testid='dimensions']")).toBeTruthy();
118
+ });
119
+
120
+ it("renders empty dimension groups", () => {
121
+ const { container } = render(
122
+ <ProductDimensions
123
+ dimensionGroups={[]}
124
+ selectDimensions={mockSelectDimensions}
125
+ handleChangeVariant={mockHandleChangeVariant}
126
+ />,
127
+ );
128
+ expect(container.firstChild).toBeTruthy();
129
+ });
130
+ });
@@ -0,0 +1,77 @@
1
+ import { render } from "@testing-library/react";
2
+ import type { ReactNode } from "react";
3
+ import { vi } from "vitest";
4
+ import ProductQuantityButtons from "../index";
5
+
6
+ vi.mock("next-intl", () => ({
7
+ useTranslations: () => (key: string) => key,
8
+ }));
9
+
10
+ vi.mock(
11
+ "@evenicanpm/storefront-core/src/components-v2/product-quantity-buttons/compound/quantity-buttons-root",
12
+ () => ({
13
+ QuantityButtons: Object.assign(
14
+ ({ children }: { children: ReactNode }) => (
15
+ <div data-testid="quantity-buttons">{children}</div>
16
+ ),
17
+ {
18
+ Remove: () => (
19
+ <button type="button" data-testid="quantity-remove">
20
+ -
21
+ </button>
22
+ ),
23
+ Quantity: () => <div data-testid="quantity-display">1</div>,
24
+ Add: () => (
25
+ <button type="button" data-testid="quantity-add">
26
+ +
27
+ </button>
28
+ ),
29
+ },
30
+ ),
31
+ }),
32
+ );
33
+
34
+ describe("ProductQuantityButtons", () => {
35
+ const mockProps = {
36
+ productId: 1 as number | undefined,
37
+ };
38
+
39
+ it("renders quantity buttons", () => {
40
+ const { container } = render(<ProductQuantityButtons {...mockProps} />);
41
+ expect(
42
+ container.querySelector("[data-testid='quantity-buttons']"),
43
+ ).toBeTruthy();
44
+ });
45
+
46
+ it("renders composition structure", () => {
47
+ const { container } = render(<ProductQuantityButtons {...mockProps} />);
48
+ expect(
49
+ container.querySelector("[data-testid='quantity-buttons']"),
50
+ ).toBeTruthy();
51
+ expect(container.firstChild).toBeTruthy();
52
+ });
53
+
54
+ it("accepts custom quantity value", () => {
55
+ const { container } = render(<ProductQuantityButtons productId={5} />);
56
+ expect(container.firstChild).toBeTruthy();
57
+ });
58
+
59
+ it("handles quantity change", () => {
60
+ const { container } = render(<ProductQuantityButtons {...mockProps} />);
61
+ expect(container.firstChild).toBeTruthy();
62
+ });
63
+
64
+ it("renders with undefined productId", () => {
65
+ const { container } = render(
66
+ <ProductQuantityButtons productId={undefined} />,
67
+ );
68
+ expect(container.firstChild).toBeTruthy();
69
+ });
70
+
71
+ it("renders with minimum quantity", () => {
72
+ const { container } = render(<ProductQuantityButtons {...mockProps} />);
73
+ expect(
74
+ container.querySelector("[data-testid='quantity-buttons']"),
75
+ ).toBeTruthy();
76
+ });
77
+ });
@@ -0,0 +1,109 @@
1
+ import { render, screen } from "@testing-library/react";
2
+ import { vi } from "vitest";
3
+ import QuantityVariantsSelect from "../index";
4
+ import type { ProductDetails } from "@evenicanpm/storefront-core/src/api-manager/schemas/product.schema";
5
+
6
+ vi.mock("next-intl", () => ({
7
+ useTranslations: () => (key: string) => key,
8
+ }));
9
+
10
+ vi.mock("@evenicanpm/storefront-core/src/hooks/use-variants", () => ({
11
+ default: () => ({
12
+ selectedVariant: { RecordId: 1 },
13
+ selectDimensions: {},
14
+ handleChangeVariant: vi.fn(),
15
+ allDimensionsSelected: true,
16
+ }),
17
+ }));
18
+
19
+ vi.mock("@evenicanpm/storefront-core/src/hooks/use-cart", () => ({
20
+ default: () => ({ handleAddToCart: vi.fn() }),
21
+ }));
22
+
23
+ vi.mock(
24
+ "@evenicanpm/storefront-core/src/api-manager/services/product/queries/get-product-availability",
25
+ () => ({
26
+ default: {
27
+ useData: vi.fn(() => ({ data: { OrgUnitAvailabilities: [] } })),
28
+ },
29
+ }),
30
+ );
31
+
32
+ vi.mock(
33
+ "@evenicanpm/storefront-core/src/components-v2/product-dimensions",
34
+ () => ({
35
+ default: () => <div data-testid="dimensions">Dimensions</div>,
36
+ }),
37
+ );
38
+
39
+ vi.mock(
40
+ "@evenicanpm/storefront-core/src/components-v2/product-quantity-buttons",
41
+ () => ({
42
+ default: () => <div data-testid="quantity-buttons">Quantity</div>,
43
+ }),
44
+ );
45
+
46
+ describe("QuantityVariantsSelect", () => {
47
+ const mockProduct: ProductDetails = {
48
+ RecordId: 1,
49
+ Name: "Test Product",
50
+ Description: "Test",
51
+ ProductTypeValue: 0,
52
+ BasePrice: 99.99,
53
+ DimensionValues: [],
54
+ Price: 99.99,
55
+ AdjustedPrice: 79.99,
56
+ Attributes: [],
57
+ Images: [],
58
+ };
59
+
60
+ it("renders quantity variants select", () => {
61
+ render(<QuantityVariantsSelect product={mockProduct} />);
62
+ expect(screen.getByTestId("dimensions")).toBeInTheDocument();
63
+ expect(screen.getByTestId("quantity-buttons")).toBeInTheDocument();
64
+ });
65
+
66
+ it("displays both dimensions and quantity components", () => {
67
+ const { container } = render(
68
+ <QuantityVariantsSelect product={mockProduct} />,
69
+ );
70
+ expect(
71
+ container.querySelector("[data-testid='dimensions']"),
72
+ ).toBeInTheDocument();
73
+ expect(
74
+ container.querySelector("[data-testid='quantity-buttons']"),
75
+ ).toBeInTheDocument();
76
+ });
77
+
78
+ it("handles product with variants", () => {
79
+ const productWithVariants: ProductDetails = {
80
+ ...mockProduct,
81
+ DimensionValues: [
82
+ [
83
+ {
84
+ DimensionTypeValue: 1,
85
+ DimensionValue: { RecordId: 1, Value: "Red" },
86
+ },
87
+ ],
88
+ ],
89
+ };
90
+
91
+ render(<QuantityVariantsSelect product={productWithVariants} />);
92
+ expect(screen.getByTestId("dimensions")).toBeInTheDocument();
93
+ });
94
+
95
+ it("renders with different products", () => {
96
+ const { rerender } = render(
97
+ <QuantityVariantsSelect product={mockProduct} />,
98
+ );
99
+ expect(screen.getByTestId("dimensions")).toBeInTheDocument();
100
+
101
+ const anotherProduct: ProductDetails = {
102
+ ...mockProduct,
103
+ RecordId: 2,
104
+ Name: "Another Product",
105
+ };
106
+ rerender(<QuantityVariantsSelect product={anotherProduct} />);
107
+ expect(screen.getByTestId("dimensions")).toBeInTheDocument();
108
+ });
109
+ });
@@ -0,0 +1,147 @@
1
+ import { render } from "@testing-library/react";
2
+ import { vi } from "vitest";
3
+ import { ProductsGrid, ProductsList } from "../index";
4
+ import type { ProductSearchResult as Product } from "@msdyn365-commerce/retail-proxy";
5
+
6
+ vi.mock("next-intl", () => ({
7
+ useTranslations: () => (key: string) => key,
8
+ }));
9
+
10
+ vi.mock(
11
+ "@evenicanpm/storefront-core/src/components-v2/products-view/compound/products-grid-view",
12
+ () => ({
13
+ default: Object.assign(
14
+ ({ children }: any) => (
15
+ <div data-testid="products-grid-view">{children}</div>
16
+ ),
17
+ {
18
+ Grid: ({ children }: any) => (
19
+ <div data-testid="products-grid">{children}</div>
20
+ ),
21
+ Card: () => <div data-testid="product-card">Card</div>,
22
+ },
23
+ ),
24
+ }),
25
+ );
26
+
27
+ vi.mock(
28
+ "@evenicanpm/storefront-core/src/components-v2/products-view/compound/products-list-view",
29
+ () => ({
30
+ default: Object.assign(
31
+ ({ children }: any) => (
32
+ <div data-testid="products-list-view">{children}</div>
33
+ ),
34
+ {
35
+ List: ({ children }: any) => (
36
+ <div data-testid="products-list">{children}</div>
37
+ ),
38
+ Card: () => <div data-testid="product-card">Card</div>,
39
+ },
40
+ ),
41
+ }),
42
+ );
43
+
44
+ describe("ProductsView components", () => {
45
+ const mockProducts: Product[] = [
46
+ {
47
+ RecordId: 1,
48
+ Name: "Product 1",
49
+ } as Product,
50
+ {
51
+ RecordId: 2,
52
+ Name: "Product 2",
53
+ } as Product,
54
+ ];
55
+
56
+ describe("ProductsGrid", () => {
57
+ it("renders products grid view", () => {
58
+ const { container } = render(<ProductsGrid products={mockProducts} />);
59
+ expect(
60
+ container.querySelector("[data-testid='products-grid-view']"),
61
+ ).toBeTruthy();
62
+ });
63
+
64
+ it("renders with pagination", () => {
65
+ const { container } = render(
66
+ <ProductsGrid
67
+ products={mockProducts}
68
+ pagination={<div>Pagination</div>}
69
+ />,
70
+ );
71
+ expect(container.firstChild).toBeTruthy();
72
+ });
73
+
74
+ it("renders with product prices", () => {
75
+ const prices = [{ price: 100, adjustedPrice: 80, productId: 1 }];
76
+ const { container } = render(
77
+ <ProductsGrid products={mockProducts} productPrices={prices as any} />,
78
+ );
79
+ expect(
80
+ container.querySelector("[data-testid='products-grid-view']"),
81
+ ).toBeTruthy();
82
+ });
83
+
84
+ it("renders empty products list", () => {
85
+ const { container } = render(<ProductsGrid products={[]} />);
86
+ expect(container.firstChild).toBeTruthy();
87
+ });
88
+
89
+ it("renders multiple products", () => {
90
+ const manyProducts = Array.from({ length: 10 }, (_, i) => ({
91
+ RecordId: i + 1,
92
+ Name: `Product ${i + 1}`,
93
+ })) as Product[];
94
+
95
+ const { container } = render(<ProductsGrid products={manyProducts} />);
96
+ expect(
97
+ container.querySelector("[data-testid='products-grid-view']"),
98
+ ).toBeTruthy();
99
+ });
100
+ });
101
+
102
+ describe("ProductsList", () => {
103
+ it("renders products list view", () => {
104
+ const { container } = render(<ProductsList products={mockProducts} />);
105
+ expect(
106
+ container.querySelector("[data-testid='products-list-view']"),
107
+ ).toBeTruthy();
108
+ });
109
+
110
+ it("renders with pagination", () => {
111
+ const { container } = render(
112
+ <ProductsList
113
+ products={mockProducts}
114
+ pagination={<div>Pagination</div>}
115
+ />,
116
+ );
117
+ expect(container.firstChild).toBeTruthy();
118
+ });
119
+
120
+ it("renders with product prices", () => {
121
+ const prices = [{ price: 100, adjustedPrice: 80, productId: 1 }];
122
+ const { container } = render(
123
+ <ProductsList products={mockProducts} productPrices={prices as any} />,
124
+ );
125
+ expect(
126
+ container.querySelector("[data-testid='products-list-view']"),
127
+ ).toBeTruthy();
128
+ });
129
+
130
+ it("renders empty products list", () => {
131
+ const { container } = render(<ProductsList products={[]} />);
132
+ expect(container.firstChild).toBeTruthy();
133
+ });
134
+
135
+ it("renders multiple products in list format", () => {
136
+ const manyProducts = Array.from({ length: 10 }, (_, i) => ({
137
+ RecordId: i + 1,
138
+ Name: `Product ${i + 1}`,
139
+ })) as Product[];
140
+
141
+ const { container } = render(<ProductsList products={manyProducts} />);
142
+ expect(
143
+ container.querySelector("[data-testid='products-list-view']"),
144
+ ).toBeTruthy();
145
+ });
146
+ });
147
+ });
@@ -0,0 +1,62 @@
1
+ import { render } from "@testing-library/react";
2
+ import { vi } from "vitest";
3
+
4
+ vi.mock("nprogress", () => ({
5
+ default: {
6
+ configure: vi.fn(),
7
+ start: vi.fn(),
8
+ done: vi.fn(),
9
+ },
10
+ }));
11
+
12
+ vi.mock("@mui/material/GlobalStyles", () => ({
13
+ default: () => <div data-testid="global-styles" />,
14
+ }));
15
+
16
+ vi.mock("@mui/material/styles/useTheme", () => ({
17
+ default: () => ({
18
+ palette: {
19
+ primary: { main: "#1976d2" },
20
+ },
21
+ }),
22
+ }));
23
+
24
+ import ProgressBar from "../progress";
25
+
26
+ describe("ProgressBar", () => {
27
+ it("renders progress bar component", () => {
28
+ const { container } = render(<ProgressBar />);
29
+ expect(container.firstChild).toBeTruthy();
30
+ });
31
+
32
+ it("renders without crashing", () => {
33
+ const { container } = render(<ProgressBar />);
34
+ expect(container.querySelectorAll("*").length).toBeGreaterThan(0);
35
+ });
36
+
37
+ it("initializes observer setup", () => {
38
+ const { container } = render(<ProgressBar />);
39
+ expect(container.firstChild).toBeTruthy();
40
+ });
41
+
42
+ it("handles anchor click events", () => {
43
+ const { container } = render(<ProgressBar />);
44
+ expect(container.firstChild).toBeTruthy();
45
+ });
46
+
47
+ it("configures NProgress", () => {
48
+ render(<ProgressBar />);
49
+ expect(true).toBe(true);
50
+ });
51
+
52
+ it("cleans up on unmount", () => {
53
+ const { unmount } = render(<ProgressBar />);
54
+ unmount();
55
+ expect(true).toBe(true);
56
+ });
57
+
58
+ it("integrates with theme", () => {
59
+ const { container } = render(<ProgressBar />);
60
+ expect(container.firstChild).toBeTruthy();
61
+ });
62
+ });
@@ -0,0 +1,93 @@
1
+ import { render, screen } from "@testing-library/react";
2
+ import { vi } from "vitest";
3
+ import Scrollbar from "../scrollbar";
4
+
5
+ vi.mock("simplebar-react", () => ({
6
+ default: ({ children, autoHide, ...props }: any) => (
7
+ <div data-testid="custom-scrollbar" data-autohide={autoHide} {...props}>
8
+ {children}
9
+ </div>
10
+ ),
11
+ }));
12
+
13
+ describe("Scrollbar", () => {
14
+ it("renders scrollbar with children", () => {
15
+ render(
16
+ <Scrollbar>
17
+ <div>Content</div>
18
+ </Scrollbar>,
19
+ );
20
+ expect(screen.getByText("Content")).toBeInTheDocument();
21
+ });
22
+
23
+ it("renders custom scrollbar component", () => {
24
+ const { container } = render(
25
+ <Scrollbar>
26
+ <div>Scrollable Content</div>
27
+ </Scrollbar>,
28
+ );
29
+ expect(
30
+ container.querySelector("[data-testid='custom-scrollbar']"),
31
+ ).toBeTruthy();
32
+ });
33
+
34
+ it("applies autoHide prop by default", () => {
35
+ const { container } = render(
36
+ <Scrollbar>
37
+ <div>Content</div>
38
+ </Scrollbar>,
39
+ );
40
+ const scrollbar = container.querySelector(
41
+ "[data-testid='custom-scrollbar']",
42
+ );
43
+ expect(scrollbar?.getAttribute("data-autohide")).toBe("true");
44
+ });
45
+
46
+ it("respects autoHide false setting", () => {
47
+ const { container } = render(
48
+ <Scrollbar autoHide={false}>
49
+ <div>Content</div>
50
+ </Scrollbar>,
51
+ );
52
+ const scrollbar = container.querySelector(
53
+ "[data-testid='custom-scrollbar']",
54
+ );
55
+ expect(scrollbar?.getAttribute("data-autohide")).toBe("false");
56
+ });
57
+
58
+ it("accepts custom sx props", () => {
59
+ const { container } = render(
60
+ <Scrollbar sx={{ height: 200 }}>
61
+ <div>Content</div>
62
+ </Scrollbar>,
63
+ );
64
+ expect(
65
+ container.querySelector("[data-testid='custom-scrollbar']"),
66
+ ).toBeTruthy();
67
+ });
68
+
69
+ it("passes additional props to SimpleBar", () => {
70
+ const { container } = render(
71
+ <Scrollbar data-custom="test">
72
+ <div>Content</div>
73
+ </Scrollbar>,
74
+ );
75
+ const scrollbar = container.querySelector(
76
+ "[data-testid='custom-scrollbar']",
77
+ );
78
+ expect(scrollbar?.getAttribute("data-custom")).toBe("test");
79
+ });
80
+
81
+ it("renders multiple children", () => {
82
+ render(
83
+ <Scrollbar>
84
+ <div>Content 1</div>
85
+ <div>Content 2</div>
86
+ <div>Content 3</div>
87
+ </Scrollbar>,
88
+ );
89
+ expect(screen.getByText("Content 1")).toBeInTheDocument();
90
+ expect(screen.getByText("Content 2")).toBeInTheDocument();
91
+ expect(screen.getByText("Content 3")).toBeInTheDocument();
92
+ });
93
+ });