@blaze-cms/react-page-builder 0.146.0-node18-tooltips.32 → 0.146.0-node18-core-styles-tooltips.41

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 (65) hide show
  1. package/CHANGELOG.md +110 -32
  2. package/lib/components/Carousel/Carousel.js +44 -7
  3. package/lib/components/Carousel/Carousel.js.map +1 -1
  4. package/lib/components/Carousel/CarouselImage/CarouselImage.js +2 -1
  5. package/lib/components/Carousel/CarouselImage/CarouselImage.js.map +1 -1
  6. package/lib/components/Menu/Menu.js +4 -1
  7. package/lib/components/Menu/Menu.js.map +1 -1
  8. package/lib/components/Menu/MenuContext.js +2 -1
  9. package/lib/components/Menu/MenuContext.js.map +1 -1
  10. package/lib/components/MenuItem/MenuItemRender.js +27 -12
  11. package/lib/components/MenuItem/MenuItemRender.js.map +1 -1
  12. package/lib/components/MenuItem/helpers/has-active-child.js +19 -0
  13. package/lib/components/MenuItem/helpers/has-active-child.js.map +1 -0
  14. package/lib/components/MenuItem/helpers/index.js +14 -0
  15. package/lib/components/MenuItem/helpers/index.js.map +1 -1
  16. package/lib/components/MenuItem/helpers/isUrlPathMatch.js +18 -0
  17. package/lib/components/MenuItem/helpers/isUrlPathMatch.js.map +1 -0
  18. package/lib/components/SearchContent/SearchContent.js +4 -2
  19. package/lib/components/SearchContent/SearchContent.js.map +1 -1
  20. package/lib/components/SearchContent/SearchContentResults.js +2 -1
  21. package/lib/components/SearchContent/SearchContentResults.js.map +1 -1
  22. package/lib/hooks/use-get-image-id-from-relation.js +4 -3
  23. package/lib/hooks/use-get-image-id-from-relation.js.map +1 -1
  24. package/lib-es/components/Carousel/Carousel.js +39 -9
  25. package/lib-es/components/Carousel/Carousel.js.map +1 -1
  26. package/lib-es/components/Carousel/CarouselImage/CarouselImage.js +2 -1
  27. package/lib-es/components/Carousel/CarouselImage/CarouselImage.js.map +1 -1
  28. package/lib-es/components/Menu/Menu.js +4 -1
  29. package/lib-es/components/Menu/Menu.js.map +1 -1
  30. package/lib-es/components/Menu/MenuContext.js +2 -1
  31. package/lib-es/components/Menu/MenuContext.js.map +1 -1
  32. package/lib-es/components/MenuItem/MenuItemRender.js +25 -11
  33. package/lib-es/components/MenuItem/MenuItemRender.js.map +1 -1
  34. package/lib-es/components/MenuItem/helpers/has-active-child.js +5 -0
  35. package/lib-es/components/MenuItem/helpers/has-active-child.js.map +1 -0
  36. package/lib-es/components/MenuItem/helpers/index.js +3 -1
  37. package/lib-es/components/MenuItem/helpers/index.js.map +1 -1
  38. package/lib-es/components/MenuItem/helpers/isUrlPathMatch.js +8 -0
  39. package/lib-es/components/MenuItem/helpers/isUrlPathMatch.js.map +1 -0
  40. package/lib-es/components/SearchContent/SearchContent.js +8 -2
  41. package/lib-es/components/SearchContent/SearchContent.js.map +1 -1
  42. package/lib-es/components/SearchContent/SearchContentResults.js +2 -1
  43. package/lib-es/components/SearchContent/SearchContentResults.js.map +1 -1
  44. package/lib-es/hooks/use-get-image-id-from-relation.js +2 -2
  45. package/lib-es/hooks/use-get-image-id-from-relation.js.map +1 -1
  46. package/package.json +10 -10
  47. package/src/components/Carousel/Carousel.js +46 -9
  48. package/src/components/Carousel/CarouselImage/CarouselImage.js +3 -1
  49. package/src/components/Menu/Menu.js +3 -1
  50. package/src/components/Menu/MenuContext.js +1 -1
  51. package/src/components/MenuItem/MenuItemRender.js +40 -12
  52. package/src/components/MenuItem/helpers/has-active-child.js +10 -0
  53. package/src/components/MenuItem/helpers/index.js +3 -1
  54. package/src/components/MenuItem/helpers/isUrlPathMatch.js +10 -0
  55. package/src/components/SearchContent/SearchContent.js +8 -2
  56. package/src/components/SearchContent/SearchContentResults.js +1 -1
  57. package/src/hooks/use-get-image-id-from-relation.js +2 -1
  58. package/tests/unit/src/components/Carousel/Carousel.test.js +45 -35
  59. package/tests/unit/src/components/Carousel/__snapshots__/Carousel.test.js.snap +49 -8
  60. package/tests/unit/src/components/MenuItem/MenuItem.test.js +5 -0
  61. package/tests/unit/src/components/MenuItem/MenuItemRender.test.js +11 -3
  62. package/tests/unit/src/components/MenuItem/helpers/constants.js +73 -0
  63. package/tests/unit/src/components/MenuItem/helpers/has-active-child.test.js +35 -0
  64. package/tests/unit/src/components/MenuItem/helpers/is-url-path-match.test.js +53 -0
  65. package/tests/unit/src/components/SearchContent/SearchContent.test.js +32 -1
@@ -1,17 +1,23 @@
1
+ /* eslint-disable jsx-a11y/no-static-element-interactions */
1
2
  import React, { useState, useContext, useEffect } from 'react';
2
3
  import PropTypes from 'prop-types';
3
4
  import { FaChevronDown, FaChevronUp } from 'react-icons/fa';
5
+ import classnames from 'classnames';
4
6
  import { useRouter } from 'next/router';
5
7
  import { useStringTemplate } from '@blaze-cms/utils-handlebars';
6
- import { HOVER, MOUSE_ENTER, MOUSE_LEAVE, HIDDEN } from '../../constants';
8
+ import { HOVER, MOUSE_ENTER, MOUSE_LEAVE, HIDDEN, CLICK } from '../../constants';
7
9
  import { hasChildren } from '../../helpers';
8
10
  import BlazeLink from '../BlazeLink';
9
11
  import MenuContext from '../Menu/MenuContext';
10
- import { injectHelperIntoTemplate } from './helpers';
12
+ import { injectHelperIntoTemplate, isUrlPathMatch, hasActiveChild } from './helpers';
11
13
 
12
14
  const MenuItemRender = ({ children, eventType, text, modifier, url, parent }) => {
13
- const [displayChildren, setDisplayChildren] = useState(false);
14
- const { showMobileMenu } = useContext(MenuContext);
15
+ const router = useRouter();
16
+ const { showMobileMenu, openActiveSubmenus } = useContext(MenuContext);
17
+
18
+ const isHoverEvent = eventType === HOVER;
19
+ const isClickEvent = eventType === CLICK;
20
+
15
21
  const {
16
22
  loading: loadingText,
17
23
  data: [textToUse]
@@ -21,14 +27,24 @@ const MenuItemRender = ({ children, eventType, text, modifier, url, parent }) =>
21
27
  data: [urlToUse]
22
28
  } = useStringTemplate(parent, [injectHelperIntoTemplate(url, 'url_encode')]);
23
29
 
24
- const router = useRouter();
25
- const isHoverEvent = eventType === HOVER;
26
- const childrenDisplayClass = displayChildren ? '' : HIDDEN;
30
+ const isActive = router ? isUrlPathMatch(router.asPath, urlToUse) : false;
31
+ const isActiveParent = router ? hasActiveChild(router.asPath, children) : false;
32
+ const shouldPreOpen = openActiveSubmenus && isActiveParent && isClickEvent;
27
33
  const hasValidChildren = hasChildren(children);
28
34
 
35
+ const [displayChildren, setDisplayChildren] = useState(shouldPreOpen);
36
+
29
37
  useEffect(() => {
30
- if (!showMobileMenu) setDisplayChildren(false);
31
- }, [showMobileMenu]);
38
+ if (!showMobileMenu && !shouldPreOpen) setDisplayChildren(false);
39
+ }, [
40
+ children,
41
+ isClickEvent,
42
+ loadingUrl,
43
+ openActiveSubmenus,
44
+ router,
45
+ shouldPreOpen,
46
+ showMobileMenu
47
+ ]);
32
48
 
33
49
  useEffect(() => {
34
50
  if (isHoverEvent) {
@@ -38,6 +54,8 @@ const MenuItemRender = ({ children, eventType, text, modifier, url, parent }) =>
38
54
 
39
55
  if (loadingUrl || loadingText) return '';
40
56
 
57
+ const childrenDisplayClass = displayChildren ? '' : HIDDEN;
58
+
41
59
  const handleItemEvent = ({ type }) => {
42
60
  if (isHoverEvent) {
43
61
  if (type === MOUSE_ENTER) {
@@ -55,15 +73,25 @@ const MenuItemRender = ({ children, eventType, text, modifier, url, parent }) =>
55
73
  }
56
74
  };
57
75
 
76
+ const menuItemLinkClassname = classnames('menu--item--link', {
77
+ 'menu--item--link--active': isActive,
78
+ 'menu--item--link--active-parent': isActiveParent
79
+ });
80
+
58
81
  return (
59
82
  <li className={modifier} onMouseEnter={handleItemEvent} onMouseLeave={handleItemEvent}>
60
83
  <div
61
- className="menu--item--link"
84
+ className={menuItemLinkClassname}
62
85
  onClick={handleMobileClick}
63
86
  role={!urlToUse && hasValidChildren ? 'button' : undefined}
64
87
  tabIndex={!urlToUse && hasValidChildren ? 0 : undefined}>
65
- {urlToUse ? <BlazeLink href={urlToUse}>{textToUse}</BlazeLink> : <span>{textToUse}</span>}
66
-
88
+ {urlToUse ? (
89
+ <BlazeLink href={urlToUse}>{textToUse}</BlazeLink>
90
+ ) : (
91
+ <span role="button" onClick={handleItemEvent}>
92
+ {textToUse}
93
+ </span>
94
+ )}
67
95
  {hasValidChildren && (
68
96
  <i
69
97
  role="button"
@@ -0,0 +1,10 @@
1
+ import isUrlPathMatch from './isUrlPathMatch';
2
+ import { hasChildren } from '../../../helpers';
3
+
4
+ const hasActiveChild = (path, children) =>
5
+ hasChildren(children) &&
6
+ children.props.children[1][0].props.component.items.find(menuItem =>
7
+ isUrlPathMatch(path, menuItem.settings.url)
8
+ );
9
+
10
+ export default hasActiveChild;
@@ -1,3 +1,5 @@
1
1
  import injectHelperIntoTemplate from './inject-helper-into-template';
2
+ import isUrlPathMatch from './isUrlPathMatch';
3
+ import hasActiveChild from './has-active-child';
2
4
 
3
- export { injectHelperIntoTemplate };
5
+ export { injectHelperIntoTemplate, isUrlPathMatch, hasActiveChild };
@@ -0,0 +1,10 @@
1
+ const isUrlPathMatch = (path, itemUrl) => {
2
+ if (!itemUrl || !path) return false;
3
+
4
+ const reg = new RegExp(/^[^#?]+/);
5
+ const _path = reg.exec(path)[0];
6
+
7
+ return _path === itemUrl || _path === `/${itemUrl}`;
8
+ };
9
+
10
+ export default isUrlPathMatch;
@@ -121,9 +121,15 @@ const SearchContent = props => {
121
121
  name="search"
122
122
  placeholder={placeholder}
123
123
  value={searchTerm}
124
- onChange={e => setSearchTerm(e.target.value)}
124
+ onChange={e => {
125
+ setSearchTerm(e.target.value);
126
+ setShowResults(true);
127
+ }}
125
128
  onKeyDown={handleKeyDown}
126
- onFocus={() => setShowResults(true)}
129
+ onFocus={() => {
130
+ setShowResults(true);
131
+ if (collapsedSearch) setCollapsed(false);
132
+ }}
127
133
  data-testid="search-content-input"
128
134
  />
129
135
  )}
@@ -6,7 +6,7 @@ const SearchContentResults = ({ results, debouncedSearchTerm, onClick }) => {
6
6
  if (!debouncedSearchTerm) return null;
7
7
  const hasResults = results.length > 0;
8
8
  return (
9
- <div className="search-content--results__wrapper">
9
+ <div className="search-content--results__wrapper" data-testid="search-content-results">
10
10
  <div className="search-content--results__wrapper--message">
11
11
  <div className="search-content--results__content">
12
12
  {hasResults ? (
@@ -10,6 +10,7 @@ function useGetImageIdFromRelation(
10
10
  hasImgSrc
11
11
  ) {
12
12
  const skip =
13
+ !actions ||
13
14
  !id ||
14
15
  hasImgSrc ||
15
16
  typeof id !== 'string' ||
@@ -18,7 +19,7 @@ function useGetImageIdFromRelation(
18
19
 
19
20
  const [imageRelationData = ''] = imageRelation;
20
21
  const [relationName = '', relationProp = ''] = imageRelationData.split('.');
21
- const { getPublished, get } = actions;
22
+ const { getPublished, get } = actions || {};
22
23
  const getAction = isPreview ? get : getPublished || get;
23
24
 
24
25
  const props = imageRelationData ? `${relationName} { ${relationProp} }` : 'id';
@@ -4,28 +4,35 @@
4
4
  import React from 'react';
5
5
  import '@testing-library/jest-dom/extend-expect';
6
6
  import { MockedProvider } from '@apollo/client/testing';
7
- import { render, screen, waitFor } from '@testing-library/react';
7
+ import { render, screen, act, waitFor } from '@testing-library/react';
8
+ import { MockedRoot } from '@blaze-cms/tools/test-helpers/test-functions';
8
9
  import { getFileById } from '../../../../../src/application/query';
9
10
  import Carousel from '../../../../../src/components/Carousel';
11
+ import { MOCK_RELATION } from '../Image/mocks';
10
12
 
11
13
  const imageId = 'test-id';
12
- const getMockedProps = overrides => ({
14
+ const getMockedProps = (overrides = {}) => ({
13
15
  imageIds: [imageId],
14
16
  enableLightbox: true,
15
17
  imageId,
16
18
  toggleModal: jest.fn(),
17
19
  handleSelectedImage: jest.fn(),
18
20
  displayCount: true,
21
+ entity: 'page',
22
+ imagesProperty: ['publishedPage.otherImageIds'],
23
+ parent: {
24
+ itemId: 'parentId',
25
+ getAction: 'getPublishedPage',
26
+ itemEntity: 'page'
27
+ },
19
28
  ...overrides
20
29
  });
21
30
 
22
- const mock = [
31
+ const mocks = [
23
32
  {
24
33
  request: {
25
34
  query: getFileById,
26
- variables: {
27
- id: imageId
28
- }
35
+ variables: { id: imageId }
29
36
  },
30
37
  result: {
31
38
  data: {
@@ -42,73 +49,76 @@ const mock = [
42
49
  }
43
50
  ];
44
51
 
45
- const MockedVariantComponent = () => <div>Variation component</div>;
46
-
47
- const setup = props => {
48
- const mockComponent = (
49
- <MockedProvider mocks={mock}>
52
+ const setup = props =>
53
+ render(
54
+ <MockedProvider mocks={mocks}>
50
55
  <Carousel {...props} />
51
56
  </MockedProvider>
52
57
  );
53
58
 
54
- return render(mockComponent);
59
+ const setupWithRoot = async (props, mockOverrides) => {
60
+ const component = (
61
+ <MockedRoot mocks={mockOverrides}>
62
+ <Carousel {...props} />
63
+ </MockedRoot>
64
+ );
65
+ let renderResults;
66
+ await act(async () => {
67
+ renderResults = render(component);
68
+ });
69
+ return renderResults;
55
70
  };
56
71
 
57
72
  describe('Carousel component', () => {
58
73
  it('should render loading state initially', async () => {
59
- const { container } = await setup(getMockedProps());
60
-
74
+ const { container } = setup(getMockedProps());
61
75
  expect(container.innerHTML).toContain('carousel');
62
76
  });
63
77
 
64
78
  it('should render carousel and match snapshot', async () => {
65
- const { asFragment } = await setup(getMockedProps());
66
-
67
- await waitFor(() => expect(asFragment()).toBeDefined());
68
-
79
+ const { asFragment } = setup(getMockedProps());
69
80
  await waitFor(() => expect(asFragment()).toMatchSnapshot());
70
81
  });
71
82
 
72
83
  it('should render priority images and match snapshot', async () => {
73
- const { asFragment, getAllByRole } = await setup(getMockedProps({ priorityLimit: 1 }));
74
-
75
- await waitFor(() => expect(asFragment()).toBeDefined());
76
-
84
+ const { asFragment, getAllByRole } = setup(getMockedProps({ priorityLimit: 1 }));
77
85
  await waitFor(() => expect(asFragment()).toMatchSnapshot());
78
- expect(getAllByRole('button').length).toEqual(3);
86
+ expect(getAllByRole('button')).toHaveLength(3);
79
87
  });
80
88
 
81
89
  it('should return null if there are no imageIds', () => {
82
- const mockedProps = getMockedProps({ imageIds: [] });
83
- const { container } = setup(mockedProps);
84
-
90
+ const { container } = setup(getMockedProps({ imageIds: [] }));
85
91
  expect(container.innerHTML).toBe('');
86
92
  });
87
93
 
94
+ it('should render image fetching data from relation', async () => {
95
+ const { asFragment, container } = await setupWithRoot(getMockedProps({ imageIds: [] }), [
96
+ ...MOCK_RELATION,
97
+ ...mocks
98
+ ]);
99
+ await waitFor(() => expect(container.childNodes.length).toBeGreaterThan(1));
100
+ expect(asFragment()).toMatchSnapshot();
101
+ });
102
+
88
103
  it('should display caption if shouldDisplayCaption is true', () => {
89
104
  const caption = 'caption test';
90
- const mockedProps = getMockedProps({ isCaptionDisplayed: true, caption });
91
-
92
- setup(mockedProps);
105
+ setup(getMockedProps({ isCaptionDisplayed: true, caption }));
93
106
  expect(screen.getByText(caption)).toBeInTheDocument();
94
107
  });
95
108
 
96
109
  it('should render VariantComponent if it is set', () => {
97
- const mockedProps = getMockedProps({ VariantComponent: MockedVariantComponent });
110
+ const mockedProps = getMockedProps({ VariantComponent: () => <div>Variation component</div> });
98
111
  const { container } = setup(mockedProps);
99
-
100
112
  expect(container.innerHTML).toBe('<div>Variation component</div>');
101
113
  });
102
114
 
103
115
  it('should display image count if displayCount is true', () => {
104
- const mockedProps = getMockedProps({ imageIds: ['id1', 'id2', 'id3'] });
105
- setup(mockedProps);
116
+ setup(getMockedProps({ imageIds: ['id1', 'id2', 'id3'] }));
106
117
  expect(screen.getByTestId('count')).toHaveTextContent('3 images');
107
118
  });
108
119
 
109
120
  it('should not display image count if displayCount is false', () => {
110
- const mockedProps = getMockedProps({ displayCount: false });
111
- setup(mockedProps);
121
+ setup(getMockedProps({ displayCount: false }));
112
122
  expect(screen.queryByTestId('count')).toBeNull();
113
123
  });
114
124
  });
@@ -43,6 +43,54 @@ exports[`Carousel component should render carousel and match snapshot 1`] = `
43
43
  </DocumentFragment>
44
44
  `;
45
45
 
46
+ exports[`Carousel component should render image fetching data from relation 1`] = `
47
+ <DocumentFragment>
48
+ <div
49
+ class="carousel"
50
+ >
51
+ <div>
52
+ <div
53
+ aria-label="Previous Slide"
54
+ class="carousel__button carousel__button--previous"
55
+ role="button"
56
+ >
57
+ <div
58
+ class="arrow arrow--left"
59
+ />
60
+ </div>
61
+ <div
62
+ class="carousel__list"
63
+ >
64
+ <div
65
+ class="carousel__slide"
66
+ >
67
+ <span />
68
+ </div>
69
+ <div
70
+ class="carousel__slide"
71
+ >
72
+ <span />
73
+ </div>
74
+ </div>
75
+ <div
76
+ aria-label="Next Slide"
77
+ class="carousel__button carousel__button--next"
78
+ role="button"
79
+ >
80
+ <p
81
+ data-testid="count"
82
+ >
83
+ 2 images
84
+ </p>
85
+ <div
86
+ class="arrow arrow--right"
87
+ />
88
+ </div>
89
+ </div>
90
+ </div>
91
+ </DocumentFragment>
92
+ `;
93
+
46
94
  exports[`Carousel component should render priority images and match snapshot 1`] = `
47
95
  <DocumentFragment>
48
96
  <div
@@ -64,14 +112,7 @@ exports[`Carousel component should render priority images and match snapshot 1`]
64
112
  <div
65
113
  class="carousel__slide"
66
114
  >
67
- <span>
68
- <img
69
- alt="Carousel image"
70
- aria-label="View Image"
71
- role="button"
72
- src="test-url"
73
- />
74
- </span>
115
+ <span />
75
116
  </div>
76
117
  </div>
77
118
  <div
@@ -19,6 +19,11 @@ jest.mock('next/router', () => ({
19
19
  useRouter: () => ({ asPath: '/' })
20
20
  }));
21
21
 
22
+ // todo: add extra tests to support this util
23
+ jest.mock('../../../../../src/components/MenuItem/helpers/has-active-child', () =>
24
+ jest.fn(() => false)
25
+ );
26
+
22
27
  const componentProps = {
23
28
  id: 'id',
24
29
  name: 'mock name',
@@ -11,14 +11,22 @@ const MENU_ITEM_CHILDREN_CLASS = 'menu--item-children';
11
11
 
12
12
  let mockAsPathValue = '/';
13
13
 
14
- jest.mock('next/router', () => ({
15
- useRouter: () => ({ asPath: mockAsPathValue })
16
- }));
14
+ jest.mock('next/router', () => {
15
+ const router = { asPath: mockAsPathValue };
16
+ return {
17
+ useRouter: () => router
18
+ };
19
+ });
17
20
 
18
21
  jest.mock('@blaze-cms/utils-handlebars', () => ({
19
22
  useStringTemplate: jest.fn((parent, [title]) => ({ loading: false, data: [title] }))
20
23
  }));
21
24
 
25
+ // todo: add extra tests to support this util
26
+ jest.mock('../../../../../src/components/MenuItem/helpers/has-active-child', () =>
27
+ jest.fn(() => false)
28
+ );
29
+
22
30
  describe('MenuRender component', () => {
23
31
  it('renders menu item with link when URL is provided', () => {
24
32
  const { getByText } = render(<MenuRender eventType="click" text="Home" url="/home" />);
@@ -0,0 +1,73 @@
1
+ export const mockMenuProps = {
2
+ props: {
3
+ children: [
4
+ false,
5
+ [
6
+ {
7
+ props: {
8
+ component: {
9
+ items: [
10
+ {
11
+ type: 'menuitem',
12
+ settings: {
13
+ name: 'menuitem-card',
14
+ url: 'card',
15
+ text: 'Card'
16
+ },
17
+ id: 'menuitem-card-1',
18
+ items: [],
19
+ name: 'menuitem-card-1'
20
+ },
21
+ {
22
+ type: 'menuitem',
23
+ settings: {
24
+ name: 'menuitem-Card',
25
+
26
+ url: 'card',
27
+ text: 'Card'
28
+ },
29
+ id: 'menuitem-Card-1',
30
+ items: [],
31
+ name: 'menuitem-Card-1'
32
+ },
33
+ {
34
+ type: 'menuitem',
35
+ settings: {
36
+ name: 'menuitem-card-Carousel',
37
+ url: 'card-carousel',
38
+ text: 'Card Carousel'
39
+ },
40
+ id: 'menuitem-card-carousel-1',
41
+ items: [],
42
+ name: 'menuitem-card-carousel-1'
43
+ },
44
+ {
45
+ type: 'menuitem',
46
+ settings: {
47
+ eventType: 'hover',
48
+ name: 'menuitem-Content-Group',
49
+ modifier: null,
50
+ url: 'content-group',
51
+ text: 'Content Group',
52
+ variant: null,
53
+ gtmClassName: null,
54
+ entities: [],
55
+ filterByProperty: [],
56
+ filterByFeatured: 'off',
57
+ filterBySponsored: 'off',
58
+ operator: 'AND',
59
+ filterBy: [],
60
+ sortProperties: []
61
+ },
62
+ id: 'menuitem-Content-Group-1',
63
+ items: [],
64
+ name: 'menuitem-Content-Group-1'
65
+ }
66
+ ]
67
+ }
68
+ }
69
+ }
70
+ ]
71
+ ]
72
+ }
73
+ };
@@ -0,0 +1,35 @@
1
+ /* eslint-disable no-unused-vars */
2
+ import '@testing-library/jest-dom/extend-expect';
3
+ import { hasActiveChild } from '../../../../../../src/components/MenuItem/helpers';
4
+ import { mockMenuProps } from './constants';
5
+
6
+ describe('hasActiveChild', () => {
7
+ const structuredClone = val => JSON.parse(JSON.stringify(val));
8
+
9
+ it('should return true for finding active menu-item child', () => {
10
+ const activePath = '/card';
11
+ const menuProps = mockMenuProps;
12
+ const result = !!hasActiveChild(activePath, menuProps);
13
+ expect(result).toBe(true);
14
+ });
15
+
16
+ it('shoul return false for findng no exact match', () => {
17
+ const activePath = '/carousel';
18
+ const menuProps = mockMenuProps;
19
+
20
+ const result = !!hasActiveChild(activePath, menuProps);
21
+ expect(result).toBe(false);
22
+ });
23
+
24
+ it('should return false for empty children-items', () => {
25
+ const activePath = '/carousel';
26
+ const menuWithNoChildrenProps = (() => {
27
+ const obj = structuredClone(mockMenuProps);
28
+ obj.props.children[1][0].props.component.items = [];
29
+ return obj;
30
+ }).call();
31
+
32
+ const result = !!hasActiveChild(activePath, menuWithNoChildrenProps);
33
+ expect(result).toBe(false);
34
+ });
35
+ });
@@ -0,0 +1,53 @@
1
+ import '@testing-library/jest-dom/extend-expect';
2
+ import { isUrlPathMatch } from '../../../../../../src/components/MenuItem/helpers';
3
+
4
+ describe('isUrlPathMatch', () => {
5
+ it('should return true since path and itemUrl match', () => {
6
+ const path = '/button';
7
+ const itemUrl = 'button';
8
+ const result = isUrlPathMatch(path, itemUrl);
9
+ expect(result).toBeTruthy();
10
+ });
11
+
12
+ it('should match since path and itemUrl do not match', () => {
13
+ const path = '/card';
14
+ const itemUrl = 'button';
15
+ const result = isUrlPathMatch(path, itemUrl);
16
+ expect(result).toBeFalsy();
17
+ });
18
+
19
+ it('should not match since path and itemUrl is a partial match', () => {
20
+ const path = '/button-card';
21
+ const itemUrl = 'button';
22
+ const result = isUrlPathMatch(path, itemUrl);
23
+ expect(result).toBeFalsy();
24
+ });
25
+
26
+ it('should not match since nested path and itemUrl is a partial match', () => {
27
+ const path = '/button/child';
28
+ const itemUrl = 'button';
29
+ const result = isUrlPathMatch(path, itemUrl);
30
+ expect(result).toBeFalsy();
31
+ });
32
+
33
+ it('should match with uri-with-fragment', () => {
34
+ const path = '/button#dark';
35
+ const itemUrl = 'button';
36
+ const result = isUrlPathMatch(path, itemUrl);
37
+ expect(result).toBeTruthy();
38
+ });
39
+
40
+ it('should match with uri-with-parameters', () => {
41
+ const path = '/button?paramater=value';
42
+ const itemUrl = 'button';
43
+ const result = isUrlPathMatch(path, itemUrl);
44
+ expect(result).toBeTruthy();
45
+ });
46
+
47
+ it('should not match with empty itemUrl', () => {
48
+ const path = '/';
49
+ const itemUrl = null;
50
+ const result = isUrlPathMatch(path, itemUrl);
51
+ expect(result).toBeFalsy();
52
+ });
53
+ });
@@ -12,8 +12,16 @@ jest.mock('@apollo/client', () => ({
12
12
  useQuery: jest.fn(() => ({ data: {}, loading: false, error: null }))
13
13
  }));
14
14
 
15
+ const mockPush = jest.fn();
16
+ const mockOn = jest.fn();
17
+ const mockOff = jest.fn();
18
+
15
19
  jest.mock('next/router', () => ({
16
- useRouter: jest.fn(() => ({ asPath: 'test-url', events: { on: jest.fn(), off: jest.fn() } }))
20
+ useRouter: jest.fn(() => ({
21
+ asPath: 'test-url',
22
+ push: mockPush,
23
+ events: { on: mockOn, off: mockOff }
24
+ }))
17
25
  }));
18
26
 
19
27
  const SEARCH_INPUT_TEST_ID = 'search-content-input';
@@ -54,4 +62,27 @@ describe('SearchContent', () => {
54
62
  fireEvent.click(closeIcon);
55
63
  await waitFor(() => expect(queryByTestId(SEARCH_INPUT_TEST_ID)).toBeNull());
56
64
  });
65
+
66
+ it('should trigger autosuggest again after navigation and typing', async () => {
67
+ const { getByTestId, queryByTestId } = render(
68
+ <MockedProvider mocks={[]} addTypename={false}>
69
+ <SearchContent entities={entities} />
70
+ </MockedProvider>
71
+ );
72
+
73
+ const input = getByTestId(SEARCH_INPUT_TEST_ID);
74
+
75
+ fireEvent.change(input, { target: { value: 'novartis' } });
76
+
77
+ await waitFor(() => expect(queryByTestId('search-content-results')).toBeTruthy());
78
+
79
+ fireEvent.keyDown(input, { key: 'Enter', code: 'Enter' });
80
+
81
+ const routeChangeHandler = mockOn.mock.calls[0][1];
82
+ routeChangeHandler();
83
+
84
+ fireEvent.change(input, { target: { value: 'blaze' } });
85
+
86
+ await waitFor(() => expect(queryByTestId('search-content-results')).toBeTruthy());
87
+ });
57
88
  });