Skip to content

Commit 2863676

Browse files
committed
fix: use a shared hook and minimize test duplication
1 parent 3f6e8ac commit 2863676

File tree

6 files changed

+572
-218
lines changed

6 files changed

+572
-218
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import React from 'react';
2+
import { render, screen, userEvent } from '@mongodb-js/testing-library-compass';
3+
import { expect } from 'chai';
4+
import sinon from 'sinon';
5+
import HadronDocument from 'hadron-document';
6+
import { DocumentJsonViewItem } from './document-json-view-item';
7+
8+
describe('DocumentJsonViewItem', function () {
9+
let doc: HadronDocument;
10+
let copyToClipboardStub: sinon.SinonStub;
11+
let openInsertDocumentDialogStub: sinon.SinonStub;
12+
13+
beforeEach(function () {
14+
doc = new HadronDocument({
15+
_id: 1,
16+
name: 'test',
17+
url: 'https://mongodb.com',
18+
nested: { field: 'value' },
19+
});
20+
21+
copyToClipboardStub = sinon.stub();
22+
openInsertDocumentDialogStub = sinon.stub();
23+
});
24+
25+
afterEach(function () {
26+
sinon.restore();
27+
});
28+
29+
it('renders the JSON editor component', function () {
30+
render(
31+
<DocumentJsonViewItem
32+
doc={doc}
33+
docRef={null}
34+
docIndex={0}
35+
namespace="test.test"
36+
isEditable={true}
37+
copyToClipboard={copyToClipboardStub}
38+
openInsertDocumentDialog={openInsertDocumentDialogStub}
39+
/>
40+
);
41+
42+
// Should render without error
43+
expect(document.querySelector('[data-testid="editable-json"]')).to.exist;
44+
});
45+
46+
it('renders context menu when right-clicked', function () {
47+
const { container } = render(
48+
<DocumentJsonViewItem
49+
doc={doc}
50+
docRef={null}
51+
docIndex={0}
52+
namespace="test.test"
53+
isEditable={true}
54+
copyToClipboard={copyToClipboardStub}
55+
openInsertDocumentDialog={openInsertDocumentDialogStub}
56+
/>
57+
);
58+
59+
const element = container.firstChild as HTMLElement;
60+
61+
// Right-click to open context menu
62+
userEvent.click(element, { button: 2 });
63+
64+
// Should show context menu with expected items
65+
expect(screen.getByText('Copy document')).to.exist;
66+
expect(screen.getByText('Clone document...')).to.exist;
67+
expect(screen.getByText('Delete document')).to.exist;
68+
});
69+
70+
it('renders scroll trigger when docIndex is 0', function () {
71+
const scrollTriggerRef = React.createRef<HTMLDivElement>();
72+
73+
render(
74+
<DocumentJsonViewItem
75+
doc={doc}
76+
docRef={null}
77+
docIndex={0}
78+
namespace="test.test"
79+
isEditable={true}
80+
scrollTriggerRef={scrollTriggerRef}
81+
copyToClipboard={copyToClipboardStub}
82+
openInsertDocumentDialog={openInsertDocumentDialogStub}
83+
/>
84+
);
85+
86+
expect(scrollTriggerRef.current).to.exist;
87+
});
88+
89+
it('does not render scroll trigger when docIndex is not 0', function () {
90+
const scrollTriggerRef = React.createRef<HTMLDivElement>();
91+
92+
render(
93+
<DocumentJsonViewItem
94+
doc={doc}
95+
docRef={null}
96+
docIndex={1}
97+
namespace="test.test"
98+
isEditable={true}
99+
scrollTriggerRef={scrollTriggerRef}
100+
copyToClipboard={copyToClipboardStub}
101+
openInsertDocumentDialog={openInsertDocumentDialogStub}
102+
/>
103+
);
104+
105+
expect(scrollTriggerRef.current).to.be.null;
106+
});
107+
});

packages/compass-crud/src/components/document-json-view-item.tsx

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react';
22
import type HadronDocument from 'hadron-document';
3-
import { css, KeylineCard, spacing } from '@mongodb-js/compass-components';
3+
import { css, KeylineCard } from '@mongodb-js/compass-components';
44

55
import JSONEditor, { type JSONEditorProps } from './json-editor';
66
import { useContextMenuItems } from '@mongodb-js/compass-components';
@@ -43,23 +43,50 @@ const DocumentJsonViewItem: React.FC<DocumentJsonViewItemProps> = ({
4343
}) => {
4444
const ref = useContextMenuItems([
4545
{
46-
label: 'Update document',
46+
label: doc.expanded ? 'Collapse all fields' : 'Expand all fields',
4747
onAction: () => {
48-
updateDocument?.(doc);
48+
if (doc.expanded) {
49+
doc.collapse();
50+
} else {
51+
doc.expand();
52+
}
4953
},
5054
},
55+
...(isEditable && !doc.editing
56+
? [
57+
{
58+
label: 'Edit document',
59+
onAction: () => {
60+
doc.startEditing();
61+
},
62+
},
63+
]
64+
: []),
5165
{
5266
label: 'Copy document',
5367
onAction: () => {
5468
copyToClipboard?.(doc);
5569
},
5670
},
57-
{
58-
label: 'Delete document',
59-
onAction: () => {
60-
removeDocument?.(doc);
61-
},
62-
},
71+
...(isEditable
72+
? [
73+
{
74+
label: 'Clone document...',
75+
onAction: () => {
76+
const clonedDoc = doc.generateObject({
77+
excludeInternalFields: true,
78+
});
79+
openInsertDocumentDialog?.(clonedDoc, true);
80+
},
81+
},
82+
{
83+
label: 'Delete document',
84+
onAction: () => {
85+
doc.markForDeletion();
86+
},
87+
},
88+
]
89+
: []),
6390
]);
6491

6592
return (

0 commit comments

Comments
 (0)