Skip to content

Commit 426857f

Browse files
authored
Merge pull request #1 from Moumouls/pr-migrations-moumouls
fix: test & review
2 parents d3ba3bb + 0e37d39 commit 426857f

File tree

6 files changed

+58
-69
lines changed

6 files changed

+58
-69
lines changed

spec/DefinedSchemas.spec.js

Lines changed: 27 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,15 @@ describe('DefinedSchemas', () => {
1414
let config;
1515
beforeEach(async () => {
1616
jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000000;
17-
1817
config = Config.get('test');
19-
await config.database.adapter.deleteAllClasses();
18+
if (config) {
19+
await config.database.adapter.deleteAllClasses();
20+
}
2021
});
2122
afterAll(async () => {
22-
await config.database.adapter.deleteAllClasses();
23+
if (config) {
24+
await config.database.adapter.deleteAllClasses();
25+
}
2326
});
2427

2528
describe('Fields', () => {
@@ -544,21 +547,17 @@ describe('DefinedSchemas', () => {
544547
expect(schema.className).toEqual('Test');
545548

546549
const schemas = await Parse.Schema.all();
547-
expect(schemas.length).toEqual(3);
550+
// Role could be flaky since all system classes are not ensured
551+
// at start up by the DefinedSchema system
552+
expect(schemas.filter(({ className }) => className !== '_Role').length).toEqual(3);
548553

549-
try {
550-
await new Parse.Schema('TheNewTest').save();
551-
fail('TheNewTest.save() should have failed');
552-
} catch (e) {
553-
expect(e.message).toContain('Cannot perform this operation when schemas options is used.');
554-
}
554+
await expectAsync(new Parse.Schema('TheNewTest').save()).toBeRejectedWithError(
555+
'Cannot perform this operation when schemas options is used.'
556+
);
555557

556-
try {
557-
await new Parse.Schema('_User').update();
558-
fail('_User.update() should have failed');
559-
} catch (e) {
560-
expect(e.message).toContain('Cannot perform this operation when schemas options is used.');
561-
}
558+
await expectAsync(new Parse.Schema('_User').update()).toBeRejectedWithError(
559+
'Cannot perform this operation when schemas options is used.'
560+
);
562561
});
563562
it('should only enable delete class endpoint since', async () => {
564563
await reconfigureServer({
@@ -574,34 +573,26 @@ describe('DefinedSchemas', () => {
574573
expect(schemas.length).toEqual(3);
575574
});
576575
it('should run beforeMigration before execution of DefinedSchemas', async () => {
577-
let before = false;
578-
const server = await reconfigureServer({
576+
const config = {
579577
schema: {
580578
definitions: [{ className: '_User' }, { className: 'Test' }],
581-
beforeMigration: async () => {
582-
expect(before).toEqual(false);
583-
before = true;
584-
},
579+
beforeMigration: async () => {},
585580
},
586-
});
587-
before = true;
588-
expect(before).toEqual(true);
589-
expect(server).toBeDefined();
581+
};
582+
const spy = spyOn(config.schema, 'beforeMigration');
583+
await reconfigureServer(config);
584+
expect(spy).toHaveBeenCalledTimes(1);
590585
});
591586
it('should run afterMigration after execution of DefinedSchemas', async () => {
592-
let before = false;
593-
const server = await reconfigureServer({
587+
const config = {
594588
schema: {
595589
definitions: [{ className: '_User' }, { className: 'Test' }],
596-
afterMigration: async () => {
597-
expect(before).toEqual(false);
598-
before = true;
599-
},
590+
afterMigration: async () => {},
600591
},
601-
});
602-
before = true;
603-
expect(before).toEqual(true);
604-
expect(server).toBeDefined();
592+
};
593+
const spy = spyOn(config.schema, 'afterMigration');
594+
await reconfigureServer(config);
595+
expect(spy).toHaveBeenCalledTimes(1);
605596
});
606597

607598
it('should use logger in case of error', async () => {

src/Adapters/Storage/Mongo/MongoSchemaCollection.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import MongoCollection from './MongoCollection';
22
import Parse from 'parse/node';
3-
import _ from 'lodash'
3+
import _ from 'lodash';
44

55
function mongoFieldToParseSchemaField(type) {
66
if (type[0] === '*') {
@@ -277,9 +277,8 @@ class MongoSchemaCollection {
277277
}
278278

279279
async updateFieldOptions(className: string, fieldName: string, fieldType: any) {
280-
const fieldOptions = _.cloneDeep(fieldType);
281-
delete fieldOptions.type
282-
delete fieldOptions.targetClass
280+
// eslint-disable-next-line no-unused-vars
281+
const { type, targetClass, ...fieldOptions } = fieldType;
283282
await this.upsertSchema(
284283
className,
285284
{ [fieldName]: { $exists: true } },

src/Config.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
SecurityOptions,
1414
SchemaOptions,
1515
} from './Options/Definitions';
16-
import { isBoolean, isString, isArray } from 'lodash';
16+
import { isBoolean, isString } from 'lodash';
1717

1818
function removeTrailingSlash(str) {
1919
if (!str) {
@@ -133,12 +133,13 @@ export class Config {
133133
}
134134

135135
static validateSchemaOptions(schema: SchemaOptions) {
136+
if (!schema) return;
136137
if (Object.prototype.toString.call(schema) !== '[object Object]') {
137138
throw 'Parse Server option schema must be an object.';
138139
}
139140
if (schema.definitions === undefined) {
140141
schema.definitions = SchemaOptions.definitions.default;
141-
} else if (!isArray(schema.definitions)) {
142+
} else if (!Array.isArray(schema.definitions)) {
142143
throw 'Parse Server option schema.definitions must be an array.';
143144
}
144145
if (schema.strict === undefined) {
@@ -164,12 +165,12 @@ export class Config {
164165
if (schema.beforeMigration === undefined) {
165166
schema.beforeMigration = null;
166167
} else if (schema.beforeMigration !== null && typeof schema.beforeMigration !== 'function') {
167-
throw 'Parse Server option schema.beforeMigration must be a boolean.';
168+
throw 'Parse Server option schema.beforeMigration must be a function.';
168169
}
169170
if (schema.afterMigration === undefined) {
170171
schema.afterMigration = null;
171172
} else if (schema.afterMigration !== null && typeof schema.afterMigration !== 'function') {
172-
throw 'Parse Server option schema.afterMigration must be a boolean.';
173+
throw 'Parse Server option schema.afterMigration must be a function.';
173174
}
174175
}
175176

src/Controllers/SchemaController.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,11 +1116,10 @@ export default class SchemaController {
11161116
// we can safely return
11171117
if (isValidation || _.isEqual(expectedType, type)) {
11181118
return undefined;
1119-
} else {
1120-
// Field options are may be changed
1121-
// ensure to have an update to date schema field
1122-
return this._dbAdapter.updateFieldOptions(className, fieldName, type);
11231119
}
1120+
// Field options are may be changed
1121+
// ensure to have an update to date schema field
1122+
return this._dbAdapter.updateFieldOptions(className, fieldName, type);
11241123
}
11251124

11261125
return this._dbAdapter

src/Routers/SchemasRouter.js

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ function getOneSchema(req) {
3636
}
3737

3838
const checkIfDefinedSchemasIsUsed = req => {
39-
if (req.config && req.config.schema && req.config.schema.lockSchemas === true) {
39+
if (req.config?.schema?.lockSchemas === true) {
4040
throw new Parse.Error(
4141
Parse.Error.OPERATION_FORBIDDEN,
4242
'Cannot perform this operation when schemas options is used.'
@@ -46,27 +46,27 @@ const checkIfDefinedSchemasIsUsed = req => {
4646

4747
export const internalCreateSchema = async (className, body, config) => {
4848
const controller = await config.database.loadSchema({ clearCache: true });
49+
const response = await controller.addClassIfNotExists(
50+
className,
51+
body.fields,
52+
body.classLevelPermissions,
53+
body.indexes
54+
);
4955
return {
50-
response: await controller.addClassIfNotExists(
51-
className,
52-
body.fields,
53-
body.classLevelPermissions,
54-
body.indexes
55-
),
56+
response,
5657
};
5758
};
5859

5960
export const internalUpdateSchema = async (className, body, config) => {
6061
const controller = await config.database.loadSchema({ clearCache: true });
61-
return {
62-
response: await controller.updateClass(
63-
className,
64-
body.fields || {},
65-
body.classLevelPermissions,
66-
body.indexes,
67-
config.database
68-
),
69-
};
62+
const response = await controller.updateClass(
63+
className,
64+
body.fields || {},
65+
body.classLevelPermissions,
66+
body.indexes,
67+
config.database
68+
);
69+
return { response };
7070
};
7171

7272
async function createSchema(req) {

src/SchemaMigrations/DefinedSchemas.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ export class DefinedSchemas {
1818
this.localSchemas = [];
1919
this.config = Config.get(config.appId);
2020
this.schemaOptions = schemaOptions;
21-
2221
if (schemaOptions && schemaOptions.definitions) {
2322
if (!Array.isArray(schemaOptions.definitions)) {
2423
throw `"schema.definitions" must be an array of schemas`;
@@ -66,13 +65,13 @@ export class DefinedSchemas {
6665
async execute() {
6766
try {
6867
logger.info('Running Migrations');
69-
if (this.schemaOptions && this.schemaOptions.beforeMigration) {
68+
if (this.schemaOptions?.beforeMigration) {
7069
await Promise.resolve(this.schemaOptions.beforeMigration());
7170
}
7271

7372
await this.executeMigrations();
7473

75-
if (this.schemaOptions && this.schemaOptions.afterMigration) {
74+
if (this.schemaOptions?.afterMigration) {
7675
await Promise.resolve(this.schemaOptions.afterMigration());
7776
}
7877

@@ -151,8 +150,8 @@ export class DefinedSchemas {
151150
}
152151

153152
// Required for testing purpose
154-
async wait(time) {
155-
await new Promise(resolve => setTimeout(resolve, time));
153+
wait(time) {
154+
return new Promise(resolve => setTimeout(resolve, time));
156155
}
157156

158157
async enforceCLPForNonProvidedClass(): void {

0 commit comments

Comments
 (0)