From fa83cb014725d7a456a5b153de107a5df2f7d83d Mon Sep 17 00:00:00 2001 From: "harshitha.d" Date: Mon, 7 Apr 2025 13:07:23 +0530 Subject: [PATCH 01/10] enh: Add environment variable checks for ContentstackClient --- test/sanity-check/utility/ContentstackClient.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/sanity-check/utility/ContentstackClient.js b/test/sanity-check/utility/ContentstackClient.js index a91c1171..6736e206 100644 --- a/test/sanity-check/utility/ContentstackClient.js +++ b/test/sanity-check/utility/ContentstackClient.js @@ -1,6 +1,15 @@ import * as contentstack from '../../../lib/contentstack.js' import dotenv from 'dotenv' dotenv.config() + +const requiredVars = ['HOST', 'EMAIL', 'PASSWORD', 'ORGANIZATION', 'API_KEY'] +const missingVars = requiredVars.filter((key) => !process.env[key]) + +if (missingVars.length > 0) { + console.error(`\x1b[31mError: Missing environment variables - ${missingVars.join(', ')}`) + process.exit(1) +} + function contentstackClient (authtoken = null) { var params = { host: process.env.HOST, defaultHostName: process.env.DEFAULTHOST } if (authtoken) { From ebd4e4f3e9f665de1b9a6ff5dc28281f67dcc1a2 Mon Sep 17 00:00:00 2001 From: "harshitha.d" Date: Mon, 7 Apr 2025 13:08:43 +0530 Subject: [PATCH 02/10] refactor: Remove unused mock files and test cases --- test/api/app-delete-test.js | 38 -- test/api/app-request-test.js | 52 --- test/api/app-test.js | 192 --------- test/api/asset-test.js | 219 ---------- test/api/authorization-test.js | 46 --- test/api/branch-test.js | 222 ----------- test/api/branchAlias-test.js | 78 ---- test/api/bulkOperation-test.js | 109 ----- test/api/contentType-delete-test.js | 29 -- test/api/contentType-test.js | 121 ------ test/api/delete-test.js | 35 -- test/api/deliveryToken-test.js | 143 ------- test/api/entry-test.js | 234 ----------- test/api/environment-test.js | 139 ------- test/api/extension-test.js | 296 -------------- test/api/globalfield-test.js | 119 ------ test/api/hosting-test.js | 139 ------- test/api/label-test.js | 127 ------ test/api/locale-test.js | 129 ------ test/api/managementToken-test.js | 136 ------- test/api/mock/berries.jfif | Bin 157612 -> 0 bytes test/api/mock/branch.js | 14 - test/api/mock/content-type.js | 179 --------- test/api/mock/contentType.json | 36 -- test/api/mock/customUpload.html | 28 -- test/api/mock/deliveryToken.js | 28 -- test/api/mock/entry.js | 7 - test/api/mock/entry.json | 1 - test/api/mock/environment.js | 32 -- test/api/mock/extension.js | 91 ----- test/api/mock/globalfield.js | 28 -- test/api/mock/globalfield.json | 34 -- test/api/mock/managementToken.js | 72 ---- test/api/mock/release.js | 10 - test/api/mock/role.js | 53 --- test/api/mock/taxonomy.json | 8 - test/api/mock/upload.html | 28 -- test/api/mock/variantGroup.js | 82 ---- test/api/mock/variants.js | 50 --- test/api/mock/webhook.js | 40 -- test/api/mock/webhook.json | 17 - test/api/mock/workflow.js | 8 - test/api/organization-test.js | 108 ----- test/api/release-test.js | 226 ----------- test/api/role-test.js | 139 ------- test/api/stack-share.js | 34 -- test/api/stack-test.js | 158 -------- test/api/taxonomy-test.js | 110 ----- test/api/team-stack-role-mapping-test.js | 65 --- test/api/team-test.js | 69 ---- test/api/team-users-test.js | 47 --- test/api/terms-test.js | 137 ------- test/api/ungroupedVariants-test.js | 106 ----- test/api/user-test.js | 77 ---- test/api/variantGroup-test.js | 136 ------- test/api/variants-test.js | 112 ------ test/api/webhook-test.js | 149 ------- test/api/workflow-test.js | 485 ----------------------- test/test.js | 33 -- test/utility/ContentstackClient.js | 12 - test/utility/fileOperations/readwrite.js | 35 -- 61 files changed, 5687 deletions(-) delete mode 100644 test/api/app-delete-test.js delete mode 100644 test/api/app-request-test.js delete mode 100644 test/api/app-test.js delete mode 100644 test/api/asset-test.js delete mode 100644 test/api/authorization-test.js delete mode 100644 test/api/branch-test.js delete mode 100644 test/api/branchAlias-test.js delete mode 100644 test/api/bulkOperation-test.js delete mode 100644 test/api/contentType-delete-test.js delete mode 100644 test/api/contentType-test.js delete mode 100644 test/api/delete-test.js delete mode 100644 test/api/deliveryToken-test.js delete mode 100644 test/api/entry-test.js delete mode 100644 test/api/environment-test.js delete mode 100644 test/api/extension-test.js delete mode 100644 test/api/globalfield-test.js delete mode 100644 test/api/hosting-test.js delete mode 100644 test/api/label-test.js delete mode 100644 test/api/locale-test.js delete mode 100644 test/api/managementToken-test.js delete mode 100644 test/api/mock/berries.jfif delete mode 100644 test/api/mock/branch.js delete mode 100644 test/api/mock/content-type.js delete mode 100644 test/api/mock/contentType.json delete mode 100644 test/api/mock/customUpload.html delete mode 100644 test/api/mock/deliveryToken.js delete mode 100644 test/api/mock/entry.js delete mode 100644 test/api/mock/entry.json delete mode 100644 test/api/mock/environment.js delete mode 100644 test/api/mock/extension.js delete mode 100644 test/api/mock/globalfield.js delete mode 100644 test/api/mock/globalfield.json delete mode 100644 test/api/mock/managementToken.js delete mode 100644 test/api/mock/release.js delete mode 100644 test/api/mock/role.js delete mode 100644 test/api/mock/taxonomy.json delete mode 100644 test/api/mock/upload.html delete mode 100644 test/api/mock/variantGroup.js delete mode 100644 test/api/mock/variants.js delete mode 100644 test/api/mock/webhook.js delete mode 100644 test/api/mock/webhook.json delete mode 100644 test/api/mock/workflow.js delete mode 100644 test/api/organization-test.js delete mode 100644 test/api/release-test.js delete mode 100644 test/api/role-test.js delete mode 100644 test/api/stack-share.js delete mode 100644 test/api/stack-test.js delete mode 100644 test/api/taxonomy-test.js delete mode 100644 test/api/team-stack-role-mapping-test.js delete mode 100644 test/api/team-test.js delete mode 100644 test/api/team-users-test.js delete mode 100644 test/api/terms-test.js delete mode 100644 test/api/ungroupedVariants-test.js delete mode 100644 test/api/user-test.js delete mode 100644 test/api/variantGroup-test.js delete mode 100644 test/api/variants-test.js delete mode 100644 test/api/webhook-test.js delete mode 100644 test/api/workflow-test.js delete mode 100644 test/test.js delete mode 100644 test/utility/ContentstackClient.js delete mode 100644 test/utility/fileOperations/readwrite.js diff --git a/test/api/app-delete-test.js b/test/api/app-delete-test.js deleted file mode 100644 index cd9a6648..00000000 --- a/test/api/app-delete-test.js +++ /dev/null @@ -1,38 +0,0 @@ -import dotenv from 'dotenv' -import { describe, it, setup } from 'mocha' -import { jsonReader } from '../utility/fileOperations/readwrite' -import { contentstackClient } from '../utility/ContentstackClient.js' -import { expect } from 'chai' - -dotenv.config() - -let apps = {} -let installation = {} -const orgID = process.env.ORGANIZATION -let client = {} - -describe('Apps api Test', () => { - setup(() => { - const user = jsonReader('loggedinuser.json') - client = contentstackClient(user.authtoken) - apps = jsonReader('apps.json') - installation = jsonReader('installation.json') - }) - - it('Uninstall installation test', done => { - client.organization(orgID).app(apps.uid).installation(installation.uid).uninstall() - .then((installation) => { - expect(installation).to.deep.equal({}) - done() - }).catch(done) - }) - - it('Delete app test', done => { - client.organization(orgID).app(apps.uid).delete() - .then((appResponse) => { - expect(appResponse).to.deep.equal({}) - done() - }) - .catch(done) - }) -}) diff --git a/test/api/app-request-test.js b/test/api/app-request-test.js deleted file mode 100644 index e03bb114..00000000 --- a/test/api/app-request-test.js +++ /dev/null @@ -1,52 +0,0 @@ -import dotenv from 'dotenv' -import { describe, it, setup } from 'mocha' -import { jsonReader } from '../utility/fileOperations/readwrite' -import { contentstackClient } from '../utility/ContentstackClient.js' -import { expect } from 'chai' - -dotenv.config() - -let apps = {} -const orgID = process.env.ORGANIZATION -let client = {} -let stack = {} -let requestUID = '' -describe('Apps request api Test', () => { - setup(() => { - const user = jsonReader('loggedinuser.json') - client = contentstackClient(user.authtoken) - apps = jsonReader('apps.json') - stack = jsonReader('stack.json') - }) - - it('test create app request', done => { - client.organization(orgID).request() - .create({ appUid: apps.uid, targetUid: stack.api_key }) - .then((response) => { - requestUID = response.data.data.uid - expect(response.data).to.not.equal(undefined) - done() - }) - .catch(done) - }) - - it('test get all request for oranization', done => { - client.organization(orgID).request() - .findAll() - .then((response) => { - expect(response.data).to.not.equal(undefined) - done() - }) - .catch(done) - }) - - it('test delete app request', done => { - client.organization(orgID).request() - .delete(requestUID) - .then((response) => { - expect(response.data).to.not.equal(undefined) - done() - }) - .catch(done) - }) -}) diff --git a/test/api/app-test.js b/test/api/app-test.js deleted file mode 100644 index b77c6885..00000000 --- a/test/api/app-test.js +++ /dev/null @@ -1,192 +0,0 @@ -import dotenv from 'dotenv' -import { describe, it, setup } from 'mocha' -import { jsonReader, jsonWrite } from '../utility/fileOperations/readwrite' -import { expect } from 'chai' -import * as contentstack from '../../lib/contentstack.js' - -dotenv.config() - -const orgID = process.env.ORGANIZATION -let client = {} -let appUid = '' -let installationUid = '' -const app = { - name: 'My New App', - description: 'My new test app', - target_type: 'organization' -} -const config = { redirect_uri: 'https://example.com/oauth/callback', app_token_config: { enabled: true, scopes: ['scim:manage'] }, user_token_config: { enabled: true, scopes: ['user:read', 'user:write', 'scim:manage'], allow_pkce: true } } - -describe('Apps api Test', () => { - setup(() => { - const user = jsonReader('loggedinuser.json') - client = contentstack.client({ host: process.env.APP_HOST, defaultHostName: process.env.DEFAULTHOST, authtoken: user.authtoken }) - }) - - it('Fetch all apps test', done => { - client.organization(orgID).app().findAll() - .then((apps) => { - for (const index in apps.items) { - const appObject = apps.items[index] - expect(appObject.name).to.not.equal(null) - expect(appObject.uid).to.not.equal(null) - expect(appObject.target_type).to.not.equal(null) - } - done() - }) - .catch(done) - }) - - it('Fetch all authorized apps test', done => { - client.organization(orgID).app().findAllAuthorized() - .then((apps) => { - for (const index in apps.data) { - const appObject = apps.data[index] - expect(appObject.name).to.not.equal(null) - expect(appObject.uid).to.not.equal(null) - expect(appObject.target_type).to.not.equal(null) - } - done() - }) - .catch(done) - }) - - it('Create app test', done => { - client.organization(orgID).app().create(app) - .then((appResponse) => { - appUid = appResponse.uid - jsonWrite(appResponse, 'apps.json') - expect(appResponse.uid).to.not.equal(undefined) - expect(appResponse.name).to.be.equal(app.name) - expect(appResponse.description).to.be.equal(app.description) - expect(appResponse.target_type).to.be.equal(app.target_type) - done() - }) - .catch(done) - }) - - it('Fetch app test', done => { - client.organization(orgID).app(appUid).fetch() - .then((appResponse) => { - expect(appResponse.uid).to.be.equal(appUid) - expect(appResponse.name).to.be.equal(app.name) - expect(appResponse.description).to.be.equal(app.description) - expect(appResponse.target_type).to.be.equal(app.target_type) - done() - }) - .catch(done) - }) - - it('Update app test', done => { - const updateApp = { name: 'Update my app name' } - let appObject = client.organization(orgID).app(appUid) - appObject = Object.assign(appObject, updateApp) - appObject.update() - .then((appResponse) => { - appUid = appResponse.uid - expect(appResponse.uid).to.not.equal(undefined) - expect(appResponse.name).to.be.equal(updateApp.name) - expect(appResponse.description).to.be.equal(app.description) - expect(appResponse.target_type).to.be.equal(app.target_type) - done() - }) - .catch(done) - }) - - it('Update OAuth app test', done => { - client.organization(orgID).app(appUid).updateOAuth({ config }) - .then((appResponse) => { - expect(appResponse.redirect_uri).to.be.equal(config.redirect_uri) - expect(appResponse.app_token_config.enabled).to.be.equal(config.app_token_config.enabled) - expect(appResponse.user_token_config.enabled).to.be.equal(config.user_token_config.enabled) - done() - }) - .catch(done) - }) - - it('Fetch OAuth app test', done => { - client.organization(orgID).app(appUid).fetchOAuth() - .then((appResponse) => { - expect(appResponse.redirect_uri).to.be.equal(config.redirect_uri) - expect(appResponse.app_token_config.enabled).to.be.equal(config.app_token_config.enabled) - expect(appResponse.user_token_config.enabled).to.be.equal(config.user_token_config.enabled) - done() - }) - .catch(done) - }) - - it('Install app test', done => { - client.organization(orgID).app(appUid).install({ targetType: 'organization', targetUid: process.env.ORGANIZATION }) - .then((installation) => { - installationUid = installation.uid - jsonWrite(installation, 'installation.json') - expect(installation.uid).to.not.equal(undefined) - expect(installation.params.organization_uid).to.be.equal(orgID) - expect(installation.urlPath).to.be.equal(`/installations/${installation.uid}`) - expect(installation.fetch).to.not.equal(undefined) - expect(installation.update).to.not.equal(undefined) - expect(installation.uninstall).to.not.equal(undefined) - done() - }) - .catch(done) - }) - - it('Get installationData for installation test', done => { - client.organization(orgID).app(appUid).installation(installationUid).installationData() - .then((installation) => { - expect(installation).to.not.equal(null) - done() - }).catch(done) - }) - - it('Get configuration for installation test', done => { - client.organization(orgID).app(appUid).installation(installationUid).configuration() - .then((config) => { - expect(config).to.not.equal(null) - done() - }).catch(done) - }) - it('Set configuration for installation test', done => { - client.organization(orgID).app(appUid).installation(installationUid).setConfiguration({}) - .then((config) => { - expect(config.data).to.deep.equal({}) - done() - }).catch(done) - }) - it('Get server config for installation test', done => { - client.organization(orgID).app(appUid).installation(installationUid).serverConfig() - .then((config) => { - expect(config).to.not.equal(null) - done() - }).catch(done) - }) - it('Set server config for installation test', done => { - client.organization(orgID).app(appUid).installation(installationUid).setServerConfig({}) - .then((config) => { - expect(config.data).to.deep.equal({}) - done() - }).catch(done) - }) - - it('Fetch installation test', done => { - client.organization(orgID).app(appUid).installation(installationUid).fetch() - .then((installation) => { - expect(installation.uid).to.be.equal(installationUid) - expect(installation.params.organization_uid).to.be.equal(orgID) - expect(installation.urlPath).to.be.equal(`/installations/${installation.uid}`) - expect(installation.target.type).to.be.equal('organization') - expect(installation.target.uid).to.be.equal(orgID) - expect(installation.status).to.be.equal('installed') - done() - }).catch(done) - }) - it('test fetch app request', done => { - client.organization(orgID).app(appUid) - .getRequests() - .then((response) => { - expect(response.data).to.not.equal(undefined) - done() - }) - .catch(done) - }) -}) diff --git a/test/api/asset-test.js b/test/api/asset-test.js deleted file mode 100644 index 0a534fa6..00000000 --- a/test/api/asset-test.js +++ /dev/null @@ -1,219 +0,0 @@ -import path from 'path' -import { expect } from 'chai' -import { describe, it, setup } from 'mocha' -import { jsonReader, writeDownloadedFile } from '../utility/fileOperations/readwrite' -import { contentstackClient } from '../utility/ContentstackClient.js' - -var client = {} -var stack = {} - -var folderUID = '' -var assetUID = '' -var publishAssetUID = '' -var assetURL = '' -describe('Assets api Test', () => { - setup(() => { - const user = jsonReader('loggedinuser.json') - stack = jsonReader('stack.json') - client = contentstackClient(user.authtoken) - }) - - it('Asset Upload ', done => { - const asset = { - upload: path.join(__dirname, './mock/customUpload.html'), - title: 'customasset', - description: 'Custom Asset Desc', - tags: ['Custom'] - } - makeAsset().create(asset) - .then((asset) => { - assetUID = asset.uid - assetURL = asset.url - expect(asset.uid).to.be.not.equal(null) - expect(asset.url).to.be.not.equal(null) - expect(asset.filename).to.be.equal('customUpload.html') - expect(asset.title).to.be.equal('customasset') - expect(asset.description).to.be.equal('Custom Asset Desc') - expect(asset.content_type).to.be.equal('text/html') - done() - }) - .catch(done) - }) - - it('Download asset from URL.', done => { - makeAsset().download({ url: assetURL, responseType: 'stream' }) - .then((response) => { - writeDownloadedFile(response, 'asset1') - done() - }).catch(done) - }) - it('Download asset from fetch details ', done => { - makeAsset(assetUID).fetch() - .then((asset) => asset.download({ responseType: 'stream' })) - .then((response) => { - writeDownloadedFile(response, 'asset2') - done() - }).catch(done) - }) - - it('Create folder ', done => { - makeAsset().folder().create({ asset: { name: 'Sample Folder' } }) - .then((asset) => { - folderUID = asset.uid - expect(asset.uid).to.be.not.equal(null) - expect(asset.name).to.be.equal('Sample Folder') - expect(asset.is_dir).to.be.equal(true) - done() - }) - .catch(done) - }) - - it('Asset Upload in folder', done => { - const asset = { - upload: path.join(__dirname, './mock/customUpload.html'), - title: 'customasset in Folder', - description: 'Custom Asset Desc in Folder', - parent_uid: folderUID, - tags: 'folder' - } - makeAsset().create(asset) - .then((asset) => { - publishAssetUID = asset.uid - expect(asset.uid).to.be.not.equal(null) - expect(asset.url).to.be.not.equal(null) - expect(asset.filename).to.be.equal('customUpload.html') - expect(asset.title).to.be.equal('customasset in Folder') - expect(asset.description).to.be.equal('Custom Asset Desc in Folder') - expect(asset.content_type).to.be.equal('text/html') - expect(asset.parent_uid).to.be.equal(folderUID) - done() - }) - .catch(done) - }) - - it('Asset Upload in folder with contenttype', done => { - const asset = { - upload: path.join(__dirname, './mock/berries.jfif'), - title: 'customasset2 in Folder', - description: 'Custom Asset Desc in Folder', - parent_uid: folderUID, - tags: 'folder', - content_type: 'image/jpeg' - } - makeAsset().create(asset) - .then((asset) => { - publishAssetUID = asset.uid - expect(asset.uid).to.be.not.equal(null) - expect(asset.url).to.be.not.equal(null) - expect(asset.filename).to.be.equal('berries.jfif') - expect(asset.title).to.be.equal('customasset2 in Folder') - expect(asset.description).to.be.equal('Custom Asset Desc in Folder') - expect(asset.content_type).to.be.equal('image/jpeg') - expect(asset.parent_uid).to.be.equal(folderUID) - done() - }) - .catch(done) - }) - it('Replace asset ', done => { - const asset = { - upload: path.join(__dirname, './mock/upload.html') - } - makeAsset(assetUID) - .replace(asset) - .then((asset) => { - expect(asset.uid).to.be.equal(assetUID) - expect(asset.filename).to.be.equal('upload.html') - expect(asset.content_type).to.be.equal('text/html') - done() - }) - .catch(done) - }) - - it('Fetch and Update asset details', done => { - makeAsset(assetUID) - .fetch() - .then((asset) => { - asset.title = 'Update title' - asset.description = 'Update description' - delete asset.ACL - return asset.update() - }) - .then((asset) => { - expect(asset.uid).to.be.equal(assetUID) - expect(asset.title).to.be.equal('Update title') - expect(asset.description).to.be.equal('Update description') - done() - }) - .catch(done) - }) - - it('Publish Asset', done => { - makeAsset(publishAssetUID) - .publish({ publishDetails: { - locales: ['hi-in', 'en-us'], - environments: ['development'] - } }) - .then((data) => { - expect(data.notice).to.be.equal('Asset sent for publishing.') - done() - }) - .catch(done) - }) - - it('Unpublish Asset', done => { - makeAsset(publishAssetUID) - .unpublish({ publishDetails: { - locales: ['hi-in', 'en-us'], - environments: ['development'] - } }) - .then((data) => { - expect(data.notice).to.be.equal('Asset sent for unpublishing.') - done() - }) - .catch(done) - }) - - it('Delete asset', done => { - makeAsset(assetUID) - .delete() - .then((data) => { - expect(data.notice).to.be.equal('Asset deleted successfully.') - done() - }) - .catch(done) - }) - - it('Query to fetch all asset', done => { - makeAsset() - .query() - .find() - .then((collection) => { - collection.items.forEach((asset) => { - expect(asset.uid).to.be.not.equal(null) - expect(asset.title).to.be.not.equal(null) - expect(asset.description).to.be.not.equal(null) - }) - done() - }) - .catch(done) - }) - - it('Query to fetch title match asset', done => { - makeAsset() - .query({ query: { title: 'Update title' } }) - .find() - .then((collection) => { - collection.items.forEach((asset) => { - expect(asset.uid).to.be.not.equal(null) - expect(asset.title).to.be.equal('Update title') - expect(asset.description).to.be.equal('Update description') - }) - done() - }) - .catch(done) - }) -}) - -function makeAsset (uid = null) { - return client.stack({ api_key: stack.api_key }).asset(uid) -} diff --git a/test/api/authorization-test.js b/test/api/authorization-test.js deleted file mode 100644 index a37e9319..00000000 --- a/test/api/authorization-test.js +++ /dev/null @@ -1,46 +0,0 @@ -import dotenv from 'dotenv' -import { describe, it, setup } from 'mocha' -import { jsonReader } from '../utility/fileOperations/readwrite' -import { contentstackClient } from '../utility/ContentstackClient.js' -import { expect } from 'chai' - -dotenv.config() - -const orgID = process.env.ORGANIZATION -let client = {} -let apps = {} - -describe('Apps api Test', () => { - setup(() => { - const user = jsonReader('loggedinuser.json') - client = contentstackClient(user.authtoken) - apps = jsonReader('apps.json') - }) - - it('fetch all authorization apps test', done => { - client.organization(orgID).app(apps.uid).authorization().findAll() - .then((response) => { - expect(response).to.not.equal(null) - done() - }) - .catch(done) - }) - - it('revoke all authorization apps test', done => { - client.organization(orgID).app(apps.uid).authorization().revokeAll() - .then((response) => { - expect(response).to.not.equal(null) - done() - }) - .catch(done) - }) - - it('revoke all authorization apps test', done => { - client.organization(orgID).app(apps.uid).authorization().revoke('uid') - .then((response) => { - expect(response).to.not.equal(null) - done() - }) - .catch(done) - }) -}) diff --git a/test/api/branch-test.js b/test/api/branch-test.js deleted file mode 100644 index 69237d6e..00000000 --- a/test/api/branch-test.js +++ /dev/null @@ -1,222 +0,0 @@ -import { expect } from 'chai' -import { describe, it, setup } from 'mocha' -import { jsonReader } from '../utility/fileOperations/readwrite' -import { contentstackClient } from '../utility/ContentstackClient.js' -import { branch, devBranch } from './mock/branch' - -var client = {} -var stack = {} - -describe('Branch api Test', () => { - setup(() => { - const user = jsonReader('loggedinuser.json') - stack = jsonReader('stack.json') - client = contentstackClient(user.authtoken) - }) - - it('Branch query should return master branch', done => { - makeBranch() - .query() - .find() - .then((response) => { - expect(response.items.length).to.be.equal(1) - var item = response.items[0] - expect(item.urlPath).to.be.equal(`/stacks/branches/${item.uid}`) - expect(item.delete).to.not.equal(undefined) - expect(item.fetch).to.not.equal(undefined) - done() - }) - .catch(done) - }) - - it('Should create Branch', done => { - makeBranch() - .create({ branch }) - .then((response) => { - expect(response.uid).to.be.equal(branch.uid) - expect(response.urlPath).to.be.equal(`/stacks/branches/${branch.uid}`) - expect(response.source).to.be.equal(branch.source) - expect(response.alias).to.not.equal(undefined) - expect(response.delete).to.not.equal(undefined) - expect(response.fetch).to.not.equal(undefined) - done() - }) - .catch(done) - }) - - it('Should create Branch from staging', done => { - makeBranch() - .create({ branch: devBranch }) - .then((response) => { - expect(response.uid).to.be.equal(devBranch.uid) - expect(response.urlPath).to.be.equal(`/stacks/branches/${devBranch.uid}`) - expect(response.source).to.be.equal(devBranch.source) - expect(response.alias).to.not.equal(undefined) - expect(response.delete).to.not.equal(undefined) - expect(response.fetch).to.not.equal(undefined) - done() - }) - .catch(done) - }) - - it('Should fetch branch from branch uid', done => { - makeBranch(devBranch.uid) - .fetch() - .then((response) => { - expect(response.uid).to.be.equal(devBranch.uid) - expect(response.urlPath).to.be.equal(`/stacks/branches/${devBranch.uid}`) - expect(response.source).to.be.equal(devBranch.source) - expect(response.alias).to.not.equal(undefined) - expect(response.delete).to.not.equal(undefined) - expect(response.fetch).to.not.equal(undefined) - done() - }) - .catch(done) - }) - - it('Branch query should return all branches', done => { - makeBranch() - .query() - .find() - .then((response) => { - expect(response.items.length).to.be.equal(3) - response.items.forEach(item => { - expect(item.urlPath).to.be.equal(`/stacks/branches/${item.uid}`) - expect(item.delete).to.not.equal(undefined) - expect(item.fetch).to.not.equal(undefined) - }) - done() - }) - .catch(done) - }) - - it('Branch query for specific condition', done => { - makeBranch() - .query({ query: { source: 'master' } }) - .find() - .then((response) => { - expect(response.items.length).to.be.equal(1) - response.items.forEach(item => { - expect(item.urlPath).to.be.equal(`/stacks/branches/${item.uid}`) - expect(item.source).to.be.equal(`master`) - expect(item.delete).to.not.equal(undefined) - expect(item.fetch).to.not.equal(undefined) - }) - done() - }) - .catch(done) - }) - - it('Should delete branch from branch uid', done => { - makeBranch(devBranch.uid) - .delete() - .then((response) => { - expect(response.notice).to.be.equal('Branch deleted successfully.') - done() - }) - .catch(done) - }) - - it('Should provide list of content types and global fields that exist in only one branch or are different between the two branches', done => { - makeBranch(branch.uid) - .compare(devBranch.uid) - .all() - .then((response) => { - expect(response.branches.base_branch).to.be.equal(branch.uid) - expect(response.branches.compare_branch).to.be.equal(devBranch.uid) - done() - }) - .catch(done) - }) - - it('Should list differences for a content types between two branches', done => { - makeBranch(branch.uid) - .compare(devBranch.uid) - .contentTypes() - .then((response) => { - expect(response.branches.base_branch).to.be.equal(branch.uid) - expect(response.branches.compare_branch).to.be.equal(devBranch.uid) - done() - }) - .catch(done) - }) - - it('Should list differences for a global fields between two branches', done => { - makeBranch(branch.uid) - .compare(devBranch.uid) - .globalFields() - .then((response) => { - expect(response.branches.base_branch).to.be.equal(branch.uid) - expect(response.branches.compare_branch).to.be.equal(devBranch.uid) - done() - }) - .catch(done) - }) - - it('Should provide list of global fields that exist in only one branch or are different between the two branches', done => { - const params = { - base_branch: branch.uid, - compare_branch: devBranch.uid, - default_merge_strategy: 'ignore', - merge_comment: 'Merging dev into main' - } - const mergeObj = { - item_merge_strategies: [ - { - uid: 'global_field_uid', - type: 'global_field', - merge_strategy: 'merge_prefer_base' - }, - { - uid: 'ct5', - type: 'content_type', - merge_strategy: 'merge_prefer_compare' - }, - { - uid: 'bot_all', - type: 'content_type', - merge_strategy: 'merge_prefer_base' - } - ] - } - makeBranch() - .merge(mergeObj, params) - .then((response) => { - expect(response.merge_details.base_branch).to.be.equal(branch.uid) - expect(response.merge_details.compare_branch).to.be.equal(devBranch.uid) - done() - }) - .catch(done) - }) - - it('Should list all recent merge jobs', done => { - makeBranch() - .mergeQueue() - .find() - .then((response) => { - expect(response.queue).to.not.equal(undefined) - expect(response.queue[0].merge_details.base_branch).to.be.equal(branch.uid) - expect(response.queue[0].merge_details.compare_branch).to.be.equal(devBranch.uid) - done() - }) - .catch(done) - }) - - it('Should list details of merge job when job uid is passed', done => { - const mergeJobUid = 'db7bf199-2a9d-4c2c-99d5-72453f70fb40' - makeBranch() - .mergeQueue(mergeJobUid) - .fetch() - .then((response) => { - expect(response.queue).to.not.equal(undefined) - expect(response.queue[0].merge_details.base_branch).to.be.equal(branch.uid) - expect(response.queue[0].merge_details.compare_branch).to.be.equal(devBranch.uid) - done() - }) - .catch(done) - }) -}) - -function makeBranch (uid = null) { - return client.stack({ api_key: stack.api_key }).branch(uid) -} diff --git a/test/api/branchAlias-test.js b/test/api/branchAlias-test.js deleted file mode 100644 index 688058c9..00000000 --- a/test/api/branchAlias-test.js +++ /dev/null @@ -1,78 +0,0 @@ -import { expect } from 'chai' -import { describe, it, setup } from 'mocha' -import { jsonReader } from '../utility/fileOperations/readwrite' -import { contentstackClient } from '../utility/ContentstackClient.js' -import { branch } from './mock/branch' - -var client = {} -var stack = {} - -describe('Branch Alias api Test', () => { - setup(() => { - const user = jsonReader('loggedinuser.json') - stack = jsonReader('stack.json') - client = contentstackClient(user.authtoken) - }) - - it('Should create Branch Alias', done => { - makeBranchAlias(`${branch.uid}_alias`) - .createOrUpdate(branch.uid) - .then((response) => { - expect(response.uid).to.be.equal(branch.uid) - expect(response.urlPath).to.be.equal(`/stacks/branches/${branch.uid}`) - expect(response.source).to.be.equal(branch.source) - expect(response.alias).to.be.equal(`${branch.uid}_alias`) - expect(response.delete).to.not.equal(undefined) - expect(response.fetch).to.not.equal(undefined) - done() - }) - .catch(done) - }) - - it('Branch query should return master branch', done => { - makeBranchAlias() - .fetchAll({ query: { uid: branch.uid } }) - .then((response) => { - expect(response.items.length).to.be.equal(1) - var item = response.items[0] - expect(item.urlPath).to.be.equal(`/stacks/branches/${branch.uid}`) - expect(item.delete).to.not.equal(undefined) - expect(item.fetch).to.not.equal(undefined) - done() - }) - .catch(done) - }) - - it('Should fetch Branch Alias', done => { - makeBranchAlias(`${branch.uid}_alias`) - .fetch() - .then((response) => { - expect(response.uid).to.be.equal(branch.uid) - expect(response.urlPath).to.be.equal(`/stacks/branches/${branch.uid}`) - expect(response.source).to.be.equal(branch.source) - expect(response.alias).to.be.equal(`${branch.uid}_alias`) - expect(response.delete).to.not.equal(undefined) - expect(response.fetch).to.not.equal(undefined) - done() - }) - .catch(done) - }) - - it('Should delete Branch Alias', done => { - try { - makeBranchAlias(`${branch.uid}_alias`) - .delete() - .then((response) => { - expect(response.notice).to.be.equal('BranchAlias deleted successfully.') - done() - }) - .catch(done) - } catch (e) { - done() - } - }) -}) - -function makeBranchAlias (uid = null) { - return client.stack({ api_key: stack.api_key }).branchAlias(uid) -} diff --git a/test/api/bulkOperation-test.js b/test/api/bulkOperation-test.js deleted file mode 100644 index 7fc2ff2d..00000000 --- a/test/api/bulkOperation-test.js +++ /dev/null @@ -1,109 +0,0 @@ -import { expect } from 'chai' -import { describe, it, setup } from 'mocha' -import { jsonReader } from '../utility/fileOperations/readwrite' -import { contentstackClient } from '../utility/ContentstackClient.js' - -var client = {} -var stack = {} - -describe('BulkOperation api test', () => { - setup(() => { - const user = jsonReader('loggedinuser.json') - stack = jsonReader('stack.json') - client = contentstackClient(user.authtoken) - }) - - it('should publish one entry when publishDetails of an entry is passed', done => { - const publishDetails = { - entries: [ - { - uid: 'blte6542a9aac484405', - content_type: 'bye', - version: 1, - locale: 'en-us' - } - ], - locales: [ - 'en-us' - ], - environments: [ - 'dev' - ] - } - doBulkOperation() - .publish({ details: publishDetails, api_version: '3.2' }) - .then((response) => { - expect(response.notice).to.not.equal(undefined) - expect(response.job_id).to.not.equal(undefined) - done() - }) - .catch(done) - }) - - it('should publish one asset when publishDetails of an asset is passed', done => { - const publishDetails = { - assets: [ - { - uid: 'blt9f8e5aa45ac36455' - } - ], - locales: [ - 'en-us' - ], - environments: [ - 'dev' - ] - } - doBulkOperation() - .publish({ details: publishDetails, api_version: '3.2' }) - .then((response) => { - expect(response.notice).to.not.equal(undefined) - expect(response.job_id).to.not.equal(undefined) - done() - }) - .catch(done) - }) - - it('should publish multiple entries assets when publishDetails of entries and assets are passed', done => { - const publishDetails = { - entries: [ - { - uid: 'blt077157784a170bab', - content_type: 'bye', - version: 1, - locale: 'en-us' - }, { - uid: 'blta519039712ca2b8a', - content_type: 'bye', - version: 1, - locale: 'en-us' - } - ], - assets: [ - { - uid: 'blt9f8e5aa45ac36455' - }, { - uid: 'blt3b097cc58475b0a3' - } - ], - locales: [ - 'en-us' - ], - environments: [ - 'dev' - ] - } - doBulkOperation() - .publish({ details: publishDetails, api_version: '3.2' }) - .then((response) => { - expect(response.notice).to.not.equal(undefined) - expect(response.job_id).to.not.equal(undefined) - done() - }) - .catch(done) - }) -}) - -function doBulkOperation (uid = null) { - return client.stack({ api_key: stack.api_key }).bulkOperation() -} diff --git a/test/api/contentType-delete-test.js b/test/api/contentType-delete-test.js deleted file mode 100644 index bd5bf5cb..00000000 --- a/test/api/contentType-delete-test.js +++ /dev/null @@ -1,29 +0,0 @@ -import { expect } from 'chai' -import { describe, it, setup } from 'mocha' -import { jsonReader } from '../utility/fileOperations/readwrite' -import { multiPageCT } from './mock/content-type' -import { contentstackClient } from '../utility/ContentstackClient.js' - -var client = {} - -var stack = {} -describe('Content Type delete api Test', () => { - setup(() => { - const user = jsonReader('loggedinuser.json') - stack = jsonReader('stack.json') - client = contentstackClient(user.authtoken) - }) - - it('Content Type delete', done => { - makeContentType(multiPageCT.content_type.uid) - .delete().then((data) => { - expect(data.notice).to.be.equal('Content Type deleted successfully.') - done() - }) - .catch(done) - }) -}) - -function makeContentType (uid = null) { - return client.stack({ api_key: stack.api_key }).contentType(uid) -} diff --git a/test/api/contentType-test.js b/test/api/contentType-test.js deleted file mode 100644 index 6f104234..00000000 --- a/test/api/contentType-test.js +++ /dev/null @@ -1,121 +0,0 @@ -import path from 'path' -import { expect } from 'chai' -import { describe, it, setup } from 'mocha' -import { jsonReader } from '../utility/fileOperations/readwrite' -import { singlepageCT, multiPageCT, schema } from './mock/content-type' -import { contentstackClient } from '../utility/ContentstackClient.js' - -var client = {} - -var stack = {} -describe('Content Type api Test', () => { - setup(() => { - const user = jsonReader('loggedinuser.json') - stack = jsonReader('stack.json') - client = contentstackClient(user.authtoken) - }) - - it('Create Single page ContentType Schema', done => { - makeContentType() - .create(singlepageCT) - .then((contentType) => { - expect(contentType.uid).to.be.equal(singlepageCT.content_type.uid) - expect(contentType.title).to.be.equal(singlepageCT.content_type.title) - done() - }) - .catch(done) - }) - - it('Create Multi page ContentType Schema', done => { - makeContentType() - .create(multiPageCT) - .then((contentType) => { - expect(contentType.uid).to.be.equal(multiPageCT.content_type.uid) - expect(contentType.title).to.be.equal(multiPageCT.content_type.title) - done() - }) - .catch(done) - }) - - it('Get all ContentType', done => { - makeContentType() - .query() - .find() - .then((response) => { - response.items.forEach(contentType => { - expect(contentType.uid).to.be.not.equal(null) - expect(contentType.title).to.be.not.equal(null) - expect(contentType.schema).to.be.not.equal(null) - }) - done() - }) - .catch(done) - }) - - it('Query ContentType title', done => { - makeContentType() - .query({ query: { title: singlepageCT.content_type.title } }) - .find() - .then((response) => { - response.items.forEach(contentType => { - expect(contentType.uid).to.be.not.equal(null) - expect(contentType.title).to.be.not.equal(null) - expect(contentType.schema).to.be.not.equal(null) - expect(contentType.uid).to.be.equal(singlepageCT.content_type.uid, 'UID not mathcing') - expect(contentType.title).to.be.equal(singlepageCT.content_type.title, 'Title not mathcing') - }) - done() - }) - .catch(done) - }) - - it('Fetch ContentType from uid', done => { - makeContentType(multiPageCT.content_type.uid) - .fetch() - .then((contentType) => { - expect(contentType.uid).to.be.equal(multiPageCT.content_type.uid) - expect(contentType.title).to.be.equal(multiPageCT.content_type.title) - done() - }) - .catch(done) - }) - - it('Fetch and Update ContentType schema', done => { - makeContentType(multiPageCT.content_type.uid) - .fetch() - .then((contentType) => { - contentType.schema = schema - return contentType.update() - }) - .then((contentType) => { - expect(contentType.schema.length).to.be.equal(6) - done() - }) - .catch(done) - }) - - it('Update ContentType schema without fetch', done => { - makeContentType(multiPageCT.content_type.uid) - .updateCT({ content_type: { schema: schema } }) - .then((contentType) => { - expect(contentType.schema.length).to.be.equal(6) - done() - }) - .catch(done) - }) - - it('Import content type', done => { - makeContentType().import({ - content_type: path.join(__dirname, './mock/contentType.json') - }) - .then((response) => { - expect(response.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) -}) - -function makeContentType (uid = null) { - return client.stack({ api_key: stack.api_key }).contentType(uid) -} diff --git a/test/api/delete-test.js b/test/api/delete-test.js deleted file mode 100644 index 9276d10d..00000000 --- a/test/api/delete-test.js +++ /dev/null @@ -1,35 +0,0 @@ - -import { expect } from 'chai' -import { describe, it, setup } from 'mocha' -import { jsonReader } from '../utility/fileOperations/readwrite' -import { contentstackClient } from '../utility/ContentstackClient.js' -var client = {} - -var stack = {} -describe('Delete api Test', () => { - setup(() => { - const user = jsonReader('loggedinuser.json') - stack = jsonReader('stack.json') - client = contentstackClient(user.authtoken) - }) - - it('Delete role in stack', done => { - const role = jsonReader('role.json') - client.stack({ api_key: stack.api_key }).role(role.uid) - .delete() - .then((data) => { - expect(data.notice).to.be.equal('The role deleted successfully.', 'Role delete notice does not match') - done() - }) - .catch(done) - }) - - it('User logout test', done => { - client.logout() - .then((response) => { - expect(response.notice).to.be.equal('You\'ve logged out successfully.') - done() - }) - .catch(done) - }) -}) diff --git a/test/api/deliveryToken-test.js b/test/api/deliveryToken-test.js deleted file mode 100644 index 3218b757..00000000 --- a/test/api/deliveryToken-test.js +++ /dev/null @@ -1,143 +0,0 @@ -import { expect } from 'chai' -import { describe, it, setup } from 'mocha' -import { jsonReader } from '../utility/fileOperations/readwrite' -import { createDeliveryToken, createDeliveryToken2 } from './mock/deliveryToken.js' -import { contentstackClient } from '../utility/ContentstackClient.js' - -var client = {} - -var stack = {} -var tokenUID = '' -describe('Delivery Token api Test', () => { - setup(() => { - const user = jsonReader('loggedinuser.json') - stack = jsonReader('stack.json') - client = contentstackClient(user.authtoken) - }) - - it('Add a Delivery Token', done => { - makeDeliveryToken() - .create(createDeliveryToken) - .then((token) => { - expect(token.name).to.be.equal(createDeliveryToken.token.name) - expect(token.description).to.be.equal(createDeliveryToken.token.description) - expect(token.scope[0].environments[0].name).to.be.equal(createDeliveryToken.token.scope[0].environments[0]) - expect(token.scope[0].module).to.be.equal(createDeliveryToken.token.scope[0].module) - expect(token.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Add a Delivery Token for production', done => { - makeDeliveryToken() - .create(createDeliveryToken2) - .then((token) => { - tokenUID = token.uid - expect(token.name).to.be.equal(createDeliveryToken2.token.name) - expect(token.description).to.be.equal(createDeliveryToken2.token.description) - expect(token.scope[0].environments[0].name).to.be.equal(createDeliveryToken2.token.scope[0].environments[0]) - expect(token.scope[0].module).to.be.equal(createDeliveryToken2.token.scope[0].module) - expect(token.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Get a Delivery Token from uid', done => { - makeDeliveryToken(tokenUID) - .fetch() - .then((token) => { - expect(token.name).to.be.equal(createDeliveryToken2.token.name) - expect(token.description).to.be.equal(createDeliveryToken2.token.description) - expect(token.scope[0].environments[0].name).to.be.equal(createDeliveryToken2.token.scope[0].environments[0]) - expect(token.scope[0].module).to.be.equal(createDeliveryToken2.token.scope[0].module) - expect(token.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Query to get all Delivery Token', done => { - makeDeliveryToken() - .query() - .find() - .then((tokens) => { - tokens.items.forEach((token) => { - expect(token.name).to.be.not.equal(null) - expect(token.description).to.be.not.equal(null) - expect(token.scope[0].environments[0].name).to.be.not.equal(null) - expect(token.scope[0].module).to.be.not.equal(null) - expect(token.uid).to.be.not.equal(null) - }) - done() - }) - .catch(done) - }) - - it('Query to get a Delivery Token from name', done => { - makeDeliveryToken() - .query({ query: { name: createDeliveryToken.token.name } }) - .find() - .then((tokens) => { - tokens.items.forEach((token) => { - expect(token.name).to.be.equal(createDeliveryToken.token.name) - expect(token.description).to.be.equal(createDeliveryToken.token.description) - expect(token.scope[0].environments[0].name).to.be.equal(createDeliveryToken.token.scope[0].environments[0]) - expect(token.scope[0].module).to.be.equal(createDeliveryToken.token.scope[0].module) - expect(token.uid).to.be.not.equal(null) - }) - done() - }) - .catch(done) - }) - - it('Fetch and update a Delivery Token from uid', done => { - makeDeliveryToken(tokenUID) - .fetch() - .then((token) => { - token.name = 'Update Production Name' - token.description = 'Update Production description' - token.scope = createDeliveryToken2.token.scope - return token.update() - }) - .then((token) => { - expect(token.name).to.be.equal('Update Production Name') - expect(token.description).to.be.equal('Update Production description') - expect(token.scope[0].environments[0].name).to.be.equal(createDeliveryToken2.token.scope[0].environments[0]) - expect(token.scope[0].module).to.be.equal(createDeliveryToken2.token.scope[0].module) - expect(token.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Update a Delivery Token from uid', done => { - const token = makeDeliveryToken(tokenUID) - Object.assign(token, createDeliveryToken2.token) - token.update() - .then((token) => { - expect(token.name).to.be.equal(createDeliveryToken2.token.name) - expect(token.description).to.be.equal(createDeliveryToken2.token.description) - expect(token.scope[0].environments[0].name).to.be.equal(createDeliveryToken2.token.scope[0].environments[0]) - expect(token.scope[0].module).to.be.equal(createDeliveryToken2.token.scope[0].module) - expect(token.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Delete a Delivery Token from uid', done => { - makeDeliveryToken(tokenUID) - .delete() - .then((data) => { - expect(data.notice).to.be.equal('Delivery Token deleted successfully.') - done() - }) - .catch(done) - }) -}) - -function makeDeliveryToken (uid = null) { - return client.stack({ api_key: stack.api_key }).deliveryToken(uid) -} diff --git a/test/api/entry-test.js b/test/api/entry-test.js deleted file mode 100644 index af97ad76..00000000 --- a/test/api/entry-test.js +++ /dev/null @@ -1,234 +0,0 @@ -import path from 'path' -import { expect } from 'chai' -import { describe, it, setup } from 'mocha' -import { jsonReader, jsonWrite } from '../utility/fileOperations/readwrite' -import { multiPageCT, singlepageCT } from './mock/content-type.js' -import { entryFirst, entrySecond, entryThird } from './mock/entry.js' -import { contentstackClient } from '../utility/ContentstackClient.js' - -var client = {} - -var stack = {} -var entryUTD = '' -describe('Entry api Test', () => { - setup(() => { - const user = jsonReader('loggedinuser.json') - stack = jsonReader('stack.json') - client = contentstackClient(user.authtoken) - }) - - it('Create Entry in Single ', done => { - var entry = { - title: 'Sample Entry', - url: 'sampleEntry' - } - makeEntry(singlepageCT.content_type.uid) - .create({ entry }) - .then((entryResponse) => { - entryUTD = entryResponse.uid - expect(entryResponse.title).to.be.equal(entry.title) - expect(entryResponse.url).to.be.equal(entry.url) - expect(entryResponse.uid).to.be.not.equal(null) - expect(entryResponse.locale).to.be.equal(stack.master_locale) - done() - }) - .catch(done) - }) - it('Entry fetch with Content Type', done => { - makeEntry(singlepageCT.content_type.uid, entryUTD) - .fetch({ include_content_type: true }) - .then((entryResponse) => { - expect(entryResponse.uid).to.be.not.equal(null) - expect(entryResponse.content_type).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Localize entry with title update', done => { - makeEntry(singlepageCT.content_type.uid, entryUTD) - .fetch() - .then((entry) => { - entry.title = 'Sample Entry in en-at' - return entry.update({ locale: 'en-at' }) - }) - .then((entryResponse) => { - entryUTD = entryResponse.uid - expect(entryResponse.title).to.be.equal('Sample Entry in en-at') - expect(entryResponse.uid).to.be.not.equal(null) - expect(entryResponse.locale).to.be.equal('en-at') - done() - }) - .catch(done) - }) - - it('Create Entries for Multiple page', done => { - makeEntry(multiPageCT.content_type.uid) - .create({ entry: entryFirst }) - .then((entry) => { - expect(entry.uid).to.be.not.equal(null) - expect(entry.title).to.be.equal(entryFirst.title) - expect(entry.single_line).to.be.equal(entryFirst.single_line) - expect(entry.url).to.be.equal(`/${entryFirst.title.toLowerCase().replace(/ /g, '-')}`) - expect(entry.multi_line).to.be.equal(entryFirst.multi_line) - expect(entry.markdown).to.be.equal(entryFirst.markdown) - done() - }) - .catch(done) - }) - - it('Create Entries 2 for Multiple page', done => { - makeEntry(multiPageCT.content_type.uid) - .create({ entry: entrySecond }) - .then((entry) => { - expect(entry.uid).to.be.not.equal(null) - expect(entry.title).to.be.equal(entrySecond.title) - expect(entry.url).to.be.equal(`/${entrySecond.title.toLowerCase().replace(/ /g, '-')}`) - expect(entry.single_line).to.be.equal(entrySecond.single_line) - expect(entry.multi_line).to.be.equal(entrySecond.multi_line) - expect(entry.markdown).to.be.equal(entrySecond.markdown) - expect(entry.tags[0]).to.be.equal(entrySecond.tags[0]) - done() - }) - .catch(done) - }) - - it('Create Entries 3 for Multiple page', done => { - makeEntry(multiPageCT.content_type.uid) - .create({ entry: entryThird }) - .then((entry) => { - expect(entry.uid).to.be.not.equal(null) - expect(entry.title).to.be.equal(entryThird.title) - expect(entry.url).to.be.equal(`/${entryThird.title.toLowerCase().replace(/ /g, '-')}`) - expect(entry.single_line).to.be.equal(entryThird.single_line) - expect(entry.multi_line).to.be.equal(entryThird.multi_line) - expect(entry.markdown).to.be.equal(entryThird.markdown) - expect(entry.tags[0]).to.be.equal(entryThird.tags[0]) - done() - }) - .catch(done) - }) - - it('Get all Entry', done => { - makeEntry(multiPageCT.content_type.uid) - .query({ include_count: true, include_content_type: true }).find() - .then((collection) => { - jsonWrite(collection.items, 'entry.json') - expect(collection.count).to.be.equal(3) - collection.items.forEach((entry) => { - expect(entry.uid).to.be.not.equal(null) - expect(entry.content_type_uid).to.be.equal(multiPageCT.content_type.uid) - }) - done() - }) - .catch(done) - }) - - it('Get all Entry from tag', done => { - makeEntry(multiPageCT.content_type.uid) - .query({ include_count: true, query: { tags: entrySecond.tags[0] } }).find() - .then((collection) => { - expect(collection.count).to.be.equal(1) - collection.items.forEach((entry) => { - expect(entry.uid).to.be.not.equal(null) - expect(entry.tags).to.have.all.keys(0) - }) - done() - }) - .catch(done) - }) - - it('Publish Entry', done => { - makeEntry(singlepageCT.content_type.uid, entryUTD) - .publish({ publishDetails: { - locales: ['en-us'], - environments: ['development'] - } }) - .then((data) => { - expect(data.notice).to.be.equal('The requested action has been performed.') - done() - }) - .catch(done) - }) - - it('Publish localized Entry to locales', done => { - makeEntry(singlepageCT.content_type.uid, entryUTD) - .publish({ publishDetails: { - locales: ['hi-in', 'en-at'], - environments: ['development'] - }, - locale: 'en-at' }) - .then((data) => { - expect(data.notice).to.be.equal('The requested action has been performed.') - done() - }) - .catch(done) - }) - - it('Unpublish localized entry', done => { - makeEntry(singlepageCT.content_type.uid, entryUTD) - .unpublish({ publishDetails: { - locales: ['hi-in', 'en-at'], - environments: ['development'] - }, - locale: 'en-at' }) - .then((data) => { - expect(data.notice).to.be.equal('The requested action has been performed.') - done() - }) - .catch(done) - }) - - it('Import Entry', done => { - makeEntry(multiPageCT.content_type.uid) - .import({ - entry: path.join(__dirname, './mock/entry.json') - }) - .then((response) => { - expect(response.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Create and update an entry with asset', done => { - // get asset - let asset - makeAsset() - .query() - .find() - .then((collection) => { - asset = collection.items[0] - // create entry - const entry = { - ...entryFirst, - title: 'uniqueTitle45', - modular_blocks: [ - { - block1: { - file: asset.uid - } - } - ] - } - makeEntry(multiPageCT.content_type.uid) - .create({ entry: entry }) - .then(entry => { - const newTitle = 'updated title' - entry.title = newTitle - entry.update().then(updatedEntry => { - expect(updatedEntry.title).to.be.equal(newTitle) - done() - }) - }) - }) - }) -}) - -function makeEntry (contentType, uid = null) { - return client.stack({ api_key: stack.api_key }).contentType(contentType).entry(uid) -} - -function makeAsset (uid = null) { - return client.stack({ api_key: stack.api_key }).asset(uid) -} diff --git a/test/api/environment-test.js b/test/api/environment-test.js deleted file mode 100644 index e462ee02..00000000 --- a/test/api/environment-test.js +++ /dev/null @@ -1,139 +0,0 @@ -import { expect } from 'chai' -import { describe, it, setup } from 'mocha' -import { jsonReader, jsonWrite } from '../utility/fileOperations/readwrite' -import { environmentCreate, environmentProdCreate } from './mock/environment.js' -import { cloneDeep } from 'lodash' -import { contentstackClient } from '../utility/ContentstackClient.js' - -var client = {} - -var stack = {} -describe('Environment api Test', () => { - setup(() => { - const user = jsonReader('loggedinuser.json') - stack = jsonReader('stack.json') - client = contentstackClient(user.authtoken) - }) - - it('Add a Environment development', done => { - makeEnvironment() - .create(environmentCreate) - .then((environment) => { - expect(environment.name).to.be.equal(environmentCreate.environment.name) - expect(environment.deploy_content).to.be.equal(environmentCreate.environment.deploy_content) - expect(environment.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Add a Environment production', done => { - makeEnvironment() - .create(environmentProdCreate) - .then((environment) => { - expect(environment.name).to.be.equal(environmentProdCreate.environment.name) - expect(environment.deploy_content).to.be.equal(environmentProdCreate.environment.deploy_content) - expect(environment.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Get a Environment development', done => { - makeEnvironment(environmentCreate.environment.name) - .fetch() - .then((environment) => { - expect(environment.name).to.be.equal(environmentCreate.environment.name) - expect(environment.deploy_content).to.be.equal(environmentCreate.environment.deploy_content) - expect(environment.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Query a Environment development', done => { - makeEnvironment() - .query({ query: { name: environmentCreate.environment.name } }) - .find() - .then((environments) => { - environments.items.forEach((environment) => { - expect(environment.name).to.be.equal(environmentCreate.environment.name) - expect(environment.deploy_content).to.be.equal(environmentCreate.environment.deploy_content) - expect(environment.uid).to.be.not.equal(null) - }) - done() - }) - .catch(done) - }) - - it('Fetch and Update a Environment', done => { - makeEnvironment(environmentCreate.environment.name) - .fetch() - .then((environment) => { - environment.name = 'dev' - return environment.update() - }) - .then((environment) => { - expect(environment.name).to.be.equal('dev') - expect(environment.deploy_content).to.be.equal(environmentCreate.environment.deploy_content) - expect(environment.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Update a Environment', done => { - var environment = makeEnvironment('dev') - Object.assign(environment, cloneDeep(environmentCreate.environment)) - environment.update() - .then((environment) => { - expect(environment.name).to.be.equal(environmentCreate.environment.name) - expect(environment.deploy_content).to.be.equal(environmentCreate.environment.deploy_content) - expect(environment.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('delete a Environment', done => { - makeEnvironment(environmentProdCreate.environment.name) - .delete() - .then((data) => { - expect(data.notice).to.be.equal('Environment deleted successfully.') - done() - }) - .catch(done) - }) - - it('Add a Environment production', done => { - makeEnvironment() - .create(environmentProdCreate) - .then((environment) => { - expect(environment.name).to.be.equal(environmentProdCreate.environment.name) - expect(environment.deploy_content).to.be.equal(environmentProdCreate.environment.deploy_content) - expect(environment.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Query all Environments', done => { - makeEnvironment() - .query() - .find() - .then((environments) => { - jsonWrite(environments.items, 'environments.json') - environments.items.forEach((environment) => { - expect(environment.name).to.be.not.equal(null) - expect(environment.deploy_content).to.be.not.equal(null) - expect(environment.uid).to.be.not.equal(null) - }) - done() - }) - .catch(done) - }) -}) - -function makeEnvironment (uid = null) { - return client.stack({ api_key: stack.api_key }).environment(uid) -} diff --git a/test/api/extension-test.js b/test/api/extension-test.js deleted file mode 100644 index 01fac1c4..00000000 --- a/test/api/extension-test.js +++ /dev/null @@ -1,296 +0,0 @@ -import path from 'path' -import { expect } from 'chai' -import { describe, it, setup } from 'mocha' -import { jsonReader } from '../utility/fileOperations/readwrite' -import { customFieldURL, customFieldSRC, customWidgetURL, customWidgetSRC, customDashboardURL, customDashboardSRC } from './mock/extension' -import { contentstackClient } from '../utility/ContentstackClient.js' -var client = {} -var stack = {} - -var customFieldUID = '' -var customWidgetUID = '' -var customDashboardUID = '' - -describe('Extension api Test', () => { - setup(() => { - const user = jsonReader('loggedinuser.json') - stack = jsonReader('stack.json') - client = contentstackClient(user.authtoken) - }) - it('Create Custom field with source URL', done => { - makeExtension() - .create(customFieldURL) - .then((extension) => { - expect(extension.uid).to.be.not.equal(null) - customFieldUID = extension.uid - expect(extension.title).to.be.equal(customFieldURL.extension.title) - expect(extension.src).to.be.equal(customFieldURL.extension.src) - expect(extension.type).to.be.equal(customFieldURL.extension.type) - expect(extension.tag).to.be.equal(customFieldURL.extension.tag) - done() - }) - .catch(done) - }) - - it('Create Custom field with source Code', done => { - makeExtension() - .create(customFieldSRC) - .then((extension) => { - expect(extension.uid).to.be.not.equal(null) - expect(extension.title).to.be.equal(customFieldSRC.extension.title) - expect(extension.src).to.be.equal(customFieldSRC.extension.src) - expect(extension.type).to.be.equal(customFieldSRC.extension.type) - expect(extension.tag).to.be.equal(customFieldSRC.extension.tag) - done() - }) - .catch(done) - }) - - it('Create Custom widget with source URL', done => { - makeExtension() - .create(customWidgetURL) - .then((extension) => { - expect(extension.uid).to.be.not.equal(null) - customWidgetUID = extension.uid - expect(extension.title).to.be.equal(customWidgetURL.extension.title) - expect(extension.src).to.be.equal(customWidgetURL.extension.src) - expect(extension.type).to.be.equal(customWidgetURL.extension.type) - expect(extension.tag).to.be.equal(customWidgetURL.extension.tag) - done() - }) - .catch(done) - }) - - it('Create Custom widget with source Code', done => { - makeExtension() - .create(customWidgetSRC) - .then((extension) => { - expect(extension.uid).to.be.not.equal(null) - expect(extension.title).to.be.equal(customWidgetSRC.extension.title) - expect(extension.src).to.be.equal(customWidgetSRC.extension.src) - expect(extension.type).to.be.equal(customWidgetSRC.extension.type) - expect(extension.tag).to.be.equal(customWidgetSRC.extension.tag) - done() - }) - .catch(done) - }) - - it('Create Custom dashboard with source URL', done => { - makeExtension() - .create(customDashboardURL) - .then((extension) => { - expect(extension.uid).to.be.not.equal(null) - customDashboardUID = extension.uid - expect(extension.title).to.be.equal(customDashboardURL.extension.title) - expect(extension.src).to.be.equal(customDashboardURL.extension.src) - expect(extension.type).to.be.equal(customDashboardURL.extension.type) - expect(extension.tag).to.be.equal(customDashboardURL.extension.tag) - done() - }) - .catch(done) - }) - - it('Create Custom dashboard with source Code', done => { - makeExtension() - .create(customDashboardSRC) - .then((extension) => { - expect(extension.uid).to.be.not.equal(null) - expect(extension.title).to.be.equal(customDashboardSRC.extension.title) - expect(extension.src).to.be.equal(customDashboardSRC.extension.src) - expect(extension.type).to.be.equal(customDashboardSRC.extension.type) - expect(extension.tag).to.be.equal(customDashboardSRC.extension.tag) - done() - }) - .catch(done) - }) - - it('fetch and Update Custom fields', done => { - makeExtension(customFieldUID) - .fetch() - .then((extension) => { - expect(extension.title).to.be.equal(customFieldURL.extension.title) - expect(extension.src).to.be.equal(customFieldURL.extension.src) - expect(extension.type).to.be.equal(customFieldURL.extension.type) - expect(extension.tag).to.be.equal(customFieldURL.extension.tag) - extension.title = 'Old field' - return extension.update() - }) - .then((extension) => { - expect(extension.uid).to.be.equal(customFieldUID) - expect(extension.title).to.be.equal('Old field') - expect(extension.src).to.be.equal(customFieldURL.extension.src) - expect(extension.type).to.be.equal(customFieldURL.extension.type) - expect(extension.tag).to.be.equal(customFieldURL.extension.tag) - done() - }) - .catch(done) - }) - - it('fetch and Update Custom Widget', done => { - makeExtension(customWidgetUID) - .fetch() - .then((extension) => { - expect(extension.title).to.be.equal(customWidgetURL.extension.title) - expect(extension.src).to.be.equal(customWidgetURL.extension.src) - expect(extension.type).to.be.equal(customWidgetURL.extension.type) - expect(extension.tag).to.be.equal(customWidgetURL.extension.tag) - extension.title = 'Old widget' - return extension.update() - }) - .then((extension) => { - expect(extension.uid).to.be.equal(customWidgetUID) - expect(extension.title).to.be.equal('Old widget') - expect(extension.src).to.be.equal(customWidgetURL.extension.src) - expect(extension.type).to.be.equal(customWidgetURL.extension.type) - expect(extension.tag).to.be.equal(customWidgetURL.extension.tag) - done() - }) - .catch(done) - }) - - it('fetch and Update Custom dashboard', done => { - makeExtension(customDashboardUID) - .fetch() - .then((extension) => { - expect(extension.title).to.be.equal(customDashboardURL.extension.title) - expect(extension.src).to.be.equal(customDashboardURL.extension.src) - expect(extension.type).to.be.equal(customDashboardURL.extension.type) - expect(extension.tag).to.be.equal(customDashboardURL.extension.tag) - extension.title = 'Old dashboard' - return extension.update() - }) - .then((extension) => { - expect(extension.uid).to.be.equal(customDashboardUID) - expect(extension.title).to.be.equal('Old dashboard') - expect(extension.src).to.be.equal(customDashboardURL.extension.src) - expect(extension.type).to.be.equal(customDashboardURL.extension.type) - expect(extension.tag).to.be.equal(customDashboardURL.extension.tag) - done() - }) - .catch(done) - }) - - it('Query Custom field', done => { - makeExtension() - .query({ query: { type: 'field' } }) - .find() - .then((extensions) => { - extensions.items.forEach(extension => { - expect(extension.uid).to.be.not.equal(null) - expect(extension.title).to.be.not.equal(null) - expect(extension.type).to.be.equal('field') - }) - done() - }) - .catch(done) - }) - - it('Query Custom widget', done => { - makeExtension() - .query({ query: { type: 'widget' } }) - .find() - .then((extensions) => { - extensions.items.forEach(extension => { - expect(extension.uid).to.be.not.equal(null) - expect(extension.title).to.be.not.equal(null) - expect(extension.type).to.be.equal('widget') - }) - done() - }) - .catch(done) - }) - - it('Query Custom dashboard', done => { - makeExtension() - .query({ query: { type: 'dashboard' } }) - .find() - .then((extensions) => { - extensions.items.forEach(extension => { - expect(extension.uid).to.be.not.equal(null) - expect(extension.title).to.be.not.equal(null) - expect(extension.type).to.be.equal('dashboard') - }) - done() - }) - .catch(done) - }) - - it('Upload Custom field', done => { - makeExtension() - .upload({ - title: 'Custom field Upload', - data_type: customFieldURL.extension.data_type, - type: customFieldURL.extension.type, - tags: customFieldURL.extension.tags, - multiple: customFieldURL.extension.multiple, - upload: path.join(__dirname, './mock/customUpload.html') - }) - .then((extension) => { - expect(extension.uid).to.be.not.equal(null) - expect(extension.title).to.be.equal('Custom field Upload') - expect(extension.data_type).to.be.equal(customFieldURL.extension.data_type) - expect(extension.type).to.be.equal(customFieldURL.extension.type) - expect(extension.tag).to.be.equal(customFieldURL.extension.tag) - done() - }) - .catch(done) - }) - - it('Upload Custom widget', done => { - makeExtension() - .upload({ - title: 'Custom widget Upload', - data_type: customWidgetURL.extension.data_type, - type: customWidgetURL.extension.type, - scope: customWidgetURL.extension.scope, - tags: customWidgetURL.extension.tags.join(','), - upload: path.join(__dirname, './mock/customUpload.html') - }) - .then((extension) => { - expect(extension.uid).to.be.not.equal(null) - expect(extension.title).to.be.equal('Custom widget Upload') - expect(extension.type).to.be.equal(customWidgetURL.extension.type) - expect(extension.tag).to.be.equal(customWidgetURL.extension.tag) - done() - }) - .catch(done) - }) - - it('Upload dashboard', done => { - makeExtension() - .upload({ - title: 'Custom dashboard Upload', - data_type: customDashboardURL.extension.data_type, - type: customDashboardURL.extension.type, - tags: customDashboardURL.extension.tags, - enable: customDashboardURL.extension.enable, - default_width: customDashboardURL.extension.default_width, - upload: path.join(__dirname, './mock/customUpload.html') - }) - .then((extension) => { - expect(extension.uid).to.be.not.equal(null) - expect(extension.title).to.be.equal('Custom dashboard Upload') - expect(extension.data_type).to.be.equal(customDashboardURL.extension.data_type) - expect(extension.type).to.be.equal(customDashboardURL.extension.type) - expect(extension.tag).to.be.equal(customDashboardURL.extension.tag) - expect(extension.enable).to.be.equal(customDashboardURL.extension.enable) - expect(extension.default_width).to.be.equal(customDashboardURL.extension.default_width) - done() - }) - .catch(done) - }) - - it('Delete Custom dashboard', done => { - makeExtension(customDashboardUID) - .delete() - .then((data) => { - expect(data.notice).to.be.equal('Extension deleted successfully.') - done() - }) - .catch(done) - }) -}) - -function makeExtension (uid = null) { - return client.stack({ api_key: stack.api_key }).extension(uid) -} diff --git a/test/api/globalfield-test.js b/test/api/globalfield-test.js deleted file mode 100644 index ddccc2e8..00000000 --- a/test/api/globalfield-test.js +++ /dev/null @@ -1,119 +0,0 @@ -import path from 'path' -import { expect } from 'chai' -import { cloneDeep } from 'lodash' -import { describe, it, setup } from 'mocha' -import { jsonReader } from '../utility/fileOperations/readwrite' -import { createGlobalField } from './mock/globalfield' -import { contentstackClient } from '../utility/ContentstackClient.js' - -var client = {} - -var stack = {} - -describe('Global Field api Test', () => { - setup(() => { - const user = jsonReader('loggedinuser.json') - stack = jsonReader('stack.json') - client = contentstackClient(user.authtoken) - }) - - it('Create global fields', done => { - makeGlobalField().create(createGlobalField) - .then((globalField) => { - expect(globalField.uid).to.be.equal(createGlobalField.global_field.uid) - expect(globalField.title).to.be.equal(createGlobalField.global_field.title) - expect(globalField.schema[0].uid).to.be.equal(createGlobalField.global_field.schema[0].uid) - expect(globalField.schema[0].data_type).to.be.equal(createGlobalField.global_field.schema[0].data_type) - expect(globalField.schema[0].display_name).to.be.equal(createGlobalField.global_field.schema[0].display_name) - done() - }) - .catch(done) - }) - - it('Fetch global Field', done => { - makeGlobalField(createGlobalField.global_field.uid).fetch() - .then((globalField) => { - expect(globalField.uid).to.be.equal(createGlobalField.global_field.uid) - expect(globalField.title).to.be.equal(createGlobalField.global_field.title) - expect(globalField.schema[0].uid).to.be.equal(createGlobalField.global_field.schema[0].uid) - expect(globalField.schema[0].data_type).to.be.equal(createGlobalField.global_field.schema[0].data_type) - expect(globalField.schema[0].display_name).to.be.equal(createGlobalField.global_field.schema[0].display_name) - done() - }) - .catch(done) - }) - - it('Fetch and update global Field', done => { - makeGlobalField(createGlobalField.global_field.uid).fetch() - .then((globalField) => { - globalField.title = 'Update title' - return globalField.update() - }) - .then((updateGlobal) => { - expect(updateGlobal.uid).to.be.equal(createGlobalField.global_field.uid) - expect(updateGlobal.title).to.be.equal('Update title') - expect(updateGlobal.schema[0].uid).to.be.equal(createGlobalField.global_field.schema[0].uid) - expect(updateGlobal.schema[0].data_type).to.be.equal(createGlobalField.global_field.schema[0].data_type) - expect(updateGlobal.schema[0].display_name).to.be.equal(createGlobalField.global_field.schema[0].display_name) - done() - }) - .catch(done) - }) - - it('Update global Field', done => { - var globalField = makeGlobalField(createGlobalField.global_field.uid) - Object.assign(globalField, cloneDeep(createGlobalField.global_field)) - globalField.update() - .then((updateGlobal) => { - expect(updateGlobal.uid).to.be.equal(createGlobalField.global_field.uid) - expect(updateGlobal.title).to.be.equal(createGlobalField.global_field.title) - expect(updateGlobal.schema[0].uid).to.be.equal(createGlobalField.global_field.schema[0].uid) - expect(updateGlobal.schema[0].data_type).to.be.equal(createGlobalField.global_field.schema[0].data_type) - expect(updateGlobal.schema[0].display_name).to.be.equal(createGlobalField.global_field.schema[0].display_name) - done() - }) - .catch(done) - }) - - it('Import global Field', done => { - makeGlobalField().import({ - global_field: path.join(__dirname, './mock/globalfield.json') - }) - .then((response) => { - expect(response.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Get all global field from Query', done => { - makeGlobalField().query() - .find() - .then((collection) => { - collection.items.forEach(globalField => { - expect(globalField.uid).to.be.not.equal(null) - expect(globalField.title).to.be.not.equal(null) - expect(globalField.schema).to.be.not.equal(null) - }) - done() - }) - .catch(done) - }) - - it('Get global field title matching Upload', done => { - makeGlobalField().query({ query: { title: 'Upload' } }) - .find() - .then((collection) => { - collection.items.forEach(globalField => { - expect(globalField.uid).to.be.not.equal(null) - expect(globalField.title).to.be.equal('Upload') - }) - done() - }) - .catch(done) - }) -}) - -function makeGlobalField (uid = null) { - return client.stack({ api_key: stack.api_key }).globalField(uid) -} diff --git a/test/api/hosting-test.js b/test/api/hosting-test.js deleted file mode 100644 index ccc32e23..00000000 --- a/test/api/hosting-test.js +++ /dev/null @@ -1,139 +0,0 @@ -import dotenv from 'dotenv' -import { describe, it, setup } from 'mocha' -import { jsonReader } from '../utility/fileOperations/readwrite' -import { contentstackClient } from '../utility/ContentstackClient.js' -import { expect } from 'chai' - -dotenv.config() - -let apps = {} -const orgID = process.env.ORGANIZATION -let client = {} -let uploadUid = '' -let deploymentUid = '' -describe('Apps hosting api Test', () => { - setup(() => { - const user = jsonReader('loggedinuser.json') - client = contentstackClient(user.authtoken) - apps = jsonReader('apps.json') - }) - - it('test get apps hosting details', done => { - makeHosting(apps.uid).isEnable() - .then((response) => { - expect(response.enabled).to.not.equal(false) - done() - }) - .catch(done) - }) - - it('test create upload url for apps hosting details', done => { - makeHosting(apps.uid).createUploadUrl() - .then((response) => { - uploadUid = response.upload_uid - expect(response.upload_uid).to.not.equal(undefined) - expect(response.form_fields).to.not.equal(undefined) - expect(response.upload_url).to.not.equal(undefined) - expect(response.expires_in).to.not.equal(undefined) - done() - }) - .catch(done) - }) - - it('test deployment for signed upload app hosting', done => { - makeHosting(apps.uid).deployment().create({ uploadUid, fileType: 'SOURCE' }) - .then((response) => { - deploymentUid = response.uid - expect(response.deployment_number).to.not.equal(undefined) - expect(response.deployment_url).to.not.equal(undefined) - expect(response.environment).to.not.equal(undefined) - expect(response.uid).to.not.equal(undefined) - expect(response.urlPath).to.not.equal(undefined) - done() - }) - .catch(done) - }) - - it('test deployment for signed upload app hosting', done => { - makeHosting(apps.uid).deployment().findAll() - .then((response) => { - response.items.forEach(deployment => { - expect(deployment.deployment_number).to.not.equal(undefined) - expect(deployment.deployment_url).to.not.equal(undefined) - expect(deployment.environment).to.not.equal(undefined) - expect(deployment.uid).to.not.equal(undefined) - expect(deployment.urlPath).to.not.equal(undefined) - }) - done() - }) - .catch(done) - }) - - it('test get deployment from uid for app hosting', done => { - makeHosting(apps.uid).deployment(deploymentUid).fetch() - .then((response) => { - expect(response.deployment_number).to.not.equal(undefined) - expect(response.deployment_url).to.not.equal(undefined) - expect(response.environment).to.not.equal(undefined) - expect(response.uid).to.not.equal(undefined) - expect(response.urlPath).to.not.equal(undefined) - done() - }) - .catch(done) - }) - - it('test get deployment logs for app hosting', done => { - makeHosting(apps.uid).deployment(deploymentUid).logs() - .then((response) => { - for (const i in response) { - const deploymentLogs = response[i] - expect(deploymentLogs.message).to.not.equal(undefined) - expect(deploymentLogs.stage).to.not.equal(undefined) - expect(deploymentLogs.timestamp).to.not.equal(undefined) - } - done() - }) - .catch(done) - }) - - it('test get deployment signed download url for app hosting', done => { - makeHosting(apps.uid).deployment(deploymentUid).signedDownloadUrl() - .then((response) => { - expect(response.download_url).to.not.equal(undefined) - expect(response.expires_in).to.not.equal(undefined) - done() - }) - .catch(done) - }) - - it('test latest live deployment for apps hosting', done => { - makeHosting(apps.uid).latestLiveDeployment() - .then((response) => { - expect(response).to.not.equal(undefined) - done() - }) - .catch(done) - }) - - it('test enable apps hosting details', done => { - makeHosting(apps.uid).enable() - .then((response) => { - expect(response.enabled).to.not.equal(true) - done() - }) - .catch(done) - }) - - it('test disable apps hosting details', done => { - makeHosting(apps.uid).disable() - .then((response) => { - expect(response.enabled).to.not.equal(false) - done() - }) - .catch(done) - }) -}) - -function makeHosting (appUid) { - return client.organization(orgID).app(appUid).hosting() -} diff --git a/test/api/label-test.js b/test/api/label-test.js deleted file mode 100644 index 4f32b93d..00000000 --- a/test/api/label-test.js +++ /dev/null @@ -1,127 +0,0 @@ -import { expect } from 'chai' -import { describe, it, setup } from 'mocha' -import { jsonReader } from '../utility/fileOperations/readwrite' -import { singlepageCT } from './mock/content-type.js' -import { contentstackClient } from '../utility/ContentstackClient.js' - -var client = {} -var stack = {} - -const label = { - name: 'First label', - content_types: [singlepageCT.content_type.uid] -} - -var labelUID = '' -var deleteLabelUID = '' -describe('Label api Test', () => { - setup(() => { - const user = jsonReader('loggedinuser.json') - stack = jsonReader('stack.json') - client = contentstackClient(user.authtoken) - }) - - it('Label create', done => { - makeLabel() - .create({ label }) - .then((labelResponse) => { - labelUID = labelResponse.uid - expect(labelResponse.uid).to.be.not.equal(null) - expect(labelResponse.name).to.be.equal(label.name) - expect(labelResponse.content_types[0]).to.be.equal(label.content_types[0]) - done() - }) - .catch(done) - }) - - it('Label create with parent uid', done => { - const label = { - name: 'With Parent label', - parent: [labelUID], - content_types: [singlepageCT.content_type.uid] - } - makeLabel() - .create({ label }) - .then((labelResponse) => { - deleteLabelUID = labelResponse.uid - expect(labelResponse.uid).to.be.not.equal(null) - expect(labelResponse.name).to.be.equal(label.name) - expect(labelResponse.parent[0]).to.be.equal(label.parent[0]) - expect(labelResponse.content_types[0]).to.be.equal(label.content_types[0]) - done() - }) - .catch(done) - }) - - it('Fetch label from uid', done => { - makeLabel(labelUID) - .fetch() - .then((labelResponse) => { - expect(labelResponse.uid).to.be.equal(labelUID) - expect(labelResponse.name).to.be.equal(label.name) - expect(labelResponse.content_types[0]).to.be.equal(label.content_types[0]) - done() - }) - .catch(done) - }) - - it('Query to get all labels', done => { - makeLabel() - .query({ query: { name: label.name } }) - .find() - .then((response) => { - response.items.forEach((labelResponse) => { - expect(labelResponse.uid).to.be.not.equal(null) - expect(labelResponse.name).to.be.not.equal(null) - expect(labelResponse.content_types).to.be.not.equal(null) - }) - done() - }) - .catch(done) - }) - - it('Query label with name', done => { - makeLabel() - .query({ query: { name: label.name } }) - .find() - .then((response) => { - response.items.forEach((labelResponse) => { - expect(labelResponse.uid).to.be.equal(labelUID) - expect(labelResponse.name).to.be.equal(label.name) - expect(labelResponse.content_types[0]).to.be.equal(label.content_types[0]) - }) - done() - }) - .catch(done) - }) - - it('Fetch and update label from uid', done => { - makeLabel(labelUID) - .fetch() - .then((labelResponse) => { - labelResponse.name = 'Update Name' - return labelResponse.update() - }) - .then((labelResponse) => { - expect(labelResponse.uid).to.be.equal(labelUID) - expect(labelResponse.name).to.be.equal('Update Name') - expect(labelResponse.content_types[0]).to.be.equal(label.content_types[0]) - done() - }) - .catch(done) - }) - - it('Delete label from uid', done => { - makeLabel(deleteLabelUID) - .delete() - .then((data) => { - expect(data.notice).to.be.equal('Label deleted successfully.') - done() - }) - .catch(done) - }) -}) - -function makeLabel (uid = null) { - return client.stack({ api_key: stack.api_key }).label(uid) -} diff --git a/test/api/locale-test.js b/test/api/locale-test.js deleted file mode 100644 index 230d8e41..00000000 --- a/test/api/locale-test.js +++ /dev/null @@ -1,129 +0,0 @@ -import { expect } from 'chai' -import { describe, it, setup } from 'mocha' -import { jsonReader } from '../utility/fileOperations/readwrite' -import { contentstackClient } from '../utility/ContentstackClient.js' - -var client = {} - -var stack = {} -describe('Locale api Test', () => { - setup(() => { - const user = jsonReader('loggedinuser.json') - stack = jsonReader('stack.json') - client = contentstackClient(user.authtoken) - }) - - it('Add a language English - Austria', done => { - makeLocale() - .create({ locale: { code: 'en-at' } }) - .then((locale) => { - expect(locale.code).to.be.equal('en-at') - expect(locale.name).to.be.equal('English - Austria') - expect(locale.fallback_locale).to.be.equal('en-us') - expect(locale.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Add a language Hindi - India', done => { - makeLocale() - .create({ locale: { code: 'hi-in' } }) - .then((locale) => { - expect(locale.code).to.be.equal('hi-in') - expect(locale.name).to.be.equal('Hindi - India') - expect(locale.fallback_locale).to.be.equal('en-us') - expect(locale.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Add a language Marathi - India with Fallback en-at', done => { - makeLocale() - .create({ locale: { code: 'mr-in', fallback_locale: 'en-at' } }) - .then((locale) => { - expect(locale.code).to.be.equal('mr-in') - expect(locale.name).to.be.equal('Marathi - India') - expect(locale.fallback_locale).to.be.equal('en-at') - expect(locale.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Get a All languages', done => { - makeLocale() - .query() - .find() - .then((locales) => { - locales.items.forEach((locale) => { - expect(locale.code).to.be.not.equal(null) - expect(locale.name).to.be.not.equal(null) - expect(locale.uid).to.be.not.equal(null) - }) - done() - }) - .catch(done) - }) - - it('Query a language Hindi - India', done => { - makeLocale() - .query({ query: { name: 'Hindi - India' } }) - .find() - .then((locales) => { - locales.items.forEach((locale) => { - expect(locale.code).to.be.equal('hi-in') - expect(locale.name).to.be.equal('Hindi - India') - expect(locale.fallback_locale).to.be.equal('en-us') - expect(locale.uid).to.be.not.equal(null) - }) - done() - }) - .catch(done) - }) - - it('Get a language Hindi - India', done => { - makeLocale('hi-in') - .fetch() - .then((locale) => { - expect(locale.code).to.be.equal('hi-in') - expect(locale.name).to.be.equal('Hindi - India') - expect(locale.fallback_locale).to.be.equal('en-us') - expect(locale.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Get and update a language Hindi - India', done => { - makeLocale('hi-in') - .fetch() - .then((locale) => { - locale.fallback_locale = 'en-at' - return locale.update() - }) - .then((locale) => { - expect(locale.code).to.be.equal('hi-in') - expect(locale.name).to.be.equal('Hindi - India') - expect(locale.fallback_locale).to.be.equal('en-at') - expect(locale.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Removed a language Hindi - India', done => { - makeLocale('mr-in') - .delete() - .then((data) => { - expect(data.notice).to.be.equal('Language removed successfully.') - done() - }) - .catch(done) - }) -}) - -function makeLocale (uid = null) { - return client.stack({ api_key: stack.api_key }).locale(uid) -} diff --git a/test/api/managementToken-test.js b/test/api/managementToken-test.js deleted file mode 100644 index 70aeb0df..00000000 --- a/test/api/managementToken-test.js +++ /dev/null @@ -1,136 +0,0 @@ -import { expect } from 'chai' -import { describe, it, setup } from 'mocha' -import { jsonReader } from '../utility/fileOperations/readwrite' -import { createManagementToken, createManagementToken2 } from './mock/managementToken.js' -import { contentstackClient } from '../utility/ContentstackClient.js' - -var client = {} - -var stack = {} -var tokenUID = '' -describe('Management Token api Test', () => { - setup(() => { - const user = jsonReader('loggedinuser.json') - stack = jsonReader('stack.json') - client = contentstackClient(user.authtoken) - }) - - it('Add a Management Token', done => { - makeManagementToken() - .create(createManagementToken) - .then((token) => { - expect(token.name).to.be.equal(createManagementToken.token.name) - expect(token.description).to.be.equal(createManagementToken.token.description) - expect(token.scope[0].module).to.be.equal(createManagementToken.token.scope[0].module) - expect(token.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Add a Management Token for production', done => { - makeManagementToken() - .create(createManagementToken2) - .then((token) => { - tokenUID = token.uid - expect(token.name).to.be.equal(createManagementToken2.token.name) - expect(token.description).to.be.equal(createManagementToken2.token.description) - expect(token.scope[0].module).to.be.equal(createManagementToken2.token.scope[0].module) - expect(token.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Get a Management Token from uid', done => { - makeManagementToken(tokenUID) - .fetch() - .then((token) => { - expect(token.name).to.be.equal(createManagementToken2.token.name) - expect(token.description).to.be.equal(createManagementToken2.token.description) - expect(token.scope[0].module).to.be.equal(createManagementToken2.token.scope[0].module) - expect(token.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Query to get all Management Token', done => { - makeManagementToken() - .query() - .find() - .then((tokens) => { - tokens.items.forEach((token) => { - expect(token.name).to.be.not.equal(null) - expect(token.description).to.be.not.equal(null) - expect(token.scope[0].module).to.be.not.equal(null) - expect(token.uid).to.be.not.equal(null) - }) - done() - }) - .catch(done) - }) - - it('Query to get a Management Token from name', done => { - makeManagementToken() - .query({ query: { name: createManagementToken.token.name } }) - .find() - .then((tokens) => { - tokens.items.forEach((token) => { - expect(token.name).to.be.equal(createManagementToken.token.name) - expect(token.description).to.be.equal(createManagementToken.token.description) - expect(token.scope[0].module).to.be.equal(createManagementToken.token.scope[0].module) - expect(token.uid).to.be.not.equal(null) - }) - done() - }) - .catch(done) - }) - - it('Fetch and update a Management Token from uid', done => { - makeManagementToken(tokenUID) - .fetch() - .then((token) => { - token.name = 'Update Production Name' - token.description = 'Update Production description' - token.scope = createManagementToken2.token.scope - return token.update() - }) - .then((token) => { - expect(token.name).to.be.equal('Update Production Name') - expect(token.description).to.be.equal('Update Production description') - expect(token.scope[0].module).to.be.equal(createManagementToken2.token.scope[0].module) - expect(token.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Update a Management Token from uid', done => { - const token = makeManagementToken(tokenUID) - Object.assign(token, createManagementToken2.token) - token.update() - .then((token) => { - expect(token.name).to.be.equal(createManagementToken2.token.name) - expect(token.description).to.be.equal(createManagementToken2.token.description) - expect(token.scope[0].module).to.be.equal(createManagementToken2.token.scope[0].module) - expect(token.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Delete a Management Token from uid', done => { - makeManagementToken(tokenUID) - .delete() - .then((data) => { - expect(data.notice).to.be.equal('Management Token deleted successfully.') - done() - }) - .catch(done) - }) -}) - -function makeManagementToken (uid = null) { - return client.stack({ api_key: stack.api_key }).managementToken(uid) -} diff --git a/test/api/mock/berries.jfif b/test/api/mock/berries.jfif deleted file mode 100644 index f0e4c1a081af3596ede3396ea0a75ee224de7ebb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 157612 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

0CJRXoE*7Wz8TA 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
&A7Y&Jwzh(uZ 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 z zJEV~q`f?c4qgE*oYo#-@b4fYHrD2lsX~w^M2tDw*}1V?`BzNK}jyS%0%dldj#JksFOO1}cHgocr((`K>{ z9IsQ*W7!Kyz~_vG=5*}eJ4g3k$EUN?fu^VdU|Pv`X*Z)k?N+zp5e!$qE6zt@oz3t< zZ>>)0`h$ho9_c^`A1`!BSk)rno=CglOK4}f=PIC@0P*2Sux~yTnim)t$JIlHf(~y4 zC?>f1a;v_-?EodJi<9*WG2petEvd+JD0blYSz3SrG#0RCb3**5dVD+N0=Y?#m+G~8 zSf_){WmLK*J)VLMx@|DJvM!c>v#D*c+OFc&I)<#Y7LF>p;bO@0_kXpFV`k0KsioH$ zB%*uyTaduXM&}yESYApN5Nu$rT|Tw!XlW#ojFhJb+BL_KJxCu?i)4q>x(CW$8Qj4} z)9+`mWR7{Xj8EMhS~j)U!t|egJBwzB8y9Rm zu6&hxI-uVX%{1_a3n118GK1D4`_7G`HUL4kp5b3kbaFAQ5)0;zDPL8mF+}H?1DH9_ z0cJb1v|U8&`W~UK1J;GRT+oQ^dvsa|^zDqvBy0|IMla|7mU|+Pr$_gVHM~#wo=F#9 z%j|{LTpA+O>Bud34q-jK{{V%gWAK9>Y9yivHq-t2MP^oBX7xPI#&m6alsTt zoT9nye8yH-{{YFSvR_e$fxzRNTO^Kl+w8MlBMq8x9E8Mj)4m=Kaxi~>$#*)KN#lzL zAzm!UL{$u%u$d;mM>i&@65!()urE3N@Q0z*ecPx$>Q9b>UFWVB<|esMV@U)8d}Cr(=;0$5f6~t-)HEN=~D>xbIkTOKqJ{lJpTS+XluH# z)V0ifk~Qsj;U@$oI$n$kWSPSN*vBXL;V>^00J-u^TE-Fp1mynx)1P>kS0iKDvL;}c z9FLdPRI#obrM%=c9)0qu3jve~rfXu1SaX5+zjmagHyp0HWSxPnt)j+nj_2#)c@MOY zt#evzmbWhcQ+dMnZ;UXE#O#6#hr~y>`^xb@XhUb~5{TVQZ^9c!oBJq_W{G@Rj^|z$ zzuBnVHSW|H_eC2^T>Gu0@UuSX<8YP>5(maxu$_(v0mldH{!;r!NV*v`cvX2O_PU1xxhtBEiy4`&h#k!oO4(tApD=8GG)h^D;QB_fjy&0FI5g&N=yWapeF^xb1oC-B4! za5x~0A!?r1vB8aN3Fd*tDCiQ0^)dtY0tn-jku8UV?Ev-N9;^uK;cJ6?UjygHct}Yt zeWcR75wywpiO+PmT+uk{Jy`PRd_tYb`XO}9Y;$@dM#mHM_mkXbKfdbHv}b#=f1O-6yuvIhsUIR$+g#8K>{^7mJJ3r=VuoF3Gu zmQOjtioU@`*I=y}-fIbg%#6Iy?aFF6+Q#H$vU z$5pB>d#`yUpPJLr$Fo+@);Do!(;SIj9Kr<-MUU^5>Nm0$OX@HN zIxWNk2qa_t6^Q1R4KZ<_PRs?_R4$XgTYoAHMekl!Dl=Anuz%>Ce7&FzW1 zvJGGF2~Mc!8U4T2>%6&1>5vWZA>m0m5Or z&2+3DgbsTSZb896^rQYpIKg0R0T~1iLYMVe<#y2}0f1|QP-V6my*2YwXPuDQ&!m14 z`}S3XqrlfZNh6*Q4i3RwC1b&Ocm}~D%@j9k#8Nu!UT*9gKyRYsrRiBU010kLe*}Nh zq}?}8*($?H;?F<7bs8;6cA|-Mnr~~IGx93ZO(P^QJ|;bbAQ5-_;RNgv>1=oe7La%X zvV|sw2tjdi1Rsb2ma1wdgxrvBjpvXu2h1z!G_p%A%WouLrczJXGZa$EQSKX!2G#

ap&SIRwz@-gIt|HaD@h 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%0Dkg2ipNI|h( z?*&mQeIA?aiuqL+U*XGHWKU-1(Y6|H4o^~2;~eeByK!})|;mo zS_^6`%cYZ(m6GkVrdmk}^hU$dCOVyST`r~A4Fm9}wS7-j)ErxXJSS(6?+M^ywNgVJFpk z)S9nRx@WjCyttgXBO{vaAH(nvL+BG(=k>~{$LyP;V%0WwIkOhE!!2>{e|c9dEWrTY zLPm1X;?`{-95`N6I$6xXvR4ZL1{2@eRZ#x`mth;YskY!i@%+e@oG4)CRfr z69}+K$yz->q_av|`Of#A1z;^bpfHkX9{tvCUqvKjMbIJynI(I`J=RB8+8n{d``I~K%^l6q?netRsl_a^ zjj_0~yu9#Jk7D%2v}A0NwrtTBFll;Tn*&**5to+BBX>K+UkeAN#p>&0Y5XntoVR3| z&zIB{Lls!0<=qhavr|hnI_)9RO!}ReV~G4g2c&N4-DYhpwi`1`L9YsuX<4a`Jw}ee z89B%*H9Gb@L}p=bqBjrX4(Sm?eKd_UdXt)Si2}2Qcmwq?MJU|nvBk~+aBQs&L~xFl z=K(~v%eV<1k0#!ks1^Zh$*@wZ3!}8LN2?P^(BNZzkVgqEZ`u7fP>IrM_Ob3aV15+m zMwFLoNN)Pc1mzn*Y8m#ni=?6lWSS~6Xz*Iy4x^^evSyG@L#qJ;by);iAFsnNDZ_Q?!&s5l`e}|o9yx0Zk4Ij0_L&64h?d&bYEtrnm}eG z6OadG>Du_B_+tY6R|>9}?hR-n@j!61d0XhwVn|a@(Db@i0zd`4UP(oMCW4sQ0X$glP)M%3Q}=BIjwYN%0={9?wJ+6c9`_PO;d@`UI`2zNV{59hj#q-P z4q8q5E29*BnPh&70b>?dGB-&hSk~EbpaSPOoMwk$jiUjMbj~CQ+hUGMI3KFm$tz{G zC9j)nG9v+_6b&jdyRvLoBn4163>qVw?ui(C96ye&NoefL?gmO^m5T*|;C-F*;AEO{;6PR)Um zir3q1?O{Flo>CY~kO~YEH_H$9LyYW}hJG^-&nLTMHG!0Z5_0cT^z|Z z0PPUDfOg&h2=V>s5(^@DCmWmyKfiP*x%30{me6k8cUR=AGoTTZKu87)2?YLXL2SGp zp08Blsfn#)Fc=LK{C=DRWDE{y_=A`S{{ZX~Iye|&0JXBSlYwBS+~}f&zB9CgO~>ed zs#yJko&VkS-XhDfR6iz3a^)V z4Fir%a;WF}#}*nnBf7gIk(t3AjaVrG4QK+!N#q_1yD6skJ%_*+tivm?90(plxqF&w zLmRIE3k3iMSDT>n@H~ttfVfCmZUNkU)ZXIY05!-ws&MPQpc|{@11~6e#H?{0om5m1 z;}|BTXuuqX@wWOK^ z*;=JajO6Xvd82Dw3rQiu&JcM`HJ+?4U~Rkkag?ze2?QG)gUCV=R|*`Q`zUCze2>*x z!p<#JST+?1@0naKyZ%VD){6j}?cqRkbJ+W&GN6zs_f~BaS6@XSWRsg+u#-p;z+L$H za-$ipeoKQ$1PdWqxWNPVO3!DBEt80ryNX_#oH^1ffX@ zk2x(o6d)=-YDckE2i-_GpM^pi6z$Y}jS)$rE!gny_P~m27P3XFdw8v}7 za}GXA8m*$!O;n1)b42ID+325WwLJ<$8*5Rclm7s7PX7SH@0Ww}N$NC>ob8j&t8C%kMB^*Ei>x_s_@1)xn41AHg{02hCegf5*Y-Gk3qzMfs_G2qPscf}3=0RI3t!Cd(<*3r?6 zB6?-@50W^V{q*@T;70)V{E-90qjL)YJ9jjpYJriAV0Zw(0G?~IW@fZW007aj;tqIN zqgh789M4O1VdR6s@Cu08cH%{hIMz?PDWZXsy|U&uw14h29~Q0aM$?&r6<7;~fCA7QNf~x96f;EP++z913V@Hj zLI=Rt5$DRZI+-0!jg21UaIAE#U=-jhB$Z~dv49M%vxDTM1U1vW#jPL#j08zEsdPInEp$GlVDRuS10`mh5(%Oc zMJuu$8bC<8A;%( z**P^x9R|E!54xd$f~&gxeo89rpfriyXSFUavD(#5T~J&FCKh!O-EeJ!YzoTbSBj-! zhLi=GuV8!2ocbq=3pc36ZfPfsSzfPGp^4JCiXX{= zEzvr3ZZ6c%Ws&eZ5}SP9uBUM)IpGpmzT*$wBY7ZGoNKxaVXp*k7C0xmrM;0S=>#|- zG)Dv!%*$xw0&>Su6^{WE(76bXQV7Vt z`9aXQ>9wNGj`>=W!4TBk&op?X0iO6LZ^mD`j{$nVmpRqw82KJ;xGie)+K!&~Gzexd z4zob;n)^Gfev?=Cd29!ov)N1gDQ`!kbh>I0IDmb^#_D}I#K%b5EjggJdY+0o2So^&;5cVZ0H*PlgyG4K6n95_u|F zv@V5uu9^C-l_YS0Nf@)j@NUw}3(F*9ffzXDdv3cluynZ$E-W>ZYsG)dYCzcMSQxSu z<4jo^&^O?m5U-?(@0b|s+nPPs3E4ZYXO^A?1?fJ;jRab$AFhna7!`X-uW+hQiZ<~v zEZHgaDL+k{L8yXB1De?gKbcy;XrVL8@*PAl5ro&;Ikc^7V`&pc930ot8$v=}r>57> zWu<_M1e}$Ol({GLbY_MaIYtk&%DJxx@sLg^1t(-+2f5NanyaM7ze)E^OMwJ1n`@7B zsi(f0K_>tMmDIL*G}EKd^s9cB5a|p-wm@jfPD>_G>s(eV_&V)=t1>1z3j&3+VcHNs7sNDY(oSemD`@3x%y@U>B+o-^bPz?iRLrr;EKr-8jbNTiMCazTyZ*aNsB zEw%3-2qYXM$E7TduaHo2+S|G*vXc7*BLW@f?BnE`eyS6tje;6`V=OMed$IKLt2}Lp zHa*rG$prwo07F`6cPTBJNpaBJI*+|HwcrOv&>BJH1>70{-w7XZD2^#O$prD23l5E- zI>#znp{Hb3UNSi-PBw2U@*cyU>dVV+9aTf<_b; z*~MoR6C#QL@MwT5BFgQU$;{0Anqu-puse?lcg_QeE+C$Bl~c5mcUbNZB~1?Kv3-i< zeE3|?h>=FQ6mW(GnhgMR?3jU{0ikEPJOs%mP#F!LPB~ec%~z`3k&*!96Uu*IAZDJ4 z8_xvySurq8Gg#J=Txyew_BUx!snehk=ov9@$0;BmVgA;iOVf$wk^{8vZMOLZ2h$#- zVFPPgHn%(~#^>oZd)NqbO@rkny_w6p4Ft1v%|R__BZoAeQyS)Jwfa{{rvOMYT24ZB z!JR`)buh(cqMkezkuH_*V~iu>X~+hWChXVHOm#nJp4T1DV4?~SP7aHrY8`DGq&19` zmqOOQDQ443C`i**JEwIKK0OmO@v!f4v*hJIhW5hrCZ9@q4O6%$f}7E4-u)Tc12+;$ zz7st^rkys8jCEMa942LZU}yoNhcqx&QlHVRF*n!;M-&=xDYnr-o=RG6KrJDlSnw4! zk`f7{V}g|i;~Tc{qw*KGz|#$#BdHWnT%9I>>j}Kng+`; zjeMkvBa1|p&1-fH4(Gz8K*a$jf$*baNXhr06%bjku}uR$$d(w#T~HTjZ4J8?D5`57 z8KRNKjqo_M4Eg^6+KpMCTv~e@wSq@#`6qgehD~&)uucM0w#Ns}cwLZGj#)ckh_Cxb zU;|8h7dnagf3kS=a21=m zhQQti50r!wF};;-Xzl>XQ|ZPH66T*43K?)SSOtLcOL#;UICE(CAplgzO(050@k$yR zXo%0xc0#|zczbWY3LCZulR$&b93W-*1muCq10h|n4{bYZ$6!?$>&#%|!jtKqEw1iI zB_IhAXf#+{!c78frrYR-n_*z`TyT+KaUTP~6_Q7~Gd6={8BYN4K~hlUPmH>Rj$rIV zzZd4J`JCyP$tF7)k{&4rU0Z`IZt!qg;gF&T;*vA#G#7(pJF*y(9d@=5_cjKH$a8HN zaQFV6QDTHnM3d9W{6KI5UIw+G`alDa0PYcea_6*Zh--)9c^?HI?x3Kr`=*j$TM&?p zhPR$nYTfI_Aeo~~AC|Xuk^3u}%~TtPnrMi299-Ow_1!BlEiMzhPDr8vpg(-2LtAD@ zvmu}fImxAX+FIh{WSkXHY4#dP2FO+qmpdW=91=?0$TsRYh>^%Q!W5DTPS!Mr@@V9# z-y^|esFBHN;Yf(Jw?V*hX$a`sV2nT8xI}DX@La>-la(7r+jL-#Y&mz{UAPFw;NIl& zft7TQ1huy7!6fjYvtR|sHD_|R!uJ=L>heedP~egn2pAxs4r^O02*`VLW0I}d(9D=fV}Z^2J(Oy+?qmHyLF}FBH3NH-%)CZVA2$zT3$H(7?_?M}@5*-3s?W z$_9~G;in*^UB6VctA5!eOZmmyBm9zi@U zX*7)0L}$}DS<9L`uRZyuG8>zB= zh3q!jWB&mBj5s6m$naFXk#$(TSlk;R^WWx{FuoUt$kGoWo5EI}g($e}_j5xS*6BoU zGQjccMBp-8SpNVYFoUa>Ee4&A>Jo^Ha@d)dyZm$AdHpxqonDKjjVv*>uZXxsF&5@E z+=2DavdfZZ%_EGZ^2+SJ&m^o?E$r3i){U)a+K0KNoi;P22FIv!_YZU1>B`3Y%jlwZ?f#>?}4e zh8i!GE^D_3fp>xjWD!VcLnM~zCLj#sxm6lBmwZyV1DeWQOy*<~M}l}vw^sLthBd^T zT_83QniiAsIN9LYR~lGY4tKopJS9lfmhId?=7Hf$G?O`?x#osWa*;Isv6H8USL zOQV5cD{hccrt-r_rx$ys{6KF4ntM<94w z8)gNi$9-_#!B$wr(U!P49!V%1S&$uGS8gYQRi7DTggWq|tCLBVM>a_+M|_%41>(pG z;k13w7C>n7p~P?x)k!^pDgd%+Iq zL029X2YjmoLz=V!>dvHznnSU{04uU#A-M+}Sinij>Xxzr$gr=ty8`jT;-jmk6H}-A z%S(U*!2xAH7d6$v9fH_w!H*G}Bgx?lU8OH(==m8KTEc#rl;Q0eAia;njf@2TpHSUP zNRZQj!R}I1Z!i~aJBKAF6q0WEtWw*vDl}zbia_kp$Xi?E)#zH|AOtpurGhn%a|>jr z4n9j$N?3Y-rx>zLpJbR9^iD)`xSlO9B$Dan58O!^vKFUIbWu3^%(k~S2P;BN4u`16 zagf4!%8{nl!t{Q$dW;(+rWWA)q(0NM#~60cgy0aewR#O#Ox4^DFKEsRc3!N`qtlEN zTVw)(J(5~2)V7UZvoSdIph+Q@b>%JggI@6F!xaMWgi*?OM>Bd~*|xag)q{MjzL5)c z8noQ3N;RAW^DpG;dUP5%JgiPOi8t+pKS((Lng zyvB}gHkMsWH5-9=A&+UdF#iB`?lsPdohY(42C#|^XrMFxSA^=2M$K7soLU|%8Y@2@ z?n#>YG@}_LDX4h$3~|V1Xf)SVTBI6jH8Tb=q`3ARl})sM6MpM|>~~dfOzT2tz}anu zyGa7?_uX~$aQD%dtPC7PPeE} zKETgVnr(0wbf>lY%_pnsY=k(07_vK$rT&StIP&9C?9Ou@8(`mVctq2Z!03+AyjJ7N z)R*k4>oL{nM3&Q&Ep)D zBn^fzID=y+Hmo%6CdebT1U6Y|CC0qkC~S@*oO~c#EXe3k86Tox4^9UYk~2!M#UV6K z2Ps~wtr0N841lUBl(5a0+L5TEF}a$6>&(;xv&C(6vyG1|RLApi}= ziSWHlY-A8J7Q16(6`ty)trDO8F-HqDU6GQAB@)q-5A0P9->7J+#?M*BqO4?uh@(fN z>m8uhnA{19d>;WbtQIPBJ-Ip0cvP^r{5UZC$k{bwB=X8bJ@>W~XGG4oi?ev#3OAGUPHn?+`7 zWU?=}zbV~A`ECLC?6V(ll+{qcSu>#k)cj1(9jKwOTXzC$u_Fl6(P$-PI1DP##@qTcL81FWOisCeb7wX zi394G&`WC^KqD(B?KI*pm_Q>S-CkCX+Hp004X;1;&UUj(7!F9u@SJwX(c&VQJ>{~u zaXAEXRK94KOH3{VatX*vfr8_eXSB$}AU0Yl)>mRjE!lVK$Uno0g19x6G8b)Wao=sS zLR!-=_(&ju@PM5P%7-+&7zdD#VWa_*&IbyOV;+7W2a-FhH0>p%&>T?Z1d`{q%`J1V zd9_H!D%(T3R^;2N`wCp~V{mP4@;OKex)cbZ*r^PBptLt}908hF(dmw^O{{eexjgD{u<+K3qQqP6#X(gq#$TmS<#qog~$f6sHu1Ws@v@g0wA1P>S zgBmwj!-`hJl01xY$mec3t{UTznG!sUdkuN3UXl7ZOC^!5Yg)__M=5FgR1VUy@zh1x z+&iO?^vqAa0~m}rJd;g4Ifu$4BbqxAO%Vjy-Z@v)biG@3FMMrj+koc^B_Ls(jQVxK z8@NqVA487yOF)xV8$iQD0mrfkmN6qh6zk>B+?050NAV{vJ;Oo|s>ZtGyYf#7(37C< z4v$da;4bq@0DJLtIHAhEsf~+JOF<)%M$p?PY_f+Wlaj3x?J%rqj1a;IK1UznTXE&! zG>_(KLl4{u3?vTZ@T>!;vKk9p$Oj=I6)yEn5J2|suGm@yycUDSj#YyQ7Rbo?_g(0` zyL0IIBp?cr7#7wMd=gF-$zW}W$#1dBtB8D+U;)CIh+~`sL&u9E&@z1{y`;uLX~`9q zt|NJ(=!qB?f>hjli=r-L#z-YgBr`gTV=Xx}+>g~DE*K*jGBof=76Ok<7Ly#VBy;fL zc8Wvm7+pj<%R%f_T{Db>{gb5)a^3|GBbkU+X*(ckT6N9wu6R{ z4V1+H0BC1pV~<7~3t|K@;Cx2=l@(9;Mr*- z$~}TE#SYe_5=k}(uqYUcv4pH53%2?{L?uy;78RX#> zUlh#OMn{zZ5$v=drrl%@)h_r5;3lL)gFxby@W>w#)rKi_Bc9Gz? z{wU5A+g**tJ;YWw><4?Sp5219jRXN0CA^n;Q6w@(3uIwnX~?RzES16&fLcykRT-Se ze0Px3jQ2;3iy$}PABYl!_`{ebgxMUA{8u#YJAfpQ#6jgCEi_m=Fw>BGE@K?#28R$^ zlbj-5Ht|OTJQV;sARGV(x&_c9EUkAWRx0v~7N(s;5D5b$_ay^mI*p3= zK+QMnTE?}coMh*eAH4@Tt|WtY0uiXPBWVY{%n1s>|nz~doR&g=m|jwY2w zla)1#$?~KRDS;n8RXg+gE0ftl=ad0l+OWDc{S;p|RE+n>bOFC3jQ~l<2g)F(G`Mrv z+770N#x9REtrf^xF2KzN$LQ;=hl(?M$N-#!-8jNu6&n?Vu*nSqfbf`R96{o+0l`u} z(VJnKmqjKR?C_M<>AfipT^xe7I)_hmfXf|N7IKz_!g#$GvdG|@u)1ROaz4zXw}W<5 zT{?F&P}YYUaiT2-cu0K#f#n6C1FRAV@T?DO6mJkyNCS%<)!U+lpA(+ulZ+Lg(7J;k z9Y}sA;AfS$Bu7yP0fUiel@u+bBdBQRj>{x31YMKD^V1hHP){JxUY}W_)Iqqlz=Q9? z#`~0-slG4(zQGEYWyLqq>3V*g^)8zLn2^Tg4=LZdvLYKBXbvxhUY=vpXqd~rqOyqT z*h8F6k-#04rizknnVnx!*no^#alqPgn&_G@yJ<|aP;>Hcl#tWIspD*i&DGscL_)R{5JPOSzHA;^w z_P18%$jHM*a(o5no2aWLfZlCs{h*Z1)E!_DF<`8q(PV8oTfu1Oo3>nPBX}URfN}`z ztSQd6xLNFk7{kCL=&T_foB{U=i6TPmfHCAKk{3%8NdN(Wh{)d4LWuErM16n@+CUrt z5C(7tHxNf1*SYB0=tMATOB&fjHoe0efb;&>lzakqlNkh`(Gn>2P1Cw2ow1+A>$`A@T}bsqBqgtno=}OsuBzDeUec~ z9!WhJ&C?S40jK+?^nYiyvbetCiLU2#oPJ2n>7ar{tv@ArtD)dj)n28L~MS!BWOiBs31xM+)V^gCvh&kw-?rNFV@3lkB+4zz7si zHiBhyu80lrs7U9N`XxbOm|rADaJrcp0_cl>$#af&erxYs~>f@H-TCi3_qot|=_WIGhu^ora3+FX$NU4RMUdDnb$7dYhPlv(vI)aoB2+)bPV*$9euI6Nzg zqGc=5xAt>PHq9{rkSV0_wVq*}n@J3iU;=PdbZCqnDUWLb4#~dg(`oecl0&wVEP|u9 zCjAJ$DIhh1!I53ijLnJdb3hf!Yh6RL(|fNP8mlt>gXR2ht7ngAo5WfCwp=acM;*xKSj7Jf;Ei^kVV zEc4#&8L=`TY~5rdVjymZa1!otFC@DA;P9D8G~AVVyoKX_+(>tZ3^eiXy_*~d#0MER zzIpbyQR?*q2|hpvg?Rq}kuv@#pCnkXl_D{s_P9_uBpiiCoDwVYR%is-KTj*D=RoC% z#`4lZt_nFj91YmoDPC6kkTu==Z_-4+c|!idcuaIPb01cGefWmEuYsK}Np?pa4fCl^|Yhlic=QD@ASuSmu{E;~+Gb7h;D9152h<4FnJii6(;3 zWR&+3;0Y8Bq+o8s)(ioP{rjdPaeTxKv^vOHGU#ct7B#o{otpE1=|2nHBxG^X+AN<7 zJ_iEV&T<=ugW)%&lxd+e5J{58+TkHRj=hFWns~5D4!;U#0z%CU1d2B_mBpa8L({a5 zmG0jxqMOZ+Wk>3p)B1T1c{59wxcN+q3$Jv0qtdp622Fb*HN#OklmQVR?%?7GzX&7o zQd3C;-A+@f)RM>nss!7UTA3Rrp}II}tQ>*Z1gK<*OQDit1spIR<_kYx(%GpD5V?^_ zM3#ZddsOdD?1i}i;h&3dO38{I7|tnSH-2A?}UKR(0ngt ztBMU+ZktnYeTt*WUURDSw`k;hqiOU81BuGgGrcjm`#{+y{WL^45E-h4&1R;>X4;bJ-j?k+kg|^}?bb*he_Z?W`@KljN)KXce??{)laD98e%;`>DA| z_(M(mAd+mo)MNmTEUP#W&CYrJ?NmtM>H)5C@xWGKAdu@Py&QxA00Wal`W1H6PPc+9 zxLg}?mp34DwDI&&8-WD4k`4_6kKeKYGlO2xNiFUO$U}P`*R{@TTnYR@D{0+C#xq$I zS3RJ7TWH@la*;?7W0@t3Bz#Rb%_3|%h}|TQY(_k}$G^!#N37u^zlLMWi0$r`)@n|v zzr%4XZ))e=B&@A1mefoo1+AdY!_T?^WjGVtlDHE10cp#59?QK@_`r4vHDF+^5~3Tj zyJ+2D@TJc9u~qNcPFZA|9jM_{xr`Pm?mv(~1PwMwAcl;RFc&*i#;^#1FYe+n67H4m z6kKbH?5Gl;Ea$o8mpGDnB%?X4^rLXdB91sH35cD)Naj%Z4TJMT8rVKgDwU0FsyJPA zC=s7!IT27IyV_zX)&rXr;GC;GXCi`@gIBZ=IW@xPjNqE^kR21uZUwYEeA8aDn%{|_ zgTWX|3cO$C!aG1LAOJ}B;Q$@9@nOJ^=(xrRyaD9$QvU71?_&tDNFHgx5|EDcs`hc& zb6sYM0{JTYnne?S!9$sLO%uQavIbDR0)4nuCa8+~cTqq%gI2C0Zo+KP91wshAP;7F z@(?yTuCPJ+qq;fN`!3VNy=%=lk5l#rn{ZWHj@OW8mc^oDp)K&_Y5~Dw`(&@X3KH(`OC8YOH$1_On zp32XNJYv5jlcL-c=*g-)E5{?^cIe4z91v0E)6qBya?0$qPRv?p)YJ7=%->61((rhA zISGTM*%tWTWQgDfoP~sm4x(5camZWpDr@L1KFtWX!7UpE@Cqz|2bTu|(~1{@fZnRf zSR1K`SipM`plmvZxv@&y9}sJa1p=?4;j~Dg8hEm<;$HmGyag_RnCt-HdxLbUEP@?F z8~}k)Pl^&rX$0gC2<(lr$7}?Xk?w(Z?S<9`MtN3_SLxrHBB%k`1T_5<5MVB3n6JWA zNdRR&8zQWda<2Hk0O3@4CzWW(jg=q{Y2btm8zg(#vO}~S*+lf9W+~4nHVzRV3tbU- z+Ck!v2tlp@Ix+)~E$&hkrWKBW0ODT4JA#9$j84*6Y>qFKUtNNPv4G)#NK>{j`T&yb z?xX>ba7#`5sctNrMAb#8K zI01Rqweq-bB>wj09FNMJc2{PL9}EDE?iNx|i($0&&iHO;0drG!MA7og>SE;P@U;k&|o?mBf$_ zBhFVHM7)z^XO%+YEYQBx6gby4eic#@lNx5Z?F5rx`=Y;HdS?JYC$T)N&T-CgQ3;`Z z`Ns)yMSezk?Nkpl$Xwz{H)(dXjE7MeIa~UjFQ^Nw4?b2j+6iJL07(9eM9J)+U@jm$ zXNz1~TGB&-BangdHN+7_W8|$J@H2TTgjzE4>lK^eGwTeT298uU(CFgaYtc(6my60 zJ5mWK@6P-_FQ6pYXSp+FBk)#ZWkYd~{AAkhSHsPOIP{zOs}E6K(9rAHi_F27(D44hD} znwGN9Bo0y7&4%uX&Qr6MAWUQ5o-Yhu-2sU}F1*1uIgO*DQG7i)FT)<|y+909;fQReQI z#y;6DTBKaI?2bYvnZC5_jDwc}KzpGv**@v+ml>0&#kQ;)RNje8XRd|JhCPH5#?S$y zg)+qkt*6s)+;9O>(#jx61>}O4)M=PYT@-*G)OlGhg!>lMG5TOy9DD^mE@>aBY(I&Q zG+IScVVb5)(H^D17U8D3PV`Qk=4u@&qQk*SxM$}&p|3wbI#~580XndZic}&G8Zw{!VXXBhR2429Ba26Ap-&~SzUH3 z0ZZFv#Ts3vKBI{o4A?5p8%^Fv6gfbcqsa9@CjHU2jerc3lVb=B1^TiD({Y24o{};n z=7$+Un-Os=CqDFs#_rU7F5p#nSDx~7gjIkf0WnnE`Qir{i@3R*XVoSz-h z*x!VMpJUkvXm%`sIQKwyPLdqo1Dd4EBicwk{De(2*&GC%l(f3xW}AVE9IELKnAn6- zB893M85Mz(@<@H=SqLDK4rl~sMqVtFXCW&DtFq2}rm`Fe9h64_878}n?26WyhATN- zl zyHLPP8;Ly79#TNdH-HU;>{Y-8wL*q?LutS3UR9frXrGsbMr4?oRxPK%DB3m>^6RFv zAOXswA_Uv4-;zpeZ>1P(Koyf*B-qeKxQ7FIDW(muiglNGN=41P0B~(wZj`XJkUtF$ zR&24eH~yb&O)je32eNZQ=e}Vy#BL3yj^DoNc-k1j6mO#IE(5(IOFyR@T0o*N1tMFr zXVx|SS|K5*;2V#FNDO)Ey0=K@R4h36S^B4X)0b`~pi_tmn53Fm#5za|7;qfq!nA9@ zT@(xiI)S1ZJ1qD$a!IY4NFy&Yd@Xfhs@i^x=_DspAv;}8XgCX47<8IA;*0?II027z z3totZ0icALAk6S6|UV@?N^ zG*W*@k=E$l)3t_TT40ctkUIn-3uGfCc_n&HUYKg*bKMXToB&2v1EF}C&`LpkV%kRp zD~zmiR;>Yalt2Jqb6hDea~oyExbQ7V1-aQ^cPoH5xzZ}@XALUv0O)zd4HckjbH1gs=YX(cZ1f=@S@%nLs)(&j)kx6@D zb$YNtf-*LNPH_HYvk9+;!9F{o@3VNnD~sIhlXZn@P@Ax~M3U+wkU1)*N;b@SCzLyt|hZUVAG2RQ*beuIK_+0fM8lpORp5HjinTu)4Pb2ZB&OtC~w(2;^lTS`J1@ zajHHS0&0P=;a*>j`D0u^1_$K@-wtog#bq|$Tl)j zV$n$VRBU^R7qm2-Bmh|;17V_liX}W7J6Z>VjLw&-)M?!`I%jNYqT`SIO=&*QYNunJ zAQ8~Eha9;sNp{Af-$q-*OEF~oD()i^5&*?5%{STUWr^g-$mMSlk;;j_&AHLE$EahT zNDi@pr<{JuP?yn&UekfcZ*@~d8z6(_Z@cW&!a~MsB6VPrDF$z|GqX+{C5*o5%>(eG zoPNjn<@8~*;CLVaLAwZA*vmCeB;N0c6W-SQ{>(@ujI&i4jOETFgdKm`y<6V-8uq+_ zhK@>WByX|)Iaf!Ytae;6;cc_*rmgV@hr|gqK|CQl?9RQqZ%{F$-4=t8tDJtx;V+{$ zIZJzlu5GYT74d;MCOU(a|?xw9HZj;8ghu~+aS$flnJ20 zB8XID-4m)nSZjh4ER;M^AgJiqQZt_!2Zc^A**`2Hz>!~)Rq+sb3q!vIyN3N56o1J~MH16p$VCZ6)(>o;2>=fBT&pphhLY0W4`Q-E zaJuYg`lbCv z-l?*f33cJIk8>e}NbN+)|?rWptgutrj#m;3|dFu0N1VPkdV=DE)(jd^>hRd+y?hBP+8Ba}uufb35; zkx80bSz5+zBemIB{ZpvJ6ort0NaT)6V^JxKOyV6!) zO5QH0;3~~E6HerFSyhfAY0h>#W0cVW8f+S&Tw1QuOpu7zC5#QpoDPENWUvX(VJ& zLT{!!N0xict|Xf(%r+>IjsltV@6*Uw;6NSKS^yR-p6fvbBHP$2F#iAyi$gEA)sk07 z$;r=j0e@J5&5!DbAg69^kaO}<=H!bdba@4){el22E-x6X=RK8)yDk(5a5+L~A;b%# z;asuo9mw}c0l0&H*~+GisLP}-ex650^WCPAPL^roBTW>Nxb_19EY6RtEOUzkE3@1I zDKws$)8plq8FEEs)jmmgImDZ?d#0KL+8)t^lYF2{(x+^k;lP}YkHt2!ioS?a-xHo5zJ0Uwc+GvkVfJvj+ zDwYy#-E+dTTtUT>J9u14Ad*cSCPk1tlx_0kUN@GZIF2b`l5q_VB@kw3#W5^H+&?4frMy-3+%LynB@i$v7nZc3A5oa z*6$#T7r;`=2^?+STuBWXB=%UHOIUSM7PM0v!1A8!8jnUXrWa=}HnE7w2I!{+>{5P# zfs@ErX~h*{+ZRUEFj=F>S`cw<*&O#y^oJ4DW2@$pwO4~d6Hg(7QrQ{_qs6598tnGu zY5xG6faC7Dx@epU2EgLGrJUAJ18_^+F7BykNckcl2}s+DwVz~A?yE<-P#W4JxL${) zv+mj^g5p3KUT3FkUnZbOC7U!{3iW}l3=L>C&I-#b^mJfbvTu1OC%z8|ak;`m3H+6S zF`Nnq-9yN1mH;=(!0NKCeMmqA0nIAvT0|ER z6uNV@gb+a-Wp<3zKmbWTaI3Aogpq;Vo)aaB=nnl;oxtXY1!-^#O`jH!>G9i%Bb-n? zr@$kdJ+gvWhNYEc-Z=xZw@QkR>IP{X&`*lK7nk(I?yM1%-%`~5<6QT*gNnWq>;;=^7sx%=To)8`PF$D) z@Zf?w@~+U+*pcSdogVfO23l}$Aq}R1y99GeiArpQx5H}0_bG>AQzW9xf}%M zngR`+6WYGhTkh#OB@i>7#acR+aXgZEQUHJnH4fc> zfq@x?tcv!4+>=MbS{Y*wGfd$|%NkD#M!%r1aS{5H3VV$*FnC$LPef(X$+kb@pTp!Q zv~v2h8J;)E!&*2CwG0hE#Cb0{ARGk0Wku6Gy9=Lel7y{0TnWii_JG?qUT^>y8BKK# znoQ2r!VdPG#i#j_t~BC9C=pmRy&x^O`L@c8(U-?DGmTxtQ)db z5{4K-V;n2u9nT4Ab&&@a8+ZiZaDz6a2JMXV$sLlQG#fTYi%BA`i%B!(HcbJ*9hDWq z4Y9Nv?s;5ZNUQ)j#|nf%W4NQ7jB>1Db3iyC_#+CYN0UU72Lkw21mu(eQ>SDz1TIHzr*oQRj7VFHJdn6S9EAE$+u%w5 zQDHz-B1r_0xQDQcUx2BVA$4Vm*Up`kE7`H zf;Y$vlgF15acenbQ7Smxk3ZA;UZY+KiGyHpX>qy>PfPZBkZW&SAao-jH=a1g2NgzPXzIWGqro_?{{{Zmrl*0B$Gt0(9h)Zhz$~?WM3EEiTEWG3`r?Jt?>BVFbcmDv2 zC*8|OsOP!Gq!4eir8b1)7LOq>*?oAG>P$%78-EBK zmD0R6M>Wo>$Q6^7Ycn!<;(YzuS=dN)F9cxxJRug4Xo3%dGQNh%T0@B;jTvzuSoyCV z_Jdr_e^Y#swX6dGG;>Q>Waa42P~)>PaKTaaE555!GH(hkN7Z%vphWPbDvz3x^ZgJs zPi5bd>%LFuySE~c1RN?JRn7-0zmj4hN93(u>N^~uL@DgJeHRa!0N}c?xO~E%+=Kx_ zG1*qKiC-mJ&tw7Zbkc8$wgyuBgl>7O$y~W`qpYkS#GB&rlxLFH&^49IlV!vYP$X%c z@>r4nBDr$gAMrWze<9e#Gq>cN(ncHsE0-q3jeefil5BoULvxT&zXFw`7$BZFUzfKm=Lh%!yW=Bj z<;o&-zJ*-#ythA^8=iL+%ax-h%QH~;z9y4{!hQ)3qB?dDau+U1mmRH@ECJ5RpsEGl za2GB?pRx(vRV{HI106QWz#x_0UmNvrW${9FfdKkALo-dq(W$*Dg&Ez)aBRG-in%)A4)^pfI^| zNIe2|IPqD^EM31P%aa*NoLgXaDLLFpzTOuuNrEk>9~N_brrW`xSzNgYrb`JqE6V+^ z)xTq!FaqVu;o2r$9xbB3s=J0)E?tKwvV?XR$`j4!y5-147t_Sj?cKs?;h#0jl43*? zk%cE4sdD6sC_W=aa5f1!E0-oB&v|SPAZEh8k}&oP370BgswmaC`+f7D?K^c&4w^7BeT!d7e4r&85I%4Qp zE!_U8X=EB!H0=^PLu9#f>=!OnN!69dlDTpKk}|9XE?kfukAKZU6uEK$k}HKH0@p4; z#-P+l1s85@R@22RzfBgSP3lI`5oy{$&8}Rhpb&d@y~CPNxpJaO9Isu{dPbad-5#a) zBj~!19Pqhv%QK~;TuRvPqfkcLYeDZp1P$fei93ar%aj1pHaKpm&}+v=ahaEkca=u3^;Nbkz!$q1&dM>UNA&^ShmPS3kI z3{bVpk?0T!+hMK*g8u-7SAxNstfk;*sw8xzy~8%S zas-6>>x>-`>@~VdE5;H@Hf?g{(}$xxy_M{vvgONj6T2u}xd2EQS8HwUZSq$xKoVI` uExs?Zfx%q4ASzB(Z!4E75!aQ=mmox1p6iz&XJ2K&<#OZ!Dy4Gd2>;nYHv|~~ diff --git a/test/api/mock/branch.js b/test/api/mock/branch.js deleted file mode 100644 index 6c2187ae..00000000 --- a/test/api/mock/branch.js +++ /dev/null @@ -1,14 +0,0 @@ -const branch = { - uid: 'main', - source: 'master' -} - -const devBranch = { - uid: 'merge_test', - source: 'staging' -} - -export { - branch, - devBranch -} diff --git a/test/api/mock/content-type.js b/test/api/mock/content-type.js deleted file mode 100644 index 2e4a7713..00000000 --- a/test/api/mock/content-type.js +++ /dev/null @@ -1,179 +0,0 @@ -const singlepageCT = { - content_type: - { - options: - { - is_page: true, - singleton: true, - title: 'title', - sub_title: [] - }, - title: 'Single Page', - uid: 'single_page', - schema: [ - { - display_name: 'Title', - uid: 'title', - data_type: 'text', - mandatory: true, - unique: true, - field_metadata: - { - _default: true - } - }, - { - display_name: 'URL', - uid: 'url', - data_type: 'text', - mandatory: true, - field_metadata: { - _default: true, - instruction: '' - } - } - ] - }, - prevcreate: true -} - -const multiPageCT = { - content_type: - { - options: - { - is_page: true, - singleton: false, - title: 'title', - sub_title: [], - url_pattern: '/:title' - }, - title: 'Multi page', - uid: 'multi_page', - schema: - [ - { - display_name: 'Title', - uid: 'title', - data_type: 'text', - mandatory: true, - unique: true, - field_metadata: - { - _default: true - } - }, - { - display_name: 'URL', - uid: 'url', - data_type: 'text', - mandatory: false, - field_metadata: - { - _default: true - } - } - ] - }, - prevcreate: true -} - -const schema = [ - { - display_name: 'Title', - uid: 'title', - data_type: 'text', - mandatory: true, - unique: true, - field_metadata: - { - _default: true, - version: 3 - }, - non_localizable: false, - multiple: false, - fldUid: 'title' - }, - { - display_name: 'URL', - uid: 'url', - data_type: 'text', - mandatory: true, - field_metadata: - { - _default: true, - version: 3 - }, - non_localizable: false, - multiple: false, - unique: false, - fldUid: 'url' - }, - { - data_type: 'text', - display_name: 'Single line textbox', - abstract: 'Name, title, email address, any short text', - uid: 'single_line', - field_metadata: - { - description: '', - default_value: '' - }, - class: 'high-lighter', - format: '', - error_messages: { format: '' }, - fldUid: 'single_line' - }, - { - data_type: 'text', - display_name: 'Multi line textbox', - abstract: 'Descriptions, paragraphs, long text', - uid: 'multi_line', - field_metadata: - { - description: '', - default_value: '', - multiline: true - }, - class: 'high-lighter', - format: '', - error_messages: - { - format: '' - }, - fldUid: 'multi_line' - }, - { - data_type: 'text', - display_name: 'Markdown', - abstract: 'Input text in markdown language', - uid: 'markdown', - field_metadata: - { - description: '', - markdown: true - }, - class: 'high-lighter', - fldUid: 'markdown' - }, - { - data_type: 'blocks', - display_name: 'Modular Blocks', - abstract: 'Create content dynamically', - blocks: - [ - { - title: 'Block1', - uid: 'block1', - blockType: 'custom', - autoEdit: true, - schema: - [ - { data_type: 'file', display_name: 'File', abstract: 'Upload images, videos, docs, etc.', uid: 'file', icon_class: 'icon-file-text-alt', class: 'high-lighter', size: { min: '', max: '' }, extensions: '', field_metadata: { description: '', rich_text_type: 'standard' }, fldUid: 'modular_blocks > block1 > file' }, { data_type: 'link', display_name: 'Link', abstract: 'Add links to text', uid: 'link', icon_class: 'icon-link', class: 'high-lighter', field_metadata: { description: '', default_value: { title: '', url: '' } }, fldUid: 'modular_blocks > block1 > link' }] }], - multiple: true, - uid: 'modular_blocks', - field_metadata: {}, - class: 'high-lighter', - fldUid: 'modular_blocks' }] - -export { singlepageCT, multiPageCT, schema } diff --git a/test/api/mock/contentType.json b/test/api/mock/contentType.json deleted file mode 100644 index df456dd6..00000000 --- a/test/api/mock/contentType.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "options": - { - "is_page": true, - "singleton": false, - "title": "title", - "sub_title": [], - "url_pattern": "/:title" - }, - "title": "Multi page from JSON", - "uid": "multi_page_from_json", - "schema": - [ - { - "display_name": "Title", - "uid": "title", - "data_type": "text", - "mandatory": true, - "unique": true, - "field_metadata": - { - "_default": true - } - }, - { - "display_name": "URL", - "uid": "url", - "data_type": "text", - "mandatory": false, - "field_metadata": - { - "_default": true - } - } - ] - } \ No newline at end of file diff --git a/test/api/mock/customUpload.html b/test/api/mock/customUpload.html deleted file mode 100644 index cfeb9844..00000000 --- a/test/api/mock/customUpload.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/test/api/mock/deliveryToken.js b/test/api/mock/deliveryToken.js deleted file mode 100644 index dfea15e6..00000000 --- a/test/api/mock/deliveryToken.js +++ /dev/null @@ -1,28 +0,0 @@ -const createDeliveryToken = { - token: { - name: 'Test', - description: 'This is a demo token.', - scope: [{ - module: 'environment', - environments: ['development'], - acl: { - read: true - } - }] - } -} -const createDeliveryToken2 = { - token: { - name: 'Test production token', - description: 'This is a demo token.', - scope: [{ - module: 'environment', - environments: ['production'], - acl: { - read: true - } - }] - } -} - -export { createDeliveryToken, createDeliveryToken2 } diff --git a/test/api/mock/entry.js b/test/api/mock/entry.js deleted file mode 100644 index 16249e58..00000000 --- a/test/api/mock/entry.js +++ /dev/null @@ -1,7 +0,0 @@ -const entryFirst = { title: 'First page', url: '', single_line: 'First Single Line', multi_line: 'First Multi line', markdown: 'Mark Down list\n 1. List item\n 2. List item 2', modular_blocks: [], tags: [] } - -const entrySecond = { title: 'Second page', url: '', single_line: 'Second Single Line', multi_line: 'Second Multi line', markdown: 'Mark Down list\n 1. List item\n 2. List item 2', modular_blocks: [], tags: ['second'] } - -const entryThird = { title: 'Third page', url: '', single_line: 'Third Single Line', multi_line: 'Third Multi line', markdown: 'Mark Down list\n 1. List item\n 2. List item 2', modular_blocks: [], tags: ['third'] } - -export { entryFirst, entrySecond, entryThird } diff --git a/test/api/mock/entry.json b/test/api/mock/entry.json deleted file mode 100644 index 60515666..00000000 --- a/test/api/mock/entry.json +++ /dev/null @@ -1 +0,0 @@ -{ "title": "First page json", "url": "", "single_line": "First Single Line", "multi_line": "First Multi line", "markdown": "Mark Down list\n 1. List item\n 2. List item 2", "modular_blocks": [], "tags": [] } \ No newline at end of file diff --git a/test/api/mock/environment.js b/test/api/mock/environment.js deleted file mode 100644 index bab8c786..00000000 --- a/test/api/mock/environment.js +++ /dev/null @@ -1,32 +0,0 @@ -const environmentCreate = { - environment: { - name: 'development', - servers: [ - { - name: 'default' - } - ], - urls: [ - { - locale: 'en-us', - url: 'http://example.com/' - } - ], - deploy_content: true - } -} -const environmentProdCreate = { - environment: { - name: 'production', - servers: [], - urls: [ - { - locale: 'en-us', - url: 'http://example.com/' - } - ], - deploy_content: true - } -} - -export { environmentCreate, environmentProdCreate } diff --git a/test/api/mock/extension.js b/test/api/mock/extension.js deleted file mode 100644 index 536bbc4a..00000000 --- a/test/api/mock/extension.js +++ /dev/null @@ -1,91 +0,0 @@ -const customFieldURL = { - extension: { - tags: [ - 'tag1', - 'tag2' - ], - data_type: 'text', - title: 'New Custom Field URL', - src: 'https://www.sample.com', - multiple: false, - config: '{}', - type: 'field' - } -} -const customFieldSRC = { - extension: { - tags: [ - 'tag1', - 'tag2' - ], - data_type: 'text', - title: 'New Custom Field source code', - srcdoc: 'Source code of the extension', - multiple: false, - config: '{}', - type: 'field' - } -} - -const customWidgetURL = { - extension: { - tags: [ - 'tag1', - 'tag2' - ], - data_type: 'text', - title: 'New Widget URL', - src: 'https://www.sample.com', - config: '{}', - type: 'widget', - scope: { - content_types: ['single_page'] - } - } -} - -const customWidgetSRC = { - extension: { - tags: [ - 'tag1', - 'tag2' - ], - title: 'New Widget SRC', - srcdoc: 'Source code of the widget', - config: '{}', - type: 'widget', - scope: { - content_types: ['$all'] - } - } -} - -const customDashboardURL = { - extension: { - tags: [ - 'tag' - ], - title: 'New Dashboard Widget URL', - src: 'https://www.sample.com', - config: '{}', - type: 'dashboard', - enable: true, - default_width: 'half' - } -} - -const customDashboardSRC = { - extension: { - tags: [ - 'tag1', - 'tag2' - ], - type: 'dashboard', - title: 'New Dashboard Widget SRC', - srcdoc: 'xyz', - config: '{}', - enable: true, - default_width: 'half' - } -} -export { customFieldURL, customFieldSRC, customWidgetURL, customWidgetSRC, customDashboardURL, customDashboardSRC } diff --git a/test/api/mock/globalfield.js b/test/api/mock/globalfield.js deleted file mode 100644 index 22f07718..00000000 --- a/test/api/mock/globalfield.js +++ /dev/null @@ -1,28 +0,0 @@ -const createGlobalField = { - global_field: { - title: 'First', - uid: 'first', - schema: [{ - display_name: 'Name', - uid: 'name', - data_type: 'text' - }, { - data_type: 'text', - display_name: 'Rich text editor', - uid: 'description', - field_metadata: { - allow_rich_text: true, - description: '', - multiline: false, - rich_text_type: 'advanced', - options: [], - version: 3 - }, - multiple: false, - mandatory: false, - unique: false - }] - } -} - -export { createGlobalField } diff --git a/test/api/mock/globalfield.json b/test/api/mock/globalfield.json deleted file mode 100644 index 56b6de61..00000000 --- a/test/api/mock/globalfield.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "title": "Upload", - "uid": "upload", - "schema": [ - { - "display_name": "Name", - "uid": "name", - "data_type": "text", - "multiple": false, - "mandatory": false, - "unique": false, - "non_localizable": false - }, - { - "display_name": "Add", - "uid": "add", - "data_type": "text", - "multiple": false, - "mandatory": false, - "unique": false, - "non_localizable": false - }, - { - "display_name": "std", - "uid": "std", - "data_type": "text", - "multiple": false, - "mandatory": false, - "unique": false, - "non_localizable": false - } - ], - "description": "" - } \ No newline at end of file diff --git a/test/api/mock/managementToken.js b/test/api/mock/managementToken.js deleted file mode 100644 index bf399d6f..00000000 --- a/test/api/mock/managementToken.js +++ /dev/null @@ -1,72 +0,0 @@ -const createManagementToken = { - token: { - name: 'Test Token', - description: 'This is a sample management token.', - scope: [ - { - module: 'content_type', - acl: { - read: true, - write: true - } - }, - { - module: 'branch', - branches: [ - 'main' - ], - acl: { - read: true - } - }, - { - module: 'branch_alias', - branch_aliases: [ - 'tst' - ], - acl: { - read: true - } - } - ], - expires_on: '2024-12-10', - is_email_notification_enabled: true - } -} -const createManagementToken2 = { - token: { - name: 'Test Token', - description: 'This is a sample management token.', - scope: [ - { - module: 'content_type', - acl: { - read: true, - write: true - } - }, - { - module: 'branch', - branches: [ - 'main' - ], - acl: { - read: true - } - }, - { - module: 'branch_alias', - branch_aliases: [ - 'tst' - ], - acl: { - read: true - } - } - ], - expires_on: '2024-12-10', - is_email_notification_enabled: true - } -} - -export { createManagementToken, createManagementToken2 } diff --git a/test/api/mock/release.js b/test/api/mock/release.js deleted file mode 100644 index 9bb45e77..00000000 --- a/test/api/mock/release.js +++ /dev/null @@ -1,10 +0,0 @@ -const releaseCreate = { - release: { - name: 'First release', - description: 'Adding release date 2020-21-07', - locked: false, - archived: false - } -} - -export { releaseCreate } diff --git a/test/api/mock/role.js b/test/api/mock/role.js deleted file mode 100644 index c0d299df..00000000 --- a/test/api/mock/role.js +++ /dev/null @@ -1,53 +0,0 @@ -const role = { - role: - { - name: 'test', - description: 'Test from CMA Js', - rules: - [ - { - module: 'environment', - environments: [], - acl: { read: true } - }, - { - module: 'locale', - locales: [], - acl: { read: true } - }, - { - module: 'taxonomy', - taxonomies: ['taxonomy_testing1'], - terms: ['taxonomy_testing1.term_test1'], - content_types: [ - { - uid: '$all', - acl: { - read: true, - sub_acl: { - read: true, - create: true, - update: true, - delete: true, - publish: true - } - } - } - ], - acl: { - read: true, - sub_acl: { - read: true, - create: true, - update: true, - delete: true, - publish: true - } - } - } - ], - uid: 'role_uid' - } -} - -export default role diff --git a/test/api/mock/taxonomy.json b/test/api/mock/taxonomy.json deleted file mode 100644 index 51df5308..00000000 --- a/test/api/mock/taxonomy.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "taxonomy": { - "uid": "UID", - "name": "name", - "description": "test" - }, - "terms": [] -} \ No newline at end of file diff --git a/test/api/mock/upload.html b/test/api/mock/upload.html deleted file mode 100644 index cfeb9844..00000000 --- a/test/api/mock/upload.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/test/api/mock/variantGroup.js b/test/api/mock/variantGroup.js deleted file mode 100644 index 8081e4a5..00000000 --- a/test/api/mock/variantGroup.js +++ /dev/null @@ -1,82 +0,0 @@ -const createVariantGroup = { - name: 'Colors', - content_types: [ - 'iphone_product_page' - ], - uid: 'iphone_color_white' -} - -const createVariantGroup1 = { - created_by: 'created_by_uid', - updated_by: 'updated_by_uid', - created_at: '2022-10-26T06:52:20.073Z', - updated_at: '2023-09-25T04:55:56.549Z', - uid: 'uid', - name: 'iPhone Colors', - content_types: [ - 'iphone_product_page' - ], - source: 'Personalize' -} -const createVariantGroup2 = { - count: 2, - variant_groups: [ - { - uid: 'uid', - name: 'iPhone Colors', - created_by: 'created_by_uid', - updated_by: 'updated_by_uid', - created_at: '2022-10-26T06:52:20.073Z', - updated_at: '2023-09-25T04:55:56.549Z', - content_types: [ - 'iphone_product_page' - ], - variant_count: 1, - variants: [ - { - created_by: 'created_by_uid', - updated_by: 'updated_by_uid', - created_at: '2022-10-26T06:52:20.073Z', - updated_at: '2023-09-25T04:55:56.549Z', - uid: 'iphone_color_white', - name: 'White' - } - ] - }, - { - uid: 'uid', - name: 'iPhone', - created_by: 'created_by_uid', - updated_by: 'updated_by_uid', - created_at: '2022-10-26T06:52:20.073Z', - updated_at: '2023-09-25T04:55:56.549Z', - content_types: [ - 'iphone_prod_desc' - ], - variant_count: 1, - variants: [ - { - created_by: 'created_by_uid', - updated_by: 'updated_by_uid', - created_at: '2022-10-26T06:52:20.073Z', - updated_at: '2023-09-25T04:55:56.549Z', - uid: 'iphone_color_white', - name: 'White' - } - ] - } - ], - ungrouped_variants: [ - { - created_by: 'created_by_uid', - updated_by: 'updated_by_uid', - created_at: '2022-10-26T06:52:20.073Z', - updated_at: '2023-09-25T04:55:56.549Z', - uid: 'iphone_color_red', - name: 'Red' - } - ], - ungrouped_variant_count: 1 -} - -export { createVariantGroup, createVariantGroup1, createVariantGroup2 } diff --git a/test/api/mock/variants.js b/test/api/mock/variants.js deleted file mode 100644 index 178c7cc3..00000000 --- a/test/api/mock/variants.js +++ /dev/null @@ -1,50 +0,0 @@ -const variant = { - uid: 'iphone_color_white', // optional - name: 'White', - personalize_metadata: { // optional sent from personalize while creating variant - experience_uid: 'exp1', - experience_short_uid: 'expShortUid1', - project_uid: 'project_uid1', - variant_short_uid: 'variantShort_uid1' - } -} - -const variant1 = { - created_by: 'blt6cdf4e0b02b1c446', - updated_by: 'blt303b74fa96e1082a', - created_at: '2022-10-26T06:52:20.073Z', - updated_at: '2023-09-25T04:55:56.549Z', - uid: 'iphone_color_white', - name: 'White' -} -const variant2 = { - uid: 'variant_group_1', - name: 'Variant Group 1', - content_types: [ - 'CTSTAET123' - ], - personalize_metadata: { - experience_uid: 'variant_group_ex_uid', - experience_short_uid: 'variant_group_short_uid', - project_uid: 'variant_group_project_uid' - }, - variants: [ // variants inside the group - { - uid: 'variant1', - created_by: 'user_id', - updated_by: 'user_id', - name: 'Variant 1', - personalize_metadata: { - experience_uid: 'exp1', - experience_short_uid: 'expShortUid1', - project_uid: 'project_uid1', - variant_short_uid: 'variantShort_uid1' - }, - created_at: '2024-04-16T05:53:50.547Z', - updated_at: '2024-04-16T05:53:50.547Z' - } - ], - count: 1 -} - -export { variant, variant1, variant2 } diff --git a/test/api/mock/webhook.js b/test/api/mock/webhook.js deleted file mode 100644 index 86af1eb4..00000000 --- a/test/api/mock/webhook.js +++ /dev/null @@ -1,40 +0,0 @@ -const webhook = { - webhook: { - name: 'Test', - destinations: [{ - target_url: 'http://example.com', - http_basic_auth: 'basic', - http_basic_password: 'test', - custom_header: [{ - header_name: 'Custom', - value: 'testing' - }] - }], - channels: [ - 'assets.create' - ], - retry_policy: 'manual', - disabled: false - } -} - -const updateWebhook = { - webhook: { - name: 'Updated webhook', - destinations: [{ - target_url: 'http://example.com', - http_basic_auth: 'basic', - http_basic_password: 'test', - custom_header: [{ - header_name: 'Custom', - value: 'testing' - }] - }], - channels: [ - 'assets.create' - ], - retry_policy: 'manual', - disabled: true - } -} -export { webhook, updateWebhook } diff --git a/test/api/mock/webhook.json b/test/api/mock/webhook.json deleted file mode 100644 index 5667abc9..00000000 --- a/test/api/mock/webhook.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "Upload webhook", - "destinations": [{ - "target_url": "http://example.com", - "http_basic_auth": "basic", - "http_basic_password": "test", - "custom_header": [{ - "header_name": "Custom", - "value": "testing" - }] - }], - "channels": [ - "assets.create" - ], - "retry_policy": "manual", - "disabled": "true" -} \ No newline at end of file diff --git a/test/api/mock/workflow.js b/test/api/mock/workflow.js deleted file mode 100644 index 198cacbd..00000000 --- a/test/api/mock/workflow.js +++ /dev/null @@ -1,8 +0,0 @@ -const firstWorkflow = { workflow_stages: [{ color: '#2196f3', SYS_ACL: { roles: { uids: [] }, users: { uids: ['$all'] }, others: {} }, next_available_stages: ['$all'], allStages: true, allUsers: true, specificStages: false, specificUsers: false, entry_lock: '$none', name: 'First stage' }, { color: '#e53935', SYS_ACL: { roles: { uids: [] }, users: { uids: ['$all'] }, others: {} }, allStages: true, allUsers: true, specificStages: false, specificUsers: false, next_available_stages: ['$all'], entry_lock: '$none', name: 'Second stage' }], admin_users: { users: [] }, name: 'First Workflow', content_types: ['multi_page_from_json'] } -const secondWorkflow = { workflow_stages: [{ color: '#2196f3', SYS_ACL: { roles: { uids: [] }, users: { uids: ['$all'] }, others: {} }, next_available_stages: ['$all'], allStages: true, allUsers: true, specificStages: false, specificUsers: false, entry_lock: '$none', name: 'first stage' }, { isNew: true, color: '#e53935', SYS_ACL: { roles: { uids: [] }, users: { uids: ['$all'] }, others: {} }, allStages: true, allUsers: true, specificStages: false, specificUsers: false, next_available_stages: ['$all'], entry_lock: '$none', name: 'stage 2' }], admin_users: { users: [] }, name: 'Second workflow', enabled: true, content_types: ['multi_page'] } -const finalWorkflow = { workflow_stages: [{ color: '#2196f3', SYS_ACL: { roles: { uids: [] }, users: { uids: ['$all'] }, others: {} }, next_available_stages: ['$all'], allStages: true, allUsers: true, specificStages: false, specificUsers: false, entry_lock: '$none', name: 'Review' }, { color: '#74ba76', SYS_ACL: { roles: { uids: [] }, users: { uids: ['$all'] }, others: {} }, allStages: true, allUsers: true, specificStages: false, specificUsers: false, next_available_stages: ['$all'], entry_lock: '$none', name: 'Complet' }], admin_users: { users: [] }, name: 'Workflow', enabled: true, content_types: ['single_page'] } - -const firstPublishRules = { isNew: true, actions: ['publish'], content_types: ['multi_page_from_json'], locales: ['en-at'], environment: 'environment_name', workflow_stage: '', approvers: { users: ['user_id'], roles: ['role_uid'] } } -const secondPublishRules = { isNew: true, actions: ['publish'], content_types: ['multi_page'], locales: ['en-at'], environment: 'environment_name', workflow_stage: '', approvers: { users: ['user_id'], roles: ['role_uid'] } } - -export { firstWorkflow, secondWorkflow, finalWorkflow, firstPublishRules, secondPublishRules } diff --git a/test/api/organization-test.js b/test/api/organization-test.js deleted file mode 100644 index d6d7bba2..00000000 --- a/test/api/organization-test.js +++ /dev/null @@ -1,108 +0,0 @@ -import { expect } from 'chai' -import { describe, it, setup } from 'mocha' -import { jsonReader } from '../utility/fileOperations/readwrite' -import { contentstackClient } from '../utility/ContentstackClient.js' - -var user = {} -var client = {} -var organization = {} - -describe('Organization api test', () => { - setup(() => { - user = jsonReader('loggedinuser.json') - client = contentstackClient(user.authtoken) - }) - - it('Fetch all organizations', done => { - client.organization().fetchAll() - .then((response) => { - for (const index in response.items) { - const organizations = response.items[index] - expect(organizations.name).to.not.equal(null, 'Organization name cannot be null') - expect(organizations.uid).to.not.equal(null, 'Organization uid cannot be null') - } - done() - }) - .catch(done) - }) - - it('Get Current user info test', done => { - client.getUser({ include_orgs: true, include_orgs_roles: true, include_stack_roles: true, include_user_settings: true }).then((user) => { - for (const index in user.organizations) { - const organizations = user.organizations[index] - if (organizations.org_roles && (organizations.org_roles.filter(function (role) { return role.admin === true }).length > 0)) { - organization = organizations - break - } - } - done() - }) - .catch(done) - }) - - it('Fetch organization', done => { - client.organization(organization).fetch() - .then((organizations) => { - expect(organizations.name).to.be.equal('SDK org', 'Organization name dose not match') - done() - }) - .catch(done) - }) - - it('Get all stacks in an Organization', done => { - client.organization(organization).stacks() - .then((response) => { - for (const index in response.items) { - const stack = response.items[index] - expect(stack.name).to.not.equal(null, 'Organization name cannot be null') - expect(stack.uid).to.not.equal(null, 'Organization uid cannot be null') - } - done() - }) - .catch(done) - }) - // need to test with transfer ownership - // it('Transfer Organization Ownership', done => { - // organization.transferOwnership('em@em.com') - // .then((data) => { - // expect(data.notice).to.be.equal('Email has been successfully sent to the user.', 'Message does not match') - // done() - // }) - // .catch((error) => { - // console.log(error) - // expect(error).to.be.equal(null, 'Failed Transfer Organization Ownership') - // done() - // }) - // }) - - it('Get all roles in an organization', done => { - organization.roles() - .then((roles) => { - for (const i in roles.items) { - expect(roles.items[i].uid).to.not.equal(null, 'Role uid cannot be null') - expect(roles.items[i].name).to.not.equal(null, 'Role name cannot be null') - expect(roles.items[i].org_uid).to.be.equal(organization.uid, 'Role org_uid not match') - } - done() - }) - .catch(done) - }) - - it('Get all invitations in an organization', done => { - organization.getInvitations({ include_count: true }) - .then((response) => { - expect(response.count).to.not.equal(null, 'Failed Transfer Organization Ownership') - for (const i in response.items) { - expect(response.items[i].uid).to.not.equal(null, 'User uid cannot be null') - expect(response.items[i].email).to.not.equal(null, 'User name cannot be null') - expect(response.items[i].user_uid).to.not.equal(null, 'User name cannot be null') - expect(response.items[i].org_uid).to.not.equal(null, 'User name cannot be null') - } - done() - }) - .catch(done) - }) - - // addUser - // Resend invitation -}) diff --git a/test/api/release-test.js b/test/api/release-test.js deleted file mode 100644 index ccdb3fa8..00000000 --- a/test/api/release-test.js +++ /dev/null @@ -1,226 +0,0 @@ -import { describe, it, setup } from 'mocha' -import { jsonReader } from '../utility/fileOperations/readwrite' -import { releaseCreate } from './mock/release.js' -import { expect } from 'chai' -import { cloneDeep } from 'lodash' -import { contentstackClient } from '../utility/ContentstackClient.js' -import { multiPageCT } from './mock/content-type' - -var client = {} -var stack = {} -var releaseUID = '' -let entries = {} -const itemToDelete = {} -describe('Relases api Test', () => { - setup(() => { - const user = jsonReader('loggedinuser.json') - stack = jsonReader('stack.json') - entries = jsonReader('entry.json') - client = contentstackClient(user.authtoken) - }) - - it('Create a Release', done => { - makeRelease() - .create(releaseCreate) - .then((release) => { - releaseUID = release.uid - expect(release.name).to.be.equal(releaseCreate.release.name) - expect(release.description).to.be.equal(releaseCreate.release.description) - expect(release.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Fetch a Release from Uid', done => { - makeRelease(releaseUID) - .fetch() - .then((release) => { - expect(release.name).to.be.equal(releaseCreate.release.name) - expect(release.description).to.be.equal(releaseCreate.release.description) - expect(release.uid).to.be.equal(releaseUID) - done() - }) - .catch(done) - }) - - it('Create release item', done => { - const item = { - version: entries[0]._version, - uid: entries[0].uid, - content_type_uid: multiPageCT.content_type.uid, - action: 'publish', - locale: 'en-us' - } - makeRelease(releaseUID) - .item() - .create({ item }) - .then((release) => { - expect(release.name).to.be.equal(releaseCreate.release.name) - expect(release.description).to.be.equal(releaseCreate.release.description) - expect(release.uid).to.be.equal(releaseUID) - expect(release.items.length).to.be.equal(1) - done() - }) - .catch(done) - }) - - it('Create release items', done => { - const items = [ - { - version: entries[1]._version, - uid: entries[1].uid, - content_type_uid: multiPageCT.content_type.uid, - action: 'publish', - locale: 'en-us' - }, - { - version: entries[2]._version, - uid: entries[2].uid, - content_type_uid: multiPageCT.content_type.uid, - action: 'publish', - locale: 'en-us' - } - ] - makeRelease(releaseUID) - .item() - .create({ items }) - .then((release) => { - expect(release.name).to.be.equal(releaseCreate.release.name) - expect(release.description).to.be.equal(releaseCreate.release.description) - expect(release.uid).to.be.equal(releaseUID) - expect(release.items.length).to.be.equal(3) - done() - }) - .catch(done) - }) - - it('Fetch a Release items from Uid', done => { - makeRelease(releaseUID) - .item() - .findAll() - .then((collection) => { - const itemdelete = collection.items[0] - itemToDelete['version'] = itemdelete.version - itemToDelete.action = itemdelete.action - itemToDelete.uid = itemdelete.uid - itemToDelete.locale = itemdelete.locale - itemToDelete.content_type_uid = itemdelete.content_type_uid - expect(collection.items.length).to.be.equal(3) - done() - }) - .catch(done) - }) - - it('Delete specific item', done => { - makeRelease(releaseUID) - .item() - .delete({ items: [itemToDelete] }) - .then((release) => { - expect(release.name).to.be.equal(releaseCreate.release.name) - expect(release.description).to.be.equal(releaseCreate.release.description) - expect(release.uid).to.be.equal(releaseUID) - expect(release.items.length).to.be.equal(2) - done() - }) - .catch(done) - }) - - it('Delete all items', done => { - makeRelease(releaseUID) - .item() - .delete() - .then((release) => { - expect(release.name).to.be.equal(releaseCreate.release.name) - expect(release.description).to.be.equal(releaseCreate.release.description) - expect(release.uid).to.be.equal(releaseUID) - expect(release.items.length).to.be.equal(0) - done() - }) - .catch(done) - }) - - it('Fetch and Update a Release from Uid', done => { - makeRelease(releaseUID) - .fetch() - .then((release) => { - release.name = 'Update release name' - return release.update() - }) - .then((release) => { - expect(release.name).to.be.equal('Update release name') - expect(release.description).to.be.equal(releaseCreate.release.description) - expect(release.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Update a Release from Uid', done => { - var relaseObject = makeRelease(releaseUID) - Object.assign(relaseObject, cloneDeep(releaseCreate.release)) - relaseObject - .update() - .then((release) => { - expect(release.name).to.be.equal(releaseCreate.release.name) - expect(release.description).to.be.equal(releaseCreate.release.description) - expect(release.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Get all Releases', done => { - makeRelease() - .query() - .find() - .then((releaseCollection) => { - releaseCollection.items.forEach(release => { - expect(release.name).to.be.not.equal(null) - expect(release.uid).to.be.not.equal(null) - }) - done() - }) - .catch(done) - }) - - it('Get specific Releases with name ', done => { - makeRelease() - .query({ query: { name: releaseCreate.release.name } }) - .find() - .then((releaseCollection) => { - releaseCollection.items.forEach(release => { - expect(release.name).to.be.equal(releaseCreate.release.name) - expect(release.uid).to.be.not.equal(null) - }) - done() - }) - .catch(done) - }) - - it('Clone specific Releases with Uid ', done => { - makeRelease(releaseUID) - .clone({ name: 'New Clone Name', description: 'New Desc' }) - .then((release) => { - expect(release.name).to.be.equal('New Clone Name') - expect(release.description).to.be.equal('New Desc') - expect(release.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Delete specific Releases with Uid ', done => { - makeRelease(releaseUID) - .delete() - .then((data) => { - expect(data.notice).to.be.equal('Release deleted successfully.') - done() - }) - .catch(done) - }) -}) - -function makeRelease (uid = null) { - return client.stack({ api_key: stack.api_key }).release(uid) -} diff --git a/test/api/role-test.js b/test/api/role-test.js deleted file mode 100644 index a5e37e5c..00000000 --- a/test/api/role-test.js +++ /dev/null @@ -1,139 +0,0 @@ -import { expect } from 'chai' -import { describe, it, setup } from 'mocha' -import role from './mock/role' -import { jsonReader, jsonWrite } from '../utility/fileOperations/readwrite' -import { contentstackClient } from '../utility/ContentstackClient.js' -var stack = {} -var client = {} -var roleUID = '' - -describe('Role api test', () => { - setup(() => { - const user = jsonReader('loggedinuser.json') - stack = jsonReader('stack.json') - client = contentstackClient(user.authtoken) - }) - - it('Get all role in stack', done => { - getRole() - .fetchAll() - .then((roles) => { - jsonWrite(roles.items, 'roles.json') - for (const index in roles.items) { - const role1 = roles.items[index] - expect(role1.uid).to.not.equal(null, 'Role uid cannot be null') - } - done() - }) - .catch(done) - }) - - it('Get 1 role in stack with limit', done => { - getRole() - .fetchAll({ limit: 1 }) - .then((roles) => { - expect(roles.items.length).to.not.equal(1, 'Role fetch with limit 1 not work') - done() - }) - .catch(done) - }) - - it('Get 2 role in stack with skip first', done => { - getRole() - .fetchAll({ skip: 1 }) - .then((roles) => { - expect(roles.items.lenth).to.not.equal(1, 'Role fetch with limit 1 not work') - done() - }) - .catch(done) - }) - - it('Create new role in stack', done => { - getRole() - .create(role) - .then((roles) => { - roleUID = roles.uid - expect(roles.name).to.be.equal(role.role.name, 'Role name not match') - expect(roles.description).to.be.equal(role.role.description, 'Role description not match') - expect(roles.rules.length).to.be.equal(3, 'Role rule length not match') - done() - }) - .catch(done) - }) - - it('Get role in stack', done => { - getRole(roleUID) - .fetch() - .then((roles) => { - jsonWrite(roles, 'role.json') - expect(roles.name).to.be.equal(role.role.name, 'Role name not match') - expect(roles.description).to.be.equal(role.role.description, 'Role description not match') - expect(roles.stack.api_key).to.be.equal(stack.api_key, 'Role stack uid not match') - done() - }) - .catch(done) - }) - - it('Update role in stack', done => { - getRole(roleUID) - .fetch({ include_rules: true, include_permissions: true }) - .then((roles) => { - roles.name = 'Update test name' - roles.description = 'Update description' - return roles.update() - }) - .then((roles) => { - expect(roles.name).to.be.equal('Update test name', 'Role name not match') - expect(roles.description).to.be.equal('Update description', 'Role description not match') - done() - }) - .catch(done) - }) - - it('Get all Roles with query', done => { - getRole() - .query() - .find() - .then((response) => { - for (const index in response.items) { - const role = response.items[index] - expect(role.name).to.not.equal(null) - expect(role.uid).to.not.equal(null) - } - done() - }) - .catch(done) - }) - - it('Get query Role', done => { - getRole() - .query({ query: { name: 'Developer' } }) - .find() - .then((response) => { - for (const index in response.items) { - const stack = response.items[index] - expect(stack.name).to.be.equal('Developer') - } - done() - }) - .catch(done) - }) - - it('Find one role', done => { - getRole() - .query({ name: 'Developer' }) - .findOne() - .then((response) => { - const stack = response.items[0] - expect(response.items.length).to.be.equal(1) - expect(stack.name).to.be.not.equal(null) - done() - }) - .catch(done) - }) -}) - -// Helper -function getRole (uid = null) { - return client.stack({ api_key: stack.api_key }).role(uid) -} diff --git a/test/api/stack-share.js b/test/api/stack-share.js deleted file mode 100644 index a61d5cad..00000000 --- a/test/api/stack-share.js +++ /dev/null @@ -1,34 +0,0 @@ -import { expect } from 'chai' -import { describe, it, setup } from 'mocha' -import { jsonReader } from '../utility/fileOperations/readwrite' -import { contentstackClient } from '../utility/ContentstackClient.js' -var stack = {} -var client = {} - -describe('Stack Share/Unshare', () => { - setup(() => { - const user = jsonReader('loggedinuser.json') - stack = jsonReader('stack.json') - client = contentstackClient(user.authtoken) - }) - it('Share stack test', done => { - const role = jsonReader('role.json') - client.stack({ api_key: stack.api_key }) - .share(['test@test.com'], { 'test@test.com': [role.uid] }) - .then((response) => { - expect(response.notice).to.be.equal('The invitation has been sent successfully.') - done() - }) - .catch(done) - }) - - it('unshare stack test', done => { - client.stack({ api_key: stack.api_key }) - .unShare('test@test.com') - .then((response) => { - expect(response.notice).to.be.equal('The stack has been successfully unshared.') - done() - }) - .catch(done) - }) -}) diff --git a/test/api/stack-test.js b/test/api/stack-test.js deleted file mode 100644 index 07e3701e..00000000 --- a/test/api/stack-test.js +++ /dev/null @@ -1,158 +0,0 @@ -import { expect } from 'chai' -import { describe, it, setup } from 'mocha' -import { jsonReader, jsonWrite } from '../utility/fileOperations/readwrite' -import dotenv from 'dotenv' -import { contentstackClient } from '../utility/ContentstackClient.js' -dotenv.config() - -var orgID = process.env.ORGANIZATION -var user = {} -var client = {} - -var stacks = {} -describe('Stack api Test', () => { - setup(() => { - user = jsonReader('loggedinuser.json') - client = contentstackClient(user.authtoken) - }) - const newStack = { - stack: - { - name: 'My New Stack', - description: 'My new test stack', - master_locale: 'en-us' - } - } - - it('Create Stack', done => { - client.stack() - .create(newStack, { organization_uid: orgID }) - .then((stack) => { - jsonWrite(stack, 'stack.json') - expect(stack.org_uid).to.be.equal(orgID) - expect(stack.api_key).to.not.equal(null) - expect(stack.name).to.be.equal(newStack.stack.name) - expect(stack.description).to.be.equal(newStack.stack.description) - done() - stacks = jsonReader('stack.json') - }) - .catch(done) - }) - - it('Fetch Stack details', done => { - client.stack({ api_key: stacks.api_key }) - .fetch() - .then((stack) => { - expect(stack.org_uid).to.be.equal(orgID) - expect(stack.api_key).to.not.equal(null) - expect(stack.name).to.be.equal(newStack.stack.name) - expect(stack.description).to.be.equal(newStack.stack.description) - done() - }) - .catch(done) - }) - - it('Update Stack details', done => { - const name = 'My New Stack Update Name' - const description = 'My New description stack' - client.stack({ api_key: stacks.api_key }) - .fetch().then((stack) => { - stack.name = name - stack.description = description - return stack.update() - }).then((stack) => { - expect(stack.name).to.be.equal(name) - expect(stack.description).to.be.equal(description) - done() - }) - .catch(done) - }) - - it('Get all users of stack', done => { - client.stack({ api_key: stacks.api_key }) - .users() - .then((response) => { - expect(response[0].uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Get stack settings', done => { - client.stack({ api_key: stacks.api_key }) - .settings() - .then((response) => { - expect(response.stack_variable).to.be.equal(undefined, 'Stack variable must be blank') - expect(response.discrete_variables.access_token).to.not.equal(null, 'Stack variable must not be blank') - expect(response.discrete_variables.secret_key).to.not.equal(null, 'Stack variable must not be blank') - done() - }) - .catch(done) - }) - - it('Add stack settings', done => { - client.stack({ api_key: stacks.api_key }) - .addSettings({ samplevariable: 'too' }) - .then((response) => { - expect(response.stack_variables.samplevariable).to.be.equal('too', 'samplevariable must set to \'too\' ') - done() - }) - .catch(done) - }) - - it('Reset stack settings', done => { - client.stack({ api_key: stacks.api_key }) - .resetSettings() - .then((response) => { - expect(response.stack_variable).to.be.equal(undefined, 'Stack variable must be blank') - expect(response.discrete_variables.access_token).to.not.equal(null, 'Stack variable must not be blank') - expect(response.discrete_variables.secret_key).to.not.equal(null, 'Stack variable must not be blank') - done() - }) - .catch(done) - }) - - it('Get all stack', done => { - client.stack() - .query() - .find() - .then((response) => { - for (const index in response.items) { - const stack = response.items[index] - expect(stack.name).to.not.equal(null) - expect(stack.uid).to.not.equal(null) - expect(stack.owner_uid).to.not.equal(null) - } - done() - }) - .catch(done) - }) - - it('Get query stack', done => { - client.stack() - .query({ query: { name: 'My New Stack Update Name' } }) - .find() - .then((response) => { - expect(response.items.length).to.be.equal(1) - for (const index in response.items) { - const stack = response.items[index] - expect(stack.name).to.be.equal('My New Stack Update Name') - } - done() - }) - .catch(done) - }) - - it('Find one stack', done => { - client.stack() - .query({ query: { name: 'My New Stack Update Name' } }) - .findOne() - .then((response) => { - const stack = response.items[0] - expect(response.items.length).to.be.equal(1) - expect(stack.name).to.be.equal('My New Stack Update Name') - done() - }) - .catch(done) - }) -}) diff --git a/test/api/taxonomy-test.js b/test/api/taxonomy-test.js deleted file mode 100644 index 86bbe597..00000000 --- a/test/api/taxonomy-test.js +++ /dev/null @@ -1,110 +0,0 @@ -import { expect } from 'chai' -import path from 'path' -import { describe, it, setup } from 'mocha' -import { jsonReader } from '../utility/fileOperations/readwrite' -import { contentstackClient } from '../utility/ContentstackClient.js' - -var client = {} -var stack = {} - -const taxonomy = { - uid: 'taxonomy_testing1', - name: 'taxonomy testing', - description: 'Description for Taxonomy testing' -} - -const importTaxonomy = { taxonomy: path.join(__dirname, './mock/taxonomy.json') } - -var taxonomyUID = '' -var taxonomyDelUID = 'taxonomy_testing' - -describe('taxonomy api Test', () => { - setup(() => { - const user = jsonReader('loggedinuser.json') - stack = jsonReader('stack.json') - client = contentstackClient(user.authtoken) - }) - - it('Create taxonomy', done => { - makeTaxonomy() - .create(taxonomy) - .then((taxonomyResponse) => { - expect(taxonomyResponse.name).to.be.equal(taxonomy.name) - done() - }) - .catch(done) - }) - - it('Import taxonomy', done => { - makeTaxonomy() - .import(importTaxonomy) - .then((taxonomyResponse) => { - expect(taxonomyResponse.name).to.be.equal('name') - done() - }) - .catch(done) - }) - - it('Export taxonomy', done => { - makeTaxonomy(taxonomyUID) - .export({}) - .then((taxonomyResponse) => { - expect(taxonomyResponse.uid).to.be.equal(taxonomyUID) - expect(taxonomyResponse.name).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Fetch taxonomy from uid', done => { - makeTaxonomy(taxonomyUID) - .fetch() - .then((taxonomyResponse) => { - expect(taxonomyResponse.uid).to.be.equal(taxonomyUID) - expect(taxonomyResponse.name).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Update taxonomy from uid', done => { - makeTaxonomy(taxonomyUID) - .fetch() - .then((taxonomyResponse) => { - taxonomyResponse.name = 'Updated Name' - return taxonomyResponse.update() - }) - .then((taxonomyResponse) => { - expect(taxonomyResponse.uid).to.be.equal(taxonomyUID) - expect(taxonomyResponse.name).to.be.equal('Updated Name') - done() - }) - .catch(done) - }) - - it('Delete taxonomy from uid', done => { - makeTaxonomy(taxonomyDelUID) - .delete() - .then((taxonomyResponse) => { - expect(taxonomyResponse.notice).to.be.equal('Taxonomy deleted successfully.') - done() - }) - .catch(done) - }) - - it('Query to get all taxonomies', async () => { - makeTaxonomy() - .query() - .find() - .then((response) => { - response.items.forEach((taxonomyResponse) => { - expect(taxonomyResponse.uid).to.be.not.equal(null) - expect(taxonomyResponse.name).to.be.not.equal(null) - }) - }) - }) -}) - -function makeTaxonomy (uid = null) { - return client.stack({ api_key: stack.api_key }).taxonomy(uid) -} diff --git a/test/api/team-stack-role-mapping-test.js b/test/api/team-stack-role-mapping-test.js deleted file mode 100644 index c94bc318..00000000 --- a/test/api/team-stack-role-mapping-test.js +++ /dev/null @@ -1,65 +0,0 @@ -import { describe, it, beforeEach } from 'mocha' -import { expect } from 'chai' -import { jsonReader } from '../utility/fileOperations/readwrite' -import { contentstackClient } from '../utility/ContentstackClient.js' - -let client = {} - -const stackApiKey = 'stackApiKey' -const organizationUid = 'organizationUid' -const teamUid = 'teamUid' - -describe('Teams API Test', () => { - beforeEach(() => { - const user = jsonReader('loggedinuser.json') - client = contentstackClient(user.authtoken) - }) - it('should fetch all stackRoleMappings', done => { - makestackRoleMappings(organizationUid, teamUid).fetchAll().then((response) => { - expect(response.stackRoleMappings).to.be.not.equal(undefined) - done() - }) - .catch(done) - }) - it('should add roles', done => { - const stackRoleMappings = { - stackApiKey: 'stackApiKey', - roles: [ - 'role_uid' - ] - } - makestackRoleMappings(organizationUid, teamUid).add(stackRoleMappings).then((response) => { - expect(response.stackRoleMapping).not.to.be.equal(undefined) - expect(response.stackRoleMapping.roles[0]).to.be.equal(stackRoleMappings.roles[0]) - expect(response.stackRoleMapping.stackApiKey).to.be.equal(stackRoleMappings.stackApiKey) - done() - }) - .catch(done) - }) - it('should update roles', done => { - const stackRoleMappings = { - roles: [ - 'role_uid1', - 'role_uid2' - ] - } - makestackRoleMappings(organizationUid, teamUid, stackApiKey).update(stackRoleMappings).then((response) => { - expect(response.stackRoleMapping).not.to.be.equal(undefined) - expect(response.stackRoleMapping.roles[0]).to.be.equal(stackRoleMappings.roles[0]) - expect(response.stackRoleMapping.stackApiKey).to.be.equal(stackApiKey) - done() - }) - .catch(done) - }) - it('should delete roles', done => { - makestackRoleMappings(organizationUid, teamUid, stackApiKey).delete().then((response) => { - expect(response.status).to.be.equal(204) - done() - }) - .catch(done) - }) -}) - -function makestackRoleMappings (organizationUid, teamUid, stackApiKey = null) { - return client.organization(organizationUid).teams(teamUid).stackRoleMappings(stackApiKey) -} diff --git a/test/api/team-test.js b/test/api/team-test.js deleted file mode 100644 index 4cbb6408..00000000 --- a/test/api/team-test.js +++ /dev/null @@ -1,69 +0,0 @@ -import { describe, it, beforeEach } from 'mocha' -import { expect } from 'chai' -import { jsonReader } from '../utility/fileOperations/readwrite' -import { contentstackClient } from '../utility/ContentstackClient.js' - -let client = {} - -const organizationUid = 'organizationUid' -const teamUid = 'teamUid' -const deleteUid = 'deleteUid' - -describe('Teams API Test', () => { - beforeEach(() => { - const user = jsonReader('loggedinuser.json') - client = contentstackClient(user.authtoken) - }) - it('should get all the teams when correct organization uid is passed', async () => { - const response = await makeTeams(organizationUid).fetchAll() - expect(response.items[0].organizationUid).to.be.equal(organizationUid) - expect(response.items[0].name).not.to.be.equal(null) - expect(response.items[0].created_by).not.to.be.equal(null) - expect(response.items[0].updated_by).not.to.be.equal(null) - }) - it('should fetch the team when correct organization uid and team uid is passed', async () => { - const response = await makeTeams(organizationUid, teamUid).fetch() - expect(response.uid).to.be.equal(teamUid) - expect(response.organizationUid).to.be.equal(organizationUid) - expect(response.name).not.to.be.equal(null) - expect(response.created_by).not.to.be.equal(null) - expect(response.updated_by).not.to.be.equal(null) - }) - it('should create new team when required object is passed', async () => { - const response = await makeTeams(organizationUid).create({ - name: 'test_team', - users: [], - stackRoleMapping: [], - organizationRole: 'organizationRole' }) - expect(response.uid).not.to.be.equal(null) - expect(response.name).not.to.be.equal(null) - expect(response.stackRoleMapping).not.to.be.equal(null) - expect(response.organizationRole).not.to.be.equal(null) - }) - it('should delete team when correct organization uid and team uid is passed', async () => { - const response = await makeTeams(organizationUid, deleteUid).delete() - expect(response.status).to.be.equal(204) - }) - it('should update team when updating data is passed', async () => { - const updateData = { - name: 'name', - users: [ - { - email: 'abc@abc.com' - } - ], - organizationRole: '', - stackRoleMapping: [] - } - await makeTeams(organizationUid, teamUid).update(updateData) - .then((team) => { - expect(team.name).to.be.equal(updateData.name) - expect(team.createdByUserName).not.to.be.equal(undefined) - expect(team.updatedByUserName).not.to.be.equal(undefined) - }) - }) -}) - -function makeTeams (organizationUid, teamUid = null) { - return client.organization(organizationUid).teams(teamUid) -} diff --git a/test/api/team-users-test.js b/test/api/team-users-test.js deleted file mode 100644 index 30c5d41d..00000000 --- a/test/api/team-users-test.js +++ /dev/null @@ -1,47 +0,0 @@ -import { describe, it, beforeEach } from 'mocha' -import { expect } from 'chai' -import { jsonReader } from '../utility/fileOperations/readwrite' -import { contentstackClient } from '../utility/ContentstackClient.js' - -let client = {} - -const organizationUid = 'organizationUid' -const teamUid = 'teamUid' -const userId = 'userId' - -describe('Teams Users API Test', () => { - beforeEach(() => { - const user = jsonReader('loggedinuser.json') - client = contentstackClient(user.authtoken) - }) - it('should add the user when user\'s mail is passed', done => { - const usersMail = { - emails: ['email@email.com'] - } - makeUsers(organizationUid, teamUid).add(usersMail).then((response) => { - expect(response.status).to.be.equal(201) - done() - }) - .catch(done) - }) - it('should remove the user when uid is passed', done => { - makeUsers(organizationUid, teamUid, userId).remove().then((response) => { - expect(response.status).to.be.equal(204) - done() - }) - .catch(done) - }) - it('should fetch all users', async () => { - makeUsers(organizationUid, teamUid) - .fetchAll() - .then((response) => { - response.items.forEach((user) => { - expect(user.uidId).to.be.not.equal(null) - }) - }) - }) -}) - -function makeUsers (organizationUid, teamUid, userId = null) { - return client.organization(organizationUid).teams(teamUid).teamUsers(userId) -} diff --git a/test/api/terms-test.js b/test/api/terms-test.js deleted file mode 100644 index 79aab144..00000000 --- a/test/api/terms-test.js +++ /dev/null @@ -1,137 +0,0 @@ -import { describe, it, beforeEach } from 'mocha' -import { expect } from 'chai' -import { jsonReader } from '../utility/fileOperations/readwrite' -import { contentstackClient } from '../utility/ContentstackClient.js' - -var client = {} -var stack = {} - -const taxonomyUid = '' -const termUid = '' -const term = { - term: { - uid: 'term_test', - name: 'Term test' - }, - parent_uid: null -} - -describe('Terms API Test', () => { - beforeEach(() => { - const user = jsonReader('loggedinuser.json') - stack = jsonReader('stack.json') - client = contentstackClient(user.authtoken) - }) - - it('Create term', async () => { - try { - const response = await makeTerms(taxonomyUid).create(term) - expect(response.notice).to.be.equal('Term created successfully.') - expect(response.uid).to.be.equal(term.term.uid) - } catch (err) { - console.log(err) - } - }) - - it('Query and get all terms', async () => { - try { - const response = await makeTerms(taxonomyUid).query().find() - expect(response.items).to.be.an('array') - expect(response.items[0].uid).not.to.be.equal(null) - expect(response.items[0].name).not.to.be.equal(null) - } catch (err) { - console.log(err) - } - }) - - it('Fetch term from UID', async () => { - try { - const response = await makeTerms(taxonomyUid, termUid).fetch() - expect(response.uid).to.be.equal(termUid) - expect(response.name).not.to.be.equal(null) - expect(response.created_by).not.to.be.equal(null) - expect(response.updated_by).not.to.be.equal(null) - } catch (err) { - console.log(err) - } - }) - - it('Update term', async () => { - try { - const response = await makeTerms(taxonomyUid, termUid).fetch() - .then((term) => { - term.name = 'fashion' - return term.update() - }) - expect(response.notice).to.be.equal('Term updated successfully.') - expect(response.uid).to.be.equal(termUid) - expect(response.name).to.be.equal('fashion') - expect(response.created_by).not.to.be.equal(null) - expect(response.updated_by).not.to.be.equal(null) - } catch (err) { - console.log(err) - } - }) - - it('Delete term from UID', async () => { - try { - const response = await makeTerms(termUid).delete() - expect(response.notice).to.be.equal('') - } catch (err) { - console.log(err) - } - }) - - it('Ancestors of the term given', async () => { - try { - const response = await makeTerms(taxonomyUid, termUid).ancestors() - expect(response.terms[0].uid).not.to.be.equal(null) - expect(response.terms[0].name).not.to.be.equal(null) - expect(response.terms[0].created_by).not.to.be.equal(null) - expect(response.terms[0].updated_by).not.to.be.equal(null) - } catch (err) { - console.log(err) - } - }) - - it('Descendants of the term given', async () => { - try { - const response = await makeTerms(taxonomyUid, termUid).descendants() - expect(response.terms.uid).not.to.be.equal(null) - expect(response.terms.name).not.to.be.equal(null) - expect(response.terms.created_by).not.to.be.equal(null) - expect(response.terms.updated_by).not.to.be.equal(null) - } catch (err) { - console.log(err) - } - }) - it('search term', async () => { - const termString = '' - try { - const response = await makeTerms(taxonomyUid).search(termString) - expect(response.terms).to.be.an('array') - } catch (err) { - console.log(err) - } - }) - it('move term', async () => { - try { - const term = { - parent_uid: 'parent_uid', - order: 2 - } - await makeTerms(taxonomyUid, termUid).move({ term }) - .then((term) => { - term.parent_uid = 'parent_uid' - console.log(term.move()) - return term.move() - }) - } catch (err) { - console.log(err) - } - }) -}) - -function makeTerms (taxonomyUid, termUid = null) { - return client.stack({ api_key: stack.api_key }).taxonomy(taxonomyUid).terms(termUid) -} diff --git a/test/api/ungroupedVariants-test.js b/test/api/ungroupedVariants-test.js deleted file mode 100644 index 94b46404..00000000 --- a/test/api/ungroupedVariants-test.js +++ /dev/null @@ -1,106 +0,0 @@ -import { expect } from 'chai' -import { describe, it, setup } from 'mocha' -import { jsonReader } from '../utility/fileOperations/readwrite' -import { contentstackClient } from '../utility/ContentstackClient.js' - -var client = {} -var stack = {} - -const variants = { - uid: 'iphone_color_white', // optional - name: 'White', - personalize_metadata: { - experience_uid: 'exp1', - experience_short_uid: 'expShortUid1', - project_uid: 'project_uid1', - variant_short_uid: 'variantShort_uid1' - } -} - -var variantsUID = '' -var deleteVariantsUID = '' -describe('Variants api Test', () => { - setup(() => { - const user = jsonReader('loggedinuser.json') - stack = jsonReader('stack.json') - client = contentstackClient(user.authtoken) - }) - - it('Variants create', done => { - makeVariants() - .create({ variants }) - .then((variantsResponse) => { - variantsUID = variantsResponse.uid - expect(variantsResponse.uid).to.be.not.equal(null) - expect(variantsResponse.name).to.be.equal(variants.name) - done() - }) - .catch(done) - }) - - it('Fetch variants from uid', done => { - makeVariants(variantsUID) - .fetch() - .then((variantsResponse) => { - expect(variantsResponse.uid).to.be.equal(variantsUID) - expect(variantsResponse.name).to.be.equal(variants.name) - done() - }) - .catch(done) - }) - - it('Query to get all variantss', done => { - makeVariants() - .query({ query: { name: variants.name } }) - .find() - .then((response) => { - response.items.forEach((variantsResponse) => { - expect(variantsResponse.uid).to.be.not.equal(null) - expect(variantsResponse.name).to.be.not.equal(null) - }) - done() - }) - .catch(done) - }) - - it('Query variants with name', done => { - makeVariants() - .query({ query: { name: variants.name } }) - .find() - .then((response) => { - response.items.forEach((variantsResponse) => { - expect(variantsResponse.uid).to.be.equal(variantsUID) - expect(variantsResponse.name).to.be.equal(variants.name) - }) - done() - }) - .catch(done) - }) - - it('Fetch By variants UIDs ', done => { - makeVariants() - .fetchByUIDs(['uid1', 'uid2']) - .then((response) => { - response.variants.forEach((variantsResponse) => { - expect(variantsResponse.uid).to.be.equal(variantsUID) - expect(variantsResponse.name).to.be.equal(variants.name) - }) - done() - }) - .catch(done) - }) - - it('Delete variants from uid', done => { - makeVariants(deleteVariantsUID) - .delete() - .then((data) => { - expect(data.notice).to.be.equal('Variants deleted successfully.') - done() - }) - .catch(done) - }) -}) - -function makeVariants (uid = null) { - return client.stack({ api_key: stack.api_key }).variants(uid) -} diff --git a/test/api/user-test.js b/test/api/user-test.js deleted file mode 100644 index 5d7b9e5e..00000000 --- a/test/api/user-test.js +++ /dev/null @@ -1,77 +0,0 @@ -import { expect } from 'chai' -import { describe, it } from 'mocha' - -import { contentstackClient } from '../utility/ContentstackClient' -import axios from 'axios' -import { jsonWrite } from '../utility/fileOperations/readwrite' -import dotenv from 'dotenv' -dotenv.config() -var authtoken = '' -var loggedinUserID = '' -var client = contentstackClient() -describe('Contentstack User Session api Test', () => { - it('User login wrong credentials', done => { - contentstackClient().login({ email: process.env.EMAIL, password: process.env.PASSWORD }) - .then((response) => { - done() - }).catch((error) => { - const jsonMessage = JSON.parse(error.message) - const payload = JSON.parse(jsonMessage.request.data) - expect(jsonMessage.status).to.be.equal(422, 'Status code does not match') - expect(jsonMessage.errorMessage).to.not.equal(null, 'Error message not proper') - expect(jsonMessage.errorCode).to.be.equal(104, 'Error code does not match') - expect(payload.user.email).to.be.equal(process.env.EMAIL, 'Email id does not match') - expect(payload.user.password).to.be.equal('contentstack', 'Password does not match') - done() - }) - }) - - it('User Login test', done => { - client.login({ email: process.env.EMAIL, password: process.env.PASSWORD }, { include_orgs: true, include_orgs_roles: true, include_stack_roles: true, include_user_settings: true }).then((response) => { - jsonWrite(response.user, 'loggedinuser.json') - expect(response.notice).to.be.equal('Login Successful.', 'Login success messsage does not match.') - done() - }) - .catch(done) - }) - - it('User logout test', done => { - client.logout() - .then((response) => { - expect(axios.defaults.headers.common.authtoken).to.be.equal(undefined) - expect(response.notice).to.be.equal('You\'ve logged out successfully.') - done() - }) - .catch(done) - }) - - it('User login with credentials', done => { - client.login({ email: process.env.EMAIL, password: process.env.PASSWORD }, { include_orgs: true, include_orgs_roles: true, include_stack_roles: true, include_user_settings: true }).then((response) => { - loggedinUserID = response.user.uid - jsonWrite(response.user, 'loggedinuser.json') - expect(response.notice).to.be.equal('Login Successful.', 'Login success messsage does not match.') - done() - }) - .catch(done) - }) - - it('Get Current user info test', done => { - client.getUser().then((user) => { - authtoken = user.authtoken - expect(user.uid).to.be.equal(loggedinUserID) - done() - }) - .catch(done) - }) - - it('Get user info from authtoken', done => { - contentstackClient(authtoken) - .getUser() - .then((user) => { - expect(user.uid).to.be.equal(loggedinUserID) - expect(true).to.be.equal(true) - done() - }) - .catch(done) - }) -}) diff --git a/test/api/variantGroup-test.js b/test/api/variantGroup-test.js deleted file mode 100644 index 695953f9..00000000 --- a/test/api/variantGroup-test.js +++ /dev/null @@ -1,136 +0,0 @@ -import { expect } from 'chai' -import { describe, it, setup } from 'mocha' -import { jsonReader } from '../utility/fileOperations/readwrite' -import { createVariantGroup, createVariantGroup1, createVariantGroup2 } from './mock/variantGroup.js' -import { contentstackClient } from '../utility/ContentstackClient.js' - -var client = {} - -var stack = {} -var tokenUID = '' -describe('Variant Group api Test', () => { - setup(() => { - const user = jsonReader('loggedinuser.json') - stack = jsonReader('stack.json') - client = contentstackClient(user.authtoken) - }) - - it('Add a Variant Group', done => { - makeVariantGroup() - .create(createVariantGroup) - .then((variantGroup) => { - expect(variantGroup.name).to.be.equal(createVariantGroup.name) - expect(variantGroup.description).to.be.equal(createVariantGroup.description) - expect(variantGroup.scope[0].module).to.be.equal(createVariantGroup.scope[0].module) - expect(variantGroup.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Add a Variant Group for production', done => { - makeVariantGroup() - .create(createVariantGroup2) - .then((variantGroup) => { - tokenUID = variantGroup.uid - expect(variantGroup.name).to.be.equal(createVariantGroup2.name) - expect(variantGroup.description).to.be.equal(createVariantGroup2.description) - expect(variantGroup.scope[0].module).to.be.equal(createVariantGroup2.scope[0].module) - expect(variantGroup.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Get a Variant Group from uid', done => { - makeVariantGroup(tokenUID) - .fetch() - .then((variantGroup) => { - expect(variantGroup.name).to.be.equal(createVariantGroup1.name) - expect(variantGroup.description).to.be.equal(createVariantGroup1.description) - expect(variantGroup.scope[0].module).to.be.equal(createVariantGroup1.scope[0].module) - expect(variantGroup.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Query to get all Variant Group', done => { - makeVariantGroup() - .query() - .find() - .then((tokens) => { - tokens.items.forEach((variantGroup) => { - expect(variantGroup.name).to.be.not.equal(null) - expect(variantGroup.description).to.be.not.equal(null) - expect(variantGroup.scope[0].module).to.be.not.equal(null) - expect(variantGroup.uid).to.be.not.equal(null) - }) - done() - }) - .catch(done) - }) - - it('Query to get a Variant Group from name', done => { - makeVariantGroup() - .query({ query: { name: createVariantGroup.name } }) - .find() - .then((tokens) => { - tokens.items.forEach((variantGroup) => { - expect(variantGroup.name).to.be.equal(createVariantGroup.name) - expect(variantGroup.description).to.be.equal(createVariantGroup.description) - expect(variantGroup.scope[0].module).to.be.equal(createVariantGroup.scope[0].module) - expect(variantGroup.uid).to.be.not.equal(null) - }) - done() - }) - .catch(done) - }) - - it('Fetch and update a Variant Group from uid', done => { - makeVariantGroup(tokenUID) - .fetch() - .then((variantGroup) => { - variantGroup.name = 'Update Production Name' - variantGroup.description = 'Update Production description' - variantGroup.scope = createVariantGroup2.scope - return variantGroup.update() - }) - .then((variantGroup) => { - expect(variantGroup.name).to.be.equal('Update Production Name') - expect(variantGroup.description).to.be.equal('Update Production description') - expect(variantGroup.scope[0].module).to.be.equal(createVariantGroup2.scope[0].module) - expect(variantGroup.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Update a Variant Group from uid', done => { - const variantGroup = makeVariantGroup(tokenUID) - Object.assign(variantGroup, createVariantGroup2.variantGroup) - variantGroup.update() - .then((variantGroup) => { - expect(variantGroup.name).to.be.equal(createVariantGroup2.name) - expect(variantGroup.description).to.be.equal(createVariantGroup2.description) - expect(variantGroup.scope[0].module).to.be.equal(createVariantGroup2.scope[0].module) - expect(variantGroup.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Delete a Variant Group from uid', done => { - makeVariantGroup(tokenUID) - .delete() - .then((data) => { - expect(data.notice).to.be.equal('Variant Group deleted successfully.') - done() - }) - .catch(done) - }) -}) - -function makeVariantGroup (uid = null) { - return client.stack({ api_key: stack.api_key }).variantGroup(uid) -} diff --git a/test/api/variants-test.js b/test/api/variants-test.js deleted file mode 100644 index bebc332d..00000000 --- a/test/api/variants-test.js +++ /dev/null @@ -1,112 +0,0 @@ -import { expect } from 'chai' -import { describe, it, setup } from 'mocha' -import { jsonReader } from '../utility/fileOperations/readwrite' -import { variant, variant2 } from './mock/variants.js' -import { contentstackClient } from '../utility/ContentstackClient.js' - -var client = {} - -var stack = {} -var tokenUID = '' -describe('Variants api Test', () => { - setup(() => { - const user = jsonReader('loggedinuser.json') - stack = jsonReader('stack.json') - client = contentstackClient(user.authtoken) - }) - - it('Add a Variants', done => { - makeVariants() - .create(variant) - .then((variants) => { - expect(variants.name).to.be.equal(variant.name) - expect(variants.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Add a Variants for production', done => { - makeVariants() - .create(variant2) - .then((variants) => { - tokenUID = variants.uid - expect(variants.name).to.be.equal(variant2.name) - expect(variants.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Get a Variants from uid', done => { - makeVariants(tokenUID) - .fetch() - .then((variants) => { - expect(variants.name).to.be.equal(variant2.name) - expect(variants.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Query to get all Variants', done => { - makeVariants() - .query() - .find() - .then((tokens) => { - tokens.items.forEach((variants) => { - expect(variants.name).to.be.not.equal(null) - expect(variants.uid).to.be.not.equal(null) - }) - done() - }) - .catch(done) - }) - - it('Query to get a Variants from name', done => { - makeVariants() - .query({ query: { name: variant.name } }) - .find() - .then((tokens) => { - tokens.items.forEach((variants) => { - expect(variants.name).to.be.equal(variant.name) - expect(variants.uid).to.be.not.equal(null) - }) - done() - }) - .catch(done) - }) - - it('Fetch and update a Variants from uid', done => { - makeVariants(tokenUID) - .fetch() - .then((variants) => { - variants.name = 'Update Production Name' - variants.description = 'Update Production description' - variants.scope = variant2.scope - return variants.update() - }) - .then((variants) => { - expect(variants.name).to.be.equal('Update Production Name') - expect(variants.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Update a Variants from uid', done => { - const variants = makeVariants(tokenUID) - Object.assign(variants, variant2.variants) - variants.update() - .then((variants) => { - expect(variants.name).to.be.equal(variant2.name) - expect(variants.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) -}) - -function makeVariants (uid = null) { - return client.stack({ api_key: stack.api_key }).variantGroup('uid').variants(uid) -} diff --git a/test/api/webhook-test.js b/test/api/webhook-test.js deleted file mode 100644 index 9816fdcd..00000000 --- a/test/api/webhook-test.js +++ /dev/null @@ -1,149 +0,0 @@ -import { expect } from 'chai' -import { describe, it, setup } from 'mocha' -import path from 'path' -import { jsonReader } from '../utility/fileOperations/readwrite' -import { webhook, updateWebhook } from './mock/webhook' -import { cloneDeep } from 'lodash' -import { contentstackClient } from '../utility/ContentstackClient.js' -var client = {} - -var stack = {} -var webhookUid = '' -describe('Webhook api Test', () => { - setup(() => { - const user = jsonReader('loggedinuser.json') - stack = jsonReader('stack.json') - client = contentstackClient(user.authtoken) - }) - - it('Create Webhook', done => { - makeWebhook() - .create(webhook) - .then((response) => { - webhookUid = response.uid - expect(response.uid).to.be.not.equal(null) - expect(response.name).to.be.equal(webhook.webhook.name) - expect(response.destinations[0].target_url).to.be.equal(webhook.webhook.destinations[0].target_url) - expect(response.destinations[0].http_basic_auth).to.be.equal(webhook.webhook.destinations[0].http_basic_auth) - expect(response.destinations[0].http_basic_password).to.be.equal(webhook.webhook.destinations[0].http_basic_password) - expect(response.channels[0]).to.be.equal(webhook.webhook.channels[0]) - expect(response.retry_policy).to.be.equal(webhook.webhook.retry_policy) - expect(response.disabled).to.be.equal(webhook.webhook.disabled) - done() - }) - .catch(done) - }) - - it('Fetch Webhook', done => { - makeWebhook(webhookUid) - .fetch() - .then((response) => { - expect(response.uid).to.be.equal(webhookUid) - expect(response.name).to.be.equal(webhook.webhook.name) - expect(response.destinations[0].target_url).to.be.equal(webhook.webhook.destinations[0].target_url) - expect(response.destinations[0].http_basic_auth).to.be.equal(webhook.webhook.destinations[0].http_basic_auth) - expect(response.destinations[0].http_basic_password).to.be.equal(webhook.webhook.destinations[0].http_basic_password) - expect(response.channels[0]).to.be.equal(webhook.webhook.channels[0]) - expect(response.retry_policy).to.be.equal(webhook.webhook.retry_policy) - expect(response.disabled).to.be.equal(webhook.webhook.disabled) - done() - }) - .catch(done) - }) - - it('Fetch and update Webhook', done => { - makeWebhook(webhookUid) - .fetch() - .then((webhookRes) => { - Object.assign(webhookRes, cloneDeep(updateWebhook.webhook)) - return webhookRes.update() - }) - .then((response) => { - expect(response.uid).to.be.equal(webhookUid) - expect(response.name).to.be.equal(updateWebhook.webhook.name) - expect(response.destinations[0].target_url).to.be.equal(updateWebhook.webhook.destinations[0].target_url) - expect(response.destinations[0].http_basic_auth).to.be.equal(updateWebhook.webhook.destinations[0].http_basic_auth) - expect(response.destinations[0].http_basic_password).to.be.equal(updateWebhook.webhook.destinations[0].http_basic_password) - expect(response.channels[0]).to.be.equal(updateWebhook.webhook.channels[0]) - expect(response.retry_policy).to.be.equal(updateWebhook.webhook.retry_policy) - expect(response.disabled).to.be.equal(updateWebhook.webhook.disabled) - done() - }) - .catch(done) - }) - - it('Update Webhook', done => { - var webhookObject = makeWebhook(webhookUid) - Object.assign(webhookObject, cloneDeep(updateWebhook.webhook)) - webhookObject.update() - .then((response) => { - expect(response.uid).to.be.equal(webhookUid) - expect(response.name).to.be.equal(updateWebhook.webhook.name) - expect(response.destinations[0].target_url).to.be.equal(updateWebhook.webhook.destinations[0].target_url) - expect(response.destinations[0].http_basic_auth).to.be.equal(updateWebhook.webhook.destinations[0].http_basic_auth) - expect(response.destinations[0].http_basic_password).to.be.equal(updateWebhook.webhook.destinations[0].http_basic_password) - expect(response.channels[0]).to.be.equal(updateWebhook.webhook.channels[0]) - expect(response.retry_policy).to.be.equal(updateWebhook.webhook.retry_policy) - expect(response.disabled).to.be.equal(updateWebhook.webhook.disabled) - done() - }) - .catch(done) - }) - - it('Import Webhook', done => { - makeWebhook().import({ - webhook: path.join(__dirname, './mock/webhook.json') - }) - .then((response) => { - expect(response.uid).to.be.not.equal(null) - done() - }) - .catch(done) - }) - - it('Get executions of a webhook', done => { - const asset = { - upload: path.join(__dirname, './mock/webhook.json') - } - client.stack({ api_key: stack.api_key }).asset().create(asset) - .then((assetFile) => { - makeWebhook(webhookUid).executions() - .then((response) => { - response.webhooks.forEach(webhookResponse => { - expect(webhookResponse.uid).to.be.not.equal(null) - expect(webhookResponse.status).to.be.equal(200) - expect(webhookResponse.event_data.module).to.be.equal('asset') - expect(webhookResponse.event_data.api_key).to.be.equal(stack.api_key) - - const webhookasset = webhookResponse.event_data.data.asset - expect(webhookasset.uid).to.be.equal(assetFile.uid) - expect(webhookasset.filename).to.be.equal(assetFile.filename) - expect(webhookasset.url).to.be.equal(assetFile.url) - expect(webhookasset.title).to.be.equal(assetFile.title) - - expect(webhookResponse.webhooks[0]).to.be.equal(webhookUid) - expect(webhookResponse.channel[0]).to.be.equal('assets.create') - }) - done() - }) - .catch(done) - }).catch(done) - }) - - it('Get all Webhook', done => { - makeWebhook().fetchAll() - .then((collection) => { - collection.items.forEach(webhookResponse => { - expect(webhookResponse.uid).to.be.not.equal(null) - expect(webhookResponse.name).to.be.not.equal(null) - expect(webhookResponse.org_uid).to.be.equal(stack.org_uid) - }) - done() - }) - .catch(done) - }) -}) - -function makeWebhook (uid = null) { - return client.stack({ api_key: stack.api_key }).webhook(uid) -} diff --git a/test/api/workflow-test.js b/test/api/workflow-test.js deleted file mode 100644 index c37cf592..00000000 --- a/test/api/workflow-test.js +++ /dev/null @@ -1,485 +0,0 @@ -import { expect } from 'chai' -import { describe, it, setup } from 'mocha' -import { jsonReader } from '../utility/fileOperations/readwrite' -import { contentstackClient } from '../utility/ContentstackClient.js' -import { firstWorkflow, secondWorkflow, finalWorkflow, firstPublishRules, secondPublishRules } from './mock/workflow' -import { cloneDeep } from 'lodash' -var client = {} -var environment = {} - -var roles = {} -var stack = {} -var user = {} -var workflowUid = '' -var publishRuleUid = '' - -describe('Workflow api Test', () => { - setup(async () => { - user = jsonReader('loggedinuser.json') - stack = jsonReader('stack.json') - client = contentstackClient(user.authtoken) - environment = jsonReader('environments.json') - roles = jsonReader('roles.json') - }) - - it('Create Workflow Content type Multi page from JSON', done => { - const workflow = { ...firstWorkflow } - makeWorkflow() - .create({ workflow }) - .then(workflowResponse => { - workflowUid = workflowResponse.uid - expect(workflowResponse.name).to.be.equal(firstWorkflow.name) - expect(workflowResponse.content_types.length).to.be.equal(firstWorkflow.content_types.length) - expect(workflowResponse.workflow_stages.length).to.be.equal(firstWorkflow.workflow_stages.length) - done() - }) - .catch(done) - }) - - it('Create Workflow Content type Multi page', done => { - const workflow = { ...secondWorkflow } - makeWorkflow() - .create({ workflow }) - .then(workflowResponse => { - expect(workflowResponse.name).to.be.equal(secondWorkflow.name) - expect(workflowResponse.content_types.length).to.be.equal(secondWorkflow.content_types.length) - expect(workflowResponse.workflow_stages.length).to.be.equal(secondWorkflow.workflow_stages.length) - done() - }) - .catch(done) - }) - - it('Create Workflow Content type single page', done => { - const workflow = { ...finalWorkflow } - makeWorkflow() - .create({ workflow }) - .then(workflowResponse => { - expect(workflowResponse.name).to.be.equal(finalWorkflow.name) - expect(workflowResponse.content_types.length).to.be.equal(finalWorkflow.content_types.length) - expect(workflowResponse.workflow_stages.length).to.be.equal(finalWorkflow.workflow_stages.length) - done() - }) - .catch(done) - }) - - it('Fetch Workflow from UID', done => { - makeWorkflow(workflowUid) - .fetch() - .then(workflowResponse => { - workflowUid = workflowResponse.uid - expect(workflowResponse.name).to.be.equal(firstWorkflow.name) - expect(workflowResponse.content_types.length).to.be.equal(firstWorkflow.content_types.length) - expect(workflowResponse.workflow_stages.length).to.be.equal(firstWorkflow.workflow_stages.length) - done() - }) - .catch(done) - }) - - it('Update Workflow from UID', done => { - const workflowObj = makeWorkflow(workflowUid) - Object.assign(workflowObj, firstWorkflow) - workflowObj.name = 'Updated name' - - workflowObj - .update() - .then(workflowResponse => { - workflowUid = workflowResponse.uid - expect(workflowResponse.name).to.be.equal('Updated name') - expect(workflowResponse.content_types.length).to.be.equal(firstWorkflow.content_types.length) - expect(workflowResponse.workflow_stages.length).to.be.equal(firstWorkflow.workflow_stages.length) - done() - }) - .catch(done) - }) - - it('Fetch and update Workflow from UID', done => { - makeWorkflow(workflowUid) - .fetch() - .then(workflowResponse => { - workflowResponse.name = firstWorkflow.name - return workflowResponse.update() - }) - .then(workflowResponse => { - expect(workflowResponse.name).to.be.equal(firstWorkflow.name) - expect(workflowResponse.content_types.length).to.be.equal(firstWorkflow.content_types.length) - expect(workflowResponse.workflow_stages.length).to.be.equal(firstWorkflow.workflow_stages.length) - done() - }) - .catch(done) - }) - it('Fetch all workflow', done => { - makeWorkflow() - .fetchAll() - .then(collection => { - expect(collection.items.length).to.be.equal(3) - done() - }) - .catch(done) - }) - - it('Fetch all workflow and update', done => { - makeWorkflow() - .fetchAll() - .then(collection => { - const updatedWorkflow = collection.items[0] - updatedWorkflow.name = 'Updated name' - return updatedWorkflow.update() - }) - .then((update) => { - expect(update.name).to.be.equal('Updated name') - done() - }) - .catch(done) - }) - - it('Fetch all workflow include count', done => { - makeWorkflow() - .fetchAll({ include_count: true }) - .then(collection => { - expect(collection.count).to.be.equal(3) - done() - }) - .catch(done) - }) - - it('Fetch all workflow skip and limit', done => { - makeWorkflow() - .fetchAll({ skip: 1, limit: 1 }) - .then(collection => { - expect(collection.items.length).to.be.equal(1) - done() - }) - .catch(done) - }) - - it('Enable Workflow from uid', done => { - makeWorkflow(workflowUid) - .enable() - .then(response => { - expect(response.notice).to.be.equal('Workflow enabled successfully.') - done() - }) - .catch(done) - }) - - it('Disable Workflow from uid', done => { - makeWorkflow(workflowUid) - .disable() - .then(response => { - expect(response.notice).to.be.equal('Workflow disabled successfully.') - done() - }) - .catch(done) - }) - - it('Create Publish rules', done => { - const publishingRule = cloneDeep(firstPublishRules) - publishingRule.environment = environment[0].uid - publishingRule.approvers = { - users: [user.uid], - roles: [roles[0].uid] - } - makeWorkflow() - .publishRule() - .create({ publishing_rule: publishingRule }) - .then(publishRule => { - publishRuleUid = publishRule.uid - expect(publishRule.actions.length).to.be.equal(publishingRule.actions.length) - expect(publishRule.environment).to.be.equal(publishingRule.environment) - expect(publishRule.content_types.length).to.be.equal(publishingRule.content_types.length) - expect(publishRule.content_types[0]).to.be.equal(publishingRule.content_types[0]) - expect(publishRule.approvers.users[0]).to.be.equal(user.uid) - done() - }) - .catch(done) - }) - - it('Create second Publish rules', done => { - const publishingRule = cloneDeep(secondPublishRules) - publishingRule.environment = environment[1].uid - publishingRule.approvers = { - users: [user.uid], - roles: [roles[1].uid] - } - makeWorkflow() - .publishRule() - .create({ publishing_rule: publishingRule }) - .then(publishRule => { - // publishRequestUid = publishRule.uid - expect(publishRule.actions.length).to.be.equal(publishingRule.actions.length) - expect(publishRule.environment).to.be.equal(publishingRule.environment) - expect(publishRule.content_types.length).to.be.equal(publishingRule.content_types.length) - expect(publishRule.content_types[0]).to.be.equal(publishingRule.content_types[0]) - expect(publishRule.approvers.users[0]).to.be.equal(user.uid) - done() - }) - .catch(done) - }) - - it('Create Single page Publish rules', done => { - const publishingRule = cloneDeep(secondPublishRules) - publishingRule.content_types = ['single_page'] - publishingRule.environment = environment[1].uid - publishingRule.approvers = { - users: [user.uid], - roles: [roles[1].uid] - } - makeWorkflow() - .publishRule() - .create({ publishing_rule: publishingRule }) - .then(publishRule => { - expect(publishRule.actions.length).to.be.equal(publishingRule.actions.length) - expect(publishRule.environment).to.be.equal(publishingRule.environment) - expect(publishRule.content_types.length).to.be.equal(publishingRule.content_types.length) - expect(publishRule.content_types[0]).to.be.equal(publishingRule.content_types[0]) - expect(publishRule.approvers.users[0]).to.be.equal(user.uid) - done() - }) - .catch(done) - }) - - it('Create second Publish rules should fail', done => { - const publishingRule = cloneDeep(secondPublishRules) - publishingRule.environment = environment[1].uid - publishingRule.approvers = { - users: [user.uid], - roles: [roles[1].uid] - } - makeWorkflow() - .publishRule() - .create({ publishing_rule: publishingRule }) - .then(publishRule => { - expect(publishRule).to.be.equal(undefined) - done() - }) - .catch(error => { - const jsonMessage = JSON.parse(error.message) - expect(jsonMessage.status).to.be.equal(422) - expect(jsonMessage.statusText).to.be.equal('Unprocessable Entity') - expect(jsonMessage.errorMessage).to.be.equal('Publish rule could not be created. Please try again.') - expect(jsonMessage.statusText).to.be.equal('Unprocessable Entity') - expect(jsonMessage.errors.publishing_rule[0]).to.be.equal('publishing rule is already set for multi_page and en-at for publish action(s).') - done() - }) - .catch(done) - }) - - it('Fetch Publish rules', done => { - makeWorkflow() - .publishRule(publishRuleUid) - .fetch() - .then(publishRule => { - expect(publishRule.actions.length).to.be.equal(firstPublishRules.actions.length) - expect(publishRule.environment).to.be.equal(environment[0].uid) - expect(publishRule.content_types.length).to.be.equal(firstPublishRules.content_types.length) - expect(publishRule.content_types[0]).to.be.equal(firstPublishRules.content_types[0]) - expect(publishRule.approvers.users[0]).to.be.equal(user.uid) - done() - }) - .catch(done) - }) - - it('Update Publish rules', done => { - makeWorkflow() - .publishRule(publishRuleUid) - .fetch() - .then(publishRule => { - publishRule.approvers = { - users: [user.uid], - roles: [roles[1].uid] - } - delete publishRule.status - return publishRule.update() - }) - .then(publishRule => { - expect(publishRule.actions.length).to.be.equal(firstPublishRules.actions.length) - expect(publishRule.environment).to.be.equal(environment[0].uid) - expect(publishRule.content_types.length).to.be.equal(firstPublishRules.content_types.length) - expect(publishRule.content_types[0]).to.be.equal(firstPublishRules.content_types[0]) - expect(publishRule.approvers.users[0]).to.be.equal(user.uid) - expect(publishRule.approvers.roles[0]).to.be.equal(roles[1].uid) - done() - }) - .catch(done) - }) - - it('Fetch All the PublishRules', done => { - makeWorkflow() - .publishRule() - .fetchAll() - .then(response => { - expect(response.items.length).to.be.equal(3) - done() - }) - .catch(done) - }) - - it('Fetch All the PublishRules include count', done => { - makeWorkflow() - .publishRule() - .fetchAll({ include_count: true }) - .then(response => { - expect(response.count).to.be.equal(3) - done() - }) - .catch(done) - }) - - it('Fetch All the PublishRules skip', done => { - makeWorkflow() - .publishRule() - .fetchAll({ skip: 1 }) - .then(response => { - expect(response.items.length).to.be.equal(2) - done() - }) - .catch(done) - }) - - it('Fetch All the PublishRules limit', done => { - makeWorkflow() - .publishRule() - .fetchAll({ limit: 1 }) - .then(response => { - expect(response.items.length).to.be.equal(1) - done() - }) - .catch(done) - }) - - it('Fetch All the PublishRules Content type', done => { - const contentTypes = 'multi_page_from_json,multi_page' - makeWorkflow() - .publishRule() - .fetchAll({ content_types: contentTypes }) - .then(response => { - expect(response.items.length).to.be.equal(2) - expect(contentTypes).to.contain(response.items[0].content_types[0]) - expect(contentTypes).to.contain(response.items[1].content_types[0]) - done() - }) - .catch(done) - }) - - it('Get Publish rules by content type', done => { - makeWorkflow() - .contentType('multi_page') - .getPublishRules({ action: 'publish' }) - .then(response => { - expect(response.items.length).to.be.equal(1) - const publishRule = response.items[0] - expect(publishRule.action).to.be.equal('publish') - expect(publishRule.environment).to.be.equal(environment[1].uid) - expect(publishRule.approvers[0]).to.be.equal(user.uid) - done() - }) - .catch(done) - }) - - it('Get unpublish rules by content type', done => { - makeWorkflow() - .contentType('multi_page') - .getPublishRules({ action: 'unpublish' }) - .then(response => { - expect(response.items.length).to.be.equal(0) - done() - }) - .catch(done) - }) - - it('Get publish rules by content type specific locale not present', done => { - makeWorkflow() - .contentType('multi_page') - .getPublishRules({ action: 'publish', locale: 'en-us' }) - .then(response => { - expect(response.items.length).to.be.equal(0) - done() - }) - .catch(done) - }) - - it('Get publish rules by content type specific locale', done => { - makeWorkflow() - .contentType('multi_page') - .getPublishRules({ action: 'publish', locale: 'en-at' }) - .then(response => { - expect(response.items.length).to.be.equal(1) - const publishRule = response.items[0] - expect(publishRule.action).to.be.equal('publish') - expect(publishRule.environment).to.be.equal(environment[1].uid) - expect(publishRule.approvers[0]).to.be.equal(user.uid) - done() - }) - .catch(done) - }) - - it('Get publish rules by content type specific environment not present', done => { - makeWorkflow() - .contentType('multi_page') - .getPublishRules({ action: 'publish', environment: environment[0].uid }) - .then(response => { - expect(response.items.length).to.be.equal(0) - done() - }) - .catch(done) - }) - - it('Get publish rules by content type specific environment', done => { - makeWorkflow() - .contentType('multi_page') - .getPublishRules({ action: 'publish', environment: environment[1].uid }) - .then(response => { - expect(response.items.length).to.be.equal(1) - const publishRule = response.items[0] - expect(publishRule.action).to.be.equal('publish') - expect(publishRule.environment).to.be.equal(environment[1].uid) - expect(publishRule.approvers[0]).to.be.equal(user.uid) - done() - }) - .catch(done) - }) - - // it('Request Publish entry', done => { - // const publishing_rule = { - // uid: publishRequestUid, - // action: 'publish', - // status: 0, - // notify: false, - // comment: "Please review the publish" - // } - // client.stack({ api_key: stack.api_key }) - // .contentType(multiPageCT.content_type.uid) - // .entry(entries[0].uid) - // .publishRequest({publishing_rule}) - // .then(response => { - // console.log(response) - // done() - // }) - // .catch(done) - // }) - - it('Delete Publish rule from UID', done => { - makeWorkflow() - .publishRule(publishRuleUid) - .delete() - .then(response => { - expect(response.notice).to.be.equal('Publish rule deleted successfully.') - done() - }) - .catch(done) - }) - - it('Delete Workflow from UID', done => { - makeWorkflow(workflowUid) - .delete() - .then(response => { - expect(response.notice).to.be.equal('Workflow deleted successfully.') - done() - }) - .catch(done) - }) -}) - -function makeWorkflow (uid = null) { - return client.stack({ api_key: stack.api_key }).workflow(uid) -} diff --git a/test/test.js b/test/test.js deleted file mode 100644 index a66cd167..00000000 --- a/test/test.js +++ /dev/null @@ -1,33 +0,0 @@ -require('./api/user-test') -require('./api/organization-test') -require('./api/stack-test') -require('./api/app-test') -require('./api/hosting-test') -require('./api/app-request-test') -require('./api/authorization-test') -require('./api/app-delete-test') -require('./api/branch-test') -require('./api/branchAlias-test') -require('./api/bulkOperation-test') -require('./api/locale-test') -require('./api/environment-test') -require('./api/deliveryToken-test') -require('./api/role-test') -require('./api/stack-share') -require('./api/contentType-test') -require('./api/asset-test') -require('./api/extension-test') -require('./api/entry-test') -require('./api/webhook-test') -require('./api/workflow-test') -require('./api/globalfield-test') -require('./api/release-test') -require('./api/label-test') -require('./api/contentType-delete-test') -require('./api/delete-test') -require('./api/taxonomy-test') -require('./api/terms-test') -require('./api/team-test') -require('./api/team-users-test') -require('./api/team-stack-role-mapping-test') -require('./api/managementToken-test') diff --git a/test/utility/ContentstackClient.js b/test/utility/ContentstackClient.js deleted file mode 100644 index b9340524..00000000 --- a/test/utility/ContentstackClient.js +++ /dev/null @@ -1,12 +0,0 @@ -import * as contentstack from '../../lib/contentstack.js' -import dotenv from 'dotenv' -dotenv.config() -function contentstackClient (authtoken = null) { - var params = { host: process.env.HOST, defaultHostName: process.env.DEFAULTHOST } - if (authtoken) { - params.authtoken = authtoken - } - return contentstack.client(params) -} - -export { contentstackClient } diff --git a/test/utility/fileOperations/readwrite.js b/test/utility/fileOperations/readwrite.js deleted file mode 100644 index c06fe895..00000000 --- a/test/utility/fileOperations/readwrite.js +++ /dev/null @@ -1,35 +0,0 @@ -import fs from 'fs' -import path from 'path' -const dataFiles = './test/utility/dataFiles/' -export function jsonReader (fileName) { - if (!fs.existsSync(`${dataFiles}${fileName}`)) { - return - } - const fileContents = fs.readFileSync(`${dataFiles}${fileName}`, 'utf8') - try { - const object = JSON.parse(fileContents) - return object - } catch (err) { - return err - } -} - -export function jsonWrite (json, fileName) { - const jsonString = JSON.stringify(json) - ensureDirectoryExistence(`${dataFiles}${fileName}`) - fs.writeFileSync(`${dataFiles}${fileName}`, jsonString) -} - -function ensureDirectoryExistence (filePath) { - var dirname = path.dirname(filePath) - if (!fs.existsSync(dirname)) { - ensureDirectoryExistence(dirname) - fs.mkdirSync(dirname) - } -} - -export function writeDownloadedFile (response, fileName) { - const filePath = path.resolve(dataFiles, fileName) - ensureDirectoryExistence(`${dataFiles}${fileName}`) - response.data.pipe(fs.createWriteStream(filePath)) -} From 25dfbbc467a9b921265d44bb88086bbfa437c78f Mon Sep 17 00:00:00 2001 From: "harshitha.d" Date: Mon, 7 Apr 2025 13:09:42 +0530 Subject: [PATCH 03/10] refactor: Remove 'test:api' script from package.json --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 0e5498ff..8edaa173 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,6 @@ "test:sanity-test": "BABEL_ENV=test nyc --reporter=html mocha --require @babel/register ./test/sanity-check/sanity.js -t 30000 --reporter mochawesome --require babel-polyfill --reporter-options reportDir=mochawesome-report,reportFilename=mochawesome.json", "test:sanity": "npm run test:sanity-test || true", "test:sanity-report": "marge mochawesome-report/mochawesome.json -f sanity-report.html --inline && node sanity-report.mjs", - "test:api": "BABEL_ENV=test nyc --reporter=html --reporter=text mocha --require @babel/register ./test/test.js -t 30000 --reporter mochawesome --require babel-polyfill", "test:unit": "BABEL_ENV=test nyc --reporter=html --reporter=text mocha --require @babel/register ./test/unit/index.js -t 30000 --reporter mochawesome --require babel-polyfill", "test:unit:report:json": "BABEL_ENV=test nyc --reporter=clover --reporter=text mocha --require @babel/register ./test/unit/index.js -t 30000 --reporter json --reporter-options output=report.json --require babel-polyfill", "test:typescript": "jest --testPathPattern=test/typescript --config ./jest.config.js --coverage", From a4a9c38d63b610c97f7a2807195c8fcf982e944a Mon Sep 17 00:00:00 2001 From: "harshitha.d" Date: Tue, 8 Apr 2025 13:21:30 +0530 Subject: [PATCH 04/10] chore: Update branch restrictions in workflows to include 'staging' and 'development' --- .github/workflows/check-branch.yml | 4 ++-- .github/workflows/unit-test.yml | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/check-branch.yml b/.github/workflows/check-branch.yml index 1e2d24a5..e79864e0 100644 --- a/.github/workflows/check-branch.yml +++ b/.github/workflows/check-branch.yml @@ -8,13 +8,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Comment PR - if: github.base_ref == 'master' && github.head_ref != 'next' + if: github.base_ref == 'master' && github.head_ref != 'staging' uses: thollander/actions-comment-pull-request@v2 with: message: | We regret to inform you that you are currently not able to merge your changes into the master branch due to restrictions applied by our SRE team. To proceed with merging your changes, we kindly request that you create a pull request from the next branch. Our team will then review the changes and work with you to ensure a successful merge into the master branch. - name: Check branch - if: github.base_ref == 'master' && github.head_ref != 'next' + if: github.base_ref == 'master' && github.head_ref != 'staging' run: | echo "ERROR: We regret to inform you that you are currently not able to merge your changes into the master branch due to restrictions applied by our SRE team. To proceed with merging your changes, we kindly request that you create a pull request from the next branch. Our team will then review the changes and work with you to ensure a successful merge into the master branch." exit 1 \ No newline at end of file diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 27062c53..5cb5242a 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -4,7 +4,8 @@ on: branches: - master - main - - next + - staging + - development jobs: build-test: name: Build & Test From 66b9b6da9a5b76f9adba392a1bf9ce30f0a9f90f Mon Sep 17 00:00:00 2001 From: "harshitha.d" Date: Tue, 8 Apr 2025 13:28:00 +0530 Subject: [PATCH 05/10] chore: Bump version to 1.20.2 and update changelog for recent fixes --- CHANGELOG.md | 4 ++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 51ee6dd7..ba1b5548 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,8 @@ # Changelog + +## [v1.20.2](https://github.com/contentstack/contentstack-management-javascript/tree/v1.20.2) (2025-04-14) + - Fix + - Handle the sanity tests when ENVs are not provided ## [v1.20.1](https://github.com/contentstack/contentstack-management-javascript/tree/v1.20.1) (2025-04-07) - Fix - Ensure 'api' is replaced with 'app' in uiHostName regardless of position diff --git a/package-lock.json b/package-lock.json index 0b55535d..91deb3ac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@contentstack/management", - "version": "1.20.1", + "version": "1.20.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@contentstack/management", - "version": "1.20.1", + "version": "1.20.2", "license": "MIT", "dependencies": { "assert": "^2.1.0", diff --git a/package.json b/package.json index 8edaa173..ca6cf2a1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@contentstack/management", - "version": "1.20.1", + "version": "1.20.2", "description": "The Content Management API is used to manage the content of your Contentstack account", "main": "./dist/node/contentstack-management.js", "browser": "./dist/web/contentstack-management.js", From e8a3c6254ba1582ad4719f7228fb3059ac46a24e Mon Sep 17 00:00:00 2001 From: "harshitha.d" Date: Tue, 8 Apr 2025 13:34:23 +0530 Subject: [PATCH 06/10] refactor: Update mock paths to use 'sanity-check' directory instead of 'api' --- test/typescript/asset.ts | 6 +++--- test/typescript/contentType.ts | 2 +- test/typescript/entry.ts | 2 +- test/typescript/extension.ts | 2 +- test/typescript/globalField.ts | 2 +- test/unit/asset-test.js | 10 +++++----- test/unit/concurrency-Queue-test.js | 2 +- test/unit/contentType-test.js | 4 ++-- test/unit/entry-test.js | 6 +++--- test/unit/extension-test.js | 6 +++--- test/unit/globalField-test.js | 8 ++++---- test/unit/mock/objects.js | 2 +- test/unit/taxonomy-test.js | 2 +- test/unit/webhook-test.js | 2 +- 14 files changed, 28 insertions(+), 28 deletions(-) diff --git a/test/typescript/asset.ts b/test/typescript/asset.ts index 0c15de5e..0dbefb46 100644 --- a/test/typescript/asset.ts +++ b/test/typescript/asset.ts @@ -9,7 +9,7 @@ export function createAsset(stack: Stack) { describe('Asset create', () => { test('Asset Upload', done => { const asset = { - upload: path.join(__dirname, '../api/mock/customUpload.html'), + upload: path.join(__dirname, '../sanity-check/mock/customUpload.html'), title: 'customasset', description: 'Custom Asset Desc', tags: ['custom'] @@ -45,7 +45,7 @@ export function createAsset(stack: Stack) { test('Upload asset in folder', done => { const asset = { - upload: path.join(__dirname, '../api/mock/customUpload.html'), + upload: path.join(__dirname, '../sanity-check/mock/customUpload.html'), title: 'customasset in Folder', description: 'Custom Asset Desc in Folder', parent_uid: folderUID, @@ -93,7 +93,7 @@ export function replaceAsset(stack: Stack) { describe('Asset replace', () => { test('Replace Asset', done => { const asset = { - upload: path.join(__dirname, '../api/mock/upload.html') + upload: path.join(__dirname, '../sanity-check/mock/upload.html') } stack.asset(assetUID) diff --git a/test/typescript/contentType.ts b/test/typescript/contentType.ts index c0af4225..3f851375 100644 --- a/test/typescript/contentType.ts +++ b/test/typescript/contentType.ts @@ -29,7 +29,7 @@ export function createContentType(contentType: ContentTypes) { test('Import Content type', done => { contentType.import({ - content_type: path.join(__dirname, '../api/mock/contentType.json') + content_type: path.join(__dirname, '../sanity-check/mock/contentType.json') }) .then((response) => { expect(response.uid).to.be.not.equal(null) diff --git a/test/typescript/entry.ts b/test/typescript/entry.ts index 57b576b2..070eff77 100644 --- a/test/typescript/entry.ts +++ b/test/typescript/entry.ts @@ -197,7 +197,7 @@ export function importEntry(stack: Stack){ describe('Import Entry', () => { test('Entry import from path', done => { stack.contentType(multiPageCT.content_type.uid).entry() - .import({ entry: path.join(__dirname, '../api/mock/entry.json')}) + .import({ entry: path.join(__dirname, '../sanity-check/mock/entry.json')}) .then((response) => { expect(response.uid).to.be.not.equal(null) done() diff --git a/test/typescript/extension.ts b/test/typescript/extension.ts index 50bd9b2d..f00c2904 100644 --- a/test/typescript/extension.ts +++ b/test/typescript/extension.ts @@ -1,6 +1,6 @@ import { expect } from "chai" import { Extensions } from "../../types/stack/extension"; -import { customFieldURL, customFieldSRC, customWidgetURL, customWidgetSRC, customDashboardURL, customDashboardSRC } from "../api/mock/extension"; +import { customFieldURL, customFieldSRC, customWidgetURL, customWidgetSRC, customDashboardURL, customDashboardSRC } from "../sanity-check/mock/extension"; var customFieldUID = '' var customWidgetUID = '' diff --git a/test/typescript/globalField.ts b/test/typescript/globalField.ts index 85fd8d3d..6e44e634 100644 --- a/test/typescript/globalField.ts +++ b/test/typescript/globalField.ts @@ -23,7 +23,7 @@ export function createGlobalField(globalField: GlobalFields) { test('Import global field', done => { globalField.import({ - global_field: path.join(__dirname, '../api/mock/globalfield.json') + global_field: path.join(__dirname, '../sanity-check/mock/globalfield.json') }) .then((response) => { expect(response.uid).to.be.not.equal(null) diff --git a/test/unit/asset-test.js b/test/unit/asset-test.js index bf4cb3b3..e8a4f22b 100644 --- a/test/unit/asset-test.js +++ b/test/unit/asset-test.js @@ -113,7 +113,7 @@ describe('Contentstack Asset test', () => { } }) makeAsset() - .create({ upload: path.join(__dirname, '../api/mock/customUpload.html') }) + .create({ upload: path.join(__dirname, '../sanity-check/mock/customUpload.html') }) .then((asset) => { checkAsset(asset) done() @@ -128,7 +128,7 @@ describe('Contentstack Asset test', () => { ...assetMock } }) - const assetUpload = { upload: path.join(__dirname, '../api/mock/customUpload.html'), tags: 'tags' } + const assetUpload = { upload: path.join(__dirname, '../sanity-check/mock/customUpload.html'), tags: 'tags' } const form = createFormData(assetUpload)() var boundary = form.getBoundary() @@ -151,7 +151,7 @@ describe('Contentstack Asset test', () => { } }) const assetUpload = { - upload: path.join(__dirname, '../api/mock/customUpload.html'), + upload: path.join(__dirname, '../sanity-check/mock/customUpload.html'), title: 'customasset', description: 'Custom Asset Desc', tags: ['Custom'], @@ -186,7 +186,7 @@ describe('Contentstack Asset test', () => { parent_uid: 'UID' } }) - const filePath = path.join(__dirname, '../api/mock/customUpload.html') + const filePath = path.join(__dirname, '../sanity-check/mock/customUpload.html') const fileBuffer = fs.readFileSync(filePath) const assetUpload = { upload: fileBuffer, // Buffer upload @@ -223,7 +223,7 @@ describe('Contentstack Asset test', () => { } }) const assetUpload = { - upload: path.join(__dirname, '../api/mock/customUpload.html'), + upload: path.join(__dirname, '../sanity-check/mock/customUpload.html'), title: 'customasset', description: 'Custom Asset Desc', tags: ['Custom'], diff --git a/test/unit/concurrency-Queue-test.js b/test/unit/concurrency-Queue-test.js index 981ec556..de3e2197 100644 --- a/test/unit/concurrency-Queue-test.js +++ b/test/unit/concurrency-Queue-test.js @@ -377,7 +377,7 @@ describe('Concurrency queue test', () => { const fuc = (pathcontent) => { return () => { const formData = new FormData() - const uploadStream = createReadStream(path.join(__dirname, '../api/mock/upload.html')) + const uploadStream = createReadStream(path.join(__dirname, '../sanity-check/mock/upload.html')) formData.append('asset[upload]', uploadStream) return formData } diff --git a/test/unit/contentType-test.js b/test/unit/contentType-test.js index 4ce44dd2..a1be2162 100644 --- a/test/unit/contentType-test.js +++ b/test/unit/contentType-test.js @@ -241,7 +241,7 @@ describe('Contentstack ContentType test', () => { ...contentTypeMock } }) - const contentTypeUpload = { content_type: path.join(__dirname, '../api/mock/contentType.json') } + const contentTypeUpload = { content_type: path.join(__dirname, '../sanity-check/mock/contentType.json') } const form = createFormData(contentTypeUpload)() var boundary = form.getBoundary() @@ -263,7 +263,7 @@ describe('Contentstack ContentType test', () => { ...contentTypeMock } }) - const contentTypeUpload = { content_type: path.join(__dirname, '../api/mock/contentType.json') } + const contentTypeUpload = { content_type: path.join(__dirname, '../sanity-check/mock/contentType.json') } const form = createFormData(contentTypeUpload)() var boundary = form.getBoundary() diff --git a/test/unit/entry-test.js b/test/unit/entry-test.js index 0df9c293..afcebe21 100644 --- a/test/unit/entry-test.js +++ b/test/unit/entry-test.js @@ -222,7 +222,7 @@ describe('Contentstack Entry test', () => { ...entryMock } }) - const entryUpload = { entry: path.join(__dirname, '../api/mock/entry.json') } + const entryUpload = { entry: path.join(__dirname, '../sanity-check/mock/entry.json') } const form = createFormData(entryUpload.entry)() var boundary = form.getBoundary() @@ -245,7 +245,7 @@ describe('Contentstack Entry test', () => { } }) makeEntry() - .import({ entry: path.join(__dirname, '../api/mock/entry.json'), overwrite: true }) + .import({ entry: path.join(__dirname, '../sanity-check/mock/entry.json'), overwrite: true }) .then((entry) => { checkEntry(entry) done() @@ -261,7 +261,7 @@ describe('Contentstack Entry test', () => { } }) makeEntry() - .import({ entry: path.join(__dirname, '../api/mock/entry.json'), locale: 'en-us' }) + .import({ entry: path.join(__dirname, '../sanity-check/mock/entry.json'), locale: 'en-us' }) .then((entry) => { checkEntry(entry) done() diff --git a/test/unit/extension-test.js b/test/unit/extension-test.js index 4a133747..14e4e66c 100644 --- a/test/unit/extension-test.js +++ b/test/unit/extension-test.js @@ -170,7 +170,7 @@ describe('Contentstack Extension test', () => { } }) - const extensionUpload = { upload: path.join(__dirname, '../api/mock/customUpload.html') } + const extensionUpload = { upload: path.join(__dirname, '../sanity-check/mock/customUpload.html') } const form = createExtensionFormData(extensionUpload)() var boundary = form.getBoundary() @@ -195,7 +195,7 @@ describe('Contentstack Extension test', () => { } }) - const extensionUpload = { upload: path.join(__dirname, '../api/mock/customUpload.html'), tags: 'tag1, tag2' } + const extensionUpload = { upload: path.join(__dirname, '../sanity-check/mock/customUpload.html'), tags: 'tag1, tag2' } const form = createExtensionFormData(extensionUpload)() var boundary = form.getBoundary() @@ -225,7 +225,7 @@ describe('Contentstack Extension test', () => { tags: extensionMock.tags, enable: true, default_width: extensionMock.default_width, - upload: path.join(__dirname, '../api/mock/customUpload.html'), + upload: path.join(__dirname, '../sanity-check/mock/customUpload.html'), scope: {}, multiple: true } diff --git a/test/unit/globalField-test.js b/test/unit/globalField-test.js index f9c2f912..361fbb60 100644 --- a/test/unit/globalField-test.js +++ b/test/unit/globalField-test.js @@ -174,7 +174,7 @@ describe('Contentstack GlobalField test', () => { } }) const gfUpload = { - global_field: path.join(__dirname, '../api/mock/globalfield.json') + global_field: path.join(__dirname, '../sanity-check/mock/globalfield.json') } const form = createFormData(gfUpload)() var boundary = form.getBoundary() @@ -198,7 +198,7 @@ describe('Contentstack GlobalField test', () => { } }) const gfUpload = { - global_field: path.join(__dirname, '../api/mock/globalfield.json') + global_field: path.join(__dirname, '../sanity-check/mock/globalfield.json') } const form = createFormData(gfUpload)() var boundary = form.getBoundary() @@ -395,7 +395,7 @@ describe('Contentstack GlobalField test (API Version 3.2)', () => { } }) const gfUpload = { - global_field: path.join(__dirname, '../api/mock/globalfield.json') + global_field: path.join(__dirname, '../sanity-check/mock/globalfield.json') } const form = createFormData(gfUpload)() var boundary = form.getBoundary() @@ -421,7 +421,7 @@ describe('Contentstack GlobalField test (API Version 3.2)', () => { } }) const gfUpload = { - global_field: path.join(__dirname, '../api/mock/globalfield.json') + global_field: path.join(__dirname, '../sanity-check/mock/globalfield.json') } const form = createFormData(gfUpload)() var boundary = form.getBoundary() diff --git a/test/unit/mock/objects.js b/test/unit/mock/objects.js index 5aea75b5..7376088c 100644 --- a/test/unit/mock/objects.js +++ b/test/unit/mock/objects.js @@ -1,5 +1,5 @@ import cloneDeep from 'lodash/cloneDeep' -import { singlepageCT } from '../../api/mock/content-type' +import { singlepageCT } from '../../sanity-check/mock/content-type' import { expect } from 'chai' const errorMock = { diff --git a/test/unit/taxonomy-test.js b/test/unit/taxonomy-test.js index 879b56cf..67a59090 100644 --- a/test/unit/taxonomy-test.js +++ b/test/unit/taxonomy-test.js @@ -152,7 +152,7 @@ describe('Contentstack Taxonomy test', () => { ...taxonomyMock } }) - const taxonomyUpload = { taxonomy: path.join(__dirname, '../api/mock/taxonomy.json') } + const taxonomyUpload = { taxonomy: path.join(__dirname, '../sanity-check/mock/taxonomy.json') } const form = createFormData(taxonomyUpload)() var boundary = form.getBoundary() diff --git a/test/unit/webhook-test.js b/test/unit/webhook-test.js index 6b2bff63..b328f225 100644 --- a/test/unit/webhook-test.js +++ b/test/unit/webhook-test.js @@ -303,7 +303,7 @@ describe('Contentstack Webhook test', () => { ...webhookMock } }) - const webhookUpload = { webhook: path.join(__dirname, '../api/mock/customUpload.html') } + const webhookUpload = { webhook: path.join(__dirname, '../sanity-check/mock/customUpload.html') } const form = createFormData(webhookUpload)() var boundary = form.getBoundary() From bd1774637fc9d8ecd2340ed822be0e43d0acbdb5 Mon Sep 17 00:00:00 2001 From: "harshitha.d" Date: Tue, 8 Apr 2025 13:36:43 +0530 Subject: [PATCH 07/10] chore: Update changelog date for version 1.20.2 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba1b5548..b65b5e61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## [v1.20.2](https://github.com/contentstack/contentstack-management-javascript/tree/v1.20.2) (2025-04-14) +## [v1.20.2](https://github.com/contentstack/contentstack-management-javascript/tree/v1.20.2) (2025-04-21) - Fix - Handle the sanity tests when ENVs are not provided ## [v1.20.1](https://github.com/contentstack/contentstack-management-javascript/tree/v1.20.1) (2025-04-07) From edee59b65b667f6f9d97cbe32953742bad6e1c2f Mon Sep 17 00:00:00 2001 From: "harshitha.d" Date: Wed, 16 Apr 2025 11:56:34 +0530 Subject: [PATCH 08/10] chore: update version to 1.20.3 and add changelog entry for sanity test handling --- CHANGELOG.md | 3 +++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d66e9af..983931b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +## [v1.20.3](https://github.com/contentstack/contentstack-management-javascript/tree/v1.20.3) (2025-04-28) + - Fix + - Handle the sanity tests when ENVs are not provided ## [v1.20.2](https://github.com/contentstack/contentstack-management-javascript/tree/v1.20.2) (2025-04-21) - Fix diff --git a/package-lock.json b/package-lock.json index 91deb3ac..5b5b6f65 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@contentstack/management", - "version": "1.20.2", + "version": "1.20.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@contentstack/management", - "version": "1.20.2", + "version": "1.20.3", "license": "MIT", "dependencies": { "assert": "^2.1.0", diff --git a/package.json b/package.json index ca6cf2a1..8134643c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@contentstack/management", - "version": "1.20.2", + "version": "1.20.3", "description": "The Content Management API is used to manage the content of your Contentstack account", "main": "./dist/node/contentstack-management.js", "browser": "./dist/web/contentstack-management.js", From 936d0284d158e00382880cec3a5291a8a833b631 Mon Sep 17 00:00:00 2001 From: "harshitha.d" Date: Wed, 16 Apr 2025 12:00:28 +0530 Subject: [PATCH 09/10] test: update access token in refreshAccessToken test case to use placeholder --- test/unit/oauthHandler-test.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/unit/oauthHandler-test.js b/test/unit/oauthHandler-test.js index f1e1e15b..5088a303 100644 --- a/test/unit/oauthHandler-test.js +++ b/test/unit/oauthHandler-test.js @@ -62,7 +62,8 @@ describe('OAuthHandler', () => { }) it('should refresh access token', async () => { - const tokenData = { access_token: 'newAccessToken', refresh_token: 'newRefreshToken', expires_in: 3600 } + // NAT = 'newAccessToken' + const tokenData = { access_token: 'NAT', refresh_token: 'newRefreshToken', expires_in: 3600 } sandbox.stub(axiosInstance, 'post').resolves({ data: tokenData }) const result = await oauthHandler.refreshAccessToken('refreshToken') From 2629d215dfec1f52ef2eda644758c25d2029c454 Mon Sep 17 00:00:00 2001 From: "harshitha.d" Date: Wed, 16 Apr 2025 12:03:21 +0530 Subject: [PATCH 10/10] chore: update changelog dates for v1.20.3 and v1.20.2 --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 983931b0..cc607393 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,10 @@ # Changelog -## [v1.20.3](https://github.com/contentstack/contentstack-management-javascript/tree/v1.20.3) (2025-04-28) +## [v1.20.3](https://github.com/contentstack/contentstack-management-javascript/tree/v1.20.3) (2025-04-21) - Fix - Handle the sanity tests when ENVs are not provided -## [v1.20.2](https://github.com/contentstack/contentstack-management-javascript/tree/v1.20.2) (2025-04-21) +## [v1.20.2](https://github.com/contentstack/contentstack-management-javascript/tree/v1.20.2) (2025-04-14) - Fix - Handle api_version chaining and ensure backward compatibility