Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 147 additions & 0 deletions packages/compass-data-modeling/src/store/diagram.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
openDiagram,
redoEdit,
undoEdit,
selectFieldsForCurrentModel,
} from './diagram';
import type {
Edit,
Expand Down Expand Up @@ -295,4 +296,150 @@ describe('Data Modeling store', function () {
expect(diagramAfterRedo.edits[0]).to.deep.include(loadedDiagram.edits[0]);
expect(diagramAfterRedo.edits[1]).to.deep.include(edit);
});

describe('selectFieldsForCurrentModel', function () {
it('should select fields from a flat schema', function () {
const edits: MongoDBDataModelDescription['edits'] = [
{
id: 'first-edit',
timestamp: new Date().toISOString(),
type: 'SetModel',
model: {
collections: [
{
ns: 'collection1',
indexes: [],
displayPosition: [0, 0],
shardKey: {},
jsonSchema: {
bsonType: 'object',
properties: {
field1: { bsonType: 'string' },
field2: { bsonType: 'int' },
field3: { bsonType: 'int' },
},
},
},
],
relationships: [],
},
},
];
const selectedFields = selectFieldsForCurrentModel(edits);

expect(selectedFields).to.deep.equal({
collection1: [['field1'], ['field2'], ['field3']],
});
});

it('should select fields from a nested schema', function () {
const edits: MongoDBDataModelDescription['edits'] = [
{
id: 'first-edit',
timestamp: new Date().toISOString(),
type: 'SetModel',
model: {
collections: [
{
ns: 'collection1',
indexes: [],
displayPosition: [0, 0],
shardKey: {},
jsonSchema: {
bsonType: 'object',
properties: {
prop1: { bsonType: 'string' },
// Deeply nested properties
prop2: {
bsonType: 'object',
properties: {
prop2A: { bsonType: 'string' },
prop2B: {
bsonType: 'object',
properties: {
prop2B1: { bsonType: 'string' },
prop2B2: { bsonType: 'int' },
},
},
},
},
// Array of objects
prop3: {
bsonType: 'array',
items: {
bsonType: 'object',
properties: {
prop3A: { bsonType: 'string' },
},
},
Comment on lines +369 to +374
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want to add a case where items is an array? Seems possible based on the implementation

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, let me add it!

},
// Mixed type with objects
prop4: {
anyOf: [
{
bsonType: 'object',
properties: {
prop4A: { bsonType: 'string' },
},
},
{
bsonType: 'object',
properties: {
prop4B: { bsonType: 'string' },
},
},
],
},
// Mixed array with objects
prop5: {
bsonType: 'array',
items: [
{
bsonType: 'object',
properties: {
prop5A: { bsonType: 'string' },
},
},
{
bsonType: 'object',
properties: {
prop5B: { bsonType: 'number' },
},
},
],
},
},
},
},
],
relationships: [],
},
},
];
const selectedFields = selectFieldsForCurrentModel(edits);

expect(selectedFields).to.have.property('collection1');
expect(selectedFields.collection1).to.deep.include(['prop1']);
expect(selectedFields.collection1).to.deep.include(['prop2']);
expect(selectedFields.collection1).to.deep.include(['prop2', 'prop2A']);
expect(selectedFields.collection1).to.deep.include([
'prop2',
'prop2B',
'prop2B1',
]);
expect(selectedFields.collection1).to.deep.include([
'prop2',
'prop2B',
'prop2B2',
]);
expect(selectedFields.collection1).to.deep.include(['prop3']);
expect(selectedFields.collection1).to.deep.include(['prop3', 'prop3A']);
expect(selectedFields.collection1).to.deep.include(['prop4']);
expect(selectedFields.collection1).to.deep.include(['prop4', 'prop4A']);
expect(selectedFields.collection1).to.deep.include(['prop4', 'prop4B']);
expect(selectedFields.collection1).to.deep.include(['prop5']);
expect(selectedFields.collection1).to.deep.include(['prop5', 'prop5A']);
expect(selectedFields.collection1).to.deep.include(['prop5', 'prop5B']);
});
});
});
13 changes: 13 additions & 0 deletions packages/compass-data-modeling/src/store/diagram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,19 @@ function extractFields(
parentKey?: string[],
fields: string[][] = []
) {
if ('anyOf' in parentSchema && parentSchema.anyOf) {
for (const schema of parentSchema.anyOf) {
extractFields(schema, parentKey, fields);
}
}
if ('items' in parentSchema && parentSchema.items) {
const items = Array.isArray(parentSchema.items)
? parentSchema.items
: [parentSchema.items];
for (const schema of items) {
extractFields(schema, parentKey, fields);
}
}
if ('properties' in parentSchema && parentSchema.properties) {
for (const [key, value] of Object.entries(parentSchema.properties)) {
const fullKey = parentKey ? [...parentKey, key] : [key];
Expand Down
Loading