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.
Files changed (110) hide show
  1. package/Makefile +7 -1
  2. package/package.json +18 -7
  3. package/public/index.html +1 -1
  4. package/src/app/components/AddNodeDropdown.jsx +44 -0
  5. package/src/app/components/ListGroupItem.jsx +2 -1
  6. package/src/app/components/NodeListActions.jsx +69 -0
  7. package/src/app/components/NodeMaterializationDelete.jsx +80 -0
  8. package/src/app/components/QueryInfo.jsx +96 -1
  9. package/src/app/components/Search.jsx +94 -0
  10. package/src/app/components/__tests__/NodeListActions.test.jsx +94 -0
  11. package/src/app/components/__tests__/Search.test.jsx +63 -0
  12. package/src/app/components/__tests__/__snapshots__/ListGroupItem.test.tsx.snap +5 -3
  13. package/src/app/components/djgraph/Collapse.jsx +3 -2
  14. package/src/app/components/djgraph/DJNode.jsx +1 -1
  15. package/src/app/components/djgraph/DJNodeColumns.jsx +5 -1
  16. package/src/app/components/djgraph/LayoutFlow.jsx +5 -3
  17. package/src/app/components/forms/Action.jsx +8 -0
  18. package/src/app/components/forms/NodeNameField.jsx +64 -0
  19. package/src/app/components/search.css +17 -0
  20. package/src/app/icons/AddItemIcon.jsx +16 -0
  21. package/src/app/icons/CommitIcon.jsx +45 -0
  22. package/src/app/icons/DiffIcon.jsx +63 -0
  23. package/src/app/icons/EyeIcon.jsx +20 -0
  24. package/src/app/icons/FilterIcon.jsx +7 -0
  25. package/src/app/icons/JupyterExportIcon.jsx +25 -0
  26. package/src/app/icons/LoadingIcon.jsx +10 -10
  27. package/src/app/icons/PythonIcon.jsx +6 -44
  28. package/src/app/index.tsx +24 -0
  29. package/src/app/pages/AddEditNodePage/AlertMessage.jsx +10 -0
  30. package/src/app/pages/AddEditNodePage/ColumnsSelect.jsx +84 -0
  31. package/src/app/pages/AddEditNodePage/DescriptionField.jsx +17 -0
  32. package/src/app/pages/AddEditNodePage/DisplayNameField.jsx +16 -0
  33. package/src/app/pages/AddEditNodePage/FormikSelect.jsx +5 -0
  34. package/src/app/pages/AddEditNodePage/FullNameField.jsx +3 -2
  35. package/src/app/pages/AddEditNodePage/Loadable.jsx +6 -2
  36. package/src/app/pages/AddEditNodePage/MetricMetadataFields.jsx +75 -0
  37. package/src/app/pages/AddEditNodePage/MetricQueryField.jsx +71 -0
  38. package/src/app/pages/AddEditNodePage/NamespaceField.jsx +40 -0
  39. package/src/app/pages/AddEditNodePage/NodeModeField.jsx +14 -0
  40. package/src/app/pages/AddEditNodePage/NodeQueryField.jsx +8 -3
  41. package/src/app/pages/AddEditNodePage/RequiredDimensionsSelect.jsx +54 -0
  42. package/src/app/pages/AddEditNodePage/TagsField.jsx +47 -0
  43. package/src/app/pages/AddEditNodePage/UpstreamNodeField.jsx +49 -0
  44. package/src/app/pages/AddEditNodePage/__tests__/AddEditNodePageFormFailed.test.jsx +15 -9
  45. package/src/app/pages/AddEditNodePage/__tests__/AddEditNodePageFormSuccess.test.jsx +167 -24
  46. package/src/app/pages/AddEditNodePage/__tests__/index.test.jsx +55 -25
  47. package/src/app/pages/AddEditNodePage/index.jsx +275 -194
  48. package/src/app/pages/CubeBuilderPage/DimensionsSelect.jsx +154 -0
  49. package/src/app/pages/CubeBuilderPage/Loadable.jsx +16 -0
  50. package/src/app/pages/CubeBuilderPage/MetricsSelect.jsx +77 -0
  51. package/src/app/pages/CubeBuilderPage/__tests__/index.test.jsx +405 -0
  52. package/src/app/pages/CubeBuilderPage/index.jsx +267 -0
  53. package/src/app/pages/NamespacePage/AddNamespacePopover.jsx +5 -5
  54. package/src/app/pages/NamespacePage/Explorer.jsx +6 -2
  55. package/src/app/pages/NamespacePage/FieldControl.jsx +21 -0
  56. package/src/app/pages/NamespacePage/NodeTypeSelect.jsx +30 -0
  57. package/src/app/pages/NamespacePage/TagSelect.jsx +44 -0
  58. package/src/app/pages/NamespacePage/UserSelect.jsx +47 -0
  59. package/src/app/pages/NamespacePage/__tests__/index.test.jsx +98 -19
  60. package/src/app/pages/NamespacePage/index.jsx +272 -89
  61. package/src/app/pages/NodePage/AddBackfillPopover.jsx +60 -61
  62. package/src/app/pages/NodePage/AddMaterializationPopover.jsx +104 -51
  63. package/src/app/pages/NodePage/ClientCodePopover.jsx +73 -25
  64. package/src/app/pages/NodePage/DimensionFilter.jsx +86 -0
  65. package/src/app/pages/NodePage/EditColumnDescriptionPopover.jsx +116 -0
  66. package/src/app/pages/NodePage/LinkDimensionPopover.jsx +38 -23
  67. package/src/app/pages/NodePage/MaterializationConfigField.jsx +60 -0
  68. package/src/app/pages/NodePage/NodeColumnTab.jsx +183 -113
  69. package/src/app/pages/NodePage/NodeDependenciesTab.jsx +153 -0
  70. package/src/app/pages/NodePage/NodeGraphTab.jsx +56 -29
  71. package/src/app/pages/NodePage/NodeHistory.jsx +165 -161
  72. package/src/app/pages/NodePage/NodeInfoTab.jsx +148 -14
  73. package/src/app/pages/NodePage/NodeMaterializationTab.jsx +201 -104
  74. package/src/app/pages/NodePage/NodeStatus.jsx +96 -21
  75. package/src/app/pages/NodePage/NodeValidateTab.jsx +367 -0
  76. package/src/app/pages/NodePage/NotebookDownload.jsx +36 -0
  77. package/src/app/pages/NodePage/PartitionColumnPopover.jsx +3 -5
  78. package/src/app/pages/NodePage/PartitionValueForm.jsx +60 -0
  79. package/src/app/pages/NodePage/RevisionDiff.jsx +209 -0
  80. package/src/app/pages/NodePage/WatchNodeButton.jsx +226 -0
  81. package/src/app/pages/NodePage/__tests__/AddBackfillPopover.test.jsx +13 -4
  82. package/src/app/pages/NodePage/__tests__/AddMaterializationPopover.test.jsx +87 -0
  83. package/src/app/pages/NodePage/__tests__/DimensionFilter.test.jsx +74 -0
  84. package/src/app/pages/NodePage/__tests__/EditColumnDescriptionPopover.test.jsx +149 -0
  85. package/src/app/pages/NodePage/__tests__/LinkDimensionPopover.test.jsx +10 -14
  86. package/src/app/pages/NodePage/__tests__/NodeColumnTab.test.jsx +166 -0
  87. package/src/app/pages/NodePage/__tests__/NodeDependenciesTab.test.jsx +151 -0
  88. package/src/app/pages/NodePage/__tests__/NodeGraphTab.test.jsx +6 -2
  89. package/src/app/pages/NodePage/__tests__/NodeLineageTab.test.jsx +3 -2
  90. package/src/app/pages/NodePage/__tests__/NodeMaterializationTab.test.jsx +148 -0
  91. package/src/app/pages/NodePage/__tests__/NodePage.test.jsx +159 -57
  92. package/src/app/pages/NodePage/__tests__/RevisionDiff.test.jsx +164 -0
  93. package/src/app/pages/NodePage/__tests__/__snapshots__/NodePage.test.jsx.snap +2 -386
  94. package/src/app/pages/NodePage/index.jsx +94 -57
  95. package/src/app/pages/Root/__tests__/index.test.jsx +3 -1
  96. package/src/app/pages/Root/index.tsx +62 -12
  97. package/src/app/services/DJService.js +587 -55
  98. package/src/app/services/__tests__/DJService.test.jsx +382 -45
  99. package/src/index.tsx +1 -0
  100. package/src/mocks/mockNodes.jsx +265 -227
  101. package/src/styles/dag.css +4 -2
  102. package/src/styles/index.css +474 -10
  103. package/src/styles/loading.css +1 -1
  104. package/src/styles/node-creation.scss +84 -5
  105. package/src/styles/node-list.css +4 -0
  106. package/src/styles/sorted-table.css +15 -0
  107. package/src/app/components/DeleteNode.jsx +0 -55
  108. package/src/app/components/__tests__/DeleteNode.test.jsx +0 -53
  109. package/src/app/pages/NodePage/NodeSQLTab.jsx +0 -82
  110. 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.some_test_metric' },
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 Metric',
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.some_test_metric',
56
- 'Some Test Metric',
60
+ 'default.some_test_dim',
61
+ 'Some Test Dim',
57
62
  '',
58
- 'SELECT * FROM test',
59
- 'draft',
63
+ 'SELECT a, b, c FROM test',
64
+ 'published',
60
65
  'default',
61
66
  null,
62
- );
63
- expect(mockDjClient.DataJunctionAPI.tagsNode).toBeCalled();
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.some_test_metric/)).toBeInTheDocument();
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.node.mockReturnValue(mocks.mockMetricNode);
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
- await fireEvent.keyDown(selectTags.firstChild, { key: 'ArrowDown' });
106
- await fireEvent.click(screen.getByText('Purpose'));
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) default_DOT_num_repair_orders FROM default.repair_orders',
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
- [{ display_name: 'Purpose', name: 'purpose' }],
264
+ ['purpose'],
122
265
  );
123
266
 
124
- expect(
125
- await screen.getByDisplayValue('repair_order_id, country'),
126
- ).toBeInTheDocument();
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
- expect(screen.getByText('default')).toBeInTheDocument();
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.node.mockReturnValue(mocks.mockMetricNode);
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 query should be populated
132
- expect(
133
- screen.getByText(
134
- 'SELECT count(repair_order_id) default_DOT_num_repair_orders FROM default.repair_orders',
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.node = jest.fn();
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.node).toBeCalledTimes(1);
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.node = jest.fn();
162
- mockDjClient.DataJunctionAPI.node.mockReturnValue({
163
- namespace: 'default',
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.node).toBeCalledTimes(1);
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',