Skip to content

Commit

Permalink
fix(dumper): ignore mongodb fields that includes column and log warni…
Browse files Browse the repository at this point in the history
…ng (#652)
  • Loading branch information
SteveBunlon authored Dec 7, 2023
1 parent 22707af commit e940447
Show file tree
Hide file tree
Showing 7 changed files with 258 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/services/dumpers/abstract-dumper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default abstract class AbstractDumper {

private readonly fs;

private readonly logger: Logger;
protected readonly logger: Logger;

private readonly chalk: Chalk;

Expand Down
51 changes: 50 additions & 1 deletion src/services/dumpers/agent-nodejs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export default class AgentNodeJs extends AbstractDumper {
lodash,
strings,
toValidPackageName,
logger,
} = context;

assertPresent({
Expand All @@ -54,6 +55,7 @@ export default class AgentNodeJs extends AbstractDumper {
lodash,
strings,
toValidPackageName,
logger,
});

super(context);
Expand Down Expand Up @@ -249,6 +251,48 @@ export default class AgentNodeJs extends AbstractDumper {
);
}

private removeNonCompliantNestedFields(collectionName: string, fieldsDefinition: any) {

Check warning on line 254 in src/services/dumpers/agent-nodejs.ts

View workflow job for this annotation

GitHub Actions / Lint

Unexpected any. Specify a different type
if (typeof fieldsDefinition !== 'string') {
if (Array.isArray(fieldsDefinition)) {
fieldsDefinition.forEach(fieldDefinition => {
this.removeNonCompliantNestedFields(collectionName, fieldDefinition);
});
} else {
Object.entries(fieldsDefinition).forEach(([key, fieldDefinition]) => {
if (key.includes(':')) {
this.logger.warn(
`Ignoring field ${key} from collection ${collectionName} as it contains column and is not valid.`,
);

delete fieldsDefinition[key];
} else {
this.removeNonCompliantNestedFields(collectionName, fieldDefinition);
}
});
}
}
}

private removeNonCompliantFields(collectionName, fieldsDefinition) {
const compliantFieldsDefinition = JSON.parse(JSON.stringify(fieldsDefinition));

return compliantFieldsDefinition.reduce((correctFieldsDefinitions, definition) => {
if (definition.name.includes(':')) {
this.logger.warn(
`Ignoring field ${definition.name} from collection ${collectionName} as it contains column and is not valid.`,
);
} else {
correctFieldsDefinitions.push(definition);

if (definition.type && typeof definition.type !== 'string') {
this.removeNonCompliantNestedFields(collectionName, definition.type);
}
}

return correctFieldsDefinitions;
}, []);
}

private computeModelsConfiguration(language: Language, schema: any): Array<ModelConfiguration> {

Check warning on line 296 in src/services/dumpers/agent-nodejs.ts

View workflow job for this annotation

GitHub Actions / Lint

Unexpected any. Specify a different type
const collectionNamesSorted = Object.keys(schema).sort();

Expand All @@ -264,10 +308,15 @@ export default class AgentNodeJs extends AbstractDumper {
};
});

const compliantFieldsDefinition = this.removeNonCompliantFields(
collectionName,
fieldsDefinition,
);

return {
modelName: this.strings.transformToCamelCaseSafeString(collectionName),
collectionName,
fields: fieldsDefinition,
fields: compliantFieldsDefinition,
timestamps: options.timestamps,
modelFileName,
modelPath,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{
"persons": {
"fields": [
{
"name": "name:column",
"type": "String"
},
{
"name": "very",
"type": {
"deep": {
"model": {
"arrayOfNumber": [
"Number"
],
"arrayMixed": [
"Object"
],
"arrayOfObjectIds": [
"Mongoose.Schema.Types.ObjectId"
],
"arrayWithComplexObject": [
{
"_id": "Mongoose.Schema.Types.ObjectId",
"name": "String",
"propGroup": {
"answer:column": "Boolean",
"date": "Date",
"sentence": "String",
"number": "Number"
}
}
],
"arrayOfComplexObjects": [
{
"_id": "Mongoose.Schema.Types.ObjectId",
"propGroup": {
"answer": "Boolean",
"date": "Date",
"sentence": "String",
"number": "Number"
},
"so:column": {
"nested": {
"arrayMixed": [
"Object"
],
"arrayOfNumber": [
"Number"
]
}
}
}
]
}
}
}
}
],
"options": {
"timestamps": false
},
"primaryKeys": [
"_id"
],
"references": []
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import rimraf from 'rimraf';
import defaultPlan from '../../../../src/context/plan';
import AgentNodeJsDumper from '../../../../src/services/dumpers/agent-nodejs';
import languages from '../../../../src/utils/languages';
import deepNestedColumn from '../../analyzer/expected/mongo/db-analysis-output/deep-nested-fields-column.expected.json';
import deepNested from '../../analyzer/expected/mongo/db-analysis-output/deep-nested-fields.expected.json';
import hasMany from '../../analyzer/expected/mongo/db-analysis-output/hasmany.expected.json';
import manyObjectIdFields from '../../analyzer/expected/mongo/db-analysis-output/many-objectid-fields.expected.json';
Expand Down Expand Up @@ -36,9 +37,16 @@ describe('services > dumpers > agentNodejsDumper > mongoose models', () => {
language,
};

const injectedContext = Context.execute(defaultPlan);
const injectedContext = Context.execute(defaultPlan) as any;

Check warning on line 40 in test/services/dumpers/agent-nodejs/agent-nodejs-dumper-mongoose-models.test.ts

View workflow job for this annotation

GitHub Actions / Lint

Unexpected any. Specify a different type

const loggerWarnSpy = jest.spyOn(injectedContext.logger, 'warn');

const dumper = new AgentNodeJsDumper(injectedContext);
await dumper.dump(config, schema);

return {
loggerWarnSpy,
};
}

describe.each([languages.Javascript, languages.Typescript])('language: $name', language => {
Expand Down Expand Up @@ -98,6 +106,14 @@ describe('services > dumpers > agentNodejsDumper > mongoose models', () => {
expectedFilePath: `${__dirname}/expected/${language.name}/mongo-models/sub-documents-with-ids.expected.${language.fileExtension}`,
},
},
{
name: 'should not dump any fields containing column',
schema: deepNestedColumn,
file: {
model: 'persons',
expectedFilePath: `${__dirname}/expected/${language.name}/mongo-models/deep-nested-column.expected.${language.fileExtension}`,
},
},
];

it.each(testCases)(`$name`, async ({ schema, file }) => {
Expand All @@ -115,6 +131,25 @@ describe('services > dumpers > agentNodejsDumper > mongoose models', () => {

expect(generatedFile).toStrictEqual(expectedFile);
});

it('should warn information when a field containing column has been ignored', async () => {
expect.assertions(4);

rimraf.sync(`${appRoot}/test-output/${language.name}/mongodb/`);

const { loggerWarnSpy } = await dump(language, deepNestedColumn);

expect(loggerWarnSpy).toHaveBeenCalledTimes(3);
expect(loggerWarnSpy).toHaveBeenCalledWith(
'Ignoring field name:column from collection persons as it contains column and is not valid.',
);
expect(loggerWarnSpy).toHaveBeenCalledWith(
'Ignoring field answer:column from collection persons as it contains column and is not valid.',
);
expect(loggerWarnSpy).toHaveBeenCalledWith(
'Ignoring field so:column from collection persons as it contains column and is not valid.',
);
});
});
});

Expand Down
6 changes: 3 additions & 3 deletions test/services/dumpers/agent-nodejs/agent-nodejs.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ describe('services > dumpers > AgentNodeJs', () => {
collectionA: {
fields: [
{
field: 'aField',
name: 'aField',
ref: 'a-collection',
},
],
Expand Down Expand Up @@ -744,7 +744,7 @@ describe('services > dumpers > AgentNodeJs', () => {
collectionName: 'collectionA',
fields: [
{
field: 'aField',
name: 'aField',
ref: 'a-collection',
},
],
Expand Down Expand Up @@ -785,7 +785,7 @@ describe('services > dumpers > AgentNodeJs', () => {
collectionName: 'collectionA',
fields: [
{
field: 'aField',
name: 'aField',
ref: 'a-collectioncamelCased',
},
],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
const Mongoose = require('mongoose');

const schema = new Mongoose.Schema({
very: {
deep: {
model: {
arrayOfNumber: [Number],
arrayMixed: [Object],
arrayOfObjectIds: [Mongoose.Schema.Types.ObjectId],
arrayWithComplexObject: [{
name: String,
propGroup: {
date: Date,
sentence: String,
number: Number,
},
}],
arrayOfComplexObjects: [{
propGroup: {
answer: Boolean,
date: Date,
sentence: String,
number: Number,
},
}],
},
},
},
}, {
timestamps: false,
});

module.exports = {
collectionName: 'persons',
modelName: 'persons',
schema,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import Mongoose from 'mongoose';

interface PersonsInterface {
very: {
deep: {
model: {
arrayOfNumber: Array<number>;
arrayMixed: Array<object>;
arrayOfObjectIds: Array<Mongoose.Types.ObjectId>;
arrayWithComplexObject: Array<{
_id: Mongoose.Types.ObjectId;
name: string;
propGroup: {
date: Date;
sentence: string;
number: number;
};
}>;
arrayOfComplexObjects: Array<{
_id: Mongoose.Types.ObjectId;
propGroup: {
answer: boolean;
date: Date;
sentence: string;
number: number;
};
}>;
};
};
};
}

const personsSchema = new Mongoose.Schema({
very: {
deep: {
model: {
arrayOfNumber: [Number],
arrayMixed: [Object],
arrayOfObjectIds: [Mongoose.Schema.Types.ObjectId],
arrayWithComplexObject: [{
name: String,
propGroup: {
date: Date,
sentence: String,
number: Number,
},
}],
arrayOfComplexObjects: [{
propGroup: {
answer: Boolean,
date: Date,
sentence: String,
number: Number,
},
}],
},
},
},
}, {
timestamps: false,
});

export { PersonsInterface, personsSchema };

0 comments on commit e940447

Please sign in to comment.