@reltio/graph 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.
Files changed (164) hide show
  1. package/index.ts +1 -0
  2. package/package.json +26 -9
  3. package/public/bundle.js +205 -0
  4. package/public/bundle.js.LICENSE.txt +88 -0
  5. package/public/package.json +29 -0
  6. package/scripts/build/index.js +20 -0
  7. package/src/__tests__/GraphView.test.tsx +25 -0
  8. package/src/components/CircleLayout/CircleLayout.tsx +76 -0
  9. package/src/components/CircleLayout/__tests__/CircleLayout.test.tsx +194 -0
  10. package/src/components/GotoButton/GotoButton.tsx +23 -0
  11. package/src/components/GotoButton/__tests__/GotoButton.test.tsx +33 -0
  12. package/src/components/GotoButton/styles.ts +15 -0
  13. package/src/components/GraphArea/GraphArea.tsx +113 -0
  14. package/src/components/GraphArea/__tests__/GraphArea.test.tsx +202 -0
  15. package/src/components/GraphArea/styles.ts +30 -0
  16. package/src/components/GraphLayoutSelector/GraphLayoutSelector.tsx +43 -0
  17. package/src/components/GraphLayoutSelector/__tests__/GraphLayoutSelector.spec.tsx +44 -0
  18. package/src/components/GraphLayoutSelector/styles.ts +15 -0
  19. package/src/components/GraphPerspectiveView/GraphPerspectiveView.tsx +58 -0
  20. package/src/components/GraphPerspectiveView/__tests__/GraphPerspectiveView.test.tsx +115 -0
  21. package/src/components/GraphPerspectiveView/__tests__/useGraphLoader.test.tsx +1519 -0
  22. package/src/components/GraphPerspectiveView/__tests__/useRelationshipTable.test.tsx +1003 -0
  23. package/src/components/GraphPerspectiveView/__tests__/useSelectedEntity.test.tsx +373 -0
  24. package/src/components/GraphPerspectiveView/styles.ts +34 -0
  25. package/src/components/GraphRightSidePanel/GraphRightSidePanel.tsx +27 -0
  26. package/src/components/GraphRightSidePanel/__tests__/GraphRightSidePanel.test.tsx +18 -0
  27. package/src/components/GraphRightSidePanel/icons/relationship-icon.svg +3 -0
  28. package/src/components/GraphRightSidePanel/styles.ts +8 -0
  29. package/src/components/GraphTypeSelector/GraphTypeSelector.tsx +56 -0
  30. package/src/components/GraphTypeSelector/__tests__/GraphTypeSelector.test.tsx +109 -0
  31. package/src/components/GraphTypeSelector/styles.ts +17 -0
  32. package/src/components/HierarchyLayout/HierarchyLayout.ts +102 -0
  33. package/src/components/HierarchyLayout/__tests__/HierarchyLayout.spec.tsx +241 -0
  34. package/src/components/HierarchyLayout/__tests__/buildHierarchy.spec.ts +130 -0
  35. package/src/components/HierarchyLayout/__tests__/calculations.spec.ts +230 -0
  36. package/src/components/HierarchyLayout/buildHierarchy.ts +109 -0
  37. package/src/components/HierarchyLayout/calculations.ts +86 -0
  38. package/src/components/RightPanelEntityDetails/RightPanelEntityDetails.tsx +33 -0
  39. package/src/components/RightPanelEntityDetails/__tests__/RightPanelEntityDetails.test.tsx +39 -0
  40. package/src/components/RightPanelEntityDetails/styles.ts +12 -0
  41. package/src/components/RightPanelProfileBand/RightPanelProfileBand.tsx +33 -0
  42. package/src/components/RightPanelProfileBand/__tests__/RightPanelProfileBand.test.tsx +67 -0
  43. package/src/components/RightPanelProfileBand/styles.ts +8 -0
  44. package/src/components/RightPanelRelationship/RightPanelRelationship.tsx +25 -0
  45. package/src/components/RightPanelRelationship/__tests__/RightPanelRelationship.test.tsx +18 -0
  46. package/src/components/RightPanelRelationship/components/CollapsibleTable/CollapsibleTable.tsx +100 -0
  47. package/src/components/RightPanelRelationship/components/CollapsibleTable/TableHead.tsx +38 -0
  48. package/src/components/RightPanelRelationship/components/CollapsibleTable/__tests__/CollapsibleTable.test.tsx +169 -0
  49. package/src/components/RightPanelRelationship/components/CollapsibleTable/__tests__/TableHead.test.tsx +107 -0
  50. package/src/components/RightPanelRelationship/components/CollapsibleTable/styles.ts +38 -0
  51. package/src/components/RightPanelRelationship/components/CollapsibleTable/types.ts +20 -0
  52. package/src/components/RightPanelRelationship/components/DeleteRelationDialog/DeleteRelationDialog.tsx +34 -0
  53. package/src/components/RightPanelRelationship/components/DeleteRelationDialog/__tests__/DeleteRelationDialog.test.tsx +46 -0
  54. package/src/components/RightPanelRelationship/components/GraphAddRelationDialog/GraphAddRelationButton.tsx +43 -0
  55. package/src/components/RightPanelRelationship/components/GraphAddRelationDialog/GraphAddRelationDialog.tsx +121 -0
  56. package/src/components/RightPanelRelationship/components/GraphAddRelationDialog/__tests__/GraphAddRelationButton.test.tsx +80 -0
  57. package/src/components/RightPanelRelationship/components/GraphAddRelationDialog/__tests__/GraphAddRelationDialog.test.tsx +262 -0
  58. package/src/components/RightPanelRelationship/components/GraphAddRelationDialog/__tests__/mockdata.ts +75 -0
  59. package/src/components/RightPanelRelationship/components/GraphAddRelationDialog/styles.ts +25 -0
  60. package/src/components/RightPanelRelationship/components/GraphAddRelationDialog/useCreatableInOutRelationTypes.ts +13 -0
  61. package/src/components/RightPanelRelationship/components/RelationshipTable/RelationshipTable.tsx +126 -0
  62. package/src/components/RightPanelRelationship/components/RelationshipTable/__tests__/RelationshipTable.test.tsx +176 -0
  63. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/ControlsCellRenderer.tsx +59 -0
  64. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/DefaultCellRenderer.tsx +29 -0
  65. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/ExpandedRowRenderer.tsx +94 -0
  66. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/HeadCellRenderer.tsx +34 -0
  67. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/ProfileCellRenderer.tsx +41 -0
  68. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/__tests__/ControlsCellRenderer.test.tsx +80 -0
  69. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/__tests__/DefaultCellRenderer.test.tsx +47 -0
  70. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/__tests__/ExpandedRowRenderer.test.tsx +166 -0
  71. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/__tests__/HeadCellRenderer.test.tsx +23 -0
  72. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/__tests__/ProfileCellRenderer.test.tsx +47 -0
  73. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/components/DeleteRelationButton.tsx +32 -0
  74. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/components/__tests__/DeleteRelationButton.test.tsx +28 -0
  75. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/styles.ts +113 -0
  76. package/src/components/RightPanelRelationship/components/RelationshipTable/styles.ts +36 -0
  77. package/src/components/RightPanelRelationship/components/RelationshipsFilters/RelationshipsFilters.tsx +41 -0
  78. package/src/components/RightPanelRelationship/components/RelationshipsFilters/RelationshipsFiltersDialog/RelationshipsFiltersDialog.tsx +91 -0
  79. package/src/components/RightPanelRelationship/components/RelationshipsFilters/RelationshipsFiltersDialog/__tests__/RelationshipsFilterDialog.test.tsx +192 -0
  80. package/src/components/RightPanelRelationship/components/RelationshipsFilters/RelationshipsFiltersDialog/styles.ts +34 -0
  81. package/src/components/RightPanelRelationship/components/RelationshipsFilters/RelationshipsSearchTextField/RelationshipsSearchTextField.tsx +31 -0
  82. package/src/components/RightPanelRelationship/components/RelationshipsFilters/RelationshipsSearchTextField/__tests__/RelationshipsSearchTextField.test.tsx +43 -0
  83. package/src/components/RightPanelRelationship/components/RelationshipsFilters/RelationshipsSearchTextField/styles.ts +17 -0
  84. package/src/components/RightPanelRelationship/components/RelationshipsFilters/__tests__/RelationshipsFilters.test.tsx +76 -0
  85. package/src/components/RightPanelRelationship/components/RelationshipsFilters/styles.ts +19 -0
  86. package/src/components/RightPanelRelationship/styles.ts +20 -0
  87. package/src/components/SigmaCustomRenderers/SigmaCustomRenderersContainer.tsx +16 -0
  88. package/src/components/SigmaGraphContainer/SigmaGraphContainer.tsx +55 -0
  89. package/src/components/SigmaGraphContainer/__tests__/SigmaGraphContainer.test.tsx +25 -0
  90. package/src/components/SigmaGraphResizer/SigmaGraphResizer.tsx +13 -0
  91. package/src/components/SigmaGraphResizer/__tests__/SigmaGraphResizer.test.tsx +28 -0
  92. package/src/components/TreeLayout/TreeLayout.tsx +33 -0
  93. package/src/components/TreeLayout/__tests__/TreeLayout.test.tsx +42 -0
  94. package/src/components/TreeLayout/styles.ts +10 -0
  95. package/src/components/ZoomSlider/ZoomSlider.tsx +90 -0
  96. package/src/components/ZoomSlider/__tests__/ZoomSlider.test.tsx +84 -0
  97. package/src/components/ZoomSlider/styles.ts +57 -0
  98. package/src/constants/index.ts +1 -0
  99. package/src/contexts/GraphStateContext.tsx +19 -0
  100. package/src/contexts/SigmaCustomRenderersContext.ts +20 -0
  101. package/src/helpers/relationsHelpers.ts +9 -0
  102. package/src/hooks/__tests__/useGraphLayout.test.tsx +825 -0
  103. package/src/hooks/__tests__/useGraphLayoutSelector.test.tsx +19 -0
  104. package/src/hooks/__tests__/useSelfRelationLoopsRenderer.test.ts +198 -0
  105. package/src/hooks/__tests__/useSigmaCustomRenderers.test.ts +273 -0
  106. package/src/hooks/__tests__/useTooltipRenderer.test.ts +289 -0
  107. package/src/hooks/useGraphLayout.ts +308 -0
  108. package/src/hooks/useGraphLayoutSelector.ts +19 -0
  109. package/src/hooks/useGraphLoader.ts +279 -0
  110. package/src/hooks/useGraphRightSidePanelElements.tsx +36 -0
  111. package/src/hooks/useGraphState.ts +40 -0
  112. package/src/hooks/useGraphType.ts +32 -0
  113. package/src/hooks/useRelationshipTable.ts +212 -0
  114. package/src/hooks/useRelationshipTableFilters.ts +43 -0
  115. package/src/hooks/useSelectedEntity.ts +89 -0
  116. package/src/hooks/useSelfRelationLoopsRenderer.ts +52 -0
  117. package/src/hooks/useSigmaCustomRenderers.ts +112 -0
  118. package/src/hooks/useTooltipRenderer.ts +80 -0
  119. package/src/index.tsx +37 -0
  120. package/src/rendering/canvas/__tests__/hover.spec.ts +31 -0
  121. package/src/rendering/canvas/__tests__/label.spec.ts +64 -0
  122. package/src/rendering/canvas/__tests__/nodeBackground.spec.ts +99 -0
  123. package/src/rendering/canvas/__tests__/selfRelationLoop.spec.ts +88 -0
  124. package/src/rendering/canvas/__tests__/tooltip.spec.ts +33 -0
  125. package/src/rendering/canvas/hover.ts +13 -0
  126. package/src/rendering/canvas/label.ts +33 -0
  127. package/src/rendering/canvas/nodeBackground.ts +61 -0
  128. package/src/rendering/canvas/selfRelationLoop.ts +108 -0
  129. package/src/rendering/canvas/tooltip.ts +38 -0
  130. package/src/rendering/icons/collapseIcon.inline.svg.ts +6 -0
  131. package/src/rendering/icons/expandIcon.inline.svg.ts +5 -0
  132. package/src/rendering/icons/no_photo.inline.svg.ts +13 -0
  133. package/src/rendering/webgl/edge.arrowHead.ts +87 -0
  134. package/src/rendering/webgl/edge.clamped.ts +246 -0
  135. package/src/rendering/webgl/edge.reversedArrowHead.ts +14 -0
  136. package/src/rendering/webgl/helpers/__tests__/imageHelper.spec.ts +36 -0
  137. package/src/rendering/webgl/helpers/imageHelper.ts +13 -0
  138. package/src/rendering/webgl/image.ts +115 -0
  139. package/src/rendering/webgl/node.border.ts +78 -0
  140. package/src/rendering/webgl/node.buttons.ts +241 -0
  141. package/src/rendering/webgl/node.image.ts +169 -0
  142. package/src/rendering/webgl/shaders/edge.clamped.vert.glsl.ts +55 -0
  143. package/src/rendering/webgl/shaders/node.border.frag.glsl.ts +30 -0
  144. package/src/rendering/webgl/shaders/node.border.vert.glsl.ts +37 -0
  145. package/src/rendering/webgl/shaders/node.buttons.frag.glsl.ts +32 -0
  146. package/src/rendering/webgl/shaders/node.buttons.vert.glsl.ts +49 -0
  147. package/src/rendering/webgl/shaders/node.image.frag.glsl.ts +46 -0
  148. package/src/rendering/webgl/shaders/node.image.vert.glsl.ts +42 -0
  149. package/src/types/graphDataTypes.ts +143 -0
  150. package/src/types/sigmaCustomRenderersTypes.ts +13 -0
  151. package/src/utils/__tests__/graph.spec.ts +152 -0
  152. package/src/utils/__tests__/graphLayout.spec.ts +125 -0
  153. package/src/utils/__tests__/hopsData.spec.ts +456 -0
  154. package/src/utils/__tests__/processResponceToGraph.spec.ts +165 -0
  155. package/src/utils/graph.ts +83 -0
  156. package/src/utils/graphLayout.ts +70 -0
  157. package/src/utils/hopsData.ts +198 -0
  158. package/src/utils/processResponseToGraph.ts +32 -0
  159. package/tsconfig.json +4 -0
  160. package/webpack.config.js +10 -0
  161. package/bundle.js +0 -2
  162. package/bundle.js.LICENSE.txt +0 -54
  163. /package/{5271a9e7b6651c852e93.png → public/5271a9e7b6651c852e93.png} +0 -0
  164. /package/{main.css → public/main.css} +0 -0
@@ -0,0 +1,1003 @@
1
+ import React from 'react';
2
+ import {mount, shallow} from 'enzyme';
3
+ import * as reactRedux from 'react-redux';
4
+ import {act} from 'react-dom/test-utils';
5
+ import {times} from 'ramda';
6
+ import {ui} from '@reltio/mdm-module';
7
+ import {Entity, getHops, getRelation, getRequestErrorMessage, Metadata, updateRelation} from '@reltio/mdm-sdk';
8
+ import {GraphStateContext} from '../../../contexts/GraphStateContext';
9
+ import GraphPerspectiveView from '../GraphPerspectiveView';
10
+ import {rerenderWrapper} from '../../../../../../__mocks__/test-utils';
11
+
12
+ jest.mock('../../GraphArea/GraphArea', () => () => null);
13
+ jest.mock('../../GraphRightSidePanel/GraphRightSidePanel', () => ({
14
+ ...(jest.requireActual('../../GraphRightSidePanel/GraphRightSidePanel') as Record<string, unknown>),
15
+ default: () => null
16
+ }));
17
+ jest.mock('../../../contexts/GraphStateContext', () => ({
18
+ GraphStateContext: {
19
+ Provider: jest.fn().mockImplementation(({children}) => <div id="graphStateContextMock">{children}</div>)
20
+ }
21
+ }));
22
+
23
+ jest.mock('@reltio/components', () => ({
24
+ ...jest.requireActual<Record<string, unknown>>('@reltio/components'),
25
+ ScreenProfileBand: () => null
26
+ }));
27
+
28
+ jest.mock('@reltio/mdm-sdk', () => ({
29
+ ...jest.requireActual<Record<string, unknown>>('@reltio/mdm-sdk'),
30
+ removeRelation: jest.fn().mockReturnValue(Promise.resolve({})),
31
+ createRelation: jest.fn().mockReturnValue(Promise.resolve({})),
32
+ getHops: jest.fn().mockReturnValue(Promise.resolve({})),
33
+ getEntity: jest.fn().mockReturnValue(Promise.resolve({})),
34
+ getRelation: jest.fn().mockReturnValue(Promise.resolve({})),
35
+ updateRelation: jest.fn().mockReturnValue(Promise.resolve())
36
+ }));
37
+
38
+ type CreateStoreProps = {
39
+ entity?: Entity;
40
+ metadata?: Metadata;
41
+ };
42
+ const createStore = ({entity, metadata}: CreateStoreProps = {}) => ({
43
+ profile: {
44
+ entity: entity || {
45
+ uri: 'entities/uri1',
46
+ type: 'configuration/entityTypes/HCO'
47
+ }
48
+ },
49
+ tenant: {
50
+ id: 't1'
51
+ },
52
+ metadata: {
53
+ t1: metadata
54
+ }
55
+ });
56
+
57
+ describe('useRelationshipTable behavior', () => {
58
+ const dispatch = jest.fn();
59
+ let store;
60
+
61
+ const setUp = (method: typeof shallow | typeof mount = shallow, customStore?) => {
62
+ store = customStore || createStore();
63
+ return (method as typeof shallow)(<GraphPerspectiveView />);
64
+ };
65
+
66
+ beforeAll(() => {
67
+ jest.spyOn(reactRedux, 'useDispatch').mockReturnValue(dispatch);
68
+ jest.spyOn(reactRedux, 'useSelector').mockImplementation((selector) => selector(store));
69
+ });
70
+
71
+ afterEach(() => {
72
+ jest.clearAllMocks();
73
+ });
74
+
75
+ const entity: Entity = {
76
+ uri: 'entities/main',
77
+ type: 'configuration/entityTypes/Organization',
78
+ label: 'Main Entity'
79
+ };
80
+ const metadata: Metadata = {
81
+ entityTypes: [
82
+ {
83
+ attributes: [],
84
+ uri: 'configuration/entityTypes/Organization',
85
+ label: 'Organization label'
86
+ },
87
+ {
88
+ attributes: [],
89
+ uri: 'configuration/entityTypes/HCO',
90
+ label: 'HCO label'
91
+ }
92
+ ],
93
+ relationTypes: [
94
+ {
95
+ attributes: [],
96
+ uri: 'configuration/relationTypes/Subsidiary',
97
+ label: 'Subsidiary label'
98
+ },
99
+ {
100
+ attributes: [],
101
+ uri: 'configuration/relationTypes/Assistant',
102
+ label: 'Assistant'
103
+ }
104
+ ]
105
+ };
106
+ const entity1 = {
107
+ uri: 'entities/e1',
108
+ type: 'configuration/entityTypes/HCO',
109
+ label: '!Entity 1!'
110
+ };
111
+ const entity2 = {
112
+ uri: 'entities/e2',
113
+ type: 'configuration/entityTypes/Organization',
114
+ label: 'Entity 2'
115
+ };
116
+ const entity3 = {
117
+ uri: 'entities/e3',
118
+ type: 'configuration/entityTypes/Organization',
119
+ label: 'Entity 3'
120
+ };
121
+ const relationMainE1 = {
122
+ uri: 'relations/main-e1',
123
+ type: 'configuration/relationTypes/Subsidiary',
124
+ startObject: {
125
+ directionalLabel: 'Company parent',
126
+ objectURI: 'entities/main'
127
+ },
128
+ endObject: {
129
+ directionalLabel: 'Company subsidiary',
130
+ objectURI: 'entities/e1'
131
+ },
132
+ direction: 'directed'
133
+ };
134
+ const relationMainE2 = {
135
+ uri: 'relations/main-e2',
136
+ type: 'configuration/relationTypes/Subsidiary',
137
+ startObject: {
138
+ objectURI: 'entities/main'
139
+ },
140
+ endObject: {
141
+ objectURI: 'entities/e2'
142
+ },
143
+ direction: 'directed'
144
+ };
145
+ const relationMainE3 = {
146
+ uri: 'relations/main-e3',
147
+ type: 'configuration/relationTypes/Assistant',
148
+ startObject: {
149
+ objectURI: 'entities/main'
150
+ },
151
+ endObject: {
152
+ objectURI: 'entities/e3'
153
+ },
154
+ direction: 'directed'
155
+ };
156
+ const relationE2E3 = {
157
+ uri: 'relations/e2-e3',
158
+ type: 'configuration/relationTypes/Subsidiary',
159
+ startObject: {
160
+ directionalLabel: 'Company parent',
161
+ objectURI: 'entities/e2'
162
+ },
163
+ endObject: {
164
+ directionalLabel: 'Company subsidiary',
165
+ objectURI: 'entities/e3'
166
+ },
167
+ direction: 'directed'
168
+ };
169
+ const relationE3E1 = {
170
+ uri: 'relations/e3-e1',
171
+ type: 'configuration/relationTypes/Subsidiary',
172
+ startObject: {
173
+ directionalLabel: 'Company parent',
174
+ objectURI: 'entities/e3'
175
+ },
176
+ endObject: {
177
+ directionalLabel: 'Company subsidiary',
178
+ objectURI: 'entities/e1'
179
+ },
180
+ direction: 'directed'
181
+ };
182
+ const data = {
183
+ entities: [entity, entity1, entity2, entity3],
184
+ relations: [relationMainE1, relationMainE2, relationMainE3, relationE2E3, relationE3E1]
185
+ };
186
+
187
+ const selectEntity = (component, uri) => {
188
+ component.find(GraphStateContext.Provider).prop('value').onEntitySelect(uri);
189
+ };
190
+
191
+ it('should prepare relationshipTable data according graph data and selected main entity by default', async () => {
192
+ (getHops as jest.Mock).mockReturnValue(Promise.resolve(data));
193
+ const component = setUp(mount, createStore({entity, metadata}));
194
+ expect(component.find(GraphStateContext.Provider)).toHaveLength(1);
195
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
196
+ rowsData: [],
197
+ page: 0,
198
+ rowsPerPage: 25,
199
+ sorting: {
200
+ field: '',
201
+ order: 'asc'
202
+ },
203
+ total: 0,
204
+ entityTypesOptions: [],
205
+ relationTypesOptions: []
206
+ });
207
+ await act(async () => {
208
+ await Promise.resolve();
209
+ });
210
+ component.update();
211
+ expect(component.find(GraphStateContext.Provider).prop('value').selectedEntity.uri).toBe(entity.uri);
212
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
213
+ rowsData: [
214
+ {
215
+ relation: relationMainE1,
216
+ entity: entity1,
217
+ entityLabel: entity1.label,
218
+ entityTypeLabel: 'HCO label',
219
+ relationTypeLabel: 'Company subsidiary'
220
+ },
221
+ {
222
+ relation: relationMainE2,
223
+ entity: entity2,
224
+ entityLabel: entity2.label,
225
+ entityTypeLabel: 'Organization label',
226
+ relationTypeLabel: 'Subsidiary label'
227
+ },
228
+ {
229
+ relation: relationMainE3,
230
+ entity: entity3,
231
+ entityLabel: entity3.label,
232
+ entityTypeLabel: 'Organization label',
233
+ relationTypeLabel: 'Assistant'
234
+ }
235
+ ],
236
+ page: 0,
237
+ rowsPerPage: 25,
238
+ sorting: {
239
+ field: '',
240
+ order: 'asc'
241
+ },
242
+ total: 3,
243
+ entityTypesOptions: [
244
+ {
245
+ attributes: [],
246
+ label: 'HCO label',
247
+ uri: 'configuration/entityTypes/HCO'
248
+ },
249
+ {
250
+ attributes: [],
251
+ label: 'Organization label',
252
+ uri: 'configuration/entityTypes/Organization'
253
+ }
254
+ ],
255
+ relationTypesOptions: [
256
+ {
257
+ attributes: [],
258
+ label: 'Subsidiary label',
259
+ uri: 'configuration/relationTypes/Subsidiary'
260
+ },
261
+ {
262
+ attributes: [],
263
+ label: 'Assistant',
264
+ uri: 'configuration/relationTypes/Assistant'
265
+ }
266
+ ]
267
+ });
268
+ });
269
+
270
+ it('should prepare relationshipTable data according graph data and current selected entity', async () => {
271
+ (getHops as jest.Mock).mockReturnValue(Promise.resolve(data));
272
+ const component = setUp(mount, createStore({entity, metadata}));
273
+ await act(async () => {
274
+ await Promise.resolve();
275
+ });
276
+ component.update();
277
+
278
+ // entity2
279
+ act(() => {
280
+ selectEntity(component, entity2.uri);
281
+ });
282
+ component.update();
283
+ expect(component.find(GraphStateContext.Provider).prop('value').selectedEntity.uri).toBe(entity2.uri);
284
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
285
+ rowsData: [
286
+ {
287
+ relation: relationMainE2,
288
+ entity: entity,
289
+ entityLabel: entity.label,
290
+ entityTypeLabel: 'Organization label',
291
+ relationTypeLabel: 'Subsidiary label'
292
+ },
293
+ {
294
+ relation: relationE2E3,
295
+ entity: entity3,
296
+ entityLabel: entity3.label,
297
+ entityTypeLabel: 'Organization label',
298
+ relationTypeLabel: 'Company subsidiary'
299
+ }
300
+ ],
301
+ page: 0,
302
+ rowsPerPage: 25,
303
+ sorting: {
304
+ field: '',
305
+ order: 'asc'
306
+ },
307
+ total: 2
308
+ });
309
+
310
+ // entity3
311
+ act(() => {
312
+ selectEntity(component, entity3.uri);
313
+ });
314
+ component.update();
315
+ expect(component.find(GraphStateContext.Provider).prop('value').selectedEntity.uri).toBe(entity3.uri);
316
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
317
+ rowsData: [
318
+ {
319
+ relation: relationMainE3,
320
+ entity: entity,
321
+ entityLabel: entity.label,
322
+ entityTypeLabel: 'Organization label',
323
+ relationTypeLabel: 'Assistant'
324
+ },
325
+ {
326
+ relation: relationE2E3,
327
+ entity: entity2,
328
+ entityLabel: entity2.label,
329
+ entityTypeLabel: 'Organization label',
330
+ relationTypeLabel: 'Company parent'
331
+ },
332
+ {
333
+ relation: relationE3E1,
334
+ entity: entity1,
335
+ entityLabel: entity1.label,
336
+ entityTypeLabel: 'HCO label',
337
+ relationTypeLabel: 'Company subsidiary'
338
+ }
339
+ ],
340
+ page: 0,
341
+ rowsPerPage: 25,
342
+ sorting: {
343
+ field: '',
344
+ order: 'asc'
345
+ },
346
+ total: 3
347
+ });
348
+ });
349
+
350
+ it('should support sorting', async () => {
351
+ (getHops as jest.Mock).mockReturnValue(Promise.resolve(data));
352
+ const component = setUp(mount, createStore({entity, metadata}));
353
+ await act(async () => {
354
+ await Promise.resolve();
355
+ });
356
+ component.update();
357
+ expect(component.find(GraphStateContext.Provider).prop('value').selectedEntity.uri).toBe(entity.uri);
358
+ act(() => {
359
+ component.find(GraphStateContext.Provider).prop('value').relationshipTable.onSort({
360
+ field: 'relationTypeLabel',
361
+ order: 'desc'
362
+ });
363
+ });
364
+ component.update();
365
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
366
+ rowsData: [
367
+ {
368
+ relation: relationMainE2,
369
+ entity: entity2,
370
+ entityLabel: entity2.label,
371
+ entityTypeLabel: 'Organization label',
372
+ relationTypeLabel: 'Subsidiary label'
373
+ },
374
+ {
375
+ relation: relationMainE1,
376
+ entity: entity1,
377
+ entityLabel: entity1.label,
378
+ entityTypeLabel: 'HCO label',
379
+ relationTypeLabel: 'Company subsidiary'
380
+ },
381
+ {
382
+ relation: relationMainE3,
383
+ entity: entity3,
384
+ entityLabel: entity3.label,
385
+ entityTypeLabel: 'Organization label',
386
+ relationTypeLabel: 'Assistant'
387
+ }
388
+ ],
389
+ page: 0,
390
+ rowsPerPage: 25,
391
+ sorting: {
392
+ field: 'relationTypeLabel',
393
+ order: 'desc'
394
+ },
395
+ total: 3
396
+ });
397
+ });
398
+
399
+ it('should support search text filtering', async () => {
400
+ (getHops as jest.Mock).mockReturnValue(Promise.resolve(data));
401
+ const component = setUp(mount, createStore({entity, metadata}));
402
+ await act(async () => {
403
+ await Promise.resolve();
404
+ });
405
+ component.update();
406
+ expect(component.find(GraphStateContext.Provider).prop('value').selectedEntity.uri).toBe(entity.uri);
407
+ act(() => {
408
+ component.find(GraphStateContext.Provider).prop('value').relationshipTable.onChangeSearchText('entity 1');
409
+ });
410
+ component.update();
411
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
412
+ rowsData: [
413
+ {
414
+ relation: relationMainE1,
415
+ entity: entity1,
416
+ entityLabel: entity1.label,
417
+ entityTypeLabel: 'HCO label',
418
+ relationTypeLabel: 'Company subsidiary'
419
+ }
420
+ ],
421
+ page: 0,
422
+ rowsPerPage: 25,
423
+ sorting: {
424
+ field: '',
425
+ order: 'asc'
426
+ },
427
+ total: 1,
428
+ searchText: 'entity 1'
429
+ });
430
+
431
+ act(() => {
432
+ component.find(GraphStateContext.Provider).prop('value').relationshipTable.onChangeSearchText('Entity 2');
433
+ });
434
+ component.update();
435
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
436
+ rowsData: [
437
+ {
438
+ relation: relationMainE2,
439
+ entity: entity2,
440
+ entityLabel: entity2.label,
441
+ entityTypeLabel: 'Organization label',
442
+ relationTypeLabel: 'Subsidiary label'
443
+ }
444
+ ],
445
+ page: 0,
446
+ rowsPerPage: 25,
447
+ sorting: {
448
+ field: '',
449
+ order: 'asc'
450
+ },
451
+ total: 1,
452
+ searchText: 'Entity 2'
453
+ });
454
+ });
455
+
456
+ it('should support entityTypes filtering', async () => {
457
+ (getHops as jest.Mock).mockReturnValue(Promise.resolve(data));
458
+ const component = setUp(mount, createStore({entity, metadata}));
459
+ await act(async () => {
460
+ await Promise.resolve();
461
+ });
462
+ component.update();
463
+ expect(component.find(GraphStateContext.Provider).prop('value').selectedEntity.uri).toBe(entity.uri);
464
+ act(() => {
465
+ component
466
+ .find(GraphStateContext.Provider)
467
+ .prop('value')
468
+ .relationshipTable.onFilter({
469
+ entityTypesUris: ['configuration/entityTypes/HCO'],
470
+ relationTypesUris: []
471
+ });
472
+ });
473
+ component.update();
474
+
475
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
476
+ rowsData: [
477
+ {
478
+ entity: entity1,
479
+ entityLabel: '!Entity 1!',
480
+ entityTypeLabel: 'HCO label',
481
+ relation: relationMainE1,
482
+ relationTypeLabel: 'Company subsidiary'
483
+ }
484
+ ],
485
+ page: 0,
486
+ rowsPerPage: 25,
487
+ sorting: {
488
+ field: '',
489
+ order: 'asc'
490
+ },
491
+ total: 1,
492
+ filters: {
493
+ entityTypesUris: ['configuration/entityTypes/HCO'],
494
+ relationTypesUris: []
495
+ },
496
+ entityTypesOptions: [
497
+ {
498
+ attributes: [],
499
+ label: 'HCO label',
500
+ uri: 'configuration/entityTypes/HCO'
501
+ },
502
+ {
503
+ attributes: [],
504
+ label: 'Organization label',
505
+ uri: 'configuration/entityTypes/Organization'
506
+ }
507
+ ]
508
+ });
509
+
510
+ act(() => {
511
+ selectEntity(component, entity2.uri);
512
+ });
513
+ component.update();
514
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
515
+ filters: {
516
+ entityTypesUris: ['configuration/entityTypes/HCO'],
517
+ relationTypesUris: []
518
+ },
519
+ entityTypesOptions: [
520
+ {
521
+ attributes: [],
522
+ label: 'Organization label',
523
+ uri: 'configuration/entityTypes/Organization'
524
+ },
525
+ {
526
+ attributes: [],
527
+ label: 'HCO label',
528
+ uri: 'configuration/entityTypes/HCO'
529
+ }
530
+ ]
531
+ });
532
+ });
533
+
534
+ it('should support relationTypes filtering', async () => {
535
+ (getHops as jest.Mock).mockReturnValue(Promise.resolve(data));
536
+ const component = setUp(mount, createStore({entity, metadata}));
537
+ await act(async () => {
538
+ await Promise.resolve();
539
+ });
540
+ component.update();
541
+ expect(component.find(GraphStateContext.Provider).prop('value').selectedEntity.uri).toBe(entity.uri);
542
+ act(() => {
543
+ component
544
+ .find(GraphStateContext.Provider)
545
+ .prop('value')
546
+ .relationshipTable.onFilter({
547
+ entityTypesUris: [],
548
+ relationTypesUris: ['configuration/relationTypes/Assistant']
549
+ });
550
+ });
551
+ component.update();
552
+
553
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
554
+ rowsData: [
555
+ {
556
+ relation: relationMainE3,
557
+ entity: entity3,
558
+ entityLabel: entity3.label,
559
+ entityTypeLabel: 'Organization label',
560
+ relationTypeLabel: 'Assistant'
561
+ }
562
+ ],
563
+ page: 0,
564
+ rowsPerPage: 25,
565
+ sorting: {
566
+ field: '',
567
+ order: 'asc'
568
+ },
569
+ total: 1,
570
+ filters: {
571
+ entityTypesUris: [],
572
+ relationTypesUris: ['configuration/relationTypes/Assistant']
573
+ },
574
+ relationTypesOptions: [
575
+ {
576
+ attributes: [],
577
+ label: 'Subsidiary label',
578
+ uri: 'configuration/relationTypes/Subsidiary'
579
+ },
580
+ {
581
+ attributes: [],
582
+ label: 'Assistant',
583
+ uri: 'configuration/relationTypes/Assistant'
584
+ }
585
+ ]
586
+ });
587
+
588
+ act(() => {
589
+ selectEntity(component, entity2.uri);
590
+ });
591
+ component.update();
592
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
593
+ filters: {
594
+ entityTypesUris: [],
595
+ relationTypesUris: ['configuration/relationTypes/Assistant']
596
+ },
597
+ relationTypesOptions: [
598
+ {
599
+ attributes: [],
600
+ label: 'Subsidiary label',
601
+ uri: 'configuration/relationTypes/Subsidiary'
602
+ },
603
+ {
604
+ attributes: [],
605
+ label: 'Assistant',
606
+ uri: 'configuration/relationTypes/Assistant'
607
+ }
608
+ ]
609
+ });
610
+ });
611
+
612
+ it('should reset filters on main entity changing', async () => {
613
+ (getHops as jest.Mock).mockReturnValue(Promise.resolve(data));
614
+ const component = setUp(mount, createStore({entity, metadata}));
615
+ await act(async () => {
616
+ await Promise.resolve();
617
+ });
618
+ component.update();
619
+ expect(component.find(GraphStateContext.Provider).prop('value').selectedEntity.uri).toBe(entity.uri);
620
+ act(() => {
621
+ component
622
+ .find(GraphStateContext.Provider)
623
+ .prop('value')
624
+ .relationshipTable.onFilter({
625
+ entityTypesUris: ['configuration/relationTypes/HCP'],
626
+ relationTypesUris: ['configuration/relationTypes/Assistant']
627
+ });
628
+ });
629
+ component.update();
630
+
631
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
632
+ filters: {
633
+ entityTypesUris: ['configuration/relationTypes/HCP'],
634
+ relationTypesUris: ['configuration/relationTypes/Assistant']
635
+ }
636
+ });
637
+
638
+ store = createStore({
639
+ entity: {
640
+ uri: 'entities/e1',
641
+ type: 'configuration/entityTypes/HCO'
642
+ },
643
+ metadata
644
+ });
645
+ component.setProps({});
646
+
647
+ act(() => {
648
+ selectEntity(component, entity2.uri);
649
+ });
650
+ component.update();
651
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
652
+ filters: {
653
+ entityTypesUris: [],
654
+ relationTypesUris: []
655
+ }
656
+ });
657
+ });
658
+
659
+ describe('pagination behavior', () => {
660
+ const REPEAT_NUMBER = 50;
661
+ const total = REPEAT_NUMBER + 3;
662
+ const bigData = {
663
+ entities: data.entities,
664
+ relations: data.relations.concat(
665
+ times(
666
+ (i) => ({
667
+ ...relationMainE1,
668
+ uri: `${relationMainE1.uri}_${i}`
669
+ }),
670
+ REPEAT_NUMBER
671
+ )
672
+ )
673
+ };
674
+
675
+ it('should support page change', async () => {
676
+ (getHops as jest.Mock).mockReturnValue(Promise.resolve(bigData));
677
+ const component = setUp(mount, createStore({entity, metadata}));
678
+ await act(async () => {
679
+ await Promise.resolve();
680
+ });
681
+ component.update();
682
+ expect(component.find(GraphStateContext.Provider).prop('value').selectedEntity.uri).toBe(entity.uri);
683
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable.rowsData.length).toBe(25);
684
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
685
+ page: 0,
686
+ rowsPerPage: 25,
687
+ total
688
+ });
689
+
690
+ act(() => {
691
+ component.find(GraphStateContext.Provider).prop('value').relationshipTable.onPageChange(1);
692
+ });
693
+ component.update();
694
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable.rowsData.length).toBe(25);
695
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
696
+ page: 1,
697
+ rowsPerPage: 25,
698
+ total
699
+ });
700
+
701
+ act(() => {
702
+ component.find(GraphStateContext.Provider).prop('value').relationshipTable.onPageChange(2);
703
+ });
704
+ component.update();
705
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable.rowsData.length).toBe(3);
706
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
707
+ page: 2,
708
+ rowsPerPage: 25,
709
+ total
710
+ });
711
+ });
712
+
713
+ it('should support rows per page changing', async () => {
714
+ (getHops as jest.Mock).mockReturnValue(Promise.resolve(bigData));
715
+ const component = setUp(mount, createStore({entity, metadata}));
716
+ await act(async () => {
717
+ await Promise.resolve();
718
+ });
719
+ component.update();
720
+
721
+ act(() => {
722
+ component.find(GraphStateContext.Provider).prop('value').relationshipTable.onRowsPerPageChange(50);
723
+ });
724
+ component.update();
725
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable.rowsData.length).toBe(50);
726
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
727
+ page: 0,
728
+ rowsPerPage: 50,
729
+ total
730
+ });
731
+
732
+ act(() => {
733
+ component.find(GraphStateContext.Provider).prop('value').relationshipTable.onPageChange(1);
734
+ });
735
+ component.update();
736
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable.rowsData.length).toBe(3);
737
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
738
+ page: 1,
739
+ rowsPerPage: 50,
740
+ total
741
+ });
742
+ });
743
+ });
744
+
745
+ describe('editing relation behavior', () => {
746
+ const relation = {
747
+ ...relationMainE1,
748
+ attributes: {
749
+ FirstName: [
750
+ {
751
+ type: 'configuration/entityTypes/HCP/attributes/FirstName',
752
+ ov: true,
753
+ value: 'HCP_5',
754
+ uri: 'entities/19oYeyx1/attributes/FirstName/1dg2njmxf'
755
+ }
756
+ ]
757
+ }
758
+ };
759
+
760
+ beforeEach(() => {
761
+ (getRelation as jest.Mock).mockReturnValue(Promise.resolve(relation));
762
+ });
763
+ it('should setLoading and request relation on relation editing', async () => {
764
+ const component = setUp(shallow, createStore({entity, metadata}));
765
+
766
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
767
+ loading: false,
768
+ editingRelations: []
769
+ });
770
+
771
+ act(() => {
772
+ component
773
+ .find(GraphStateContext.Provider)
774
+ .prop('value')
775
+ .relationshipTable.onStartRelationEditing(relation.uri);
776
+ });
777
+ expect(getRelation).toHaveBeenCalledWith(relation.uri);
778
+
779
+ rerenderWrapper(component);
780
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
781
+ loading: true,
782
+ editingRelations: []
783
+ });
784
+
785
+ await act(async () => {
786
+ await Promise.resolve();
787
+ });
788
+
789
+ rerenderWrapper(component);
790
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
791
+ loading: false,
792
+ editingRelations: [{initialRelation: relation, relation}]
793
+ });
794
+ });
795
+
796
+ it('should request relation on relation editing and process error correctly', async () => {
797
+ (getRelation as jest.Mock).mockRejectedValue('some error');
798
+ const component = setUp(shallow, createStore({entity, metadata}));
799
+
800
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
801
+ loading: false,
802
+ editingRelations: []
803
+ });
804
+
805
+ act(() => {
806
+ component
807
+ .find(GraphStateContext.Provider)
808
+ .prop('value')
809
+ .relationshipTable.onStartRelationEditing(relation.uri);
810
+ });
811
+ expect(getRelation).toHaveBeenCalledWith(relation.uri);
812
+
813
+ rerenderWrapper(component);
814
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
815
+ loading: true,
816
+ editingRelations: []
817
+ });
818
+
819
+ await act(async () => {
820
+ await Promise.resolve();
821
+ });
822
+
823
+ rerenderWrapper(component);
824
+ expect(dispatch).toHaveBeenCalledWith(
825
+ ui.actions.errorSet(getRequestErrorMessage('some error', "Can't load relationship's attributes"))
826
+ );
827
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
828
+ loading: false,
829
+ editingRelations: []
830
+ });
831
+ });
832
+
833
+ it('should update relation in editing relations on update relation action', async () => {
834
+ const component = setUp(shallow, createStore({entity, metadata}));
835
+
836
+ act(() => {
837
+ component
838
+ .find(GraphStateContext.Provider)
839
+ .prop('value')
840
+ .relationshipTable.onStartRelationEditing(relation.uri);
841
+ });
842
+
843
+ await act(async () => {
844
+ await Promise.resolve();
845
+ });
846
+
847
+ rerenderWrapper(component);
848
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
849
+ editingRelations: [{initialRelation: relation, relation}]
850
+ });
851
+
852
+ const updatedRelation = {
853
+ ...relation,
854
+ attributes: {
855
+ FirstName: [
856
+ {
857
+ ...relation.attributes.FirstName[0],
858
+ value: 'new Value'
859
+ }
860
+ ]
861
+ }
862
+ };
863
+ act(() => {
864
+ component
865
+ .find(GraphStateContext.Provider)
866
+ .prop('value')
867
+ .relationshipTable.onUpdateEditingRelation(updatedRelation);
868
+ });
869
+ rerenderWrapper(component);
870
+
871
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
872
+ editingRelations: [{initialRelation: relation, relation: updatedRelation}]
873
+ });
874
+
875
+ act(() => {
876
+ component
877
+ .find(GraphStateContext.Provider)
878
+ .prop('value')
879
+ .relationshipTable.onCancelRelationEditing(updatedRelation.uri);
880
+ });
881
+ rerenderWrapper(component);
882
+
883
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
884
+ editingRelations: []
885
+ });
886
+ });
887
+
888
+ it('should make request update relation on onSaveEditingRelation action', async () => {
889
+ const component = setUp(shallow, createStore({entity, metadata}));
890
+
891
+ act(() => {
892
+ component
893
+ .find(GraphStateContext.Provider)
894
+ .prop('value')
895
+ .relationshipTable.onStartRelationEditing(relation.uri);
896
+ });
897
+
898
+ await act(async () => {
899
+ await Promise.resolve();
900
+ });
901
+
902
+ rerenderWrapper(component);
903
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
904
+ editingRelations: [{initialRelation: relation, relation}]
905
+ });
906
+
907
+ const updatedRelation = {
908
+ ...relation,
909
+ attributes: {
910
+ FirstName: [
911
+ {
912
+ ...relation.attributes.FirstName[0],
913
+ value: 'new Value'
914
+ }
915
+ ]
916
+ }
917
+ };
918
+ act(() => {
919
+ component
920
+ .find(GraphStateContext.Provider)
921
+ .prop('value')
922
+ .relationshipTable.onUpdateEditingRelation(updatedRelation);
923
+ });
924
+ rerenderWrapper(component);
925
+
926
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
927
+ editingRelations: [{initialRelation: relation, relation: updatedRelation}],
928
+ loading: false
929
+ });
930
+
931
+ act(() => {
932
+ component
933
+ .find(GraphStateContext.Provider)
934
+ .prop('value')
935
+ .relationshipTable.onSaveEditingRelation(relation, updatedRelation);
936
+ });
937
+
938
+ expect(updateRelation).toHaveBeenCalledWith({oldRelation: relation, newRelation: updatedRelation});
939
+ rerenderWrapper(component);
940
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
941
+ editingRelations: [{initialRelation: relation, relation: updatedRelation}],
942
+ loading: true
943
+ });
944
+ await act(async () => {
945
+ await Promise.resolve();
946
+ });
947
+ rerenderWrapper(component);
948
+
949
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
950
+ editingRelations: [],
951
+ loading: false
952
+ });
953
+ });
954
+
955
+ it('should make request update relation on onSaveEditingRelation action and process error correctly', async () => {
956
+ const component = setUp(shallow, createStore({entity, metadata}));
957
+
958
+ (updateRelation as jest.Mock).mockRejectedValue('some error');
959
+ act(() => {
960
+ component
961
+ .find(GraphStateContext.Provider)
962
+ .prop('value')
963
+ .relationshipTable.onStartRelationEditing(relation.uri);
964
+ });
965
+
966
+ await act(async () => {
967
+ await Promise.resolve();
968
+ });
969
+
970
+ rerenderWrapper(component);
971
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
972
+ editingRelations: [{initialRelation: relation, relation}],
973
+ loading: false
974
+ });
975
+
976
+ act(() => {
977
+ component
978
+ .find(GraphStateContext.Provider)
979
+ .prop('value')
980
+ .relationshipTable.onSaveEditingRelation(relation, relation);
981
+ });
982
+
983
+ expect(updateRelation).toHaveBeenCalledWith({oldRelation: relation, newRelation: relation});
984
+ rerenderWrapper(component);
985
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
986
+ editingRelations: [{initialRelation: relation, relation}],
987
+ loading: true
988
+ });
989
+ await act(async () => {
990
+ await Promise.resolve();
991
+ });
992
+ rerenderWrapper(component);
993
+
994
+ expect(dispatch).toHaveBeenCalledWith(
995
+ ui.actions.errorSet(getRequestErrorMessage('some error', "Can't edit relationship"))
996
+ );
997
+ expect(component.find(GraphStateContext.Provider).prop('value').relationshipTable).toMatchObject({
998
+ editingRelations: [{initialRelation: relation, relation}],
999
+ loading: false
1000
+ });
1001
+ });
1002
+ });
1003
+ });