@truedat/dq 8.4.3 → 8.4.5

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@truedat/dq",
3
- "version": "8.4.3",
3
+ "version": "8.4.5",
4
4
  "description": "Truedat Web Data Quality Module",
5
5
  "sideEffects": false,
6
6
  "module": "src/index.js",
@@ -56,7 +56,7 @@
56
56
  "@testing-library/jest-dom": "^6.6.3",
57
57
  "@testing-library/react": "^16.3.0",
58
58
  "@testing-library/user-event": "^14.6.1",
59
- "@truedat/test": "8.4.3",
59
+ "@truedat/test": "8.4.5",
60
60
  "identity-obj-proxy": "^3.0.0",
61
61
  "jest": "^29.7.0",
62
62
  "redux-saga-test-plan": "^4.0.6"
@@ -89,5 +89,5 @@
89
89
  "semantic-ui-react": "^3.0.0-beta.2",
90
90
  "swr": "^2.3.3"
91
91
  },
92
- "gitHead": "4c27fe8b467a2b0b26f69d4931d85d8bdf674e6d"
92
+ "gitHead": "b02bd52fc13d8e811993059bc50085f841415c91"
93
93
  }
@@ -124,7 +124,11 @@ export const Subscription = ({
124
124
 
125
125
  const className = subscribed ? "secondary" : "";
126
126
 
127
- const handleSubmit = () => {
127
+ const handleSubmit = (e) => {
128
+ if (e) {
129
+ e.preventDefault();
130
+ e.stopPropagation();
131
+ }
128
132
  const payload = {
129
133
  ...{
130
134
  subscription: {
@@ -175,7 +179,11 @@ export const Subscription = ({
175
179
  }
176
180
  };
177
181
 
178
- const handleDelete = () => {
182
+ const handleDelete = (e) => {
183
+ if (e) {
184
+ e.preventDefault();
185
+ e.stopPropagation();
186
+ }
179
187
  const payload = {
180
188
  ...{
181
189
  subscription: subscriptionField,
@@ -191,7 +199,10 @@ export const Subscription = ({
191
199
  };
192
200
 
193
201
  const handleChange = (e, { name, value }) => {
194
- e && e.preventDefault() && e.stopPropagation();
202
+ if (e) {
203
+ e.preventDefault();
204
+ e.stopPropagation();
205
+ }
195
206
  setSubscription({ ...subscriptionField, [name]: value });
196
207
  };
197
208
 
@@ -1,7 +1,11 @@
1
1
  import userEvent from "@testing-library/user-event";
2
2
  import { waitFor } from "@testing-library/react";
3
3
  import { render, waitForLoad } from "@truedat/test/render";
4
- import { Subscription, SubscriptionContent } from "../Subscription";
4
+ import {
5
+ Subscription,
6
+ SubscriptionContent,
7
+ mapStateToProps,
8
+ } from "../Subscription";
5
9
 
6
10
  describe("<SubscriptionContent />", () => {
7
11
  const subscription = {
@@ -43,6 +47,23 @@ describe("<SubscriptionContent />", () => {
43
47
  await user.click(rendered.getByText(/subscriptions.status.success/i));
44
48
  expect(setSubscription).toHaveBeenCalled();
45
49
  });
50
+
51
+ it("removes status when selecting an already selected event type", async () => {
52
+ const props = {
53
+ subscription,
54
+ setSubscription,
55
+ };
56
+ const rendered = render(<SubscriptionContent {...props} />);
57
+ await waitForLoad(rendered);
58
+
59
+ const user = userEvent.setup({ delay: null });
60
+ await user.click(rendered.getByText(/subscriptions.status.warn/i));
61
+
62
+ expect(setSubscription).toHaveBeenCalledWith({
63
+ ...subscription,
64
+ scope: { status: [] },
65
+ });
66
+ });
46
67
  });
47
68
 
48
69
  describe("<Subscription />", () => {
@@ -102,4 +123,121 @@ describe("<Subscription />", () => {
102
123
  expect(rendered.queryByText(/actions.save/i)).not.toBeInTheDocument()
103
124
  );
104
125
  });
126
+
127
+ it("updates periodicity when selecting another radio option", async () => {
128
+ const rendered = render(<Subscription {...props} />);
129
+ await waitForLoad(rendered);
130
+
131
+ const user = userEvent.setup({ delay: null });
132
+ await user.click(rendered.getByRole("button"));
133
+ await user.click(
134
+ await rendered.findByText(/subscriptions.periodicity.hourly/i)
135
+ );
136
+ await user.click(await rendered.findByText(/actions.save/i));
137
+
138
+ expect(updateSubscription).toHaveBeenCalledWith(
139
+ expect.objectContaining({
140
+ subscription: expect.objectContaining({ periodicity: "hourly" }),
141
+ })
142
+ );
143
+ });
144
+
145
+ it("deletes subscription and closes popup", async () => {
146
+ const rendered = render(<Subscription {...props} />);
147
+ await waitForLoad(rendered);
148
+
149
+ const user = userEvent.setup({ delay: null });
150
+ await user.click(rendered.getByRole("button"));
151
+ await user.click(
152
+ await rendered.findByText(/ruleSubscription.actions.remove/i)
153
+ );
154
+
155
+ expect(deleteSubscription).toHaveBeenCalledWith(
156
+ expect.objectContaining({
157
+ resource_id: 1,
158
+ resource_type: "rule",
159
+ })
160
+ );
161
+
162
+ await waitFor(() =>
163
+ expect(
164
+ rendered.queryByText(/ruleSubscription.actions.remove/i)
165
+ ).not.toBeInTheDocument()
166
+ );
167
+ });
168
+
169
+ it("handles implementation payload fields on save and delete", async () => {
170
+ const implementationProps = {
171
+ ...props,
172
+ resource: {
173
+ id: 9,
174
+ implementation_key: "impl-key",
175
+ implementation_ref: "impl-ref",
176
+ },
177
+ resourceType: "implementation",
178
+ searchSubscription: {
179
+ ...searchSubscription,
180
+ scope: { ...searchSubscription.scope, status: ["success"] },
181
+ },
182
+ };
183
+ const rendered = render(<Subscription {...implementationProps} />);
184
+ await waitForLoad(rendered);
185
+
186
+ const user = userEvent.setup({ delay: null });
187
+ await user.click(rendered.getByRole("button"));
188
+ await user.click(await rendered.findByText(/actions.save/i));
189
+
190
+ expect(updateSubscription).toHaveBeenCalledWith(
191
+ expect.objectContaining({
192
+ implementation_id: 9,
193
+ subscription: expect.objectContaining({
194
+ scope: expect.objectContaining({
195
+ resource_id: "impl-ref",
196
+ resource_name: "impl-key",
197
+ resource_type: "implementation",
198
+ }),
199
+ }),
200
+ })
201
+ );
202
+
203
+ await user.click(rendered.getByRole("button"));
204
+ await user.click(
205
+ await rendered.findByText(/ruleSubscription.actions.remove/i)
206
+ );
207
+
208
+ expect(deleteSubscription).toHaveBeenCalledWith(
209
+ expect.objectContaining({
210
+ implementation_id: 9,
211
+ resource_id: 9,
212
+ resource_type: "implementation",
213
+ })
214
+ );
215
+ });
216
+
217
+ it("closes popup when clicking outside", async () => {
218
+ const rendered = render(<Subscription {...props} />);
219
+ await waitForLoad(rendered);
220
+
221
+ const user = userEvent.setup({ delay: null });
222
+ await user.click(rendered.getByRole("button"));
223
+ expect(await rendered.findByText(/actions.save/i)).toBeInTheDocument();
224
+
225
+ await user.click(document.body);
226
+
227
+ await waitFor(() =>
228
+ expect(rendered.queryByText(/actions.save/i)).not.toBeInTheDocument()
229
+ );
230
+ });
231
+
232
+ it("maps state to props", () => {
233
+ const state = {
234
+ searchSubscription: { id: 12 },
235
+ subscriptionUpdating: true,
236
+ };
237
+
238
+ expect(mapStateToProps(state)).toEqual({
239
+ searchSubscription: { id: 12 },
240
+ subscriptionUpdating: true,
241
+ });
242
+ });
105
243
  });
@@ -1,6 +1,15 @@
1
- import { clearRedirect } from "@truedat/core/routines";
2
1
  import {
2
+ clearRedirect,
3
+ createSubscription,
4
+ deleteSubscription,
5
+ updateSubscription,
6
+ } from "@truedat/core/routines";
7
+ import { IMPLEMENTATIONS, linkTo } from "@truedat/core/routes";
8
+ import {
9
+ createExecutionGroup,
10
+ createImplementationStructure,
3
11
  createRuleImplementation,
12
+ uploadImplementations,
4
13
  updateRuleImplementation,
5
14
  deleteRuleResult,
6
15
  } from "../../routines";
@@ -52,4 +61,92 @@ describe("reducers: ruleImplementationRedirect", () => {
52
61
  })
53
62
  ).toBe("/implementations/2/results");
54
63
  });
64
+
65
+ it("should keep current state after createSubscription.SUCCESS action", () => {
66
+ const payload = { implementation_id: 311 };
67
+
68
+ expect(
69
+ ruleImplementationRedirect(fooState, {
70
+ type: createSubscription.SUCCESS,
71
+ payload,
72
+ })
73
+ ).toBe(fooState);
74
+ });
75
+
76
+ it("should keep current state after updateSubscription.SUCCESS action", () => {
77
+ const payload = { implementation_id: 311 };
78
+
79
+ expect(
80
+ ruleImplementationRedirect(fooState, {
81
+ type: updateSubscription.SUCCESS,
82
+ payload,
83
+ })
84
+ ).toBe(fooState);
85
+ });
86
+
87
+ it("should keep current state after deleteSubscription.SUCCESS action", () => {
88
+ const payload = { implementation_id: 311 };
89
+
90
+ expect(
91
+ ruleImplementationRedirect(fooState, {
92
+ type: deleteSubscription.SUCCESS,
93
+ payload,
94
+ })
95
+ ).toBe(fooState);
96
+ });
97
+
98
+ it("should return implementation concepts link after createRuleImplementation.FAILURE action with implementation_id", () => {
99
+ const payload = { implementation_id: 2 };
100
+
101
+ expect(
102
+ ruleImplementationRedirect(fooState, {
103
+ type: createRuleImplementation.FAILURE,
104
+ payload,
105
+ })
106
+ ).toBe(
107
+ linkTo.IMPLEMENTATION_CONCEPT_LINKS({
108
+ implementation_id: payload.implementation_id,
109
+ })
110
+ );
111
+ });
112
+
113
+ it("should keep current state after createRuleImplementation.FAILURE action without implementation_id", () => {
114
+ expect(
115
+ ruleImplementationRedirect(fooState, {
116
+ type: createRuleImplementation.FAILURE,
117
+ payload: {},
118
+ })
119
+ ).toBe(fooState);
120
+ });
121
+
122
+ it("should return redirectUrl after createImplementationStructure.SUCCESS action", () => {
123
+ const payload = { redirectUrl: "/custom/redirect" };
124
+
125
+ expect(
126
+ ruleImplementationRedirect(fooState, {
127
+ type: createImplementationStructure.SUCCESS,
128
+ payload,
129
+ })
130
+ ).toBe("/custom/redirect");
131
+ });
132
+
133
+ it("should return execution group link after createExecutionGroup.SUCCESS action", () => {
134
+ const payload = { data: { id: 10 } };
135
+
136
+ expect(
137
+ ruleImplementationRedirect(fooState, {
138
+ type: createExecutionGroup.SUCCESS,
139
+ payload,
140
+ })
141
+ ).toBe(linkTo.EXECUTION_GROUP({ id: 10 }));
142
+ });
143
+
144
+ it("should return implementations route after uploadImplementations.SUCCESS action", () => {
145
+ expect(
146
+ ruleImplementationRedirect(fooState, {
147
+ type: uploadImplementations.SUCCESS,
148
+ payload: {},
149
+ })
150
+ ).toBe(IMPLEMENTATIONS);
151
+ });
55
152
  });
@@ -1,5 +1,6 @@
1
1
  import { linkTo, RULES } from "@truedat/core/routes";
2
2
  import {
3
+ clearRedirect,
3
4
  createSubscription,
4
5
  deleteSubscription,
5
6
  updateSubscription,
@@ -8,6 +9,8 @@ import {
8
9
  createRule,
9
10
  deleteRule,
10
11
  deleteImplementation,
12
+ updateRule,
13
+ uploadRules,
11
14
  submitImplementation,
12
15
  publishImplementation,
13
16
  rejectImplementation,
@@ -34,33 +37,51 @@ describe("reducers: ruleImplementationRedirect", () => {
34
37
  expect(ruleRedirect(fooState, deleteRule.success(payload))).toBe(RULES);
35
38
  });
36
39
 
37
- it("should return a link to Rule after updateSubscription.SUCCESS action", () => {
40
+ it("should be true after receiving the clearRedirect.TRIGGER action", () => {
41
+ expect(ruleRedirect(fooState, { type: clearRedirect.TRIGGER })).toBe(
42
+ initialState
43
+ );
44
+ });
45
+
46
+ it("should return redirectUrl after updateRule.SUCCESS action", () => {
47
+ const redirectUrl = "/rules/22";
48
+ const action = {
49
+ type: updateRule.SUCCESS,
50
+ payload: { data: { id: 22 } },
51
+ meta: { redirectUrl },
52
+ };
53
+ expect(ruleRedirect(fooState, action)).toBe(redirectUrl);
54
+ });
55
+
56
+ it("should return RULES route after uploadRules.SUCCESS action", () => {
57
+ const payload = {};
58
+ expect(ruleRedirect(fooState, uploadRules.success(payload))).toBe(RULES);
59
+ });
60
+
61
+ it("should keep current state after updateSubscription.SUCCESS action", () => {
38
62
  const rule_id = 2;
39
63
  const payload = { rule_id };
40
- const url = linkTo.RULE({ id: rule_id });
41
64
 
42
65
  expect(ruleRedirect(fooState, updateSubscription.success(payload))).toBe(
43
- url
66
+ fooState
44
67
  );
45
68
  });
46
69
 
47
- it("should return a link to Rule after deleteSubscription.SUCCESS action", () => {
70
+ it("should keep current state after deleteSubscription.SUCCESS action", () => {
48
71
  const rule_id = 2;
49
72
  const payload = { rule_id };
50
- const url = linkTo.RULE({ id: rule_id });
51
73
 
52
74
  expect(ruleRedirect(fooState, deleteSubscription.success(payload))).toBe(
53
- url
75
+ fooState
54
76
  );
55
77
  });
56
78
 
57
- it("should return a link to Rule after createSubscription.SUCCESS action", () => {
79
+ it("should keep current state after createSubscription.SUCCESS action", () => {
58
80
  const rule_id = 2;
59
81
  const payload = { rule_id };
60
- const url = linkTo.RULE({ id: rule_id });
61
82
 
62
83
  expect(ruleRedirect(fooState, createSubscription.success(payload))).toBe(
63
- url
84
+ fooState
64
85
  );
65
86
  });
66
87
 
@@ -72,6 +93,13 @@ describe("reducers: ruleImplementationRedirect", () => {
72
93
  );
73
94
  });
74
95
 
96
+ it("should return current state on deleteImplementation.SUCCESS action without redirectUrl", () => {
97
+ const payload = {};
98
+ expect(ruleRedirect(fooState, deleteImplementation.success(payload))).toBe(
99
+ fooState
100
+ );
101
+ });
102
+
75
103
  it("should return the current state on submitImplementation.SUCCESS action", () => {
76
104
  const payload = { data: {} };
77
105
  expect(ruleRedirect(fooState, submitImplementation.success(payload))).toBe(
@@ -1,4 +1,3 @@
1
- import _ from "lodash/fp";
2
1
  import { IMPLEMENTATIONS, linkTo } from "@truedat/core/routes";
3
2
  import {
4
3
  clearRedirect,
@@ -61,12 +60,8 @@ export const ruleImplementationRedirect = (
61
60
  }
62
61
  case createSubscription.SUCCESS:
63
62
  case deleteSubscription.SUCCESS:
64
- case updateSubscription.SUCCESS: {
65
- const { implementation_id } = payload;
66
- return _.isNil(implementation_id)
67
- ? state
68
- : linkTo.IMPLEMENTATION({ implementation_id });
69
- }
63
+ case updateSubscription.SUCCESS:
64
+ return state;
70
65
  default:
71
66
  return state;
72
67
  }
@@ -1,4 +1,3 @@
1
- import _ from "lodash/fp";
2
1
  import { RULES, linkTo } from "@truedat/core/routes";
3
2
  import {
4
3
  clearRedirect,
@@ -31,24 +30,17 @@ export const ruleRedirect = (state = initialState, { type, payload, meta }) => {
31
30
  case deleteRule.SUCCESS:
32
31
  return RULES;
33
32
  case updateRule.SUCCESS: {
34
- const { redirectUrl } = meta;
33
+ const redirectUrl = meta?.redirectUrl;
35
34
  return redirectUrl;
36
35
  }
37
- case updateSubscription.SUCCESS: {
38
- const { rule_id } = payload;
39
- return _.isNil(rule_id) ? state : linkTo.RULE({ id: rule_id });
40
- }
36
+ case updateSubscription.SUCCESS:
37
+ return state;
41
38
  case uploadRules.SUCCESS: {
42
39
  return RULES;
43
40
  }
44
- case deleteSubscription.SUCCESS: {
45
- const { rule_id } = payload;
46
- return _.isNil(rule_id) ? state : linkTo.RULE({ id: rule_id });
47
- }
48
- case createSubscription.SUCCESS: {
49
- const { rule_id } = payload;
50
- return _.isNil(rule_id) ? state : linkTo.RULE({ id: rule_id });
51
- }
41
+ case deleteSubscription.SUCCESS:
42
+ case createSubscription.SUCCESS:
43
+ return state;
52
44
  case deleteImplementation.SUCCESS:
53
45
  return payload?.redirectUrl || state;
54
46
  case publishImplementation.SUCCESS: