Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions lib/stack/taxonomy/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,59 @@ export function Taxonomy (http, data = {}) {
throw error(err)
}
}

/**
* @description The Publish taxonomy call initiates a job to publish a taxonomy and/or specific terms to the specified environments and locales.
* @memberof Taxonomy
* @func publish
* @param {Object} data - Publish details
* @param {string} [api_version=''] - Optional API version (e.g., '3.2')
* @param {Object=} params - Optional query parameters. If params.branch is set, it is sent as the branch request header.
* @returns {Promise<Object>} Response object with publish job details
* @example
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client()
*
* const publishData = {
* locales: ["en-us"],
* environments: ["development"],
* items: [
* {
* uid: "taxonomy_testing",
* term_uid: "vehicles"
* },
* {
* uid: "taxonomy_testing",
* term_uid: "cars"
* }
* ]
* }
* client.stack({ api_key: 'api_key'}).taxonomy().publish(publishData, '3.2')
* .then((response) => console.log(response))
*/
this.publish = async function (data, api_version = '', params = {}) {
try {
const { branch, ...queryParams } = params
const headers = {
headers: { ...cloneDeep(this.stackHeaders) },
params: queryParams
}
if (api_version) {
headers.headers.api_version = api_version
}
if (branch) {
headers.headers.branch = branch
}
const response = await http.post(`${this.urlPath}/publish`, data, headers)
if (response.data) {
return response.data
} else {
throw error(response)
}
} catch (err) {
throw error(err)
}
}
}
}
export function TaxonomyCollection (http, data) {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"test": "npm run test:api && npm run test:unit",
"test:sanity-test": "BABEL_ENV=test nyc --reporter=html mocha --require @babel/register ./test/sanity-check/sanity.js -t 30000 --reporter mochawesome --require babel-polyfill --reporter-options reportDir=mochawesome-report,reportFilename=mochawesome.json",
"test:sanity": "npm run test:sanity-test || true",
"test:sanity-report": "marge mochawesome-report/mochawesome.json -f sanity-report.html --inline && node sanity-report.mjs",
"test:sanity-report": "node sanity-report.mjs",
"test:unit": "BABEL_ENV=test nyc --reporter=html --reporter=text mocha --require @babel/register ./test/unit/index.js -t 30000 --reporter mochawesome --require babel-polyfill",
"test:unit:report:json": "BABEL_ENV=test nyc --reporter=clover --reporter=text mocha --require @babel/register ./test/unit/index.js -t 30000 --reporter json --reporter-options output=report.json --require babel-polyfill",
"test:typescript": "jest --testPathPattern=test/typescript --config ./jest.config.js --coverage",
Expand Down
12 changes: 11 additions & 1 deletion sanity-report.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,20 @@ import Slack from '@slack/bolt'
const { App } = Slack
import dotenv from 'dotenv'
import fs from 'fs'
import { execSync } from 'child_process'
import path from 'path'

dotenv.config()

// Marge expects meta.marge.options to be an Object; mochawesome leaves it null. Patch before marge.
const reportJsonPath = path.join(process.cwd(), 'mochawesome-report', 'mochawesome.json')
const json = JSON.parse(fs.readFileSync(reportJsonPath, 'utf8'))
if (json.meta?.marge?.options == null) {
json.meta.marge.options = {}
fs.writeFileSync(reportJsonPath, JSON.stringify(json))
}
execSync('marge mochawesome-report/mochawesome.json -f sanity-report.html --inline', { stdio: 'inherit', cwd: process.cwd() })

const mochawesomeJsonOutput = fs.readFileSync('./mochawesome-report/mochawesome.json', 'utf8')
const mochawesomeReport = JSON.parse(mochawesomeJsonOutput)
const report = `./mochawesome-report/sanity-report.html`
Expand Down Expand Up @@ -58,7 +69,6 @@ async function publishMessage (text, report) {
token: process.env.SLACK_BOT_TOKEN,
channel_id: process.env.SLACK_CHANNEL_ID,
initial_comment: '*Here is the report generated*',
filetype: 'html',
filename: 'sanity-report.html',
file: fs.createReadStream(report)
})
Expand Down
36 changes: 36 additions & 0 deletions test/sanity-check/api/terms-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { describe, it, beforeEach } from 'mocha'
import { expect } from 'chai'
import { jsonReader } from '../utility/fileOperations/readwrite'
import { contentstackClient } from '../utility/ContentstackClient.js'
import { environmentCreate } from '../mock/environment.js'
import { stageBranch } from '../mock/branch.js'

var client = {}
Expand Down Expand Up @@ -42,6 +43,7 @@ describe('Terms API Test', () => {
})
it('should create taxonomy', async () => {
const response = await client.stack({ api_key: process.env.API_KEY }).taxonomy().create({ taxonomy })
await client.stack({ api_key: process.env.API_KEY }).environment().create(environmentCreate)
expect(response.uid).to.be.equal(taxonomy.uid)
await new Promise(resolve => setTimeout(resolve, 5000))
}, 10000)
Expand Down Expand Up @@ -127,6 +129,35 @@ describe('Terms API Test', () => {
.catch(done)
})

it.skip('should publish with api_version', done => {
const publishData = {
locales: ['en-us'],
environments: ['development'],
items: [
{
uid: taxonomy.uid,
term_uid: 'term_test'
},
{
uid: taxonomy.uid,
term_uid: 'term_test_child1'
},
{
uid: taxonomy.uid,
term_uid: 'term_test_child2'
}
]
}
makeTaxonomy()
.publish(publishData, '3.2')
.then((response) => {
expect(response.notice).to.not.equal(null)
expect(response.job_id).to.not.equal(undefined)
done()
})
.catch(done)
})

it('should search the term with the string passed', done => {
makeTerms(taxonomy.uid).search(termString)
.then((response) => {
Expand Down Expand Up @@ -195,6 +226,10 @@ function makeTerms (taxonomyUid, termUid = null) {
return client.stack({ api_key: process.env.API_KEY }).taxonomy(taxonomyUid).terms(termUid)
}

function makeTaxonomy () {
return client.stack({ api_key: process.env.API_KEY }).taxonomy()
}

describe('Terms Query Parameters Sanity Tests', () => {
beforeEach(async () => {
const user = jsonReader('loggedinuser.json')
Expand Down Expand Up @@ -359,6 +394,7 @@ describe('Terms Query Parameters Sanity Tests', () => {
skip: 0,
limit: 10
})
await client.stack({ api_key: process.env.API_KEY }).environment(environmentCreate.environment.name).delete()
expect(terms).to.have.property('items')
expect(terms.items).to.be.an('array')
// Count property might not be available in all environments
Expand Down
27 changes: 27 additions & 0 deletions test/unit/taxonomy-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -759,6 +759,33 @@ describe('Contentstack Taxonomy test', () => {
})
.catch(done)
})

it('Taxonomy publish test with api_version', done => {
var mock = new MockAdapter(Axios)
mock.onPost('/taxonomies/publish').reply(200, {
notice: 'Taxonomy publish job initiated successfully.',
job_id: 'job_456'
})
const publishData = {
locales: ['en-us', 'fr-fr'],
environments: ['production'],
scheduled_at: '2025-10-01T10:00:00.000Z',
items: [
{
uid: 'taxonomy_testing',
term_uid: 'vehicles'
}
]
}
makeTaxonomy()
.publish(publishData, '3.2')
.then((response) => {
expect(response.notice).to.be.equal('Taxonomy publish job initiated successfully.')
expect(response.job_id).to.be.equal('job_456')
done()
})
.catch(done)
})
})

function makeTaxonomy (data = {}) {
Expand Down
17 changes: 17 additions & 0 deletions types/stack/taxonomy/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,27 @@ export interface Taxonomy extends SystemFields, SystemFunction<Taxonomy> {

export interface Taxonomies extends Creatable<Taxonomy, {taxonomy: TaxonomyData}>, Queryable<Taxonomy, {taxonomy: TaxonomyData}> {
import(data: TaxonomyData, params?: any): Promise<Taxonomy>
publish(data: TaxonomyPublishData, api_version?: string): Promise<TaxonomyPublishResponse>
}

export interface TaxonomyData extends AnyProperty {
name: string
uid: string
description: string
}

export interface TaxonomyPublishData {
locales: Array<string>
environments: Array<string>
items: Array<TaxonomyPublishItem>
}

export interface TaxonomyPublishItem {
uid: string
term_uid: string
}

export interface TaxonomyPublishResponse extends AnyProperty {
notice?: string
job_id?: string
}
Loading