Skip to content

Commit 2a8d6ca

Browse files
support sending json attributes
1 parent 69e40f4 commit 2a8d6ca

2 files changed

Lines changed: 68 additions & 1 deletion

File tree

packages/destination-actions/src/destinations/airship/__tests__/utilities.test.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,63 @@ describe('Testing _build_attribute_object', () => {
155155
})
156156
})
157157

158+
describe('Testing _build_attribute_object with JSON (array/object) values', () => {
159+
it('should append #default to array attribute keys without an instance ID', () => {
160+
const payload: AttributesPayload = {
161+
named_user_id: 'test-user',
162+
occurred: occurred.toISOString(),
163+
attributes: {
164+
favourite_teams: ['Team A', 'Team B', 'Team C']
165+
}
166+
}
167+
const result = _private._build_attributes_object(payload)
168+
const attr = result.find((a: any) => a.key === 'favourite_teams#default')
169+
expect(attr?.action).toBe('set')
170+
expect(attr?.value).toEqual(['Team A', 'Team B', 'Team C'])
171+
})
172+
173+
it('should append #default to object attribute keys without an instance ID', () => {
174+
const payload: AttributesPayload = {
175+
named_user_id: 'test-user',
176+
occurred: occurred.toISOString(),
177+
attributes: {
178+
preferences: { theme: 'dark', language: 'en' }
179+
}
180+
}
181+
const result = _private._build_attributes_object(payload)
182+
const attr = result.find((a: any) => a.key === 'preferences#default')
183+
expect(attr?.action).toBe('set')
184+
expect(attr?.value).toEqual({ theme: 'dark', language: 'en' })
185+
})
186+
187+
it('should preserve a user-supplied instance ID in the key', () => {
188+
const payload: AttributesPayload = {
189+
named_user_id: 'test-user',
190+
occurred: occurred.toISOString(),
191+
attributes: {
192+
'reservation#a001': { flight: 'UA123', seat: '12A' }
193+
}
194+
}
195+
const result = _private._build_attributes_object(payload)
196+
const attr = result.find((a: any) => a.key === 'reservation#a001')
197+
expect(attr?.action).toBe('set')
198+
expect(attr?.value).toEqual({ flight: 'UA123', seat: '12A' })
199+
})
200+
201+
it('should set action to remove for null value', () => {
202+
const payload: AttributesPayload = {
203+
named_user_id: 'test-user',
204+
occurred: occurred.toISOString(),
205+
attributes: {
206+
favourite_teams: null
207+
}
208+
}
209+
const result = _private._build_attributes_object(payload)
210+
const attr = result.find((a: any) => a.key === 'favourite_teams')
211+
expect(attr?.action).toBe('remove')
212+
})
213+
})
214+
158215
describe('Testing _build_tags_object', () => {
159216
it('should correctly format a tag', () => {
160217
expect(_private._build_tags_object(valid_tags_payload)).toEqual(airship_tags_payload)

packages/destination-actions/src/destinations/airship/utilities.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,16 @@ function _build_attribute(attribute_key: string, attribute_value: any, occurred:
279279
/*
280280
This function builds a single attribute from a key/value.
281281
*/
282+
// JSON attributes (object/array values) require a key in the format attribute_name#instance_id.
283+
// If the user hasn't included an instance ID, append '#default'.
284+
if (
285+
attribute_value !== null &&
286+
typeof attribute_value === 'object' &&
287+
!attribute_key.includes('#')
288+
) {
289+
attribute_key = `${attribute_key}#default`
290+
}
291+
282292
let adjustedDate = null
283293
if (typeof attribute_value == 'string') {
284294
adjustedDate = _parse_date(attribute_value)
@@ -291,7 +301,7 @@ function _build_attribute(attribute_key: string, attribute_value: any, occurred:
291301
const attribute: {
292302
action: string
293303
key: string
294-
value?: string | number | boolean
304+
value?: unknown
295305
timestamp: string | boolean
296306
} = {
297307
action: 'set',

0 commit comments

Comments
 (0)