@truedat/core 5.18.1 → 5.18.3

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.
@@ -1,47 +1,182 @@
1
1
  import _ from "lodash/fp";
2
2
  import React from "react";
3
- import { shallow } from "enzyme";
4
- import { Dropdown } from "semantic-ui-react";
3
+ import { render } from "@truedat/test/render";
4
+ import { waitFor, within, screen } from "@testing-library/react";
5
+ import userEvent from "@testing-library/user-event";
6
+
5
7
  import { FilterDropdown } from "../FilterDropdown";
6
8
 
7
- const options = _.map(value => ({ value, text: value }))(["value1", "value2"]);
9
+ const options = _.map((value) => ({ value, text: value }))([
10
+ "value1",
11
+ "value2",
12
+ ]);
13
+
14
+ const largeOptions = _.range(0, 8).map((n) => ({
15
+ value: `value${n}`,
16
+ text: `value${n}`,
17
+ }));
18
+
19
+ const props = {
20
+ openFilter: jest.fn(),
21
+ closeFilter: jest.fn(),
22
+ removeFilter: jest.fn(),
23
+ toggleFilterValue: jest.fn(),
24
+ filter: "foo",
25
+ options,
26
+ };
8
27
 
9
28
  describe("<FilterDropdown/>", () => {
10
29
  it("matches the latest snapshot", () => {
11
- const filter = "foo";
12
- const props = { filter, options };
13
- const wrapper = shallow(<FilterDropdown {...props} />);
14
- expect(wrapper).toMatchSnapshot();
15
- });
16
-
17
- it("dispatches openFilter, closeFilter and removeFilter", () => {
18
- const closeFilter = jest.fn();
19
- const openFilter = jest.fn();
20
- const removeFilter = jest.fn();
21
- const filter = "foo";
22
- const props = {
23
- closeFilter,
24
- filter,
25
- openFilter,
26
- options,
27
- removeFilter
30
+ const { container } = render(<FilterDropdown {...props} />);
31
+ expect(container).toMatchSnapshot();
32
+ });
33
+
34
+ it("render search input if has more than eight options", () => {
35
+ const customProps = {
36
+ ...props,
37
+ options: largeOptions,
38
+ };
39
+ const { getByRole } = render(<FilterDropdown {...customProps} />);
40
+
41
+ expect(getByRole("textbox")).toBeInTheDocument();
42
+ });
43
+
44
+ it("no render search input if has more than eight options", () => {
45
+ const { queryByRole } = render(<FilterDropdown {...props} />);
46
+ expect(queryByRole("textbox")).toBeNull();
47
+ });
48
+
49
+ it("check option check it correctly", () => {
50
+ const customProps = {
51
+ ...props,
52
+ options: largeOptions,
53
+ };
54
+
55
+ const selectedOption = customProps.options[6].text;
56
+
57
+ const { getByRole, getAllByRole, rerender } = render(
58
+ <FilterDropdown {...customProps} />
59
+ );
60
+
61
+ expect(customProps.toggleFilterValue).toBeCalledTimes(0);
62
+ userEvent.click(
63
+ getByRole("option", { name: new RegExp(selectedOption, "i") })
64
+ );
65
+ expect(customProps.toggleFilterValue).toBeCalledWith({
66
+ filter: props.filter,
67
+ value: selectedOption,
68
+ });
69
+
70
+ const rerenderProps = {
71
+ ...customProps,
72
+ activeValues: [selectedOption],
73
+ };
74
+ rerender(<FilterDropdown {...rerenderProps} />);
75
+
76
+ expect(
77
+ within(getAllByRole("option")[0]).queryByText(selectedOption)
78
+ ).not.toBeNull();
79
+ });
80
+
81
+ it("type in filter input filter options", () => {
82
+ const customProps = {
83
+ ...props,
84
+ options: largeOptions,
28
85
  };
29
- const wrapper = shallow(<FilterDropdown {...props} />);
30
- expect(openFilter.mock.calls.length).toBe(0);
31
- expect(closeFilter.mock.calls.length).toBe(0);
32
- expect(removeFilter.mock.calls.length).toBe(0);
33
-
34
- wrapper.find(Dropdown).simulate("open");
35
- expect(openFilter.mock.calls.length).toBe(1);
36
-
37
- wrapper.find(Dropdown).simulate("close");
38
- expect(closeFilter.mock.calls.length).toBe(1);
39
-
40
- const e = { preventDefault: jest.fn(), stopPropagation: jest.fn() };
41
- wrapper
42
- .prop("trigger")
43
- .props["children"].find(_.has("props.onClick"))
44
- .props.onClick(e);
45
- expect(removeFilter.mock.calls.length).toBe(1);
86
+
87
+ const searchText = "3";
88
+
89
+ const { getByRole, queryByRole, getAllByRole } = render(
90
+ <FilterDropdown {...customProps} />
91
+ );
92
+ const input = getByRole("textbox");
93
+
94
+ expect(
95
+ getByRole("option", {
96
+ name: new RegExp(customProps.options[1].text, "i"),
97
+ })
98
+ ).toBeInTheDocument();
99
+
100
+ userEvent.type(input, searchText);
101
+
102
+ expect(
103
+ queryByRole("option", {
104
+ name: new RegExp(customProps.options[1].text, "i"),
105
+ })
106
+ ).toBeNull();
107
+
108
+ expect(
109
+ within(getByRole("option")).getByText(`value${searchText}`)
110
+ ).toBeInTheDocument();
111
+
112
+ expect(getAllByRole("option").length).toBe(1);
113
+ });
114
+
115
+ it("type in filter not hidde selected values", () => {
116
+ const selectedOption = largeOptions[6].text;
117
+
118
+ const customProps = {
119
+ ...props,
120
+ options: largeOptions,
121
+ activeValues: [selectedOption],
122
+ };
123
+
124
+ const searchText = "3";
125
+
126
+ const { getByRole, queryByRole, getAllByRole } = render(
127
+ <FilterDropdown {...customProps} />
128
+ );
129
+ const input = getByRole("textbox");
130
+
131
+ userEvent.type(input, searchText);
132
+
133
+ expect(
134
+ within(getAllByRole("option")[0]).getByText(selectedOption)
135
+ ).toBeInTheDocument();
136
+
137
+ expect(
138
+ within(getAllByRole("option")[1]).getByText(`value${searchText}`)
139
+ ).toBeInTheDocument();
140
+
141
+ expect(
142
+ queryByRole("option", {
143
+ name: new RegExp(customProps.options[1].text, "i"),
144
+ })
145
+ ).toBeNull();
146
+
147
+ expect(getAllByRole("option").length).toBe(2);
148
+ });
149
+
150
+ it("dispatches openFilter", () => {
151
+ const customProps = {
152
+ ...props,
153
+ options: [],
154
+ };
155
+
156
+ const { rerender } = render(<FilterDropdown {...customProps} />);
157
+
158
+ rerender(<FilterDropdown {...props} />);
159
+
160
+ waitFor(() => expect(props.openFilter).toBeCalledTimes(1));
161
+ });
162
+
163
+ it("dispatches closeFilter", () => {
164
+ const customProps = {
165
+ ...props,
166
+ options: [],
167
+ };
168
+
169
+ const { rerender } = render(<FilterDropdown {...props} />);
170
+ rerender(<FilterDropdown {...customProps} />);
171
+
172
+ waitFor(() => expect(props.closeFilter).toBeCalledTimes(1));
173
+ });
174
+
175
+ it("remove filter dispatches removeFilter", async () => {
176
+ const { container } = render(<FilterDropdown {...props} />);
177
+ userEvent.click(container.querySelector('[class="delete icon"]'));
178
+ await waitFor(() => {
179
+ expect(props.removeFilter).toBeCalledTimes(1);
180
+ });
46
181
  });
47
182
  });
@@ -0,0 +1,106 @@
1
+ /* eslint-disable react/prop-types */
2
+ import React from "react";
3
+ import { render } from "@truedat/test/render";
4
+ import { within, waitFor } from "@testing-library/react";
5
+ import userEvent from "@testing-library/user-event";
6
+
7
+ import { Icon, Dropdown, Segment } from "semantic-ui-react";
8
+
9
+ import SearchFilterDropdown from "../SearchFilterDropdown";
10
+
11
+ const DummyLoader = () => <div></div>;
12
+ const DummyFilerItem = ({ active, toggleFilterValue, option }) => (
13
+ <Dropdown.Item onClick={() => toggleFilterValue(option)} active={active}>
14
+ <Segment vertical>
15
+ <Icon name={active ? "check square outline" : "square outline"} />
16
+ {option.name}
17
+ </Segment>
18
+ </Dropdown.Item>
19
+ );
20
+
21
+ const props = {
22
+ query: "foo_query",
23
+ searchCallback: jest.fn(),
24
+ placeholder: "search dropdown",
25
+ options: [
26
+ {
27
+ id: 1,
28
+ name: "foo_option",
29
+ },
30
+ {
31
+ id: 2,
32
+ name: "bar_option",
33
+ },
34
+ {
35
+ id: 3,
36
+ name: "baz_option",
37
+ },
38
+ ],
39
+ open: true,
40
+ loading: false,
41
+ activeValues: [1],
42
+ closeFilter: jest.fn(),
43
+ filter: "foo_filter",
44
+ FilterDataLoader: DummyLoader,
45
+ loaderProps: { name: "loader-prop" },
46
+ FilterItem: DummyFilerItem,
47
+ openFilter: jest.fn(),
48
+ removeFilter: jest.fn(),
49
+ toggleFilterValue: jest.fn(),
50
+ searchFilterDispacher: jest.fn(),
51
+ };
52
+
53
+ describe("<SearchFilterDropDown/>", () => {
54
+ it("matches the latest snapshot unfolded", () => {
55
+ const { container } = render(<SearchFilterDropdown {...props} />);
56
+ expect(container).toMatchSnapshot();
57
+ });
58
+
59
+ it("matches the latest snapshot folded", () => {
60
+ const customProps = {
61
+ ...props,
62
+ open: false,
63
+ };
64
+ const { container } = render(<SearchFilterDropdown {...customProps} />);
65
+ expect(container).toMatchSnapshot();
66
+ });
67
+
68
+ it("check option check it correctly", () => {
69
+ const { getByRole, getAllByRole } = render(
70
+ <SearchFilterDropdown {...props} />
71
+ );
72
+
73
+ expect(props.toggleFilterValue).toBeCalledTimes(0);
74
+ userEvent.click(getByRole("option", { name: "baz_option" }));
75
+ expect(props.toggleFilterValue).toBeCalledWith({
76
+ value: 3,
77
+ filter: "foo_filter",
78
+ });
79
+
80
+ expect(
81
+ within(getAllByRole("option")[0]).queryByText("baz_option")
82
+ ).not.toBeNull();
83
+ });
84
+
85
+ it("type in filter input dispatch searchCallback with correct query", () => {
86
+ const searchText = "a";
87
+
88
+ const { getByRole } = render(<SearchFilterDropdown {...props} />);
89
+ const input = getByRole("textbox");
90
+
91
+ userEvent.type(input, searchText);
92
+
93
+ expect(props.searchCallback).toBeCalledWith({
94
+ query: `${props.query}${searchText}`,
95
+ });
96
+ expect(props.searchFilterDispacher).toBeCalledTimes(1);
97
+ });
98
+
99
+ it("remove filter dispatches removeFilter", async () => {
100
+ const { container } = render(<SearchFilterDropdown {...props} />);
101
+ userEvent.click(container.querySelector('[class="delete icon"]'));
102
+ await waitFor(() => {
103
+ expect(props.removeFilter).toBeCalledTimes(1);
104
+ });
105
+ });
106
+ });
@@ -1,66 +1,94 @@
1
+ /* eslint-disable react/prop-types */
1
2
  import React from "react";
2
- import { shallowWithIntl } from "@truedat/test/intl-stub";
3
+ import { render } from "@truedat/test/render";
4
+
5
+ import userEvent from "@testing-library/user-event";
6
+ import { Icon, Dropdown, Segment } from "semantic-ui-react";
7
+
3
8
  import { SelectedFilters } from "../SelectedFilters";
4
9
 
10
+ const DummyLoader = () => <div></div>;
11
+ const DummyFilerItem = ({ active, toggleFilterValue, option }) => (
12
+ <Dropdown.Item onClick={() => toggleFilterValue(option)} active={active}>
13
+ <Segment vertical>
14
+ <Icon name={active ? "check square outline" : "square outline"} />
15
+ {option.name}
16
+ </Segment>
17
+ </Dropdown.Item>
18
+ );
19
+
5
20
  describe("<SelectedFilters/>", () => {
6
- const getProps = () => ({
21
+ const props = {
7
22
  resetFilters: jest.fn(),
8
23
  filterTypes: {
9
24
  foo: "fooType",
10
25
  },
26
+ openFilter: jest.fn(),
27
+ closeFilter: jest.fn(),
11
28
  selectedFilter: "foo",
12
29
  selectedFilters: ["foo", "bar"],
13
30
  selectedFilterActiveValues: ["value2"],
14
31
  selectedFilterValues: ["value1", "value2"],
15
- saveFilters: jest.fn(),
16
32
  selectedUserFilter: null,
17
33
  userFilters: ["uf1", "uf2"],
18
- });
34
+ searchFiltersPropsMapping: {},
35
+ searchFilterDispacher: jest.fn(),
36
+ };
37
+
38
+ const messages = {
39
+ "search.clear_filters": "clean filters",
40
+ "search.save_filters": "save filters",
41
+ };
42
+
43
+ const renderOptions = {
44
+ messages: {
45
+ en: messages,
46
+ },
47
+ };
19
48
 
20
49
  it("matches the latest snapshot", () => {
21
- const props = getProps();
22
- const wrapper = shallowWithIntl(<SelectedFilters {...props} />);
23
- expect(wrapper).toMatchSnapshot();
50
+ const { container } = render(<SelectedFilters {...props} />);
51
+ expect(container).toMatchSnapshot();
24
52
  });
25
53
 
26
54
  it("dispatches resetFilters", () => {
27
- const props = getProps();
28
- const wrapper = shallowWithIntl(<SelectedFilters {...props} />);
55
+ const { getByText } = render(<SelectedFilters {...props} />, renderOptions);
29
56
 
30
- expect(props.resetFilters.mock.calls.length).toBe(0);
31
- wrapper.find("a").simulate("click");
32
- expect(props.resetFilters.mock.calls.length).toBe(1);
57
+ expect(props.resetFilters).toBeCalledTimes(0);
58
+ userEvent.click(getByText(messages["search.clear_filters"]));
59
+ expect(props.resetFilters).toBeCalledTimes(1);
33
60
  });
34
61
 
35
62
  it("does not render Save filters option if saveFilters is undefined", () => {
36
- const props = getProps();
37
- const customProps = { ...props, saveFilters: undefined };
38
- const wrapper = shallowWithIntl(<SelectedFilters {...customProps} />);
39
- expect(wrapper.find("ModalSaveFilter")).toHaveLength(0);
63
+ const { queryByText } = render(
64
+ <SelectedFilters {...props} />,
65
+ renderOptions
66
+ );
67
+ expect(queryByText(messages["search.save_filters"])).toBeNull();
40
68
  });
41
69
 
42
70
  it("renders Save filters option if saveFilters is defined", () => {
43
- const props = getProps();
44
- const wrapper = shallowWithIntl(<SelectedFilters {...props} />);
45
- expect(wrapper.find("ModalSaveFilter")).toHaveLength(1);
71
+ const customProps = { ...props, saveFilters: jest.fn() };
72
+ const { getByText } = render(
73
+ <SelectedFilters {...customProps} />,
74
+ renderOptions
75
+ );
76
+ expect(getByText(messages["search.save_filters"])).toBeInTheDocument();
46
77
  });
47
78
 
48
79
  it("does not render userFilters if they are empty", () => {
49
- const props = getProps();
50
80
  const customProps = { ...props, userFilters: [] };
51
- const wrapper = shallowWithIntl(<SelectedFilters {...customProps} />);
52
- expect(wrapper.find("UserFilters")).toHaveLength(0);
81
+ const { container } = render(<SelectedFilters {...customProps} />);
82
+ expect(container.getElementsByClassName("userFilter")).toHaveLength(0);
53
83
  });
54
84
 
55
85
  it("renders userFilters if they are defined", () => {
56
- const props = getProps();
57
86
  const customProps = { ...props, userFilters: [{ country: ["a"] }] };
58
- const wrapper = shallowWithIntl(<SelectedFilters {...customProps} />);
59
- expect(wrapper.find("UserFilters")).toHaveLength(1);
87
+ const { container } = render(<SelectedFilters {...customProps} />);
88
+ expect(container.getElementsByClassName("userFilter")).toHaveLength(1);
60
89
  });
61
90
 
62
91
  it("renders FilterMultilevelDropdown if filter is of type domain", () => {
63
- const props = getProps();
64
92
  const customProps = {
65
93
  ...props,
66
94
  selectedFilters: ["taxonomy"],
@@ -68,20 +96,49 @@ describe("<SelectedFilters/>", () => {
68
96
  filterTypes: { taxonomy: "domain" },
69
97
  selectedFilterValues: [{ id: 1, name: "foo", level: 0 }],
70
98
  };
71
- const wrapper = shallowWithIntl(<SelectedFilters {...customProps} />);
72
- expect(wrapper.find("FilterMultilevelDropdown")).toHaveLength(1);
99
+ const { container } = render(<SelectedFilters {...customProps} />);
100
+ expect(
101
+ container.querySelector('[name="filterMultilevelDropdown"]')
102
+ ).not.toBeNull();
73
103
  });
74
104
 
75
105
  it("renders HierarchyFilterDropdown if filter is of type hierarchy", () => {
76
- const props = getProps();
77
106
  const customProps = {
78
107
  ...props,
79
108
  selectedFilters: ["hierarchy_field"],
80
109
  selectedFilter: "hierarchy_field",
81
110
  filterTypes: { hierarchy_field: "hierarchy" },
82
- selectedFilterValues: [{ key: "2_1", id: 1, name: "foo", level: 0 }],
111
+ selectedFilterValues: [],
112
+ };
113
+ const { container } = render(<SelectedFilters {...customProps} />);
114
+ expect(
115
+ container.querySelector('[name="hierarchyFilterDropdown"]')
116
+ ).not.toBeNull();
117
+ });
118
+
119
+ it("renders SearchFilterDropdown if filter is of type search", () => {
120
+ const customProps = {
121
+ ...props,
122
+ selectedFilters: ["search_filter"],
123
+ selectedFilter: "search_filter",
124
+ filterTypes: { search_filter: "search" },
125
+ selectedFilterValues: [],
126
+ searchFiltersPropsMapping: {
127
+ search_filter: {
128
+ query: "query test",
129
+ searchCallback: jest.fn(),
130
+ options: [],
131
+ placeholder: "test",
132
+ FilterDataLoader: DummyLoader,
133
+ loaderProps: { pageSize: 50 },
134
+ FilterItem: DummyFilerItem,
135
+ },
136
+ },
137
+ searchFilterDispacher: jest.fn(),
83
138
  };
84
- const wrapper = shallowWithIntl(<SelectedFilters {...customProps} />);
85
- expect(wrapper.find("HierarchyFilterDropdown")).toHaveLength(1);
139
+ const { container } = render(<SelectedFilters {...customProps} />);
140
+ expect(
141
+ container.querySelector('[name="searchFilterDropdown"]')
142
+ ).not.toBeNull();
86
143
  });
87
144
  });
@@ -0,0 +1,26 @@
1
+ import React from "react";
2
+ import { render } from "@truedat/test/render";
3
+ import { within } from "@testing-library/react";
4
+ import userEvent from "@testing-library/user-event";
5
+ import { StructureFilterItem } from "../StructureFilterItem";
6
+
7
+ const props = {
8
+ active: true,
9
+ filter: "foo",
10
+ toggleFilterValue: jest.fn(),
11
+ option: { id: 123, name: "bar", path: ["one", "two", "three"], type: "baz" },
12
+ };
13
+
14
+ describe("<StructureFilterItem/>", () => {
15
+ it("matches the latest snapshot", () => {
16
+ const { container } = render(<StructureFilterItem {...props} />);
17
+ expect(container).toMatchSnapshot();
18
+ });
19
+
20
+ it("dispatches toggleFilterValue on click", () => {
21
+ const { container } = render(<StructureFilterItem {...props} />);
22
+ expect(props.toggleFilterValue.mock.calls.length).toBe(0);
23
+ userEvent.click(within(container).getByText(props.option.name));
24
+ expect(props.toggleFilterValue.mock.calls.length).toBe(1);
25
+ });
26
+ });
@@ -1,67 +1,48 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
3
  exports[`<FilterDropdown/> matches the latest snapshot 1`] = `
4
- <Dropdown
5
- additionLabel="Add "
6
- additionPosition="top"
7
- closeOnBlur={true}
8
- closeOnEscape={true}
9
- deburr={false}
10
- floating={true}
11
- icon={false}
12
- item={true}
13
- minCharacters={1}
14
- noResultsMessage="No results found."
15
- onClose={[Function]}
16
- onOpen={[Function]}
17
- open={true}
18
- openOnFocus={true}
19
- renderLabel={[Function]}
20
- scrolling={true}
21
- searchInput="text"
22
- selectOnBlur={true}
23
- selectOnNavigation={true}
24
- trigger={
25
- <Label>
26
- <Memo(MemoizedFormattedMessage)
27
- defaultMessage="foo"
28
- id="filters.foo"
29
- />
30
- <Icon
31
- as="i"
32
- name="delete"
33
- onClick={[Function]}
34
- />
35
- </Label>
36
- }
37
- upward={false}
38
- wrapSelection={true}
39
- >
40
- <DimmerDimmable
41
- as={[Function]}
4
+ <div>
5
+ <div
6
+ aria-expanded="true"
7
+ class="ui active visible floating item scrolling dropdown"
8
+ role="listbox"
9
+ tabindex="0"
42
10
  >
43
- <FilterItem
44
- active={false}
45
- filter="foo"
46
- key="0"
47
- option={
48
- {
49
- "text": "value1",
50
- "value": "value1",
51
- }
52
- }
53
- />
54
- <FilterItem
55
- active={false}
56
- filter="foo"
57
- key="1"
58
- option={
59
- {
60
- "text": "value2",
61
- "value": "value2",
62
- }
63
- }
64
- />
65
- </DimmerDimmable>
66
- </Dropdown>
11
+ <div
12
+ class="ui label"
13
+ >
14
+ foo
15
+ <i
16
+ aria-hidden="true"
17
+ class="delete icon"
18
+ />
19
+ </div>
20
+ <div
21
+ class="menu transition dimmable visible"
22
+ >
23
+ <div
24
+ aria-checked="false"
25
+ class="item"
26
+ role="option"
27
+ >
28
+ <i
29
+ aria-hidden="true"
30
+ class="square outline icon"
31
+ />
32
+ value1
33
+ </div>
34
+ <div
35
+ aria-checked="false"
36
+ class="item"
37
+ role="option"
38
+ >
39
+ <i
40
+ aria-hidden="true"
41
+ class="square outline icon"
42
+ />
43
+ value2
44
+ </div>
45
+ </div>
46
+ </div>
47
+ </div>
67
48
  `;
@@ -5,6 +5,7 @@ exports[`<FilterMultilevelDropdown /> matches the latest snapshot 1`] = `
5
5
  <div
6
6
  aria-expanded="true"
7
7
  class="ui active visible floating item dropdown"
8
+ name="filterMultilevelDropdown"
8
9
  role="listbox"
9
10
  tabindex="0"
10
11
  >
@@ -5,6 +5,7 @@ exports[`<HierarchyFilterDropdown /> matches the latest snapshot 1`] = `
5
5
  <div
6
6
  aria-expanded="true"
7
7
  class="ui active visible floating item dropdown"
8
+ name="hierarchyFilterDropdown"
8
9
  role="listbox"
9
10
  tabindex="0"
10
11
  >
@@ -68,6 +69,7 @@ exports[`<HierarchyFilterDropdown /> matches the latest snapshot for empty optio
68
69
  <div
69
70
  aria-expanded="false"
70
71
  class="ui floating item dropdown"
72
+ name="hierarchyFilterDropdown"
71
73
  role="listbox"
72
74
  tabindex="0"
73
75
  >