@truedat/dq 4.33.10 → 4.35.2

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 (96) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/package.json +5 -5
  3. package/src/api.js +7 -1
  4. package/src/components/ConditionSummary.js +23 -21
  5. package/src/components/ExecutionDetails.js +11 -14
  6. package/src/components/ExecutionGroup.js +24 -15
  7. package/src/components/ImplementationResultBar.js +80 -0
  8. package/src/components/ImplementationSummary.js +33 -72
  9. package/src/components/ImplementationsUploadButton.js +61 -0
  10. package/src/components/InformationSummary.js +68 -0
  11. package/src/components/NewRuleImplementation.js +12 -0
  12. package/src/components/RuleForm.js +0 -178
  13. package/src/components/RuleImplementation.js +10 -6
  14. package/src/components/RuleImplementationProperties.js +31 -64
  15. package/src/components/RuleImplementationResults.js +87 -53
  16. package/src/components/RuleImplementationsActions.js +3 -59
  17. package/src/components/RuleImplementationsDownload.js +86 -0
  18. package/src/components/RuleImplementationsOptions.js +28 -0
  19. package/src/components/RuleProperties.js +1 -10
  20. package/src/components/RuleResultDecorator.js +43 -26
  21. package/src/components/RuleResultRow.js +4 -1
  22. package/src/components/RuleResultsUpload.js +47 -0
  23. package/src/components/RuleRoutes.js +0 -13
  24. package/src/components/RuleSummary.js +15 -2
  25. package/src/components/RulesActions.js +17 -10
  26. package/src/components/RulesUploadButton.js +58 -0
  27. package/src/components/__tests__/ExecutionGroup.spec.js +11 -7
  28. package/src/components/__tests__/ImplementationResultBar.spec.js +98 -0
  29. package/src/components/__tests__/ImplementationSummary.spec.js +9 -26
  30. package/src/components/__tests__/InformationSummary.spec.js +35 -0
  31. package/src/components/__tests__/NewRuleImplementation.spec.js +1 -1
  32. package/src/components/__tests__/RuleForm.spec.js +0 -191
  33. package/src/components/__tests__/RuleImplementation.spec.js +1 -0
  34. package/src/components/__tests__/RuleImplementationProperties.spec.js +23 -33
  35. package/src/components/__tests__/RuleImplementationsActions.spec.js +0 -9
  36. package/src/components/__tests__/RuleImplementationsOptions.spec.js +18 -0
  37. package/src/components/__tests__/RuleProperties.spec.js +7 -9
  38. package/src/components/__tests__/RuleResultDecorator.spec.js +17 -11
  39. package/src/components/__tests__/RuleResultRow.spec.js +25 -46
  40. package/src/components/__tests__/RuleResultsUpload.spec.js +18 -0
  41. package/src/components/__tests__/RuleRow.spec.js +0 -4
  42. package/src/components/__tests__/RuleSummary.spec.js +6 -6
  43. package/src/components/__tests__/Rules.spec.js +15 -39
  44. package/src/components/__tests__/__snapshots__/ConditionSummary.spec.js.snap +55 -51
  45. package/src/components/__tests__/__snapshots__/ExecutionGroup.spec.js.snap +5 -4
  46. package/src/components/__tests__/__snapshots__/ImplementationResultBar.spec.js.snap +141 -0
  47. package/src/components/__tests__/__snapshots__/ImplementationSummary.spec.js.snap +194 -457
  48. package/src/components/__tests__/__snapshots__/InformationSummary.spec.js.snap +185 -0
  49. package/src/components/__tests__/__snapshots__/NewRuleImplementation.spec.js.snap +6 -0
  50. package/src/components/__tests__/__snapshots__/RuleForm.spec.js.snap +0 -148
  51. package/src/components/__tests__/__snapshots__/RuleImplementation.spec.js.snap +20 -0
  52. package/src/components/__tests__/__snapshots__/RuleImplementationProperties.spec.js.snap +43 -49
  53. package/src/components/__tests__/__snapshots__/RuleImplementationResults.spec.js.snap +63 -61
  54. package/src/components/__tests__/__snapshots__/RuleImplementationsActions.spec.js.snap +1 -7
  55. package/src/components/__tests__/__snapshots__/RuleImplementationsOptions.spec.js.snap +58 -0
  56. package/src/components/__tests__/__snapshots__/RuleProperties.spec.js.snap +0 -1
  57. package/src/components/__tests__/__snapshots__/RuleResultsUpload.spec.js.snap +18 -0
  58. package/src/components/__tests__/__snapshots__/RuleRow.spec.js.snap +0 -28
  59. package/src/components/__tests__/__snapshots__/Rules.spec.js.snap +0 -101
  60. package/src/components/ruleImplementationForm/FiltersGroup.js +1 -0
  61. package/src/components/ruleImplementationForm/InformationForm.js +5 -5
  62. package/src/components/ruleImplementationForm/LimitsForm.js +142 -0
  63. package/src/components/ruleImplementationForm/RuleImplementationForm.js +14 -4
  64. package/src/components/ruleImplementationForm/RuleImplementationRawForm.js +16 -6
  65. package/src/components/ruleImplementationForm/ValueConditions.js +11 -0
  66. package/src/components/ruleImplementationForm/__tests__/LimitsForm.spec.js +186 -0
  67. package/src/components/ruleImplementationForm/__tests__/RuleImplementationRawForm.spec.js +42 -35
  68. package/src/components/ruleImplementationForm/__tests__/__snapshots__/LimitsForm.spec.js.snap +1104 -0
  69. package/src/components/ruleImplementationForm/__tests__/__snapshots__/RuleImplementationForm.spec.js.snap +4 -1
  70. package/src/components/ruleImplementationForm/__tests__/__snapshots__/RuleImplementationRawForm.spec.js.snap +12 -1
  71. package/src/components/ruleImplementationForm/limitsValidation.js +72 -0
  72. package/src/messages/en.js +167 -76
  73. package/src/messages/es.js +292 -185
  74. package/src/reducers/__tests__/rule.spec.js +2 -4
  75. package/src/reducers/__tests__/ruleImplementation.spec.js +2 -0
  76. package/src/reducers/__tests__/ruleImplementations.spec.js +12 -8
  77. package/src/reducers/__tests__/uploadingResults.spec.js +28 -0
  78. package/src/reducers/dqMessage.js +121 -1
  79. package/src/reducers/index.js +6 -0
  80. package/src/reducers/rule.js +0 -3
  81. package/src/reducers/ruleImplementation.js +3 -0
  82. package/src/reducers/ruleImplementationRedirect.js +6 -1
  83. package/src/reducers/ruleImplementations.js +3 -0
  84. package/src/reducers/ruleRedirect.js +5 -0
  85. package/src/reducers/uploadImplementationsFile.js +28 -0
  86. package/src/reducers/uploadRulesFile.js +25 -0
  87. package/src/reducers/uploadingResults.js +16 -0
  88. package/src/routines.js +3 -0
  89. package/src/sagas/__tests__/uploadResults.spec.js +65 -0
  90. package/src/sagas/index.js +9 -0
  91. package/src/sagas/uploadImplementations.js +28 -0
  92. package/src/sagas/uploadResults.js +32 -0
  93. package/src/sagas/uploadRules.js +28 -0
  94. package/src/selectors/getRuleImplementationColumns.js +38 -3
  95. package/src/selectors/ruleColumnsSelector.js +0 -31
  96. package/src/styles/ruleSummary.less +17 -10
@@ -20,18 +20,16 @@ describe("reducers: rule", () => {
20
20
  current_business_concept_version: { name: "alfalfa", id: 1234 },
21
21
  name: "rule1",
22
22
  description: "desc1",
23
- goal: 10,
24
- minimum: 1,
25
23
  active: false,
26
24
  domain_id: 1,
27
- domain: { id: 1, name: "foo", external_id: "bar" }
25
+ domain: { id: 1, name: "foo", external_id: "bar" },
28
26
  };
29
27
  const payload = { data: someRule };
30
28
 
31
29
  expect(
32
30
  rule(fooState, {
33
31
  type: fetchRule.SUCCESS,
34
- payload
32
+ payload,
35
33
  })
36
34
  ).toMatchObject(someRule);
37
35
  });
@@ -21,6 +21,8 @@ describe("reducers: ruleImplementation", () => {
21
21
  id: 2,
22
22
  implementation_key: "xxx",
23
23
  results: [],
24
+ goal: 10,
25
+ minimum: 1,
24
26
  };
25
27
  const payload = { data: ruleImpl };
26
28
 
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  clearRuleImplementations,
3
3
  fetchRuleImplementations,
4
- searchRuleImplementations
4
+ searchRuleImplementations,
5
5
  } from "../../routines";
6
6
  import { ruleImplementations } from "..";
7
7
 
@@ -9,12 +9,16 @@ const fooState = { foo: "bar" };
9
9
  const data = [
10
10
  {
11
11
  id: 1,
12
- implementation_key: "RuleImplementations 1"
12
+ implementation_key: "RuleImplementations 1",
13
+ goal: 10,
14
+ minimum: 1,
13
15
  },
14
16
  {
15
17
  id: 2,
16
- implementation_key: "RuleImplementations 2"
17
- }
18
+ implementation_key: "RuleImplementations 2",
19
+ goal: 10,
20
+ minimum: 1,
21
+ },
18
22
  ];
19
23
 
20
24
  describe("reducers: ruleImplementations", () => {
@@ -27,7 +31,7 @@ describe("reducers: ruleImplementations", () => {
27
31
  it("should handle the fetchRuleImplementations.TRIGGER action", () => {
28
32
  expect(
29
33
  ruleImplementations(fooState, {
30
- type: fetchRuleImplementations.TRIGGER
34
+ type: fetchRuleImplementations.TRIGGER,
31
35
  })
32
36
  ).toMatchObject(initialState);
33
37
  });
@@ -38,7 +42,7 @@ describe("reducers: ruleImplementations", () => {
38
42
  expect(
39
43
  ruleImplementations(fooState, {
40
44
  type: fetchRuleImplementations.SUCCESS,
41
- payload
45
+ payload,
42
46
  })
43
47
  ).toMatchObject(data);
44
48
  });
@@ -49,7 +53,7 @@ describe("reducers: ruleImplementations", () => {
49
53
  expect(
50
54
  ruleImplementations(fooState, {
51
55
  type: searchRuleImplementations.SUCCESS,
52
- payload
56
+ payload,
53
57
  })
54
58
  ).toMatchObject(data);
55
59
  });
@@ -57,7 +61,7 @@ describe("reducers: ruleImplementations", () => {
57
61
  it("should handle the clearRuleImplementations.TRIGGER action", () => {
58
62
  expect(
59
63
  ruleImplementations(fooState, {
60
- type: clearRuleImplementations.TRIGGER
64
+ type: clearRuleImplementations.TRIGGER,
61
65
  })
62
66
  ).toMatchObject(initialState);
63
67
  });
@@ -0,0 +1,28 @@
1
+ import { uploadResults } from "../../routines";
2
+ import { uploadingResults } from "..";
3
+
4
+ const fooState = { foo: "bar" };
5
+
6
+ const initialState = false;
7
+
8
+ describe("reducers: previousRuleImplementationQuery", () => {
9
+ it("should provide the initial state", () => {
10
+ expect(uploadingResults(undefined, {})).toEqual(initialState);
11
+ });
12
+
13
+ it("should handle the uploadResults.TRIGGER action", () => {
14
+ expect(
15
+ uploadingResults(fooState, {
16
+ type: uploadResults.TRIGGER,
17
+ })
18
+ ).toBeTruthy();
19
+ });
20
+
21
+ it("should handle the uploadResults.FULFILL action", () => {
22
+ expect(
23
+ uploadingResults(fooState, {
24
+ type: uploadResults.FULFILL,
25
+ })
26
+ ).toBeFalsy();
27
+ });
28
+ });
@@ -1,5 +1,125 @@
1
+ import _ from "lodash/fp";
2
+ import { dismissAlert } from "@truedat/core/routines";
3
+ import { uploadRules, uploadImplementations, uploadResults } from "../routines";
4
+
1
5
  const initialState = {};
2
6
 
3
- const dqMessage = () => initialState;
7
+ const dqMessage = (state = initialState, { type, payload }) => {
8
+ switch (type) {
9
+ case dismissAlert.TRIGGER:
10
+ return initialState;
11
+ case uploadRules.SUCCESS:
12
+ const messages = _.has("errors")(payload.data)
13
+ ? _.flow(
14
+ _.propOr([], "errors"),
15
+ _.map((error) => ({
16
+ id: "rules.upload.success.errors",
17
+ fields: {
18
+ rule_name: error.rule_name,
19
+ key: Object.keys(error.message)[0],
20
+ message: error.message[Object.keys(error.message)[0]][0],
21
+ },
22
+ defaultMessage: "rules.upload.success.errors.default",
23
+ }))
24
+ )(payload.data)
25
+ : "";
26
+ return {
27
+ error: false,
28
+ header: "rules.upload.success.header",
29
+ icon: "check",
30
+ color: payload.data.errors.length >= 1 ? "orange" : "green",
31
+ text: "",
32
+ messages,
33
+ fields: {
34
+ count_ids: payload.data.ids.length,
35
+ count_errors: payload.data.errors.length,
36
+ },
37
+ };
38
+ case uploadRules.FAILURE:
39
+ if (payload.status != 500 && !_.path("data.errors")(payload)) {
40
+ return {
41
+ error: true,
42
+ header: "rules.upload.failed.header",
43
+ content: `rules.upload.failed.${
44
+ _.path("data.error.error")(payload) || _.path("data.error")(payload)
45
+ }`,
46
+ icon: "attention",
47
+ text: "",
48
+ fields: _.path("data.error")(payload),
49
+ };
50
+ } else {
51
+ return null;
52
+ }
53
+
54
+ case uploadImplementations.SUCCESS:
55
+ const messagesImp = _.has("errors")(payload.data)
56
+ ? _.flow(
57
+ _.propOr([], "errors"),
58
+ _.map((error) => ({
59
+ id: "ruleImplementations.upload.success.errors",
60
+ fields: {
61
+ name: error.implementation_key,
62
+ key: Object.keys(error.message)[0],
63
+ message: error.message[Object.keys(error.message)[0]][0],
64
+ },
65
+ defaultMessage:
66
+ "ruleImplementations.upload.success.errors.default",
67
+ }))
68
+ )(payload.data)
69
+ : "";
70
+
71
+ return {
72
+ error: false,
73
+ header: "ruleImplementations.upload.success.header",
74
+ icon: "check",
75
+ color: payload.data.errors.length >= 1 ? "orange" : "green",
76
+ text: "",
77
+ messages: messagesImp,
78
+ fields: {
79
+ count_ids: payload.data.ids.length,
80
+ count_errors: payload.data.errors.length,
81
+ },
82
+ };
83
+ case uploadImplementations.FAILURE:
84
+ if (payload.status != 500 && !_.path("data.errors")(payload)) {
85
+ return {
86
+ error: true,
87
+ header: "ruleImplementations.upload.failed.header",
88
+ content: `ruleImplementations.upload.failed.${
89
+ _.path("data.error.error")(payload) || _.path("data.error")(payload)
90
+ }`,
91
+ icon: "attention",
92
+ text: "",
93
+ fields: _.path("data.error")(payload),
94
+ };
95
+ } else {
96
+ return null;
97
+ }
98
+ case uploadResults.SUCCESS:
99
+ return {
100
+ error: false,
101
+ header: "ruleResults.upload.success.header",
102
+ icon: "check",
103
+ color: "green",
104
+ text: "",
105
+ };
106
+ case uploadResults.FAILURE:
107
+ if (payload.status != 500) {
108
+ return {
109
+ error: true,
110
+ header: "ruleResults.upload.failed.header",
111
+ content: `ruleResults.upload.failed.content`,
112
+ icon: "attention",
113
+ text: "",
114
+ fields: { row: _.path("data.row")(payload) },
115
+ };
116
+ } else {
117
+ return null;
118
+ }
119
+
120
+ default:
121
+ return state;
122
+ }
123
+ };
4
124
 
5
125
  export { dqMessage };
@@ -37,9 +37,12 @@ import { ruleUpdating } from "./ruleUpdating";
37
37
  import { rules } from "./rules";
38
38
  import { rulesLoading } from "./rulesLoading";
39
39
  import { rulesPageSize } from "./rulesPageSize";
40
+ import { uploadImplementationsFile } from "./uploadImplementationsFile";
41
+ import { uploadRulesFile } from "./uploadRulesFile";
40
42
  import { userRulePermissions } from "./userRulePermissions";
41
43
  import { userRulesPermissions } from "./userRulesPermissions";
42
44
  import { userImplementationsPermissions } from "./userImplementationsPermissions";
45
+ import { uploadingResults } from "./uploadingResults";
43
46
 
44
47
  export {
45
48
  conceptRules,
@@ -81,7 +84,10 @@ export {
81
84
  rules,
82
85
  rulesLoading,
83
86
  rulesPageSize,
87
+ uploadRulesFile,
88
+ uploadImplementationsFile,
84
89
  userRulePermissions,
85
90
  userRulesPermissions,
86
91
  userImplementationsPermissions,
92
+ uploadingResults,
87
93
  };
@@ -13,13 +13,10 @@ const pickFields = _.pick([
13
13
  "current_business_concept_version",
14
14
  "name",
15
15
  "description",
16
- "goal",
17
- "minimum",
18
16
  "system_values",
19
17
  "type_params",
20
18
  "df_name",
21
19
  "df_content",
22
- "result_type"
23
20
  ]);
24
21
 
25
22
  const rule = (state = initialState, { type, payload }) => {
@@ -21,6 +21,9 @@ const pickFields = _.pick([
21
21
  "rule_id",
22
22
  "system",
23
23
  "validations",
24
+ "result_type",
25
+ "minimum",
26
+ "goal",
24
27
  ]);
25
28
 
26
29
  const ruleImplementation = (state = initialState, { type, payload }) => {
@@ -5,13 +5,14 @@ import {
5
5
  createRuleImplementation,
6
6
  updateRuleImplementation,
7
7
  deleteRuleResult,
8
+ uploadImplementations,
8
9
  } from "../routines";
9
10
 
10
11
  const initialState = "";
11
12
 
12
13
  export const ruleImplementationRedirect = (
13
14
  state = initialState,
14
- { type, payload }
15
+ { type, payload, meta }
15
16
  ) => {
16
17
  switch (type) {
17
18
  case clearRedirect.TRIGGER:
@@ -29,6 +30,10 @@ export const ruleImplementationRedirect = (
29
30
  const { id: implementation_id, rule_id: id } = data;
30
31
  return linkTo.RULE_IMPLEMENTATION({ id, implementation_id });
31
32
  }
33
+ case uploadImplementations.SUCCESS: {
34
+ const { redirectUrl } = meta;
35
+ return redirectUrl;
36
+ }
32
37
  case deleteRuleResult.SUCCESS: {
33
38
  const { rule_implementation_id: implementation_id, rule_id: id } =
34
39
  payload;
@@ -21,6 +21,9 @@ const pickFields = _.pick([
21
21
  "event_type",
22
22
  "event_inserted_at",
23
23
  "deleted_at",
24
+ "result_type",
25
+ "minimum",
26
+ "goal",
24
27
  "dataset",
25
28
  "valdations",
26
29
  ]);
@@ -11,6 +11,7 @@ import {
11
11
  updateRule,
12
12
  deleteRule,
13
13
  setRuleImplementationStatus,
14
+ uploadRules,
14
15
  } from "../routines";
15
16
 
16
17
  const initialState = "";
@@ -37,6 +38,10 @@ export const ruleRedirect = (state = initialState, { type, payload, meta }) => {
37
38
  const { rule_id } = payload;
38
39
  return _.isNil(rule_id) ? state : linkTo.RULE({ id: rule_id });
39
40
  }
41
+ case uploadRules.SUCCESS: {
42
+ const { redirectUrl } = meta;
43
+ return redirectUrl;
44
+ }
40
45
  case deleteSubscription.SUCCESS: {
41
46
  const { rule_id } = payload;
42
47
  return _.isNil(rule_id) ? state : linkTo.RULE({ id: rule_id });
@@ -0,0 +1,28 @@
1
+ import { uploadImplementations } from "../routines";
2
+
3
+ const initialState = {
4
+ loading: false,
5
+ error: {},
6
+ };
7
+
8
+ export const uploadImplementationsFile = (
9
+ state = initialState,
10
+ { type, payload }
11
+ ) => {
12
+ switch (type) {
13
+ case uploadImplementations.TRIGGER:
14
+ return state;
15
+ case uploadImplementations.REQUEST:
16
+ return { ...state, loading: true };
17
+ case uploadImplementations.SUCCESS:
18
+ return state;
19
+ case uploadImplementations.FAILURE:
20
+ return { ...state, error: payload };
21
+ case uploadImplementations.FULFILL:
22
+ return { ...state, loading: false };
23
+ default:
24
+ return state;
25
+ }
26
+ };
27
+
28
+ export default uploadImplementationsFile;
@@ -0,0 +1,25 @@
1
+ import { uploadRules } from "../routines";
2
+
3
+ const initialState = {
4
+ loading: false,
5
+ error: {},
6
+ };
7
+
8
+ export const uploadRulesFile = (state = initialState, { type, payload }) => {
9
+ switch (type) {
10
+ case uploadRules.TRIGGER:
11
+ return state;
12
+ case uploadRules.REQUEST:
13
+ return { ...state, loading: true };
14
+ case uploadRules.SUCCESS:
15
+ return state;
16
+ case uploadRules.FAILURE:
17
+ return { ...state, error: payload };
18
+ case uploadRules.FULFILL:
19
+ return { ...state, loading: false };
20
+ default:
21
+ return state;
22
+ }
23
+ };
24
+
25
+ export default uploadRulesFile;
@@ -0,0 +1,16 @@
1
+ import { uploadResults } from "../routines";
2
+
3
+ const initialState = false;
4
+
5
+ export const uploadingResults = (state = initialState, { type }) => {
6
+ switch (type) {
7
+ case uploadResults.TRIGGER:
8
+ return true;
9
+ case uploadResults.FULFILL:
10
+ return false;
11
+ default:
12
+ return state;
13
+ }
14
+ };
15
+
16
+ export default uploadingResults;
package/src/routines.js CHANGED
@@ -45,6 +45,8 @@ export const sortRules = createRoutine("SORT_RULES");
45
45
  export const selectRulePage = createRoutine("SELECT_RULE_PAGE");
46
46
  export const toggleRuleFilterValue = createRoutine("TOGGLE_RULE_FILTER_VALUE");
47
47
  export const updateDeletionQuery = createRoutine("UPDATE_DELETION_QUERY");
48
+ export const uploadRules = createRoutine("UPLOAD_RULES");
49
+ export const uploadImplementations = createRoutine("UPLOAD_IMPLEMENTATIONS");
48
50
  export const clearStructure = createRoutine("CLEAR_STRUCTURE");
49
51
  export const setImplementationFilterValues = createRoutine(
50
52
  "SET_IMPLEMENTATION_FILTER_VALUES"
@@ -87,6 +89,7 @@ export const openImplementationFilter = createRoutine(
87
89
  export const downloadImplementations = createRoutine(
88
90
  "DOWNLOAD_IMPLEMENTATIONS"
89
91
  );
92
+ export const uploadResults = createRoutine("UPLOAD_RESULTS");
90
93
  export const createExecutionGroup = createRoutine("CREATE_EXECUTION_GROUP");
91
94
  export const fetchExecutionGroup = createRoutine("FETCH_EXECUTION_GROUP");
92
95
  export const clearExecutionGroup = createRoutine("CLEAR_EXECUTION_GROUP");
@@ -0,0 +1,65 @@
1
+ import { testSaga } from "redux-saga-test-plan";
2
+ import { apiJsonPost, UPLOAD_JSON_OPTS } from "@truedat/core/services/api";
3
+ import { uploadResultsRequestSaga, uploadResultsSaga } from "../uploadResults";
4
+ import { uploadResults } from "../../routines";
5
+ import { API_RULE_RESULTS } from "../../api";
6
+
7
+ describe("sagas: uploadResultsRequestSaga", () => {
8
+ it("should invoke uploadResultsSaga on trigger", () => {
9
+ expect(() => {
10
+ testSaga(uploadResultsRequestSaga)
11
+ .next()
12
+ .takeLatest(uploadResults.TRIGGER, uploadResultsSaga)
13
+ .finish()
14
+ .isDone();
15
+ }).not.toThrow();
16
+ });
17
+
18
+ it("should throw exception if an unhandled action is received", () => {
19
+ expect(() => {
20
+ testSaga(uploadResultsRequestSaga)
21
+ .next()
22
+ .takeLatest("FOO", uploadResultsSaga);
23
+ }).toThrow();
24
+ });
25
+ });
26
+
27
+ describe("sagas: uploadResultsSaga", () => {
28
+ const body = { rule_results: "content" };
29
+ const payload = { data: body };
30
+ const data = { message: [1, 2] };
31
+ it("should put a success action when a response is returned", () => {
32
+ expect(() => {
33
+ testSaga(uploadResultsSaga, { payload })
34
+ .next()
35
+ .put(uploadResults.request())
36
+ .next()
37
+ .call(apiJsonPost, API_RULE_RESULTS, body, UPLOAD_JSON_OPTS)
38
+ .next({ data })
39
+ .put(uploadResults.success(data))
40
+ .next()
41
+ .put(uploadResults.fulfill())
42
+ .next()
43
+ .isDone();
44
+ }).not.toThrow();
45
+ });
46
+
47
+ it("should put a failure action when the call returns an error", () => {
48
+ const message = "Request failed";
49
+ const error = { message };
50
+
51
+ expect(() => {
52
+ testSaga(uploadResultsSaga, { payload })
53
+ .next()
54
+ .put(uploadResults.request())
55
+ .next()
56
+ .call(apiJsonPost, API_RULE_RESULTS, body, UPLOAD_JSON_OPTS)
57
+ .throw(error)
58
+ .put(uploadResults.failure(message))
59
+ .next()
60
+ .put(uploadResults.fulfill())
61
+ .next()
62
+ .isDone();
63
+ }).not.toThrow();
64
+ });
65
+ });
@@ -14,8 +14,11 @@ import { fetchRuleImplementationsRequestSaga } from "./fetchRuleImplementations"
14
14
  import { fetchRuleRequestSaga } from "./fetchRule";
15
15
  import { fetchRulesRequestSaga } from "./fetchRules";
16
16
  import { searchRuleImplementationsRequestSaga } from "./searchRuleImplementations";
17
+ import { uploadImplementationsRequestsSaga } from "./uploadImplementations";
18
+ import { uploadRulesRequestsSaga } from "./uploadRules";
17
19
  import { updateRuleImplementationRequestSaga } from "./updateRuleImplementation";
18
20
  import { updateRuleRequestSaga } from "./updateRule";
21
+ import { uploadResultsRequestSaga } from "./uploadResults";
19
22
 
20
23
  export {
21
24
  createExecutionGroupRequestSaga,
@@ -34,8 +37,11 @@ export {
34
37
  fetchRuleRequestSaga,
35
38
  fetchRulesRequestSaga,
36
39
  searchRuleImplementationsRequestSaga,
40
+ uploadRulesRequestsSaga,
41
+ uploadImplementationsRequestsSaga,
37
42
  updateRuleImplementationRequestSaga,
38
43
  updateRuleRequestSaga,
44
+ uploadResultsRequestSaga,
39
45
  };
40
46
 
41
47
  export default [
@@ -55,6 +61,9 @@ export default [
55
61
  fetchRuleRequestSaga(),
56
62
  fetchRulesRequestSaga(),
57
63
  searchRuleImplementationsRequestSaga(),
64
+ uploadRulesRequestsSaga(),
65
+ uploadImplementationsRequestsSaga(),
58
66
  updateRuleImplementationRequestSaga(),
59
67
  updateRuleRequestSaga(),
68
+ uploadResultsRequestSaga(),
60
69
  ];
@@ -0,0 +1,28 @@
1
+ import { call, put, takeLatest } from "redux-saga/effects";
2
+ import { IMPLEMENTATIONS } from "@truedat/core/routes";
3
+ import { apiJsonPost, UPLOAD_JSON_OPTS } from "@truedat/core/services/api";
4
+ import { uploadImplementations } from "../routines";
5
+
6
+ export function* uploadImplementationsSaga({ payload }) {
7
+ try {
8
+ const { action, method, href, ...rest } = payload;
9
+ const meta = { action, method, href, redirectUrl: IMPLEMENTATIONS };
10
+ yield put(uploadImplementations.request({ method, href, ...rest }));
11
+ const body = rest || {};
12
+ const { data } = yield call(apiJsonPost, href, body.data, UPLOAD_JSON_OPTS);
13
+ yield put({ meta, ...uploadImplementations.success(data) });
14
+ } catch (error) {
15
+ if (error.response) {
16
+ const { status, data } = error.response;
17
+ yield put(uploadImplementations.failure({ status, data }));
18
+ } else {
19
+ yield put(uploadImplementations.failure(error.message));
20
+ }
21
+ } finally {
22
+ yield put(uploadImplementations.fulfill());
23
+ }
24
+ }
25
+
26
+ export function* uploadImplementationsRequestsSaga() {
27
+ yield takeLatest(uploadImplementations.TRIGGER, uploadImplementationsSaga);
28
+ }
@@ -0,0 +1,32 @@
1
+ import { call, put, takeLatest } from "redux-saga/effects";
2
+ import { apiJsonPost, UPLOAD_JSON_OPTS } from "@truedat/core/services/api";
3
+ import { uploadResults } from "../routines";
4
+ import { API_RULE_RESULTS } from "../api";
5
+
6
+ export function* uploadResultsSaga({ payload }) {
7
+ try {
8
+ const { data: body } = payload;
9
+ yield put(uploadResults.request());
10
+ const { data } = yield call(
11
+ apiJsonPost,
12
+ API_RULE_RESULTS,
13
+ body,
14
+ UPLOAD_JSON_OPTS
15
+ );
16
+
17
+ yield put(uploadResults.success(data));
18
+ } catch (error) {
19
+ if (error.response) {
20
+ const { status, data } = error.response;
21
+ yield put(uploadResults.failure({ status, data }));
22
+ } else {
23
+ yield put(uploadResults.failure(error.message));
24
+ }
25
+ } finally {
26
+ yield put(uploadResults.fulfill());
27
+ }
28
+ }
29
+
30
+ export function* uploadResultsRequestSaga() {
31
+ yield takeLatest(uploadResults.TRIGGER, uploadResultsSaga);
32
+ }
@@ -0,0 +1,28 @@
1
+ import { call, put, takeLatest } from "redux-saga/effects";
2
+ import { RULES } from "@truedat/core/routes";
3
+ import { apiJsonPost, UPLOAD_JSON_OPTS } from "@truedat/core/services/api";
4
+ import { uploadRules } from "../routines";
5
+
6
+ export function* uploadRulesSaga({ payload }) {
7
+ try {
8
+ const { action, method, href, ...rest } = payload;
9
+ const meta = { action, method, href, redirectUrl: RULES };
10
+ yield put(uploadRules.request({ method, href, ...rest }));
11
+ const body = rest || {};
12
+ const { data } = yield call(apiJsonPost, href, body.data, UPLOAD_JSON_OPTS);
13
+ yield put({ meta, ...uploadRules.success(data) });
14
+ } catch (error) {
15
+ if (error.response) {
16
+ const { status, data } = error.response;
17
+ yield put(uploadRules.failure({ status, data }));
18
+ } else {
19
+ yield put(uploadRules.failure(error.message));
20
+ }
21
+ } finally {
22
+ yield put(uploadRules.fulfill());
23
+ }
24
+ }
25
+
26
+ export function* uploadRulesRequestsSaga() {
27
+ yield takeLatest(uploadRules.TRIGGER, uploadRulesSaga);
28
+ }