datajunction-ui 0.0.1-a1 → 0.0.1-a101
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/Makefile +7 -1
- package/package.json +18 -7
- package/public/index.html +1 -1
- package/src/app/components/AddNodeDropdown.jsx +44 -0
- package/src/app/components/ListGroupItem.jsx +2 -1
- package/src/app/components/NodeListActions.jsx +69 -0
- package/src/app/components/NodeMaterializationDelete.jsx +80 -0
- package/src/app/components/QueryInfo.jsx +96 -1
- package/src/app/components/Search.jsx +94 -0
- package/src/app/components/__tests__/NodeListActions.test.jsx +94 -0
- package/src/app/components/__tests__/Search.test.jsx +63 -0
- package/src/app/components/__tests__/__snapshots__/ListGroupItem.test.tsx.snap +5 -3
- package/src/app/components/djgraph/Collapse.jsx +3 -2
- package/src/app/components/djgraph/DJNode.jsx +1 -1
- package/src/app/components/djgraph/DJNodeColumns.jsx +5 -1
- package/src/app/components/djgraph/LayoutFlow.jsx +5 -3
- package/src/app/components/forms/Action.jsx +8 -0
- package/src/app/components/forms/NodeNameField.jsx +64 -0
- package/src/app/components/search.css +17 -0
- package/src/app/icons/AddItemIcon.jsx +16 -0
- package/src/app/icons/CommitIcon.jsx +45 -0
- package/src/app/icons/DiffIcon.jsx +63 -0
- package/src/app/icons/EyeIcon.jsx +20 -0
- package/src/app/icons/FilterIcon.jsx +7 -0
- package/src/app/icons/JupyterExportIcon.jsx +25 -0
- package/src/app/icons/LoadingIcon.jsx +10 -10
- package/src/app/icons/PythonIcon.jsx +6 -44
- package/src/app/index.tsx +24 -0
- package/src/app/pages/AddEditNodePage/AlertMessage.jsx +10 -0
- package/src/app/pages/AddEditNodePage/ColumnsSelect.jsx +84 -0
- package/src/app/pages/AddEditNodePage/DescriptionField.jsx +17 -0
- package/src/app/pages/AddEditNodePage/DisplayNameField.jsx +16 -0
- package/src/app/pages/AddEditNodePage/FormikSelect.jsx +5 -0
- package/src/app/pages/AddEditNodePage/FullNameField.jsx +3 -2
- package/src/app/pages/AddEditNodePage/Loadable.jsx +6 -2
- package/src/app/pages/AddEditNodePage/MetricMetadataFields.jsx +75 -0
- package/src/app/pages/AddEditNodePage/MetricQueryField.jsx +71 -0
- package/src/app/pages/AddEditNodePage/NamespaceField.jsx +40 -0
- package/src/app/pages/AddEditNodePage/NodeModeField.jsx +14 -0
- package/src/app/pages/AddEditNodePage/NodeQueryField.jsx +8 -3
- package/src/app/pages/AddEditNodePage/RequiredDimensionsSelect.jsx +54 -0
- package/src/app/pages/AddEditNodePage/TagsField.jsx +47 -0
- package/src/app/pages/AddEditNodePage/UpstreamNodeField.jsx +49 -0
- package/src/app/pages/AddEditNodePage/__tests__/AddEditNodePageFormFailed.test.jsx +15 -9
- package/src/app/pages/AddEditNodePage/__tests__/AddEditNodePageFormSuccess.test.jsx +167 -24
- package/src/app/pages/AddEditNodePage/__tests__/index.test.jsx +55 -25
- package/src/app/pages/AddEditNodePage/index.jsx +275 -194
- package/src/app/pages/CubeBuilderPage/DimensionsSelect.jsx +154 -0
- package/src/app/pages/CubeBuilderPage/Loadable.jsx +16 -0
- package/src/app/pages/CubeBuilderPage/MetricsSelect.jsx +77 -0
- package/src/app/pages/CubeBuilderPage/__tests__/index.test.jsx +405 -0
- package/src/app/pages/CubeBuilderPage/index.jsx +267 -0
- package/src/app/pages/NamespacePage/AddNamespacePopover.jsx +5 -5
- package/src/app/pages/NamespacePage/Explorer.jsx +6 -2
- package/src/app/pages/NamespacePage/FieldControl.jsx +21 -0
- package/src/app/pages/NamespacePage/NodeTypeSelect.jsx +30 -0
- package/src/app/pages/NamespacePage/TagSelect.jsx +44 -0
- package/src/app/pages/NamespacePage/UserSelect.jsx +47 -0
- package/src/app/pages/NamespacePage/__tests__/index.test.jsx +98 -19
- package/src/app/pages/NamespacePage/index.jsx +272 -89
- package/src/app/pages/NodePage/AddBackfillPopover.jsx +60 -61
- package/src/app/pages/NodePage/AddMaterializationPopover.jsx +104 -51
- package/src/app/pages/NodePage/ClientCodePopover.jsx +73 -25
- package/src/app/pages/NodePage/DimensionFilter.jsx +86 -0
- package/src/app/pages/NodePage/EditColumnDescriptionPopover.jsx +116 -0
- package/src/app/pages/NodePage/LinkDimensionPopover.jsx +38 -23
- package/src/app/pages/NodePage/MaterializationConfigField.jsx +60 -0
- package/src/app/pages/NodePage/NodeColumnTab.jsx +183 -113
- package/src/app/pages/NodePage/NodeDependenciesTab.jsx +153 -0
- package/src/app/pages/NodePage/NodeGraphTab.jsx +56 -29
- package/src/app/pages/NodePage/NodeHistory.jsx +165 -161
- package/src/app/pages/NodePage/NodeInfoTab.jsx +148 -14
- package/src/app/pages/NodePage/NodeMaterializationTab.jsx +201 -104
- package/src/app/pages/NodePage/NodeStatus.jsx +96 -21
- package/src/app/pages/NodePage/NodeValidateTab.jsx +367 -0
- package/src/app/pages/NodePage/NotebookDownload.jsx +36 -0
- package/src/app/pages/NodePage/PartitionColumnPopover.jsx +3 -5
- package/src/app/pages/NodePage/PartitionValueForm.jsx +60 -0
- package/src/app/pages/NodePage/RevisionDiff.jsx +209 -0
- package/src/app/pages/NodePage/WatchNodeButton.jsx +226 -0
- package/src/app/pages/NodePage/__tests__/AddBackfillPopover.test.jsx +13 -4
- package/src/app/pages/NodePage/__tests__/AddMaterializationPopover.test.jsx +87 -0
- package/src/app/pages/NodePage/__tests__/DimensionFilter.test.jsx +74 -0
- package/src/app/pages/NodePage/__tests__/EditColumnDescriptionPopover.test.jsx +149 -0
- package/src/app/pages/NodePage/__tests__/LinkDimensionPopover.test.jsx +10 -14
- package/src/app/pages/NodePage/__tests__/NodeColumnTab.test.jsx +166 -0
- package/src/app/pages/NodePage/__tests__/NodeDependenciesTab.test.jsx +151 -0
- package/src/app/pages/NodePage/__tests__/NodeGraphTab.test.jsx +6 -2
- package/src/app/pages/NodePage/__tests__/NodeLineageTab.test.jsx +3 -2
- package/src/app/pages/NodePage/__tests__/NodeMaterializationTab.test.jsx +148 -0
- package/src/app/pages/NodePage/__tests__/NodePage.test.jsx +159 -57
- package/src/app/pages/NodePage/__tests__/RevisionDiff.test.jsx +164 -0
- package/src/app/pages/NodePage/__tests__/__snapshots__/NodePage.test.jsx.snap +2 -386
- package/src/app/pages/NodePage/index.jsx +94 -57
- package/src/app/pages/Root/__tests__/index.test.jsx +3 -1
- package/src/app/pages/Root/index.tsx +62 -12
- package/src/app/services/DJService.js +587 -55
- package/src/app/services/__tests__/DJService.test.jsx +382 -45
- package/src/index.tsx +1 -0
- package/src/mocks/mockNodes.jsx +265 -227
- package/src/styles/dag.css +4 -2
- package/src/styles/index.css +474 -10
- package/src/styles/loading.css +1 -1
- package/src/styles/node-creation.scss +84 -5
- package/src/styles/node-list.css +4 -0
- package/src/styles/sorted-table.css +15 -0
- package/src/app/components/DeleteNode.jsx +0 -55
- package/src/app/components/__tests__/DeleteNode.test.jsx +0 -53
- package/src/app/pages/NodePage/NodeSQLTab.jsx +0 -82
- package/src/app/pages/NodePage/__tests__/ClientCodePopover.test.jsx +0 -49
|
@@ -4,8 +4,10 @@ import fetchMock from 'jest-fetch-mock';
|
|
|
4
4
|
import userEvent from '@testing-library/user-event';
|
|
5
5
|
import {
|
|
6
6
|
initializeMockDJClient,
|
|
7
|
+
renderCreateMetric,
|
|
7
8
|
renderCreateNode,
|
|
8
9
|
renderEditNode,
|
|
10
|
+
renderEditTransformNode,
|
|
9
11
|
testElement,
|
|
10
12
|
} from './index.test';
|
|
11
13
|
import { mocks } from '../../../../mocks/mockNodes';
|
|
@@ -21,11 +23,11 @@ describe('AddEditNodePage submission succeeded', () => {
|
|
|
21
23
|
window.scrollTo = jest.fn();
|
|
22
24
|
});
|
|
23
25
|
|
|
24
|
-
it('for creating a node', async () => {
|
|
26
|
+
it('for creating a dimension/transform node', async () => {
|
|
25
27
|
const mockDjClient = initializeMockDJClient();
|
|
26
28
|
mockDjClient.DataJunctionAPI.createNode.mockReturnValue({
|
|
27
29
|
status: 200,
|
|
28
|
-
json: { name: 'default.
|
|
30
|
+
json: { name: 'default.some_test_dim' },
|
|
29
31
|
});
|
|
30
32
|
|
|
31
33
|
mockDjClient.DataJunctionAPI.tagsNode.mockReturnValue({
|
|
@@ -42,42 +44,179 @@ describe('AddEditNodePage submission succeeded', () => {
|
|
|
42
44
|
const { container } = renderCreateNode(element);
|
|
43
45
|
|
|
44
46
|
await userEvent.type(
|
|
45
|
-
screen.getByLabelText('Display Name'),
|
|
46
|
-
'Some Test
|
|
47
|
+
screen.getByLabelText('Display Name *'),
|
|
48
|
+
'Some Test Dim',
|
|
49
|
+
);
|
|
50
|
+
await userEvent.type(
|
|
51
|
+
screen.getByLabelText('Query *'),
|
|
52
|
+
'SELECT a, b, c FROM test',
|
|
47
53
|
);
|
|
48
|
-
await userEvent.type(screen.getByLabelText('Query'), 'SELECT * FROM test');
|
|
49
54
|
await userEvent.click(screen.getByText('Create dimension'));
|
|
50
55
|
|
|
51
56
|
await waitFor(() => {
|
|
52
57
|
expect(mockDjClient.DataJunctionAPI.createNode).toBeCalled();
|
|
53
58
|
expect(mockDjClient.DataJunctionAPI.createNode).toBeCalledWith(
|
|
54
59
|
'dimension',
|
|
55
|
-
'default.
|
|
56
|
-
'Some Test
|
|
60
|
+
'default.some_test_dim',
|
|
61
|
+
'Some Test Dim',
|
|
57
62
|
'',
|
|
58
|
-
'SELECT
|
|
59
|
-
'
|
|
63
|
+
'SELECT a, b, c FROM test',
|
|
64
|
+
'published',
|
|
60
65
|
'default',
|
|
61
66
|
null,
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
expect(mockDjClient.DataJunctionAPI.tagsNode).toBeCalledWith(
|
|
65
|
-
'default.some_test_metric',
|
|
67
|
+
undefined,
|
|
68
|
+
undefined,
|
|
66
69
|
undefined,
|
|
67
70
|
);
|
|
68
|
-
expect(screen.getByText(/default.
|
|
71
|
+
expect(screen.getByText(/default.some_test_dim/)).toBeInTheDocument();
|
|
69
72
|
});
|
|
70
73
|
|
|
74
|
+
// After successful creation, it should return a success message
|
|
75
|
+
expect(screen.getByTestId('success')).toHaveTextContent(
|
|
76
|
+
'Successfully created node default.some_test_dim',
|
|
77
|
+
);
|
|
78
|
+
}, 60000);
|
|
79
|
+
|
|
80
|
+
it('for creating a metric node', async () => {
|
|
81
|
+
const mockDjClient = initializeMockDJClient();
|
|
82
|
+
mockDjClient.DataJunctionAPI.createNode.mockReturnValue({
|
|
83
|
+
status: 200,
|
|
84
|
+
json: { name: 'default.some_test_metric' },
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
mockDjClient.DataJunctionAPI.tagsNode.mockReturnValue({
|
|
88
|
+
status: 200,
|
|
89
|
+
json: { message: 'Success' },
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
mockDjClient.DataJunctionAPI.nodesWithType
|
|
93
|
+
.mockReturnValueOnce(['default.test1'])
|
|
94
|
+
.mockReturnValueOnce(['default.test2'])
|
|
95
|
+
.mockReturnValueOnce([]);
|
|
96
|
+
|
|
97
|
+
mockDjClient.DataJunctionAPI.listTags.mockReturnValue([
|
|
98
|
+
{ name: 'purpose', display_name: 'Purpose' },
|
|
99
|
+
{ name: 'intent', display_name: 'Intent' },
|
|
100
|
+
]);
|
|
101
|
+
|
|
102
|
+
mockDjClient.DataJunctionAPI.listMetricMetadata.mockReturnValue(
|
|
103
|
+
mocks.metricMetadata,
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
const element = testElement(mockDjClient);
|
|
107
|
+
const { container } = renderCreateMetric(element);
|
|
108
|
+
|
|
109
|
+
await userEvent.type(
|
|
110
|
+
screen.getByLabelText('Display Name *'),
|
|
111
|
+
'Some Test Metric',
|
|
112
|
+
);
|
|
113
|
+
const selectUpstream = screen.getByTestId('select-upstream-node');
|
|
114
|
+
fireEvent.keyDown(selectUpstream.firstChild, { key: 'ArrowDown' });
|
|
115
|
+
fireEvent.click(screen.getByText('default.repair_orders'));
|
|
116
|
+
|
|
117
|
+
await userEvent.type(
|
|
118
|
+
screen.getByLabelText('Aggregate Expression *'),
|
|
119
|
+
'SUM(a)',
|
|
120
|
+
);
|
|
121
|
+
await userEvent.click(screen.getByText('Create metric'));
|
|
122
|
+
|
|
123
|
+
await waitFor(
|
|
124
|
+
() => {
|
|
125
|
+
expect(mockDjClient.DataJunctionAPI.createNode).toBeCalled();
|
|
126
|
+
expect(mockDjClient.DataJunctionAPI.createNode).toBeCalledWith(
|
|
127
|
+
'metric',
|
|
128
|
+
'default.some_test_metric',
|
|
129
|
+
'Some Test Metric',
|
|
130
|
+
'',
|
|
131
|
+
'SELECT SUM(a) FROM default.repair_orders',
|
|
132
|
+
'published',
|
|
133
|
+
'default',
|
|
134
|
+
null,
|
|
135
|
+
undefined,
|
|
136
|
+
undefined,
|
|
137
|
+
undefined,
|
|
138
|
+
);
|
|
139
|
+
expect(
|
|
140
|
+
screen.getByText(/default.some_test_metric/),
|
|
141
|
+
).toBeInTheDocument();
|
|
142
|
+
},
|
|
143
|
+
{ timeout: 10000 },
|
|
144
|
+
);
|
|
145
|
+
|
|
71
146
|
// After successful creation, it should return a success message
|
|
72
147
|
expect(screen.getByTestId('success')).toHaveTextContent(
|
|
73
148
|
'Successfully created node default.some_test_metric',
|
|
74
149
|
);
|
|
75
150
|
}, 60000);
|
|
76
151
|
|
|
77
|
-
it('for editing a node', async () => {
|
|
152
|
+
it('for editing a transform or dimension node', async () => {
|
|
78
153
|
const mockDjClient = initializeMockDJClient();
|
|
79
154
|
|
|
80
|
-
mockDjClient.DataJunctionAPI.
|
|
155
|
+
mockDjClient.DataJunctionAPI.getNodeForEditing.mockReturnValue(
|
|
156
|
+
mocks.mockGetTransformNode,
|
|
157
|
+
);
|
|
158
|
+
mockDjClient.DataJunctionAPI.patchNode = jest.fn();
|
|
159
|
+
mockDjClient.DataJunctionAPI.patchNode.mockReturnValue({
|
|
160
|
+
status: 201,
|
|
161
|
+
json: { name: 'default.repair_order_transform', type: 'transform' },
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
mockDjClient.DataJunctionAPI.tagsNode.mockReturnValue({
|
|
165
|
+
status: 200,
|
|
166
|
+
json: { message: 'Success' },
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
mockDjClient.DataJunctionAPI.listTags.mockReturnValue([
|
|
170
|
+
{ name: 'purpose', display_name: 'Purpose' },
|
|
171
|
+
{ name: 'intent', display_name: 'Intent' },
|
|
172
|
+
]);
|
|
173
|
+
|
|
174
|
+
const element = testElement(mockDjClient);
|
|
175
|
+
const { getByTestId } = renderEditTransformNode(element);
|
|
176
|
+
|
|
177
|
+
await userEvent.type(screen.getByLabelText('Display Name *'), '!!!');
|
|
178
|
+
await userEvent.type(screen.getByLabelText('Description'), '!!!');
|
|
179
|
+
await userEvent.click(screen.getByText('Save'));
|
|
180
|
+
|
|
181
|
+
const selectTags = getByTestId('select-tags');
|
|
182
|
+
fireEvent.keyDown(selectTags.firstChild, { key: 'ArrowDown' });
|
|
183
|
+
fireEvent.click(screen.getByText('Purpose'));
|
|
184
|
+
|
|
185
|
+
await waitFor(async () => {
|
|
186
|
+
expect(mockDjClient.DataJunctionAPI.patchNode).toBeCalledTimes(1);
|
|
187
|
+
expect(mockDjClient.DataJunctionAPI.patchNode).toBeCalledWith(
|
|
188
|
+
'default.repair_order_transform',
|
|
189
|
+
'Default: Repair Order Transform!!!',
|
|
190
|
+
'Repair order dimension!!!',
|
|
191
|
+
'SELECT repair_order_id, municipality_id, hard_hat_id, dispatcher_id FROM default.repair_orders',
|
|
192
|
+
'published',
|
|
193
|
+
[],
|
|
194
|
+
'',
|
|
195
|
+
'',
|
|
196
|
+
'',
|
|
197
|
+
undefined,
|
|
198
|
+
);
|
|
199
|
+
expect(mockDjClient.DataJunctionAPI.tagsNode).toBeCalledTimes(1);
|
|
200
|
+
expect(mockDjClient.DataJunctionAPI.tagsNode).toBeCalledWith(
|
|
201
|
+
'default.repair_order_transform',
|
|
202
|
+
[],
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
expect(mockDjClient.DataJunctionAPI.listMetricMetadata).toBeCalledTimes(
|
|
206
|
+
0,
|
|
207
|
+
);
|
|
208
|
+
expect(
|
|
209
|
+
await screen.getByText(/Successfully updated transform node/),
|
|
210
|
+
).toBeInTheDocument();
|
|
211
|
+
});
|
|
212
|
+
}, 1000000);
|
|
213
|
+
|
|
214
|
+
it('for editing a metric node', async () => {
|
|
215
|
+
const mockDjClient = initializeMockDJClient();
|
|
216
|
+
|
|
217
|
+
mockDjClient.DataJunctionAPI.getNodeForEditing.mockReturnValue(
|
|
218
|
+
mocks.mockGetMetricNode,
|
|
219
|
+
);
|
|
81
220
|
mockDjClient.DataJunctionAPI.patchNode = jest.fn();
|
|
82
221
|
mockDjClient.DataJunctionAPI.patchNode.mockReturnValue({
|
|
83
222
|
status: 201,
|
|
@@ -97,13 +236,13 @@ describe('AddEditNodePage submission succeeded', () => {
|
|
|
97
236
|
const element = testElement(mockDjClient);
|
|
98
237
|
const { getByTestId } = renderEditNode(element);
|
|
99
238
|
|
|
100
|
-
await userEvent.type(screen.getByLabelText('Display Name'), '!!!');
|
|
239
|
+
await userEvent.type(screen.getByLabelText('Display Name *'), '!!!');
|
|
101
240
|
await userEvent.type(screen.getByLabelText('Description'), '!!!');
|
|
102
241
|
await userEvent.click(screen.getByText('Save'));
|
|
103
242
|
|
|
104
243
|
const selectTags = getByTestId('select-tags');
|
|
105
|
-
|
|
106
|
-
|
|
244
|
+
fireEvent.keyDown(selectTags.firstChild, { key: 'ArrowDown' });
|
|
245
|
+
fireEvent.click(screen.getByText('Purpose'));
|
|
107
246
|
|
|
108
247
|
await waitFor(async () => {
|
|
109
248
|
expect(mockDjClient.DataJunctionAPI.patchNode).toBeCalledTimes(1);
|
|
@@ -111,19 +250,23 @@ describe('AddEditNodePage submission succeeded', () => {
|
|
|
111
250
|
'default.num_repair_orders',
|
|
112
251
|
'Default: Num Repair Orders!!!',
|
|
113
252
|
'Number of repair orders!!!',
|
|
114
|
-
'SELECT count(repair_order_id)
|
|
253
|
+
'SELECT count(repair_order_id) FROM default.repair_orders',
|
|
115
254
|
'published',
|
|
116
255
|
['repair_order_id', 'country'],
|
|
256
|
+
'neutral',
|
|
257
|
+
'unitless',
|
|
258
|
+
5,
|
|
259
|
+
undefined,
|
|
117
260
|
);
|
|
118
261
|
expect(mockDjClient.DataJunctionAPI.tagsNode).toBeCalledTimes(1);
|
|
119
262
|
expect(mockDjClient.DataJunctionAPI.tagsNode).toBeCalledWith(
|
|
120
263
|
'default.num_repair_orders',
|
|
121
|
-
[
|
|
264
|
+
['purpose'],
|
|
122
265
|
);
|
|
123
266
|
|
|
124
|
-
expect(
|
|
125
|
-
|
|
126
|
-
)
|
|
267
|
+
expect(mockDjClient.DataJunctionAPI.listMetricMetadata).toBeCalledTimes(
|
|
268
|
+
1,
|
|
269
|
+
);
|
|
127
270
|
expect(
|
|
128
271
|
await screen.getByText(/Successfully updated metric node/),
|
|
129
272
|
).toBeInTheDocument();
|
|
@@ -6,7 +6,6 @@ import fetchMock from 'jest-fetch-mock';
|
|
|
6
6
|
import { AddEditNodePage } from '../index.jsx';
|
|
7
7
|
import { mocks } from '../../../../mocks/mockNodes';
|
|
8
8
|
import DJClientContext from '../../../providers/djclient';
|
|
9
|
-
import userEvent from '@testing-library/user-event';
|
|
10
9
|
|
|
11
10
|
fetchMock.enableMocks();
|
|
12
11
|
|
|
@@ -36,6 +35,7 @@ export const initializeMockDJClient = () => {
|
|
|
36
35
|
];
|
|
37
36
|
},
|
|
38
37
|
metrics: {},
|
|
38
|
+
getNodeForEditing: jest.fn(),
|
|
39
39
|
namespaces: () => {
|
|
40
40
|
return [
|
|
41
41
|
{
|
|
@@ -52,7 +52,20 @@ export const initializeMockDJClient = () => {
|
|
|
52
52
|
patchNode: jest.fn(),
|
|
53
53
|
node: jest.fn(),
|
|
54
54
|
tagsNode: jest.fn(),
|
|
55
|
-
listTags: jest.fn(),
|
|
55
|
+
listTags: jest.fn().mockReturnValue([]),
|
|
56
|
+
metric: jest.fn().mockReturnValue(mocks.mockMetricNode),
|
|
57
|
+
nodesWithType: jest
|
|
58
|
+
.fn()
|
|
59
|
+
.mockReturnValueOnce(['a'])
|
|
60
|
+
.mockReturnValueOnce(['b'])
|
|
61
|
+
.mockReturnValueOnce(['default.repair_orders']),
|
|
62
|
+
listMetricMetadata: jest.fn().mockReturnValue({
|
|
63
|
+
directions: ['higher_is_better', 'lower_is_better', 'neutral'],
|
|
64
|
+
units: [
|
|
65
|
+
{ name: 'dollar', label: 'Dollar' },
|
|
66
|
+
{ name: 'second', label: 'Second' },
|
|
67
|
+
],
|
|
68
|
+
}),
|
|
56
69
|
},
|
|
57
70
|
};
|
|
58
71
|
};
|
|
@@ -75,6 +88,16 @@ export const renderCreateNode = element => {
|
|
|
75
88
|
);
|
|
76
89
|
};
|
|
77
90
|
|
|
91
|
+
export const renderCreateMetric = element => {
|
|
92
|
+
return render(
|
|
93
|
+
<MemoryRouter initialEntries={['/create/metric/default']}>
|
|
94
|
+
<Routes>
|
|
95
|
+
<Route path="create/:nodeType/:initialNamespace" element={element} />
|
|
96
|
+
</Routes>
|
|
97
|
+
</MemoryRouter>,
|
|
98
|
+
);
|
|
99
|
+
};
|
|
100
|
+
|
|
78
101
|
export const renderEditNode = element => {
|
|
79
102
|
return render(
|
|
80
103
|
<MemoryRouter initialEntries={['/nodes/default.num_repair_orders/edit']}>
|
|
@@ -85,6 +108,18 @@ export const renderEditNode = element => {
|
|
|
85
108
|
);
|
|
86
109
|
};
|
|
87
110
|
|
|
111
|
+
export const renderEditTransformNode = element => {
|
|
112
|
+
return render(
|
|
113
|
+
<MemoryRouter
|
|
114
|
+
initialEntries={['/nodes/default.repair_order_transform/edit']}
|
|
115
|
+
>
|
|
116
|
+
<Routes>
|
|
117
|
+
<Route path="nodes/:name/edit" element={element} />
|
|
118
|
+
</Routes>
|
|
119
|
+
</MemoryRouter>,
|
|
120
|
+
);
|
|
121
|
+
};
|
|
122
|
+
|
|
88
123
|
describe('AddEditNodePage', () => {
|
|
89
124
|
beforeEach(() => {
|
|
90
125
|
fetchMock.resetMocks();
|
|
@@ -104,13 +139,17 @@ describe('AddEditNodePage', () => {
|
|
|
104
139
|
).toMatchSnapshot();
|
|
105
140
|
|
|
106
141
|
// The namespace should be set to the one provided in params
|
|
107
|
-
|
|
142
|
+
screen
|
|
143
|
+
.getAllByText('default')
|
|
144
|
+
.forEach(element => expect(element).toBeInTheDocument());
|
|
108
145
|
});
|
|
109
146
|
});
|
|
110
147
|
|
|
111
148
|
it('Edit node page renders with the selected node', async () => {
|
|
112
149
|
const mockDjClient = initializeMockDJClient();
|
|
113
|
-
mockDjClient.DataJunctionAPI.
|
|
150
|
+
mockDjClient.DataJunctionAPI.getNodeForEditing.mockReturnValue(
|
|
151
|
+
mocks.mockGetMetricNode,
|
|
152
|
+
);
|
|
114
153
|
|
|
115
154
|
const element = testElement(mockDjClient);
|
|
116
155
|
renderEditNode(element);
|
|
@@ -128,28 +167,23 @@ describe('AddEditNodePage', () => {
|
|
|
128
167
|
// The description should be populated
|
|
129
168
|
expect(screen.getByText('Number of repair orders')).toBeInTheDocument();
|
|
130
169
|
|
|
131
|
-
// The
|
|
132
|
-
expect(
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
).toBeInTheDocument();
|
|
170
|
+
// The upstream node should be populated
|
|
171
|
+
expect(screen.getByText('default.repair_orders')).toBeInTheDocument();
|
|
172
|
+
|
|
173
|
+
// The aggregate expression should be populated
|
|
174
|
+
expect(screen.getByText('count')).toBeInTheDocument();
|
|
175
|
+
expect(screen.getByText('(repair_order_id)')).toBeInTheDocument();
|
|
137
176
|
});
|
|
138
177
|
});
|
|
139
178
|
|
|
140
179
|
it('Verify edit page node not found', async () => {
|
|
141
180
|
const mockDjClient = initializeMockDJClient();
|
|
142
|
-
mockDjClient.DataJunctionAPI.
|
|
143
|
-
mockDjClient.DataJunctionAPI.node.mockReturnValue({
|
|
144
|
-
message: 'A node with name `default.num_repair_orders` does not exist.',
|
|
145
|
-
errors: [],
|
|
146
|
-
warnings: [],
|
|
147
|
-
});
|
|
181
|
+
mockDjClient.DataJunctionAPI.getNodeForEditing.mockReturnValue(null);
|
|
148
182
|
const element = testElement(mockDjClient);
|
|
149
183
|
renderEditNode(element);
|
|
150
184
|
|
|
151
185
|
await waitFor(() => {
|
|
152
|
-
expect(mockDjClient.DataJunctionAPI.
|
|
186
|
+
expect(mockDjClient.DataJunctionAPI.getNodeForEditing).toBeCalledTimes(1);
|
|
153
187
|
expect(
|
|
154
188
|
screen.getByText('Node default.num_repair_orders does not exist!'),
|
|
155
189
|
).toBeInTheDocument();
|
|
@@ -158,18 +192,14 @@ describe('AddEditNodePage', () => {
|
|
|
158
192
|
|
|
159
193
|
it('Verify only transforms, metrics, and dimensions can be edited', async () => {
|
|
160
194
|
const mockDjClient = initializeMockDJClient();
|
|
161
|
-
mockDjClient.DataJunctionAPI.
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
type: 'source',
|
|
165
|
-
name: 'default.repair_orders',
|
|
166
|
-
display_name: 'Default: Repair Orders',
|
|
167
|
-
});
|
|
195
|
+
mockDjClient.DataJunctionAPI.getNodeForEditing.mockReturnValue(
|
|
196
|
+
mocks.mockGetSourceNode,
|
|
197
|
+
);
|
|
168
198
|
const element = testElement(mockDjClient);
|
|
169
199
|
renderEditNode(element);
|
|
170
200
|
|
|
171
201
|
await waitFor(() => {
|
|
172
|
-
expect(mockDjClient.DataJunctionAPI.
|
|
202
|
+
expect(mockDjClient.DataJunctionAPI.getNodeForEditing).toBeCalledTimes(1);
|
|
173
203
|
expect(
|
|
174
204
|
screen.getByText(
|
|
175
205
|
'Node default.num_repair_orders is of type source and cannot be edited',
|