From 60067e4a066a5eb3323dd5651b86e1d61e742625 Mon Sep 17 00:00:00 2001 From: Antony Date: Tue, 30 Apr 2024 10:45:11 +0530 Subject: [PATCH] test: Variant entries import unit test cases --- .../src/import/variant-entries.ts | 42 ++-- .../test/unit/import/variant-entries.test.ts | 200 ++++++++++++++++++ .../mock/contents/content_types/CT-1.json | 7 + .../variants/E-1/9b0da6xd7et72y-6gv7he23.json | 12 ++ .../CT-1/en-us/variants/E-1/index.json | 3 + .../variants/E-2/9b0da6xd7et72y-6gv7he23.json | 12 ++ .../CT-1/en-us/variants/E-2/index.json | 3 + .../contents/mapper/assets/uid-mapping.json | 6 + .../contents/mapper/assets/url-mapping.json | 6 + .../entries/data-for-variant-entry.json | 6 + .../empty-data/data-for-variant-entry.json | 1 + .../contents/mapper/entries/uid-mapping.json | 6 + .../mapper/marketplace_apps/uid-mapping.json | 3 + .../experiences/variants-uid-mapping.json | 5 + .../mapper/taxonomies/terms/success.json | 1 + .../test/unit/mock/import-config.json | 63 ++++++ 16 files changed, 355 insertions(+), 21 deletions(-) create mode 100644 packages/contentstack-variants/test/unit/import/variant-entries.test.ts create mode 100644 packages/contentstack-variants/test/unit/mock/contents/content_types/CT-1.json create mode 100644 packages/contentstack-variants/test/unit/mock/contents/entries/CT-1/en-us/variants/E-1/9b0da6xd7et72y-6gv7he23.json create mode 100644 packages/contentstack-variants/test/unit/mock/contents/entries/CT-1/en-us/variants/E-1/index.json create mode 100644 packages/contentstack-variants/test/unit/mock/contents/entries/CT-1/en-us/variants/E-2/9b0da6xd7et72y-6gv7he23.json create mode 100644 packages/contentstack-variants/test/unit/mock/contents/entries/CT-1/en-us/variants/E-2/index.json create mode 100644 packages/contentstack-variants/test/unit/mock/contents/mapper/assets/uid-mapping.json create mode 100644 packages/contentstack-variants/test/unit/mock/contents/mapper/assets/url-mapping.json create mode 100644 packages/contentstack-variants/test/unit/mock/contents/mapper/entries/data-for-variant-entry.json create mode 100644 packages/contentstack-variants/test/unit/mock/contents/mapper/entries/empty-data/data-for-variant-entry.json create mode 100644 packages/contentstack-variants/test/unit/mock/contents/mapper/entries/uid-mapping.json create mode 100644 packages/contentstack-variants/test/unit/mock/contents/mapper/marketplace_apps/uid-mapping.json create mode 100644 packages/contentstack-variants/test/unit/mock/contents/mapper/personalization/experiences/variants-uid-mapping.json create mode 100644 packages/contentstack-variants/test/unit/mock/contents/mapper/taxonomies/terms/success.json create mode 100644 packages/contentstack-variants/test/unit/mock/import-config.json diff --git a/packages/contentstack-variants/src/import/variant-entries.ts b/packages/contentstack-variants/src/import/variant-entries.ts index 83b4d20ea4..6c72813bb5 100644 --- a/packages/contentstack-variants/src/import/variant-entries.ts +++ b/packages/contentstack-variants/src/import/variant-entries.ts @@ -1,8 +1,6 @@ import omit from 'lodash/omit'; import chunk from 'lodash/chunk'; -import values from 'lodash/values'; import entries from 'lodash/entries'; -import orderBy from 'lodash/orderBy'; import isEmpty from 'lodash/isEmpty'; import { join, resolve } from 'path'; import { readFileSync, existsSync } from 'fs'; @@ -67,7 +65,7 @@ export default class VariantEntries extends VariantAdapter { + let config: ImportConfig; + + const test = fancy.stdout({ print: process.env.PRINT === 'true' || false }); + + beforeEach(() => { + config = cloneDeep(importConf) as unknown as ImportConfig; + }); + + describe('import method', () => { + test + .stub(Import.VariantEntries.prototype, 'importVariantEntries', async () => {}) + .spy(Import.VariantEntries.prototype, 'importVariantEntries') + .it('should call import variant entry method (API call)', async ({ spy }) => { + let entryVariantInstace = new Import.VariantEntries(config); + await entryVariantInstace.import(); + + expect(spy.importVariantEntries.called).to.be.true; + expect(spy.importVariantEntries.calledWith(variantEntryData[0])).to.be.true; + }); + + test + .stub(Import.VariantEntries.prototype, 'importVariantEntries', async () => {}) + .spy(Import.VariantEntries.prototype, 'importVariantEntries') + .it('should return with entry not found message', async (ctx) => { + config.backupDir = './'; + let entryVariantInstace = new Import.VariantEntries(config); + await entryVariantInstace.import(); + + expect(ctx.stdout).to.be.includes(entryVariantInstace.messages.IMPORT_ENTRY_NOT_FOUND); + }); + + test + .stub(Import.VariantEntries.prototype, 'importVariantEntries', async () => {}) + .spy(Import.VariantEntries.prototype, 'importVariantEntries') + .it('should return with variant UID mapper file not found message', async (ctx) => { + config.modules.personalization.dirName = 'wrong-dir'; + let entryVariantInstace = new Import.VariantEntries(config); + await entryVariantInstace.import(); + + expect(ctx.stdout).to.be.includes(entryVariantInstace.messages.EMPTY_VARIANT_UID_DATA); + }); + + test + .stub(Import.VariantEntries.prototype, 'importVariantEntries', async () => {}) + .spy(Import.VariantEntries.prototype, 'importVariantEntries') + .it('should return with entry not found message if empty content found on file', async (ctx) => { + let entryVariantInstace = new Import.VariantEntries(config); + entryVariantInstace.entriesMapperPath = join(entryVariantInstace.entriesMapperPath, 'empty-data'); + await entryVariantInstace.import(); + + expect(ctx.stdout).to.be.includes(entryVariantInstace.messages.IMPORT_ENTRY_NOT_FOUND); + }); + + test + .stub(Import.VariantEntries.prototype, 'importVariantEntries', async () => {}) + .spy(Import.VariantEntries.prototype, 'importVariantEntries') + .it('should check taxonomies folder existence', async (ctx) => { + config.modules.taxonomies.dirName = 'wrong-dir'; + let entryVariantInstace = new Import.VariantEntries(config); + await entryVariantInstace.import(); + + expect(entryVariantInstace.taxonomies).to.contain({}); + }); + }); + + describe('importVariantEntries method', () => { + test + .stub(Import.VariantEntries.prototype, 'handleCuncurrency', async () => {}) + .spy(Import.VariantEntries.prototype, 'handleCuncurrency') + .it('should call handle Cuncurrency method to manage import batch', async ({ spy }) => { + let entryVariantInstace = new Import.VariantEntries(config); + await entryVariantInstace.importVariantEntries(variantEntryData[0]); + + expect(spy.handleCuncurrency.called).to.be.true; + expect(spy.handleCuncurrency.calledWith(ContentType, variantEntries, variantEntryData[0])).to.be.true; + }); + + test + .stub(Import.VariantEntries.prototype, 'handleCuncurrency', async () => { + throw new Error('Dummy error'); + }) + .spy(Import.VariantEntries.prototype, 'handleCuncurrency') + .it('should catch and log errors on catch block', async (ctx) => { + let entryVariantInstace = new Import.VariantEntries(config); + await entryVariantInstace.importVariantEntries(variantEntryData[0]); + + expect(ctx.stdout).to.be.includes('Dummy error'); + }); + }); + + describe('handleCuncurrency method', () => { + test + .stub(VariantHttpClient.prototype, 'createVariantEntry', async () => {}) + .stub(Import.VariantEntries.prototype, 'handleVariantEntryRelationalData', () => variantEntries[0]) + .spy(VariantHttpClient.prototype, 'createVariantEntry') + .spy(Import.VariantEntries.prototype, 'handleVariantEntryRelationalData') + .it('should call handle Cuncurrency method to manage import batch', async ({ spy }) => { + const variantEntry = variantEntries[0]; + const { content_type, entry_uid, locale } = variantEntryData[0]; + let entryVariantInstace = new Import.VariantEntries(config); + entryVariantInstace.variantIdList = { 'VARIANT-ID-1': 'VARIANT-ID-2' }; + await entryVariantInstace.handleCuncurrency(ContentType, variantEntries, variantEntryData[0]); + + expect(spy.createVariantEntry.called).to.be.true; + expect(spy.handleVariantEntryRelationalData.called).to.be.true; + expect(spy.handleVariantEntryRelationalData.calledWith(ContentType, variantEntry)).to.be.true; + expect( + spy.createVariantEntry.calledWith(variantEntry, { + locale, + entry_uid, + variant_id: 'VARIANT-ID-2', + content_type_uid: content_type, + }), + ).to.be.true; + }); + + test + .stub(VariantHttpClient.prototype, 'createVariantEntry', async () => {}) + .stub(Import.VariantEntries.prototype, 'handleVariantEntryRelationalData', () => variantEntries[0]) + .spy(VariantHttpClient.prototype, 'createVariantEntry') + .spy(Import.VariantEntries.prototype, 'handleVariantEntryRelationalData') + .it('should return without any execution if empty batch found', async (ctx) => { + let entryVariantInstace = new Import.VariantEntries(config); + const result = await entryVariantInstace.handleCuncurrency(ContentType, [], variantEntryData[0]); + + expect(result).to.be.undefined; + }); + + test + .stub(VariantHttpClient.prototype, 'createVariantEntry', async () => {}) + .stub(Import.VariantEntries.prototype, 'handleVariantEntryRelationalData', () => variantEntries[0]) + .spy(VariantHttpClient.prototype, 'createVariantEntry') + .spy(Import.VariantEntries.prototype, 'handleVariantEntryRelationalData') + .it('should log error message if variant UID not found on the mapper file', async (ctx) => { + let entryVariantInstace = new Import.VariantEntries(config); + entryVariantInstace.config.modules.variantEntry.apiConcurrency = null as any; // NOTE Missing apiConcurrency value in config + entryVariantInstace.variantIdList = { 'VARIANT-ID-2': 'VARIANT-ID-NEW-2' }; + await entryVariantInstace.handleCuncurrency(ContentType, variantEntries, variantEntryData[0]); + + expect(ctx.stdout).to.be.includes(entryVariantInstace.messages.VARIANT_ID_NOT_FOUND); + }); + }); + + describe('handleVariantEntryRelationalData method', () => { + test.it('should call handle Cuncurrency method to manage import batch', async () => { + // NOTE passing helper methods along with config + let conf = Object.assign(config, { + helpers: { + lookUpTerms: () => {}, + lookupExtension: () => {}, + lookupAssets: (entry: any) => entry, + lookupEntries: (entry: any) => entry, + restoreJsonRteEntryRefs: (entry: any) => entry, + }, + }); + const variantEntry = variantEntries[0]; + let entryVariantInstace = new Import.VariantEntries(conf); + const entry = await entryVariantInstace.handleVariantEntryRelationalData(ContentType, variantEntry); + + expect(entry).to.contain(variantEntry); + }); + + test.it('should skip calling lookupExtension if not available in helper', async () => { + // NOTE passing helper methods along with config + let conf = Object.assign(config, { + helpers: { + lookUpTerms: () => {}, + lookupAssets: (entry: any) => entry, + lookupEntries: (entry: any) => entry, + restoreJsonRteEntryRefs: (entry: any) => entry, + }, + }); + const variantEntry = variantEntries[0]; + let entryVariantInstace = new Import.VariantEntries(conf); + const entry = await entryVariantInstace.handleVariantEntryRelationalData(ContentType, variantEntry); + + expect(entry).to.contain(variantEntry); + }); + + test.it('will skip calling lookup function if helper is not present in config', async () => { + const variantEntry = variantEntries[0]; + let entryVariantInstace = new Import.VariantEntries(config); + const entry = await entryVariantInstace.handleVariantEntryRelationalData(ContentType, variantEntry); + + expect(entry).to.contain(variantEntry); + }); + }); +}); diff --git a/packages/contentstack-variants/test/unit/mock/contents/content_types/CT-1.json b/packages/contentstack-variants/test/unit/mock/contents/content_types/CT-1.json new file mode 100644 index 0000000000..5da35cfaa7 --- /dev/null +++ b/packages/contentstack-variants/test/unit/mock/contents/content_types/CT-1.json @@ -0,0 +1,7 @@ +{ + "uid": "CT-1", + "title": "CT-1", + "description": "test CT", + "schema": [], + "options": {} +} \ No newline at end of file diff --git a/packages/contentstack-variants/test/unit/mock/contents/entries/CT-1/en-us/variants/E-1/9b0da6xd7et72y-6gv7he23.json b/packages/contentstack-variants/test/unit/mock/contents/entries/CT-1/en-us/variants/E-1/9b0da6xd7et72y-6gv7he23.json new file mode 100644 index 0000000000..494fc889ec --- /dev/null +++ b/packages/contentstack-variants/test/unit/mock/contents/entries/CT-1/en-us/variants/E-1/9b0da6xd7et72y-6gv7he23.json @@ -0,0 +1,12 @@ +[{ + "uid": "E-1", + "locale": "en-us", + "title": "Variant 1", + "variant_id": "VARIANT-ID-1", + "_version": 1, + "_variant": { + "uid": "UID-1", + "_change_set": [], + "_base_entry_version": 1 + } +}] \ No newline at end of file diff --git a/packages/contentstack-variants/test/unit/mock/contents/entries/CT-1/en-us/variants/E-1/index.json b/packages/contentstack-variants/test/unit/mock/contents/entries/CT-1/en-us/variants/E-1/index.json new file mode 100644 index 0000000000..4772b56547 --- /dev/null +++ b/packages/contentstack-variants/test/unit/mock/contents/entries/CT-1/en-us/variants/E-1/index.json @@ -0,0 +1,3 @@ +{ + "1": "9b0da6xd7et72y-6gv7he23.json" +} \ No newline at end of file diff --git a/packages/contentstack-variants/test/unit/mock/contents/entries/CT-1/en-us/variants/E-2/9b0da6xd7et72y-6gv7he23.json b/packages/contentstack-variants/test/unit/mock/contents/entries/CT-1/en-us/variants/E-2/9b0da6xd7et72y-6gv7he23.json new file mode 100644 index 0000000000..494fc889ec --- /dev/null +++ b/packages/contentstack-variants/test/unit/mock/contents/entries/CT-1/en-us/variants/E-2/9b0da6xd7et72y-6gv7he23.json @@ -0,0 +1,12 @@ +[{ + "uid": "E-1", + "locale": "en-us", + "title": "Variant 1", + "variant_id": "VARIANT-ID-1", + "_version": 1, + "_variant": { + "uid": "UID-1", + "_change_set": [], + "_base_entry_version": 1 + } +}] \ No newline at end of file diff --git a/packages/contentstack-variants/test/unit/mock/contents/entries/CT-1/en-us/variants/E-2/index.json b/packages/contentstack-variants/test/unit/mock/contents/entries/CT-1/en-us/variants/E-2/index.json new file mode 100644 index 0000000000..4772b56547 --- /dev/null +++ b/packages/contentstack-variants/test/unit/mock/contents/entries/CT-1/en-us/variants/E-2/index.json @@ -0,0 +1,3 @@ +{ + "1": "9b0da6xd7et72y-6gv7he23.json" +} \ No newline at end of file diff --git a/packages/contentstack-variants/test/unit/mock/contents/mapper/assets/uid-mapping.json b/packages/contentstack-variants/test/unit/mock/contents/mapper/assets/uid-mapping.json new file mode 100644 index 0000000000..233c2f5173 --- /dev/null +++ b/packages/contentstack-variants/test/unit/mock/contents/mapper/assets/uid-mapping.json @@ -0,0 +1,6 @@ +{ + "O-A-UID-1": "N-A-UID-1", + "O-A-UID-2": "N-A-UID-2", + "O-A-UID-3": "N-A-UID-3", + "O-A-UID-4": "N-A-UID-4" +} \ No newline at end of file diff --git a/packages/contentstack-variants/test/unit/mock/contents/mapper/assets/url-mapping.json b/packages/contentstack-variants/test/unit/mock/contents/mapper/assets/url-mapping.json new file mode 100644 index 0000000000..b8728b6841 --- /dev/null +++ b/packages/contentstack-variants/test/unit/mock/contents/mapper/assets/url-mapping.json @@ -0,0 +1,6 @@ +{ + "o-ass-url-1.com": "n-ass-url-1.com", + "o-ass-url-2.com": "n-ass-url-2.com", + "o-ass-url-3.com": "n-ass-url-3.com", + "o-ass-url-4.com": "n-ass-url-4.com" +} \ No newline at end of file diff --git a/packages/contentstack-variants/test/unit/mock/contents/mapper/entries/data-for-variant-entry.json b/packages/contentstack-variants/test/unit/mock/contents/mapper/entries/data-for-variant-entry.json new file mode 100644 index 0000000000..f1c7cf727b --- /dev/null +++ b/packages/contentstack-variants/test/unit/mock/contents/mapper/entries/data-for-variant-entry.json @@ -0,0 +1,6 @@ +[ + { "content_type": "CT-1", "locale": "en-us", "entry_uid": "E-1" }, + { "content_type": "CT-2", "locale": "en-us", "entry_uid": "E-2" }, + { "content_type": "CT-3", "locale": "en-us", "entry_uid": "E-3" }, + { "content_type": "CT-4", "locale": "en-us", "entry_uid": "E-4" } +] diff --git a/packages/contentstack-variants/test/unit/mock/contents/mapper/entries/empty-data/data-for-variant-entry.json b/packages/contentstack-variants/test/unit/mock/contents/mapper/entries/empty-data/data-for-variant-entry.json new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/packages/contentstack-variants/test/unit/mock/contents/mapper/entries/empty-data/data-for-variant-entry.json @@ -0,0 +1 @@ +[] diff --git a/packages/contentstack-variants/test/unit/mock/contents/mapper/entries/uid-mapping.json b/packages/contentstack-variants/test/unit/mock/contents/mapper/entries/uid-mapping.json new file mode 100644 index 0000000000..ab0b06ac7c --- /dev/null +++ b/packages/contentstack-variants/test/unit/mock/contents/mapper/entries/uid-mapping.json @@ -0,0 +1,6 @@ +{ + "E-UID-1": "E-UID-1", + "E-UID-2": "E-UID-2", + "E-UID-3": "E-UID-3", + "E-UID-4": "E-UID-4" +} \ No newline at end of file diff --git a/packages/contentstack-variants/test/unit/mock/contents/mapper/marketplace_apps/uid-mapping.json b/packages/contentstack-variants/test/unit/mock/contents/mapper/marketplace_apps/uid-mapping.json new file mode 100644 index 0000000000..b3c565eb60 --- /dev/null +++ b/packages/contentstack-variants/test/unit/mock/contents/mapper/marketplace_apps/uid-mapping.json @@ -0,0 +1,3 @@ +{ + "extension_uid": {} +} \ No newline at end of file diff --git a/packages/contentstack-variants/test/unit/mock/contents/mapper/personalization/experiences/variants-uid-mapping.json b/packages/contentstack-variants/test/unit/mock/contents/mapper/personalization/experiences/variants-uid-mapping.json new file mode 100644 index 0000000000..3597394145 --- /dev/null +++ b/packages/contentstack-variants/test/unit/mock/contents/mapper/personalization/experiences/variants-uid-mapping.json @@ -0,0 +1,5 @@ +{ + "OLD-UID-1": "NEW-UID-1", + "OLD-UID-2": "NEW-UID-2", + "OLD-UID-3": "NEW-UID-3" +} diff --git a/packages/contentstack-variants/test/unit/mock/contents/mapper/taxonomies/terms/success.json b/packages/contentstack-variants/test/unit/mock/contents/mapper/taxonomies/terms/success.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/packages/contentstack-variants/test/unit/mock/contents/mapper/taxonomies/terms/success.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/packages/contentstack-variants/test/unit/mock/import-config.json b/packages/contentstack-variants/test/unit/mock/import-config.json new file mode 100644 index 0000000000..98e5eae527 --- /dev/null +++ b/packages/contentstack-variants/test/unit/mock/import-config.json @@ -0,0 +1,63 @@ +{ + "data": "./test/unit/mock/contents", + "contentDir": "./test/unit/mock/contents", + "backupDir": "./test/unit/mock/contents", + "apiKey": "TEST-STACK-API-KEY", + "master_locale": { "code": "en-us" }, + "host": "https://test.abc.com", + "modules": { + "entries": { + "dirName": "entries", + "fileName": "entries.json", + "invalidKeys": [ + "stackHeaders", + "content_type_uid", + "urlPath", + "created_at", + "updated_at", + "created_by", + "updated_by", + "_metadata", + "published" + ], + "batchLimit": 20, + "downloadLimit": 5, + "limit": 100, + "dependencies": ["locales", "content-types"], + "exportVersions": false + }, + "content-types": { + "dirName": "content_types", + "fileName": "content_types.json", + "validKeys": ["title", "uid", "schema", "options", "singleton", "description"], + "limit": 100 + }, + "personalization": { + "project_id": "PROJ-1", + "importData": true, + "dirName": "personalization", + "importOrder": ["attributes", "audiences", "events", "experiences"], + "projects": { "dirName": "projects", "fileName": "projects.json" }, + "attributes": { "dirName": "attributes", "fileName": "attributes.json" }, + "audiences": { "dirName": "audiences", "fileName": "audiences.json" }, + "events": { "dirName": "events", "fileName": "events.json" }, + "experiences": { + "dirName": "experiences", + "fileName": "experiences.json", + "thresholdTimer": 0, + "checkIntervalDuration": 0 + } + }, + "variantEntry": { + "apiConcurrency": 1, + "dirName": "variants", + "fileName": "index.json", + "query": { "locale": "en-us" } + }, + "taxonomies": { + "dirName": "taxonomies", + "fileName": "taxonomies.json" + } + }, + "personalizationEnabled": true +}