Skip to content

Commit c4501bd

Browse files
STRATCONN-6484 - [Youappi] - new non native audience destination (#3610)
* new Youappi destination * using audience_id field * adding unit tests * updating url * comverting to password field
1 parent 97ac555 commit c4501bd

11 files changed

Lines changed: 1344 additions & 0 deletions

File tree

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`Testing snapshot for actions-youappi-audience destination: sync action - all fields 1`] = `
4+
Object {
5+
"api_key": "*bGwH[",
6+
"audiences": Array [
7+
Object {
8+
"action": "remove",
9+
"audience_id": 1295161243,
10+
"audience_name": "*bGwH[",
11+
},
12+
],
13+
"device_identities": Array [
14+
Object {
15+
"type": "IDFA",
16+
"value": "*bGwH[",
17+
},
18+
Object {
19+
"type": "GAID",
20+
"value": "*bGwH[",
21+
},
22+
],
23+
}
24+
`;
25+
26+
exports[`Testing snapshot for actions-youappi-audience destination: sync action - required fields 1`] = `
27+
Object {
28+
"api_key": "*bGwH[",
29+
"audiences": Array [
30+
Object {
31+
"action": "remove",
32+
"audience_id": 1295161243,
33+
"audience_name": "*bGwH[",
34+
},
35+
],
36+
"device_identities": Array [
37+
Object {
38+
"type": "IDFA",
39+
"value": "*bGwH[",
40+
},
41+
Object {
42+
"type": "GAID",
43+
"value": "*bGwH[",
44+
},
45+
],
46+
}
47+
`;
Lines changed: 286 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,286 @@
1+
import { getJSON } from '../sync/functions'
2+
import { Payload } from '../sync/generated-types'
3+
import { Settings } from '../generated-types'
4+
5+
describe('YouAppi Audiences - Helper Functions', () => {
6+
const mockSettings: Settings = {
7+
api_key: 'test-api-key-123'
8+
}
9+
10+
describe('getJSON', () => {
11+
it('should construct proper request JSON for add operation with both IDFA and GAID', () => {
12+
const payloads: Payload[] = [
13+
{
14+
idfa: 'test-idfa-123',
15+
gaid: 'test-gaid-456',
16+
audience_name: 'Test Audience',
17+
audience_id: 'audience-id-123',
18+
traits_or_props: {
19+
'Test Audience': true
20+
},
21+
enable_batching: true,
22+
batch_size: 1000
23+
}
24+
]
25+
26+
const result = getJSON(payloads, mockSettings, 'add')
27+
28+
// Verify API key
29+
expect(result).toHaveProperty('api_key', 'test-api-key-123')
30+
31+
// Verify device identities structure
32+
expect(result).toHaveProperty('device_identities')
33+
expect(result.device_identities).toHaveLength(2)
34+
expect(result.device_identities).toContainEqual({
35+
type: 'IDFA',
36+
value: 'test-idfa-123'
37+
})
38+
expect(result.device_identities).toContainEqual({
39+
type: 'GAID',
40+
value: 'test-gaid-456'
41+
})
42+
43+
// Verify audiences structure
44+
expect(result).toHaveProperty('audiences')
45+
expect(result.audiences).toHaveLength(1)
46+
expect(result.audiences[0]).toHaveProperty('audience_name', 'Test Audience')
47+
expect(result.audiences[0]).toHaveProperty('action', 'add')
48+
49+
// Verify audience_id is a number (hash)
50+
expect(result.audiences[0]).toHaveProperty('audience_id')
51+
expect(typeof result.audiences[0].audience_id).toBe('number')
52+
53+
// Verify the hash is generated from audience_id
54+
const expectedHash = [...'audience-id-123'].reduce((h, c) => (h = (h << 5) - h + c.charCodeAt(0) | 0), 0)
55+
expect(result.audiences[0].audience_id).toBe(expectedHash)
56+
})
57+
58+
it('should construct proper request JSON for remove operation', () => {
59+
const payloads: Payload[] = [
60+
{
61+
idfa: 'test-idfa-456',
62+
gaid: 'test-gaid-456',
63+
audience_name: 'Test Audience',
64+
audience_id: 'audience-id-456',
65+
traits_or_props: {
66+
'Test Audience': false
67+
},
68+
enable_batching: true,
69+
batch_size: 1000
70+
}
71+
]
72+
73+
const result = getJSON(payloads, mockSettings, 'remove')
74+
75+
expect(result.device_identities).toHaveLength(2)
76+
expect(result.device_identities).toContainEqual({
77+
type: 'IDFA',
78+
value: 'test-idfa-456'
79+
})
80+
expect(result.device_identities).toContainEqual({
81+
type: 'GAID',
82+
value: 'test-gaid-456'
83+
})
84+
expect(result.audiences[0]).toMatchObject({
85+
audience_name: 'Test Audience',
86+
action: 'remove'
87+
})
88+
89+
// Verify audience_id hash for this specific audience_id
90+
const expectedHash = [...'audience-id-456'].reduce((h, c) => (h = (h << 5) - h + c.charCodeAt(0) | 0), 0)
91+
expect(result.audiences[0].audience_id).toBe(expectedHash)
92+
})
93+
94+
it('should handle multiple payloads and flatten device identities', () => {
95+
const payloads: Payload[] = [
96+
{
97+
idfa: 'idfa-1',
98+
gaid: 'gaid-1',
99+
audience_name: 'Test Audience',
100+
audience_id: 'audience-id-1',
101+
traits_or_props: {
102+
'Test Audience': true
103+
},
104+
enable_batching: true,
105+
batch_size: 1000
106+
},
107+
{
108+
idfa: 'idfa-2',
109+
gaid: 'gaid-2',
110+
audience_name: 'Test Audience',
111+
audience_id: 'audience-id-2',
112+
traits_or_props: {
113+
'Test Audience': true
114+
},
115+
enable_batching: true,
116+
batch_size: 1000
117+
},
118+
{
119+
idfa: 'idfa-3',
120+
gaid: 'gaid-3',
121+
audience_name: 'Test Audience',
122+
audience_id: 'audience-id-3',
123+
traits_or_props: {
124+
'Test Audience': true
125+
},
126+
enable_batching: true,
127+
batch_size: 1000
128+
}
129+
]
130+
131+
const result = getJSON(payloads, mockSettings, 'add')
132+
133+
// Should have 6 device identities total: idfa-1, gaid-1, idfa-2, gaid-2, idfa-3, gaid-3
134+
expect(result.device_identities).toHaveLength(6)
135+
136+
// Verify all device identities are present
137+
expect(result.device_identities).toContainEqual({ type: 'IDFA', value: 'idfa-1' })
138+
expect(result.device_identities).toContainEqual({ type: 'GAID', value: 'gaid-1' })
139+
expect(result.device_identities).toContainEqual({ type: 'IDFA', value: 'idfa-2' })
140+
expect(result.device_identities).toContainEqual({ type: 'GAID', value: 'gaid-2' })
141+
expect(result.device_identities).toContainEqual({ type: 'IDFA', value: 'idfa-3' })
142+
expect(result.device_identities).toContainEqual({ type: 'GAID', value: 'gaid-3' })
143+
})
144+
145+
it('should generate consistent audience_id hash for same audience_id string', () => {
146+
const payloads1: Payload[] = [
147+
{
148+
idfa: 'test-idfa',
149+
gaid: 'test-gaid',
150+
audience_name: 'My Test Audience',
151+
audience_id: 'consistent-id',
152+
traits_or_props: {
153+
'My Test Audience': true
154+
},
155+
enable_batching: true,
156+
batch_size: 1000
157+
}
158+
]
159+
160+
const payloads2: Payload[] = [
161+
{
162+
idfa: 'different-idfa',
163+
gaid: 'different-gaid',
164+
audience_name: 'My Test Audience',
165+
audience_id: 'consistent-id',
166+
traits_or_props: {
167+
'My Test Audience': true
168+
},
169+
enable_batching: true,
170+
batch_size: 1000
171+
}
172+
]
173+
174+
const result1 = getJSON(payloads1, mockSettings, 'add')
175+
const result2 = getJSON(payloads2, mockSettings, 'add')
176+
177+
// Same audience_id string should produce same hash
178+
expect(result1.audiences[0].audience_id).toBe(result2.audiences[0].audience_id)
179+
180+
// Verify it matches the expected hash value
181+
const expectedHash = [...'consistent-id'].reduce((h, c) => (h = (h << 5) - h + c.charCodeAt(0) | 0), 0)
182+
expect(result1.audiences[0].audience_id).toBe(expectedHash)
183+
expect(result2.audiences[0].audience_id).toBe(expectedHash)
184+
})
185+
186+
it('should generate different audience_id hash for different audience_id strings', () => {
187+
const payloads1: Payload[] = [
188+
{
189+
idfa: 'test-idfa',
190+
gaid: 'test-gaid',
191+
audience_name: 'Audience A',
192+
audience_id: 'id-a',
193+
traits_or_props: {
194+
'Audience A': true
195+
},
196+
enable_batching: true,
197+
batch_size: 1000
198+
}
199+
]
200+
201+
const payloads2: Payload[] = [
202+
{
203+
idfa: 'test-idfa',
204+
gaid: 'test-gaid',
205+
audience_name: 'Audience B',
206+
audience_id: 'id-b',
207+
traits_or_props: {
208+
'Audience B': true
209+
},
210+
enable_batching: true,
211+
batch_size: 1000
212+
}
213+
]
214+
215+
const result1 = getJSON(payloads1, mockSettings, 'add')
216+
const result2 = getJSON(payloads2, mockSettings, 'add')
217+
218+
// Different audience_id strings should produce different hashes
219+
expect(result1.audiences[0].audience_id).not.toBe(result2.audiences[0].audience_id)
220+
221+
// Verify each hash matches its expected value
222+
const expectedHash1 = [...'id-a'].reduce((h, c) => (h = (h << 5) - h + c.charCodeAt(0) | 0), 0)
223+
const expectedHash2 = [...'id-b'].reduce((h, c) => (h = (h << 5) - h + c.charCodeAt(0) | 0), 0)
224+
expect(result1.audiences[0].audience_id).toBe(expectedHash1)
225+
expect(result2.audiences[0].audience_id).toBe(expectedHash2)
226+
})
227+
228+
it('should use audience_id and audience_name from first payload for audiences array', () => {
229+
const payloads: Payload[] = [
230+
{
231+
idfa: 'idfa-1',
232+
gaid: 'gaid-1',
233+
audience_name: 'Primary Audience',
234+
audience_id: 'primary-id',
235+
traits_or_props: {
236+
'Primary Audience': true
237+
},
238+
enable_batching: true,
239+
batch_size: 1000
240+
},
241+
{
242+
idfa: 'idfa-2',
243+
gaid: 'gaid-2',
244+
audience_name: 'Primary Audience',
245+
audience_id: 'primary-id',
246+
traits_or_props: {
247+
'Primary Audience': true
248+
},
249+
enable_batching: true,
250+
batch_size: 1000
251+
}
252+
]
253+
254+
const result = getJSON(payloads, mockSettings, 'add')
255+
256+
expect(result.audiences).toHaveLength(1)
257+
expect(result.audiences[0].audience_name).toBe('Primary Audience')
258+
259+
// Verify hash is generated from first payload's audience_id
260+
const expectedHash = [...'primary-id'].reduce((h, c) => (h = (h << 5) - h + c.charCodeAt(0) | 0), 0)
261+
expect(result.audiences[0].audience_id).toBe(expectedHash)
262+
})
263+
264+
it('should include both IDFA and GAID when both are present', () => {
265+
const payloads: Payload[] = [
266+
{
267+
idfa: 'test-idfa',
268+
gaid: 'test-gaid',
269+
audience_name: 'Multi-Platform Audience',
270+
audience_id: 'multi-id',
271+
traits_or_props: {
272+
'Multi-Platform Audience': true
273+
},
274+
enable_batching: true,
275+
batch_size: 1000
276+
}
277+
]
278+
279+
const result = getJSON(payloads, mockSettings, 'add')
280+
281+
expect(result.device_identities).toHaveLength(2)
282+
expect(result.device_identities.some(id => id.type === 'IDFA')).toBe(true)
283+
expect(result.device_identities.some(id => id.type === 'GAID')).toBe(true)
284+
})
285+
})
286+
})

0 commit comments

Comments
 (0)