From cb914746d2cce3776ecf547462a6f307efd95fb7 Mon Sep 17 00:00:00 2001 From: ian Date: Mon, 5 Sep 2022 21:58:59 +0800 Subject: [PATCH] Add singleton tests (#15402) * Add singleton tests * Test if working for all vendors * Revert triggering for all vendors --- tests-blackbox/common/functions.ts | 16 +++ tests-blackbox/routes/items/singleton.seed.ts | 126 ++++++++++++++++++ tests-blackbox/routes/items/singleton.test.ts | 125 +++++++++++++++++ 3 files changed, 267 insertions(+) create mode 100644 tests-blackbox/routes/items/singleton.seed.ts create mode 100644 tests-blackbox/routes/items/singleton.test.ts diff --git a/tests-blackbox/common/functions.ts b/tests-blackbox/common/functions.ts index 6ddca4cc95..1fc0388c3e 100644 --- a/tests-blackbox/common/functions.ts +++ b/tests-blackbox/common/functions.ts @@ -565,6 +565,22 @@ export async function ReadItem(vendor: string, options: OptionsReadItem) { return response.body.data; } +export type OptionsUpdateItem = { + id?: string | number; + collection: string; + item: any; +}; + +export async function UpdateItem(vendor: string, options: OptionsUpdateItem) { + // Action + const response = await request(getUrl(vendor)) + .patch(`/items/${options.collection}/${options.id === undefined ? '' : options.id}`) + .set('Authorization', `Bearer ${common.USER.TESTS_FLOW.TOKEN}`) + .send(options.item); + + return response.body.data; +} + // TODO // export async function CreatePermissions() {} // export async function UpdatePermissions() {} diff --git a/tests-blackbox/routes/items/singleton.seed.ts b/tests-blackbox/routes/items/singleton.seed.ts new file mode 100644 index 0000000000..25be972f92 --- /dev/null +++ b/tests-blackbox/routes/items/singleton.seed.ts @@ -0,0 +1,126 @@ +import vendors from '@common/get-dbs-to-test'; +import { + CreateCollection, + CreateField, + CreateFieldO2M, + CreateItem, + DeleteCollection, + PRIMARY_KEY_TYPES, + SeedFunctions, + UpdateItem, +} from '@common/index'; + +export const collectionSingleton = 'test_items_singleton'; +export const collectionSingletonO2M = 'test_items_singleton_o2m'; + +export type Singleton = { + id?: number | string; + name: string; +}; + +export type SingletonO2M = { + id?: number | string; + name: string; + country_id?: number | string | null; +}; + +export const seedDBStructure = () => { + it.each(vendors)( + '%s', + async (vendor) => { + for (const pkType of PRIMARY_KEY_TYPES) { + try { + const localCollectionSingleton = `${collectionSingleton}_${pkType}`; + const localCollectionSingletonO2M = `${collectionSingletonO2M}_${pkType}`; + + // Delete existing collections + await DeleteCollection(vendor, { collection: localCollectionSingletonO2M }); + await DeleteCollection(vendor, { collection: localCollectionSingleton }); + + // Create singleton collection + await CreateCollection(vendor, { + collection: localCollectionSingleton, + primaryKeyType: pkType, + meta: { singleton: true }, + }); + + await CreateField(vendor, { + collection: localCollectionSingleton, + field: 'name', + type: 'string', + }); + + // Create singleton O2M collection + await CreateCollection(vendor, { + collection: localCollectionSingletonO2M, + primaryKeyType: pkType, + }); + + await CreateField(vendor, { + collection: localCollectionSingletonO2M, + field: 'name', + type: 'string', + }); + + // Create O2M relationships + await CreateFieldO2M(vendor, { + collection: localCollectionSingleton, + field: 'o2m', + otherCollection: localCollectionSingletonO2M, + otherField: 'singleton_id', + primaryKeyType: pkType, + }); + + expect(true).toBeTruthy(); + } catch (error) { + expect(error).toBeFalsy(); + } + } + }, + 600000 + ); +}; + +export const seedDBValues = async () => { + let isSeeded = false; + + await Promise.all( + vendors.map(async (vendor) => { + for (const pkType of PRIMARY_KEY_TYPES) { + const localCollectionSingleton = `${collectionSingleton}_${pkType}`; + const localCollectionSingletonO2M = `${collectionSingletonO2M}_${pkType}`; + + const item = await UpdateItem(vendor, { + collection: localCollectionSingleton, + item: { + id: + pkType === 'string' + ? SeedFunctions.generatePrimaryKeys(pkType, { quantity: 1, seed: localCollectionSingleton })[0] + : undefined, + name: 'parent', + }, + }); + + await CreateItem(vendor, { + collection: localCollectionSingletonO2M, + item: { + id: + pkType === 'string' + ? SeedFunctions.generatePrimaryKeys(pkType, { quantity: 1, seed: localCollectionSingletonO2M })[0] + : undefined, + name: 'child_o2m', + singleton_id: item.id, + }, + }); + } + }) + ) + .then(() => { + isSeeded = true; + }) + .catch(() => { + isSeeded = false; + }); + + return isSeeded; +}; diff --git a/tests-blackbox/routes/items/singleton.test.ts b/tests-blackbox/routes/items/singleton.test.ts new file mode 100644 index 0000000000..b9d36f2fea --- /dev/null +++ b/tests-blackbox/routes/items/singleton.test.ts @@ -0,0 +1,125 @@ +import request from 'supertest'; +import { getUrl } from '@common/config'; +import vendors from '@common/get-dbs-to-test'; +import * as common from '@common/index'; +import { collectionSingleton, collectionSingletonO2M, seedDBValues } from './singleton.seed'; +import { SeedFunctions } from '@common/index'; + +let isSeeded = false; + +beforeAll(async () => { + isSeeded = await seedDBValues(); +}, 300000); + +test('Seed Database Values', () => { + expect(isSeeded).toStrictEqual(true); +}); + +describe.each(common.PRIMARY_KEY_TYPES)('/items', (pkType) => { + const localCollectionSingleton = `${collectionSingleton}_${pkType}`; + const localCollectionSingletonO2M = `${collectionSingletonO2M}_${pkType}`; + + describe(`pkType: ${pkType}`, () => { + describe('GET /:collection', () => { + describe('retrieves singleton', () => { + it.each(vendors)('%s', async (vendor) => { + // Action + const response = await request(getUrl(vendor)) + .get(`/items/${localCollectionSingleton}`) + .set('Authorization', `Bearer ${common.USER.ADMIN.TOKEN}`); + + // Assert + expect(response.statusCode).toEqual(200); + expect(response.body.data).toMatchObject({ name: 'parent', o2m: expect.anything() }); + }); + }); + + describe('Error handling', () => { + describe('returns an error when an invalid id is used', () => { + it.each(vendors)('%s', async (vendor) => { + // Action + const response = await request(getUrl(vendor)) + .get(`/items/${localCollectionSingleton}/invalid_id`) + .set('Authorization', `Bearer ${common.USER.ADMIN.TOKEN}`); + + // Assert + expect(response.statusCode).toBe(403); + }); + }); + }); + }); + + describe('PATCH /:collection', () => { + describe(`updates singleton's name with no relations`, () => { + it.each(vendors)('%s', async (vendor) => { + // Setup + const newName = 'parent_updated'; + + // Action + const response = await request(getUrl(vendor)) + .patch(`/items/${localCollectionSingleton}`) + .send({ name: newName }) + .set('Authorization', `Bearer ${common.USER.ADMIN.TOKEN}`); + + // Assert + expect(response.statusCode).toEqual(200); + expect(response.body.data).toMatchObject({ + name: newName, + }); + }); + }); + + describe('updates o2m items', () => { + it.each(vendors)('%s', async (vendor) => { + // Setup + const existingItem = ( + await request(getUrl(vendor)) + .get(`/items/${localCollectionSingleton}`) + .set('Authorization', `Bearer ${common.USER.ADMIN.TOKEN}`) + ).body.data; + + const o2mNameNew = 'child_o2m_new'; + const o2mNameUpdated = 'child_o2m_updated'; + + const body = { + o2m: { + create: [ + { + id: + pkType === 'string' + ? SeedFunctions.generatePrimaryKeys(pkType, { + quantity: 1, + seed: `${localCollectionSingletonO2M}_update_o2m`, + })[0] + : undefined, + name: o2mNameNew, + }, + ], + update: [ + { + id: existingItem.o2m[0], + name: o2mNameUpdated, + }, + ], + delete: [], + }, + }; + + // Action + const response = await request(getUrl(vendor)) + .patch(`/items/${localCollectionSingleton}?fields=*.*`) + .send(body) + .set('Authorization', `Bearer ${common.USER.ADMIN.TOKEN}`); + + // Assert + expect(response.statusCode).toEqual(200); + expect(response.body.data.o2m).toBeDefined(); + expect(response.body.data.o2m.length).toBe(2); + expect(response.body.data.o2m.map((item: any) => item.name)).toEqual( + expect.arrayContaining([o2mNameNew, o2mNameUpdated]) + ); + }); + }); + }); + }); +});