From 3b92fa1ca9e8889127a32eba913d68309397ca2c Mon Sep 17 00:00:00 2001 From: Manuel <5673677+mtrezza@users.noreply.github.com> Date: Thu, 13 Jan 2022 03:04:49 +0100 Subject: [PATCH] fix: schema cache not cleared in some cases (#7771) --- spec/schemas.spec.js | 87 ++++++++++++++++++++++++++++++++++++ src/Routers/SchemasRouter.js | 2 +- 2 files changed, 88 insertions(+), 1 deletion(-) diff --git a/spec/schemas.spec.js b/spec/schemas.spec.js index 5180b36ca5..52c02811f5 100644 --- a/spec/schemas.spec.js +++ b/spec/schemas.spec.js @@ -5,6 +5,7 @@ const dd = require('deep-diff'); const Config = require('../lib/Config'); const request = require('../lib/request'); const TestUtils = require('../lib/TestUtils'); +const SchemaController = require('../lib/Controllers/SchemaController').SchemaController; let config; @@ -239,6 +240,52 @@ describe('schemas', () => { }); }); + it('ensure refresh cache after creating a class', async done => { + spyOn(SchemaController.prototype, 'reloadData').and.callFake(() => Promise.resolve()); + await request({ + url: 'http://localhost:8378/1/schemas', + method: 'POST', + headers: masterKeyHeaders, + json: true, + body: { + className: 'A', + }, + }); + const response = await request({ + url: 'http://localhost:8378/1/schemas', + method: 'GET', + headers: masterKeyHeaders, + json: true, + }); + const expected = { + results: [ + userSchema, + roleSchema, + { + className: 'A', + fields: { + //Default fields + ACL: { type: 'ACL' }, + createdAt: { type: 'Date' }, + updatedAt: { type: 'Date' }, + objectId: { type: 'String' }, + }, + classLevelPermissions: defaultClassLevelPermissions, + }, + ], + }; + expect( + response.data.results + .sort((s1, s2) => s1.className.localeCompare(s2.className)) + .map(s => { + const withoutIndexes = Object.assign({}, s); + delete withoutIndexes.indexes; + return withoutIndexes; + }) + ).toEqual(expected.results.sort((s1, s2) => s1.className.localeCompare(s2.className))); + done(); + }); + it('responds with a single schema', done => { const obj = hasAllPODobject(); obj.save().then(() => { @@ -1507,6 +1554,46 @@ describe('schemas', () => { }); }); + it('ensure refresh cache after deleting a class', async done => { + config = Config.get('test'); + spyOn(config.schemaCache, 'del').and.callFake(() => {}); + spyOn(SchemaController.prototype, 'reloadData').and.callFake(() => Promise.resolve()); + await request({ + url: 'http://localhost:8378/1/schemas', + method: 'POST', + headers: masterKeyHeaders, + json: true, + body: { + className: 'A', + }, + }); + await request({ + method: 'DELETE', + url: 'http://localhost:8378/1/schemas/A', + headers: masterKeyHeaders, + json: true, + }); + const response = await request({ + url: 'http://localhost:8378/1/schemas', + method: 'GET', + headers: masterKeyHeaders, + json: true, + }); + const expected = { + results: [userSchema, roleSchema], + }; + expect( + response.data.results + .sort((s1, s2) => s1.className.localeCompare(s2.className)) + .map(s => { + const withoutIndexes = Object.assign({}, s); + delete withoutIndexes.indexes; + return withoutIndexes; + }) + ).toEqual(expected.results.sort((s1, s2) => s1.className.localeCompare(s2.className))); + done(); + }); + it('deletes collections including join tables', done => { const obj = new Parse.Object('MyClass'); obj.set('data', 'data'); diff --git a/src/Routers/SchemasRouter.js b/src/Routers/SchemasRouter.js index 54f73ceacc..1b72b93a68 100644 --- a/src/Routers/SchemasRouter.js +++ b/src/Routers/SchemasRouter.js @@ -16,7 +16,7 @@ function classNameMismatchResponse(bodyClass, pathClass) { function getAllSchemas(req) { return req.config.database .loadSchema({ clearCache: true }) - .then(schemaController => schemaController.getAllClasses(true)) + .then(schemaController => schemaController.getAllClasses({ clearCache: true })) .then(schemas => ({ response: { results: schemas } })); }