Skip to content

Commit eb5d54d

Browse files
committed
chore(data-modeling): add tests
1 parent 0eaeb31 commit eb5d54d

File tree

7 files changed

+714
-6
lines changed

7 files changed

+714
-6
lines changed

packages/compass-data-modeling/src/components/collection-drawer-content.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ const CollectionDrawerContent: React.FunctionComponent<
4343
<ul>
4444
{relationships.map((r) => {
4545
return (
46-
<li key={r.id}>
46+
<li key={r.id} data-relationship-id={r.id}>
4747
{r.relationship[0].fields.join(', ')}&nbsp;-&gt;&nbsp;
4848
{r.relationship[1].fields.join(', ')}
4949
<Button
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import React from 'react';
2+
import { expect } from 'chai';
3+
import {
4+
createPluginTestHelpers,
5+
screen,
6+
waitFor,
7+
userEvent,
8+
within,
9+
} from '@mongodb-js/testing-library-compass';
10+
import { DataModelingWorkspaceTab } from '../index';
11+
import DiagramEditorSidePanel from './diagram-editor-side-panel';
12+
import {
13+
getCurrentDiagramFromState,
14+
openDiagram,
15+
selectCollection,
16+
selectCurrentModel,
17+
selectRelationship,
18+
} from '../store/diagram';
19+
import dataModel from '../../test/fixtures/data-model-with-relationships.json';
20+
21+
async function comboboxSelectItem(
22+
label: string,
23+
value: string,
24+
visibleLabel = value
25+
) {
26+
userEvent.click(screen.getByRole('textbox', { name: label }));
27+
await waitFor(() => {
28+
screen.getByRole('option', { name: visibleLabel });
29+
});
30+
userEvent.click(screen.getByRole('option', { name: visibleLabel }));
31+
await waitFor(() => {
32+
expect(screen.getByRole('textbox', { name: label })).to.have.attribute(
33+
'value',
34+
value
35+
);
36+
});
37+
}
38+
39+
describe.only('DiagramEditorSidePanel', function () {
40+
function renderDrawer() {
41+
const { renderWithConnections } = createPluginTestHelpers(
42+
DataModelingWorkspaceTab.provider.withMockServices({})
43+
);
44+
const result = renderWithConnections(
45+
<DiagramEditorSidePanel></DiagramEditorSidePanel>
46+
);
47+
result.plugin.store.dispatch(openDiagram(dataModel));
48+
return result;
49+
}
50+
51+
it('should not render if no items are selected', function () {
52+
renderDrawer();
53+
});
54+
55+
it('should render a collection context drawer when collection is clicked', async function () {
56+
const result = renderDrawer();
57+
await result.plugin.store.dispatch(selectCollection('flights.airlines'));
58+
expect(screen.getByText('flights.airlines')).to.be.visible;
59+
});
60+
61+
it('should render a relationship context drawer when relations is clicked', async function () {
62+
const result = renderDrawer();
63+
await result.plugin.store.dispatch(
64+
selectRelationship('204b1fc0-601f-4d62-bba3-38fade71e049')
65+
);
66+
expect(screen.getByText('Edit Relationship')).to.be.visible;
67+
expect(
68+
document.querySelector(
69+
'[data-relationship-id="204b1fc0-601f-4d62-bba3-38fade71e049"]'
70+
)
71+
).to.exist;
72+
});
73+
74+
it('should open and edit relationship starting from collection', async function () {
75+
const result = renderDrawer();
76+
await result.plugin.store.dispatch(selectCollection('flights.countries'));
77+
78+
// Open relationshipt editing form
79+
const relationshipCard = document.querySelector<HTMLElement>(
80+
'[data-relationship-id="204b1fc0-601f-4d62-bba3-38fade71e049"]'
81+
);
82+
userEvent.click(
83+
within(relationshipCard!).getByRole('button', { name: 'Edit' })
84+
);
85+
expect(screen.getByText('Edit Relationship')).to.be.visible;
86+
87+
// Select new values
88+
await comboboxSelectItem('Local collection', 'planes');
89+
await comboboxSelectItem('Local field', 'name');
90+
await comboboxSelectItem('Foreign collection', 'countries');
91+
await comboboxSelectItem('Foreign field', 'iso_code');
92+
93+
userEvent.click(screen.getByRole('button', { name: 'Save' }));
94+
95+
// We should be testing through rendered UI but as it's really hard to make
96+
// diagram rendering in tests property, we are just validating the final
97+
// model here
98+
const modifiedRelationship = selectCurrentModel(
99+
getCurrentDiagramFromState(result.plugin.store.getState()).edits
100+
).relationships.find((r) => {
101+
return r.id === '204b1fc0-601f-4d62-bba3-38fade71e049';
102+
});
103+
104+
expect(modifiedRelationship)
105+
.to.have.property('relationship')
106+
.deep.eq([
107+
{
108+
ns: 'flights.planes',
109+
fields: ['name'],
110+
cardinality: 1,
111+
},
112+
{
113+
ns: 'flights.countries',
114+
fields: ['iso_code'],
115+
cardinality: 1,
116+
},
117+
]);
118+
119+
// After saving when starting from collection, we should end up back in the
120+
// collection drawer that we started from
121+
expect(screen.getByText('flights.countries')).to.be.visible;
122+
});
123+
});

packages/compass-data-modeling/src/components/diagram-editor.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
selectCurrentModel,
1717
selectCollection,
1818
selectRelationship,
19+
selectBackground,
1920
} from '../store/diagram';
2021
import {
2122
Banner,
@@ -192,6 +193,7 @@ const DiagramEditor: React.FunctionComponent<{
192193
onMoveCollection: (ns: string, newPosition: [number, number]) => void;
193194
onCollectionSelect: (namespace: string) => void;
194195
onRelationshipSelect: (rId: string) => void;
196+
onDiagramBackgroundClicked: () => void;
195197
selectedItem?: string | null;
196198
}> = ({
197199
diagramLabel,
@@ -203,6 +205,7 @@ const DiagramEditor: React.FunctionComponent<{
203205
onMoveCollection,
204206
onCollectionSelect,
205207
onRelationshipSelect,
208+
onDiagramBackgroundClicked,
206209
selectedItem,
207210
}) => {
208211
const { log, mongoLogId } = useLogger('COMPASS-DATA-MODELING-DIAGRAM-EDITOR');
@@ -353,6 +356,7 @@ const DiagramEditor: React.FunctionComponent<{
353356
}
354357
onCollectionSelect(node.id);
355358
}}
359+
onPaneClick={onDiagramBackgroundClicked}
356360
onEdgeClick={(_evt, edge) => {
357361
onRelationshipSelect(edge.id);
358362
}}
@@ -399,5 +403,6 @@ export default connect(
399403
onMoveCollection: moveCollection,
400404
onCollectionSelect: selectCollection,
401405
onRelationshipSelect: selectRelationship,
406+
onDiagramBackgroundClicked: selectBackground,
402407
}
403408
)(DiagramEditor);

packages/compass-data-modeling/src/components/relationship-drawer-content.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ const RelationshipDrawerContent: React.FunctionComponent<
8080
);
8181

8282
return (
83-
<>
83+
<div data-relationship-id={relationshipId}>
8484
<H3>Edit Relationship</H3>
8585

8686
<FormFieldContainer>
@@ -198,11 +198,11 @@ const RelationshipDrawerContent: React.FunctionComponent<
198198
Delete
199199
</Button>
200200
<Button disabled={!isValid} onClick={onSubmitFormClick}>
201-
Submit
201+
Save
202202
</Button>
203203
<Button onClick={onCancelEditClick}>Cancel</Button>
204204
</div>
205-
</>
205+
</div>
206206
);
207207
};
208208

packages/compass-data-modeling/src/store/diagram.ts

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export enum DiagramActionTypes {
4242
REDO_EDIT = 'data-modeling/diagram/REDO_EDIT',
4343
COLLECTION_SELECTED = 'data-modeling/diagram/COLLECTION_SELECTED',
4444
RELATIONSHIP_SELECTED = 'data-modeling/diagram/RELATIONSHIP_SELECTED',
45+
DIAGRAM_BACKGROUND_SELECTED = 'data-modeling/diagram/DIAGRAM_BACKGROUND_SELECTED',
4546
}
4647

4748
export type OpenDiagramAction = {
@@ -93,6 +94,10 @@ export type RelationSelectedAction = {
9394
relationship: Relationship;
9495
};
9596

97+
export type DiagramBackgroundSelectedAction = {
98+
type: DiagramActionTypes.DIAGRAM_BACKGROUND_SELECTED;
99+
};
100+
96101
export type DiagramActions =
97102
| OpenDiagramAction
98103
| DeleteDiagramAction
@@ -103,7 +108,8 @@ export type DiagramActions =
103108
| UndoEditAction
104109
| RedoEditAction
105110
| CollectionSelectedAction
106-
| RelationSelectedAction;
111+
| RelationSelectedAction
112+
| DiagramBackgroundSelectedAction;
107113

108114
const INITIAL_STATE: DiagramState = null;
109115

@@ -297,6 +303,12 @@ export const diagramReducer: Reducer<DiagramState> = (
297303
}
298304
return state;
299305
}
306+
if (isAction(action, DiagramActionTypes.DIAGRAM_BACKGROUND_SELECTED)) {
307+
return {
308+
...state,
309+
selectedItems: null,
310+
};
311+
}
300312
return state;
301313
};
302314

@@ -375,6 +387,33 @@ export function selectRelationship(
375387
};
376388
}
377389

390+
export function selectBackground(): DataModelingThunkAction<
391+
Promise<void>,
392+
DiagramBackgroundSelectedAction
393+
> {
394+
return async (dispatch, getState) => {
395+
const { sidePanel } = getState();
396+
397+
if (
398+
sidePanel.viewType === 'relationship-editing' &&
399+
sidePanel.relationshipFormState.modified
400+
) {
401+
const allowSelect = await showConfirmation({
402+
title: 'You have unsaved chages',
403+
description:
404+
'You are currently editing a relationship. Are you sure you want to stop editing?',
405+
});
406+
if (!allowSelect) {
407+
return;
408+
}
409+
}
410+
411+
dispatch({
412+
type: DiagramActionTypes.DIAGRAM_BACKGROUND_SELECTED,
413+
});
414+
};
415+
}
416+
378417
export function undoEdit(): DataModelingThunkAction<void, UndoEditAction> {
379418
return (dispatch, getState, { dataModelStorage }) => {
380419
dispatch({ type: DiagramActionTypes.UNDO_EDIT });

packages/compass-data-modeling/src/store/side-panel.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,8 @@ export const sidePanelReducer: Reducer<SidePanelState> = (
252252
if (
253253
isAction(action, SidePanelActionTypes.EDIT_RELATIONSHIP_FORM_CANCELED) ||
254254
isAction(action, SidePanelActionTypes.EDIT_RELATIONSHIP_FORM_SUBMITTED) ||
255-
isAction(action, DiagramActionTypes.COLLECTION_SELECTED)
255+
isAction(action, DiagramActionTypes.COLLECTION_SELECTED) ||
256+
isAction(action, DiagramActionTypes.DIAGRAM_BACKGROUND_SELECTED)
256257
) {
257258
return { viewType: null };
258259
}

0 commit comments

Comments
 (0)