@reltio/sources 1.4.1585 → 1.4.1586-mui5
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/index.ts +1 -0
- package/package.json +38 -21
- package/public/bundle.js +205 -0
- package/public/bundle.js.LICENSE.txt +79 -0
- package/public/package.json +22 -0
- package/scripts/build/index.js +20 -0
- package/src/components/CrosswalkTreeView/CrosswalkTreeView.tsx +47 -0
- package/src/components/CrosswalkTreeView/__tests__/CrosswalkTreeView.spec.tsx +72 -0
- package/src/components/CrosswalkTreeView/__tests__/helpers.spec.ts +961 -0
- package/src/components/CrosswalkTreeView/helpers.ts +91 -0
- package/src/components/CrosswalkTreeView/styles.ts +10 -0
- package/src/components/EmptyState/EmptyState.tsx +20 -0
- package/src/components/EmptyState/__tests__/EmptyState.test.tsx +13 -0
- package/src/components/EmptyState/icons/EmptySources.svg +43 -0
- package/src/components/EmptyState/styles.ts +19 -0
- package/src/components/LegendTable/LegendTable.tsx +124 -0
- package/src/components/LegendTable/LegendTableRow/ContributorRow/ContributorRow.tsx +46 -0
- package/src/components/LegendTable/LegendTableRow/ContributorRow/__tests__/ContributorRow.test.tsx +103 -0
- package/src/components/LegendTable/LegendTableRow/ContributorRow/styles.ts +31 -0
- package/src/components/LegendTable/LegendTableRow/LegendTableRow.tsx +179 -0
- package/src/components/LegendTable/LegendTableRow/__tests__/LegendTableRow.test.tsx +371 -0
- package/src/components/LegendTable/LegendTableRow/styles.ts +31 -0
- package/src/components/LegendTable/__tests__/LegendTable.test.tsx +273 -0
- package/src/components/LegendTable/__tests__/helpers.test.ts +541 -0
- package/src/components/LegendTable/helpers.ts +64 -0
- package/src/components/LegendTable/styles.ts +17 -0
- package/src/components/LegendView/LegendView.tsx +201 -0
- package/src/components/LegendView/__tests__/LegendView.test.tsx +307 -0
- package/src/components/LegendView/styles.ts +51 -0
- package/src/components/RightSidePanel/RightSidePanel.tsx +25 -0
- package/src/components/RightSidePanel/__tests__/RightSidePanel.test.tsx +28 -0
- package/src/components/RightSidePanel/styles.ts +14 -0
- package/src/components/RulesestsSelector/RulesestsSelector.tsx +31 -0
- package/src/components/RulesestsSelector/RulesetOption/RulesetOption.tsx +25 -0
- package/src/components/RulesestsSelector/RulesetOption/__tests__/RulesetOption.test.tsx +25 -0
- package/src/components/RulesestsSelector/RulesetOption/styles.ts +27 -0
- package/src/components/RulesestsSelector/RulesetsMenuList/RulesetsMenuList.tsx +14 -0
- package/src/components/RulesestsSelector/__tests__/RulesetsSelector.test.tsx +91 -0
- package/src/components/RulesestsSelector/styles.ts +7 -0
- package/src/components/SankeyChart/Link.tsx +31 -0
- package/src/components/SankeyChart/MergeTooltip.tsx +37 -0
- package/src/components/SankeyChart/Node.tsx +137 -0
- package/src/components/SankeyChart/SankeyChart.tsx +103 -0
- package/src/components/SankeyChart/__tests__/Link.spec.tsx +127 -0
- package/src/components/SankeyChart/__tests__/MergeTooltip.spec.tsx +22 -0
- package/src/components/SankeyChart/__tests__/Node.spec.tsx +248 -0
- package/src/components/SankeyChart/__tests__/SankeyChart.spec.tsx +161 -0
- package/src/components/SankeyChart/__tests__/__snapshots__/SankeyChart.spec.tsx.snap +183 -0
- package/src/components/SankeyChart/sankey.ts +322 -0
- package/src/components/SankeyChart/styles.ts +41 -0
- package/src/components/SankeyChart/useSankey.tsx +44 -0
- package/src/components/SelectableTree/SelectableTree.tsx +46 -0
- package/src/components/SelectableTree/__tests__/SelectableTree.test.tsx +28 -0
- package/src/components/SelectableTree/__tests__/__snapshots__/SelectableTree.test.tsx.snap +59 -0
- package/src/components/SelectableTree/styles.ts +42 -0
- package/src/components/SourcesView/SourcesView.tsx +318 -0
- package/src/components/SourcesView/__tests__/IntegrationSourcesView.spec.tsx +199 -0
- package/src/components/SourcesView/__tests__/SourcesView.spec.tsx +903 -0
- package/src/components/SourcesView/__tests__/data/metadata.data.ts +27 -0
- package/src/components/SourcesView/__tests__/data/store.data.ts +65 -0
- package/src/components/SourcesView/icons/LegendIcon.svg +8 -0
- package/src/components/SourcesView/index.tsx +57 -0
- package/src/components/SourcesView/styles.ts +44 -0
- package/src/components/TreeActionSnackbar/TreeActionSnackbar.tsx +38 -0
- package/src/components/TreeActionSnackbar/__tests__/TreeActionSnackbar.test.tsx +38 -0
- package/src/components/TreeActionSnackbar/styles.ts +11 -0
- package/src/components/UnmergeDialog/UnmergeDialog.tsx +78 -0
- package/src/components/UnmergeDialog/__tests__/UnmergeDialog.test.tsx +124 -0
- package/src/components/UnmergeDialog/__tests__/testData.data.ts +271 -0
- package/src/components/UnmergeDialog/styles.ts +34 -0
- package/src/components/UnsubscribeDialog/UnsubscribeDialog.tsx +64 -0
- package/src/components/UnsubscribeDialog/__tests__/UnsubscribeDialog.test.tsx +59 -0
- package/src/components/UnsubscribeDialog/styles.ts +31 -0
- package/src/hooks/__tests__/useCrosswalkTree.specs.tsx +68 -0
- package/src/hooks/__tests__/useCrosswalkTreeActions.specs.ts +110 -0
- package/src/hooks/__tests__/useCrosswalksDisplay.specs.tsx +213 -0
- package/src/hooks/__tests__/useEntityWithSurvivorshipGroups.specs.ts +160 -0
- package/src/hooks/useCrosswalkTree.ts +38 -0
- package/src/hooks/useCrosswalkTreeActions.ts +83 -0
- package/src/hooks/useCrosswalksDisplay.ts +110 -0
- package/src/hooks/useEntityWithSurvivorshipGroups.tsx +51 -0
- package/src/icons/notMatch.svg +14 -0
- package/src/index.ts +1 -0
- package/src/services/errors.ts +11 -0
- package/src/types/LegendMode.ts +5 -0
- package/src/types/SankeyChartData.ts +31 -0
- package/src/types/SourcesSavedState.ts +3 -0
- package/src/types/UnmergeContributorEvent.ts +7 -0
- package/src/types/UnsubscribeContributorEvent.ts +6 -0
- package/src/types/index.ts +4 -0
- package/tsconfig.json +4 -0
- package/webpack.config.js +10 -0
- package/bundle.js +0 -2
- package/bundle.js.LICENSE.txt +0 -42
|
@@ -0,0 +1,903 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {createStore} from 'redux';
|
|
3
|
+
import {Provider} from 'react-redux';
|
|
4
|
+
import {act} from 'react-dom/test-utils';
|
|
5
|
+
import {mount, ReactWrapper, shallow} from 'enzyme';
|
|
6
|
+
import Typography from '@mui/material/Typography';
|
|
7
|
+
import Divider from '@mui/material/Divider';
|
|
8
|
+
|
|
9
|
+
import * as components from '@reltio/components';
|
|
10
|
+
import {
|
|
11
|
+
AttributesTable,
|
|
12
|
+
CrosswalkDragLayer,
|
|
13
|
+
EmptyStub,
|
|
14
|
+
ErrorPopup,
|
|
15
|
+
ExpandedAttributesProvider,
|
|
16
|
+
HistoryActivityType,
|
|
17
|
+
HistoryFilter,
|
|
18
|
+
HistoryHeader,
|
|
19
|
+
HistoryPanelEmptyState,
|
|
20
|
+
HistoryView,
|
|
21
|
+
PerspectivesSettingsContext,
|
|
22
|
+
ResizablePanes,
|
|
23
|
+
ScreenProfileBand,
|
|
24
|
+
SideButtonsPanel
|
|
25
|
+
} from '@reltio/components';
|
|
26
|
+
import * as mdmSdk from '@reltio/mdm-sdk';
|
|
27
|
+
import {DateRangeTypes, UnmergeOperation} from '@reltio/mdm-sdk';
|
|
28
|
+
import SourcesView from '../SourcesView';
|
|
29
|
+
import {RulesetsSelector} from '../../RulesestsSelector/RulesestsSelector';
|
|
30
|
+
import * as RightSidePanelImport from '../../RightSidePanel/RightSidePanel';
|
|
31
|
+
import {RightSidePanel} from '../../RightSidePanel/RightSidePanel';
|
|
32
|
+
import {LegendMode, SourcesSavedState} from '../../../types';
|
|
33
|
+
import * as useCrosswalkTreeImport from '../../../hooks/useCrosswalkTree';
|
|
34
|
+
import * as useCrosswalksDisplayImport from '../../../hooks/useCrosswalksDisplay';
|
|
35
|
+
import * as useCrosswalkTreeActionsImport from '../../../hooks/useCrosswalkTreeActions';
|
|
36
|
+
import * as useEntityWithSurvivorshipGroupsImport from '../../../hooks/useEntityWithSurvivorshipGroups';
|
|
37
|
+
import {profile} from '@reltio/mdm-module';
|
|
38
|
+
import LegendView from '../../LegendView/LegendView';
|
|
39
|
+
import EmptyState from '../../EmptyState/EmptyState';
|
|
40
|
+
import TreeActionSnackbar from '../../TreeActionSnackbar/TreeActionSnackbar';
|
|
41
|
+
|
|
42
|
+
jest.mock('@reltio/mdm-sdk', () => ({
|
|
43
|
+
...jest.requireActual<Record<string, unknown>>('@reltio/mdm-sdk'),
|
|
44
|
+
getCrosswalkTree: jest.fn(),
|
|
45
|
+
isDataTenantEntity: jest.fn(),
|
|
46
|
+
getHistoricUris: jest.fn(),
|
|
47
|
+
getHistoryWithTotal: jest.fn()
|
|
48
|
+
}));
|
|
49
|
+
|
|
50
|
+
jest.mock('@reltio/components', () => ({
|
|
51
|
+
...jest.requireActual<Record<string, unknown>>('@reltio/components'),
|
|
52
|
+
ScreenProfileBand: () => null,
|
|
53
|
+
AttributesTable: () => null,
|
|
54
|
+
useModifiedEntity: jest.fn(),
|
|
55
|
+
CrosswalkDragLayer: () => null,
|
|
56
|
+
useHistory: jest.fn(),
|
|
57
|
+
HistoryHeader: () => null,
|
|
58
|
+
HistoryView: () => null,
|
|
59
|
+
useHistorySlice: jest.fn(),
|
|
60
|
+
useSnackbar: jest.fn()
|
|
61
|
+
}));
|
|
62
|
+
|
|
63
|
+
describe('SourcesView tests', () => {
|
|
64
|
+
let initialState;
|
|
65
|
+
let resolveSavedState;
|
|
66
|
+
const dispatch = jest.fn();
|
|
67
|
+
const createTestStore = (customInitialState?) => {
|
|
68
|
+
const reducer = (state = {...initialState, ...customInitialState}) => {
|
|
69
|
+
return state;
|
|
70
|
+
};
|
|
71
|
+
const store = createStore(reducer);
|
|
72
|
+
store.dispatch = dispatch;
|
|
73
|
+
return store;
|
|
74
|
+
};
|
|
75
|
+
const saveState = jest.fn();
|
|
76
|
+
const props = {
|
|
77
|
+
config: {
|
|
78
|
+
id: 'SourcesViewId'
|
|
79
|
+
},
|
|
80
|
+
saveState,
|
|
81
|
+
getSavedState: jest.fn(
|
|
82
|
+
() =>
|
|
83
|
+
new Promise((_resolve) => {
|
|
84
|
+
resolveSavedState = _resolve;
|
|
85
|
+
})
|
|
86
|
+
) as () => Promise<SourcesSavedState>
|
|
87
|
+
};
|
|
88
|
+
const attributeActions = {
|
|
89
|
+
onPinAttribute: jest.fn(),
|
|
90
|
+
onDeleteAttribute: jest.fn(),
|
|
91
|
+
onIgnoreAttribute: jest.fn(),
|
|
92
|
+
onEditAttribute: jest.fn(),
|
|
93
|
+
onAddAttribute: jest.fn()
|
|
94
|
+
};
|
|
95
|
+
const modifiedEntity = {
|
|
96
|
+
uri: 'entities/1',
|
|
97
|
+
type: 'configuration/entityTypes/HCP'
|
|
98
|
+
};
|
|
99
|
+
const crosswalksMap = {
|
|
100
|
+
entity: {},
|
|
101
|
+
relation: {}
|
|
102
|
+
};
|
|
103
|
+
const crosswalkTree = {
|
|
104
|
+
crosswalks: [],
|
|
105
|
+
uri: 'test'
|
|
106
|
+
};
|
|
107
|
+
const crosswalksDisplayProps = {
|
|
108
|
+
getCrosswalkColor: jest.fn(),
|
|
109
|
+
focusedCrosswalks: [],
|
|
110
|
+
highlightedCrosswalks: [],
|
|
111
|
+
toggleCrosswalkFocus: jest.fn(),
|
|
112
|
+
setCrosswalkHighlighted: jest.fn()
|
|
113
|
+
};
|
|
114
|
+
const showSnackbarMessageMock = jest.fn();
|
|
115
|
+
const SnackbarRendererMock = () => <div />;
|
|
116
|
+
const useSnackbarMock = jest.spyOn(components, 'useSnackbar').mockReturnValue({
|
|
117
|
+
SnackbarRenderer: SnackbarRendererMock,
|
|
118
|
+
showSnackbarMessage: showSnackbarMessageMock
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
const newlyCreatedAttributes = [];
|
|
122
|
+
const useModifiedEntityMock = jest.spyOn(components, 'useModifiedEntity').mockReturnValue({
|
|
123
|
+
modifiedEntity,
|
|
124
|
+
crosswalksMap,
|
|
125
|
+
newlyCreatedAttributes,
|
|
126
|
+
...attributeActions
|
|
127
|
+
});
|
|
128
|
+
const useCrosswalksDisplayMock = jest
|
|
129
|
+
.spyOn(useCrosswalksDisplayImport, 'useCrosswalksDisplay')
|
|
130
|
+
.mockReturnValue(crosswalksDisplayProps);
|
|
131
|
+
const showErrorMock = jest.spyOn(ErrorPopup, 'addError');
|
|
132
|
+
const isDataTenantEntityMock = jest.spyOn(mdmSdk, 'isDataTenantEntity').mockReturnValue(false);
|
|
133
|
+
|
|
134
|
+
const useCrosswalkTreeMock = jest.spyOn(useCrosswalkTreeImport, 'useCrosswalkTree');
|
|
135
|
+
const crosswalkTreeActions = {
|
|
136
|
+
addCrosswalk: jest.fn(),
|
|
137
|
+
unmergeContributor: jest.fn(),
|
|
138
|
+
editCrosswalk: jest.fn(),
|
|
139
|
+
deleteCrosswalk: jest.fn(),
|
|
140
|
+
unsubscribeContributor: jest.fn()
|
|
141
|
+
};
|
|
142
|
+
const useCrosswalkTreeActionsMock = jest
|
|
143
|
+
.spyOn(useCrosswalkTreeActionsImport, 'useCrosswalkTreeActions')
|
|
144
|
+
.mockReturnValue(crosswalkTreeActions);
|
|
145
|
+
const onReloadCrosswalkTree = jest.fn();
|
|
146
|
+
|
|
147
|
+
const onChangeSurvivorshipGroup = jest.fn();
|
|
148
|
+
|
|
149
|
+
const historicUris = ['entities/12345', 'entities/54321'];
|
|
150
|
+
const historyWithTotal = {
|
|
151
|
+
total: 3,
|
|
152
|
+
changes: [
|
|
153
|
+
{
|
|
154
|
+
timestamp: 1636456567409,
|
|
155
|
+
user: 'user1',
|
|
156
|
+
type: 'ENTITY_CHANGED'
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
timestamp: 1633089195406,
|
|
160
|
+
user: 'user2',
|
|
161
|
+
type: 'ENTITIES_SPLITTED'
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
timestamp: 1633089195000,
|
|
165
|
+
user: 'user3',
|
|
166
|
+
type: 'ENTITIES_SPLITTED'
|
|
167
|
+
}
|
|
168
|
+
]
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
const onApplyFilterMock = jest.fn();
|
|
172
|
+
const onClearFilterMock = jest.fn();
|
|
173
|
+
|
|
174
|
+
const useHistoryResult = {
|
|
175
|
+
isLoading: false,
|
|
176
|
+
canLoadMore: false,
|
|
177
|
+
onLoadMore: jest.fn(),
|
|
178
|
+
historicUris,
|
|
179
|
+
historyFilter: {
|
|
180
|
+
users: ['username2'],
|
|
181
|
+
activities: [HistoryActivityType.UNMERGE]
|
|
182
|
+
},
|
|
183
|
+
historyWithTotal,
|
|
184
|
+
onApplyFilter: onApplyFilterMock,
|
|
185
|
+
onClearFilter: onClearFilterMock
|
|
186
|
+
};
|
|
187
|
+
const useHistoryMock = jest.spyOn(components, 'useHistory');
|
|
188
|
+
const useHistorySliceMock = jest
|
|
189
|
+
.spyOn(components, 'useHistorySlice')
|
|
190
|
+
.mockReturnValue({historySlice: null, isLoading: false});
|
|
191
|
+
|
|
192
|
+
beforeEach(() => {
|
|
193
|
+
initialState = {
|
|
194
|
+
tenant: {
|
|
195
|
+
id: 'tenant'
|
|
196
|
+
},
|
|
197
|
+
profile: {
|
|
198
|
+
entity: {
|
|
199
|
+
uri: 'entities/1',
|
|
200
|
+
type: 'configuration/entityTypes/HCP',
|
|
201
|
+
attributes: {
|
|
202
|
+
CountryCode: [
|
|
203
|
+
{
|
|
204
|
+
uri: 'entities/1/attributes/CountryCode/1',
|
|
205
|
+
type: 'configuration/entityTypes/HCP/attributes/CountryCode',
|
|
206
|
+
value: 'Italy',
|
|
207
|
+
lookupCode: 'IT'
|
|
208
|
+
}
|
|
209
|
+
]
|
|
210
|
+
},
|
|
211
|
+
crosswalks: [
|
|
212
|
+
{
|
|
213
|
+
uri: 'entities/j8K1vc9/crosswalks/12jf9nL05',
|
|
214
|
+
type: 'configuration/sources/Reltio',
|
|
215
|
+
value: 'nQpZyQt',
|
|
216
|
+
reltioLoadDate: '2021-06-11T08:24:31.726Z',
|
|
217
|
+
createDate: '2018-11-19T12:14:00.735Z',
|
|
218
|
+
updateDate: '2018-11-19T12:14:00.735Z',
|
|
219
|
+
attributes: [
|
|
220
|
+
'entities/j8K1vc9/attributes/CountryCode/12jf9nc37',
|
|
221
|
+
'entities/j8K1vc9/attributes/Name/1dl1LhLwS'
|
|
222
|
+
],
|
|
223
|
+
singleAttributeUpdateDates: {
|
|
224
|
+
'entities/j8K1vc9/attributes/Name/1dl1LhLwS': '2018-11-29T05:39:56.445Z'
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
uri: 'entities/j8K1vc9/crosswalks/1CwTinUzm',
|
|
229
|
+
type: 'configuration/sources/AHA',
|
|
230
|
+
value: 'AHA_LEV',
|
|
231
|
+
reltioLoadDate: '2021-06-09T11:32:16.434Z',
|
|
232
|
+
sourcePublishDate: '1970-01-01T00:00:00.000Z',
|
|
233
|
+
createDate: '2018-11-28T13:16:18.540Z',
|
|
234
|
+
updateDate: '2018-11-28T13:16:18.540Z',
|
|
235
|
+
attributes: [
|
|
236
|
+
'entities/j8K1vc9/attributes/Address/ZxOfYYo',
|
|
237
|
+
'entities/j8K1vc9/attributes/Name/1CwTindWI'
|
|
238
|
+
],
|
|
239
|
+
singleAttributeUpdateDates: {
|
|
240
|
+
'entities/j8K1vc9/attributes/Name/1CwTindWI': '2021-06-09T11:32:16.434Z'
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
]
|
|
244
|
+
},
|
|
245
|
+
history: {
|
|
246
|
+
event: {
|
|
247
|
+
aStamp: 1637128261696
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
metadata: {
|
|
252
|
+
tenant: {
|
|
253
|
+
entityTypes: [
|
|
254
|
+
{
|
|
255
|
+
uri: 'configuration/entityTypes/HCP',
|
|
256
|
+
label: 'HCP',
|
|
257
|
+
attributes: [
|
|
258
|
+
{
|
|
259
|
+
label: 'Country Code',
|
|
260
|
+
name: 'CountryCode',
|
|
261
|
+
type: 'String',
|
|
262
|
+
uri: 'configuration/entityTypes/HCP/attributes/CountryCode'
|
|
263
|
+
}
|
|
264
|
+
]
|
|
265
|
+
}
|
|
266
|
+
]
|
|
267
|
+
}
|
|
268
|
+
},
|
|
269
|
+
ui: {
|
|
270
|
+
config: {}
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
beforeAll(() => {
|
|
276
|
+
useCrosswalkTreeMock.mockReturnValue({
|
|
277
|
+
crosswalkTree: {
|
|
278
|
+
crosswalks: [],
|
|
279
|
+
uri: 'test'
|
|
280
|
+
},
|
|
281
|
+
reload: onReloadCrosswalkTree
|
|
282
|
+
});
|
|
283
|
+
jest.spyOn(RightSidePanelImport, 'RightSidePanel').mockImplementation(EmptyStub);
|
|
284
|
+
useHistoryMock.mockReturnValue(useHistoryResult);
|
|
285
|
+
jest.spyOn(useEntityWithSurvivorshipGroupsImport, 'useEntityWithSurvivorshipGroups').mockImplementation(
|
|
286
|
+
(entity) => ({
|
|
287
|
+
survivorshipGroups: [{uri: 'uri1', mapping: [], label: 'label'}],
|
|
288
|
+
currentSurvivorshipGroupUri: 'uri1',
|
|
289
|
+
onChangeSurvivorshipGroup,
|
|
290
|
+
entity,
|
|
291
|
+
isDefaultSurvivorshipGroupUri: true,
|
|
292
|
+
isLoading: false
|
|
293
|
+
})
|
|
294
|
+
);
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
it('should render correctly', () => {
|
|
298
|
+
const store = createTestStore();
|
|
299
|
+
const settingsContext = {settings: {source: {active: 0, width: 480}}, onChange: () => {}};
|
|
300
|
+
const wrapper = mount(
|
|
301
|
+
<Provider store={store}>
|
|
302
|
+
<PerspectivesSettingsContext.Provider value={settingsContext}>
|
|
303
|
+
<SourcesView {...props} />
|
|
304
|
+
</PerspectivesSettingsContext.Provider>
|
|
305
|
+
</Provider>
|
|
306
|
+
);
|
|
307
|
+
expect(wrapper.find(ResizablePanes).prop('size')).toBe(480);
|
|
308
|
+
expect(useCrosswalksDisplayMock).toBeCalledWith({
|
|
309
|
+
activeMode: 'crosswalks',
|
|
310
|
+
contributors: [crosswalkTree],
|
|
311
|
+
entity: initialState.profile.entity
|
|
312
|
+
});
|
|
313
|
+
expect(useModifiedEntityMock).toBeCalledWith(
|
|
314
|
+
expect.objectContaining({
|
|
315
|
+
entity: initialState.profile.entity
|
|
316
|
+
})
|
|
317
|
+
);
|
|
318
|
+
expect(useSnackbarMock).toBeCalledWith({
|
|
319
|
+
anchorOrigin: {vertical: 'top', horizontal: 'center'},
|
|
320
|
+
showDismiss: true
|
|
321
|
+
});
|
|
322
|
+
expect(useCrosswalkTreeMock).toBeCalledWith({
|
|
323
|
+
entityUri: initialState.profile.entity.uri,
|
|
324
|
+
onSuccess: expect.any(Function)
|
|
325
|
+
});
|
|
326
|
+
expect(wrapper.find(ExpandedAttributesProvider).prop('attributeUris')).toBe(newlyCreatedAttributes);
|
|
327
|
+
const attributeTable = wrapper.find(ExpandedAttributesProvider).find(AttributesTable);
|
|
328
|
+
expect(attributeTable.prop('entity')).toBe(modifiedEntity);
|
|
329
|
+
expect(attributeTable.prop('crosswalksMap')).toBe(crosswalksMap);
|
|
330
|
+
expect(attributeTable.prop('onDelete')).toBe(attributeActions.onDeleteAttribute);
|
|
331
|
+
expect(attributeTable.prop('onPin')).toBe(attributeActions.onPinAttribute);
|
|
332
|
+
expect(attributeTable.prop('onIgnore')).toBe(attributeActions.onIgnoreAttribute);
|
|
333
|
+
expect(attributeTable.prop('onEdit')).toBe(attributeActions.onEditAttribute);
|
|
334
|
+
expect(attributeTable.prop('onAdd')).toBe(attributeActions.onAddAttribute);
|
|
335
|
+
expect(attributeTable.prop('isLoading')).toBe(false);
|
|
336
|
+
|
|
337
|
+
const additionalHeaderItems = new ReactWrapper(attributeTable.prop('additionalHeaderItems') as any);
|
|
338
|
+
expect(additionalHeaderItems.find(RulesetsSelector).props()).toEqual({
|
|
339
|
+
survivorshipGroups: [{uri: 'uri1', mapping: [], label: 'label'}],
|
|
340
|
+
currentSurvivorshipGroupUri: 'uri1',
|
|
341
|
+
onChange: onChangeSurvivorshipGroup
|
|
342
|
+
});
|
|
343
|
+
expect(additionalHeaderItems.find(Divider)).toHaveLength(1);
|
|
344
|
+
|
|
345
|
+
const profileBand = wrapper.find(ScreenProfileBand);
|
|
346
|
+
expect(profileBand.prop('entity')).toBe(initialState.profile.entity);
|
|
347
|
+
expect(profileBand.prop('historySlice')).toBe(null);
|
|
348
|
+
|
|
349
|
+
expect(wrapper.find(SideButtonsPanel).prop('activeIndexId')).toBe(0);
|
|
350
|
+
|
|
351
|
+
expect(wrapper.find(CrosswalkDragLayer)).toHaveLength(1);
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
it('should pass correct isLoading prop to AttributesTable', () => {
|
|
355
|
+
jest.spyOn(useEntityWithSurvivorshipGroupsImport, 'useEntityWithSurvivorshipGroups').mockImplementation(
|
|
356
|
+
(entity) => ({
|
|
357
|
+
survivorshipGroups: [],
|
|
358
|
+
currentSurvivorshipGroupUri: null,
|
|
359
|
+
onChangeSurvivorshipGroup,
|
|
360
|
+
entity,
|
|
361
|
+
isDefaultSurvivorshipGroupUri: false,
|
|
362
|
+
isLoading: true
|
|
363
|
+
})
|
|
364
|
+
);
|
|
365
|
+
|
|
366
|
+
const store = createTestStore();
|
|
367
|
+
const wrapper = mount(
|
|
368
|
+
<Provider store={store}>
|
|
369
|
+
<SourcesView {...props} />
|
|
370
|
+
</Provider>
|
|
371
|
+
);
|
|
372
|
+
|
|
373
|
+
const attributeTable = wrapper.find(ExpandedAttributesProvider).find(AttributesTable);
|
|
374
|
+
expect(attributeTable.prop('isLoading')).toBe(true);
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
it('should pass readOnly prop equals true to AttributesTable if current survivorshipGroup is not default', () => {
|
|
378
|
+
jest.spyOn(useEntityWithSurvivorshipGroupsImport, 'useEntityWithSurvivorshipGroups').mockImplementation(
|
|
379
|
+
(entity) => ({
|
|
380
|
+
survivorshipGroups: [],
|
|
381
|
+
currentSurvivorshipGroupUri: null,
|
|
382
|
+
onChangeSurvivorshipGroup,
|
|
383
|
+
entity,
|
|
384
|
+
isDefaultSurvivorshipGroupUri: false,
|
|
385
|
+
isLoading: false
|
|
386
|
+
})
|
|
387
|
+
);
|
|
388
|
+
|
|
389
|
+
const store = createTestStore();
|
|
390
|
+
const wrapper = mount(
|
|
391
|
+
<Provider store={store}>
|
|
392
|
+
<SourcesView {...props} />
|
|
393
|
+
</Provider>
|
|
394
|
+
);
|
|
395
|
+
|
|
396
|
+
const attributeTable = wrapper.find(ExpandedAttributesProvider).find(AttributesTable);
|
|
397
|
+
expect(attributeTable.prop('readOnly')).toBe(true);
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
describe('Legend tab', () => {
|
|
401
|
+
it('should render LegendView in side panel and close it on tab click', async () => {
|
|
402
|
+
const store = createTestStore();
|
|
403
|
+
let wrapper;
|
|
404
|
+
const settingsContext = {settings: {source: {active: 0, width: 480}}, onChange: () => {}};
|
|
405
|
+
await act(async () => {
|
|
406
|
+
wrapper = mount(
|
|
407
|
+
<Provider store={store}>
|
|
408
|
+
<PerspectivesSettingsContext.Provider value={settingsContext}>
|
|
409
|
+
<SourcesView {...props} />
|
|
410
|
+
</PerspectivesSettingsContext.Provider>
|
|
411
|
+
</Provider>
|
|
412
|
+
);
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
const rightSidePanel = wrapper.find(RightSidePanel);
|
|
416
|
+
const titleBlock = shallow(<div>{rightSidePanel.prop('tabs')[0].title}</div>);
|
|
417
|
+
expect(titleBlock.find(Typography).text()).toBe('Legend');
|
|
418
|
+
const legendBlock = shallow(<div>{rightSidePanel.prop('tabs')[0].content}</div>).find(LegendView);
|
|
419
|
+
expect(legendBlock.props()).toMatchObject({
|
|
420
|
+
entity: initialState.profile.entity,
|
|
421
|
+
activeMode: 'crosswalks',
|
|
422
|
+
crosswalkTree,
|
|
423
|
+
contributors: [{uri: 'test', crosswalks: []}],
|
|
424
|
+
selectedAttributeTypes: undefined,
|
|
425
|
+
onAddCrosswalk: crosswalkTreeActions.addCrosswalk,
|
|
426
|
+
onUnmergeContributor: crosswalkTreeActions.unmergeContributor,
|
|
427
|
+
onUnsubscribeContributor: crosswalkTreeActions.unsubscribeContributor,
|
|
428
|
+
onEditCrosswalk: crosswalkTreeActions.editCrosswalk,
|
|
429
|
+
onDeleteCrosswalk: crosswalkTreeActions.deleteCrosswalk
|
|
430
|
+
});
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
it('should change legend mode correctly', () => {
|
|
434
|
+
const store = createTestStore();
|
|
435
|
+
const settingsContext = {settings: {source: {active: 0, width: 480}}, onChange: () => {}};
|
|
436
|
+
const wrapper = mount(
|
|
437
|
+
<Provider store={store}>
|
|
438
|
+
<PerspectivesSettingsContext.Provider value={settingsContext}>
|
|
439
|
+
<SourcesView {...props} />
|
|
440
|
+
</PerspectivesSettingsContext.Provider>
|
|
441
|
+
</Provider>
|
|
442
|
+
);
|
|
443
|
+
|
|
444
|
+
const rightSidePanel = wrapper.find(RightSidePanel);
|
|
445
|
+
const legendBlock = shallow(<div>{rightSidePanel.prop('tabs')[0].content}</div>).find(LegendView);
|
|
446
|
+
act(() => {
|
|
447
|
+
legendBlock.prop('onChangeMode')(LegendMode.Source);
|
|
448
|
+
});
|
|
449
|
+
wrapper.update();
|
|
450
|
+
|
|
451
|
+
const newRightSidePanel = wrapper.find(RightSidePanel);
|
|
452
|
+
const newLegendBlock = shallow(<div>{newRightSidePanel.prop('tabs')[0].content}</div>).find(LegendView);
|
|
453
|
+
expect(newLegendBlock.prop('activeMode')).toBe(LegendMode.Source);
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
it('should apply selected attributes from table to legend view', () => {
|
|
457
|
+
const store = createTestStore();
|
|
458
|
+
const settingsContext = {settings: {source: {active: 0, width: 480}}, onChange: () => {}};
|
|
459
|
+
const wrapper = mount(
|
|
460
|
+
<Provider store={store}>
|
|
461
|
+
<PerspectivesSettingsContext.Provider value={settingsContext}>
|
|
462
|
+
<SourcesView {...props} />
|
|
463
|
+
</PerspectivesSettingsContext.Provider>
|
|
464
|
+
</Provider>
|
|
465
|
+
);
|
|
466
|
+
|
|
467
|
+
const selectedAttributeTypes = [
|
|
468
|
+
{
|
|
469
|
+
label: 'Country Code',
|
|
470
|
+
name: 'CountryCode',
|
|
471
|
+
type: 'String',
|
|
472
|
+
uri: 'configuration/entityTypes/HCP/attributes/CountryCode'
|
|
473
|
+
}
|
|
474
|
+
];
|
|
475
|
+
act(() => {
|
|
476
|
+
wrapper.find(AttributesTable).prop('onSelectAttributeTypes')(selectedAttributeTypes);
|
|
477
|
+
});
|
|
478
|
+
wrapper.update();
|
|
479
|
+
|
|
480
|
+
const rightSidePanel = wrapper.find(RightSidePanel);
|
|
481
|
+
const titleBlock = shallow(<div>{rightSidePanel.prop('tabs')[0].title}</div>);
|
|
482
|
+
expect(titleBlock.find(Typography).text()).toBe('Legend');
|
|
483
|
+
const legendBlock = shallow(<div>{rightSidePanel.prop('tabs')[0].content}</div>).find(LegendView);
|
|
484
|
+
expect(legendBlock.prop('selectedAttributeTypes')).toBe(selectedAttributeTypes);
|
|
485
|
+
});
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
it('should provide correct visibleColumns to AttributeTable and change it', async () => {
|
|
489
|
+
const store = createTestStore();
|
|
490
|
+
const wrapper = mount(
|
|
491
|
+
<Provider store={store}>
|
|
492
|
+
<SourcesView {...props} />
|
|
493
|
+
</Provider>
|
|
494
|
+
);
|
|
495
|
+
await act(async () => {
|
|
496
|
+
resolveSavedState({visibleColumns: ['name1', 'name2']});
|
|
497
|
+
});
|
|
498
|
+
wrapper.update();
|
|
499
|
+
|
|
500
|
+
const attributeTable = wrapper.find(AttributesTable);
|
|
501
|
+
expect(attributeTable.prop('visibleColumns')).toEqual(['name1', 'name2']);
|
|
502
|
+
|
|
503
|
+
act(() => {
|
|
504
|
+
attributeTable.prop('onChangeVisibleColumns')(['name3']);
|
|
505
|
+
});
|
|
506
|
+
wrapper.update();
|
|
507
|
+
expect(wrapper.find(AttributesTable).prop('visibleColumns')).toEqual(['name3']);
|
|
508
|
+
expect(saveState).toHaveBeenCalledWith({visibleColumns: ['name3']});
|
|
509
|
+
});
|
|
510
|
+
|
|
511
|
+
it('should refresh entity and reload crosswalk tree on successful attribute action', () => {
|
|
512
|
+
const store = createTestStore();
|
|
513
|
+
mount(
|
|
514
|
+
<Provider store={store}>
|
|
515
|
+
<SourcesView {...props} />
|
|
516
|
+
</Provider>
|
|
517
|
+
);
|
|
518
|
+
const {onModify} = useModifiedEntityMock.mock.calls[0][0];
|
|
519
|
+
onModify();
|
|
520
|
+
expect(dispatch).toBeCalledWith(
|
|
521
|
+
profile.entity.actions.loadEntity({
|
|
522
|
+
viewId: 'SourcesViewId',
|
|
523
|
+
uri: 'entities/1'
|
|
524
|
+
})
|
|
525
|
+
);
|
|
526
|
+
expect(onReloadCrosswalkTree).toHaveBeenCalled();
|
|
527
|
+
});
|
|
528
|
+
|
|
529
|
+
it('should show error on entity attribute action error', () => {
|
|
530
|
+
const store = createTestStore();
|
|
531
|
+
mount(
|
|
532
|
+
<Provider store={store}>
|
|
533
|
+
<SourcesView {...props} />
|
|
534
|
+
</Provider>
|
|
535
|
+
);
|
|
536
|
+
const {onError} = useModifiedEntityMock.mock.calls[0][0];
|
|
537
|
+
onError({errorMessage: 'Some error'});
|
|
538
|
+
expect(showErrorMock).toBeCalledWith({
|
|
539
|
+
title: 'Error',
|
|
540
|
+
message: 'Some error'
|
|
541
|
+
});
|
|
542
|
+
});
|
|
543
|
+
|
|
544
|
+
it('should refresh entity and reload crosswalk tree on successful crosswalk tree action', () => {
|
|
545
|
+
const store = createTestStore();
|
|
546
|
+
mount(
|
|
547
|
+
<Provider store={store}>
|
|
548
|
+
<SourcesView {...props} />
|
|
549
|
+
</Provider>
|
|
550
|
+
);
|
|
551
|
+
const {onSuccess} = useCrosswalkTreeActionsMock.mock.calls[0][0];
|
|
552
|
+
onSuccess();
|
|
553
|
+
expect(dispatch).toBeCalledWith(
|
|
554
|
+
profile.entity.actions.loadEntity({
|
|
555
|
+
viewId: 'SourcesViewId',
|
|
556
|
+
uri: 'entities/1'
|
|
557
|
+
})
|
|
558
|
+
);
|
|
559
|
+
expect(onReloadCrosswalkTree).toHaveBeenCalled();
|
|
560
|
+
});
|
|
561
|
+
|
|
562
|
+
it('should show correct snackbar when onShowMessage prop of useCrosswalkTreeActions calls', () => {
|
|
563
|
+
const store = createTestStore();
|
|
564
|
+
const options = {
|
|
565
|
+
message: 'some message',
|
|
566
|
+
entity: {
|
|
567
|
+
uri: 'entities/123',
|
|
568
|
+
type: 'configuration/entityTypes/HCP',
|
|
569
|
+
label: 'Entity label'
|
|
570
|
+
}
|
|
571
|
+
};
|
|
572
|
+
mount(
|
|
573
|
+
<Provider store={store}>
|
|
574
|
+
<SourcesView {...props} />
|
|
575
|
+
</Provider>
|
|
576
|
+
);
|
|
577
|
+
const {onShowMessage} = useCrosswalkTreeActionsMock.mock.calls[0][0];
|
|
578
|
+
onShowMessage(options.message, options.entity);
|
|
579
|
+
expect(showSnackbarMessageMock).toBeCalledWith(
|
|
580
|
+
<TreeActionSnackbar message={options.message} entity={options.entity} />
|
|
581
|
+
);
|
|
582
|
+
|
|
583
|
+
onShowMessage(options.message);
|
|
584
|
+
expect(showSnackbarMessageMock).toBeCalledWith(options.message);
|
|
585
|
+
});
|
|
586
|
+
|
|
587
|
+
it('should show error on crosswalk tree action error', () => {
|
|
588
|
+
const store = createTestStore();
|
|
589
|
+
mount(
|
|
590
|
+
<Provider store={store}>
|
|
591
|
+
<SourcesView {...props} />
|
|
592
|
+
</Provider>
|
|
593
|
+
);
|
|
594
|
+
const {onError} = useCrosswalkTreeActionsMock.mock.calls[0][0];
|
|
595
|
+
onError({errorMessage: 'Some error'});
|
|
596
|
+
expect(showErrorMock).toBeCalledWith({
|
|
597
|
+
title: 'Error',
|
|
598
|
+
message: 'Some error'
|
|
599
|
+
});
|
|
600
|
+
});
|
|
601
|
+
|
|
602
|
+
it('should show error and reload data on crosswalk not found error', () => {
|
|
603
|
+
const store = createTestStore();
|
|
604
|
+
mount(
|
|
605
|
+
<Provider store={store}>
|
|
606
|
+
<SourcesView {...props} />
|
|
607
|
+
</Provider>
|
|
608
|
+
);
|
|
609
|
+
const {onError} = useCrosswalkTreeActionsMock.mock.calls[0][0];
|
|
610
|
+
onError({errorMessage: 'Crosswalk not found', errorCode: 102});
|
|
611
|
+
expect(showErrorMock).toBeCalledWith({
|
|
612
|
+
title: 'Error',
|
|
613
|
+
message: 'Crosswalk not found'
|
|
614
|
+
});
|
|
615
|
+
expect(dispatch).toBeCalledWith(
|
|
616
|
+
profile.entity.actions.loadEntity({
|
|
617
|
+
viewId: 'SourcesViewId',
|
|
618
|
+
uri: 'entities/1'
|
|
619
|
+
})
|
|
620
|
+
);
|
|
621
|
+
expect(onReloadCrosswalkTree).toHaveBeenCalled();
|
|
622
|
+
});
|
|
623
|
+
|
|
624
|
+
it('should render correctly for data tenant entity', () => {
|
|
625
|
+
isDataTenantEntityMock.mockReturnValueOnce(true);
|
|
626
|
+
const store = createTestStore();
|
|
627
|
+
const settingsContext = {settings: {source: {active: 0, width: 480}}, onChange: () => {}};
|
|
628
|
+
const wrapper = mount(
|
|
629
|
+
<Provider store={store}>
|
|
630
|
+
<PerspectivesSettingsContext.Provider value={settingsContext}>
|
|
631
|
+
<SourcesView {...props} />
|
|
632
|
+
</PerspectivesSettingsContext.Provider>
|
|
633
|
+
</Provider>
|
|
634
|
+
);
|
|
635
|
+
expect(useCrosswalkTreeImport.useCrosswalkTree).toBeCalledWith({
|
|
636
|
+
entityUri: undefined,
|
|
637
|
+
onSuccess: expect.any(Function)
|
|
638
|
+
});
|
|
639
|
+
expect(wrapper.find(AttributesTable)).toHaveLength(0);
|
|
640
|
+
expect(wrapper.find(EmptyState)).toHaveLength(1);
|
|
641
|
+
|
|
642
|
+
isDataTenantEntityMock.mockReturnValueOnce(true);
|
|
643
|
+
|
|
644
|
+
const rightSidePanel = wrapper.find(RightSidePanel);
|
|
645
|
+
|
|
646
|
+
const legendBlock = shallow(<div>{rightSidePanel.prop('tabs')[0].content}</div>).find(LegendView);
|
|
647
|
+
expect(legendBlock.prop('entity')).toBeNull();
|
|
648
|
+
});
|
|
649
|
+
|
|
650
|
+
describe('History tab', () => {
|
|
651
|
+
it('should render History tab', () => {
|
|
652
|
+
const store = createTestStore();
|
|
653
|
+
const wrapper = mount(
|
|
654
|
+
<Provider store={store}>
|
|
655
|
+
<SourcesView {...props} config={{id: 'SourcesViewId'}} />
|
|
656
|
+
</Provider>
|
|
657
|
+
);
|
|
658
|
+
const sideButtonsPanelButtons = wrapper.find(SideButtonsPanel).prop('buttonsProps');
|
|
659
|
+
expect(sideButtonsPanelButtons.length).toBe(2);
|
|
660
|
+
expect(sideButtonsPanelButtons[0].tooltipTitle).toBe('Legend');
|
|
661
|
+
expect(sideButtonsPanelButtons[1].tooltipTitle).toBe('History');
|
|
662
|
+
});
|
|
663
|
+
|
|
664
|
+
it('should render HistoryView in side panel if click on History tab', () => {
|
|
665
|
+
const store = createTestStore();
|
|
666
|
+
const settingsContext = {settings: {source: {active: 1, width: 480}}, onChange: () => {}};
|
|
667
|
+
const wrapper = mount(
|
|
668
|
+
<Provider store={store}>
|
|
669
|
+
<PerspectivesSettingsContext.Provider value={settingsContext}>
|
|
670
|
+
<SourcesView {...props} config={{id: 'SourcesViewId'}} />
|
|
671
|
+
</PerspectivesSettingsContext.Provider>
|
|
672
|
+
</Provider>
|
|
673
|
+
);
|
|
674
|
+
|
|
675
|
+
const rightSidePanel = wrapper.find(RightSidePanel);
|
|
676
|
+
const titleBlock = shallow(<div>{rightSidePanel.prop('tabs')[1].title}</div>);
|
|
677
|
+
expect(titleBlock.find(HistoryHeader)).toHaveLength(1);
|
|
678
|
+
expect(titleBlock.find(HistoryHeader).props()).toMatchObject({
|
|
679
|
+
total: historicUris.length + 1,
|
|
680
|
+
entityType: initialState.metadata.tenant.entityTypes[0],
|
|
681
|
+
filter: useHistoryResult.historyFilter
|
|
682
|
+
});
|
|
683
|
+
|
|
684
|
+
const historyBlock = shallow(<div>{rightSidePanel.prop('tabs')[1].content}</div>).find(HistoryView);
|
|
685
|
+
expect(historyBlock).toHaveLength(1);
|
|
686
|
+
expect(historyBlock.props()).toMatchObject({
|
|
687
|
+
isLoading: useHistoryResult.isLoading,
|
|
688
|
+
historyWithTotal: useHistoryResult.historyWithTotal,
|
|
689
|
+
entityUri: initialState.profile.entity.uri,
|
|
690
|
+
historyEvent: initialState.profile.history.event,
|
|
691
|
+
contributorsUris: useHistoryResult.historicUris,
|
|
692
|
+
onLoadMore: useHistoryResult.onLoadMore,
|
|
693
|
+
canLoadMore: useHistoryResult.canLoadMore
|
|
694
|
+
});
|
|
695
|
+
});
|
|
696
|
+
|
|
697
|
+
it('should render HistoryPanelEmptyState in side panel for data tenant entity', () => {
|
|
698
|
+
const store = createTestStore();
|
|
699
|
+
isDataTenantEntityMock.mockReturnValue(true);
|
|
700
|
+
const settingsContext = {settings: {source: {active: 1, width: 480}}, onChange: () => {}};
|
|
701
|
+
const wrapper = mount(
|
|
702
|
+
<Provider store={store}>
|
|
703
|
+
<PerspectivesSettingsContext.Provider value={settingsContext}>
|
|
704
|
+
<SourcesView {...props} config={{id: 'SourcesViewId'}} />
|
|
705
|
+
</PerspectivesSettingsContext.Provider>
|
|
706
|
+
</Provider>
|
|
707
|
+
);
|
|
708
|
+
expect(useHistoryMock).toBeCalledWith({entity: null, enabled: false});
|
|
709
|
+
|
|
710
|
+
const rightSidePanel = wrapper.find(RightSidePanel);
|
|
711
|
+
const titleBlock = shallow(<div>{rightSidePanel.prop('tabs')[1].title}</div>);
|
|
712
|
+
expect(titleBlock.find(HistoryHeader)).toHaveLength(1);
|
|
713
|
+
const historyBlock = shallow(<div>{rightSidePanel.prop('tabs')[1].content}</div>);
|
|
714
|
+
expect(historyBlock.find(HistoryView).length).toBe(0);
|
|
715
|
+
expect(historyBlock.find(HistoryPanelEmptyState).length).toBe(1);
|
|
716
|
+
isDataTenantEntityMock.mockReset();
|
|
717
|
+
});
|
|
718
|
+
|
|
719
|
+
it('should render HistoryPanelEmptyState in side panel for temp entity', () => {
|
|
720
|
+
const store = createTestStore({
|
|
721
|
+
profile: {
|
|
722
|
+
entity: {
|
|
723
|
+
uri: 'entities/uri$$1644994321193',
|
|
724
|
+
type: 'configuration/entityTypes/HCP',
|
|
725
|
+
attributes: {},
|
|
726
|
+
crosswalks: []
|
|
727
|
+
},
|
|
728
|
+
history: {
|
|
729
|
+
event: {
|
|
730
|
+
aStamp: 1637128261696
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
});
|
|
735
|
+
const settingsContext = {settings: {source: {active: 1, width: 480}}, onChange: () => {}};
|
|
736
|
+
const wrapper = mount(
|
|
737
|
+
<Provider store={store}>
|
|
738
|
+
<PerspectivesSettingsContext.Provider value={settingsContext}>
|
|
739
|
+
<SourcesView {...props} config={{id: 'SourcesViewId'}} />
|
|
740
|
+
</PerspectivesSettingsContext.Provider>
|
|
741
|
+
</Provider>
|
|
742
|
+
);
|
|
743
|
+
expect(useHistoryMock).toBeCalledWith({entity: null, enabled: false});
|
|
744
|
+
|
|
745
|
+
act(() => {
|
|
746
|
+
wrapper.find(SideButtonsPanel).prop('onButtonClick')(1);
|
|
747
|
+
});
|
|
748
|
+
wrapper.update();
|
|
749
|
+
|
|
750
|
+
const rightSidePanel = wrapper.find(RightSidePanel);
|
|
751
|
+
const titleBlock = shallow(<div>{rightSidePanel.prop('tabs')[1].title}</div>);
|
|
752
|
+
expect(titleBlock.find(HistoryHeader)).toHaveLength(1);
|
|
753
|
+
const historyBlock = shallow(<div>{rightSidePanel.prop('tabs')[1].content}</div>);
|
|
754
|
+
expect(historyBlock.find(HistoryView).length).toBe(0);
|
|
755
|
+
expect(historyBlock.find(HistoryPanelEmptyState).length).toBe(1);
|
|
756
|
+
});
|
|
757
|
+
|
|
758
|
+
it('should set history filter in useHistory hook when call onApplyFilter of HistoryHeader', () => {
|
|
759
|
+
const store = createTestStore();
|
|
760
|
+
const settingsContext = {settings: {source: {active: 1, width: 480}}, onChange: () => {}};
|
|
761
|
+
const wrapper = mount(
|
|
762
|
+
<Provider store={store}>
|
|
763
|
+
<PerspectivesSettingsContext.Provider value={settingsContext}>
|
|
764
|
+
<SourcesView {...props} config={{id: 'SourcesViewId'}} />
|
|
765
|
+
</PerspectivesSettingsContext.Provider>
|
|
766
|
+
</Provider>
|
|
767
|
+
);
|
|
768
|
+
|
|
769
|
+
const rightSidePanel = wrapper.find(RightSidePanel);
|
|
770
|
+
const titleBlock = shallow(<div>{rightSidePanel.prop('tabs')[1].title}</div>);
|
|
771
|
+
expect(titleBlock.find(HistoryHeader).prop('filter')).toBe(useHistoryResult.historyFilter);
|
|
772
|
+
const newFilter: HistoryFilter = {
|
|
773
|
+
dateRange: {
|
|
774
|
+
type: DateRangeTypes.AGO,
|
|
775
|
+
period: [4, 'month']
|
|
776
|
+
},
|
|
777
|
+
users: ['username1', 'username3'],
|
|
778
|
+
activities: [HistoryActivityType.UPDATE, HistoryActivityType.UNMERGE],
|
|
779
|
+
attributes: []
|
|
780
|
+
};
|
|
781
|
+
|
|
782
|
+
act(() => {
|
|
783
|
+
titleBlock.find(HistoryHeader).prop('onApplyFilter')(newFilter);
|
|
784
|
+
});
|
|
785
|
+
wrapper.update();
|
|
786
|
+
expect(onApplyFilterMock).toBeCalledWith(newFilter);
|
|
787
|
+
});
|
|
788
|
+
});
|
|
789
|
+
|
|
790
|
+
it('should render correctly if history slice is opened', () => {
|
|
791
|
+
const historySlice = {
|
|
792
|
+
aEntity: {
|
|
793
|
+
uri: 'entities/sliceA',
|
|
794
|
+
type: 'configuration/entityTypes/HCP',
|
|
795
|
+
attributes: {}
|
|
796
|
+
},
|
|
797
|
+
bEntity: {
|
|
798
|
+
uri: 'entities/sliceB',
|
|
799
|
+
type: 'configuration/entityTypes/HCP',
|
|
800
|
+
attributes: {}
|
|
801
|
+
}
|
|
802
|
+
};
|
|
803
|
+
useHistorySliceMock.mockReturnValue({isLoading: false, historySlice});
|
|
804
|
+
const store = createTestStore();
|
|
805
|
+
const settingsContext = {settings: {source: {active: 0, width: 480}}, onChange: () => {}};
|
|
806
|
+
const wrapper = mount(
|
|
807
|
+
<Provider store={store}>
|
|
808
|
+
<PerspectivesSettingsContext.Provider value={settingsContext}>
|
|
809
|
+
<SourcesView {...props} />
|
|
810
|
+
</PerspectivesSettingsContext.Provider>
|
|
811
|
+
</Provider>
|
|
812
|
+
);
|
|
813
|
+
const profileBand = wrapper.find(ScreenProfileBand);
|
|
814
|
+
expect(profileBand.prop('entity')).toBe(initialState.profile.entity);
|
|
815
|
+
expect(profileBand.prop('historySlice')).toBe(historySlice);
|
|
816
|
+
|
|
817
|
+
expect(useModifiedEntityMock).toBeCalledWith(
|
|
818
|
+
expect.objectContaining({
|
|
819
|
+
entity: historySlice.aEntity
|
|
820
|
+
})
|
|
821
|
+
);
|
|
822
|
+
expect(wrapper.find(AttributesTable).prop('readOnly')).toBe(true);
|
|
823
|
+
|
|
824
|
+
expect(useCrosswalkTreeMock).toBeCalledWith({
|
|
825
|
+
entityUri: historySlice.aEntity.uri,
|
|
826
|
+
onSuccess: expect.any(Function)
|
|
827
|
+
});
|
|
828
|
+
const rightSidePanel = wrapper.find(RightSidePanel);
|
|
829
|
+
const legendView = shallow(<div>{rightSidePanel.prop('tabs')[0].content}</div>).find(LegendView);
|
|
830
|
+
expect(legendView.prop('entity')).toBe(historySlice.aEntity);
|
|
831
|
+
expect(legendView.prop('readOnly')).toBe(true);
|
|
832
|
+
useHistorySliceMock.mockClear();
|
|
833
|
+
});
|
|
834
|
+
|
|
835
|
+
it('should pass readOnly prop equals true to if unmerge or unsubscribe request is in process', async () => {
|
|
836
|
+
const getLegendBlock = (wrapper: ReactWrapper) => {
|
|
837
|
+
const rightSidePanel = wrapper.find(RightSidePanel);
|
|
838
|
+
return shallow(<div>{rightSidePanel.prop('tabs')[0].content}</div>).find(LegendView);
|
|
839
|
+
};
|
|
840
|
+
useHistorySliceMock.mockReturnValue({isLoading: false, historySlice: null});
|
|
841
|
+
useCrosswalkTreeActionsMock.mockImplementation((params) => {
|
|
842
|
+
const crosswalkTreeActions = {
|
|
843
|
+
addCrosswalk: jest.fn(),
|
|
844
|
+
unmergeContributor: (_event) => {
|
|
845
|
+
params.onLoad();
|
|
846
|
+
params.onSuccess();
|
|
847
|
+
},
|
|
848
|
+
editCrosswalk: jest.fn(),
|
|
849
|
+
deleteCrosswalk: jest.fn(),
|
|
850
|
+
unsubscribeContributor: jest.fn()
|
|
851
|
+
};
|
|
852
|
+
return crosswalkTreeActions;
|
|
853
|
+
});
|
|
854
|
+
|
|
855
|
+
const reloadData = () =>
|
|
856
|
+
new Promise<void>((resolve) => {
|
|
857
|
+
resolve();
|
|
858
|
+
});
|
|
859
|
+
|
|
860
|
+
useCrosswalkTreeMock.mockImplementation((params) => {
|
|
861
|
+
return {
|
|
862
|
+
crosswalkTree: {
|
|
863
|
+
crosswalks: [],
|
|
864
|
+
uri: 'test'
|
|
865
|
+
},
|
|
866
|
+
reload: () => {
|
|
867
|
+
reloadData().finally(() => {
|
|
868
|
+
params.onSuccess();
|
|
869
|
+
});
|
|
870
|
+
}
|
|
871
|
+
};
|
|
872
|
+
});
|
|
873
|
+
|
|
874
|
+
const store = createTestStore();
|
|
875
|
+
const settingsContext = {settings: {source: {active: 0, width: 480}}, onChange: () => {}};
|
|
876
|
+
const wrapper = mount(
|
|
877
|
+
<Provider store={store}>
|
|
878
|
+
<PerspectivesSettingsContext.Provider value={settingsContext}>
|
|
879
|
+
<SourcesView {...props} />
|
|
880
|
+
</PerspectivesSettingsContext.Provider>
|
|
881
|
+
</Provider>
|
|
882
|
+
);
|
|
883
|
+
const legendBlock = getLegendBlock(wrapper);
|
|
884
|
+
expect(legendBlock.prop('readOnly')).toBe(false);
|
|
885
|
+
|
|
886
|
+
legendBlock.prop('onUnmergeContributor')({
|
|
887
|
+
contributorUri: 'contributorUri',
|
|
888
|
+
entityUri: 'entityUri',
|
|
889
|
+
operationType: UnmergeOperation.Unmerge
|
|
890
|
+
});
|
|
891
|
+
|
|
892
|
+
wrapper.setProps({});
|
|
893
|
+
|
|
894
|
+
expect(getLegendBlock(wrapper).prop('readOnly')).toBe(true);
|
|
895
|
+
|
|
896
|
+
await act(async () => {
|
|
897
|
+
reloadData();
|
|
898
|
+
});
|
|
899
|
+
wrapper.setProps({});
|
|
900
|
+
|
|
901
|
+
expect(getLegendBlock(wrapper).prop('readOnly')).toBe(false);
|
|
902
|
+
});
|
|
903
|
+
});
|