diff --git a/README.md b/README.md index 432838fb..9ae2fe35 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +# contentstack-management-javascript-variants [![Contentstack](https://www.contentstack.com/docs/static/images/contentstack.png)](https://www.contentstack.com/) ## Contentstack Management JavaScript SDK diff --git a/lib/entity.js b/lib/entity.js index 768d3fc4..d56d4d39 100644 --- a/lib/entity.js +++ b/lib/entity.js @@ -205,7 +205,6 @@ export const fetch = (http, type, params = {}) => { if (this.organization_uid) { headers.headers.organization_uid = this.organization_uid } - const response = await http.get(this.urlPath, headers) if (response.data) { if (type === 'entry') { diff --git a/lib/stack/contentType/entry/index.js b/lib/stack/contentType/entry/index.js index de34aad3..6701ed89 100644 --- a/lib/stack/contentType/entry/index.js +++ b/lib/stack/contentType/entry/index.js @@ -12,6 +12,7 @@ import { create, import FormData from 'form-data' import { createReadStream } from 'fs' import error from '../../../core/contentstackError' +import { Variants } from './variants/index' /** * An entry is the actual piece of content created using one of the defined content types. Read more about Entries. @@ -268,14 +269,69 @@ export function Entry (http, data) { } /** - * @description The get locales request allows to get the languages of an entry. + * @description The variants requestan entry call is used to fetch a specific entry with variants from a content type. * @memberof Entry - * @func locales + * @func variants * @returns {Promise} Response Object. + * @param {Object} publishing_rule Details for the publish request + * @param {String} locale Enter the code of the locale that the entry belongs to. * @example * import * as contentstack from '@contentstack/management' * const client = contentstack.client() - * + * client.stack({ api_key: 'api_key'}).contentType('content_type_uid').entry('uid').variants('uid').fetch() + * .then((response) => console.log(response.notice)); + */ + this.variants = (uid = null) => { + const data = { stackHeaders: this.stackHeaders } + data.content_type_uid = this.content_type_uid + data.entry_uid = this.uid + if (uid) { + data.variants_uid = uid + } + return new Variants(http, data) + } + + /** + * @description The includeVariants an entry call is used to fetch a specific base entry with variants from a content type. + * @memberof Variants + * @func includeVariants + * @returns {Object} Response Object. + * @example + * import * as contentstack from '@contentstack/management' + * const client = contentstack.client() + * client.stack({ api_key: 'api_key'}).contentType('content_type_uid').entry('uid').includeVariants('true','variants_uid') + * .then((response) => console.log(response)) + */ + + this.includeVariants = async (include_variant, variants_uid) => { + try { + const headers = { + ...cloneDeep(this.stackHeaders) // Clone existing headers + }; + + // Add custom header + headers['x-cs-variant-uid'] = variants_uid; // add variant UID + let params = {}; + if (include_variant) { + params.include_variant = include_variant; // if include_variant present + } + const response = await http.get(this.urlPath, { headers, params }); + if (response.data) { + return response.data; + } else { + throw error(response); + } + } catch (err) { + error(err); + } + }; + + + /** + * @description The get locales request allows to get the languages of an entry. + * @memberof Entry + * @func locales + * @returns {Promise} Response Object. * client.stack({ api_key: 'api_key'}).contentType('content_type_uid').entry('uid').locales() * .then((response) => console.log(response)); */ @@ -295,6 +351,7 @@ export function Entry (http, data) { throw error(err) } } + } else { /** * @description The Create an entry call creates a new entry for the selected content type. diff --git a/lib/stack/contentType/entry/variants/index.js b/lib/stack/contentType/entry/variants/index.js new file mode 100644 index 00000000..daff560d --- /dev/null +++ b/lib/stack/contentType/entry/variants/index.js @@ -0,0 +1,166 @@ +import cloneDeep from 'lodash/cloneDeep' +import { + update, + deleteEntity, + fetch, + upload, + query, + parseData +} +from '../../../../entity' +import FormData from 'form-data' +import { + createReadStream +} from 'fs' +import error from '../../../../core/contentstackError' +/** + * An variants is the actual piece of content created using one of the defined content types. Read more about Entries. + * @namespace Variants + */ +export function Variants(http, data) { + Object.assign(this, cloneDeep(data)) + this.urlPath = `/content_types/${this.content_type_uid}/entries/${this.entry_uid}/variants` + if (data && data.variants_uid) { + this.urlPath += `/${this.variants_uid}` + /** + * @description The Create an variants call creates a new variants for the selected content type. + * @memberof Variants + * @func update + * @returns {Promise} Promise for Variants instance + * @example + * import * as contentstack from '@contentstack/management' + * const client = contentstack.client() + * const data = { + * "entry": { + * "title": "example", + * "url": "/example", + * "_variant": { + * "_change_set": [ + * "title", + * "url" + * ] + * } + * } + * } + * client.stack({ api_key: 'api_key'}).contentType('content_type_uid').entry('entry_uid').variants('uid').update(data) + * .then((variants) => console.log(variants)) + */ + this.update = async (data) => { + try { + const response = await http.put(this.urlPath, + data, + { + headers: { + ...cloneDeep(this.stackHeaders) + } + }) + if (response.data) { + return response.data + } else { + return error(response) + } + } catch (err) { + return error(err) + } + } + + /** + * @description The Delete an variants call is used to delete a specific variants from a content type. + * @memberof Variants + * @func delete + * @returns {Object} Response Object. + * @example + * import * as contentstack from '@contentstack/management' + * const client = contentstack.client() + * + * client.stack({ api_key: 'api_key'}).contentType('content_type_uid').entry('entry_uid').variants('uid').delete() + * .then((response) => console.log(response.notice)) + */ + this.delete = deleteEntity(http) + + /** + * @description The fetch Variants call fetches Variants details. + * @memberof Variants + * @func fetch + * @returns {Promise} Promise for Variants instance + * @example + * import * as contentstack from '@contentstack/management' + * const client = contentstack.client() + * + * client.stack({ api_key: 'api_key'}).contentType('content_type_uid').entry('entry_uid').variants('uid').fetch() + * .then((variants) => console.log(variants)) + * + */ + this.fetch = fetch(http, 'variants') + + /** + * @description The version Variants call fetches Variants version details. + * @memberof Variants + * @func versions + * @returns {Promise} Promise for Variants instance + * @example + * import * as contentstack from '@contentstack/management' + * const client = contentstack.client() + * + * client.stack({ api_key: 'api_key'}).contentType('content_type_uid').entry('entry_uid').variants('uid').versions() + * .then((variants) => console.log(variants)) + * + */ + this.versions = async () => { + try { + const response = await http.get(`${this.urlPath}/versions`, { + headers: { + ...cloneDeep(this.stackHeaders) + } + }) + if (response.data) { + return response.data + } else { + return error(response) + } + } catch (err) { + return error(err) + } + } + + } else { + /** + * @description The Query on Variants will allow to fetch details of all or specific Variants + * @memberof Variants + * @func query + * @param {Int} locale Enter the code of the language of which the entries need to be included. Only the entries published in this locale will be displayed. + * @param {Object} query Queries that you can use to fetch filtered results. + * @returns {Array} Array of Variants. + * + * @example + * import * as contentstack from '@contentstack/management' + * const client = contentstack.client() + * + * client.stack().contentType('content_type_uid').entry('entry_uid').variants().query({ query: { title: 'Variants title' } }).find() + * .then((entries) => console.log(entries)) + */ + this.query = query({ http: http, wrapperCollection: VariantsCollection }) + } +} +export function VariantsCollection(http, data) { + const obj = cloneDeep(data.entries) || [] + const variantCollection = obj.map((variant) => { + return new Variants(http, { + content_type_uid: data.content_type_uid, + entry_uid: variant.uid, + variants_uid: variant.variant_id, + stackHeaders: data.stackHeaders, + variants: variant + }) + }) + return variantCollection +} + +export function createFormData(variants) { + return () => { + const formData = new FormData() + const uploadStream = createReadStream(variants) + formData.append('variants', uploadStream) + return formData + } +} \ No newline at end of file diff --git a/lib/stack/index.js b/lib/stack/index.js index 2ef5e72e..a5c0152a 100644 --- a/lib/stack/index.js +++ b/lib/stack/index.js @@ -20,6 +20,8 @@ import { BranchAlias } from './branchAlias' import { AuditLog } from './auditlog' import { Taxonomy } from './taxonomy' import { ManagementToken } from './managementToken' +import { Variants } from './variants' +import { VariantGroup } from './variantGroup' /** * A stack is a space that stores the content of a project (a web or mobile property). Within a stack, you can create content structures, content entries, users, etc. related to the project. Read more about Stacks. @@ -368,6 +370,29 @@ export function Stack (http, data) { return new Label(http, data) } + /** + * @description For creating ungrouped variants. + * @param {String} uid The UID of the variants you want to get details. + * @returns {Variants} Instance of variants. + * @example + * import * as contentstack from '@contentstack/management' + * const client = contentstack.client() + * + * client.stack({ api_key: 'api_key'}).variants().create() + * .then((variants) => console.log(variants)) + * + * client.stack({ api_key: 'api_key'}).variants('variants_uid').fetch() + * .then((variants) => console.log(variants)) + */ + this.variants = (variantsUid = null) => { + const data = { stackHeaders: this.stackHeaders } + if (variantsUid) { + data.variants = { uid: variantsUid } + } + return new Variants(http, data) + } + + /** * @description You can pin a set of entries and assets (along with the deploy action, i.e., publish/unpublish) to a ‘release’, and then deploy this release to an environment. * @param {String} releaseUid The UID of the Releases you want to get details. @@ -676,6 +701,28 @@ export function Stack (http, data) { } } + /** + * @description Variant Group allows you to create a variant groups. + * @param {String} uid The UID of the variant group you want to get details. + * @returns {VariantGroup} Instance of VariantGroup. + * @example + * import * as contentstack from '@contentstack/management' + * const client = contentstack.client() + * + * client.stack({ api_key: 'api_key'}).variantGroup().create() + * .then((variant_group) => console.log(variant_group)) + * + * client.stack({ api_key: 'api_key'}).variantGroup('variant_group_uid').fetch() + * .then((variant_group) => console.log(variant_group)) + */ + this.variantGroup = (variantGroupUid = null) => { + const data = { stackHeaders: this.stackHeaders } + if (variantGroupUid) { + data.variant_group = { uid: variantGroupUid } + } + return new VariantGroup(http, data) + } + /** * @description A role is a collection of permissions that will be applicable to all the users who are assigned this role. * @memberof Stack diff --git a/lib/stack/variantGroup/index.js b/lib/stack/variantGroup/index.js new file mode 100644 index 00000000..b036c5bd --- /dev/null +++ b/lib/stack/variantGroup/index.js @@ -0,0 +1,145 @@ +import cloneDeep from 'lodash/cloneDeep' +import { create, update, deleteEntity, fetch, query } from '../../entity' +import { Variants } from './variants/index' + +/** + * Contentstack has a sophisticated multilingual capability. It allows you to create and publish entries in any language. This feature allows you to set up multilingual websites and cater to a wide variety of audience by serving content in their local language(s). Read more about VariantGroups. + * @namespace VariantGroup + */ + +export function VariantGroup (http, data = {}) { + this.stackHeaders = data.stackHeaders + this.urlPath = `/variant_groups` + + if (data.variant_group) { + Object.assign(this, cloneDeep(data.variant_group)) + this.urlPath += `/${this.uid}` + /** + * @description The Update VariantGroup call lets you update the name and description of an existing VariantGroup. + * @memberof VariantGroup + * @func update + * @returns {Promise} Promise for VariantGroup instance + * @example + * import * as contentstack from '@contentstack/management' + * const client = contentstack.client() + * const up_data = {name: 'update name'} + * client.stack({ api_key: 'api_key'}).VariantGroup('variant_group_uid').update(up_data) + * .then((variant_group) => console.log(variant_group)) + * + */ + this.update = async (data) => { + try { + const response = await http.put(this.urlPath, + data, + { + headers: { + ...cloneDeep(this.stackHeaders) + } + }) + if (response.data) { + return response.data + } else { + return error(response) + } + } catch (err) { + return error(err) + } + } + /** + * @description The Delete VariantGroup call is used to delete an existing VariantGroup permanently from your Stack. + * @memberof VariantGroup + * @func delete + * @returns {Object} Response Object. + * @example + * import * as contentstack from '@contentstack/management' + * const client = contentstack.client() + * + * client.stack({ api_key: 'api_key'}).VariantGroup('variant_group_uid').delete() + * .then((response) => console.log(response.notice)) + */ + this.delete = deleteEntity(http) + + /** + * @description The fetch VariantGroup call fetches VariantGroup details. + * @memberof VariantGroup + * @func fetch + * @returns {Promise} Promise for VariantGroup instance + * @param {Int} version Enter the unique ID of the content type of which you want to retrieve the details. The UID is generated based on the title of the content type. The unique ID of a content type is unique across a stack. + * @example + * import * as contentstack from '@contentstack/management' + * const client = contentstack.client() + * + * client.stack({ api_key: 'api_key'}).VariantGroup('variant_group_uid').fetch() + * .then((variant_group) => console.log(variant_group)) + * + */ + // this.fetch = fetch(http, 'variant_group') + + /** + * @description Content type defines the structure or schema of a page or a section of your web or mobile property. + * @param {String} uid The UID of the ContentType you want to get details. + * @returns {ContenType} Instace of ContentType. + * @example + * import * as contentstack from '@contentstack/management' + * const client = contentstack.client() + * + * client.stack({ api_key: 'api_key'}).VariantGroup('variant_group_uid').variants('variant_uid').fetch() + * .then((Variants) => console.log(Variants)) + */ + this.variants = (uid = null) => { + const data = { stackHeaders: this.stackHeaders } + data.variant_group_uid = this.uid + if (uid) { + data.variants = { uid: uid } + } + return new Variants(http, data) + } + + } else { + /** + * @description The Create a variant group call creates a new variant group in a particular stack of your Contentstack account. + * @memberof VariantGroup + * @func create + * @returns {Promise} Promise for VariantGroup instance + * + * @example + * import * as contentstack from '@contentstack/management' + * const client = contentstack.client() + * const variant_group = { + * "name": "Colors", + * "content_types": [ + * "iphone_product_page" + * ], + * "uid": "iphone_color_white", // optional + * } + * client.stack().VariantGroup().create({ variant_group } ) + * .then((variant_group) => console.log(variant_group)) + */ + this.create = create({ http: http }) + + /** + * @description The Query on Variant Groups will allow to fetch details of all or specific Variant Groups + * @memberof VariantGroup + * @func query + * @param {Boolean} include_count Set this to 'true' to include in response the total count of content types available in your stack. + * @returns {Array} Array of ContentTyoe. + * + * @example + * import * as contentstack from '@contentstack/management' + * const client = contentstack.client() + * + * client.stack(api_key).VariantGroup().query({ query: { code: 'variant_group-code' } }).find() + * .then((variant_groups) => console.log(variant_groups)) + */ + this.query = query({ http: http, wrapperCollection: VariantGroupCollection }) + } + return this +} + +export function VariantGroupCollection (http, data) { + const obj = cloneDeep(data.variant_groups) || [] + const variant_groupCollection = obj.map((userdata) => { + return new VariantGroup(http, { variant_group: userdata, stackHeaders: data.stackHeaders }) + }) + return variant_groupCollection +} diff --git a/lib/stack/variantGroup/variants/index.js b/lib/stack/variantGroup/variants/index.js new file mode 100644 index 00000000..53fe28c9 --- /dev/null +++ b/lib/stack/variantGroup/variants/index.js @@ -0,0 +1,114 @@ +import cloneDeep from 'lodash/cloneDeep' +import { create, update, fetch, query } from '../../../entity' + +/** + * Contentstack has a sophisticated multilingual capability. It allows you to create and publish entries in any language. This feature allows you to set up multilingual websites and cater to a wide variety of audience by serving content in their local language(s). Read more about VariantGroups. + * @namespace Variants + */ + +export function Variants (http, data = {}) { + this.stackHeaders = data.stackHeaders + this.variant_group_uid = data.variant_group_uid + this.urlPath = `/variant_groups/${this.variant_group_uid}/variants` + + if (data.variants) { + Object.assign(this, cloneDeep(data.variants)) + this.urlPath += `/${this.uid}` + /** + * @description The Update Variants call lets you update the name and description of an existing Variants. + * @memberof Variants + * @func update + * @returns {Promise} Promise for Variants instance + * @example + * import * as contentstack from '@contentstack/management' + * const client = contentstack.client() + * const data = { "name": "Update name" } + * client.stack({ api_key: 'api_key'}).VariantGroup('variant_group_uid').variants('variant_uid').update(data) + * .then((variants) => console.log(variants)) + * + */ + this.update = async (data) => { + try { + const response = await http.put(this.urlPath, + data, + { + headers: { + ...cloneDeep(this.stackHeaders) + } + }) + if (response.data) { + return response.data + } else { + return error(response) + } + } catch (err) { + return error(err) + } + } + + /** + * @description The fetch Variants call fetches Variants details. + * @memberof Variants + * @func fetch + * @returns {Promise} Promise for Variants instance + * @param {Int} version Enter the unique ID of the content type of which you want to retrieve the details. The UID is generated based on the title of the content type. The unique ID of a content type is unique across a stack. + * @example + * import * as contentstack from '@contentstack/management' + * const client = contentstack.client() + * + * client.stack({ api_key: 'api_key'}).VariantGroup('variant_group_uid').variants('variant_uid').fetch() + * .then((variants) => console.log(variants)) + * + */ + this.fetch = fetch(http, 'variants') + } else { + /** + * @description The Create a variant group call creates a new variant group in a particular stack of your Contentstack account. + * @memberof Variants + * @func create + * @returns {Promise} Promise for Variants instance + * + * @example + * import * as contentstack from '@contentstack/management' + * const client = contentstack.client() + * const data = { + * "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" + * }, + * } + * client.stack().VariantGroup('variant_group_uid').variants().create({ data } ) + * .then((variants) => console.log(variants)) + */ + this.create = create({ http: http }) + + /** + * @description The Query on Variant Groups will allow to fetch details of all or specific Variant Groups + * @memberof Variants + * @func query + * @param {Boolean} include_count Set this to 'true' to include in response the total count of content types available in your stack. + * @returns {Array} Array of ContentTyoe. + * + * @example + * import * as contentstack from '@contentstack/management' + * const client = contentstack.client() + + * client.stack(api_key).VariantGroup('variant_group_uid').variants().query({ query: { name: 'white' } }).find() + * .then((variant_groups) => console.log(variant_groups)) + */ + this.query = query({ http: http, wrapperCollection: VariantsCollection }) + } + return this +} + +export function VariantsCollection (http, data) { + const obj = cloneDeep(data.variants) || [] + const variantsCollection = obj.map((userdata) => { + return new Variants(http, { variants: userdata, variant_group_uid: data.variant_group_uid ,stackHeaders: data.stackHeaders }) + }) + return variantsCollection +} diff --git a/lib/stack/variants/index.js b/lib/stack/variants/index.js new file mode 100644 index 00000000..cb630073 --- /dev/null +++ b/lib/stack/variants/index.js @@ -0,0 +1,134 @@ +import cloneDeep from 'lodash/cloneDeep' +import { + deleteEntity, + fetch, + query, + create +} from '../../entity' +/** + * Variantss allow you to group a collection of content within a stack. Using variants you can group content types that need to work together. Read more about Variantss. + * @namespace Variants + */ +export function Variants (http, data) { + this.stackHeaders = data.stackHeaders + this.urlPath = `/variants` + + if (data.variants) { + Object.assign(this, cloneDeep(data.variants)) + this.urlPath += `/${this.uid}` + + /** + * @description The Delete variants call is used to delete a specific variants. + * @memberof Variants + * @func delete + * @returns {Object} Response Object. + * @example + * import * as contentstack from '@contentstack/management' + * const client = contentstack.client() + * + * client.stack({ api_key: 'api_key'}).variants('variants_uid').delete() + * .then((response) => console.log(response.notice)) + */ + this.delete = deleteEntity(http) + + /** + * @description The fetch Variants returns information about a particular variants of a stack. + * @memberof Variants + * @func fetch + * @returns {Promise} Promise for Variants instance + * @example + * import * as contentstack from '@contentstack/management' + * const client = contentstack.client() + * + * client.stack({ api_key: 'api_key'}).variants('variants_uid').fetch() + * .then((variants) => console.log(variants)) + * + */ + this.fetch = fetch(http, 'variants') + } else { + /** + * @description The Create an variants call creates a new variants. + * @memberof Variants + * @func create + * @returns {Promise} Promise for Variants instance + * + * @example + * import * as contentstack from '@contentstack/management' + * const client = contentstack.client() + * 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" + * }, + * } + * client.stack().variants().create({ variants }) + * .then((variants) => console.log(variants)) + */ + this.create = create({ http }) + + /** + * @description The Query on Variants will allow to fetch details of all or specific Variants. + * @memberof Variants + * @param {Object} params - URI parameters + * @prop {Object} params.query - Queries that you can use to fetch filtered results. + * @func query + * @returns {Array} Array of Variants. + * + * @example + * import * as contentstack from '@contentstack/management' + * const client = contentstack.client() + * + * client.stack().variants().query({ query: { name: 'Variants Name' } }).find() + * .then((variants) => console.log(variants)) + */ + this.query = query({ http: http, wrapperCollection: VariantsCollection }) + + /** + * @description The fetchByUIDs on Variants will allow to fetch details of specific Variants UID. + * @memberof Variants + * @param {Object} params - URI parameters + * @prop {Object} params.query - fetchByUIDs that you can use to fetch filtered results. + * @func query + * @returns {Array} Array of Variants. + * + * @example + * import * as contentstack from '@contentstack/management' + * const client = contentstack.client() + * + * client.stack().variants().fetchByUIDs(['uid1','uid2']).find() + * .then((variants) => console.log(variants)) + */ + this.fetchByUIDs = async (variantUids) => { + + try { + const response = await http.get(this.urlPath, { + params: { + uids: variantUids + }, + headers: { + ...cloneDeep(this.stackHeaders) + } + }) + if (response.data) { + return response.data + } else { + throw error(response) + } + } catch (err) { + throw error(err) + } + } + } +} + +export function VariantsCollection (http, data) { + const obj = cloneDeep(data.variants) || [] + const VariantsCollection = obj.map((userdata) => { + return new Variants(http, { variants: userdata, stackHeaders: data.stackHeaders }) + }) + return VariantsCollection +} diff --git a/package.json b/package.json index 52ee81df..b8047b75 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@contentstack/management", - "version": "1.17.2", + "version": "1.18.0", "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", @@ -106,7 +106,8 @@ "typescript": "^4.7.2", "webpack": "^5.72.1", "webpack-cli": "^4.9.2", - "webpack-merge": "4.1.0" + "webpack-merge": "4.1.0", + "@slack/bolt": "^3.17.1" }, "homepage": "https://www.contentstack.com" } diff --git a/test/api/mock/variantGroup.js b/test/api/mock/variantGroup.js new file mode 100644 index 00000000..805553be --- /dev/null +++ b/test/api/mock/variantGroup.js @@ -0,0 +1,82 @@ +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_product_description" + ], + "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 new file mode 100644 index 00000000..9e590226 --- /dev/null +++ b/test/api/mock/variants.js @@ -0,0 +1,50 @@ +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/ungroupedVariants-test.js b/test/api/ungroupedVariants-test.js new file mode 100644 index 00000000..a42ab83a --- /dev/null +++ b/test/api/ungroupedVariants-test.js @@ -0,0 +1,107 @@ +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/variantGroup-test.js b/test/api/variantGroup-test.js new file mode 100644 index 00000000..1c7fa13e --- /dev/null +++ b/test/api/variantGroup-test.js @@ -0,0 +1,136 @@ +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) +} \ No newline at end of file diff --git a/test/api/variants-test.js b/test/api/variants-test.js new file mode 100644 index 00000000..b01968de --- /dev/null +++ b/test/api/variants-test.js @@ -0,0 +1,112 @@ +import { expect } from 'chai' +import { describe, it, setup } from 'mocha' +import { jsonReader } from '../utility/fileOperations/readwrite' +import { variant, variant1, 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) +} \ No newline at end of file diff --git a/test/sanity-check/api/ungroupedVariants-test.js b/test/sanity-check/api/ungroupedVariants-test.js new file mode 100644 index 00000000..a42ab83a --- /dev/null +++ b/test/sanity-check/api/ungroupedVariants-test.js @@ -0,0 +1,107 @@ +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/sanity-check/api/variantGroup-test.js b/test/sanity-check/api/variantGroup-test.js new file mode 100644 index 00000000..e131049d --- /dev/null +++ b/test/sanity-check/api/variantGroup-test.js @@ -0,0 +1,136 @@ +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) +} \ No newline at end of file diff --git a/test/sanity-check/api/variants-test.js b/test/sanity-check/api/variants-test.js new file mode 100644 index 00000000..1390d53f --- /dev/null +++ b/test/sanity-check/api/variants-test.js @@ -0,0 +1,112 @@ +import { expect } from 'chai' +import { describe, it, setup } from 'mocha' +import { jsonReader } from '../utility/fileOperations/readwrite' +import { variant, variant1, 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) +} \ No newline at end of file diff --git a/test/sanity-check/mock/variantGroup.js b/test/sanity-check/mock/variantGroup.js new file mode 100644 index 00000000..805553be --- /dev/null +++ b/test/sanity-check/mock/variantGroup.js @@ -0,0 +1,82 @@ +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_product_description" + ], + "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/sanity-check/mock/variants.js b/test/sanity-check/mock/variants.js new file mode 100644 index 00000000..9e590226 --- /dev/null +++ b/test/sanity-check/mock/variants.js @@ -0,0 +1,50 @@ +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/sanity-check/sanity.js b/test/sanity-check/sanity.js index d2c047b0..f470aa13 100644 --- a/test/sanity-check/sanity.js +++ b/test/sanity-check/sanity.js @@ -21,6 +21,9 @@ require('./api/workflow-test') require('./api/globalfield-test') require('./api/release-test') require('./api/label-test') +require('./api/variants-test') +require('./api/variantGroup-test') +require('./api/ungroupedVariants-test') require('./api/contentType-delete-test') require('./api/delete-test') require('./api/team-test') diff --git a/test/typescript/index.test.ts b/test/typescript/index.test.ts index 0f59461e..f9c8594a 100644 --- a/test/typescript/index.test.ts +++ b/test/typescript/index.test.ts @@ -13,6 +13,8 @@ import { createLocale, deleteLocale, getLocale } from './locale'; import { createEnvironment, deleteEnvironment, getEnvironment, updateEnvironment } from './environment'; import { createDeliveryToken, deleteDeliveryToken, deliveryToken, queryDeliveryToken } from './deliveryToken'; import { createManagementToken, deleteManagementToken, managementToken, queryManagementToken } from './managementToken'; +import { createVariantGroup, deleteVariantGroup, variantGroup, queryVariantGroup } from './variantGroup'; +import { createVariant, variant, queryVariant } from './variants'; import { createRole, findAllRole, getRole, getRoleUid, queryRole } from './role'; import { createApp, deleteApp, fetchApp, installation, updateApp, updateAuth } from './app'; import { deployment, hosting } from './hosting'; @@ -23,6 +25,8 @@ import { testTerm } from './terms'; import { testTeams } from './teams'; import { testTeamUsers } from './teamUsers'; import { testTeamStackRoleMapping } from './teamsStackRoleMappings'; +import { createVariants, deleteVariants, variants, queryVariants } from './ungroupedVariants'; + dotenv.config() jest.setTimeout(10000); @@ -85,6 +89,19 @@ describe('Typescript API test', () => { managementToken(stack) deleteManagementToken(stack) + createVariants(stack) + deleteVariants(stack) + variants(stack.variant) + queryVariants(stack.variant) + createVariantGroup(stack.VariantGroup()) + queryVariantGroup(stack.VariantGroup()) + variantGroup(stack) + deleteVariantGroup(stack) + + createVariant(stack.VariantGroup().Variants()) + queryVariant(stack.VariantGroup().Variants()) + variant(stack.VariantGroup().variants()) + findAllRole(stack.role()) createRole(stack.role()) getRole(stack) diff --git a/test/typescript/mock/ungroupedvariants.ts b/test/typescript/mock/ungroupedvariants.ts new file mode 100644 index 00000000..9ada80ce --- /dev/null +++ b/test/typescript/mock/ungroupedvariants.ts @@ -0,0 +1,49 @@ +const variant = { + "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 variants1 = { + "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" + }, + } +const variants2 = { + "uid": "variant_1", + "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", + "variant_group": { + "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" + } + } +} + + + +export { variant, variants1, variants2 } \ No newline at end of file diff --git a/test/typescript/mock/variantGroup.ts b/test/typescript/mock/variantGroup.ts new file mode 100644 index 00000000..474f2027 --- /dev/null +++ b/test/typescript/mock/variantGroup.ts @@ -0,0 +1,82 @@ +const variantEntry = { + "name": "Colors", + "content_types": [ + "iphone_product_page" + ], + "uid": "iphone_color_white" + } + +const variantEntry1 = { + "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 variantEntry2 = { + 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_product_description" + ], + "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 { variantEntry, variantEntry1, variantEntry2 } diff --git a/test/typescript/mock/variants.ts b/test/typescript/mock/variants.ts new file mode 100644 index 00000000..d32ae855 --- /dev/null +++ b/test/typescript/mock/variants.ts @@ -0,0 +1,41 @@ +const variantEntry = { + "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", + } + + +const variantEntry2 = { + "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 { variantEntry, variantEntry2 } diff --git a/test/typescript/ungroupedVariants.ts b/test/typescript/ungroupedVariants.ts new file mode 100644 index 00000000..731fe63f --- /dev/null +++ b/test/typescript/ungroupedVariants.ts @@ -0,0 +1,87 @@ +import { expect } from "chai" +import path from "path" +import { Stack } from "../../types/stack"; +import { Variants } from "../../types/stack/variants"; +import { variant, variants1, variants2 } from "./mock/ungroupedvariants"; +var variantUID = '' +export function createVariants(stack: Stack) { + describe('Variants create', () => { + test('Create a Variants', done => { + stack.variant().create(variants1) + .then((variant) => { + expect(variant.name).to.be.equal(variants.name) + expect(variant.uid).to.be.not.equal(null) + done() + }) + .catch(done) + }) + + test('Create Variants for production', done => { + stack.variant().create(variants1) + .then((variant) => { + variantUID = variant.uid + expect(variant.name).to.be.equal(variants2.name) + expect(variant.uid).to.be.not.equal(null) + done() + }) + .catch(done) + }) + }) +} + +export function queryVariants(variants: Variants) { + describe('Query Variants', () => { + test('Get all Variants', done => { + variants.query().find() + .then((variants) => { + variants.items.forEach((variant) => { + expect(variant.name).to.be.not.equal(null) + expect(variant.uid).to.be.not.equal(null) + }) + done() + }) + .catch(done) + }) + + test('Get Variants from name', done => { + variants.query({query: {name: variants1.name}}) + .find() + .then((variants) => { + variants.items.forEach((variant) => { + expect(variant.name).to.be.equal(variants1.name) + expect(variant.uid).to.be.not.equal(null) + }) + done() + }) + .catch(done) + }) + }) +} +export function variants(stack: Stack) { + describe('Variants operations', () => { + test('Fetch Variants', done => { + stack.variants(variantUID) + .fetch() + .then((variant) => { + expect(variant.name).to.be.equal(variants2.name) + expect(variant.uid).to.be.not.equal(null) + done() + }) + .catch(done) + }) + }) +} + +export function deleteVariants(stack: Stack) { + describe('Delete Variants', () => { + test('Delete variant from uid', done => { + stack.variants(variantUID) + .delete() + .then((data) => { + expect(data.notice).to.be.equal('Variants deleted successfully.') + done() + }) + .catch(done) + }) + }) +} \ No newline at end of file diff --git a/test/typescript/variantGroup.ts b/test/typescript/variantGroup.ts new file mode 100644 index 00000000..e6956d50 --- /dev/null +++ b/test/typescript/variantGroup.ts @@ -0,0 +1,103 @@ +import { expect } from "chai" +import path from "path" +import { Stack } from "../../types/stack"; +import { VariantGroup, VariantGroups } from "../../types/stack/VariantGroup"; +import { variantEntry, variantEntry1, variantEntry2 } from "./mock/variantGroup"; +var tokenUID = '' +export function createVariantGroup(variantGroup: VariantGroup) { + describe('Variant group create', () => { + test('Create a management token', done => { + variantGroup.create({variantEntry}) + .then((response) => { + expect(response.name).to.be.equal(variantEntry.name) + expect(response.uid).to.be.not.equal(null) + done() + }) + .catch(done) + }) + }) +} + +export function queryVariantGroup(variantGroup: VariantGroups) { + describe('Query variant group', () => { + test('Get all variant group', done => { + variantGroup.query().find() + .then((response) => { + response.items.forEach((variant_groups) => { + expect(variant_groups.name).to.be.not.equal(null) + expect(variant_groups.uid).to.be.not.equal(null) + }) + done() + }) + .catch(done) + }) + + test('Get variant group from name', done => { + variantGroup.query({query: {name: variantEntry2[0].name}}) + .find() + .then((response) => { + response.items.forEach((variant_groups) => { + expect(variant_groups.name).to.be.equal(variantEntry1.name) + expect(variant_groups.uid).to.be.not.equal(null) + }) + done() + }) + .catch(done) + }) + }) +} +export function variantGroup(stack: Stack) { + describe('Variant group operations', () => { + test('Fetch variant group', done => { + stack.variantGroup(tokenUID) + .fetch() + .then((response) => { + expect(response.name).to.be.equal(variantEntry1.name) + expect(response.uid).to.be.not.equal(null) + done() + }) + .catch(done) + }) + + test('Fetch and update a Variant Group from uid', done => { + stack.variantGroup(tokenUID) + .fetch() + .then((response) => { + response.name = 'Update Variant Group' + return response.update() + }) + .then((response) => { + expect(response.name).to.be.equal('Update Variant Group') + expect(response.uid).to.be.not.equal(null) + done() + }) + .catch(done) + }) + + test('Update variant group from uid', done => { + const variantgroup = stack.variantGroup(tokenUID) + Object.assign(variantgroup, variantEntry) + variantgroup.update() + .then((response) => { + expect(response.name).to.be.equal(variantEntry.name) + expect(response.uid).to.be.not.equal(null) + done() + }) + .catch(done) + }) + }) +} + +export function deleteVariantGroup(stack: Stack) { + describe('Delete variant group', () => { + test('Delete token from uid', done => { + stack.variantGroup(tokenUID) + .delete() + .then((data) => { + expect(data.notice).to.be.equal('Variant Group deleted successfully.') + done() + }) + .catch(done) + }) + }) +} \ No newline at end of file diff --git a/test/typescript/variants.ts b/test/typescript/variants.ts new file mode 100644 index 00000000..84b8ffcc --- /dev/null +++ b/test/typescript/variants.ts @@ -0,0 +1,89 @@ +import { expect } from "chai" +import path from "path" +import { Stack } from "../../types/stack"; +import { Variant, Variants } from "../../types/stack/VariantGroup/variants"; +import { variantEntry, variantEntry2 } from "./mock/variants"; +var tokenUID = '' +export function createVariant(stack: Stack) { + describe('Variant create', () => { + test('Create a variant', done => { + stack.VariantGroup('variant_group_uid').variants().create({variantEntry}) + .then((response) => { + expect(response.name).to.be.equal(variantEntry.name) + expect(response.uid).to.be.not.equal(null) + done() + }) + .catch(done) + }) + }) +} + +export function queryVariant(stack: Stack) { + describe('Query variants', () => { + test('Get all variants', done => { + stack.VariantGroup('variant_group_uid').variants().query().find() + .then((response) => { + response.items.forEach((variant) => { + expect(variant.name).to.be.not.equal(null) + expect(variant.uid).to.be.not.equal(null) + }) + done() + }) + .catch(done) + }) + + test('Get variants from name', done => { + stack.VariantGroup(tokenUID).variants().query({query: {name: variantEntry2[0].name}}) + .find() + .then((response) => { + response.items.forEach((variant_groups) => { + expect(variant_groups.name).to.be.equal(variantEntry.name) + expect(variant_groups.uid).to.be.not.equal(null) + }) + done() + }) + .catch(done) + }) + }) +} +export function variant(stack: Stack) { + describe('Variants operations', () => { + test('Fetch variant', done => { + stack.variantGroup(tokenUID).variant(variantEntry.uid) + .fetch() + .then((response) => { + expect(response.name).to.be.equal(variantEntry.name) + expect(response.uid).to.be.not.equal(null) + done() + }) + .catch(done) + }) + + test('Fetch and update a Variant from uid', done => { + stack.variantGroup(tokenUID).variant('uid') + .fetch() + .then((response) => { + response.name = 'Update Variant name' + return response.update() + }) + .then((response) => { + expect(response.name).to.be.equal('Update Variant name') + expect(response.uid).to.be.not.equal(null) + done() + }) + .catch(done) + }) + + test('Update variant from uid', done => { + const variants = stack.variantGroup(tokenUID).variant(variantEntry.uid) + Object.assign(variants, variantEntry) + variants.update() + .then((response) => { + expect(response.name).to.be.equal(variantEntry.name) + expect(response.uid).to.be.not.equal(null) + done() + }) + .catch(done) + }) + }) +} \ No newline at end of file diff --git a/test/unit/entry-test.js b/test/unit/entry-test.js index 6e739f1f..9e65ddd2 100644 --- a/test/unit/entry-test.js +++ b/test/unit/entry-test.js @@ -5,7 +5,7 @@ import { describe, it } from 'mocha' import MockAdapter from 'axios-mock-adapter' import { Entry, EntryCollection, createFormData } from '../../lib/stack/contentType/entry' import { cleanAssets } from '../../lib/entity' -import { systemUidMock, stackHeadersMock, entryMock, noticeMock, checkSystemFields } from './mock/objects' +import { systemUidMock, stackHeadersMock, entryMock, noticeMock, checkSystemFields, variantBaseEntryMock } from './mock/objects' describe('Contentstack Entry test', () => { it('Entry test without uid', done => { @@ -291,6 +291,23 @@ describe('Contentstack Entry test', () => { .catch(done) }) + it('Entry with include variants request test', done => { + var mock = new MockAdapter(Axios) + mock.onGet('/content_types/content_type_uid/entries/UID').reply(200, { + ...variantBaseEntryMock + }) + makeEntry({ entry: { ...systemUidMock }, + stackHeaders: stackHeadersMock + }) + .includeVariants({ include_variant: 'True', variants_uid: 'test_uid' }) + .then((response) => { + expect(response.api_key).to.be.equal('api_key') + expect(response['x-cs-variant-uid']).to.be.equal('test_uid') + done() + }) + .catch(done) + }) + it('Entry set Workflow stage test', done => { var mock = new MockAdapter(Axios) diff --git a/test/unit/index.js b/test/unit/index.js index a06cb20b..28d1b876 100644 --- a/test/unit/index.js +++ b/test/unit/index.js @@ -39,3 +39,6 @@ require('./team-test') require('./team-users-test') require('./team-stack-role-mapping-test') require('./managementToken-test') +require('./ungroupedVariants-test') +require('./variantGroup-test') +require('./variantsWithVariantsGroup-test') diff --git a/test/unit/mock/objects.js b/test/unit/mock/objects.js index 3f7a5ff1..54110dcf 100644 --- a/test/unit/mock/objects.js +++ b/test/unit/mock/objects.js @@ -18,6 +18,11 @@ const stackHeadersMock = { api_key: 'api_key' } +const variantBaseEntryMock = { + api_key: 'api_key', + 'x-cs-variant-uid': 'test_uid' +} + const noticeMock = { notice: 'Notice' } @@ -438,6 +443,57 @@ const entryMock = { _rules: [] } +const variantsEntriesMock = { + "title": "title", + "url": "/url", + "author": "Kurt Tank", + "created_by": "created_by", + "updated_by": "updated_by", + "created_at": "created_at_date", + "updated_at": "updated_at_date", + "uid": "UID", + "locale": "en-us", + "_version": 1, + "_in_progress": false, + "_variant": { + "uid": "_variant_uid", + "variant_id": 'variant_id', + "customized_fields": ["title", "author"], + "base_entry_version": 1, + } +} +const variantsUpdateEntryMock = { + "title": "title", + "url": "/url", + "uid": "UID", + "locale": "en-us", + "_version": 1, + "_in_progress": false, + "_variant": { + "customized_fields": ["title", "url"], + }, + "created_at": "created_at_date", + "updated_at": "updated_at_date", +} +const variantsEntryMock = { + "title": "title", + "url": "/url", + "locale": "en-us", + "uid": "UID", + "_version": 1, + "_in_progress": false, + "created_by": "created_by_uid", + "updated_by": "updated_by_uid", + "created_at": "created_at_date", + "updated_at": "updated_at_date", + "_variant": { + "uid": "_variant_uid", + "variant_id": 'variant_id', + "customized_fields": ["title"], + "base_entry_version": 10, + } +} + const labelMock = { ...systemFieldsMock, ...systemFieldsUserMock, @@ -453,6 +509,13 @@ const labelMock = { ] } +const variantsMock1 = { + ...systemFieldsMock, + ...systemFieldsUserMock, + name: 'name' +} + + const environmentMock = { ...systemFieldsMock, ...systemFieldsUserMock, @@ -893,6 +956,106 @@ const teamUsersMock = { userId: 'UID' } } + +const variantGroupMock = { + ...systemFieldsMock, + ...systemFieldsUserMock, + name: 'Test', + source: 'Personalize', + content_types: [ + "iphone_product_page" + ], +} + +const variantMock = { + ...systemFieldsMock, + ...systemFieldsUserMock, + name: 'Test' +} + +const variantsMock = { + "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": "UID", + "created_by": "user_id", + "updated_by": "user_id", + "name": "Test", + "personalize_metadata": { + "experience_uid": "exp1", + "experience_short_uid": "expShortUid1", + "project_uid": "project_uid1", + "variant_short_uid": "variantShort_uid1" + }, + "created_at": "created_at_date", + "updated_at": "updated_at_date" + } + ], + "count": 1 +} + +const variantGroupsMock = { + count: 2, + variant_groups: [ + { + ...systemFieldsMock, + ...systemFieldsUserMock, + "name": "Test", + "source": 'Personalize', + "content_types": [ + "iphone_product_page" + ], + "variant_count": 1, + "variants": [ + { + ...systemFieldsMock, + ...systemFieldsUserMock, + "name": "Test" + } + ] + }, + { + "name": "Test", + "source": 'Personalize', + ...systemFieldsMock, + ...systemFieldsUserMock, + "content_types": [ + "iphone_product_description" + ], + "variant_count": 1, + "variants": [ + { + ...systemFieldsMock, + ...systemFieldsUserMock, + "name": "Test" + } + ] + } + ], + ungrouped_variants: [ + { + "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_red", + "name": "Red" + } + ], + ungrouped_variant_count: 1 +} + + + const stackRoleMappingMock = { stackRoleMappings: [ { @@ -981,5 +1144,14 @@ export { entryMockCollection, checkSystemFields, managementTokenMock, + variantGroupMock, + variantGroupsMock, + variantMock, + variantsMock, + variantsMock1, + variantsEntryMock, + variantsEntriesMock, + variantsUpdateEntryMock, + variantBaseEntryMock, roleMockWithTaxonomy } diff --git a/test/unit/ungroupedVariants-test.js b/test/unit/ungroupedVariants-test.js new file mode 100644 index 00000000..e26ade1f --- /dev/null +++ b/test/unit/ungroupedVariants-test.js @@ -0,0 +1,167 @@ +import Axios from 'axios' +import { expect } from 'chai' +import { describe, it } from 'mocha' +import MockAdapter from 'axios-mock-adapter' +import { Variants, VariantsCollection } from '../../lib/stack/variants' +import { systemUidMock, stackHeadersMock, variantsMock1, checkSystemFields, noticeMock } from './mock/objects' + +describe('Contentstack Variants test', () => { + it('Variants test without uid', done => { + const variants = makeVariants() + expect(variants.urlPath).to.be.equal('/variants') + expect(variants.stackHeaders).to.be.equal(undefined) + expect(variants.delete).to.be.equal(undefined) + expect(variants.fetch).to.be.equal(undefined) + expect(variants.create).to.not.equal(undefined) + expect(variants.query).to.not.equal(undefined) + done() + }) + + it('Variants test with uid', done => { + const variants = makeVariants({ + variants: { + ...systemUidMock + } + }) + expect(variants.urlPath).to.be.equal(`/variants/${systemUidMock.uid}`) + expect(variants.stackHeaders).to.be.equal(undefined) + expect(variants.delete).to.not.equal(undefined) + expect(variants.fetch).to.not.equal(undefined) + expect(variants.create).to.be.equal(undefined) + expect(variants.query).to.be.equal(undefined) + done() + }) + + it('Variants test with Stack Headers', done => { + const variants = makeVariants({ + variants: { + ...systemUidMock + }, + stackHeaders: stackHeadersMock + }) + expect(variants.urlPath).to.be.equal(`/variants/${systemUidMock.uid}`) + expect(variants.stackHeaders).to.not.equal(undefined) + expect(variants.stackHeaders.api_key).to.be.equal(stackHeadersMock.api_key) + expect(variants.delete).to.not.equal(undefined) + expect(variants.fetch).to.not.equal(undefined) + expect(variants.create).to.be.equal(undefined) + expect(variants.fetchAll).to.be.equal(undefined) + expect(variants.query).to.be.equal(undefined) + done() + }) + + it('Variants Collection test with blank data', done => { + const variants = new VariantsCollection(Axios, {}) + expect(variants.length).to.be.equal(0) + done() + }) + + it('Variants Collection test with data', done => { + const variants = new VariantsCollection(Axios, { + variants: [ + variantsMock1 + ] + }) + expect(variants.length).to.be.equal(1) + checkVariants(variants[0]) + done() + }) + + it('Variants create test', done => { + var mock = new MockAdapter(Axios) + mock.onPost('/variants').reply(200, { + variants: { + ...variantsMock1 + } + }) + makeVariants() + .create() + .then((variants) => { + checkVariants(variants) + done() + }) + .catch(done) + }) + + it('Variants Query test', done => { + var mock = new MockAdapter(Axios) + mock.onGet('/variants').reply(200, { + variants: [ + variantsMock1 + ] + }) + makeVariants() + .query() + .find() + .then((variants) => { + checkVariants(variants.items[0]) + done() + }) + .catch(done) + }) + + it('Variants fetchByUIDs test', done => { + var mock = new MockAdapter(Axios) + mock.onGet('/variants').reply(200, { + variants: [ + variantsMock1 + ] + }) + makeVariants() + .fetchByUIDs(['uid1','uid2']) + .then((variants) => { + checkVariants(variants.variants[0]) + done() + }) + .catch(done) + }) + + it('Variants fetch test', done => { + var mock = new MockAdapter(Axios) + mock.onGet('/variants/UID').reply(200, { + variants: { + ...variantsMock1 + } + }) + makeVariants({ + variants: { + ...systemUidMock + }, + stackHeaders: stackHeadersMock + }) + .fetch() + .then((variants) => { + checkVariants(variants) + done() + }) + .catch(done) + }) + + it('Variants delete test', done => { + var mock = new MockAdapter(Axios) + mock.onDelete('/variants/UID').reply(200, { + ...noticeMock + }) + makeVariants({ + variants: { + ...systemUidMock + }, + stackHeaders: stackHeadersMock + }) + .delete() + .then((response) => { + expect(response.notice).to.be.equal(noticeMock.notice) + done() + }) + .catch(done) + }) +}) + +function makeVariants (data = {}) { + return new Variants(Axios, data) +} + +function checkVariants (variants) { + checkSystemFields(variants) + expect(variants.name).to.be.equal('name') +} diff --git a/test/unit/variantGroup-test.js b/test/unit/variantGroup-test.js new file mode 100644 index 00000000..8d61c969 --- /dev/null +++ b/test/unit/variantGroup-test.js @@ -0,0 +1,166 @@ +import Axios from 'axios' +import { expect } from 'chai' +import { describe, it } from 'mocha' +import MockAdapter from 'axios-mock-adapter' +import { VariantGroup, VariantGroupCollection } from '../../lib/stack/variantGroup' +import { systemUidMock, stackHeadersMock, variantGroupMock, noticeMock, checkSystemFields, variantGroupsMock } from './mock/objects' +import { checkEnvironment } from './variantGroup-test' + +describe('Contentstack VariantGroup test', () => { + it('VariantGroup test without uid', done => { + const variantGroup = makeVariantGroup() + expect(variantGroup.urlPath).to.be.equal('/variant_groups') + expect(variantGroup.stackHeaders).to.be.equal(undefined) + expect(variantGroup.update).to.be.equal(undefined) + expect(variantGroup.delete).to.be.equal(undefined) + expect(variantGroup.create).to.not.equal(undefined) + expect(variantGroup.query).to.not.equal(undefined) + done() + }) + + it('VariantGroup test with uid', done => { + const variantGroup = makeVariantGroup({variant_group: {...systemUidMock}}) + expect(variantGroup.urlPath).to.be.equal(`/variant_groups/${systemUidMock.uid}`) + expect(variantGroup.stackHeaders).to.be.equal(undefined) + expect(variantGroup.update).to.not.equal(undefined) + expect(variantGroup.delete).to.not.equal(undefined) + expect(variantGroup.create).to.be.equal(undefined) + expect(variantGroup.query).to.be.equal(undefined) + done() + }) + + it('VariantGroup test with Stack Headers', done => { + const variantGroup = makeVariantGroup({ variant_group:{ + ...systemUidMock, + stackHeaders: stackHeadersMock + } + }) + expect(variantGroup.urlPath).to.be.equal(`/variant_groups/${systemUidMock.uid}`) + expect(variantGroup.stackHeaders).to.not.equal(undefined) + expect(variantGroup.stackHeaders.api_key).to.be.equal(stackHeadersMock.api_key) + expect(variantGroup.update).to.not.equal(undefined) + expect(variantGroup.delete).to.not.equal(undefined) + expect(variantGroup.create).to.be.equal(undefined) + expect(variantGroup.query).to.be.equal(undefined) + done() + }) + + it('VariantGroup Collection test with blank data', done => { + const variantGroup = new VariantGroupCollection(Axios, {}) + expect(variantGroup.length).to.be.equal(0) + done() + }) + + it('VariantGroup Collection test with data', done => { + const variantGroup = new VariantGroupCollection(Axios, { + variant_groups: [ + variantGroupMock + ] + }) + expect(variantGroup.length).to.be.equal(1) + checkVariantGroup(variantGroup[0]) + done() + }) + + it('VariantGroup create test', done => { + var mock = new MockAdapter(Axios) + mock.onPost('/variant_groups').reply(200, { + variant_group: { + ...variantGroupMock + } + }) + makeVariantGroup() + .create() + .then((variantGroup) => { + checkVariantGroup(variantGroup) + done() + }) + .catch(done) + }) + + it('VariantGroup Query test', done => { + var mock = new MockAdapter(Axios) + mock.onGet('/variant_groups').reply(200, { ...variantGroupsMock + }) + makeVariantGroup() + .query() + .find() + .then((variantGroups) => { + checkVariantGroup(variantGroups.items[0]) + done() + }) + .catch(done) + }) + + it('VariantGroup update test', done => { + var mock = new MockAdapter(Axios) + mock.onPut('/variant_groups/UID').reply(200, { + variant_group: { + ...variantGroupMock + } + }) + makeVariantGroup({variant_group:{ + ...systemUidMock, + stackHeaders: stackHeadersMock + } + }) + .update({name: 'test'}) + .then((variantGroup) => { + checkVariantGroup(variantGroup.variant_group) + done() + }) + .catch(done) + }) + + // Fetch API not present in the variant group + // it('VariantGroup fetch test', done => { + // var mock = new MockAdapter(Axios) + // mock.onGet('/variant_groups/UID').reply(200, { + // variant_group: { + // ...variantGroupMock + // } + // }) + // makeVariantGroup({ + // variant_group: { + // ...systemUidMock + // }, + // stackHeaders: stackHeadersMock + // }) + // .fetch() + // .then((variantGroup) => { + // checkVariantGroup(variantGroup) + // done() + // }) + // .catch(done) + // }) + + it('VariantGroup delete test', done => { + var mock = new MockAdapter(Axios) + mock.onDelete('/variant_groups/UID').reply(200, { + ...noticeMock + }) + makeVariantGroup({ + variant_group: { + ...systemUidMock + }, + stackHeaders: stackHeadersMock + }) + .delete() + .then((response) => { + expect(response.notice).to.be.equal(noticeMock.notice) + done() + }) + .catch(done) + }) +}) + +function makeVariantGroup (data = {}) { + return new VariantGroup(Axios, data) +} + +function checkVariantGroup (variantGroup) { + checkSystemFields(variantGroup) + expect(variantGroup.name).to.be.equal('Test') + expect(variantGroup.source).to.be.equal('Personalize') + expect(variantGroup.content_types.length).to.be.equal(1) +} \ No newline at end of file diff --git a/test/unit/variantsWithVariantsGroup-test.js b/test/unit/variantsWithVariantsGroup-test.js new file mode 100644 index 00000000..dea369d2 --- /dev/null +++ b/test/unit/variantsWithVariantsGroup-test.js @@ -0,0 +1,141 @@ +import Axios from 'axios' +import { expect } from 'chai' +import { describe, it } from 'mocha' +import MockAdapter from 'axios-mock-adapter' +import { Variants, VariantsCollection } from '../../lib/stack/variantGroup/variants' +import { systemUidMock, stackHeadersMock, variantMock, noticeMock, checkSystemFields, variantsMock } from './mock/objects' +import { checkEnvironment } from './variantsWithVariantsGroup-test' + +describe('Contentstack Variants test', () => { + it(' Variants test without uid', done => { + const variants = makeVariants({variant_group_uid: systemUidMock.uid}) + expect(variants.urlPath).to.be.equal(`/variant_groups/${systemUidMock.uid}/variants`) + expect(variants.stackHeaders).to.be.equal(undefined) + expect(variants.update).to.be.equal(undefined) + expect(variants.delete).to.be.equal(undefined) + expect(variants.fetch).to.be.equal(undefined) + expect(variants.create).to.not.equal(undefined) + expect(variants.query).to.not.equal(undefined) + done() + }) + + it(' Variants test with uid', done => { + const variants = makeVariants({variant_group_uid: systemUidMock.uid, variants: {uid: systemUidMock.uid}}) + expect(variants.urlPath).to.be.equal(`/variant_groups/${systemUidMock.uid}/variants/${systemUidMock.uid}`) + expect(variants.stackHeaders).to.be.equal(undefined) + expect(variants.update).to.not.equal(undefined) + expect(variants.fetch).to.not.equal(undefined) + expect(variants.create).to.be.equal(undefined) + expect(variants.query).to.be.equal(undefined) + done() + }) + + it(' Variants test with Stack Headers', done => { + const variants = makeVariants({ variant_group_uid: systemUidMock.uid, + stackHeaders: stackHeadersMock + }) + expect(variants.urlPath).to.be.equal(`/variant_groups/${systemUidMock.uid}/variants`) + expect(variants.stackHeaders).to.not.equal(undefined) + expect(variants.stackHeaders.api_key).to.be.equal(stackHeadersMock.api_key) + done() + }) + + it(' Variants Collection test with blank data', done => { + const variants = new VariantsCollection(Axios, {}) + expect(variants.length).to.be.equal(0) + done() + }) + + it(' Variants Collection test with data', done => { + const variants = new VariantsCollection(Axios, { variant_group_uid: systemUidMock.uid, + variants: [ + variantMock + ] + }) + expect(variants.length).to.be.equal(1) + checkVariants(variants[0]) + done() + }) + + it(' Variants create test', done => { + var mock = new MockAdapter(Axios) + mock.onPost('/variant_groups/UID/variants').reply(200, { variant_group_uid: systemUidMock.uid, + variants: { + ...variantMock + } + }) + makeVariants({variant_group_uid: systemUidMock.uid}) + .create() + .then((variant) => { + checkVariants(variant) + done() + }) + .catch(done) + }) + + it(' Variants Query test', done => { + var mock = new MockAdapter(Axios) + mock.onGet('/variant_groups/UID/variants').reply(200, { variant_group_uid: systemUidMock.uid, ...variantsMock + }) + makeVariants({variant_group_uid: systemUidMock.uid}) + .query() + .find() + .then((variants) => { + checkVariants(variants.items[0]) + done() + }) + .catch(done) + }) + + it(' Variants update test', done => { + var mock = new MockAdapter(Axios) + mock.onPut('/variant_groups/UID/variants/UID').reply(200, { variant_group_uid: systemUidMock.uid, + variants: { + ...variantMock + } + }) + makeVariants({variant_group_uid: systemUidMock.uid, variants:{ + ...systemUidMock, + stackHeaders: stackHeadersMock + } + }) + .update() + .then((variant) => { + checkVariants(variant.variants) + done() + }) + .catch(done) + }) + + it(' Variants fetch test', done => { + var mock = new MockAdapter(Axios) + mock.onGet('/variant_groups/UID/variants/UID').reply(200, { variant_group_uid: systemUidMock.uid, + variants: { + ...variantMock + } + }) + makeVariants({ variant_group_uid: systemUidMock.uid, + variants: { + ...systemUidMock + }, + stackHeaders: stackHeadersMock + }) + .fetch() + .then((variant) => { + checkVariants(variant) + done() + }) + .catch(done) + }) + +}) + +function makeVariants (data = {}) { + return new Variants(Axios, data) +} + +function checkVariants (variant) { + checkSystemFields(variant) + expect(variant.name).to.be.equal('Test') + expect(variant.uid).to.be.equal('UID') +} \ No newline at end of file diff --git a/types/stack/VariantGroup/index.ts b/types/stack/VariantGroup/index.ts new file mode 100644 index 00000000..fe09fee5 --- /dev/null +++ b/types/stack/VariantGroup/index.ts @@ -0,0 +1,29 @@ +import { AnyProperty, SystemFields } from "../../utility/fields"; +import { Queryable, SystemFunction } from "../../utility/operations"; +import { Variants, Variant } from "./variants"; + +export interface VariantGroup extends SystemFields, SystemFunction { + variants(): Variants + variants(variant: string): Variant +} + +export interface VariantGroups extends Queryable { +} + +export interface VariantGroupData extends AnyProperty { + name: string + scope: Array +} + +export interface Scope { + module: string + environments?: Array + locales?: Array + acl: ACL +} +export interface ACL extends AnyProperty { + read?: boolean + write?: boolean + create?: boolean + update?: boolean +} \ No newline at end of file diff --git a/types/stack/VariantGroup/variants/index.d.ts b/types/stack/VariantGroup/variants/index.d.ts new file mode 100644 index 00000000..c5c1d358 --- /dev/null +++ b/types/stack/VariantGroup/variants/index.d.ts @@ -0,0 +1,29 @@ +import { AnyProperty, SystemFields } from "../../../utility/fields"; +import { Queryable, SystemFunction } from "../../../utility/operations"; + +export interface Variant extends SystemFields, SystemFunction { + +} + +export interface Variants extends Queryable { + +} + +export interface VariantData extends AnyProperty { + name: string + uid: string + scope: Array +} + +export interface Scope { + module: string + environments?: Array + locales?: Array + acl: ACL +} +export interface ACL extends AnyProperty { + read?: boolean + write?: boolean + create?: boolean + update?: boolean +} \ No newline at end of file diff --git a/types/stack/contentType/entry.d.ts b/types/stack/contentType/entry.d.ts index 6d3f8149..36cfc1cd 100644 --- a/types/stack/contentType/entry.d.ts +++ b/types/stack/contentType/entry.d.ts @@ -3,9 +3,12 @@ import { AnyProperty, SystemFields } from "../../utility/fields"; import { Queryable, SystemFunction } from "../../utility/operations"; import { Publishable } from "../../utility/publish"; import { Unpublishable } from "../../utility/unpublish"; +import { Variants, Variant } from "./variants"; export interface Entry extends Publishable, Unpublishable, SystemFields, SystemFunction { + variants(): Variants + variants(uid: string): Variant setWorkflowStage(data: { workflow_stage: WorkflowStage, locale?:string}): Promise locales(): Promise } diff --git a/types/stack/contentType/index.d.ts b/types/stack/contentType/index.d.ts index 761aed39..2b34aaa4 100644 --- a/types/stack/contentType/index.d.ts +++ b/types/stack/contentType/index.d.ts @@ -6,6 +6,8 @@ export interface ContentType extends SystemFields, SystemFunction { entry(): Entries entry(uid: string): Entry } + + export interface ContentTypes extends Queryable { import(data: {content_type: string}, params?: any): Promise diff --git a/types/stack/contentType/variants.d.ts b/types/stack/contentType/variants.d.ts new file mode 100644 index 00000000..b584785f --- /dev/null +++ b/types/stack/contentType/variants.d.ts @@ -0,0 +1,25 @@ +import { Response } from "../../contentstackCollection"; +import { AnyProperty, SystemFields } from "../../utility/fields"; +import { Queryable, SystemFunction } from "../../utility/operations"; + +export interface Variant extends SystemFields, SystemFunction { +} +export interface Variants extends Queryable { +} + +export interface VariantData extends AnyProperty { + title: string + url?: string +} +export interface Scope { + module: string + environments?: Array + locales?: Array + acl: ACL +} +export interface ACL extends AnyProperty { + read?: boolean + write?: boolean + create?: boolean + update?: boolean +} \ No newline at end of file diff --git a/types/stack/index.d.ts b/types/stack/index.d.ts index 331f036d..f1ed0d43 100644 --- a/types/stack/index.d.ts +++ b/types/stack/index.d.ts @@ -20,6 +20,9 @@ import { Webhook, Webhooks } from "./webhook"; import { Workflow, Workflows } from "./workflow"; import { Taxonomy, Taxonomies } from "./taxonomy"; import { ManagementToken, ManagementTokens } from "./managementToken"; +import { Variant, Variants } from "./variants"; +import { VariantGroup, VariantGroups } from "./VariantGroup"; +import { Variant, Variants } from "./VariantGroup/variants"; export interface StackConfig { api_key:string @@ -100,4 +103,13 @@ export interface Stack extends SystemFields { managementToken(): ManagementTokens managementToken(uid: string): ManagementToken + + variants(): Variants + variants(uid: string): Variant + + variantGroup(): VariantGroups + variantGroup(uid: string): VariantGroup + + variant(): Variants + variant(uid: string): Variant } diff --git a/types/stack/variants/index.d.ts b/types/stack/variants/index.d.ts new file mode 100644 index 00000000..7009cc1f --- /dev/null +++ b/types/stack/variants/index.d.ts @@ -0,0 +1,14 @@ +import { AnyProperty, SystemFields } from "../../utility/fields"; +import { Queryable, SystemFunction } from "../../utility/operations"; + +export interface Variant extends SystemFields, SystemFunction { +} + +export interface Variants extends Queryable { + fetchByUIDs(data: Array): Promise +} + +export interface VariantData extends AnyProperty { + name: string + parent?: Array +}