@truedat/bg 7.2.1 → 7.2.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.
Files changed (29) hide show
  1. package/package.json +6 -6
  2. package/src/concepts/components/ConceptsUploadButton.js +1 -1
  3. package/src/concepts/components/__tests__/ConceptManageDomain.spec.js +28 -4
  4. package/src/concepts/components/__tests__/__snapshots__/ConceptForm.spec.js.snap +10 -12
  5. package/src/concepts/components/__tests__/__snapshots__/ConceptManageDomain.spec.js.snap +58 -1
  6. package/src/concepts/components/__tests__/__snapshots__/ConceptsBulkUpdate.spec.js.snap +10 -12
  7. package/src/concepts/components/__tests__/__snapshots__/SharedToForm.spec.js.snap +10 -12
  8. package/src/messages/en.js +2 -0
  9. package/src/messages/es.js +2 -0
  10. package/src/taxonomy/components/Domain.js +11 -71
  11. package/src/taxonomy/components/DomainCards.js +113 -0
  12. package/src/taxonomy/components/DomainContent.js +119 -0
  13. package/src/taxonomy/components/DomainTabs.js +92 -40
  14. package/src/taxonomy/components/Domains.js +144 -25
  15. package/src/taxonomy/components/DomainsActions.js +4 -4
  16. package/src/taxonomy/components/__tests__/Domain.spec.js +127 -2
  17. package/src/taxonomy/components/__tests__/DomainCards.spec.js +148 -0
  18. package/src/taxonomy/components/__tests__/DomainContent.spec.js +168 -0
  19. package/src/taxonomy/components/__tests__/DomainTabs.spec.js +108 -0
  20. package/src/taxonomy/components/__tests__/Domains.spec.js +149 -2
  21. package/src/taxonomy/components/__tests__/DomainsActions.spec.js +15 -8
  22. package/src/taxonomy/components/__tests__/__snapshots__/Domain.spec.js.snap +8 -0
  23. package/src/taxonomy/components/__tests__/__snapshots__/DomainCards.spec.js.snap +291 -0
  24. package/src/taxonomy/components/__tests__/__snapshots__/DomainContent.spec.js.snap +305 -0
  25. package/src/taxonomy/components/__tests__/__snapshots__/DomainTabs.spec.js.snap +40 -0
  26. package/src/taxonomy/components/__tests__/__snapshots__/Domains.spec.js.snap +74 -4
  27. package/src/taxonomy/components/__tests__/__snapshots__/DomainsActions.spec.js.snap +13 -22
  28. package/src/taxonomy/styles/domainCards.less +4 -0
  29. package/src/taxonomy/styles/domains.less +15 -0
@@ -0,0 +1,148 @@
1
+ import _ from "lodash/fp";
2
+ import React from "react";
3
+ import { render } from "@truedat/test/render";
4
+ import { fireEvent } from "@testing-library/react";
5
+ import { DomainCards } from "../DomainCards";
6
+
7
+ describe("<DomainCards />", () => {
8
+ const renderOpts = {
9
+ messages: {
10
+ en: {
11
+ "domain.children.empty": "No subdomains found",
12
+ "domain.props.children": "Subdomains: {count}",
13
+ "domains.actions.create": "New Domain",
14
+ "domains.search.placeholder": "Search domains...",
15
+ "domains.search.results.count": "Results: {count}",
16
+ domain: "Domain",
17
+ },
18
+ },
19
+ };
20
+ const domains = [
21
+ {
22
+ id: 1,
23
+ name: "rootNoSub",
24
+ type: null,
25
+ description: "Root domain with no subdomains",
26
+ parents: [
27
+ {
28
+ id: 1,
29
+ name: "rootNoSub",
30
+ external_id: "rootNoSub",
31
+ },
32
+ ],
33
+ domain_group: {
34
+ id: 1,
35
+ name: "DomainGroup",
36
+ },
37
+ parent_id: null,
38
+ external_id: "rootNoSub",
39
+ },
40
+ {
41
+ id: 2,
42
+ name: "rootWithSub",
43
+ type: null,
44
+ description: null,
45
+ parents: [
46
+ {
47
+ id: 2,
48
+ name: "rootWithSub",
49
+ external_id: "rootWithSub",
50
+ },
51
+ ],
52
+ domain_group: {
53
+ id: 1,
54
+ name: "DomainGroup",
55
+ },
56
+ parent_id: null,
57
+ external_id: "rootWithSub",
58
+ },
59
+ {
60
+ id: 3,
61
+ name: "rootOtherGroup",
62
+ type: null,
63
+ description: null,
64
+ parents: [
65
+ {
66
+ id: 3,
67
+ name: "rootOtherGroup",
68
+ external_id: "rootOtherGroup",
69
+ },
70
+ ],
71
+ domain_group: {
72
+ id: 2,
73
+ name: "OtherDomainGroup",
74
+ },
75
+ parent_id: null,
76
+ external_id: "rootOtherGroup",
77
+ },
78
+ {
79
+ id: 4,
80
+ name: "subdomain",
81
+ type: null,
82
+ description: null,
83
+ parents: [
84
+ {
85
+ id: 3,
86
+ name: "subdomain",
87
+ external_id: "subdomain",
88
+ },
89
+ {
90
+ id: 2,
91
+ name: "rootWithSub",
92
+ external_id: "rootWithSub",
93
+ },
94
+ ],
95
+ domain_group: {
96
+ id: 1,
97
+ name: "DomainGroup",
98
+ },
99
+ parent_id: 2,
100
+ external_id: "subdomain",
101
+ },
102
+ ];
103
+ it("matches the latest snapshot front page", () => {
104
+ const props = { domains };
105
+ const { container } = render(<DomainCards {...props} />, renderOpts);
106
+ expect(container).toMatchSnapshot();
107
+ });
108
+
109
+ it("matches the latest snapshot domain without subdomain", () => {
110
+ const domain = _.find(["id", 1])(domains);
111
+ const props = { domains, domain };
112
+ const { container } = render(<DomainCards {...props} />, renderOpts);
113
+ expect(container).toMatchSnapshot();
114
+ });
115
+
116
+ it("matches the latest snapshot domain with subdomain", () => {
117
+ const domain = _.find(["id", 2])(domains);
118
+ const props = { domains, domain };
119
+ const { container } = render(<DomainCards {...props} />, renderOpts);
120
+ expect(container).toMatchSnapshot();
121
+ });
122
+
123
+ it("filters domains based on search input", () => {
124
+ const props = { domains };
125
+ const { getByPlaceholderText, getByText } = render(
126
+ <DomainCards {...props} />,
127
+ renderOpts
128
+ );
129
+
130
+ const searchInput = getByPlaceholderText("Search domains...");
131
+ fireEvent.change(searchInput, { target: { value: "other" } });
132
+
133
+ expect(getByText("rootOtherGroup")).toBeInTheDocument();
134
+ });
135
+
136
+ it("displays 'No subdomains found' message when no subdomains are present", () => {
137
+ const domain = _.find(["id", 1])(domains);
138
+ const props = { domains, domain };
139
+ const { getByText } = render(<DomainCards {...props} />, renderOpts);
140
+ expect(getByText("No subdomains found")).toBeInTheDocument();
141
+ });
142
+
143
+ it("renders DomainsActions component when no domain is selected", () => {
144
+ const props = { domains, actions: { create: { href: "" } } };
145
+ const { getByText } = render(<DomainCards {...props} />, renderOpts);
146
+ expect(getByText("New Domain")).toBeInTheDocument();
147
+ });
148
+ });
@@ -0,0 +1,168 @@
1
+ import _ from "lodash/fp";
2
+ import React from "react";
3
+ import { render } from "@truedat/test/render";
4
+ import { MemoryRouter } from "react-router-dom";
5
+ import DomainContent from "../DomainContent";
6
+
7
+ jest.mock("../../../hooks/useDomains", () => ({
8
+ ...jest.requireActual("../../../hooks/useDomains"),
9
+ useDomain: jest.fn((domainId) => ({
10
+ data: {
11
+ description: "DOMAIN DESCRIPTION",
12
+ domain_group: null,
13
+ external_id: "EXTERNAL ID",
14
+ id: domainId,
15
+ name: "DOMAIN NAME",
16
+ parent_id: 6,
17
+ parents: null,
18
+ type: null,
19
+ },
20
+ })),
21
+ }));
22
+
23
+ describe("<DomainContent />", () => {
24
+ const domains = [
25
+ {
26
+ id: 1,
27
+ name: "rootNoSub",
28
+ type: null,
29
+ description: "Root domain with no subdomains",
30
+ parents: [
31
+ {
32
+ id: 1,
33
+ name: "rootNoSub",
34
+ external_id: "rootNoSub",
35
+ },
36
+ ],
37
+ domain_group: {
38
+ id: 1,
39
+ name: "DomainGroup",
40
+ },
41
+ parent_id: null,
42
+ external_id: "rootNoSub",
43
+ },
44
+ {
45
+ id: 2,
46
+ name: "rootWithSub",
47
+ type: null,
48
+ description: null,
49
+ parents: [
50
+ {
51
+ id: 2,
52
+ name: "rootWithSub",
53
+ external_id: "rootWithSub",
54
+ },
55
+ ],
56
+ domain_group: {
57
+ id: 1,
58
+ name: "DomainGroup",
59
+ },
60
+ parent_id: null,
61
+ external_id: "rootWithSub",
62
+ },
63
+ {
64
+ id: 3,
65
+ name: "rootOtherGroup",
66
+ type: null,
67
+ description: null,
68
+ parents: [
69
+ {
70
+ id: 3,
71
+ name: "rootOtherGroup",
72
+ external_id: "rootOtherGroup",
73
+ },
74
+ ],
75
+ domain_group: {
76
+ id: 2,
77
+ name: "OtherDomainGroup",
78
+ },
79
+ parent_id: null,
80
+ external_id: "rootOtherGroup",
81
+ },
82
+ {
83
+ id: 4,
84
+ name: "childSubdomain",
85
+ type: null,
86
+ description: null,
87
+ parents: [
88
+ {
89
+ id: 3,
90
+ name: "childSubdomain",
91
+ external_id: "subdomain",
92
+ },
93
+ {
94
+ id: 2,
95
+ name: "rootWithSub",
96
+ external_id: "rootWithSub",
97
+ },
98
+ ],
99
+ domain_group: {
100
+ id: 1,
101
+ name: "DomainGroup",
102
+ },
103
+ parent_id: 2,
104
+ external_id: "subdomain",
105
+ },
106
+ ];
107
+
108
+ const taxonomyConfig = {
109
+ priorityTabs: [],
110
+ hiddenTabs: [],
111
+ };
112
+
113
+ const testList = [
114
+ {
115
+ content: "subdomains",
116
+ domainId: 1,
117
+ textToSearch: "This domain has no subdomains",
118
+ },
119
+ {
120
+ content: "subdomains",
121
+ domainId: 2,
122
+ textToSearch: "childSubdomain",
123
+ },
124
+ {
125
+ content: "concepts",
126
+ domainId: 1,
127
+ textToSearch: "Searching...",
128
+ },
129
+ {
130
+ content: "structures",
131
+ domainId: 1,
132
+ textToSearch: "You are not authorized to view this content",
133
+ },
134
+ {
135
+ content: "implementations",
136
+ domainId: 1,
137
+ textToSearch: "You are not authorized to view this content",
138
+ },
139
+ {
140
+ content: "members",
141
+ domainId: 1,
142
+ textToSearch: "This domain has no members",
143
+ },
144
+ ];
145
+ const renderOpts = {
146
+ mocks: [],
147
+ fallback: "lazy",
148
+ };
149
+
150
+ test.each(testList)(
151
+ "Render %s content for %s domain with text %s",
152
+ ({ content, domainId, textToSearch }) => {
153
+ const domain = _.find(["id", domainId])(domains);
154
+ const { container, getByText } = render(
155
+ <MemoryRouter initialEntries={[`/domains/${domainId}/${content}`]}>
156
+ <DomainContent
157
+ domain={domain}
158
+ domains={domains}
159
+ taxonomyConfig={taxonomyConfig}
160
+ />
161
+ </MemoryRouter>,
162
+ renderOpts
163
+ );
164
+ expect(container).toMatchSnapshot();
165
+ expect(getByText(textToSearch)).toBeInTheDocument();
166
+ }
167
+ );
168
+ });
@@ -0,0 +1,108 @@
1
+ import React from "react";
2
+ import { render } from "@truedat/test/render";
3
+ import { useAuthorized } from "@truedat/core/hooks";
4
+ import DomainTabs from "../DomainTabs";
5
+
6
+ jest.mock("@truedat/core/hooks", () => ({
7
+ useAuthorized: jest.fn(() => true),
8
+ }));
9
+
10
+ describe("<DomainTabs />", () => {
11
+ const domain = {
12
+ id: 1,
13
+ name: "Test Domain",
14
+ };
15
+
16
+ const taxonomyConfig = {
17
+ priorityTabs: [],
18
+ hiddenTabs: [],
19
+ };
20
+
21
+ const renderOpts = {
22
+ messages: {
23
+ en: {
24
+ "tabs.subdomains": "Subdomains",
25
+ "tabs.concepts": "Concepts",
26
+ "tabs.structures": "Structures",
27
+ "tabs.implementations": "Implementations",
28
+ "tabs.members": "Members",
29
+ },
30
+ },
31
+ };
32
+
33
+ it("matches the latest snapshot", () => {
34
+ const { container } = render(
35
+ <DomainTabs domain={domain} taxonomyConfig={taxonomyConfig} />,
36
+ renderOpts
37
+ );
38
+ expect(container).toMatchSnapshot();
39
+ });
40
+
41
+ it("renders all tabs", () => {
42
+ const { getByText } = render(
43
+ <DomainTabs domain={domain} taxonomyConfig={taxonomyConfig} />,
44
+ renderOpts
45
+ );
46
+
47
+ expect(getByText("Subdomains")).toBeInTheDocument();
48
+ expect(getByText("Concepts")).toBeInTheDocument();
49
+ expect(getByText("Structures")).toBeInTheDocument();
50
+ expect(getByText("Implementations")).toBeInTheDocument();
51
+ expect(getByText("Members")).toBeInTheDocument();
52
+ });
53
+
54
+ it("hides tabs based on hiddenTabs config", () => {
55
+ const hiddenTabsConfig = {
56
+ ...taxonomyConfig,
57
+ hiddenTabs: ["structures", "implementations"],
58
+ };
59
+
60
+ const { queryByText } = render(
61
+ <DomainTabs domain={domain} taxonomyConfig={hiddenTabsConfig} />,
62
+ renderOpts
63
+ );
64
+
65
+ expect(queryByText("Structures")).not.toBeInTheDocument();
66
+ expect(queryByText("Implementations")).not.toBeInTheDocument();
67
+ });
68
+
69
+ it("prioritizes tabs based on priorityTabs config", () => {
70
+ const priorityTabsConfig = {
71
+ ...taxonomyConfig,
72
+ priorityTabs: ["implementations", "concepts"],
73
+ };
74
+
75
+ const { container } = render(
76
+ <DomainTabs domain={domain} taxonomyConfig={priorityTabsConfig} />,
77
+ renderOpts
78
+ );
79
+
80
+ const tabs = container.querySelectorAll(".item");
81
+ expect(tabs[0].textContent).toBe("Implementations");
82
+ expect(tabs[1].textContent).toBe("Concepts");
83
+ });
84
+
85
+ it("hides 'implementations' tab if dqAuthorized is false", () => {
86
+ useAuthorized.mockImplementation(
87
+ (permission) => permission == "data_dictionary"
88
+ );
89
+
90
+ const { queryByText } = render(
91
+ <DomainTabs domain={domain} taxonomyConfig={taxonomyConfig} />,
92
+ renderOpts
93
+ );
94
+
95
+ expect(queryByText("Implementations")).not.toBeInTheDocument();
96
+ });
97
+
98
+ it("hides 'structures' tab if ddAuthorized is false", () => {
99
+ useAuthorized.mockImplementation((permission) => permission == "quality");
100
+
101
+ const { queryByText } = render(
102
+ <DomainTabs domain={domain} taxonomyConfig={taxonomyConfig} />,
103
+ renderOpts
104
+ );
105
+
106
+ expect(queryByText("Structures")).not.toBeInTheDocument();
107
+ });
108
+ });
@@ -1,7 +1,14 @@
1
1
  import React from "react";
2
+ import { waitFor } from "@testing-library/react";
3
+ import { DOMAINS_QUERY } from "@truedat/core/api/queries";
4
+ import userEvent from "@testing-library/user-event";
5
+ import { useParams, useHistory } from "react-router-dom";
2
6
  import { render } from "@truedat/test/render";
7
+ import { useDomains } from "../../../hooks/useDomains";
3
8
  import Domains from "../Domains";
4
9
 
10
+ jest.mock("../../assets/searching.png", () => "mocked-searching.png");
11
+
5
12
  jest.mock("react-router-dom", () => ({
6
13
  ...jest.requireActual("react-router-dom"),
7
14
  useHistory: jest.fn(),
@@ -103,9 +110,149 @@ jest.mock("../../../hooks/useDomains", () => ({
103
110
  })),
104
111
  }));
105
112
 
113
+ const domains = [
114
+ {
115
+ id: 10,
116
+ name: "other_domain",
117
+ parentId: null,
118
+ externalId: "10",
119
+ actions: [],
120
+ },
121
+ ];
122
+
123
+ const variables = {
124
+ action: "viewDomain",
125
+ };
126
+
127
+ const domainsMock = {
128
+ request: { query: DOMAINS_QUERY, variables },
129
+ result: { data: { domains: domains } },
130
+ };
131
+
132
+ const renderOpts = {
133
+ mocks: [domainsMock, domainsMock],
134
+ fallback: "lazy",
135
+ };
136
+
106
137
  describe("<Domains />", () => {
107
- it("matches the latest snapshot", () => {
108
- const { container } = render(<Domains />);
138
+ it("matches the latest snapshot", async () => {
139
+ const { container, queryByText } = render(<Domains />, renderOpts);
140
+
141
+ await waitFor(() => expect(queryByText(/lazy/i)).not.toBeInTheDocument());
142
+ await waitFor(() =>
143
+ expect(queryByText(/loading/i)).not.toBeInTheDocument()
144
+ );
109
145
  expect(container).toMatchSnapshot();
110
146
  });
147
+
148
+ it("renders the correct number of domain elements", async () => {
149
+ const { getAllByText, queryByText } = render(<Domains />, renderOpts);
150
+
151
+ await waitFor(() => expect(queryByText(/lazy/i)).not.toBeInTheDocument());
152
+ await waitFor(() =>
153
+ expect(queryByText(/loading/i)).not.toBeInTheDocument()
154
+ );
155
+ const domainElements = getAllByText(/element_/);
156
+ expect(domainElements.length).toBe(2);
157
+ });
158
+
159
+ it("renders domain elements with correct names", async () => {
160
+ const { getByText, queryByText } = render(<Domains />, renderOpts);
161
+ await waitFor(() => expect(queryByText(/lazy/i)).not.toBeInTheDocument());
162
+ await waitFor(() =>
163
+ expect(queryByText(/loading/i)).not.toBeInTheDocument()
164
+ );
165
+
166
+ expect(getByText("element_2")).toBeInTheDocument();
167
+ expect(getByText("element_3")).toBeInTheDocument();
168
+
169
+ expect(queryByText("element_1")).not.toBeInTheDocument();
170
+ expect(queryByText("element_4")).not.toBeInTheDocument();
171
+ expect(queryByText("element_5")).not.toBeInTheDocument();
172
+ expect(queryByText("element_6")).not.toBeInTheDocument();
173
+ });
174
+
175
+ it("redirects to domains list if domainId is invalid", async () => {
176
+ const mockHistoryPush = jest.fn();
177
+ useHistory.mockImplementationOnce(() => ({ push: mockHistoryPush }));
178
+ useParams.mockImplementationOnce(() => ({ id: 999 }));
179
+
180
+ render(<Domains />, renderOpts);
181
+
182
+ await waitFor(() => {
183
+ expect(mockHistoryPush).toHaveBeenCalledWith("/domains");
184
+ });
185
+ });
186
+
187
+ it("renders EmptyImage when no domains available", async () => {
188
+ useParams.mockImplementationOnce(() => ({ id: undefined }));
189
+ useDomains.mockImplementationOnce(() => ({
190
+ data: [],
191
+ actions: {},
192
+ loading: false,
193
+ }));
194
+ const mockHistoryPush = jest.fn();
195
+ useHistory.mockImplementationOnce(() => ({ push: mockHistoryPush }));
196
+
197
+ const { queryByText } = render(<Domains />, renderOpts);
198
+
199
+ await waitFor(() => {
200
+ expect(
201
+ queryByText(
202
+ "Please, select a domain on the left pane to see the detail."
203
+ )
204
+ ).toBeInTheDocument();
205
+ });
206
+ });
207
+
208
+ it("handles grid control buttons correctly", async () => {
209
+ const { container, queryByText, queryByTestId } = render(
210
+ <Domains />,
211
+ renderOpts
212
+ );
213
+
214
+ await waitFor(() => expect(queryByText(/lazy/i)).not.toBeInTheDocument());
215
+ await waitFor(() =>
216
+ expect(queryByText(/loading/i)).not.toBeInTheDocument()
217
+ );
218
+
219
+ await waitFor(() => {
220
+ expect(
221
+ container.querySelector(".taxonomy-domains-breadcrumb")
222
+ ).toBeInTheDocument();
223
+ });
224
+
225
+ const hideButton = container.querySelector(
226
+ "button[data-tooltip='Hide Domains List']"
227
+ );
228
+
229
+ const minimizeButton = container.querySelector(
230
+ "button[data-tooltip='domains.list.minimize']"
231
+ );
232
+
233
+ const maximizeButton = container.querySelector(
234
+ "button[data-tooltip='domains.list.maximize']"
235
+ );
236
+
237
+ userEvent.click(hideButton);
238
+ await waitFor(() => {
239
+ expect(
240
+ container.querySelector(".taxonomy-domains-grid-animation")
241
+ ).toBeNull();
242
+ });
243
+
244
+ userEvent.click(minimizeButton);
245
+ await waitFor(() => {
246
+ expect(
247
+ container.querySelector(".taxonomy-domains-grid-animation")
248
+ ).toBeNull();
249
+ });
250
+
251
+ userEvent.click(maximizeButton);
252
+ await waitFor(() => {
253
+ expect(
254
+ container.querySelector(".taxonomy-domains-grid-animation")
255
+ ).toBeInTheDocument();
256
+ });
257
+ });
111
258
  });
@@ -1,15 +1,22 @@
1
1
  import React from "react";
2
- import { shallow } from "enzyme";
3
- import { intl } from "@truedat/test/intl-stub";
2
+ import { render } from "@truedat/test/render";
4
3
  import { DomainsActions } from "../DomainsActions";
5
4
 
6
- // workaround for enzyme issue with React.useContext
7
- // see https://github.com/airbnb/enzyme/issues/2176#issuecomment-532361526
8
- jest.spyOn(React, "useContext").mockImplementation(() => intl);
9
-
10
5
  describe("<DomainsActions />", () => {
11
6
  it("matches the latest snapshot", () => {
12
- const wrapper = shallow(<DomainsActions />);
13
- expect(wrapper).toMatchSnapshot();
7
+ const actions = {
8
+ create: { href: "/api/domains", input: {}, method: "POST" },
9
+ index: { href: "/api/domains", input: {}, method: "GET" },
10
+ };
11
+ const { container, getByText } = render(
12
+ <DomainsActions actions={actions} />
13
+ );
14
+ expect(container).toMatchSnapshot();
15
+ expect(getByText("New Domain")).toBeInTheDocument();
16
+ });
17
+
18
+ it("Do not show the button if not have actions", () => {
19
+ const { queryByText } = render(<DomainsActions />);
20
+ expect(queryByText("New Domain")).not.toBeInTheDocument();
14
21
  });
15
22
  });
@@ -50,6 +50,12 @@ exports[`<Domain /> matches the latest snapshot 1`] = `
50
50
  <div
51
51
  class="ui pointing secondary top attached tabular menu"
52
52
  >
53
+ <a
54
+ class="item"
55
+ href="/domains/3"
56
+ >
57
+ Subdomains
58
+ </a>
53
59
  <a
54
60
  class="item"
55
61
  href="/domains/3/concepts"
@@ -81,3 +87,5 @@ exports[`<Domain /> matches the latest snapshot 1`] = `
81
87
  </div>
82
88
  </div>
83
89
  `;
90
+
91
+ exports[`<Domain /> renders null when no has any domain 1`] = `<div />`;