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