From 15dbab3f52212b54935310d791ffaffddec20b60 Mon Sep 17 00:00:00 2001 From: sunil-lakshman <104969541+sunil-lakshman@users.noreply.github.com> Date: Mon, 16 Dec 2024 12:59:38 +0530 Subject: [PATCH 1/5] Added support for nested global fields --- lib/stack/globalField/index.js | 3 +- lib/stack/index.js | 25 +- package-lock.json | 4 +- package.json | 2 +- test/sanity-check/api/globalfield-test.js | 296 +++++++++++++++------- test/sanity-check/mock/globalfield.js | 115 +++++++-- test/unit/globalField-test.js | 213 +++++++++++++++- test/unit/mock/objects.js | 91 ++++++- 8 files changed, 627 insertions(+), 122 deletions(-) diff --git a/lib/stack/globalField/index.js b/lib/stack/globalField/index.js index ad254a2a..1f4f3119 100644 --- a/lib/stack/globalField/index.js +++ b/lib/stack/globalField/index.js @@ -119,8 +119,9 @@ export function GlobalField (http, data = {}) { * .then((globalField) => console.log(globalField)) * */ - this.import = async function (data, params = {}) { + this.import = async function (data, params = {}, headers = {}) { try { + this.stackHeaders = { ...this.stackHeaders, ...headers }; const response = await upload({ http: http, urlPath: `${this.urlPath}/import`, diff --git a/lib/stack/index.js b/lib/stack/index.js index a5c0152a..2ba65286 100644 --- a/lib/stack/index.js +++ b/lib/stack/index.js @@ -159,12 +159,29 @@ export function Stack (http, data) { * * client.stack({ api_key: 'api_key'}).globalField('globalField_uid').fetch() * .then((globalField) => console.log(globalField)) + * + * client.stack({ api_key: 'api_key'}).globalField('globalField_uid', { api_version: '3.2' }).fetch() + * .then((globalField) => console.log(globalField)) + * + * client.stack({ api_key: 'api_key'}).globalField({ api_version: '3.2' }).fetch() + * .then((globalField) => console.log(globalField)) */ - this.globalField = (globalFieldUid = null) => { - const data = { stackHeaders: this.stackHeaders } - if (globalFieldUid) { - data.global_field = { uid: globalFieldUid } + this.globalField = (globalFieldUidOrOptions = null, options = {}) => { + let data = { + stackHeaders: this.stackHeaders, + }; + if (typeof globalFieldUidOrOptions === 'object' && globalFieldUidOrOptions !== null) { + options = globalFieldUidOrOptions; + } else if (globalFieldUidOrOptions) { + data.global_field = { uid: globalFieldUidOrOptions }; + } + + if (options?.api_version) { + data.api_version = options.api_version; + http.defaults.headers.api_version = data.api_version; + http.httpClientParams.headers.api_version = data.api_version; } + return new GlobalField(http, data) } diff --git a/package-lock.json b/package-lock.json index 165e7c43..cc22921a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@contentstack/management", - "version": "1.18.4", + "version": "1.19.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@contentstack/management", - "version": "1.18.4", + "version": "1.19.0", "license": "MIT", "dependencies": { "axios": "^1.7.8", diff --git a/package.json b/package.json index b7b177c8..4dbfaf46 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@contentstack/management", - "version": "1.18.4", + "version": "1.19.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", diff --git a/test/sanity-check/api/globalfield-test.js b/test/sanity-check/api/globalfield-test.js index acecd852..fdb2f9dc 100644 --- a/test/sanity-check/api/globalfield-test.js +++ b/test/sanity-check/api/globalfield-test.js @@ -11,130 +11,250 @@ dotenv.config() let client = {} let createGlobalFieldUid = '' -describe('Global Field api Test', () => { +describe("Global Field api Test", () => { setup(() => { - const user = jsonReader('loggedinuser.json') - client = contentstackClient(user.authtoken) - }) + const user = jsonReader("loggedinuser.json"); + client = contentstackClient(user.authtoken); + }); - it('should create global field', done => { - makeGlobalField().create(createGlobalField) + it("should create global field", (done) => { + makeGlobalField() + .create(createGlobalField) .then((globalField) => { - expect(globalField.uid).to.be.equal(createGlobalField.global_field.uid) - expect(globalField.title).to.be.equal(createGlobalField.global_field.title) - expect(globalField.schema[0].uid).to.be.equal(createGlobalField.global_field.schema[0].uid) - expect(globalField.schema[0].data_type).to.be.equal(createGlobalField.global_field.schema[0].data_type) - expect(globalField.schema[0].display_name).to.be.equal(createGlobalField.global_field.schema[0].display_name) - done() + expect(globalField.uid).to.be.equal(createGlobalField.global_field.uid); + expect(globalField.title).to.be.equal( + createGlobalField.global_field.title + ); + expect(globalField.schema[0].uid).to.be.equal( + createGlobalField.global_field.schema[0].uid + ); + expect(globalField.schema[0].data_type).to.be.equal( + createGlobalField.global_field.schema[0].data_type + ); + expect(globalField.schema[0].display_name).to.be.equal( + createGlobalField.global_field.schema[0].display_name + ); + done(); }) - .catch(done) - }) + .catch(done); + }); - it('should fetch global Field', done => { - makeGlobalField(createGlobalField.global_field.uid).fetch() + it("should fetch global Field", (done) => { + makeGlobalField(createGlobalField.global_field.uid) + .fetch() .then((globalField) => { - expect(globalField.uid).to.be.equal(createGlobalField.global_field.uid) - expect(globalField.title).to.be.equal(createGlobalField.global_field.title) - expect(globalField.schema[0].uid).to.be.equal(createGlobalField.global_field.schema[0].uid) - expect(globalField.schema[0].data_type).to.be.equal(createGlobalField.global_field.schema[0].data_type) - expect(globalField.schema[0].display_name).to.be.equal(createGlobalField.global_field.schema[0].display_name) - done() + expect(globalField.uid).to.be.equal(createGlobalField.global_field.uid); + expect(globalField.title).to.be.equal( + createGlobalField.global_field.title + ); + expect(globalField.schema[0].uid).to.be.equal( + createGlobalField.global_field.schema[0].uid + ); + expect(globalField.schema[0].data_type).to.be.equal( + createGlobalField.global_field.schema[0].data_type + ); + expect(globalField.schema[0].display_name).to.be.equal( + createGlobalField.global_field.schema[0].display_name + ); + done(); }) - .catch(done) - }) + .catch(done); + }); - it('should fetch and update global Field', done => { - makeGlobalField(createGlobalField.global_field.uid).fetch() + it("should fetch and update global Field", (done) => { + makeGlobalField(createGlobalField.global_field.uid) + .fetch() .then((globalField) => { - globalField.title = 'Update title' - return globalField.update() + globalField.title = "Update title"; + return globalField.update(); }) .then((updateGlobal) => { - expect(updateGlobal.uid).to.be.equal(createGlobalField.global_field.uid) - expect(updateGlobal.title).to.be.equal('Update title') - expect(updateGlobal.schema[0].uid).to.be.equal(createGlobalField.global_field.schema[0].uid) - expect(updateGlobal.schema[0].data_type).to.be.equal(createGlobalField.global_field.schema[0].data_type) - expect(updateGlobal.schema[0].display_name).to.be.equal(createGlobalField.global_field.schema[0].display_name) - done() + expect(updateGlobal.uid).to.be.equal( + createGlobalField.global_field.uid + ); + expect(updateGlobal.title).to.be.equal("Update title"); + expect(updateGlobal.schema[0].uid).to.be.equal( + createGlobalField.global_field.schema[0].uid + ); + expect(updateGlobal.schema[0].data_type).to.be.equal( + createGlobalField.global_field.schema[0].data_type + ); + expect(updateGlobal.schema[0].display_name).to.be.equal( + createGlobalField.global_field.schema[0].display_name + ); + done(); }) - .catch(done) - }) + .catch(done); + }); - it('should update global Field', done => { - const globalField = makeGlobalField(createGlobalField.global_field.uid) - Object.assign(globalField, cloneDeep(createGlobalField.global_field)) - globalField.update() + it("should update global Field", (done) => { + const globalField = makeGlobalField(createGlobalField.global_field.uid); + Object.assign(globalField, cloneDeep(createGlobalField.global_field)); + globalField + .update() .then((updateGlobal) => { - expect(updateGlobal.uid).to.be.equal(createGlobalField.global_field.uid) - expect(updateGlobal.title).to.be.equal(createGlobalField.global_field.title) - expect(updateGlobal.schema[0].uid).to.be.equal(createGlobalField.global_field.schema[0].uid) - expect(updateGlobal.schema[0].data_type).to.be.equal(createGlobalField.global_field.schema[0].data_type) - expect(updateGlobal.schema[0].display_name).to.be.equal(createGlobalField.global_field.schema[0].display_name) - done() + expect(updateGlobal.uid).to.be.equal( + createGlobalField.global_field.uid + ); + expect(updateGlobal.title).to.be.equal( + createGlobalField.global_field.title + ); + expect(updateGlobal.schema[0].uid).to.be.equal( + createGlobalField.global_field.schema[0].uid + ); + expect(updateGlobal.schema[0].data_type).to.be.equal( + createGlobalField.global_field.schema[0].data_type + ); + expect(updateGlobal.schema[0].display_name).to.be.equal( + createGlobalField.global_field.schema[0].display_name + ); + done(); }) - .catch(done) - }) + .catch(done); + }); - it('should import global Field', done => { - makeGlobalField().import({ - global_field: path.join(__dirname, '../mock/globalfield.json') - }) + it("should import global Field", (done) => { + makeGlobalField() + .import({ + global_field: path.join(__dirname, "../mock/globalfield.json"), + }) .then((response) => { - createGlobalFieldUid = response.uid - expect(response.uid).to.be.not.equal(null) - done() + createGlobalFieldUid = response.uid; + expect(response.uid).to.be.not.equal(null); + done(); }) - .catch(done) - }) + .catch(done); + }); - it('should get all global field from Query', done => { - makeGlobalField().query() + it("should get all global field from Query", (done) => { + makeGlobalField() + .query() .find() .then((collection) => { - collection.items.forEach(globalField => { - expect(globalField.uid).to.be.not.equal(null) - expect(globalField.title).to.be.not.equal(null) - expect(globalField.schema).to.be.not.equal(null) - }) - done() + collection.items.forEach((globalField) => { + expect(globalField.uid).to.be.not.equal(null); + expect(globalField.title).to.be.not.equal(null); + expect(globalField.schema).to.be.not.equal(null); + }); + done(); }) - .catch(done) - }) + .catch(done); + }); - it('should get global field title matching Upload', done => { - makeGlobalField().query({ query: { title: 'Upload' } }) + it("should get global field title matching Upload", (done) => { + makeGlobalField() + .query({ query: { title: "Upload" } }) .find() .then((collection) => { - collection.items.forEach(globalField => { - expect(globalField.uid).to.be.not.equal(null) - expect(globalField.title).to.be.equal('Upload') + collection.items.forEach((globalField) => { + expect(globalField.uid).to.be.not.equal(null); + expect(globalField.title).to.be.equal("Upload"); + }); + done(); + }) + .catch(done); + }); + + it("should get all nested global field from Query", (done) => { + makeGlobalField({ api_version: "3.2" }) + .query() + .find() + .then((collection) => { + collection.items.forEach((globalField) => { + expect(globalField.uid).to.be.not.equal(null); + expect(globalField.title).to.be.not.equal(null); + expect(globalField.schema).to.be.not.equal(null); + }); + done(); + }) + .catch(done); + }); + + it('should create nested global field', done => { + const payload = { + global_field: { + title: 'Nested Global Field', + uid: 'nested_global_field222', + schema: [ + { data_type: 'text', display_name: 'Single Line Textbox', uid: 'single_line' }, + { data_type: 'global_field', display_name: 'Global', uid: 'global_field', reference_to: 'first' }, + ], + }, + }; + + makeGlobalField({ api_version: '3.2' }).create(payload) + .then(globalField => { + console.log('Response:', globalField); + expect(globalField.uid).to.be.equal(payload.global_field.uid); + done(); + }) + .catch(err => { + console.error('Error:', err.response?.data || err.message); + done(err); + }); + }); + + it('should fetch nested global field', done => { + makeGlobalField('nested_global_field222').fetch() + .then(globalField => { + console.log('Response:', globalField); + expect(globalField.uid).to.be.equal('nested_global_field222'); + done(); }) - done() + .catch(err => { + console.error('Error:', err.response?.data || err.message); + done(err); + }); + }); + + it("should delete nested global field", (done) => { + makeGlobalField("nested_global_field222") + .delete() + .then((data) => { + console.log("Response:", data); + expect(data.notice).to.be.equal("Global Field deleted successfully."); + done(); }) - .catch(done) - }) + .catch((err) => { + console.error("Error:", err.response?.data || err.message); + done(err); + }); + }); - it('should delete global Field', done => { + it("should delete global Field", (done) => { makeGlobalField(createGlobalField.global_field.uid) .delete() .then((data) => { - expect(data.notice).to.be.equal('Global Field deleted successfully.') - done() + expect(data.notice).to.be.equal("Global Field deleted successfully."); + done(); }) - .catch(done) - }) + .catch(done); + }); - it('should delete imported global Field', done => { + it("should delete imported global Field", (done) => { makeGlobalField(createGlobalFieldUid) .delete() .then((data) => { - expect(data.notice).to.be.equal('Global Field deleted successfully.') - done() + expect(data.notice).to.be.equal("Global Field deleted successfully."); + done(); }) - .catch(done) - }) -}) + .catch(done); + }); +}); + +function makeGlobalField(globalFieldUid = null, options = {}) { + let uid = null; + let finalOptions = options; + // If globalFieldUid is an object, treat it as options + if (typeof globalFieldUid === "object") { + finalOptions = globalFieldUid; + } else { + uid = globalFieldUid; + } + // Ensure finalOptions is always an object with default values + finalOptions = finalOptions || {}; -function makeGlobalField (uid = null) { - return client.stack({ api_key: process.env.API_KEY }).globalField(uid) + return client + .stack({ api_key: process.env.API_KEY }) + .globalField(uid, finalOptions); } diff --git a/test/sanity-check/mock/globalfield.js b/test/sanity-check/mock/globalfield.js index 22f07718..fb15219b 100644 --- a/test/sanity-check/mock/globalfield.js +++ b/test/sanity-check/mock/globalfield.js @@ -1,28 +1,95 @@ const createGlobalField = { global_field: { - title: 'First', - uid: 'first', - schema: [{ - display_name: 'Name', - uid: 'name', - data_type: 'text' - }, { - data_type: 'text', - display_name: 'Rich text editor', - uid: 'description', - field_metadata: { - allow_rich_text: true, - description: '', - multiline: false, - rich_text_type: 'advanced', - options: [], - version: 3 + title: "First", + uid: "first", + schema: [ + { + display_name: "Name", + uid: "name", + data_type: "text", }, - multiple: false, - mandatory: false, - unique: false - }] - } -} + { + data_type: "text", + display_name: "Rich text editor", + uid: "description", + field_metadata: { + allow_rich_text: true, + description: "", + multiline: false, + rich_text_type: "advanced", + options: [], + version: 3, + }, + multiple: false, + mandatory: false, + unique: false, + }, + ], + }, +}; + +const createNestedGlobalField = { + global_field: { + title: "Nested Global Field", + uid: "nested_global_field222", + description: "", + schema: [ + { + data_type: "text", + display_name: "Single Line Textbox", + uid: "single_line", + field_metadata: { + description: "", + default_value: "", + version: 3, + }, + format: "", + error_messages: { + format: "", + }, + mandatory: false, + multiple: false, + non_localizable: false, + unique: false, + indexed: false, + inbuilt_model: false, + }, + { + data_type: "global_field", + display_name: "Global", + reference_to: "first", + field_metadata: { + description: "", + }, + uid: "global_field", + mandatory: false, + multiple: false, + non_localizable: false, + unique: false, + indexed: false, + inbuilt_model: false, + }, + ], + referred_content_types: [ + { + uid: "first", + title: "First", + }, + ], + global_field_refs: [ + { + uid: "first", + occurrence_count: 3, + isChild: true, + paths: ["schema.1", "schema.3.schema.4", "schema.4.blocks.0.schema.2"], + }, + { + uid: "first", + occurrence_count: 1, + isChild: false, + }, + ], + }, +}; -export { createGlobalField } +export { createGlobalField, createNestedGlobalField }; diff --git a/test/unit/globalField-test.js b/test/unit/globalField-test.js index 0dae7502..744f51c8 100644 --- a/test/unit/globalField-test.js +++ b/test/unit/globalField-test.js @@ -3,7 +3,7 @@ import Axios from 'axios' import { expect } from 'chai' import { describe, it } from 'mocha' import { GlobalField, GlobalFieldCollection, createFormData } from '../../lib/stack/globalField' -import { systemUidMock, checkSystemFields, globalFieldMock, stackHeadersMock, noticeMock } from './mock/objects' +import { systemUidMock, checkSystemFields, globalFieldMock, stackHeadersMock, noticeMock, nestedGlobalFieldMock, nestedGlobalFieldPayload } from './mock/objects' import MockAdapter from 'axios-mock-adapter' describe('Contentstack GlobalField test', () => { @@ -209,6 +209,217 @@ describe('Contentstack GlobalField test', () => { }) }) +describe('Contentstack GlobalField test (API Version 3.2)', () => { + it('GlobalField test without uid', done => { + const globalField = makeGlobalField({ api_version: '3.2' }) + expect(globalField.urlPath).to.be.equal('/global_fields') + expect(globalField.apiVersion).to.be.equal('3.2') + expect(globalField.stackHeaders).to.be.equal(undefined) + expect(globalField.update).to.be.equal(undefined) + expect(globalField.delete).to.be.equal(undefined) + expect(globalField.fetch).to.be.equal(undefined) + expect(globalField.create).to.not.equal(undefined) + expect(globalField.query).to.not.equal(undefined) + done() + }) + + it('GlobalField test with uid', done => { + const globalField = makeGlobalField({ + global_field: { + ...systemUidMock + }, + api_version: '3.2' + }) + expect(globalField.urlPath).to.be.equal(`/global_fields/${systemUidMock.uid}`) + expect(globalField.apiVersion).to.be.equal('3.2') + expect(globalField.update).to.not.equal(undefined) + expect(globalField.delete).to.not.equal(undefined) + expect(globalField.fetch).to.not.equal(undefined) + expect(globalField.create).to.be.equal(undefined) + expect(globalField.query).to.be.equal(undefined) + done() + }) + + it('GlobalField test with Stack Headers', done => { + const globalField = makeGlobalField({ + global_field: { + ...systemUidMock + }, + stackHeaders: stackHeadersMock, + api_version: '3.2' + }) + expect(globalField.urlPath).to.be.equal(`/global_fields/${systemUidMock.uid}`) + expect(globalField.apiVersion).to.be.equal('3.2') + expect(globalField.stackHeaders).to.not.equal(undefined) + expect(globalField.stackHeaders.api_key).to.be.equal(stackHeadersMock.api_key) + expect(globalField.update).to.not.equal(undefined) + expect(globalField.delete).to.not.equal(undefined) + expect(globalField.fetch).to.not.equal(undefined) + expect(globalField.create).to.be.equal(undefined) + expect(globalField.query).to.be.equal(undefined) + done() + }) + + it('GlobalField Collection test with blank data', done => { + const globalFields = new GlobalFieldCollection(Axios, { api_version: '3.2' }) + expect(globalFields.length).to.be.equal(0) + done() + }) + + it('GlobalField Collection test with data', done => { + const globalFields = new GlobalFieldCollection(Axios, { + global_fields: [ + nestedGlobalFieldMock + ], + api_version: '3.2' + }) + expect(globalFields.length).to.be.equal(1) + checkGlobalField(globalFields[0]) + done() + }) + + it('GlobalField create test', done => { + var mock = new MockAdapter(Axios) + mock.onPost('/global_fields').reply(200, { + global_field: { + ...nestedGlobalFieldMock + } + }) + makeGlobalField({ api_version: '3.2' }) + .create() + .then((globalField) => { + checkGlobalField(globalField) + done() + }) + .catch(done) + }) + + it('GlobalField Query test', done => { + var mock = new MockAdapter(Axios) + mock.onGet('/global_fields').reply(200, { + global_fields: [ + nestedGlobalFieldMock + ] + }) + makeGlobalField({ api_version: '3.2' }) + .query() + .find() + .then((globalField) => { + checkGlobalField(globalField.items[0]) + done() + }) + .catch(done) + }) + + it('GlobalField update test', done => { + var mock = new MockAdapter(Axios) + mock.onPut('/global_fields/UID').reply(200, { + global_field: { + ...nestedGlobalFieldMock + } + }) + makeGlobalField({ + global_field: { + ...systemUidMock + }, + stackHeaders: stackHeadersMock, + api_version: '3.2' + }) + .update() + .then((globalField) => { + checkGlobalField(globalField) + done() + }) + .catch(done) + }) + + it('GlobalField fetch test', done => { + var mock = new MockAdapter(Axios) + mock.onGet('/global_fields/UID').reply(200, { + global_field: { + ...nestedGlobalFieldMock + } + }) + makeGlobalField({ + global_field: { + ...systemUidMock + }, + stackHeaders: stackHeadersMock, + api_version: '3.2' + }) + .fetch() + .then((globalField) => { + checkGlobalField(globalField) + done() + }) + .catch(done) + }) + + it('GlobalField delete test', done => { + var mock = new MockAdapter(Axios) + mock.onDelete('/global_fields/UID').reply(200, { + ...noticeMock + }) + makeGlobalField({ + global_field: { + ...systemUidMock + }, + stackHeaders: stackHeadersMock, + api_version: '3.2' + }) + .delete() + .then((response) => { + expect(response.notice).to.be.equal(noticeMock.notice) + done() + }) + .catch(done) + }) + + it('GlobalField import test', done => { + var mock = new MockAdapter(Axios) + mock.onPost('/global_fields/import').reply(200, { + global_field: { + ...globalFieldMock + } + }) + const gfUpload = { global_field: path.join(__dirname, '../api/mock/globalfield.json') } + const form = createFormData(gfUpload)() + var boundary = form.getBoundary() + + expect(boundary).to.be.equal(form.getBoundary()) + expect(boundary.length).to.be.equal(50) + makeGlobalField({ api_version: '3.2' }) + .import() + .then((webhook) => { + checkGlobalField(webhook) + done() + }) + .catch(done) + }) + + it('GlobalField import test with overwrite flag', done => { + var mock = new MockAdapter(Axios) + mock.onPost('/global_fields/import').reply(200, { + global_field: { + ...nestedGlobalFieldMock + } + }) + const gfUpload = { global_field: path.join(__dirname, '../api/mock/globalfield.json') } + const form = createFormData(gfUpload)() + var boundary = form.getBoundary() + + expect(boundary).to.be.equal(form.getBoundary()) + expect(boundary.length).to.be.equal(50) + makeGlobalField({ api_version: '3.2' }) + .import(gfUpload, { overwrite: true }) + .then((webhook) => { + checkGlobalField(webhook) + done() + }) + .catch(done) + }) +}) + function makeGlobalField (data) { return new GlobalField(Axios, data) } diff --git a/test/unit/mock/objects.js b/test/unit/mock/objects.js index 4071e8a6..11e0e291 100644 --- a/test/unit/mock/objects.js +++ b/test/unit/mock/objects.js @@ -431,6 +431,93 @@ const globalFieldMock = { ] } +const nestedGlobalFieldMock = { + ...systemFieldsMock, + ...systemFieldsUserMock, + title: 'title', + schema: + [ + { + display_name: 'Title', + uid: 'title', + data_type: 'text', + mandatory: true, + unique: true, + field_metadata: + { + _default: true + } + }, + { + display_name: 'URL', + uid: 'url', + data_type: 'text', + mandatory: false, + field_metadata: + { + _default: true + } + } + ] +} +const nestedGlobalFieldPayload = { + global_field: { + title: 'Nested Global Field 12345', + uid: 'nested_global_field_12345', + description: '', + schema: [ + { + data_type: 'text', + display_name: 'Single Line Textbox', + uid: 'single_line', + field_metadata: { + description: '', + default_value: '', + version: 3, + }, + format: '', + error_messages: { + format: '', + }, + mandatory: false, + multiple: false, + non_localizable: false, + unique: false, + }, + { + data_type: 'global_field', + display_name: 'Global', + reference_to: 'nested_global_field1234', + field_metadata: { + description: '', + }, + uid: 'global_field', + mandatory: false, + multiple: false, + non_localizable: false, + unique: false, + }, + ], + global_field_refs: [ + { + uid: 'nested_global_field_1234', + occurrence_count: 3, + isChild: true, + paths: [ + 'schema.1', + 'schema.3.schema.4', + 'schema.4.blocks.0.schema.2', + ], + }, + { + uid: 'nested_global_field_123', + occurrence_count: 1, + isChild: false, + }, + ], + }, +} + const entryMock = { ...systemFieldsMock, ...systemFieldsUserMock, @@ -1191,5 +1278,7 @@ export { variantBaseEntryMock, roleMockWithTaxonomy, varinatsEntryMock, - variantEntryVersion + variantEntryVersion, + nestedGlobalFieldMock, + nestedGlobalFieldPayload } From cfcad6da0329631629d4d320576335a47442812a Mon Sep 17 00:00:00 2001 From: sunil-lakshman <104969541+sunil-lakshman@users.noreply.github.com> Date: Mon, 16 Dec 2024 19:05:05 +0530 Subject: [PATCH 2/5] Added updated method --- lib/entity.js | 4 ++ lib/stack/globalField/index.js | 55 +++++++++++++++++++++++ lib/stack/index.js | 5 ++- test/sanity-check/api/globalfield-test.js | 39 +++++++--------- 4 files changed, 79 insertions(+), 24 deletions(-) diff --git a/lib/entity.js b/lib/entity.js index a1d55a23..5206e474 100644 --- a/lib/entity.js +++ b/lib/entity.js @@ -71,6 +71,10 @@ export const upload = async ({ http, urlPath, stackHeaders, formData, params, me export const create = ({ http, params }) => { return async function (data, param) { + this.stackHeaders = { + ...this.stackHeaders, + ...(http.httpClientParams.headers?.api_version && { api_version: http.httpClientParams.headers.api_version }) + }; const headers = { headers: { ...cloneDeep(params), diff --git a/lib/stack/globalField/index.js b/lib/stack/globalField/index.js index 1f4f3119..dba00ef8 100644 --- a/lib/stack/globalField/index.js +++ b/lib/stack/globalField/index.js @@ -11,6 +11,12 @@ import { createReadStream } from 'fs' export function GlobalField (http, data = {}) { this.stackHeaders = data.stackHeaders + this.apiVersion = data.api_version || undefined; + + if (this.apiVersion) { + http.defaults.headers.api_version = this.apiVersion; + http.httpClientParams.headers.api_version = this.apiVersion; + } this.urlPath = `/global_fields` if (data.global_field) { @@ -36,6 +42,55 @@ export function GlobalField (http, data = {}) { */ this.update = update(http, 'global_field') + /** + * @description The Update GlobalField call lets you update the name and description of an existing GlobalField. + * @memberof GlobalField + * @func update + * @returns {Promise} Promise for GlobalField instance + * @example + * import * as contentstack from '@contentstack/management' + * const client = contentstack.client() + * const data = { + * "global_field": { + * "title": "Nested Global Field33", + * "uid": "nested_global_field33", + * "schema": [ + * { + * "data_type": "text", + * "display_name": "Single Line Textbox", + * "uid": "single_line" + * }, + * { + * "data_type": "global_field", + * "display_name": "Global", + * "uid": "global_field", + * "reference_to": "nested_global_field_123" + * } + * ] + * } + * } + * client.stack({ api_key: 'api_key'}).globalField('global_field_uid').updateNestedGlobalField(data, { headers: { api_version: '3.3' }}) + * .then((globalField) => { + console.log(globalField) + * }) + */ + this.updateNestedGlobalField = async (config, headers={}) => { + this.stackHeaders = {api_version: '3.2' } + try { + const headers = { + headers: { ...cloneDeep(this.stackHeaders) } + } + const response = await http.put(`${this.urlPath}`, config, headers) + if (response.data) { + return response.data + } else { + throw error(response) + } + } catch (err) { + throw error(err) + } + } + /** * @description The Delete GlobalField call is used to delete an existing GlobalField permanently from your Stack. * @memberof GlobalField diff --git a/lib/stack/index.js b/lib/stack/index.js index 2ba65286..4f71ada6 100644 --- a/lib/stack/index.js +++ b/lib/stack/index.js @@ -178,8 +178,9 @@ export function Stack (http, data) { if (options?.api_version) { data.api_version = options.api_version; - http.defaults.headers.api_version = data.api_version; - http.httpClientParams.headers.api_version = data.api_version; + if (options.api_version === '3.2') { + data.nested_global_fields = true; + } } return new GlobalField(http, data) diff --git a/test/sanity-check/api/globalfield-test.js b/test/sanity-check/api/globalfield-test.js index fdb2f9dc..669e3cf4 100644 --- a/test/sanity-check/api/globalfield-test.js +++ b/test/sanity-check/api/globalfield-test.js @@ -3,7 +3,7 @@ import { expect } from 'chai' import { cloneDeep } from 'lodash' import { describe, it, setup } from 'mocha' import { jsonReader } from '../utility/fileOperations/readwrite' -import { createGlobalField } from '../mock/globalfield' +import { createGlobalField, createNestedGlobalField } from '../mock/globalfield' import { contentstackClient } from '../utility/ContentstackClient.js' import dotenv from 'dotenv' @@ -155,8 +155,8 @@ describe("Global Field api Test", () => { .catch(done); }); - it("should get all nested global field from Query", (done) => { - makeGlobalField({ api_version: "3.2" }) + it("should get all nested global fields from Query", (done) => { + makeGlobalField({ api_version: '3.2' }) .query() .find() .then((collection) => { @@ -171,18 +171,7 @@ describe("Global Field api Test", () => { }); it('should create nested global field', done => { - const payload = { - global_field: { - title: 'Nested Global Field', - uid: 'nested_global_field222', - schema: [ - { data_type: 'text', display_name: 'Single Line Textbox', uid: 'single_line' }, - { data_type: 'global_field', display_name: 'Global', uid: 'global_field', reference_to: 'first' }, - ], - }, - }; - - makeGlobalField({ api_version: '3.2' }).create(payload) + makeGlobalField({ api_version: '3.2' }).create(createNestedGlobalField) .then(globalField => { console.log('Response:', globalField); expect(globalField.uid).to.be.equal(payload.global_field.uid); @@ -195,7 +184,7 @@ describe("Global Field api Test", () => { }); it('should fetch nested global field', done => { - makeGlobalField('nested_global_field222').fetch() + makeGlobalField('nested_global_field333', { api_version: '3.2' }).fetch() .then(globalField => { console.log('Response:', globalField); expect(globalField.uid).to.be.equal('nested_global_field222'); @@ -207,8 +196,18 @@ describe("Global Field api Test", () => { }); }); + it('should update nested global fields without fetch', done => { + makeGlobalField(createNestedGlobalField.global_field.uid, { headers: { api_version: '3.2' }}) + .updateNestedGlobalField(createNestedGlobalField) + .then((globalField) => { + expect(globalField.global_field.schema.length).to.be.equal(2) + done() + }) + .catch(done) + }) + it("should delete nested global field", (done) => { - makeGlobalField("nested_global_field222") + makeGlobalField("nested_global_field333", { api_version: '3.2' }) .delete() .then((data) => { console.log("Response:", data); @@ -245,16 +244,12 @@ describe("Global Field api Test", () => { function makeGlobalField(globalFieldUid = null, options = {}) { let uid = null; let finalOptions = options; - // If globalFieldUid is an object, treat it as options if (typeof globalFieldUid === "object") { finalOptions = globalFieldUid; } else { uid = globalFieldUid; } - // Ensure finalOptions is always an object with default values finalOptions = finalOptions || {}; - return client - .stack({ api_key: process.env.API_KEY }) - .globalField(uid, finalOptions); + .stack({ api_key: process.env.API_KEY }).globalField(uid, finalOptions); } From 7e97085f625c910bf53207e7388d6e94b7caf310 Mon Sep 17 00:00:00 2001 From: sunil-lakshman <104969541+sunil-lakshman@users.noreply.github.com> Date: Tue, 17 Dec 2024 14:50:43 +0530 Subject: [PATCH 3/5] Added update method testcases --- lib/stack/globalField/index.js | 3 +- test/sanity-check/api/globalfield-test.js | 40 ++++++++++++++++++----- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/lib/stack/globalField/index.js b/lib/stack/globalField/index.js index dba00ef8..f5af05d0 100644 --- a/lib/stack/globalField/index.js +++ b/lib/stack/globalField/index.js @@ -75,7 +75,8 @@ export function GlobalField (http, data = {}) { * }) */ this.updateNestedGlobalField = async (config, headers={}) => { - this.stackHeaders = {api_version: '3.2' } + const apiVersion = {api_version: '3.2' } + this.stackHeaders = {...this.stackHeaders, ...apiVersion, ...headers} try { const headers = { headers: { ...cloneDeep(this.stackHeaders) } diff --git a/test/sanity-check/api/globalfield-test.js b/test/sanity-check/api/globalfield-test.js index 669e3cf4..638f592b 100644 --- a/test/sanity-check/api/globalfield-test.js +++ b/test/sanity-check/api/globalfield-test.js @@ -3,14 +3,13 @@ import { expect } from 'chai' import { cloneDeep } from 'lodash' import { describe, it, setup } from 'mocha' import { jsonReader } from '../utility/fileOperations/readwrite' -import { createGlobalField, createNestedGlobalField } from '../mock/globalfield' +import { createGlobalField, createNestedGlobalField, createNestedGlobalFieldForReference } from '../mock/globalfield' import { contentstackClient } from '../utility/ContentstackClient.js' import dotenv from 'dotenv' dotenv.config() let client = {} let createGlobalFieldUid = '' - describe("Global Field api Test", () => { setup(() => { const user = jsonReader("loggedinuser.json"); @@ -170,11 +169,23 @@ describe("Global Field api Test", () => { .catch(done); }); + + it('should create nested global field for reference', done => { + makeGlobalField({ api_version: '3.2' }).create(createNestedGlobalFieldForReference) + .then(globalField => { + expect(globalField.uid).to.be.equal(createNestedGlobalFieldForReference.global_field.uid); + done(); + }) + .catch(err => { + console.error('Error:', err.response?.data || err.message); + done(err); + }); + }); + it('should create nested global field', done => { makeGlobalField({ api_version: '3.2' }).create(createNestedGlobalField) .then(globalField => { - console.log('Response:', globalField); - expect(globalField.uid).to.be.equal(payload.global_field.uid); + expect(globalField.uid).to.be.equal(createNestedGlobalField.global_field.uid); done(); }) .catch(err => { @@ -184,10 +195,9 @@ describe("Global Field api Test", () => { }); it('should fetch nested global field', done => { - makeGlobalField('nested_global_field333', { api_version: '3.2' }).fetch() + makeGlobalField(createNestedGlobalField.global_field.uid, { api_version: '3.2' }).fetch() .then(globalField => { - console.log('Response:', globalField); - expect(globalField.uid).to.be.equal('nested_global_field222'); + expect(globalField.uid).to.be.equal(createNestedGlobalField.global_field.uid); done(); }) .catch(err => { @@ -207,10 +217,22 @@ describe("Global Field api Test", () => { }) it("should delete nested global field", (done) => { - makeGlobalField("nested_global_field333", { api_version: '3.2' }) + makeGlobalField(createNestedGlobalField.global_field.uid, { api_version: '3.2' }) + .delete() + .then((data) => { + expect(data.notice).to.be.equal("Global Field deleted successfully."); + done(); + }) + .catch((err) => { + console.error("Error:", err.response?.data || err.message); + done(err); + }); + }); + + it("should delete nested global reference field", (done) => { + makeGlobalField(createNestedGlobalFieldForReference.global_field.uid, { api_version: '3.2' }) .delete() .then((data) => { - console.log("Response:", data); expect(data.notice).to.be.equal("Global Field deleted successfully."); done(); }) From a47ff36db40392ae76fcb6766d3540758701d4c0 Mon Sep 17 00:00:00 2001 From: sunil-lakshman <104969541+sunil-lakshman@users.noreply.github.com> Date: Tue, 17 Dec 2024 14:51:08 +0530 Subject: [PATCH 4/5] Added mock file --- test/sanity-check/mock/globalfield.js | 102 ++++++++++---------------- 1 file changed, 39 insertions(+), 63 deletions(-) diff --git a/test/sanity-check/mock/globalfield.js b/test/sanity-check/mock/globalfield.js index fb15219b..ef1d3ec0 100644 --- a/test/sanity-check/mock/globalfield.js +++ b/test/sanity-check/mock/globalfield.js @@ -29,67 +29,43 @@ const createGlobalField = { }; const createNestedGlobalField = { - global_field: { - title: "Nested Global Field", - uid: "nested_global_field222", - description: "", - schema: [ - { - data_type: "text", - display_name: "Single Line Textbox", - uid: "single_line", - field_metadata: { - description: "", - default_value: "", - version: 3, - }, - format: "", - error_messages: { - format: "", - }, - mandatory: false, - multiple: false, - non_localizable: false, - unique: false, - indexed: false, - inbuilt_model: false, - }, - { - data_type: "global_field", - display_name: "Global", - reference_to: "first", - field_metadata: { - description: "", - }, - uid: "global_field", - mandatory: false, - multiple: false, - non_localizable: false, - unique: false, - indexed: false, - inbuilt_model: false, - }, - ], - referred_content_types: [ - { - uid: "first", - title: "First", - }, - ], - global_field_refs: [ - { - uid: "first", - occurrence_count: 3, - isChild: true, - paths: ["schema.1", "schema.3.schema.4", "schema.4.blocks.0.schema.2"], - }, - { - uid: "first", - occurrence_count: 1, - isChild: false, - }, - ], - }, -}; + "global_field": { + "title": "Nested Global Fields9", + "uid": "nested_global_field9", + "schema": [ + { + "data_type": "text", + "display_name": "Single Line Textbox", + "uid": "single_line" + }, + { + "data_type": "global_field", + "display_name": "Global", + "uid": "global_field", + "reference_to": "nested_global_field33" + } + ] + } +} + +const createNestedGlobalFieldForReference = { + "global_field": { + "title": "nested global field for reference", + "uid": "nested_global_field33", + "schema": [ + { + "data_type": "text", + "display_name": "Single Line Textbox", + "uid": "single_line" + }, + { + "data_type": "global_field", + "display_name": "Global", + "uid": "global_field", + "reference_to": "first" + } + ] + } +} -export { createGlobalField, createNestedGlobalField }; +export { createGlobalField, createNestedGlobalField, createNestedGlobalFieldForReference }; From ff4a22d469cd9f134c11a6a865778deb02a44257 Mon Sep 17 00:00:00 2001 From: sunil-lakshman <104969541+sunil-lakshman@users.noreply.github.com> Date: Tue, 17 Dec 2024 16:06:01 +0530 Subject: [PATCH 5/5] Fixed PR comments --- lib/stack/globalField/index.js | 2 +- lib/stack/index.js | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/stack/globalField/index.js b/lib/stack/globalField/index.js index f5af05d0..2389c0ba 100644 --- a/lib/stack/globalField/index.js +++ b/lib/stack/globalField/index.js @@ -69,7 +69,7 @@ export function GlobalField (http, data = {}) { * ] * } * } - * client.stack({ api_key: 'api_key'}).globalField('global_field_uid').updateNestedGlobalField(data, { headers: { api_version: '3.3' }}) + * client.stack({ api_key: 'api_key'}).globalField('global_field_uid').updateNestedGlobalField(data, { headers: { api_version: '3.2' }}) * .then((globalField) => { console.log(globalField) * }) diff --git a/lib/stack/index.js b/lib/stack/index.js index 4f71ada6..4bb62a46 100644 --- a/lib/stack/index.js +++ b/lib/stack/index.js @@ -163,8 +163,6 @@ export function Stack (http, data) { * client.stack({ api_key: 'api_key'}).globalField('globalField_uid', { api_version: '3.2' }).fetch() * .then((globalField) => console.log(globalField)) * - * client.stack({ api_key: 'api_key'}).globalField({ api_version: '3.2' }).fetch() - * .then((globalField) => console.log(globalField)) */ this.globalField = (globalFieldUidOrOptions = null, options = {}) => { let data = {