Skip to content

Added api_version support in get job status method. #405

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

Merged
merged 4 commits into from
Jul 29, 2025
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
9 changes: 8 additions & 1 deletion lib/stack/bulkOperation/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,13 @@ export function BulkOperation (http, data = {}) {
* @returns {Promise<Object>} Response Object.
* @param {String} params.job_id - The ID of the job.
* @param {String} [params.bulk_version] - The bulk version.
* @param {String} [params.api_version] - The API version.
* @example
* client.stack({ api_key: 'api_key'}).bulkOperation().jobStatus({ job_id: 'job_id' })
* .then((response) => { console.log(response) })
*/
// eslint-disable-next-line camelcase
this.jobStatus = async ({ job_id, bulk_version = '' }) => {
this.jobStatus = async ({ job_id, bulk_version = '', api_version = '' }) => {
// eslint-disable-next-line camelcase
this.urlPath = `/bulk/jobs/${job_id}`
const headers = {
Expand All @@ -109,12 +110,18 @@ export function BulkOperation (http, data = {}) {
}
// eslint-disable-next-line camelcase
if (bulk_version) headers.headers.bulk_version = bulk_version
// eslint-disable-next-line camelcase
if (api_version) headers.headers.api_version = api_version
try {
const response = await http.get(this.urlPath, headers)
if (response.data) {
// eslint-disable-next-line camelcase
if (api_version) delete headers.headers.api_version
return response.data
}
} catch (error) {
// eslint-disable-next-line camelcase
if (api_version) delete headers.headers.api_version
console.error(error)
}
}
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@contentstack/management",
"version": "1.23.1",
"version": "1.23.2",
"description": "The Content Management API is used to manage the content of your Contentstack account",
"main": "./dist/node/contentstack-management.js",
"browser": "./dist/web/contentstack-management.js",
Expand Down
151 changes: 151 additions & 0 deletions test/sanity-check/api/bulkOperation-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,21 @@ import { describe, it, setup } from 'mocha'
import { jsonReader } from '../../sanity-check/utility/fileOperations/readwrite'
import { contentstackClient } from '../../sanity-check/utility/ContentstackClient'
import { singlepageCT, multiPageCT } from '../mock/content-type.js'
import { createManagementToken } from '../mock/managementToken.js'
import dotenv from 'dotenv'
dotenv.config()

let client = {}
let clientWithManagementToken = {}
let entryUid1 = ''
let assetUid1 = ''
let entryUid2 = ''
let assetUid2 = ''
let jobId1 = ''
let jobId2 = ''
let jobId3 = ''
let tokenUidDev = ''
let tokenUid = ''

describe('BulkOperation api test', () => {
setup(() => {
Expand All @@ -24,6 +31,22 @@ describe('BulkOperation api test', () => {
entryUid2 = entryRead2.uid
assetUid2 = assetRead2.uid
client = contentstackClient(user.authtoken)
clientWithManagementToken = contentstackClient()
})

it('should create a Management Token for get job status', done => {
makeManagementToken()
.create(createManagementToken)
.then((token) => {
tokenUidDev = token.token
tokenUid = token.uid
expect(token.name).to.be.equal(createManagementToken.token.name)
expect(token.description).to.be.equal(createManagementToken.token.description)
expect(token.scope[0].module).to.be.equal(createManagementToken.token.scope[0].module)
expect(token.uid).to.be.not.equal(null)
done()
})
.catch(done)
})

it('should publish one entry when publishDetails of an entry is passed', done => {
Expand All @@ -47,6 +70,7 @@ describe('BulkOperation api test', () => {
.then((response) => {
expect(response.notice).to.not.equal(undefined)
expect(response.job_id).to.not.equal(undefined)
jobId1 = response.job_id
done()
})
.catch(done)
Expand All @@ -71,6 +95,7 @@ describe('BulkOperation api test', () => {
.then((response) => {
expect(response.notice).to.not.equal(undefined)
expect(response.job_id).to.not.equal(undefined)
jobId2 = response.job_id
done()
})
.catch(done)
Expand Down Expand Up @@ -110,12 +135,138 @@ describe('BulkOperation api test', () => {
.then((response) => {
expect(response.notice).to.not.equal(undefined)
expect(response.job_id).to.not.equal(undefined)
jobId3 = response.job_id
done()
})
.catch(done)
})

it('should get job status for the first publish job', done => {
doBulkOperationWithManagementToken(tokenUidDev)
.jobStatus({ job_id: jobId1, api_version: '3.2' })
.then((response) => {
expect(response).to.not.equal(undefined)
expect(response.uid).to.not.equal(undefined)
expect(response.status).to.not.equal(undefined)
expect(response.action).to.not.equal(undefined)
expect(response.summary).to.not.equal(undefined)
expect(response.body).to.not.equal(undefined)
done()
})
.catch((error) => {
console.error('Job status error:', error)
done(error)
})
})

it('should validate detailed job status response structure', done => {
doBulkOperationWithManagementToken(tokenUidDev)
.jobStatus({ job_id: jobId1, api_version: '3.2' })
.then((response) => {
expect(response).to.not.equal(undefined)
// Validate main job properties
expect(response.uid).to.not.equal(undefined)
expect(response.api_key).to.not.equal(undefined)
expect(response.status).to.not.equal(undefined)

// Validate body structure
expect(response.body).to.not.equal(undefined)
expect(response.body.locales).to.be.an('array')
expect(response.body.environments).to.be.an('array')
// Validate summary structure
expect(response.summary).to.not.equal(undefined)
done()
})
.catch((error) => {
console.error('Detailed job status error:', error)
done(error)
})
})

it('should get job status for the second publish job', done => {
doBulkOperationWithManagementToken(tokenUidDev)
.jobStatus({ job_id: jobId2, api_version: '3.2' })
.then((response) => {
expect(response).to.not.equal(undefined)
expect(response.uid).to.not.equal(undefined)
expect(response.status).to.not.equal(undefined)
expect(response.action).to.not.equal(undefined)
expect(response.summary).to.not.equal(undefined)
expect(response.body).to.not.equal(undefined)
done()
})
.catch(done)
})

it('should get job status for the third publish job', done => {
doBulkOperationWithManagementToken(tokenUidDev)
.jobStatus({ job_id: jobId3, api_version: '3.2' })
.then((response) => {
expect(response).to.not.equal(undefined)
expect(response.uid).to.not.equal(undefined)
expect(response.status).to.not.equal(undefined)
expect(response.action).to.not.equal(undefined)
expect(response.summary).to.not.equal(undefined)
expect(response.body).to.not.equal(undefined)
done()
})
.catch(done)
})

it('should get job status with bulk_version parameter', done => {
doBulkOperationWithManagementToken(tokenUidDev)
.jobStatus({ job_id: jobId1, bulk_version: 'v3', api_version: '3.2' })
.then((response) => {
expect(response).to.not.equal(undefined)
expect(response.uid).to.not.equal(undefined)
expect(response.status).to.not.equal(undefined)
expect(response.action).to.not.equal(undefined)
expect(response.summary).to.not.equal(undefined)
expect(response.body).to.not.equal(undefined)
done()
})
.catch(done)
})

it('should test job status endpoint accessibility', done => {
doBulkOperationWithManagementToken(tokenUidDev)
.jobStatus({ job_id: 'test-job-id', api_version: '3.2' })
.then((response) => {
done()
})
.catch((error) => {
console.log('Job status endpoint error (expected for invalid job ID):', error.message)
// This is expected to fail with invalid job ID, but should not be an auth error
if (error.message && (error.message.includes('authentication') || error.message.includes('401'))) {
done(error)
} else {
done() // Expected error for invalid job ID
}
})
})

it('should delete a Management Token', done => {
makeManagementToken(tokenUid)
.delete()
.then((data) => {
expect(data.notice).to.be.equal('Management Token deleted successfully.')
done()
})
.catch(done)
})
})

function doBulkOperation (uid = null) {
// @ts-ignore-next-line secret-detection
return client.stack({ api_key: process.env.API_KEY }).bulkOperation()
}

function doBulkOperationWithManagementToken (tokenUidDev) {
// @ts-ignore-next-line secret-detection
return clientWithManagementToken.stack({ api_key: process.env.API_KEY, management_token: tokenUidDev }).bulkOperation()
}

function makeManagementToken (uid = null) {
// @ts-ignore-next-line secret-detection
return client.stack({ api_key: process.env.API_KEY }).managementToken(uid)
}
1 change: 1 addition & 0 deletions types/stack/bulkOperation/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,5 @@ export interface BulkAddItemsConfig {
export interface BulkJobStatus {
job_id: AnyProperty;
bulk_version?: string;
api_version?: string;
}
Loading