Skip to content

Commit c2d4562

Browse files
Merge pull request #491 from contentstack/enh/dx-3904
Added DAM 2.0 query support testcases
2 parents 811e9a2 + 2790ca6 commit c2d4562

File tree

3 files changed

+261
-1
lines changed

3 files changed

+261
-1
lines changed

README.md

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,39 @@ contentstackClient.stack({ api_key: 'API_KEY', management_token: 'MANAGEMENT_TOK
7171
console.log(contenttype)
7272
})
7373
```
74+
75+
### Host and Region Configuration
76+
You can configure the SDK to use a specific region or custom host for API requests.
77+
78+
#### Region
79+
The SDK supports multiple regions. Valid region values are: `NA`, `EU`, `AU`, `AZURE_NA`, `AZURE_EU`, `GCP_NA`, `GCP_EU`. The default region is `NA`.
80+
81+
```javascript
82+
// Use EU region
83+
contentstackClient = contentstack.client({
84+
authtoken: 'AUTHTOKEN',
85+
region: 'EU'
86+
})
87+
```
88+
89+
#### Custom Host
90+
You can specify a custom host for API requests. If both `host` and `region` are provided, the `host` parameter takes priority.
91+
92+
```javascript
93+
// Use custom host
94+
contentstackClient = contentstack.client({
95+
authtoken: 'AUTHTOKEN',
96+
host: 'api.contentstack.io'
97+
})
98+
99+
// Custom host takes priority over region
100+
contentstackClient = contentstack.client({
101+
authtoken: 'AUTHTOKEN',
102+
region: 'EU',
103+
host: 'custom-api.example.com'
104+
})
105+
```
106+
74107
### Contentstack Management JavaScript SDK: 5-minute Quickstart
75108
#### Initializing Your SDK:
76109
To use the JavaScript CMA SDK, you need to first initialize it. To do this, use the following code:
@@ -124,7 +157,7 @@ contentstackClient.stack({ api_key: 'API_KEY' }).asset().create({ asset })
124157
- [Content Management API Docs](https://www.contentstack.com/docs/developers/apis/content-management-api)
125158

126159
### The MIT License (MIT)
127-
Copyright © 2012-2025 [Contentstack](https://www.contentstack.com/). All Rights Reserved
160+
Copyright © 2012-2026 [Contentstack](https://www.contentstack.com/). All Rights Reserved
128161

129162
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
130163

test/sanity-check/api/entry-test.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,26 @@ describe('Entry api Test', () => {
4242
.catch(done)
4343
})
4444

45+
it('should entry fetch with asset_fields parameter - single value', done => {
46+
makeEntry(singlepageCT.content_type.uid, entryUTD)
47+
.fetch({ asset_fields: ['user_defined_fields'] })
48+
.then((entryResponse) => {
49+
expect(entryResponse.uid).to.be.not.equal(null)
50+
done()
51+
})
52+
.catch(done)
53+
})
54+
55+
it('should entry fetch with asset_fields parameter - multiple values', done => {
56+
makeEntry(singlepageCT.content_type.uid, entryUTD)
57+
.fetch({ asset_fields: ['user_defined_fields', 'embedded', 'ai_suggested', 'visual_markups'] })
58+
.then((entryResponse) => {
59+
expect(entryResponse.uid).to.be.not.equal(null)
60+
done()
61+
})
62+
.catch(done)
63+
})
64+
4565
it('should localize entry with title update', done => {
4666
makeEntry(singlepageCT.content_type.uid, entryUTD)
4767
.fetch()
@@ -127,6 +147,52 @@ describe('Entry api Test', () => {
127147
.catch(done)
128148
})
129149

150+
it('should get all Entry with asset_fields parameter - single value', done => {
151+
makeEntry(multiPageCT.content_type.uid)
152+
.query({ include_count: true, asset_fields: ['user_defined_fields'] }).find()
153+
.then((collection) => {
154+
expect(collection.count).to.be.equal(3)
155+
collection.items.forEach((entry) => {
156+
expect(entry.uid).to.be.not.equal(null)
157+
expect(entry.content_type_uid).to.be.equal(multiPageCT.content_type.uid)
158+
})
159+
done()
160+
})
161+
.catch(done)
162+
})
163+
164+
it('should get all Entry with asset_fields parameter - multiple values', done => {
165+
makeEntry(multiPageCT.content_type.uid)
166+
.query({ include_count: true, asset_fields: ['user_defined_fields', 'embedded', 'ai_suggested', 'visual_markups'] }).find()
167+
.then((collection) => {
168+
expect(collection.count).to.be.equal(3)
169+
collection.items.forEach((entry) => {
170+
expect(entry.uid).to.be.not.equal(null)
171+
expect(entry.content_type_uid).to.be.equal(multiPageCT.content_type.uid)
172+
})
173+
done()
174+
})
175+
.catch(done)
176+
})
177+
178+
it('should get all Entry with asset_fields parameter combined with other query params', done => {
179+
makeEntry(multiPageCT.content_type.uid)
180+
.query({
181+
include_count: true,
182+
include_content_type: true,
183+
asset_fields: ['user_defined_fields', 'embedded']
184+
}).find()
185+
.then((collection) => {
186+
expect(collection.count).to.be.equal(3)
187+
collection.items.forEach((entry) => {
188+
expect(entry.uid).to.be.not.equal(null)
189+
expect(entry.content_type_uid).to.be.equal(multiPageCT.content_type.uid)
190+
})
191+
done()
192+
})
193+
.catch(done)
194+
})
195+
130196
it('should publish Entry', done => {
131197
makeEntry(singlepageCT.content_type.uid, entryUTD)
132198
.publish({

test/unit/entry-test.js

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,97 @@ describe('Contentstack Entry test', () => {
110110
.catch(done)
111111
})
112112

113+
it('Entry Query test with asset_fields parameter - single value', done => {
114+
var mock = new MockAdapter(Axios)
115+
mock.onGet('/content_types/content_type_uid/entries', (config) => {
116+
// Check if asset_fields parameter is present in the request
117+
const assetFields = config.params && (config.params['asset_fields[]'] || config.params.asset_fields)
118+
if (Array.isArray(assetFields)) {
119+
return assetFields.includes('user_defined_fields')
120+
}
121+
// Also check URL if params are serialized
122+
if (config.url && config.url.includes('asset_fields')) {
123+
return config.url.includes('user_defined_fields')
124+
}
125+
return false
126+
}).reply(200, {
127+
entries: [
128+
entryMock
129+
]
130+
})
131+
makeEntry()
132+
.query({ asset_fields: ['user_defined_fields'] })
133+
.find()
134+
.then((entry) => {
135+
checkEntry(entry.items[0])
136+
done()
137+
})
138+
.catch(done)
139+
})
140+
141+
it('Entry Query test with asset_fields parameter - multiple values', done => {
142+
var mock = new MockAdapter(Axios)
143+
mock.onGet('/content_types/content_type_uid/entries', (config) => {
144+
// Check if asset_fields parameter is present in the request
145+
const assetFields = config.params && (config.params['asset_fields[]'] || config.params.asset_fields)
146+
if (Array.isArray(assetFields)) {
147+
return assetFields.includes('user_defined_fields') &&
148+
assetFields.includes('embedded') &&
149+
assetFields.includes('ai_suggested') &&
150+
assetFields.includes('visual_markups')
151+
}
152+
// Also check URL if params are serialized
153+
if (config.url && config.url.includes('asset_fields')) {
154+
return config.url.includes('user_defined_fields') &&
155+
config.url.includes('embedded') &&
156+
config.url.includes('ai_suggested') &&
157+
config.url.includes('visual_markups')
158+
}
159+
return false
160+
}).reply(200, {
161+
entries: [
162+
entryMock
163+
]
164+
})
165+
makeEntry()
166+
.query({ asset_fields: ['user_defined_fields', 'embedded', 'ai_suggested', 'visual_markups'] })
167+
.find()
168+
.then((entry) => {
169+
checkEntry(entry.items[0])
170+
done()
171+
})
172+
.catch(done)
173+
})
174+
175+
it('Entry Query test with asset_fields parameter combined with other query params', done => {
176+
var mock = new MockAdapter(Axios)
177+
mock.onGet('/content_types/content_type_uid/entries', (config) => {
178+
// Check if asset_fields parameter is present in the request
179+
const assetFields = config.params && (config.params['asset_fields[]'] || config.params.asset_fields)
180+
const hasAssetFields = Array.isArray(assetFields)
181+
? (assetFields.includes('user_defined_fields') && assetFields.includes('embedded'))
182+
: (config.url && config.url.includes('asset_fields') && config.url.includes('user_defined_fields') && config.url.includes('embedded'))
183+
return hasAssetFields && config.params && config.params.include_count === true
184+
}).reply(200, {
185+
entries: [
186+
entryMock
187+
],
188+
count: 1
189+
})
190+
makeEntry()
191+
.query({
192+
asset_fields: ['user_defined_fields', 'embedded'],
193+
include_count: true
194+
})
195+
.find()
196+
.then((entry) => {
197+
checkEntry(entry.items[0])
198+
expect(entry.count).to.be.equal(1)
199+
done()
200+
})
201+
.catch(done)
202+
})
203+
113204
it('Entry update test', done => {
114205
var mock = new MockAdapter(Axios)
115206
mock.onPut('/content_types/content_type_uid/entries/UID').reply(200, {
@@ -152,6 +243,76 @@ describe('Contentstack Entry test', () => {
152243
.catch(done)
153244
})
154245

246+
it('Entry fetch test with asset_fields parameter - single value', done => {
247+
var mock = new MockAdapter(Axios)
248+
mock.onGet('/content_types/content_type_uid/entries/UID', (config) => {
249+
// Check if asset_fields parameter is present in the request
250+
const assetFields = config.params && (config.params['asset_fields[]'] || config.params.asset_fields)
251+
if (Array.isArray(assetFields)) {
252+
return assetFields.includes('user_defined_fields')
253+
}
254+
// Also check URL if params are serialized
255+
if (config.url && config.url.includes('asset_fields')) {
256+
return config.url.includes('user_defined_fields')
257+
}
258+
return false
259+
}).reply(200, {
260+
entry: {
261+
...entryMock
262+
}
263+
})
264+
makeEntry({
265+
entry: {
266+
...systemUidMock
267+
},
268+
stackHeaders: stackHeadersMock
269+
})
270+
.fetch({ asset_fields: ['user_defined_fields'] })
271+
.then((entry) => {
272+
checkEntry(entry)
273+
done()
274+
})
275+
.catch(done)
276+
})
277+
278+
it('Entry fetch test with asset_fields parameter - multiple values', done => {
279+
var mock = new MockAdapter(Axios)
280+
mock.onGet('/content_types/content_type_uid/entries/UID', (config) => {
281+
// Check if asset_fields parameter is present in the request
282+
const assetFields = config.params && (config.params['asset_fields[]'] || config.params.asset_fields)
283+
if (Array.isArray(assetFields)) {
284+
return assetFields.includes('user_defined_fields') &&
285+
assetFields.includes('embedded') &&
286+
assetFields.includes('ai_suggested') &&
287+
assetFields.includes('visual_markups')
288+
}
289+
// Also check URL if params are serialized
290+
if (config.url && config.url.includes('asset_fields')) {
291+
return config.url.includes('user_defined_fields') &&
292+
config.url.includes('embedded') &&
293+
config.url.includes('ai_suggested') &&
294+
config.url.includes('visual_markups')
295+
}
296+
return false
297+
}).reply(200, {
298+
entry: {
299+
...entryMock
300+
}
301+
})
302+
makeEntry({
303+
entry: {
304+
...systemUidMock
305+
},
306+
stackHeaders: stackHeadersMock
307+
})
308+
.fetch({ asset_fields: ['user_defined_fields', 'embedded', 'ai_suggested', 'visual_markups'] })
309+
.then((entry) => {
310+
checkEntry(entry)
311+
done()
312+
})
313+
.catch(done)
314+
})
315+
155316
it('Entry delete test', done => {
156317
var mock = new MockAdapter(Axios)
157318
mock.onDelete('/content_types/content_type_uid/entries/UID').reply(200, {

0 commit comments

Comments
 (0)