From 512ca48680ee1ebc1844af7bda345451fbdc5dc1 Mon Sep 17 00:00:00 2001 From: Azri Kahar <42867097+azrikahar@users.noreply.github.com> Date: Thu, 2 Mar 2023 15:23:13 +0800 Subject: [PATCH] Allow null for related_collection in applyJoiSchema (#17665) * allow null for related_collection * Add M2A to schema tests * Trigger testing for all vendors * Standardize naming convention * Update deleted collections assertion * Fix typo * Revert testing for all vendors --------- Co-authored-by: ian --- api/src/utils/validate-diff.ts | 2 +- tests-blackbox/common/functions.ts | 2 +- tests-blackbox/routes/schema/schema.seed.ts | 46 +++++++ tests-blackbox/routes/schema/schema.test.ts | 132 +++++++++++++------- 4 files changed, 136 insertions(+), 46 deletions(-) diff --git a/api/src/utils/validate-diff.ts b/api/src/utils/validate-diff.ts index 1c1f5dad02..2cf4b77049 100644 --- a/api/src/utils/validate-diff.ts +++ b/api/src/utils/validate-diff.ts @@ -38,7 +38,7 @@ const applyJoiSchema = Joi.object({ Joi.object({ collection: Joi.string().required(), field: Joi.string().required(), - related_collection: Joi.string(), + related_collection: Joi.string().allow(null), diff: Joi.array().items(deepDiffSchema).required(), }) ) diff --git a/tests-blackbox/common/functions.ts b/tests-blackbox/common/functions.ts index 15dbb499df..42897279d4 100644 --- a/tests-blackbox/common/functions.ts +++ b/tests-blackbox/common/functions.ts @@ -548,7 +548,7 @@ export async function CreateFieldM2A(vendor: string, options: OptionsCreateField otherMeta: {}, otherSchema: {}, relationSchema: null, - otherRelationSchema: { + itemRelationSchema: { on_delete: 'SET NULL', }, }; diff --git a/tests-blackbox/routes/schema/schema.seed.ts b/tests-blackbox/routes/schema/schema.seed.ts index 6389d89ece..0d092b33ca 100644 --- a/tests-blackbox/routes/schema/schema.seed.ts +++ b/tests-blackbox/routes/schema/schema.seed.ts @@ -5,6 +5,7 @@ import { DeleteCollection, PRIMARY_KEY_TYPES, CreateFieldM2M, + CreateFieldM2A, CreateFieldM2O, CreateFieldO2M, DeleteField, @@ -21,6 +22,10 @@ export const collectionM2M = 'test_schema_m2m'; export const collectionM2M2 = 'test_schema_m2m2'; export const junctionM2M = 'test_schema_jm2m'; export const junctionM2M2 = 'test_schema_jm2m2'; +export const collectionM2A = 'test_schema_m2a'; +export const collectionM2A2 = 'test_schema_m2a2'; +export const junctionM2A = 'test_schema_jm2a'; +export const junctionM2A2 = 'test_schema_jm2a2'; export const collectionSelf = 'test_schema_self'; export const junctionSelfM2M = 'test_schema_jm2m_self'; export const tempTestCollection = 'temp_test_collection'; @@ -49,6 +54,10 @@ export const deleteAllCollections = async (vendor: string, pkType: PrimaryKeyTyp const localCollectionM2M2 = `${collectionM2M2}_${pkType}${suffix}`; const localJunctionAllM2M = `${junctionM2M}_${pkType}${suffix}`; const localJunctionM2MM2M2 = `${junctionM2M2}_${pkType}${suffix}`; + const localCollectionM2A = `${collectionM2A}_${pkType}${suffix}`; + const localCollectionM2A2 = `${collectionM2A2}_${pkType}${suffix}`; + const localJunctionAllM2A = `${junctionM2A}_${pkType}${suffix}`; + const localJunctionM2AM2A2 = `${junctionM2A2}_${pkType}${suffix}`; const localCollectionM2O = `${collectionM2O}_${pkType}${suffix}`; const localCollectionM2O2 = `${collectionM2O2}_${pkType}${suffix}`; const localCollectionO2M = `${collectionO2M}_${pkType}${suffix}`; @@ -67,6 +76,10 @@ export const deleteAllCollections = async (vendor: string, pkType: PrimaryKeyTyp await DeleteCollection(vendor, { collection: localJunctionAllM2M }); await DeleteCollection(vendor, { collection: localCollectionM2M2 }); await DeleteCollection(vendor, { collection: localCollectionM2M }); + await DeleteCollection(vendor, { collection: localJunctionM2AM2A2 }); + await DeleteCollection(vendor, { collection: localJunctionAllM2A }); + await DeleteCollection(vendor, { collection: localCollectionM2A2 }); + await DeleteCollection(vendor, { collection: localCollectionM2A }); await DeleteCollection(vendor, { collection: localCollectionAll }); await DeleteCollection(vendor, { collection: localCollectionM2O }); await DeleteCollection(vendor, { collection: localCollectionM2O2 }); @@ -86,6 +99,10 @@ export const seedDBStructure = () => { const localCollectionM2M2 = `${collectionM2M2}_${pkType}${suffix}`; const localJunctionAllM2M = `${junctionM2M}_${pkType}${suffix}`; const localJunctionM2MM2M2 = `${junctionM2M2}_${pkType}${suffix}`; + const localCollectionM2A = `${collectionM2A}_${pkType}${suffix}`; + const localCollectionM2A2 = `${collectionM2A2}_${pkType}${suffix}`; + const localJunctionAllM2A = `${junctionM2A}_${pkType}${suffix}`; + const localJunctionM2AM2A2 = `${junctionM2A2}_${pkType}${suffix}`; const localCollectionM2O = `${collectionM2O}_${pkType}${suffix}`; const localCollectionM2O2 = `${collectionM2O2}_${pkType}${suffix}`; const localCollectionO2M = `${collectionO2M}_${pkType}${suffix}`; @@ -142,6 +159,35 @@ export const seedDBStructure = () => { primaryKeyType: pkType, }); + // Create M2A collection + await CreateCollection(vendor, { + collection: localCollectionM2A, + primaryKeyType: pkType, + }); + + // Create nested M2A collection + await CreateCollection(vendor, { + collection: localCollectionM2A2, + primaryKeyType: pkType, + }); + + // Create M2A relationships + await CreateFieldM2A(vendor, { + collection: localCollectionAll, + field: 'all_m2a', + junctionCollection: localJunctionAllM2A, + relatedCollections: [localCollectionM2A], + primaryKeyType: pkType, + }); + + await CreateFieldM2A(vendor, { + collection: localCollectionM2A, + field: 'm2a_m2a2', + junctionCollection: localJunctionM2AM2A2, + relatedCollections: [localCollectionM2A2], + primaryKeyType: pkType, + }); + // Create M2O collection await CreateCollection(vendor, { collection: localCollectionM2O, diff --git a/tests-blackbox/routes/schema/schema.test.ts b/tests-blackbox/routes/schema/schema.test.ts index 813fd2801c..d8a4c30427 100644 --- a/tests-blackbox/routes/schema/schema.test.ts +++ b/tests-blackbox/routes/schema/schema.test.ts @@ -4,6 +4,8 @@ import vendors from '@common/get-dbs-to-test'; import * as common from '@common/index'; import { collectionAll, + collectionM2A, + collectionM2A2, collectionM2M, collectionM2M2, collectionM2O, @@ -12,6 +14,8 @@ import { collectionO2M2, collectionSelf, deleteAllCollections, + junctionM2A, + junctionM2A2, junctionM2M, junctionM2M2, junctionSelfM2M, @@ -502,6 +506,7 @@ function parseSnapshot(vendor: string, snapshot: any) { async function assertCollectionsDeleted(vendor: string, pkType: PrimaryKeyType) { for (const setDefaultValues of [false, true]) { const suffix = setDefaultValues ? '2' : ''; + const responses = []; // Setup const localCollectionAll = `${collectionAll}_${pkType}${suffix}`; @@ -509,6 +514,10 @@ async function assertCollectionsDeleted(vendor: string, pkType: PrimaryKeyType) const localCollectionM2M2 = `${collectionM2M2}_${pkType}${suffix}`; const localJunctionAllM2M = `${junctionM2M}_${pkType}${suffix}`; const localJunctionM2MM2M2 = `${junctionM2M2}_${pkType}${suffix}`; + const localCollectionM2A = `${collectionM2A}_${pkType}${suffix}`; + const localCollectionM2A2 = `${collectionM2A2}_${pkType}${suffix}`; + const localJunctionAllM2A = `${junctionM2A}_${pkType}${suffix}`; + const localJunctionM2AM2A2 = `${junctionM2A2}_${pkType}${suffix}`; const localCollectionM2O = `${collectionM2O}_${pkType}${suffix}`; const localCollectionM2O2 = `${collectionM2O2}_${pkType}${suffix}`; const localCollectionO2M = `${collectionO2M}_${pkType}${suffix}`; @@ -516,51 +525,86 @@ async function assertCollectionsDeleted(vendor: string, pkType: PrimaryKeyType) const localCollectionSelf = `${collectionSelf}_${pkType}${suffix}`; const localJunctionSelfM2M = `${junctionSelfM2M}_${pkType}${suffix}`; - const response = await request(getUrl(vendor)) - .get(`/items/${localJunctionSelfM2M}`) - .set('Authorization', `Bearer ${common.USER.ADMIN.TOKEN}`); - const response2 = await request(getUrl(vendor)) - .get(`/items/${localCollectionSelf}`) - .set('Authorization', `Bearer ${common.USER.ADMIN.TOKEN}`); - const response3 = await request(getUrl(vendor)) - .get(`/items/${localCollectionO2M2}`) - .set('Authorization', `Bearer ${common.USER.ADMIN.TOKEN}`); - const response4 = await request(getUrl(vendor)) - .get(`/items/${localCollectionO2M}`) - .set('Authorization', `Bearer ${common.USER.ADMIN.TOKEN}`); - const response5 = await request(getUrl(vendor)) - .get(`/items/${localJunctionM2MM2M2}`) - .set('Authorization', `Bearer ${common.USER.ADMIN.TOKEN}`); - const response6 = await request(getUrl(vendor)) - .get(`/items/${localJunctionAllM2M}`) - .set('Authorization', `Bearer ${common.USER.ADMIN.TOKEN}`); - const response7 = await request(getUrl(vendor)) - .get(`/items/${localCollectionM2M2}`) - .set('Authorization', `Bearer ${common.USER.ADMIN.TOKEN}`); - const response8 = await request(getUrl(vendor)) - .get(`/items/${localCollectionM2M}`) - .set('Authorization', `Bearer ${common.USER.ADMIN.TOKEN}`); - const response9 = await request(getUrl(vendor)) - .get(`/items/${localCollectionAll}`) - .set('Authorization', `Bearer ${common.USER.ADMIN.TOKEN}`); - const response10 = await request(getUrl(vendor)) - .get(`/items/${localCollectionM2O}`) - .set('Authorization', `Bearer ${common.USER.ADMIN.TOKEN}`); - const response11 = await request(getUrl(vendor)) - .get(`/items/${localCollectionM2O2}`) - .set('Authorization', `Bearer ${common.USER.ADMIN.TOKEN}`); + responses.push( + await request(getUrl(vendor)) + .get(`/items/${localJunctionSelfM2M}`) + .set('Authorization', `Bearer ${common.USER.ADMIN.TOKEN}`) + ); + responses.push( + await request(getUrl(vendor)) + .get(`/items/${localCollectionSelf}`) + .set('Authorization', `Bearer ${common.USER.ADMIN.TOKEN}`) + ); + responses.push( + await request(getUrl(vendor)) + .get(`/items/${localCollectionO2M2}`) + .set('Authorization', `Bearer ${common.USER.ADMIN.TOKEN}`) + ); + responses.push( + await request(getUrl(vendor)) + .get(`/items/${localCollectionO2M}`) + .set('Authorization', `Bearer ${common.USER.ADMIN.TOKEN}`) + ); + responses.push( + await request(getUrl(vendor)) + .get(`/items/${localJunctionM2AM2A2}`) + .set('Authorization', `Bearer ${common.USER.ADMIN.TOKEN}`) + ); + responses.push( + await request(getUrl(vendor)) + .get(`/items/${localJunctionAllM2A}`) + .set('Authorization', `Bearer ${common.USER.ADMIN.TOKEN}`) + ); + responses.push( + await request(getUrl(vendor)) + .get(`/items/${localCollectionM2A2}`) + .set('Authorization', `Bearer ${common.USER.ADMIN.TOKEN}`) + ); + responses.push( + await request(getUrl(vendor)) + .get(`/items/${localCollectionM2A}`) + .set('Authorization', `Bearer ${common.USER.ADMIN.TOKEN}`) + ); + + responses.push( + await request(getUrl(vendor)) + .get(`/items/${localJunctionM2MM2M2}`) + .set('Authorization', `Bearer ${common.USER.ADMIN.TOKEN}`) + ); + responses.push( + await request(getUrl(vendor)) + .get(`/items/${localJunctionAllM2M}`) + .set('Authorization', `Bearer ${common.USER.ADMIN.TOKEN}`) + ); + responses.push( + await request(getUrl(vendor)) + .get(`/items/${localCollectionM2M2}`) + .set('Authorization', `Bearer ${common.USER.ADMIN.TOKEN}`) + ); + responses.push( + await request(getUrl(vendor)) + .get(`/items/${localCollectionM2M}`) + .set('Authorization', `Bearer ${common.USER.ADMIN.TOKEN}`) + ); + responses.push( + await request(getUrl(vendor)) + .get(`/items/${localCollectionAll}`) + .set('Authorization', `Bearer ${common.USER.ADMIN.TOKEN}`) + ); + responses.push( + await request(getUrl(vendor)) + .get(`/items/${localCollectionM2O}`) + .set('Authorization', `Bearer ${common.USER.ADMIN.TOKEN}`) + ); + responses.push( + await request(getUrl(vendor)) + .get(`/items/${localCollectionM2O2}`) + .set('Authorization', `Bearer ${common.USER.ADMIN.TOKEN}`) + ); // Assert - expect(response.statusCode).toEqual(403); - expect(response2.statusCode).toEqual(403); - expect(response3.statusCode).toEqual(403); - expect(response4.statusCode).toEqual(403); - expect(response5.statusCode).toEqual(403); - expect(response6.statusCode).toEqual(403); - expect(response7.statusCode).toEqual(403); - expect(response8.statusCode).toEqual(403); - expect(response9.statusCode).toEqual(403); - expect(response10.statusCode).toEqual(403); - expect(response11.statusCode).toEqual(403); + for (const response of responses) { + expect(response.statusCode).toEqual(403); + } } }