Skip to content

Commit ec6248f

Browse files
Merge pull request #182 from contentstack/development
Development
2 parents 8661083 + b38eee7 commit ec6248f

File tree

9 files changed

+917
-2474
lines changed

9 files changed

+917
-2474
lines changed

.github/workflows/secrets-scan.yml

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,29 @@
1-
name: Secrets Scan
2-
on:
3-
pull_request:
4-
types: [opened, synchronize, reopened]
5-
jobs:
6-
security-secrets:
7-
runs-on: ubuntu-latest
8-
steps:
9-
- uses: actions/checkout@v4
10-
with:
11-
fetch-depth: '2'
12-
ref: '${{ github.event.pull_request.head.ref }}'
13-
- run: |
14-
git reset --soft HEAD~1
15-
- name: Install Talisman
16-
run: |
17-
# Download Talisman
18-
wget https://github.com/thoughtworks/talisman/releases/download/v1.37.0/talisman_linux_amd64 -O talisman
19-
20-
# Checksum verification
21-
checksum=$(sha256sum ./talisman | awk '{print $1}')
22-
if [ "$checksum" != "8e0ae8bb7b160bf10c4fa1448beb04a32a35e63505b3dddff74a092bccaaa7e4" ]; then exit 1; fi
23-
24-
# Make it executable
25-
chmod +x talisman
26-
- name: Run talisman
27-
run: |
28-
# Run Talisman with the pre-commit hook
1+
name: Secrets Scan
2+
on:
3+
pull_request:
4+
types: [opened, synchronize, reopened]
5+
jobs:
6+
security-secrets:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: actions/checkout@v4
10+
with:
11+
fetch-depth: '2'
12+
ref: '${{ github.event.pull_request.head.ref }}'
13+
- run: |
14+
git reset --soft HEAD~1
15+
- name: Install Talisman
16+
run: |
17+
# Download Talisman
18+
wget https://github.com/thoughtworks/talisman/releases/download/v1.37.0/talisman_linux_amd64 -O talisman
19+
20+
# Checksum verification
21+
checksum=$(sha256sum ./talisman | awk '{print $1}')
22+
if [ "$checksum" != "8e0ae8bb7b160bf10c4fa1448beb04a32a35e63505b3dddff74a092bccaaa7e4" ]; then exit 1; fi
23+
24+
# Make it executable
25+
chmod +x talisman
26+
- name: Run talisman
27+
run: |
28+
# Run Talisman with the pre-commit hook
2929
./talisman --githook pre-commit

.talismanrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ fileignoreconfig:
33
ignore_detectors:
44
- filecontent
55
- filename: package-lock.json
6-
checksum: 030162c3c72502ccac30f3ce0172f1c2ae31a794544e0e1096771326780ea21b
6+
checksum: 88174adc8b9dcedecf549defe09988aa4ca95940801e923d829123ba2f3ef6f4
77
- filename: src/entry-editable.ts
88
checksum: f9c4694229205fca252bb087482a3e408c6ad3b237cd108e337bcff49458db5c
99
- filename: .husky/pre-commit

CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# Changelog
22

3-
## [1.5.0](https://github.com/contentstack/contentstack-utils-javascript/tree/v1.4.1) (2025-09-01)
3+
## [1.4.3](https://github.com/contentstack/contentstack-utils-javascript/tree/v1.4.3) (2025-09-22)
4+
- Fix data-cslp generation logic in case of applied_variants
5+
6+
## [1.4.2](https://github.com/contentstack/contentstack-utils-javascript/tree/v1.4.2) (2025-09-01)
47
- Improve null checks in find embedded entry and find embedded asset functions
58

69
## [1.4.1](https://github.com/contentstack/contentstack-utils-javascript/tree/v1.4.1) (2025-05-26)

CODEOWNERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
* @contentstack/security-admin
1+
* @contentstack/security-admin

__test__/entry-editable.test.ts

Lines changed: 144 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
import { EntryModel } from '../src'
21
import { addTags } from '../src/entry-editable'
3-
import { entry_global_field, entry_global_field_multiple, entry_modular_block, entry_reference, entry_with_text } from './mock/entry-editable-mock'
4-
import { entryMultipleContent } from './mock/entry-multiple-rich-text-content'
2+
import { entry_global_field, entry_global_field_multiple, entry_modular_block, entry_reference, entry_with_text, entry_with_applied_variants, entry_with_parent_path_variants } from './mock/entry-editable-mock'
53

64
describe('Entry editable test', () => {
75
it('Entry with text test', done => {
@@ -129,4 +127,147 @@ describe('Entry editable test', () => {
129127
done()
130128
})
131129

130+
// Tests for applied variants functionality
131+
describe('Applied Variants Tests', () => {
132+
it('Entry with applied variants should generate v2 tags with variant suffix', done => {
133+
addTags(entry_with_applied_variants, 'entry_asset', false)
134+
135+
// Field with direct variant match should get v2 prefix and variant suffix
136+
expect((entry_with_applied_variants as any)['$']['rich_text_editor']).toEqual('data-cslp=v2:entry_asset.entry_uid_1_variant_1.en-us.rich_text_editor')
137+
138+
// Nested field with direct variant match
139+
expect((entry_with_applied_variants as any)['nested']['$']['field']).toEqual('data-cslp=v2:entry_asset.entry_uid_1_variant_2.en-us.nested.field')
140+
141+
// Field without variant should not have v2 prefix
142+
expect((entry_with_applied_variants as any)['nested']['$']['other_field']).toEqual('data-cslp=entry_asset.entry_uid_1.en-us.nested.other_field')
143+
expect((entry_with_applied_variants as any)['$']['rich_text_editor_multiple']).toEqual('data-cslp=entry_asset.entry_uid_1.en-us.rich_text_editor_multiple')
144+
145+
done()
146+
})
147+
148+
it('Entry with applied variants should return v2 objects when tagsAsObject is true', done => {
149+
addTags(entry_with_applied_variants, 'entry_asset', true)
150+
151+
// Field with direct variant match should get v2 prefix and variant suffix as object
152+
expect((entry_with_applied_variants as any)['$']['rich_text_editor']).toEqual({'data-cslp': 'v2:entry_asset.entry_uid_1_variant_1.en-us.rich_text_editor'})
153+
154+
// Nested field with direct variant match
155+
expect((entry_with_applied_variants as any)['nested']['$']['field']).toEqual({'data-cslp': 'v2:entry_asset.entry_uid_1_variant_2.en-us.nested.field'})
156+
157+
// Field without variant should not have v2 prefix
158+
expect((entry_with_applied_variants as any)['nested']['$']['other_field']).toEqual({'data-cslp': 'entry_asset.entry_uid_1.en-us.nested.other_field'})
159+
expect((entry_with_applied_variants as any)['$']['rich_text_editor_multiple']).toEqual({'data-cslp': 'entry_asset.entry_uid_1.en-us.rich_text_editor_multiple'})
160+
161+
done()
162+
})
163+
164+
it('Entry with parent path variants should find correct variant', done => {
165+
addTags(entry_with_parent_path_variants, 'entry_asset', false)
166+
167+
// Group field should get parent variant
168+
expect((entry_with_parent_path_variants as any)['$']['group']).toEqual('data-cslp=v2:entry_asset.entry_uid_3_parent_variant.en-us.group')
169+
// Field under 'group' parent should get parent variant
170+
expect((entry_with_parent_path_variants as any)['group']['$']['other']).toEqual('data-cslp=v2:entry_asset.entry_uid_3_parent_variant.en-us.group.other')
171+
// Field under 'group.nested' should get parent variant (group is longer match)
172+
expect((entry_with_parent_path_variants as any)['group']['nested']['$']['field']).toEqual('data-cslp=v2:entry_asset.entry_uid_3_parent_variant.en-us.group.nested.field')
173+
// Field with exact deep path match should get deep variant
174+
expect((entry_with_parent_path_variants as any)['group']['nested']['deep']['$']['field']).toEqual('data-cslp=v2:entry_asset.entry_uid_3_deep_variant.en-us.group.nested.deep.field')
175+
176+
// Field with the same starting path should not get parent variant
177+
expect((entry_with_parent_path_variants as any)['$']['group_multiple']).toEqual('data-cslp=entry_asset.entry_uid_3.en-us.group_multiple')
178+
179+
// Modular block content with variant should get v2 prefix and variant suffix
180+
expect((entry_with_parent_path_variants as any)['modular_blocks'][0]['$']['content']).toEqual('data-cslp=v2:entry_asset.entry_uid_3_parent_variant.en-us.modular_blocks.0.content')
181+
// Modular block field inside a variantised parent should get v2 prefix and variant suffix
182+
expect((entry_with_parent_path_variants as any)['modular_blocks'][0]['content']['$']['title']).toEqual('data-cslp=v2:entry_asset.entry_uid_3_parent_variant.en-us.modular_blocks.0.content.title')
183+
184+
// Modular block content without variant should not have v2 prefix and variant suffix
185+
expect((entry_with_parent_path_variants as any)['modular_blocks'][1]['$']['content']).toEqual('data-cslp=entry_asset.entry_uid_3.en-us.modular_blocks.1.content')
186+
// Modular block field inside a non variantised parent should not get v2 prefix and variant suffix
187+
expect((entry_with_parent_path_variants as any)['modular_blocks'][1]['content']['$']['title']).toEqual('data-cslp=entry_asset.entry_uid_3.en-us.modular_blocks.1.content.title')
188+
189+
done()
190+
})
191+
192+
it('Entry with modular block variants should apply variants correctly', done => {
193+
addTags(entry_with_applied_variants, 'entry_asset', false)
194+
195+
// Modular block content with variant should get v2 prefix and variant suffix
196+
expect((entry_with_applied_variants as any)['modular_blocks'][1]['$']['content_from_variant']).toEqual('data-cslp=v2:entry_asset.entry_uid_1_variant_3.en-us.modular_blocks.1.content_from_variant')
197+
// Modular block field inside a variantised parent should get v2 prefix and variant suffix
198+
expect((entry_with_applied_variants as any)['modular_blocks'][1]['content_from_variant']['$']['title']).toEqual('data-cslp=v2:entry_asset.entry_uid_1_variant_3.en-us.modular_blocks.1.content_from_variant.title')
199+
// Field inside a variantised parent with a different variant should get v2 prefix and variant suffix of that variant
200+
expect((entry_with_applied_variants as any)['modular_blocks'][1]['content_from_variant']['$']['different_from_parent_variant']).toEqual('data-cslp=v2:entry_asset.entry_uid_1_variant_4.en-us.modular_blocks.1.content_from_variant.different_from_parent_variant')
201+
202+
// Modular block content without variant should get v2 prefix and variant suffix
203+
expect((entry_with_applied_variants as any)['modular_blocks'][0]['$']['content']).toEqual('data-cslp=entry_asset.entry_uid_1.en-us.modular_blocks.0.content')
204+
// Modular block field without variant should not have v2 prefix and variant suffix
205+
expect((entry_with_applied_variants as any)['modular_blocks'][0]['content']['$']['title']).toEqual('data-cslp=entry_asset.entry_uid_1.en-us.modular_blocks.0.content.title')
206+
207+
done()
208+
})
209+
210+
it('Entry without applied variants should work normally', done => {
211+
addTags(entry_with_text, 'entry_asset', false)
212+
213+
// Should not have v2 prefix when no variants are applied
214+
expect((entry_with_text as any)['$']['rich_text_editor']).toEqual('data-cslp=entry_asset.entry_uid_1.en-us.rich_text_editor')
215+
expect((entry_with_text as any)['$']['rich_text_editor_multiple']).toEqual('data-cslp=entry_asset.entry_uid_1.en-us.rich_text_editor_multiple')
216+
217+
done()
218+
})
219+
220+
it('Entry with empty applied variants should work normally', done => {
221+
const entryWithEmptyVariants = {
222+
...entry_with_text,
223+
_applied_variants: {}
224+
}
225+
226+
addTags(entryWithEmptyVariants, 'entry_asset', false)
227+
228+
// Should not have v2 prefix when variants object is empty
229+
expect((entryWithEmptyVariants as any)['$']['rich_text_editor']).toEqual('data-cslp=entry_asset.entry_uid_1.en-us.rich_text_editor')
230+
expect((entryWithEmptyVariants as any)['$']['rich_text_editor_multiple']).toEqual('data-cslp=entry_asset.entry_uid_1.en-us.rich_text_editor_multiple')
231+
232+
done()
233+
})
234+
235+
it('Variant path sorting should work correctly for nested paths', done => {
236+
const entryWithComplexVariants = {
237+
"_version": 10,
238+
"locale": "en-us",
239+
"uid": "entry_uid_test",
240+
"ACL": {},
241+
"_applied_variants": {
242+
"a": "variant_a",
243+
"a.b": "variant_ab",
244+
"a.b.c": "variant_abc",
245+
"a.b.c.d": "variant_abcd"
246+
},
247+
"a": {
248+
"b": {
249+
"c": {
250+
"d": {
251+
"field": "deep field"
252+
},
253+
"field": "c field"
254+
},
255+
"field": "b field"
256+
},
257+
"field": "a field"
258+
}
259+
}
260+
261+
addTags(entryWithComplexVariants, 'entry_asset', false)
262+
263+
// Should use the longest matching path variant
264+
expect((entryWithComplexVariants as any)['a']['b']['c']['d']['$']['field']).toEqual('data-cslp=v2:entry_asset.entry_uid_test_variant_abcd.en-us.a.b.c.d.field')
265+
expect((entryWithComplexVariants as any)['a']['b']['c']['$']['field']).toEqual('data-cslp=v2:entry_asset.entry_uid_test_variant_abc.en-us.a.b.c.field')
266+
expect((entryWithComplexVariants as any)['a']['b']['$']['field']).toEqual('data-cslp=v2:entry_asset.entry_uid_test_variant_ab.en-us.a.b.field')
267+
expect((entryWithComplexVariants as any)['a']['$']['field']).toEqual('data-cslp=v2:entry_asset.entry_uid_test_variant_a.en-us.a.field')
268+
269+
done()
270+
})
271+
})
272+
132273
})

0 commit comments

Comments
 (0)