Skip to content

Commit

Permalink
Merge branch 'feat/additional-attribution' of github.com:Topsort/segm…
Browse files Browse the repository at this point in the history
…ent-destination into feat/additional-attribution
  • Loading branch information
agustinespildora committed Jan 7, 2025
2 parents bda5694 + 77b4af7 commit ed5b732
Show file tree
Hide file tree
Showing 12 changed files with 508 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Topsort.bannerClick should be successful with default mappings and resolvedBidId 1`] = `
Headers {
Symbol(map): Object {
"authorization": Array [
"Bearer bar",
],
"content-type": Array [
"application/json",
],
"user-agent": Array [
"Segment (Actions)",
],
},
}
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Testing snapshot for Topsort's bannerClick destination action: all fields 1`] = `
Object {
"clicks": Array [
Object {
"id": "hSP][%Rg14m2c",
"occurredAt": "2021-02-01T00:00:00.000Z",
"opaqueUserId": "hSP][%Rg14m2c",
"resolvedBidId": "hSP][%Rg14m2c",
},
],
}
`;

exports[`Testing snapshot for Topsort's bannerClick destination action: required fields 1`] = `
Object {
"clicks": Array [
Object {
"id": "hSP][%Rg14m2c",
"occurredAt": "2021-02-01T00:00:00.000Z",
"opaqueUserId": "hSP][%Rg14m2c",
"resolvedBidId": "hSP][%Rg14m2c",
},
],
}
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import nock from 'nock'
import { AggregateAjvError } from '@segment/ajv-human-errors'
import { createTestEvent, createTestIntegration } from '@segment/actions-core'
import Destination from '../../index'

const testDestination = createTestIntegration(Destination)

describe('Topsort.bannerClick', () => {
it('should be successful with default mappings and resolvedBidId', async () => {
nock(/.*/).persist().post(/.*/).reply(200)

const event = createTestEvent({
properties: {
resolvedBidId: 'thisisaresolvedbidid'
}
})

const responses = await testDestination.testAction('bannerClick', {
event,
settings: {
api_key: 'bar'
},
useDefaultMappings: true
})

expect(responses.length).toBe(1)
expect(responses[0].status).toBe(200)
expect(responses[0].options.headers).toMatchSnapshot()
expect(responses[0].options.json).toMatchObject({
clicks: expect.arrayContaining([
expect.objectContaining({
id: expect.any(String),
resolvedBidId: 'thisisaresolvedbidid',
occurredAt: expect.any(String),
opaqueUserId: expect.any(String)
})
])
})
})

it('should fail because it misses a required field (resolvedBidId)', async () => {
nock(/.*/).persist().post(/.*/).reply(200)

const event = createTestEvent({})

await expect(
testDestination.testAction('bannerClick', {
event,
settings: {
api_key: 'bar'
},
useDefaultMappings: true
})
).rejects.toThrowError(AggregateAjvError)
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { createTestEvent, createTestIntegration } from '@segment/actions-core'
import { generateTestData } from '../../../../lib/test-data'
import destination from '../../index'
import nock from 'nock'

const testDestination = createTestIntegration(destination)
const actionSlug = 'bannerClick'
const destinationSlug = 'Topsort'
const seedName = `${destinationSlug}#${actionSlug}`

describe(`Testing snapshot for ${destinationSlug}'s ${actionSlug} destination action:`, () => {
it('required fields', async () => {
const action = destination.actions[actionSlug]
const [eventData, settingsData] = generateTestData(seedName, destination, action, true)

nock(/.*/).persist().get(/.*/).reply(200)
nock(/.*/).persist().post(/.*/).reply(200)
nock(/.*/).persist().put(/.*/).reply(200)

const event = createTestEvent({
properties: eventData
})

const responses = await testDestination.testAction(actionSlug, {
event: event,
mapping: event.properties,
settings: settingsData,
auth: undefined
})

const request = responses[0].request
const rawBody = await request.text()

try {
const json = JSON.parse(rawBody)
expect(json).toMatchSnapshot()
return
} catch (err) {
expect(rawBody).toMatchSnapshot()
}

expect(request.headers).toMatchSnapshot()
})

it('all fields', async () => {
const action = destination.actions[actionSlug]
const [eventData, settingsData] = generateTestData(seedName, destination, action, false)

nock(/.*/).persist().get(/.*/).reply(200)
nock(/.*/).persist().post(/.*/).reply(200)
nock(/.*/).persist().put(/.*/).reply(200)

const event = createTestEvent({
properties: eventData
})

const responses = await testDestination.testAction(actionSlug, {
event: event,
mapping: event.properties,
settings: settingsData,
auth: undefined
})

const request = responses[0].request
const rawBody = await request.text()

try {
const json = JSON.parse(rawBody)
expect(json).toMatchSnapshot()
return
} catch (err) {
expect(rawBody).toMatchSnapshot()
}
})
})

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import type { ActionDefinition } from '@segment/actions-core'
import type { Settings } from '../generated-types'
import type { Payload } from './generated-types'
import { TopsortAPIClient } from '../client'

const action: ActionDefinition<Settings, Payload> = {
title: 'Banner Click',
defaultSubscription: 'type = "track" and event = "Banner Clicked"',
description: 'Send click events to Topsort when a consumer has clicked on a banner.',
fields: {
id: {
label: 'Event ID',
description:
'Unique ID generated by the client to suppress duplicate events. The length should not exceed 128 characters.',
type: 'string',
required: true,
default: {
'@path': '$.messageId'
}
},
occurredAt: {
label: 'Occurred At',
description: 'Timestamp that the event happened at.',
type: 'datetime',
required: true,
default: {
'@path': '$.timestamp'
}
},
opaqueUserId: {
label: 'Opaque User ID',
description:
'Identifier for tracking users regardless of sign-in status. The length should not exceed 128 characters.',
type: 'string',
required: true,
default: {
'@path': '$.anonymousId'
}
},
resolvedBidId: {
label: 'Resolved Bid ID',
description:
'Identifier of an instance of a resolved auction for a determined banner. The length should not exceed 128 characters.',
type: 'string',
required: true,
default: {
'@path': '$.properties.resolvedBidId'
}
}
},
perform: (request, { payload, settings }) => {
const client = new TopsortAPIClient(request, settings)
return client.sendEvent({
clicks: [payload]
})
}
}

export default action
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Topsort.bannerImpression should be successful with default mappings and resolvedBidId 1`] = `
Headers {
Symbol(map): Object {
"authorization": Array [
"Bearer bar",
],
"content-type": Array [
"application/json",
],
"user-agent": Array [
"Segment (Actions)",
],
},
}
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Testing snapshot for Topsort's bannerImpression destination action: all fields 1`] = `
Object {
"impressions": Array [
Object {
"id": "#Is04AIKNbh",
"occurredAt": "2021-02-01T00:00:00.000Z",
"opaqueUserId": "#Is04AIKNbh",
"resolvedBidId": "#Is04AIKNbh",
},
],
}
`;

exports[`Testing snapshot for Topsort's bannerImpression destination action: required fields 1`] = `
Object {
"impressions": Array [
Object {
"id": "#Is04AIKNbh",
"occurredAt": "2021-02-01T00:00:00.000Z",
"opaqueUserId": "#Is04AIKNbh",
"resolvedBidId": "#Is04AIKNbh",
},
],
}
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import nock from 'nock'
import { AggregateAjvError } from '@segment/ajv-human-errors'
import { createTestEvent, createTestIntegration } from '@segment/actions-core'
import Destination from '../../index'

const testDestination = createTestIntegration(Destination)

describe('Topsort.bannerImpression', () => {
it('should be successful with default mappings and resolvedBidId', async () => {
nock(/.*/).persist().post(/.*/).reply(200)

const event = createTestEvent({
properties: {
resolvedBidId: 'thisisaresolvedbidid'
}
})

const responses = await testDestination.testAction('bannerImpression', {
event,
settings: {
api_key: 'bar'
},
useDefaultMappings: true
})

expect(responses.length).toBe(1)
expect(responses[0].status).toBe(200)
expect(responses[0].options.headers).toMatchSnapshot()
expect(responses[0].options.json).toMatchObject({
impressions: expect.arrayContaining([
expect.objectContaining({
id: expect.any(String),
resolvedBidId: 'thisisaresolvedbidid',
occurredAt: expect.any(String),
opaqueUserId: expect.any(String)
})
])
})
})

it('should fail because it misses a required field (resolvedBidId)', async () => {
nock(/.*/).persist().post(/.*/).reply(200)

const event = createTestEvent({})

await expect(
testDestination.testAction('bannerImpression', {
event,
settings: {
api_key: 'bar'
},
useDefaultMappings: true
})
).rejects.toThrowError(AggregateAjvError)
})
})
Loading

0 comments on commit ed5b732

Please sign in to comment.