orc-shared 1.5.0-dev.10 → 1.5.0-dev.11
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/dist/actions/tasks.js +190 -0
- package/dist/buildStore.js +3 -1
- package/dist/components/AppFrame/Sidebar.js +4 -8
- package/dist/components/TaskDetailsModal.js +193 -0
- package/dist/constants.js +16 -1
- package/dist/reducers/request.js +4 -0
- package/dist/reducers/tasks.js +99 -0
- package/dist/selectors/tasks.js +66 -0
- package/dist/sharedMessages.js +17 -1
- package/dist/utils/propertyHelper.js +35 -0
- package/package.json +1 -1
- package/src/actions/tasks.js +77 -0
- package/src/actions/tasks.test.js +169 -0
- package/src/buildStore.js +2 -0
- package/src/components/AppFrame/About.test.js +3 -3
- package/src/components/AppFrame/Sidebar.js +4 -3
- package/src/components/TaskDetailsModal.js +132 -0
- package/src/components/TaskDetailsModal.test.js +317 -0
- package/src/components/Text.test.js +44 -59
- package/src/constants.js +13 -0
- package/src/hooks/useLabelMessage.test.js +16 -10
- package/src/reducers/request.js +4 -0
- package/src/reducers/request.test.js +11 -0
- package/src/reducers/tasks.js +56 -0
- package/src/reducers/tasks.test.js +404 -0
- package/src/selectors/tasks.js +16 -0
- package/src/selectors/tasks.test.js +60 -0
- package/src/sharedMessages.js +17 -1
- package/src/translations/en-US.json +16 -12
- package/src/translations/fr-CA.json +16 -12
- package/src/utils/propertyHelper.js +38 -0
- package/src/utils/propertyHelper.test.js +160 -0
- package/src/utils/timezoneHelper.test.js +4 -2
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import Immutable from "immutable";
|
|
3
|
+
import { mount } from "enzyme";
|
|
4
|
+
import TaskDetailsModal from "./TaskDetailsModal";
|
|
5
|
+
import Modal from "./MaterialUI/DataDisplay/Modal";
|
|
6
|
+
import { defaultCulture } from "../selectors/locale";
|
|
7
|
+
import sinon from "sinon";
|
|
8
|
+
import { createMuiTheme, extractMessages, TestWrapper } from "../utils/testUtils";
|
|
9
|
+
import sharedMessages from "../sharedMessages";
|
|
10
|
+
import ModalProps from "./MaterialUI/DataDisplay/modalProps";
|
|
11
|
+
import { Ignore } from "unexpected-reaction";
|
|
12
|
+
import InformationItem from "./MaterialUI/DataDisplay/PredefinedElements/InformationItem";
|
|
13
|
+
import { clearTaskLog, getTaskInfo, getTaskLog } from "../actions/tasks";
|
|
14
|
+
import { taskStatuses } from "../constants";
|
|
15
|
+
|
|
16
|
+
const messages = extractMessages(sharedMessages);
|
|
17
|
+
|
|
18
|
+
jest.mock("../utils/buildUrl", () => {
|
|
19
|
+
const modExport = {};
|
|
20
|
+
modExport.loadConfig = () => Promise.resolve({});
|
|
21
|
+
modExport.buildUrl = (path = [], params = "") => "URL: " + path.join("/") + " " + JSON.stringify(params);
|
|
22
|
+
return modExport;
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
function removeBailout(obj) {
|
|
26
|
+
delete obj["@@redux-api-middleware/RSAA"].bailout;
|
|
27
|
+
return obj;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
describe("TaskDetailsModal", () => {
|
|
31
|
+
let state, dispatch, store, clearIntervalSpy;
|
|
32
|
+
const theme = createMuiTheme();
|
|
33
|
+
|
|
34
|
+
beforeEach(() => {
|
|
35
|
+
//window.bypassDebounce = true;
|
|
36
|
+
|
|
37
|
+
dispatch = sinon.spy().named("dispatch");
|
|
38
|
+
jest.useFakeTimers();
|
|
39
|
+
clearIntervalSpy = sinon.spy(global, "clearInterval");
|
|
40
|
+
|
|
41
|
+
state = Immutable.fromJS({
|
|
42
|
+
requests: {
|
|
43
|
+
logout: false,
|
|
44
|
+
},
|
|
45
|
+
metadata: {
|
|
46
|
+
lookups: {},
|
|
47
|
+
},
|
|
48
|
+
tasks: {
|
|
49
|
+
taskInfos: {},
|
|
50
|
+
tasks: [],
|
|
51
|
+
logs: {},
|
|
52
|
+
},
|
|
53
|
+
locale: {
|
|
54
|
+
defaultCulture: defaultCulture,
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
store = {
|
|
59
|
+
getState: () => state,
|
|
60
|
+
subscribe: () => {},
|
|
61
|
+
dispatch: dispatch,
|
|
62
|
+
};
|
|
63
|
+
});
|
|
64
|
+
afterEach(() => {
|
|
65
|
+
jest.useRealTimers();
|
|
66
|
+
jest.restoreAllMocks();
|
|
67
|
+
clearIntervalSpy.restore();
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it("renders a modal for task", () => {
|
|
71
|
+
const modalProps = new ModalProps();
|
|
72
|
+
|
|
73
|
+
modalProps.set(ModalProps.propNames.title, "Task In Progress");
|
|
74
|
+
modalProps.set(ModalProps.propNames.open, true);
|
|
75
|
+
modalProps.set(ModalProps.propNames.type, "wide");
|
|
76
|
+
modalProps.set(ModalProps.propNames.actionPanel, <Ignore />);
|
|
77
|
+
|
|
78
|
+
const expectedContent = (
|
|
79
|
+
<div>
|
|
80
|
+
<InformationItem label={sharedMessages.taskId}>1234</InformationItem>
|
|
81
|
+
<InformationItem label={sharedMessages.taskStatus}>
|
|
82
|
+
<Ignore />
|
|
83
|
+
</InformationItem>
|
|
84
|
+
<InformationItem label={sharedMessages.taskLogs}>
|
|
85
|
+
<textarea />
|
|
86
|
+
</InformationItem>
|
|
87
|
+
</div>
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
expect(
|
|
91
|
+
<TestWrapper
|
|
92
|
+
provider={{ store }}
|
|
93
|
+
memoryRouter
|
|
94
|
+
stylesProvider
|
|
95
|
+
muiThemeProvider={{ theme }}
|
|
96
|
+
intlProvider={{ messages }}
|
|
97
|
+
>
|
|
98
|
+
<TaskDetailsModal taskId="1234" open={true} closeModal={() => {}} />
|
|
99
|
+
</TestWrapper>,
|
|
100
|
+
"when mounted",
|
|
101
|
+
"to satisfy",
|
|
102
|
+
<TestWrapper
|
|
103
|
+
provider={{ store }}
|
|
104
|
+
memoryRouter
|
|
105
|
+
stylesProvider
|
|
106
|
+
muiThemeProvider={{ theme }}
|
|
107
|
+
intlProvider={{ messages }}
|
|
108
|
+
>
|
|
109
|
+
<Modal message={expectedContent} modalProps={modalProps} />
|
|
110
|
+
</TestWrapper>,
|
|
111
|
+
).then(() => expect(console.error, "was not called"));
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it("renders a modal for task with status and logs", () => {
|
|
115
|
+
state = state.setIn(
|
|
116
|
+
["tasks", "logs", "1234"],
|
|
117
|
+
[
|
|
118
|
+
{ executionTime: "", message: null },
|
|
119
|
+
{ executionTime: "4", message: "msg\r\n" },
|
|
120
|
+
{ executionTime: "3", message: "another" },
|
|
121
|
+
],
|
|
122
|
+
);
|
|
123
|
+
state = state.setIn(["tasks", "taskInfos", "1234"], { status: taskStatuses.running });
|
|
124
|
+
|
|
125
|
+
const modalProps = new ModalProps();
|
|
126
|
+
|
|
127
|
+
modalProps.set(ModalProps.propNames.title, "Task In Progress");
|
|
128
|
+
modalProps.set(ModalProps.propNames.open, true);
|
|
129
|
+
modalProps.set(ModalProps.propNames.type, "wide");
|
|
130
|
+
modalProps.set(ModalProps.propNames.actionPanel, <Ignore />);
|
|
131
|
+
|
|
132
|
+
const expectedContent = (
|
|
133
|
+
<div>
|
|
134
|
+
<InformationItem label={sharedMessages.taskId}>1234</InformationItem>
|
|
135
|
+
<InformationItem label={sharedMessages.taskStatus}>[Running]</InformationItem>
|
|
136
|
+
<InformationItem label={sharedMessages.taskLogs}>
|
|
137
|
+
<textarea readOnly value={"another\nmsg"} />
|
|
138
|
+
</InformationItem>
|
|
139
|
+
</div>
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
expect(
|
|
143
|
+
<TestWrapper
|
|
144
|
+
provider={{ store }}
|
|
145
|
+
memoryRouter
|
|
146
|
+
stylesProvider
|
|
147
|
+
muiThemeProvider={{ theme }}
|
|
148
|
+
intlProvider={{ messages }}
|
|
149
|
+
>
|
|
150
|
+
<TaskDetailsModal taskId="1234" open={true} closeModal={() => {}} />
|
|
151
|
+
</TestWrapper>,
|
|
152
|
+
"when mounted",
|
|
153
|
+
"to satisfy",
|
|
154
|
+
<TestWrapper
|
|
155
|
+
provider={{ store }}
|
|
156
|
+
memoryRouter
|
|
157
|
+
stylesProvider
|
|
158
|
+
muiThemeProvider={{ theme }}
|
|
159
|
+
intlProvider={{ messages }}
|
|
160
|
+
>
|
|
161
|
+
<Modal message={expectedContent} modalProps={modalProps} />
|
|
162
|
+
</TestWrapper>,
|
|
163
|
+
).then(() => expect(console.error, "was not called"));
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it("close the dialog", () => {
|
|
167
|
+
const closeSpy = sinon.spy().named("close");
|
|
168
|
+
|
|
169
|
+
const content = (
|
|
170
|
+
<TestWrapper
|
|
171
|
+
provider={{ store }}
|
|
172
|
+
memoryRouter
|
|
173
|
+
stylesProvider
|
|
174
|
+
muiThemeProvider={{ theme }}
|
|
175
|
+
intlProvider={{ messages }}
|
|
176
|
+
>
|
|
177
|
+
<TaskDetailsModal taskId="1234" open={true} closeModal={closeSpy} />
|
|
178
|
+
</TestWrapper>
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
const mountedComponent = mount(content);
|
|
182
|
+
store.dispatch.resetHistory();
|
|
183
|
+
|
|
184
|
+
const input = mountedComponent.find("[data-qa='" + sharedMessages.close.id + "']").at(0);
|
|
185
|
+
input.simulate("click");
|
|
186
|
+
|
|
187
|
+
expect(closeSpy, "was called");
|
|
188
|
+
expect(store.dispatch, "to have calls satisfying", [
|
|
189
|
+
{
|
|
190
|
+
args: [clearTaskLog("1234")],
|
|
191
|
+
},
|
|
192
|
+
]);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it("clear timer on unmount", () => {
|
|
196
|
+
const closeSpy = sinon.spy().named("close");
|
|
197
|
+
const content = (
|
|
198
|
+
<TestWrapper
|
|
199
|
+
provider={{ store }}
|
|
200
|
+
memoryRouter
|
|
201
|
+
stylesProvider
|
|
202
|
+
muiThemeProvider={{ theme }}
|
|
203
|
+
intlProvider={{ messages }}
|
|
204
|
+
>
|
|
205
|
+
<TaskDetailsModal taskId="1234" open={true} closeModal={closeSpy} />
|
|
206
|
+
</TestWrapper>
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
const mountedComponent = mount(content);
|
|
210
|
+
clearIntervalSpy.resetHistory();
|
|
211
|
+
mountedComponent.unmount();
|
|
212
|
+
|
|
213
|
+
expect(clearIntervalSpy, "was called");
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
it("taskInfo is called to load data", () => {
|
|
217
|
+
const content = (
|
|
218
|
+
<TestWrapper
|
|
219
|
+
provider={{ store }}
|
|
220
|
+
memoryRouter
|
|
221
|
+
stylesProvider
|
|
222
|
+
muiThemeProvider={{ theme }}
|
|
223
|
+
intlProvider={{ messages }}
|
|
224
|
+
>
|
|
225
|
+
<TaskDetailsModal taskId="1234" open={true} closeModal={() => {}} />
|
|
226
|
+
</TestWrapper>
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
mount(content);
|
|
230
|
+
|
|
231
|
+
expect(store.dispatch, "to have calls satisfying", [
|
|
232
|
+
{
|
|
233
|
+
args: [removeBailout(getTaskInfo("1234"))],
|
|
234
|
+
},
|
|
235
|
+
]);
|
|
236
|
+
expect(store.dispatch, "not to have calls satisfying", [
|
|
237
|
+
{
|
|
238
|
+
args: [removeBailout(getTaskLog("1234"))],
|
|
239
|
+
},
|
|
240
|
+
]);
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
it("taskLogs is called to load data", () => {
|
|
244
|
+
const content = (
|
|
245
|
+
<TestWrapper
|
|
246
|
+
provider={{ store }}
|
|
247
|
+
memoryRouter
|
|
248
|
+
stylesProvider
|
|
249
|
+
muiThemeProvider={{ theme }}
|
|
250
|
+
intlProvider={{ messages }}
|
|
251
|
+
>
|
|
252
|
+
<TaskDetailsModal taskId="1234" open={true} closeModal={() => {}} />
|
|
253
|
+
</TestWrapper>
|
|
254
|
+
);
|
|
255
|
+
|
|
256
|
+
mount(content);
|
|
257
|
+
|
|
258
|
+
expect(store.dispatch, "to have calls satisfying", [
|
|
259
|
+
{
|
|
260
|
+
args: [removeBailout(getTaskInfo("1234"))],
|
|
261
|
+
},
|
|
262
|
+
]);
|
|
263
|
+
|
|
264
|
+
store.dispatch.resetHistory();
|
|
265
|
+
|
|
266
|
+
jest.runOnlyPendingTimers();
|
|
267
|
+
|
|
268
|
+
expect(store.dispatch, "to have calls satisfying", [
|
|
269
|
+
{
|
|
270
|
+
args: [removeBailout(getTaskInfo("1234"))],
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
args: [removeBailout(getTaskLog("1234", false))],
|
|
274
|
+
},
|
|
275
|
+
]);
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
it.each([taskStatuses.faulted, taskStatuses.ranToCompletion, taskStatuses.canceled, taskStatuses.ignored])(
|
|
279
|
+
"taskLogs is not called because task is completed (%s)",
|
|
280
|
+
newStatus => {
|
|
281
|
+
state = state.setIn(["tasks", "taskInfos", "1234"], { status: newStatus });
|
|
282
|
+
|
|
283
|
+
const content = (
|
|
284
|
+
<TestWrapper
|
|
285
|
+
provider={{ store }}
|
|
286
|
+
memoryRouter
|
|
287
|
+
stylesProvider
|
|
288
|
+
muiThemeProvider={{ theme }}
|
|
289
|
+
intlProvider={{ messages }}
|
|
290
|
+
>
|
|
291
|
+
<TaskDetailsModal taskId="1234" open={true} closeModal={() => {}} />
|
|
292
|
+
</TestWrapper>
|
|
293
|
+
);
|
|
294
|
+
|
|
295
|
+
mount(content);
|
|
296
|
+
|
|
297
|
+
expect(store.dispatch, "not to have calls satisfying", [
|
|
298
|
+
{
|
|
299
|
+
args: [removeBailout(getTaskInfo("1234"))],
|
|
300
|
+
},
|
|
301
|
+
]);
|
|
302
|
+
|
|
303
|
+
store.dispatch.resetHistory();
|
|
304
|
+
|
|
305
|
+
jest.runOnlyPendingTimers();
|
|
306
|
+
|
|
307
|
+
expect(store.dispatch, "not to have calls satisfying", [
|
|
308
|
+
{
|
|
309
|
+
args: [removeBailout(getTaskInfo("1234"))],
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
args: [removeBailout(getTaskLog("1234"))],
|
|
313
|
+
},
|
|
314
|
+
]);
|
|
315
|
+
},
|
|
316
|
+
);
|
|
317
|
+
});
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { Provider } from "react-redux";
|
|
3
|
-
import { IntlProvider } from "react-intl";
|
|
4
2
|
import Text, { Placeholder } from "./Text";
|
|
3
|
+
import { createMuiTheme, TestWrapper } from "../utils/testUtils";
|
|
4
|
+
|
|
5
|
+
const theme = createMuiTheme();
|
|
5
6
|
|
|
6
7
|
describe("Text", () => {
|
|
7
8
|
let state, store;
|
|
@@ -16,11 +17,9 @@ describe("Text", () => {
|
|
|
16
17
|
|
|
17
18
|
it("renders a simple message", () =>
|
|
18
19
|
expect(
|
|
19
|
-
<
|
|
20
|
-
<
|
|
21
|
-
|
|
22
|
-
</IntlProvider>
|
|
23
|
-
</Provider>,
|
|
20
|
+
<TestWrapper provider={{ store }} intlProvider memoryRouter stylesProvider muiThemeProvider={{ theme }}>
|
|
21
|
+
<Text message="Test message" />
|
|
22
|
+
</TestWrapper>,
|
|
24
23
|
"when mounted",
|
|
25
24
|
"to satisfy",
|
|
26
25
|
"Test message",
|
|
@@ -28,11 +27,9 @@ describe("Text", () => {
|
|
|
28
27
|
|
|
29
28
|
it("renders an empty string", () =>
|
|
30
29
|
expect(
|
|
31
|
-
<
|
|
32
|
-
<
|
|
33
|
-
|
|
34
|
-
</IntlProvider>
|
|
35
|
-
</Provider>,
|
|
30
|
+
<TestWrapper provider={{ store }} intlProvider memoryRouter stylesProvider muiThemeProvider={{ theme }}>
|
|
31
|
+
<Text message="" />
|
|
32
|
+
</TestWrapper>,
|
|
36
33
|
"when mounted",
|
|
37
34
|
"to satisfy",
|
|
38
35
|
"",
|
|
@@ -40,11 +37,9 @@ describe("Text", () => {
|
|
|
40
37
|
|
|
41
38
|
it("renders a translated message", () =>
|
|
42
39
|
expect(
|
|
43
|
-
<
|
|
44
|
-
<
|
|
45
|
-
|
|
46
|
-
</IntlProvider>
|
|
47
|
-
</Provider>,
|
|
40
|
+
<TestWrapper provider={{ store }} intlProvider memoryRouter stylesProvider muiThemeProvider={{ theme }}>
|
|
41
|
+
<Text message={{ id: "test.msg", defaultMessage: "Test message" }} />
|
|
42
|
+
</TestWrapper>,
|
|
48
43
|
"when mounted",
|
|
49
44
|
"to satisfy",
|
|
50
45
|
"Test message",
|
|
@@ -52,17 +47,15 @@ describe("Text", () => {
|
|
|
52
47
|
|
|
53
48
|
it("renders a translated message with values", () =>
|
|
54
49
|
expect(
|
|
55
|
-
<
|
|
56
|
-
<
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
</IntlProvider>
|
|
65
|
-
</Provider>,
|
|
50
|
+
<TestWrapper provider={{ store }} intlProvider memoryRouter stylesProvider muiThemeProvider={{ theme }}>
|
|
51
|
+
<Text
|
|
52
|
+
message={{
|
|
53
|
+
id: "test.msg",
|
|
54
|
+
defaultMessage: "Test message {foo}",
|
|
55
|
+
values: { foo: 3 },
|
|
56
|
+
}}
|
|
57
|
+
/>
|
|
58
|
+
</TestWrapper>,
|
|
66
59
|
"when mounted",
|
|
67
60
|
"to satisfy",
|
|
68
61
|
"Test message 3",
|
|
@@ -70,17 +63,15 @@ describe("Text", () => {
|
|
|
70
63
|
|
|
71
64
|
it("renders a translated message with a value selector", () =>
|
|
72
65
|
expect(
|
|
73
|
-
<
|
|
74
|
-
<
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
</IntlProvider>
|
|
83
|
-
</Provider>,
|
|
66
|
+
<TestWrapper provider={{ store }} intlProvider memoryRouter stylesProvider muiThemeProvider={{ theme }}>
|
|
67
|
+
<Text
|
|
68
|
+
message={{
|
|
69
|
+
id: "test.msg",
|
|
70
|
+
defaultMessage: "Test message {foo}",
|
|
71
|
+
values: state => state.dataVal,
|
|
72
|
+
}}
|
|
73
|
+
/>
|
|
74
|
+
</TestWrapper>,
|
|
84
75
|
"when mounted",
|
|
85
76
|
"to satisfy",
|
|
86
77
|
"Test message 3",
|
|
@@ -88,16 +79,14 @@ describe("Text", () => {
|
|
|
88
79
|
|
|
89
80
|
it("renders a translated message missing its values as a placeholder", () =>
|
|
90
81
|
expect(
|
|
91
|
-
<
|
|
92
|
-
<
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
</IntlProvider>
|
|
100
|
-
</Provider>,
|
|
82
|
+
<TestWrapper provider={{ store }} intlProvider memoryRouter stylesProvider muiThemeProvider={{ theme }}>
|
|
83
|
+
<Text
|
|
84
|
+
message={{
|
|
85
|
+
id: "test.msg",
|
|
86
|
+
defaultMessage: "Test message {foo}",
|
|
87
|
+
}}
|
|
88
|
+
/>
|
|
89
|
+
</TestWrapper>,
|
|
101
90
|
"when mounted",
|
|
102
91
|
"to satisfy",
|
|
103
92
|
<Placeholder />,
|
|
@@ -105,11 +94,9 @@ describe("Text", () => {
|
|
|
105
94
|
|
|
106
95
|
it("renders an error", () =>
|
|
107
96
|
expect(
|
|
108
|
-
<
|
|
109
|
-
<
|
|
110
|
-
|
|
111
|
-
</IntlProvider>
|
|
112
|
-
</Provider>,
|
|
97
|
+
<TestWrapper provider={{ store }} intlProvider memoryRouter stylesProvider muiThemeProvider={{ theme }}>
|
|
98
|
+
<Text message="Test message" error={{ message: "This failed" }} />
|
|
99
|
+
</TestWrapper>,
|
|
113
100
|
"when mounted",
|
|
114
101
|
"to satisfy",
|
|
115
102
|
<span
|
|
@@ -126,11 +113,9 @@ describe("Text", () => {
|
|
|
126
113
|
|
|
127
114
|
it("renders an error if no message given", () =>
|
|
128
115
|
expect(
|
|
129
|
-
<
|
|
130
|
-
<
|
|
131
|
-
|
|
132
|
-
</IntlProvider>
|
|
133
|
-
</Provider>,
|
|
116
|
+
<TestWrapper provider={{ store }} intlProvider memoryRouter stylesProvider muiThemeProvider={{ theme }}>
|
|
117
|
+
<Text />
|
|
118
|
+
</TestWrapper>,
|
|
134
119
|
"when mounted",
|
|
135
120
|
"to satisfy",
|
|
136
121
|
<span
|
package/src/constants.js
CHANGED
|
@@ -107,3 +107,16 @@ export const requestStateOperationMap = {
|
|
|
107
107
|
fetch: "fetches",
|
|
108
108
|
update: "updates",
|
|
109
109
|
};
|
|
110
|
+
|
|
111
|
+
export const taskStatuses = {
|
|
112
|
+
created: "Created",
|
|
113
|
+
waitingToRun: "WaitingToRun",
|
|
114
|
+
running: "Running",
|
|
115
|
+
ranToCompletion: "RanToCompletion",
|
|
116
|
+
canceled: "Canceled",
|
|
117
|
+
faulted: "Faulted",
|
|
118
|
+
idle: "Idle",
|
|
119
|
+
waitingToCancel: "WaitingToCancel",
|
|
120
|
+
ignored: "Ignored",
|
|
121
|
+
queuedForSequence: "QueuedForSequence",
|
|
122
|
+
};
|
|
@@ -5,12 +5,14 @@ import Immutable from "immutable";
|
|
|
5
5
|
import sinon from "sinon";
|
|
6
6
|
import { messageContainsValues } from "./useLabelMessage";
|
|
7
7
|
import useLabelMessage from "./useLabelMessage";
|
|
8
|
+
import { createMuiTheme, extractMessages, TestWrapper } from "../utils/testUtils";
|
|
8
9
|
|
|
9
10
|
const TestComp = ({ message, buildMessage }) => {
|
|
10
11
|
const [msgResult, missingValues = false] = useLabelMessage(message, buildMessage);
|
|
11
12
|
|
|
12
13
|
return <div missing-values={missingValues ? 1 : 0}>{msgResult}</div>;
|
|
13
14
|
};
|
|
15
|
+
const theme = createMuiTheme();
|
|
14
16
|
|
|
15
17
|
describe("useLabelMessage", () => {
|
|
16
18
|
let store, state;
|
|
@@ -45,12 +47,18 @@ describe("useLabelMessage", () => {
|
|
|
45
47
|
values: { aValue: "testValue" },
|
|
46
48
|
};
|
|
47
49
|
|
|
50
|
+
const messages = extractMessages({ "test.msg": message });
|
|
51
|
+
|
|
48
52
|
return expect(
|
|
49
|
-
<
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
<TestWrapper
|
|
54
|
+
provider={{ store }}
|
|
55
|
+
intlProvider={{ messages }}
|
|
56
|
+
memoryRouter
|
|
57
|
+
stylesProvider
|
|
58
|
+
muiThemeProvider={{ theme }}
|
|
59
|
+
>
|
|
60
|
+
<TestComp message={message} />
|
|
61
|
+
</TestWrapper>,
|
|
54
62
|
"when mounted",
|
|
55
63
|
"to satisfy",
|
|
56
64
|
<div>Test message testValue</div>,
|
|
@@ -65,11 +73,9 @@ describe("useLabelMessage", () => {
|
|
|
65
73
|
};
|
|
66
74
|
|
|
67
75
|
return expect(
|
|
68
|
-
<
|
|
69
|
-
<
|
|
70
|
-
|
|
71
|
-
</IntlProvider>
|
|
72
|
-
</Provider>,
|
|
76
|
+
<TestWrapper provider={{ store }} intlProvider memoryRouter stylesProvider muiThemeProvider={{ theme }}>
|
|
77
|
+
<TestComp message={message} />
|
|
78
|
+
</TestWrapper>,
|
|
73
79
|
"when mounted",
|
|
74
80
|
"to satisfy",
|
|
75
81
|
<div missing-values={1}></div>,
|
package/src/reducers/request.js
CHANGED
|
@@ -11,6 +11,10 @@ export const LOGOUT = "logout";
|
|
|
11
11
|
|
|
12
12
|
const requestReducer = (state = initialState, action) => {
|
|
13
13
|
if (action.type.endsWith("_REQUEST")) {
|
|
14
|
+
if (safeGet(action, "meta", "addToActiveRequests") === false) {
|
|
15
|
+
// this flag should only be used by requests triggered by a background process to avoid the spinner
|
|
16
|
+
return state;
|
|
17
|
+
}
|
|
14
18
|
const requestName = action.type.replace(/_REQUEST$/, "");
|
|
15
19
|
return state.setIn(["actives", requestName], true);
|
|
16
20
|
}
|
|
@@ -28,6 +28,17 @@ describe("Request reducer", () => {
|
|
|
28
28
|
);
|
|
29
29
|
});
|
|
30
30
|
|
|
31
|
+
it("ignore activity flag when a request is started because addToActiveRequests is false", () => {
|
|
32
|
+
const oldState = Immutable.fromJS({
|
|
33
|
+
actives: {
|
|
34
|
+
SOME_FLAG: true,
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
const action = { type: "TEST_THIS_REQUEST", meta: { addToActiveRequests: false } };
|
|
38
|
+
const newState = reducer(oldState, action);
|
|
39
|
+
expect(newState, "to be", oldState);
|
|
40
|
+
});
|
|
41
|
+
|
|
31
42
|
it("clears activity and logout flag when a request succeeds", () => {
|
|
32
43
|
const oldState = Immutable.fromJS({
|
|
33
44
|
actives: {
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import Immutable from "immutable";
|
|
2
|
+
import { safeGet } from "../utils";
|
|
3
|
+
import {
|
|
4
|
+
GET_TASK_LIST_SUCCESS,
|
|
5
|
+
DELETE_TASK_REQUEST,
|
|
6
|
+
GET_TASK_LOG_SUCCESS,
|
|
7
|
+
CLEAR_TASK_LOG,
|
|
8
|
+
GET_TASKINFO_SUCCESS,
|
|
9
|
+
} from "../actions/tasks";
|
|
10
|
+
import { compareObjectProperty } from "../utils/propertyHelper";
|
|
11
|
+
|
|
12
|
+
const initialState = Immutable.fromJS({
|
|
13
|
+
tasks: [],
|
|
14
|
+
taskInfos: {},
|
|
15
|
+
logs: {},
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const tasks = (state = initialState, action) => {
|
|
19
|
+
switch (action.type) {
|
|
20
|
+
case GET_TASKINFO_SUCCESS:
|
|
21
|
+
return state.setIn(["taskInfos", action.payload.taskId], Immutable.fromJS(action.payload));
|
|
22
|
+
case GET_TASK_LIST_SUCCESS:
|
|
23
|
+
return state.set(
|
|
24
|
+
"tasks",
|
|
25
|
+
Immutable.fromJS(action.payload.sort((a, b) => compareObjectProperty(a, b, "created"))),
|
|
26
|
+
);
|
|
27
|
+
case DELETE_TASK_REQUEST:
|
|
28
|
+
const deleteTaskId = safeGet(action, "meta", "taskId");
|
|
29
|
+
|
|
30
|
+
return state.withMutations(s => {
|
|
31
|
+
s.set(
|
|
32
|
+
"tasks",
|
|
33
|
+
s.get("tasks").filter(task => task.get("taskId") !== deleteTaskId),
|
|
34
|
+
);
|
|
35
|
+
s.deleteIn(["logs", deleteTaskId]);
|
|
36
|
+
s.deleteIn(["taskInfos", deleteTaskId]);
|
|
37
|
+
});
|
|
38
|
+
case GET_TASK_LOG_SUCCESS:
|
|
39
|
+
const logTaskId = safeGet(action, "meta", "taskId");
|
|
40
|
+
if (action.payload?.length > 0) {
|
|
41
|
+
return state.setIn(
|
|
42
|
+
["logs", logTaskId],
|
|
43
|
+
Immutable.fromJS(action.payload.sort((a, b) => compareObjectProperty(a, b, "executionTime"))),
|
|
44
|
+
);
|
|
45
|
+
} else {
|
|
46
|
+
return state.deleteIn(["logs", logTaskId]);
|
|
47
|
+
}
|
|
48
|
+
case CLEAR_TASK_LOG:
|
|
49
|
+
const taskId = safeGet(action, "meta", "taskId");
|
|
50
|
+
return state.deleteIn(["logs", taskId]);
|
|
51
|
+
default:
|
|
52
|
+
return state;
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export default tasks;
|