diff --git a/lib/stack/index.js b/lib/stack/index.js index 94cde5fa..d86f72cb 100644 --- a/lib/stack/index.js +++ b/lib/stack/index.js @@ -18,7 +18,8 @@ import { Label } from './label' import { Branch } from './branch' import { BranchAlias } from './branchAlias' import { AuditLog } from './auditlog' -// import { format } from 'util' +import { Taxonomy } from './taxonomy' + /** * 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. * @namespace Stack @@ -684,6 +685,28 @@ export function Stack (http, data) { } return new Role(http, data) } + + /** + * @description Taxonomies allow you to group a collection of content within a stack. Using taxonomies you can group content types that need to work together + * @param {String} uid The UID of the Taxonomy you want to get details. + * @returns {Taxonomy} Instance of Taxonomy. + * @example + * import * as contentstack from '@contentstack/management' + * const client = contentstack.client() + * + * client.stack({ api_key: 'api_key'}).taxonomy().create() + * .then((taxonomy) => console.log(taxonomy)) + * + * client.stack({ api_key: 'api_key'}).taxonomy('taxonomy_uid').fetch() + * .then((taxonomy) => console.log(taxonomy)) + */ + this.taxonomy = (taxonomyUid = '') => { + const data = { stackHeaders: this.stackHeaders } + if (taxonomyUid) { + data.taxonomy = { uid: taxonomyUid } + } + return new Taxonomy(http, data) + } } else { /** * @description The Create stack call creates a new stack in your Contentstack account. diff --git a/lib/stack/taxonomy/index.js b/lib/stack/taxonomy/index.js new file mode 100644 index 00000000..a4989712 --- /dev/null +++ b/lib/stack/taxonomy/index.js @@ -0,0 +1,110 @@ +import cloneDeep from 'lodash/cloneDeep' +import { + create, + fetch, + query, + update, + deleteEntity +} from '../../entity' + +export function Taxonomy (http, data) { + this.stackHeaders = data.stackHeaders + this.urlPath = `/taxonomies` + + if (data.taxonomy) { + Object.assign(this, cloneDeep(data.taxonomy)) + this.urlPath = `/taxonomies/${this.uid}` + + /** + * @description The Update taxonomy call is used to update an existing taxonomy. + * @memberof Taxonomy + * @func update + * @returns {Promise} Promise for Taxonomy instance + * @example + * import * as contentstack from '@contentstack/management' + * const client = contentstack.client() + * + * client.stack({ api_key: 'api_key'}).taxonomy('taxonomy_uid').fetch() + * .then((taxonomy) => { + * taxonomy.name = 'taxonomy name' + * return taxonomy.update() + * }) + * .then((taxonomy) => console.log(taxonomy)) + * + */ + this.update = update(http, 'taxonomy') + + /** + * @description The Delete taxonomy call is used to delete an existing taxonomy. + * @memberof Taxonomy + * @func delete + * @returns {Promise} Response Object. + * @example + * import * as contentstack from '@contentstack/management' + * const client = contentstack.client() + * + * client.stack({ api_key: 'api_key'}).taxonomy('taxonomy_uid').delete() + * .then((response) => console.log(response.notice)) + * + */ + this.delete = deleteEntity(http) + + /** + * @description The Fetch taxonomy call is used to fetch an existing taxonomy. + * @memberof Taxonomy + * @func fetch + * @returns {Promise} Promise for Taxonomy instance + * @example + * import * as contentstack from '@contentstack/management' + * const client = contentstack.client() + * + * client.stack({ api_key: 'api_key'}).taxonomy('taxonomy_uid').fetch() + * .then((taxonomy) => console.log(taxonomy)) + * + */ + this.fetch = fetch(http, 'taxonomy') + } else { + /** + * @description The Create taxonomy call is used to create a taxonomy. + * @memberof Taxonomy + * @func create + * @returns {Promise} Promise for Taxonomy instance + * @example + * import * as contentstack from '@contentstack/management' + * const client = contentstack.client() + * const taxonomy = { + * uid: 'taxonomy_testing1', + * name: 'taxonomy testing', + * description: 'Description for Taxonomy testing' + * } + * client.stack({ api_key: 'api_key'}).taxonomy().create({taxonomy}) + * .then(taxonomy) => console.log(taxonomy) + * + */ + this.create = create({ http }) + + /** + * @description The Query on Taxonomy will allow to fetch details of all Taxonomies. + * @memberof Taxonomy + * @param {Object} params - URI parameters + * @prop {Object} params.query - Queries that you can use to fetch filtered results. + * @func query + * @returns {Array} Array of Taxonomy. + * + * @example + * import * as contentstack from '@contentstack/management' + * const client = contentstack.client() + * + * client.stack().taxonomy().query().find() + * .then((taxonomies) => console.log(taxonomies) + */ + this.query = query({ http: http, wrapperCollection: TaxonomyCollection }) + } +} +export function TaxonomyCollection (http, data) { + const obj = cloneDeep(data.taxonomy) || [] + const taxonomyCollection = obj.map((userdata) => { + return new Taxonomy(http, { taxonomy: userdata, stackHeaders: data.stackHeaders }) + }) + return taxonomyCollection +} diff --git a/test/api/taxonomy-test.js b/test/api/taxonomy-test.js new file mode 100644 index 00000000..2ecc7c73 --- /dev/null +++ b/test/api/taxonomy-test.js @@ -0,0 +1,86 @@ +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 taxonomy = { + uid: 'taxonomy_testing1', + name: 'taxonomy testing', + description: 'Description for Taxonomy testing' +} + +var taxonomyUID = '' +var taxonomyDelUID = 'taxonomy_testing' + +describe('taxonomy api Test', () => { + setup(() => { + const user = jsonReader('loggedinuser.json') + stack = jsonReader('stack.json') + client = contentstackClient(user.authtoken) + }) + + it('Create taxonomy', done => { + makeTaxonomy() + .create([{ taxonomy }]) + .then((taxonomyResponse) => { + expect(taxonomyResponse.name).to.be.equal(taxonomy.name) + done() + }) + .catch(done) + }) + + it('Fetch taxonomy from uid', done => { + makeTaxonomy(taxonomyUID) + .fetch() + .then((taxonomyResponse) => { + expect(taxonomyResponse.uid).to.be.equal(taxonomyUID) + expect(taxonomyResponse.name).to.be.not.equal(null) + done() + }) + .catch(done) + }) + + it('Update taxonomy from uid', done => { + makeTaxonomy(taxonomyUID) + .fetch() + .then((taxonomyResponse) => { + taxonomyResponse.name = 'Updated Name' + return taxonomyResponse.update() + }) + .then((taxonomyResponse) => { + expect(taxonomyResponse.uid).to.be.equal(taxonomyUID) + expect(taxonomyResponse.name).to.be.equal('Updated Name') + done() + }) + .catch(done) + }) + + it('Delete taxonomy from uid', done => { + makeTaxonomy(taxonomyDelUID) + .delete() + .then((taxonomyResponse) => { + expect(taxonomyResponse.notice).to.be.equal('Taxonomy deleted successfully.') + done() + }) + .catch(done) + }) + + it('Query to get all taxonomies', async () => { + makeTaxonomy() + .query() + .find() + .then((response) => { + response.items.forEach((taxonomyResponse) => { + expect(taxonomyResponse.uid).to.be.not.equal(null) + expect(taxonomyResponse.name).to.be.not.equal(null) + }) + }) + }) +}) + +function makeTaxonomy (uid = null) { + return client.stack({ api_key: stack.api_key }).taxonomy(uid) +} diff --git a/test/test.js b/test/test.js index 818f04cb..30f75299 100644 --- a/test/test.js +++ b/test/test.js @@ -25,3 +25,4 @@ require('./api/release-test') require('./api/label-test') require('./api/contentType-delete-test') require('./api/delete-test') +require('./api/taxonomy-test') diff --git a/test/unit/index.js b/test/unit/index.js index abd607f4..77316e2a 100644 --- a/test/unit/index.js +++ b/test/unit/index.js @@ -33,3 +33,4 @@ require('./deployment-test') require('./app-request-test') require('./authorization-test') require('./auditLog-test') +require('./taxonomy-test') diff --git a/test/unit/mock/objects.js b/test/unit/mock/objects.js index b525b6c6..0948d14f 100644 --- a/test/unit/mock/objects.js +++ b/test/unit/mock/objects.js @@ -539,7 +539,7 @@ const appInstallMock = { status: 'installed', installation_uid: 'installationUID', redirect_to: 'config', - redirect_uri: 'redirect_uri', + redirect_uri: 'redirect_uri' } const installationMock = { @@ -613,7 +613,7 @@ const branchCompareAllMock = { compare_branch: 'dev' }, diff: [...globalFieldDiff, ...contentTypeDiff], - next_url:'https://api.contentstack.io/v3/stacks/branches/compare?base_branch=main&compare_branch=dev&skip=0&limit=100' + next_url: 'https://api.contentstack.io/v3/stacks/branches/compare?base_branch=main&compare_branch=dev&skip=0&limit=100' } const branchCompareContentTypeMock = { @@ -621,8 +621,8 @@ const branchCompareContentTypeMock = { base_branch: 'UID', compare_branch: 'dev' }, - diff: [ ...contentTypeDiff ], - next_url:'https://api.contentstack.io/v3/stacks/branches/compare?base_branch=main&compare_branch=dev&skip=0&limit=100' + diff: [...contentTypeDiff], + next_url: 'https://api.contentstack.io/v3/stacks/branches/compare?base_branch=main&compare_branch=dev&skip=0&limit=100' } const branchCompareGlobalFieldMock = { @@ -631,7 +631,7 @@ const branchCompareGlobalFieldMock = { compare_branch: 'dev' }, diff: [...globalFieldDiff], - next_url:'https://api.contentstack.io/v3/stacks/branches/compare?base_branch=main&compare_branch=dev&skip=0&limit=100' + next_url: 'https://api.contentstack.io/v3/stacks/branches/compare?base_branch=main&compare_branch=dev&skip=0&limit=100' } const branchMergeAllMock = { @@ -647,7 +647,7 @@ const branchMergeAllMock = { status: 'in_progress' }, merged_at: null, - errors: [ + errors: [ { code: 'error_code', message: 'Error message' @@ -725,6 +725,15 @@ const auditLogsMock = { ] } +const taxonomyMock = { + uid: 'UID', + name: 'name', + description: 'Description for Taxonomy', + terms_count: 4, + referenced_terms_count: 3, + referenced_entries_count: 6 +} + function mockCollection (mockData, type) { const mock = { ...cloneDeep(noticeMock), @@ -793,6 +802,7 @@ export { branchMergeQueueFetchMock, auditLogsMock, auditLogItemMock, + taxonomyMock, mockCollection, entryMockCollection, checkSystemFields diff --git a/test/unit/taxonomy-test.js b/test/unit/taxonomy-test.js new file mode 100644 index 00000000..b9435185 --- /dev/null +++ b/test/unit/taxonomy-test.js @@ -0,0 +1,132 @@ +import Axios from 'axios' +import { expect } from 'chai' +import { describe, it } from 'mocha' +import MockAdapter from 'axios-mock-adapter' +import { Taxonomy } from '../../lib/stack/taxonomy' +import { systemUidMock, stackHeadersMock, taxonomyMock, noticeMock } from './mock/objects' + +describe('Contentstack Taxonomy test', () => { + it('taxonomy create test', done => { + var mock = new MockAdapter(Axios) + mock.onPost('/taxonomies').reply(200, { + taxonomy: { + ...taxonomyMock + } + }) + makeTaxonomy() + .create() + .then((taxonomy) => { + checkTaxonomy(taxonomy) + done() + }) + .catch(done) + }) + it('Taxonomy fetch test', done => { + var mock = new MockAdapter(Axios) + mock.onGet('/taxonomies/UID').reply(200, { + taxonomy: { + ...taxonomyMock + } + }) + makeTaxonomy({ + taxonomy: { + ...systemUidMock + }, + stackHeaders: stackHeadersMock + }) + .fetch() + .then((taxonomy) => { + checkTaxonomy(taxonomy) + done() + }) + .catch(done) + }) + it('Taxonomies query test', done => { + var mock = new MockAdapter(Axios) + mock.onGet('/taxonomies').reply(200, { + taxonomy: [ + taxonomyMock + ] + }) + makeTaxonomy() + .query() + .find() + .then((taxonomies) => { + checkTaxonomy(taxonomies.items[0]) + done() + }) + .catch(done) + }) + it('Taxonomy update test', done => { + var mock = new MockAdapter(Axios) + mock.onPut('/taxonomies/UID').reply(200, { + taxonomy: { + ...taxonomyMock + } + }) + makeTaxonomy({ + taxonomy: { + ...systemUidMock + }, + stackHeaders: stackHeadersMock + }) + .update() + .then((taxonomy) => { + checkTaxonomy(taxonomy) + done() + }) + .catch(done) + }) + it('taxonomy delete test', done => { + var mock = new MockAdapter(Axios) + mock.onDelete('/taxonomies/UID').reply(200, { + ...noticeMock + }) + makeTaxonomy({ + taxonomy: { + ...systemUidMock + }, + stackHeaders: stackHeadersMock + }) + .delete() + .then((response) => { + expect(response.notice).to.be.equal(noticeMock.notice) + done() + }) + .catch(done) + }) + it('Taxonomy test without uid', done => { + const taxonomy = makeTaxonomy() + expect(taxonomy.urlPath).to.be.equal('/taxonomies') + expect(taxonomy.stackHeaders).to.be.equal(undefined) + expect(taxonomy.update).to.be.equal(undefined) + expect(taxonomy.delete).to.be.equal(undefined) + expect(taxonomy.fetch).to.be.equal(undefined) + expect(taxonomy.create).to.not.equal(undefined) + expect(taxonomy.query).to.not.equal(undefined) + done() + }) + it('Taxonomy test with uid', done => { + const taxonomy = makeTaxonomy({ + taxonomy: { + ...systemUidMock + } + }) + expect(taxonomy.urlPath).to.be.equal(`/taxonomies/${systemUidMock.uid}`) + expect(taxonomy.stackHeaders).to.be.equal(undefined) + expect(taxonomy.update).to.not.equal(undefined) + expect(taxonomy.delete).to.not.equal(undefined) + expect(taxonomy.fetch).to.not.equal(undefined) + expect(taxonomy.create).to.be.equal(undefined) + expect(taxonomy.query).to.be.equal(undefined) + done() + }) +}) + +function makeTaxonomy (data = {}) { + return new Taxonomy(Axios, data) +} + +function checkTaxonomy (taxonomy) { + expect(taxonomy.name).to.be.equal('name') +}