Skip to content

Commit 9747847

Browse files
committed
add unit tests
1 parent ba9815e commit 9747847

File tree

2 files changed

+182
-2
lines changed

2 files changed

+182
-2
lines changed

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

Lines changed: 181 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ import {
44
createPluginTestHelpers,
55
screen,
66
waitFor,
7+
render,
8+
userEvent,
79
} from '@mongodb-js/testing-library-compass';
8-
import DiagramEditor from './diagram-editor';
10+
import DiagramEditor, { getFieldsFromSchema } from './diagram-editor';
911
import type { DataModelingStore } from '../../test/setup-store';
1012
import type {
1113
Edit,
@@ -229,3 +231,181 @@ describe('DiagramEditor', function () {
229231
});
230232
});
231233
});
234+
235+
describe('getFieldsFromSchema', function () {
236+
const validateMixedType = async (
237+
type: React.ReactNode,
238+
expectedTooltip: RegExp
239+
) => {
240+
render(<>{type}</>);
241+
const mixed = screen.getByText('(mixed)');
242+
expect(mixed).to.be.visible;
243+
userEvent.hover(mixed);
244+
await waitFor(() => {
245+
expect(screen.getByText(expectedTooltip)).to.be.visible;
246+
});
247+
};
248+
249+
describe('flat schema', function () {
250+
it('return empty array for empty schema', function () {
251+
const result = getFieldsFromSchema({});
252+
expect(result).to.deep.equal([]);
253+
});
254+
255+
it('returns fields for a simple schema', function () {
256+
const result = getFieldsFromSchema({
257+
bsonType: 'object',
258+
properties: {
259+
name: { bsonType: 'string' },
260+
age: { bsonType: 'int' },
261+
},
262+
});
263+
expect(result).to.deep.equal([
264+
{ name: 'name', type: 'string', depth: 0, glyphs: [] },
265+
{ name: 'age', type: 'int', depth: 0, glyphs: [] },
266+
]);
267+
});
268+
269+
it('returns mixed fields with tooltip on hover', async function () {
270+
const result = getFieldsFromSchema({
271+
bsonType: 'object',
272+
properties: {
273+
age: { bsonType: ['int', 'string'] },
274+
},
275+
});
276+
expect(result[0]).to.deep.include({ name: 'age', depth: 0, glyphs: [] });
277+
await validateMixedType(result[0].type, /int, string/);
278+
});
279+
});
280+
281+
describe('nested schema', function () {
282+
it('returns fields for a nested schema', function () {
283+
const result = getFieldsFromSchema({
284+
bsonType: 'object',
285+
properties: {
286+
person: {
287+
bsonType: 'object',
288+
properties: {
289+
name: { bsonType: 'string' },
290+
address: {
291+
bsonType: 'object',
292+
properties: {
293+
street: { bsonType: 'string' },
294+
city: { bsonType: 'string' },
295+
},
296+
},
297+
},
298+
},
299+
},
300+
});
301+
expect(result).to.deep.equal([
302+
{ name: 'person', type: 'object', depth: 0, glyphs: [] },
303+
{ name: 'name', type: 'string', depth: 1, glyphs: [] },
304+
{ name: 'address', type: 'object', depth: 1, glyphs: [] },
305+
{ name: 'street', type: 'string', depth: 2, glyphs: [] },
306+
{ name: 'city', type: 'string', depth: 2, glyphs: [] },
307+
]);
308+
});
309+
310+
it('returns [] for array', function () {
311+
const result = getFieldsFromSchema({
312+
bsonType: 'object',
313+
properties: {
314+
tags: {
315+
bsonType: 'array',
316+
items: { bsonType: 'string' },
317+
},
318+
},
319+
});
320+
expect(result).to.deep.equal([
321+
{ name: 'tags', type: '[]', depth: 0, glyphs: [] },
322+
]);
323+
});
324+
325+
it('returns fields for an array of objects', function () {
326+
const result = getFieldsFromSchema({
327+
bsonType: 'object',
328+
properties: {
329+
todos: {
330+
bsonType: 'array',
331+
items: {
332+
bsonType: 'object',
333+
properties: {
334+
title: { bsonType: 'string' },
335+
completed: { bsonType: 'boolean' },
336+
},
337+
},
338+
},
339+
},
340+
});
341+
expect(result).to.deep.equal([
342+
{ name: 'todos', type: '[]', depth: 0, glyphs: [] },
343+
{ name: 'title', type: 'string', depth: 1, glyphs: [] },
344+
{ name: 'completed', type: 'boolean', depth: 1, glyphs: [] },
345+
]);
346+
});
347+
348+
it('returns fields for a mixed schema with objects', async function () {
349+
const result = getFieldsFromSchema({
350+
bsonType: 'object',
351+
properties: {
352+
name: {
353+
anyOf: [
354+
{ bsonType: 'string' },
355+
{
356+
bsonType: 'object',
357+
properties: {
358+
first: { bsonType: 'string' },
359+
last: { bsonType: 'string' },
360+
},
361+
},
362+
],
363+
},
364+
},
365+
});
366+
expect(result).to.have.lengthOf(3);
367+
expect(result[0]).to.deep.include({ name: 'name', depth: 0, glyphs: [] });
368+
await validateMixedType(result[0].type, /string, object/);
369+
expect(result[1]).to.deep.equal({
370+
name: 'first',
371+
type: 'string',
372+
depth: 1,
373+
glyphs: [],
374+
});
375+
expect(result[2]).to.deep.equal({
376+
name: 'last',
377+
type: 'string',
378+
depth: 1,
379+
glyphs: [],
380+
});
381+
});
382+
383+
it('returns fields for an array of mixed (including objects)', function () {
384+
const result = getFieldsFromSchema({
385+
bsonType: 'object',
386+
properties: {
387+
todos: {
388+
bsonType: 'array',
389+
items: {
390+
anyOf: [
391+
{
392+
bsonType: 'object',
393+
properties: {
394+
title: { bsonType: 'string' },
395+
completed: { bsonType: 'boolean' },
396+
},
397+
},
398+
{ bsonType: 'string' },
399+
],
400+
},
401+
},
402+
},
403+
});
404+
expect(result).to.deep.equal([
405+
{ name: 'todos', type: '[]', depth: 0, glyphs: [] },
406+
{ name: 'title', type: 'string', depth: 1, glyphs: [] },
407+
{ name: 'completed', type: 'boolean', depth: 1, glyphs: [] },
408+
]);
409+
});
410+
});
411+
});

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ function getFieldTypeDisplay(bsonTypes: string[]) {
122122
);
123123
}
124124

125-
const getFieldsFromSchema = (
125+
export const getFieldsFromSchema = (
126126
jsonSchema: MongoDBJSONSchema,
127127
depth = 0
128128
): NodeProps['fields'] => {

0 commit comments

Comments
 (0)