Skip to content

Commit e817a1a

Browse files
Update DV360 Protobuf Dependencies (#2778)
* Update protobuf-es * Update protofile.ts --no-verify * Fix Uses and Tests * Comment Tests * Properly mock protobuf * Fix broken import * Fix tests --------- Co-authored-by: Valerie Ernst <[email protected]>
1 parent 4390dca commit e817a1a

File tree

5 files changed

+457
-563
lines changed

5 files changed

+457
-563
lines changed

packages/destination-actions/package.json

+5-4
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
"typecheck": "tsc -p tsconfig.build.json --noEmit"
3232
},
3333
"devDependencies": {
34+
"@bufbuild/buf": "^1.50.0",
35+
"@bufbuild/protoc-gen-es": "^2.2.3",
3436
"@types/google-libphonenumber": "^7.4.23",
3537
"@types/jest": "^27.0.0",
3638
"@types/ssh2-sftp-client": "^9.0.0",
@@ -41,9 +43,7 @@
4143
"@amplitude/ua-parser-js": "^0.7.25",
4244
"@aws-sdk/client-eventbridge": "^3.741.0",
4345
"@aws-sdk/client-s3": "^3.600.0",
44-
"@bufbuild/buf": "^1.28.0",
45-
"@bufbuild/protobuf": "^1.4.2",
46-
"@bufbuild/protoc-gen-es": "^1.4.2",
46+
"@bufbuild/protobuf": "^2.2.3",
4747
"@segment/a1-notation": "^2.1.4",
4848
"@segment/actions-core": "^3.147.0",
4949
"@segment/actions-shared": "^1.128.0",
@@ -75,7 +75,8 @@
7575
"@segment/ajv-human-errors": "<rootDir>/../ajv-human-errors/src",
7676
"@segment/actions-core": "<rootDir>/../core/src",
7777
"@segment/actions-shared": "<rootDir>/../actions-shared/src",
78-
"@segment/destination-subscriptions": "<rootDir>/../destination-subscriptions/src"
78+
"@segment/destination-subscriptions": "<rootDir>/../destination-subscriptions/src",
79+
"@bufbuild/protobuf/codegenv1": "<rootDir>/../../node_modules/@bufbuild/protobuf/dist/cjs/codegenv1"
7980
},
8081
"setupFilesAfterEnv": [
8182
"<rootDir>/test/setup-after-env.ts"

packages/destination-actions/src/destinations/display-video-360/__tests__/shared.test.ts

+53-24
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,13 @@ import {
88
} from '../shared'
99
import { AudienceSettings } from '../generated-types'
1010
import { UpdateHandlerPayload } from '../types'
11-
import { UpdateUsersDataResponse, ErrorCode, ErrorInfo } from '../proto/protofile'
11+
import {
12+
UpdateUsersDataResponseSchema,
13+
UpdateUsersDataRequestSchema,
14+
ErrorCode,
15+
ErrorInfoSchema
16+
} from '../proto/protofile'
17+
import * as protobuf from '@bufbuild/protobuf'
1218
import { StatsContext, Response } from '@segment/actions-core'
1319
import createRequestClient from '../../../../../core/src/create-request-client'
1420

@@ -20,6 +26,9 @@ const oneMockPayload: UpdateHandlerPayload = {
2026
enable_batching: true
2127
}
2228

29+
const normalizeJson = (jsonString: string) =>
30+
JSON.stringify(JSON.parse(jsonString), Object.keys(JSON.parse(jsonString)).sort())
31+
2332
const mockRequestClient = createRequestClient()
2433

2534
const manyMockPayloads: UpdateHandlerPayload[] = [
@@ -67,24 +76,25 @@ const getRandomError = () => {
6776

6877
// Mock only the error code. The contents of the response are not important.
6978
const createMockResponse = (errorCode: ErrorCode, payload: UpdateHandlerPayload[]) => {
70-
const responseHandler = new UpdateUsersDataResponse()
79+
const responseHandler = protobuf.create(UpdateUsersDataResponseSchema, {})
7180
responseHandler.status = errorCode
7281

7382
if (errorCode === ErrorCode.PARTIAL_SUCCESS) {
7483
// Making assumptions about IdType and UserId here because
7584
// we are not currently testing their content therefore, it doesn't matter.
7685

7786
responseHandler.errors = payload.map((p) => {
78-
const errorInfo = new ErrorInfo()
79-
errorInfo.errorCode = getRandomError()
80-
errorInfo.userListId = BigInt(p.external_audience_id.split('/').pop() || '-1')
81-
errorInfo.userIdType = 0
82-
errorInfo.userId = p.google_gid || p.mobile_advertising_id || p.partner_provided_id || ''
87+
const errorInfo = protobuf.create(ErrorInfoSchema, {
88+
errorCode: getRandomError(),
89+
userListId: BigInt(p.external_audience_id.split('/').pop() || '-1'),
90+
userIdType: 0,
91+
userId: p.google_gid || p.mobile_advertising_id || p.partner_provided_id || ''
92+
})
8393
return errorInfo
8494
})
8595
}
8696

87-
const b = Buffer.from(responseHandler.toBinary())
97+
const b = Buffer.from(protobuf.toBinary(UpdateUsersDataResponseSchema, responseHandler))
8898
const arrayBuffer = b.buffer.slice(b.byteOffset, b.byteOffset + b.byteLength)
8999

90100
return new Response(arrayBuffer, { status: errorCode === ErrorCode.NO_ERROR ? 200 : 400 })
@@ -202,8 +212,19 @@ describe('shared', () => {
202212
const r = createUpdateRequest(manyMockPayloads, 'add')
203213
expect(r.ops.length).toEqual(5)
204214
expect(r.processConsent).toEqual(true)
205-
expect(r.toJsonString()).toMatchInlineSnapshot(
206-
`"{\\"ops\\":[{\\"userId\\":\\"CAESEHIV8HXNp0pFdHgi2rElMfk\\",\\"userIdType\\":\\"GOOGLE_USER_ID\\",\\"userListId\\":\\"456\\",\\"delete\\":false},{\\"userId\\":\\"3b6e47b3-1437-4ba2-b3c9-446e4d0cd1e5\\",\\"userIdType\\":\\"IDFA\\",\\"userListId\\":\\"456\\",\\"delete\\":false},{\\"userId\\":\\"my-anon-id-42\\",\\"userIdType\\":\\"PARTNER_PROVIDED_ID\\",\\"userListId\\":\\"456\\",\\"delete\\":false},{\\"userId\\":\\"my-anon-id-43\\",\\"userIdType\\":\\"PARTNER_PROVIDED_ID\\",\\"userListId\\":\\"456\\",\\"delete\\":false},{\\"userId\\":\\"XNp0pFdHgi2rElMfk\\",\\"userIdType\\":\\"GOOGLE_USER_ID\\",\\"userListId\\":\\"456\\",\\"delete\\":false}],\\"processConsent\\":true}"`
215+
expect(normalizeJson(protobuf.toJsonString(UpdateUsersDataRequestSchema, r))).toEqual(
216+
normalizeJson(
217+
JSON.stringify({
218+
ops: [
219+
{ userId: 'CAESEHIV8HXNp0pFdHgi2rElMfk', userIdType: 'GOOGLE_USER_ID', userListId: '456', delete: false },
220+
{ userId: '3b6e47b3-1437-4ba2-b3c9-446e4d0cd1e5', userIdType: 'IDFA', userListId: '456', delete: false },
221+
{ userId: 'my-anon-id-42', userIdType: 'PARTNER_PROVIDED_ID', userListId: '456', delete: false },
222+
{ userId: 'my-anon-id-43', userIdType: 'PARTNER_PROVIDED_ID', userListId: '456', delete: false },
223+
{ userId: 'XNp0pFdHgi2rElMfk', userIdType: 'GOOGLE_USER_ID', userListId: '456', delete: false }
224+
],
225+
processConsent: true
226+
})
227+
)
207228
)
208229
})
209230

@@ -230,25 +251,33 @@ describe('shared', () => {
230251
// The response will contain a list of errors. Its content is unknown.
231252
// The endpoint will return a 400 status code.
232253
it('should gracefully fail', async () => {
233-
nock('https://cm.g.doubleclick.net').post('/upload?nid=segment').reply(400)
234-
235-
UpdateUsersDataResponse.prototype.fromBinary = jest.fn(() => {
236-
const responseHandler = new UpdateUsersDataResponse()
237-
responseHandler.status = ErrorCode.PARTIAL_SUCCESS
238-
responseHandler.errors = [
239-
{
254+
jest.spyOn(protobuf, 'fromBinary').mockImplementation(() => ({
255+
status: ErrorCode.PARTIAL_SUCCESS,
256+
errors: [
257+
protobuf.create(ErrorInfoSchema, {
240258
errorCode: ErrorCode.BAD_DATA,
241259
userListId: BigInt(456),
242260
userIdType: 0,
243261
userId: 'CAESEHIV8HXNp0pFdHgi2rElMfk'
244-
} as ErrorInfo
245-
]
246-
return responseHandler
247-
})
262+
})
263+
],
264+
$typeName: 'UpdateUsersDataResponse'
265+
}))
248266

249-
const r = createUpdateRequest(manyMockPayloads, 'add')
250-
await sendUpdateRequest(mockRequestClient, r, 'addToAudience', mockStatsContext)
251-
expect(mockStatsClient.incr).toHaveBeenCalledWith('addToAudience.error.PARTIAL_SUCCESS', 1, mockStatsContext.tags)
267+
try {
268+
nock('https://cm.g.doubleclick.net').post('/upload?nid=segment').reply(400)
269+
270+
const r = createUpdateRequest(manyMockPayloads, 'add')
271+
await sendUpdateRequest(mockRequestClient, r, 'addToAudience', mockStatsContext)
272+
273+
expect(mockStatsClient.incr).toHaveBeenCalledWith(
274+
'addToAudience.error.PARTIAL_SUCCESS',
275+
1,
276+
mockStatsContext.tags
277+
)
278+
} finally {
279+
jest.restoreAllMocks()
280+
}
252281
})
253282

254283
it('should abruptly fail', async () => {

0 commit comments

Comments
 (0)