Skip to content

Commit 75d8301

Browse files
[Survicate cloud] - new Cloud Destination (#3364)
* [Survicate] - new Cloud Destination * adding types
1 parent 0cf3be4 commit 75d8301

File tree

12 files changed

+819
-0
lines changed

12 files changed

+819
-0
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import nock from 'nock'
2+
import { createTestIntegration } from '@segment/actions-core'
3+
import Definition from '../index'
4+
5+
const testDestination = createTestIntegration(Definition)
6+
7+
describe('Survicate Cloud Mode', () => {
8+
beforeEach(() => {
9+
nock.cleanAll()
10+
})
11+
12+
describe('testAuthentication', () => {
13+
const authData = {
14+
apiKey: 'test_api_key'
15+
}
16+
17+
it('should validate authentication inputs', async () => {
18+
nock('https://integrations.survicate.com').get('/endpoint/segment/check').reply(200, {})
19+
20+
await expect(testDestination.testAuthentication(authData)).resolves.not.toThrowError()
21+
})
22+
23+
it('should fail on authentication failure', async () => {
24+
nock('https://integrations.survicate.com').get('/endpoint/segment/check').reply(401, {})
25+
26+
await expect(testDestination.testAuthentication(authData)).rejects.toThrowError()
27+
})
28+
})
29+
})

packages/destination-actions/src/destinations/survicate/generated-types.ts

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import nock from 'nock'
2+
import { createTestEvent, createTestIntegration, SegmentEvent } from '@segment/actions-core'
3+
import Definition from '../../index'
4+
import { Settings } from '../../generated-types'
5+
6+
let testDestination = createTestIntegration(Definition)
7+
const settings: Settings = {
8+
apiKey: 'test_api_key'
9+
}
10+
11+
const payload = {
12+
type: 'group' as const,
13+
userId: 'user123',
14+
anonymousId: 'anon123',
15+
groupId: 'group123',
16+
traits: {
17+
name: 'Test Group',
18+
industry: 'Technology',
19+
size: 100
20+
},
21+
timestamp: '2023-10-01T00:00:00Z'
22+
} as Partial<SegmentEvent>
23+
24+
const mapping = {
25+
userId: { '@path': '$.userId' },
26+
anonymousId: { '@path': '$.anonymousId' },
27+
groupId: { '@path': '$.groupId' },
28+
traits: { '@path': '$.traits' },
29+
timestamp: { '@path': '$.timestamp' }
30+
}
31+
32+
beforeEach(() => {
33+
testDestination = createTestIntegration(Definition)
34+
nock.cleanAll()
35+
})
36+
37+
describe('Survicate Cloud Mode - identifyGroup', () => {
38+
it('should send identify group payload to Survicate', async () => {
39+
const event = createTestEvent(payload)
40+
41+
const expectedJson = {
42+
userId: 'user123',
43+
anonymousId: 'anon123',
44+
groupId: 'group123',
45+
traits: {
46+
group_name: 'Test Group',
47+
group_industry: 'Technology',
48+
group_size: 100
49+
},
50+
timestamp: '2023-10-01T00:00:00Z'
51+
}
52+
53+
nock('https://integrations.survicate.com').post('/endpoint/segment/group', expectedJson).reply(200, {})
54+
55+
const response = await testDestination.testAction('identifyGroup', {
56+
event,
57+
settings,
58+
useDefaultMappings: true,
59+
mapping
60+
})
61+
62+
expect(response.length).toBe(1)
63+
})
64+
65+
it('should throw error when userId is not provided', async () => {
66+
const event = createTestEvent({
67+
...payload,
68+
userId: undefined
69+
})
70+
71+
await expect(
72+
testDestination.testAction('identifyGroup', {
73+
event,
74+
settings,
75+
useDefaultMappings: true,
76+
mapping
77+
})
78+
).rejects.toThrowError()
79+
})
80+
81+
it('should throw error when groupId is missing', async () => {
82+
const event = createTestEvent({
83+
...payload,
84+
groupId: undefined
85+
})
86+
87+
await expect(
88+
testDestination.testAction('identifyGroup', {
89+
event,
90+
settings,
91+
useDefaultMappings: true,
92+
mapping
93+
})
94+
).rejects.toThrowError()
95+
})
96+
97+
it('should throw error when traits are missing', async () => {
98+
const event = createTestEvent({
99+
...payload,
100+
traits: undefined
101+
})
102+
103+
await expect(
104+
testDestination.testAction('identifyGroup', {
105+
event,
106+
settings,
107+
useDefaultMappings: true,
108+
mapping
109+
})
110+
).rejects.toThrowError()
111+
})
112+
})

packages/destination-actions/src/destinations/survicate/identifyGroup/generated-types.ts

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { PayloadValidationError, ActionDefinition } from '@segment/actions-core'
2+
import { Settings } from '../generated-types'
3+
import { Payload } from './generated-types'
4+
5+
const action: ActionDefinition<Settings, Payload> = {
6+
title: 'Identify Group',
7+
description: 'Send group traits to Survicate',
8+
defaultSubscription: 'type = "group"',
9+
platform: 'cloud',
10+
fields: {
11+
userId: {
12+
type: 'string',
13+
required: true,
14+
description: "The user's id",
15+
label: 'User ID',
16+
default: {
17+
'@path': '$.userId'
18+
}
19+
},
20+
anonymousId: {
21+
type: 'string',
22+
required: false,
23+
description: 'An anonymous id',
24+
label: 'Anonymous ID',
25+
default: {
26+
'@path': '$.anonymousId'
27+
}
28+
},
29+
groupId: {
30+
type: 'string',
31+
required: true,
32+
description: 'The group id',
33+
label: 'Group ID',
34+
default: { '@path': '$.groupId' }
35+
},
36+
traits: {
37+
type: 'object',
38+
required: true,
39+
description: 'The Segment traits to be forwarded to Survicate',
40+
label: 'Group traits',
41+
default: { '@path': '$.traits' }
42+
},
43+
timestamp: {
44+
type: 'string',
45+
required: true,
46+
format: 'date-time',
47+
description: 'The timestamp of the event.',
48+
label: 'Timestamp',
49+
default: { '@path': '$.timestamp' }
50+
}
51+
},
52+
perform: (request, { payload }) => {
53+
const { userId, anonymousId, groupId, traits, timestamp } = payload
54+
55+
if (!userId && !anonymousId) {
56+
throw new PayloadValidationError("'User ID' or 'Anonymous ID' is required")
57+
}
58+
59+
return request(`https://integrations.survicate.com/endpoint/segment/group`, {
60+
method: 'post',
61+
json: {
62+
...(userId ? { userId } : {}),
63+
...(anonymousId ? { anonymousId } : {}),
64+
groupId,
65+
traits: Object.fromEntries(Object.entries(traits).map(([key, value]) => [`group_${key}`, value])),
66+
timestamp
67+
}
68+
})
69+
}
70+
}
71+
72+
export default action

0 commit comments

Comments
 (0)