From 7e36fd998540beee0cba8dfaafb128110479ca6c Mon Sep 17 00:00:00 2001 From: Rajul Vadera Date: Thu, 13 Feb 2025 22:01:35 -0800 Subject: [PATCH] update unit tests --- .../first-party-dv360/tests/index.test.ts | 282 ++++++++++++++++++ 1 file changed, 282 insertions(+) create mode 100644 packages/destination-actions/src/destinations/first-party-dv360/tests/index.test.ts diff --git a/packages/destination-actions/src/destinations/first-party-dv360/tests/index.test.ts b/packages/destination-actions/src/destinations/first-party-dv360/tests/index.test.ts new file mode 100644 index 0000000000..95730518a1 --- /dev/null +++ b/packages/destination-actions/src/destinations/first-party-dv360/tests/index.test.ts @@ -0,0 +1,282 @@ +import nock from 'nock' +import { createTestEvent, createTestIntegration, IntegrationError } from '@segment/actions-core' +import Destination from '../index' + +const audienceName = 'Test Audience' +const testDestination = createTestIntegration(Destination) + +const createAudienceInput = { + settings: { + oauth: { + refresh_token: 'mock-refresh-token' + } + }, + audienceName: audienceName, + audienceSettings: { + advertiserId: '12345', + audienceType: 'CUSTOMER_MATCH_CONTACT_INFO', + membershipDurationDays: '30', + description: 'Test description' + } +} + +const getAudienceInput = { + settings: { + oauth: { + refresh_token: 'mock-refresh-token' + } + }, + audienceSettings: { + advertiserId: '12345' + }, + externalId: 'audience-id-123' +} + +// Mock environment variables +beforeAll(() => { + process.env.ACTIONS_FIRST_PARTY_DV360_CLIENT_ID = 'mock-client-id' + process.env.ACTIONS_FIRST_PARTY_DV360_CLIENT_SECRET = 'mock-client-secret' +}) + +// Mock token request +beforeEach(() => { + nock('https://www.googleapis.com') + .post('/oauth2/v4/token', { + refresh_token: 'mock-refresh-token', + client_id: 'mock-client-id', + client_secret: 'mock-client-secret', + grant_type: 'refresh_token' + }) + .reply(200, { access_token: 'temp-token' }) +}) + +// Create Audience Tests +describe('Audience Destination', () => { + describe('createAudience', () => { + it('creates an audience successfully', async () => { + nock('https://displayvideo.googleapis.com') + .post('/v3/firstAndThirdPartyAudiences?advertiserId=12345', { + displayName: audienceName, + audienceType: 'CUSTOMER_MATCH_CONTACT_INFO', + membershipDurationDays: '30', + description: 'Test description', + audienceSource: 'AUDIENCE_SOURCE_UNSPECIFIED', + firstAndThirdPartyAudienceType: 'FIRST_AND_THIRD_PARTY_AUDIENCE_TYPE_FIRST_PARTY' + }) + .matchHeader('Authorization', 'Bearer temp-token') + .reply(200, { firstAndThirdPartyAudienceId: 'audience-id-123' }) + + const result = await testDestination.createAudience(createAudienceInput) + expect(result).toEqual({ externalId: 'audience-id-123' }) + }) + + it('errors out when no advertiser ID is provided', async () => { + createAudienceInput.audienceSettings.advertiserId = '' + + await expect(testDestination.createAudience(createAudienceInput)).rejects.toThrowError(IntegrationError) + }) + }) + + // Get Audience Tests + describe('getAudience', () => { + it('should succeed when provided with a valid audience ID', async () => { + nock('https://displayvideo.googleapis.com') + .get(`/v3/firstAndThirdPartyAudiences/audience-id-123?advertiserId=12345`) + .matchHeader('Authorization', 'Bearer temp-token') + .reply(200, { + firstAndThirdPartyAudienceId: 'audience-id-123' + }) + + const result = await testDestination.getAudience(getAudienceInput) + expect(result).toEqual({ externalId: 'audience-id-123' }) + }) + + it('should fail when the audience ID is missing', async () => { + const missingIdInput = { + ...getAudienceInput, + externalId: '' // Simulate missing audience ID + } + + await expect(testDestination.getAudience(missingIdInput)).rejects.toThrowError( + new IntegrationError('Failed to retrieve audience ID value', 'MISSING_REQUIRED_FIELD', 400) + ) + }) + }) + + // Edit Customer Match Members - Contact Info List + describe('Edit Customer Match Members - Contact Info List', () => { + const payloadContactInfo = { + emails: 'test@gmail.com', + phoneNumbers: '1234567890', + zipCodes: '12345', + firstName: 'John', + lastName: 'Doe', + countryCode: '+1' + } + + const event = createTestEvent({ + event: 'Audience Entered', + type: 'track', + properties: {}, + context: { + traits: payloadContactInfo, + personas: { + external_audience_id: 'audience-id-123', + audience_settings: { + advertiserId: '12345', + token: 'temp-token' + } + } + } + }) + + it('should add customer match members successfully', async () => { + nock('https://displayvideo.googleapis.com') + .post('/v3/firstAndThirdPartyAudiences/audience-id-123:editCustomerMatchMembers', { + advertiserId: '12345', + addedContactInfoList: { + contactInfos: [ + { + hashedEmails: '87924606b4131a8aceeeae8868531fbb9712aaa07a5d3a756b26ce0f5d6ca674', + hashedPhoneNumbers: 'c775e7b757ede630cd0aa1113bd102661ab38829ca52a6422ab782862f268646', + zipCodes: '12345', + hashedFirstName: '96d9632f363564cc3032521409cf22a852f2032eec099ed5967c0d000cec607a', + hashedLastName: '799ef92a11af918e3fb741df42934f3b568ed2d93ac1df74f1b8d41a27932a6f', + countryCode: '+1' + } + ], + consent: { + adUserData: 'CONSENT_STATUS_GRANTED', + adPersonalization: 'CONSENT_STATUS_GRANTED' + } + } + }) + .reply(200, { firstAndThirdPartyAudienceId: 'audience-id-123' }) + + const result = await testDestination.testAction('addToAudContactInfo', { + event, + useDefaultMappings: true + }) + expect(result).toContainEqual( + expect.objectContaining({ + data: expect.objectContaining({ + firstAndThirdPartyAudienceId: 'audience-id-123' + }) + }) + ) + }) + + it('should remove customer match members successfully', async () => { + nock('https://displayvideo.googleapis.com') + .post('/v3/firstAndThirdPartyAudiences/audience-id-123:editCustomerMatchMembers', { + advertiserId: '12345', + removedContactInfoList: { + contactInfos: [ + { + hashedEmails: '87924606b4131a8aceeeae8868531fbb9712aaa07a5d3a756b26ce0f5d6ca674', + hashedPhoneNumbers: 'c775e7b757ede630cd0aa1113bd102661ab38829ca52a6422ab782862f268646', + zipCodes: '12345', + hashedFirstName: '96d9632f363564cc3032521409cf22a852f2032eec099ed5967c0d000cec607a', + hashedLastName: '799ef92a11af918e3fb741df42934f3b568ed2d93ac1df74f1b8d41a27932a6f', + countryCode: '+1' + } + ], + consent: { + adUserData: 'CONSENT_STATUS_GRANTED', + adPersonalization: 'CONSENT_STATUS_GRANTED' + } + } + }) + .reply(200, { firstAndThirdPartyAudienceId: 'audience-id-123' }) + + const result = await testDestination.testAction('removeFromAudContactInfo', { + event, + useDefaultMappings: true + }) + expect(result).toContainEqual( + expect.objectContaining({ + data: expect.objectContaining({ + firstAndThirdPartyAudienceId: 'audience-id-123' + }) + }) + ) + }) + }) + + // Edit Customer Match Members - Mobile Device ID List + describe('Edit Customer Match Members - Mobile Device ID List', () => { + const payloadDeviceId = { + mobileDeviceIds: '123' + } + + const event = createTestEvent({ + event: 'Audience Entered', + type: 'track', + properties: {}, + context: { + traits: payloadDeviceId, + personas: { + external_audience_id: 'audience-id-123', + audience_settings: { + advertiserId: '12345', + token: 'temp-token' + } + } + } + }) + + it('should add customer match members successfully', async () => { + nock('https://displayvideo.googleapis.com') + .post('/v3/firstAndThirdPartyAudiences/audience-id-123:editCustomerMatchMembers', { + advertiserId: '12345', + addedMobileDeviceIdList: { + mobileDeviceIds: ['123'], + consent: { + adUserData: 'CONSENT_STATUS_GRANTED', + adPersonalization: 'CONSENT_STATUS_GRANTED' + } + } + }) + .reply(200, { firstAndThirdPartyAudienceId: 'audience-id-123' }) + + const result = await testDestination.testAction('addToAudMobileDeviceId', { + event, + useDefaultMappings: true + }) + expect(result).toContainEqual( + expect.objectContaining({ + data: expect.objectContaining({ + firstAndThirdPartyAudienceId: 'audience-id-123' + }) + }) + ) + }) + + it('should remove customer match members successfully', async () => { + nock('https://displayvideo.googleapis.com') + .post('/v3/firstAndThirdPartyAudiences/audience-id-123:editCustomerMatchMembers', { + advertiserId: '12345', + removedMobileDeviceIdList: { + mobileDeviceIds: ['123'], + consent: { + adUserData: 'CONSENT_STATUS_GRANTED', + adPersonalization: 'CONSENT_STATUS_GRANTED' + } + } + }) + .reply(200, { firstAndThirdPartyAudienceId: 'audience-id-123' }) + + const result = await testDestination.testAction('removeFromAudMobileDeviceId', { + event, + useDefaultMappings: true + }) + expect(result).toContainEqual( + expect.objectContaining({ + data: expect.objectContaining({ + firstAndThirdPartyAudienceId: 'audience-id-123' + }) + }) + ) + }) + }) +})