@truedat/dq 4.44.2 → 4.44.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 (48) hide show
  1. package/CHANGELOG.md +8 -1
  2. package/package.json +5 -5
  3. package/src/components/EditRule.js +1 -1
  4. package/src/components/ExecutionForm.js +68 -78
  5. package/src/components/ExecutionPopup.js +10 -6
  6. package/src/components/NewRule.js +1 -1
  7. package/src/components/NewRuleImplementation.js +91 -111
  8. package/src/components/RemediationForm.js +32 -43
  9. package/src/components/RuleForm.js +102 -103
  10. package/src/components/RuleImplementation.js +29 -13
  11. package/src/components/RuleImplementationActions.js +11 -21
  12. package/src/components/RuleImplementationsActions.js +1 -1
  13. package/src/components/RuleResultsRoutes.js +41 -56
  14. package/src/components/RuleRoutes.js +40 -56
  15. package/src/components/RulesRoutes.js +0 -5
  16. package/src/components/__tests__/ExecutionForm.spec.js +7 -1
  17. package/src/components/__tests__/ExecutionPopup.spec.js +3 -2
  18. package/src/components/__tests__/ImplementationResultBar.spec.js +44 -63
  19. package/src/components/__tests__/InformationSummary.spec.js +2 -6
  20. package/src/components/__tests__/NewRuleImplementation.spec.js +4 -6
  21. package/src/components/__tests__/RemediationForm.spec.js +47 -58
  22. package/src/components/__tests__/RuleForm.spec.js +80 -207
  23. package/src/components/__tests__/RuleImplementation.spec.js +45 -22
  24. package/src/components/__tests__/RuleImplementationsActions.spec.js +0 -1
  25. package/src/components/__tests__/RuleImplementationsOptions.spec.js +1 -10
  26. package/src/components/__tests__/RuleResultsUpload.spec.js +1 -5
  27. package/src/components/__tests__/RuleSummary.spec.js +6 -11
  28. package/src/components/__tests__/__snapshots__/EditRule.spec.js.snap +1 -1
  29. package/src/components/__tests__/__snapshots__/ExecutionForm.spec.js.snap +1 -2
  30. package/src/components/__tests__/__snapshots__/NewRule.spec.js.snap +1 -1
  31. package/src/components/__tests__/__snapshots__/RemediationForm.spec.js.snap +2 -3
  32. package/src/components/__tests__/__snapshots__/RuleForm.spec.js.snap +699 -385
  33. package/src/components/__tests__/__snapshots__/RuleImplementation.spec.js.snap +71 -5
  34. package/src/components/__tests__/__snapshots__/RuleImplementationsActions.spec.js.snap +1 -1
  35. package/src/components/index.js +0 -2
  36. package/src/components/ruleImplementationForm/InformationForm.js +40 -76
  37. package/src/components/ruleImplementationForm/RuleImplementationForm.js +40 -40
  38. package/src/components/ruleImplementationForm/RuleImplementationRawForm.js +63 -101
  39. package/src/components/ruleImplementationForm/__tests__/LimitsForm.spec.js +9 -35
  40. package/src/components/ruleImplementationForm/__tests__/RuleImplementationForm.spec.js +23 -50
  41. package/src/components/ruleImplementationForm/__tests__/RuleImplementationRawForm.spec.js +2 -2
  42. package/src/components/ruleImplementationForm/__tests__/__snapshots__/RuleImplementationForm.spec.js.snap +86 -19
  43. package/src/components/ruleImplementationForm/__tests__/__snapshots__/RuleImplementationRawForm.spec.js.snap +7 -1
  44. package/src/messages/en.js +3 -6
  45. package/src/messages/es.js +3 -6
  46. package/src/components/DynamicRuleForm.js +0 -78
  47. package/src/components/__tests__/DynamicRuleForm.spec.js +0 -51
  48. package/src/components/__tests__/__snapshots__/DynamicRuleForm.spec.js.snap +0 -3
@@ -1,222 +1,95 @@
1
1
  import React from "react";
2
- import { shallowWithIntl } from "@truedat/test/intl-stub";
3
- import { applyTemplate } from "@truedat/df/utils";
4
- import { RuleForm, FieldLabelWrapping } from "../RuleForm";
5
-
6
- describe("<RuleForm />", () => {
7
- const rule = {
8
- id: 123,
9
- business_concept_id: "2D2B3",
10
- name: "control1",
11
- description: {
12
- document: {
13
- data: {},
14
- object: "document",
15
- nodes: [
16
- {
17
- data: {},
18
- nodes: [
19
- { marks: [{ data: {}, object: "text", text: "description" }] },
20
- ],
21
- },
22
- ],
23
- },
2
+ import { waitFor } from "@testing-library/react";
3
+ import userEvent from "@testing-library/user-event";
4
+ import { render } from "@truedat/test/render";
5
+ import { TEMPLATES_QUERY } from "@truedat/core/api/queries";
6
+ import RuleForm from "../RuleForm";
7
+
8
+ const templatesMock = {
9
+ request: { query: TEMPLATES_QUERY, variables: { scope: "remediation" } },
10
+ result: {
11
+ data: {
12
+ templates: [
13
+ {
14
+ id: "1",
15
+ name: "template1",
16
+ label: "template1",
17
+ scope: "remediation",
18
+ content: [
19
+ { name: "g1", fields: [{ name: "field1", label: "field1" }] },
20
+ ],
21
+ },
22
+ {
23
+ id: "2",
24
+ name: "template2",
25
+ label: "template2",
26
+ scope: "remediation",
27
+ content: {},
28
+ },
29
+ ],
24
30
  },
25
- current_business_concept_version: { name: "My Concept" },
26
- };
27
- const handleSubmit = jest.fn();
28
- const selectDomain = jest.fn();
29
- const isSubmitting = false;
30
- const business_concept_id = 123;
31
-
32
- const templatesLoaded = true;
33
- const template = {};
34
-
35
- const history = { goBack: jest.fn() };
36
- const match = { params: {} };
37
- const domain = { id: 1, name: "foo", external_id: "foo" };
38
- const defaultProps = {
39
- handleSubmit,
40
- templatesLoaded,
41
- isSubmitting,
42
- template,
43
- business_concept_id,
44
- history,
45
- match,
46
- selectDomain,
47
- applyTemplate: applyTemplate(template),
48
- };
31
+ },
32
+ };
49
33
 
50
- const eventMock = {
51
- preventDefault: jest.fn(),
52
- };
53
- const findField = (wrapper, name) => wrapper.find({ name });
34
+ const rule = {
35
+ id: 123,
36
+ business_concept_id: "2D2B3",
37
+ name: "control1",
38
+ current_business_concept_version: { name: "My Concept" },
39
+ };
54
40
 
55
- it("matches the latest snapshot for editMode", () => {
56
- const editMode = true;
57
- const props = {
58
- rule,
59
- handleSubmit,
60
- templatesLoaded,
61
- editMode,
62
- isSubmitting,
63
- template,
64
- business_concept_id,
65
- applyTemplate: applyTemplate(template),
66
- };
67
-
68
- const wrapper = shallowWithIntl(<RuleForm {...props} />);
69
- expect(wrapper).toMatchSnapshot();
70
- });
71
-
72
- it("matches the latest snapshot for create", () => {
73
- const wrapper = shallowWithIntl(<RuleForm {...defaultProps} />);
74
- expect(wrapper).toMatchSnapshot();
75
- });
76
-
77
- it("doesnt call handleSubmit when submitting invalid form", () => {
78
- const wrapper = shallowWithIntl(<RuleForm {...defaultProps} />);
79
-
80
- expect(handleSubmit.mock.calls.length).toBe(0);
81
- const form = wrapper.find("Form");
82
- form.simulate("submit", eventMock);
83
- expect(handleSubmit.mock.calls.length).toBe(0);
84
- });
85
-
86
- it("calls handleSubmit when submitting valid form", () => {
87
- const editMode = true;
88
- const props = {
89
- rule: { ...rule, domain_id: domain.id },
90
- handleSubmit,
91
- templatesLoaded,
92
- editMode,
93
- isSubmitting,
94
- template,
95
- business_concept_id,
96
- selectDomain,
97
- match,
98
- applyTemplate: applyTemplate(template),
99
- };
100
- const wrapper = shallowWithIntl(<RuleForm {...props} />);
101
-
102
- wrapper.find({ name: "dynamicForm" }).props().handleContentChange({});
103
-
104
- expect(handleSubmit.mock.calls.length).toBe(0);
105
- const form = wrapper.find("Form");
106
- form.simulate("submit", eventMock);
107
- expect(handleSubmit.mock.calls.length).toBe(1);
108
- });
41
+ const state = {
42
+ conceptActiveFilters: {},
43
+ domains: [{ id: 1, name: "domain1" }],
44
+ };
109
45
 
110
- it("handles correctly active field", () => {
111
- const wrapper = shallowWithIntl(<RuleForm {...defaultProps} />);
46
+ const renderOpts = { mocks: [templatesMock], state };
112
47
 
113
- expect(findField(wrapper, "active").props().checked).toEqual(true);
114
- findField(wrapper, "active").simulate("change", eventMock, {
115
- name: "active",
116
- checked: false,
48
+ describe("<RuleForm />", () => {
49
+ it("matches the latest snapshot", async () => {
50
+ const props = { onSubmit: jest.fn() };
51
+ const { container, queryByText } = render(
52
+ <React.Suspense fallback="loading...">
53
+ <RuleForm {...props} />
54
+ </React.Suspense>,
55
+ renderOpts
56
+ );
57
+ await waitFor(() => {
58
+ expect(queryByText(/loading/i)).not.toBeInTheDocument();
117
59
  });
118
- expect(findField(wrapper, "active").props().checked).toEqual(false);
119
- });
120
-
121
- it("handles domain selection", () => {
122
- const wrapper = shallowWithIntl(<RuleForm {...defaultProps} />);
123
- const DomainSelector = wrapper.find({ name: "domain" });
124
- DomainSelector.simulate("change", eventMock, { value: domain.id });
125
- expect(selectDomain).toHaveBeenCalledWith({ id: domain.id });
126
- expect(wrapper.find({ name: "domain" }).prop("value")).toBe(domain.id);
127
- expect(wrapper.find("Segment").at(0).prop("disabled")).toBeFalsy();
60
+ expect(container).toMatchSnapshot();
128
61
  });
129
62
 
130
- describe("<FieldLabelWrapping />", () => {
131
- it("matches the latest snapshot full", () => {
132
- const props = {
133
- children: <>child</>,
134
- label: "label",
135
- required: true,
136
- tooltip: "tooltip",
137
- messages: ["message"],
138
- };
139
-
140
- const wrapper = shallowWithIntl(<FieldLabelWrapping {...props} />);
141
- expect(wrapper).toMatchSnapshot();
142
- });
143
- it("matches the latest snapshot no messages", () => {
144
- const props = {
145
- children: <>child</>,
146
- label: "label",
147
- required: true,
148
- tooltip: "tooltip",
149
- };
150
-
151
- const wrapper = shallowWithIntl(<FieldLabelWrapping {...props} />);
152
- expect(wrapper).toMatchSnapshot();
153
- });
154
- it("matches the latest snapshot no tooltip", () => {
155
- const props = {
156
- children: <>child</>,
157
- label: "label",
158
- required: true,
159
- messages: ["message"],
160
- };
161
-
162
- const wrapper = shallowWithIntl(<FieldLabelWrapping {...props} />);
163
- expect(wrapper).toMatchSnapshot();
164
- });
165
- it("matches the latest snapshot not required", () => {
166
- const props = {
167
- children: <>child</>,
168
- label: "label",
169
- tooltip: "tooltip",
170
- messages: ["message"],
171
- };
172
-
173
- const wrapper = shallowWithIntl(<FieldLabelWrapping {...props} />);
174
- expect(wrapper).toMatchSnapshot();
63
+ it("matches the latest snapshot (edit mode)", async () => {
64
+ const props = { onSubmit: jest.fn(), editMode: true };
65
+ const { container, queryByText } = render(
66
+ <React.Suspense fallback="loading...">
67
+ <RuleForm {...props} />
68
+ </React.Suspense>,
69
+ { ...renderOpts, state: { ...state, rule } }
70
+ );
71
+ await waitFor(() => {
72
+ expect(queryByText(/loading/i)).not.toBeInTheDocument();
175
73
  });
74
+ expect(container).toMatchSnapshot();
75
+ });
176
76
 
177
- it("shows concept selector when concept prop is empty", () => {
178
- const concept = {};
179
- const props = {
180
- rule,
181
- handleSubmit,
182
- templatesLoaded,
183
- isSubmitting,
184
- template,
185
- business_concept_id,
186
- concept,
187
- applyTemplate: applyTemplate(template),
188
- };
189
-
190
- const wrapper = shallowWithIntl(<RuleForm {...props} />);
191
- expect(
192
- wrapper.find("AccordionContent").children().find("lazy").length
193
- ).toBe(1);
194
- wrapper.setProps({
195
- concept: { business_concept_id: 1, name: "some name" },
196
- });
197
- expect(wrapper.find("Accordion").length).toBe(0);
77
+ it("enables save button after name and domain are specified", async () => {
78
+ const props = { onSubmit: jest.fn() };
79
+ const { getByRole, queryByText } = render(
80
+ <React.Suspense fallback="loading...">
81
+ <RuleForm {...props} />
82
+ </React.Suspense>,
83
+ renderOpts
84
+ );
85
+ await waitFor(() => {
86
+ expect(queryByText(/loading/i)).not.toBeInTheDocument();
198
87
  });
199
-
200
- it("when accordion label is clicked handleConceptSelected is called", () => {
201
- const concept = {};
202
- const props = {
203
- rule,
204
- handleSubmit,
205
- templatesLoaded,
206
- isSubmitting,
207
- template,
208
- business_concept_id,
209
- concept,
210
- applyTemplate: applyTemplate(template),
211
- };
212
-
213
- const wrapper = shallowWithIntl(<RuleForm {...props} />);
214
- const instance = wrapper.instance();
215
- const label = wrapper.find("Label").find({ name: "delete" });
216
- jest.spyOn(instance, "handleConceptSelected");
217
- label.simulate("click", eventMock);
218
- expect(instance.handleConceptSelected.mock.calls.length).toBe(1);
219
- expect(instance.handleConceptSelected).toHaveBeenCalledWith(null);
88
+ expect(getByRole("button", { name: /save/i })).toBeDisabled();
89
+ userEvent.click(getByRole("option", { name: "domain1" }));
90
+ userEvent.type(getByRole("textbox", { name: /rule name/i }), "rule1");
91
+ await waitFor(() => {
92
+ expect(getByRole("button", { name: /save/i })).not.toBeDisabled();
220
93
  });
221
94
  });
222
95
  });
@@ -9,37 +9,60 @@ const state = {
9
9
  rule_id: 1,
10
10
  implementation_key: "impl key",
11
11
  id: 1,
12
+ executable: true,
12
13
  },
13
- userRulePermissions: {
14
- manage_quality_rule_implementations: true,
15
- manage_quality_rules: true,
14
+ };
15
+
16
+ const stateExecutePermission = {
17
+ ...state,
18
+ implementationActions: {
19
+ manage: true,
20
+ link_concept: true,
21
+ execute: true,
16
22
  },
17
- implementationActions: { link_concept: true },
18
23
  };
19
24
 
20
- const renderOpts = {
21
- messages: {
22
- en: {
23
- "quality.result.no.data": "No information about quality",
24
- "ruleImplementation.actions.clone": "clone",
25
- "ruleImplementation.actions.delete.confirmation.content": "confirm",
26
- "ruleImplementation.actions.delete.confirmation.header": "header",
27
- "ruleImplementation.actions.deprecate": "archive",
28
- "ruleImplementation.actions.edit": "edit",
29
- "ruleImplementation.actions.move": "move",
30
- "tabs.dq.implementation.links.concepts": "Related concepts",
31
- "tabs.dq.implementation.structures": "Structures",
32
- "tabs.dq.ruleImplementation.audit": "events",
33
- "tabs.dq.ruleImplementation.results": "results",
34
- "tabs.dq.ruleImplementation": "implementation",
35
- },
25
+ const stateNoExecutePermission = {
26
+ ...state,
27
+ implementationActions: {
28
+ manage: true,
29
+ link_concept: true,
30
+ execute: false,
36
31
  },
37
- state,
32
+ };
33
+
34
+ const renderOptsNoExecutePermission = {
35
+ state: stateNoExecutePermission,
36
+ };
37
+
38
+ const renderOptsExecutePermission = {
39
+ state: stateExecutePermission,
38
40
  };
39
41
 
40
42
  describe("<RuleImplementation />", () => {
41
43
  it("matches the latest snapshot", () => {
42
- const { container } = render(<RuleImplementation />, renderOpts);
44
+ const { container } = render(
45
+ <RuleImplementation />,
46
+ renderOptsExecutePermission
47
+ );
43
48
  expect(container).toMatchSnapshot();
44
49
  });
50
+
51
+ it("presence of execute permissions enables the execute button", () => {
52
+ const { queryByText } = render(
53
+ <RuleImplementation />,
54
+ renderOptsExecutePermission
55
+ );
56
+ const button = queryByText(/execute/i);
57
+ expect(button).toBeInTheDocument();
58
+ });
59
+
60
+ it("lack of execute permissions disables the execute button", () => {
61
+ const { queryByText } = render(
62
+ <RuleImplementation />,
63
+ renderOptsNoExecutePermission
64
+ );
65
+ const button = queryByText(/execute/i);
66
+ expect(button).not.toBeInTheDocument();
67
+ });
45
68
  });
@@ -1,4 +1,3 @@
1
- import _ from "lodash/fp";
2
1
  import React from "react";
3
2
  import { shallow } from "enzyme";
4
3
  import { intl } from "@truedat/test/intl-stub";
@@ -1,22 +1,13 @@
1
1
  import React from "react";
2
2
  import { waitFor } from "@testing-library/react";
3
3
  import { render } from "@truedat/test/render";
4
- import coreEn from "@truedat/core/messages/en";
5
4
  import RuleImplementationsOptions from "../RuleImplementationsOptions";
6
- import en from "../../messages/en";
7
-
8
- const renderOpts = {
9
- messages: { en: { ...coreEn, ...en } },
10
- };
11
5
 
12
6
  const props = { canUploadResults: true };
13
7
 
14
8
  describe("<RuleImplementationsOptions />", () => {
15
9
  it("matches the latest snapshot", async () => {
16
- const { container } = render(
17
- <RuleImplementationsOptions {...props} />,
18
- renderOpts
19
- );
10
+ const { container } = render(<RuleImplementationsOptions {...props} />);
20
11
  await waitFor(() => expect(container).toMatchSnapshot());
21
12
  });
22
13
  });
@@ -1,15 +1,11 @@
1
1
  import React from "react";
2
2
  import { waitFor } from "@testing-library/react";
3
3
  import { render } from "@truedat/test/render";
4
- import coreEn from "@truedat/core/messages/en";
5
4
  import RuleResultsUpload from "../RuleResultsUpload";
6
- import en from "../../messages/en";
7
-
8
- const renderOpts = { messages: { en: { ...coreEn, ...en } } };
9
5
 
10
6
  describe("<RuleResultsUpload />", () => {
11
7
  it("matches the latest snapshot", async () => {
12
- const { container } = render(<RuleResultsUpload />, renderOpts);
8
+ const { container } = render(<RuleResultsUpload />);
13
9
  await waitFor(() => expect(container).toMatchSnapshot());
14
10
  });
15
11
  });
@@ -1,8 +1,7 @@
1
1
  import React from "react";
2
- import { render } from "@truedat/test/render";
3
2
  import { fireEvent } from "@testing-library/react";
3
+ import { render } from "@truedat/test/render";
4
4
  import { RuleSummary } from "../RuleSummary";
5
- import messages from "../../messages/en";
6
5
 
7
6
  describe("<RuleSummary />", () => {
8
7
  const implementationLimits = {
@@ -40,15 +39,11 @@ describe("<RuleSummary />", () => {
40
39
  },
41
40
  };
42
41
 
43
- const renderOpts = {
44
- messages: { en: messages },
45
- };
46
-
47
42
  it("render 100% overGoal implementations", () => {
48
43
  const props = {
49
44
  implementations: [overGoalExecution],
50
45
  };
51
- const { container } = render(<RuleSummary {...props} />, renderOpts);
46
+ const { container } = render(<RuleSummary {...props} />);
52
47
  expect(container).toMatchSnapshot();
53
48
  expect(container).toHaveTextContent("100%");
54
49
  });
@@ -61,7 +56,7 @@ describe("<RuleSummary />", () => {
61
56
  underMinimumExecution,
62
57
  ],
63
58
  };
64
- const { container } = render(<RuleSummary {...props} />, renderOpts);
59
+ const { container } = render(<RuleSummary {...props} />);
65
60
  expect(container).toMatchSnapshot();
66
61
  expect(container).toHaveTextContent("33%");
67
62
  });
@@ -70,7 +65,7 @@ describe("<RuleSummary />", () => {
70
65
  const props = {
71
66
  implementations: [notExecuted, failedExecution],
72
67
  };
73
- const { container } = render(<RuleSummary {...props} />, renderOpts);
68
+ const { container } = render(<RuleSummary {...props} />);
74
69
  expect(container).toMatchSnapshot();
75
70
  expect(container).toHaveTextContent("50%");
76
71
  });
@@ -79,7 +74,7 @@ describe("<RuleSummary />", () => {
79
74
  const props = {
80
75
  implementations: [],
81
76
  };
82
- const { container } = render(<RuleSummary {...props} />, renderOpts);
77
+ const { container } = render(<RuleSummary {...props} />);
83
78
  expect(container).toMatchSnapshot();
84
79
  });
85
80
 
@@ -92,7 +87,7 @@ describe("<RuleSummary />", () => {
92
87
  underMinimumExecution,
93
88
  ],
94
89
  };
95
- const { container } = render(<RuleSummary {...props} />, renderOpts);
90
+ const { container } = render(<RuleSummary {...props} />);
96
91
  expect(container).toMatchSnapshot();
97
92
  expect(container.querySelector(".over-goal-color")).toHaveTextContent(
98
93
  "75%"
@@ -20,7 +20,7 @@ exports[`<EditRule /> matches the latest snapshot 1`] = `
20
20
  </Header>
21
21
  <withRouter(injectIntl(Connect(RuleForm)))
22
22
  editMode={true}
23
- handleSubmit={[MockFunction]}
23
+ onSubmit={[MockFunction]}
24
24
  rule={
25
25
  Object {
26
26
  "description": "dd",
@@ -8,8 +8,7 @@ exports[`<ExecutionForm /> matches the latest snapshot 1`] = `
8
8
  header
9
9
  </h2>
10
10
  <form
11
- class="ui form"
12
- style="display: none;"
11
+ class="ui loading form"
13
12
  >
14
13
  <p>
15
14
  content
@@ -22,7 +22,7 @@ exports[`<NewRule /> matches the latest snapshot 1`] = `
22
22
  actions="manage_quality_rule"
23
23
  />
24
24
  <withRouter(injectIntl(Connect(RuleForm)))
25
- handleSubmit={[MockFunction]}
25
+ onSubmit={[MockFunction]}
26
26
  />
27
27
  </Container>
28
28
  `;
@@ -1,18 +1,17 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
- exports[`<RemediationForm /> with multiple templates matches the latest snapshot 1`] = `
3
+ exports[`<RemediationForm /> matches the latest snapshot 1`] = `
4
4
  <div>
5
5
  <form
6
6
  aria-label="remediation-form"
7
7
  class="ui form"
8
- style="display: none;"
9
8
  >
10
9
  <button
11
10
  class="ui primary disabled button"
12
11
  disabled=""
13
12
  tabindex="-1"
14
13
  >
15
- actions.create
14
+ Create
16
15
  </button>
17
16
  </form>
18
17
  </div>