Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: ✨ terms support #81

Merged
merged 7 commits into from
Sep 29, 2023
13 changes: 8 additions & 5 deletions lib/entity.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export const create = ({ http, params }) => {
try {
const response = await http.post(this.urlPath, data, headers)
if (response.data) {
return new this.constructor(http, parseData(response, this.stackHeaders, this.content_type_uid))
return new this.constructor(http, parseData(response, this.stackHeaders, this.content_type_uid, this.taxonomy_uid))
harshithad0703 marked this conversation as resolved.
Show resolved Hide resolved
} else {
throw error(response)
}
Expand Down Expand Up @@ -144,7 +144,7 @@ export const update = (http, type, params = {}) => {
}
})
if (response.data) {
return new this.constructor(http, parseData(response, this.stackHeaders, this.content_type_uid))
return new this.constructor(http, parseData(response, this.stackHeaders, this.content_type_uid, this.taxonomy_uid))
} else {
throw error(response)
}
Expand Down Expand Up @@ -204,7 +204,7 @@ export const fetch = (http, type, params = {}) => {
response.data[type]['content_type'] = response.data['content_type']
response.data[type]['schema'] = response.data['schema']
}
return new this.constructor(http, parseData(response, this.stackHeaders, this.content_type_uid))
return new this.constructor(http, parseData(response, this.stackHeaders, this.content_type_uid, this.taxonomy_uid))
} else {
throw error(response)
}
Expand Down Expand Up @@ -235,14 +235,17 @@ export const fetchAll = (http, wrapperCollection, params = {}) => {
}
}

export function parseData (response, stackHeaders, contentTypeUID) {
export function parseData (response, stackHeaders, contentTypeUID, taxonomyUID) {
const data = response.data || {}
if (stackHeaders) {
data.stackHeaders = stackHeaders
}
if (contentTypeUID) {
data.content_type_uid = contentTypeUID
}
if (taxonomyUID) {
data.taxonomy_uid = taxonomyUID
}
return data
}

Expand All @@ -266,4 +269,4 @@ export async function get (http, url, params, data) {
} catch (err) {
throw error(err)
}
}
}
22 changes: 18 additions & 4 deletions lib/stack/taxonomy/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable camelcase */
import cloneDeep from 'lodash/cloneDeep'
import {
create,
Expand All @@ -6,13 +7,17 @@ import {
update,
deleteEntity
} from '../../entity'
import { Terms, TermsCollection } from './terms'

export function Taxonomy (http, data) {
export function Taxonomy (http, data = {}) {
this.stackHeaders = data.stackHeaders
this.urlPath = `/taxonomies`

if (data.taxonomy) {
Object.assign(this, cloneDeep(data.taxonomy))
if (data.taxonomy.terms) {
this.terms = new TermsCollection(http, { terms: data.taxonomy.terms, stackHeaders: data.stackHeaders }, this.uid)
}
this.urlPath = `/taxonomies/${this.uid}`

/**
Expand All @@ -24,7 +29,7 @@ export function Taxonomy (http, data) {
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client()
*
* client.stack({ api_key: 'api_key'}).taxonomy('taxonomy_uid').fetch()
* client.stack({ api_key: 'api_key'}).taxonomy('taxonomyUid').fetch()
* .then((taxonomy) => {
* taxonomy.name = 'taxonomy name'
* return taxonomy.update()
Expand All @@ -43,7 +48,7 @@ export function Taxonomy (http, data) {
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client()
*
* client.stack({ api_key: 'api_key'}).taxonomy('taxonomy_uid').delete()
* client.stack({ api_key: 'api_key'}).taxonomy('taxonomyUid').delete()
* .then((response) => console.log(response.notice))
*
*/
Expand All @@ -58,11 +63,20 @@ export function Taxonomy (http, data) {
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client()
*
* client.stack({ api_key: 'api_key'}).taxonomy('taxonomy_uid').fetch()
* client.stack({ api_key: 'api_key'}).taxonomy('taxonomyUid').fetch()
* .then((taxonomy) => console.log(taxonomy))
*
*/
this.fetch = fetch(http, 'taxonomy')

this.terms = (uid = '') => {
const data = { stackHeaders: this.stackHeaders }
data.taxonomy_uid = this.uid
if (uid) {
data.term = { uid: uid }
}
return new Terms(http, data)
}
} else {
/**
* @description The Create taxonomy call is used to create a taxonomy.
Expand Down
145 changes: 145 additions & 0 deletions lib/stack/taxonomy/terms/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import cloneDeep from 'lodash/cloneDeep'
import {
create,
fetch,
update,
query,
deleteEntity
} from '../../../entity'

export function Terms (http, data) {
this.stackHeaders = data.stackHeaders
this.taxonomy_uid = data.taxonomy_uid
this.urlPath = `/taxonomies/${this.taxonomy_uid}/terms`

if (data && data.term) {
Object.assign(this, cloneDeep(data.term))
this.urlPath = `/taxonomies/${this.taxonomy_uid}/terms/${this.uid}`

/**
* @description The Update terms call is used to update an existing terms.
* @memberof Terms
* @func update
* @returns {Promise<Terms.Terms>} Promise for Terms instance
* @example
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client()
*
* client.stack({ api_key: 'api_key'}).terms('terms_uid').fetch()
* .then((terms) => {
* terms.name = 'terms name'
* return terms.update()
* })
* .then((terms) => console.log(terms))
*
*/
this.update = update(http, 'term')

/**
* @description The Delete terms call is used to delete an existing terms.
* @memberof Terms
* @func delete
* @returns {Promise<Terms.Terms>} Response Object.
* @example
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client()
*
* client.stack({ api_key: 'api_key'}).terms('terms_uid').delete()
* .then((response) => console.log(response.notice))
*
*/
this.delete = deleteEntity(http)

/**
* @description The Fetch terms call is used to fetch an existing terms.
* @memberof Terms
* @func fetch
* @returns {Promise<Terms.Terms>} Promise for Terms instance
* @example
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client()
*
* client.stack({ api_key: 'api_key'}).terms('terms_uid').fetch()
* .then((terms) => console.log(terms))
*
*/
this.fetch = fetch(http, 'term')
this.ancestors = async (params = {}) => {
try {
const headers = {
headers: { ...cloneDeep(this.stackHeaders), ...cloneDeep(params) }
}
const response = await http.get(`${this.urlPath}/ancestors`, headers)
return parseData(response, this.stackHeaders)
} catch (err) {
console.error(err)
throw err
}
}
this.descendants = async (params = {}) => {
try {
const headers = {
headers: { ...cloneDeep(this.stackHeaders), ...cloneDeep(params) }
}
const response = await http.get(`${this.urlPath}/descendants`, headers)
return parseData(response, this.stackHeaders)
} catch (err) {
console.error(err)
throw err
}
}
} else {
/**
* @description The Create terms call is used to create a terms.
* @memberof Terms
* @func create
* @returns {Promise<Terms.Terms>} Promise for Terms instance
* @example
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client()
* const terms = {
* uid: 'terms_testing1',
* name: 'terms testing',
* description: 'Description for terms testing'
* }
* client.stack({ api_key: 'api_key'}).terms().create({terms})
* .then(terms) => console.log(terms)
*
*/
this.create = create({ http })

/**
* @description The Query on Terms will allow to fetch details of all Terms.
* @memberof Terms
* @param {Object} params - URI parameters
* @prop {Object} params.query - Queries that you can use to fetch filtered results.
* @func query
* @returns {Array<Terms>} Array of Terms.
*
* @example
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client()
*
* client.stack().terms().query().find()
* .then((terms) => console.log(terms)
*/
this.query = query({ http: http, wrapperCollection: TermsCollection })
}
}
export function parseData (response, stackHeaders, taxonomy_uid) {
const data = response.data || {}
if (stackHeaders) {
data.stackHeaders = stackHeaders
}
if (taxonomy_uid) {
data.taxonomy_uid = taxonomy_uid
}
return data
}
export function TermsCollection (http, data) {
const obj = cloneDeep(data.terms) || []
const termsCollection = obj.map((term) => {
return new Terms(http, { term: term, taxonomy_uid: data.taxonomy_uid, stackHeaders: data.stackHeaders })
})
return termsCollection
}
89 changes: 89 additions & 0 deletions test/api/terms-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { describe, it, beforeEach } from 'mocha'
import { expect } from 'chai'
import { jsonReader } from '../utility/fileOperations/readwrite'
import { contentstackClient } from '../utility/ContentstackClient.js'

var client = {}
var stack = {}

const taxonomy_uid = 'taxonomy_21'
const term = {
term: {
uid: 'term_test',
name: 'Term test'
},
parent_uid: null
}

describe('Terms API Test', () => {
beforeEach(() => {
const user = jsonReader('loggedinuser.json')
stack = jsonReader('stack.json')
client = contentstackClient(user.authtoken)
})

it('Create term', async () => {
const response = await makeTerms().create([{ term }])
console.log(response)
expect(response.notice).to.be.equal('Term created successfully.')
expect(response.uid).to.be.equal(term.term.uid)
})

it('Query and get all terms', async () => {
const response = await makeTerms().query().find()
expect(response.items).to.be.an('array')
expect(response.items[0].uid).not.to.be.equal(null)
expect(response.items[0].name).not.to.be.equal(null)
})

it('Fetch term from UID', async () => {
const termsUid = 'fashion'
const response = await makeTerms(termsUid).fetch()
expect(response.uid).to.be.equal(termsUid)
expect(response.name).not.to.be.equal(null)
expect(response.created_by).not.to.be.equal(null)
expect(response.updated_by).not.to.be.equal(null)
})

it('Update term', async () => {
const termsUid = 'fashion'
const response = await makeTerms(termsUid).fetch()
.then((term) => {
term.name = 'fashion'
return term.update()
})
expect(response.notice).to.be.equal('Term updated successfully.')
expect(response.uid).to.be.equal(termsUid)
expect(response.name).to.be.equal('fashion')
expect(response.created_by).not.to.be.equal(null)
expect(response.updated_by).not.to.be.equal(null)
})

it('Delete term from UID', async () => {
const termsUid = 'testing'
const response = await makeTerms(termsUid).delete()
expect(response.notice).to.be.equal('')
})

it('Ancestors of the term given', async () => {
const termsUid = 'term_3'
const response = await makeTerms(termsUid).ancestors()
expect(response.terms[0].uid).not.to.be.equal(null)
expect(response.terms[0].name).not.to.be.equal(null)
expect(response.terms[0].created_by).not.to.be.equal(null)
expect(response.terms[0].updated_by).not.to.be.equal(null)
})

it('Descendants of the term given', async () => {
const termsUid = 'term_3'
const response = await makeTerms(termsUid).descendants()
expect(response.terms.uid).not.to.be.equal(null)
expect(response.terms.name).not.to.be.equal(null)
expect(response.terms.created_by).not.to.be.equal(null)
expect(response.terms.updated_by).not.to.be.equal(null)
})
})

function makeTerms (uid = '') {
return client.stack({ api_key: stack.api_key }).taxonomy(taxonomy_uid).terms(uid)
}
1 change: 1 addition & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ require('./api/label-test')
require('./api/contentType-delete-test')
require('./api/delete-test')
require('./api/taxonomy-test')
require('./api/terms-test')