-
Notifications
You must be signed in to change notification settings - Fork 305
[Actions Core] [LinkedIn Audiences] [Linkedin Conversions] Fix LinkedIn token propagation 401s with refresh and retry #3708
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 3 commits
e39d6fc
58502ec
e4fc510
82a51a5
1246404
391b2c3
0255433
0c47c61
eebb75d
a96cf93
4c5c523
7ea5b47
5635b9e
28025c7
c28e31e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,10 @@ | ||
| import nock from 'nock' | ||
| import { createTestEvent, createTestIntegration } from '@segment/actions-core' | ||
| import { | ||
| createTestEvent, | ||
| createTestIntegration, | ||
| RefreshTokenAndRetryError, | ||
| RetryableError | ||
| } from '@segment/actions-core' | ||
| import { DynamicFieldResponse } from '@segment/actions-core' | ||
| import { BASE_URL } from '../../constants' | ||
| import Destination from '../../index' | ||
|
|
@@ -612,6 +617,83 @@ describe('LinkedinConversions.streamConversion', () => { | |
| ).rejects.toThrowError("User Info is missing the required field 'lastName'.") | ||
| }) | ||
|
|
||
| it('should throw RefreshTokenAndRetryError when LinkedIn returns 401 with token propagation error code', async () => { | ||
| nock(`${BASE_URL}/conversionEvents`).post(/.*/).reply(401, { | ||
| serviceErrorCode: 65601, | ||
| message: 'Unable to verify access token' | ||
| }) | ||
|
|
||
| await expect( | ||
| testDestination.testAction('streamConversion', { | ||
| event, | ||
| settings, | ||
| mapping: { | ||
| email: { '@path': '$.context.traits.email' }, | ||
| conversionHappenedAt: { | ||
| '@path': '$.timestamp' | ||
| }, | ||
| onMappingSave: { | ||
| inputs: {}, | ||
| outputs: { | ||
| id: 789123 | ||
| } | ||
| }, | ||
| enable_batching: true, | ||
| batch_size: 5000 | ||
| } | ||
| }) | ||
| ).rejects.toThrow(RefreshTokenAndRetryError) | ||
| }) | ||
|
|
||
| it('should refresh token and throw RetryableError for the full propagation-delay flow', async () => { | ||
| // Simulate a fresh token that hasn't propagated yet: | ||
| // the conversion call returns 401+65601, the framework then refreshes the token | ||
| // and throws RetryableError so Segment infrastructure retries later. | ||
| process.env.ACTIONS_LINKEDIN_CONVERSIONS_CLIENT_ID = 'test-client-id' | ||
| process.env.ACTIONS_LINKEDIN_CONVERSIONS_CLIENT_SECRET = 'test-client-secret' | ||
|
|
||
| nock(`${BASE_URL}/conversionEvents`).post(/.*/).reply(401, { | ||
| serviceErrorCode: 65601, | ||
| message: 'Unable to verify access token' | ||
| }) | ||
|
|
||
|
Comment on lines
+710
to
+717
|
||
| nock('https://www.linkedin.com').post('/oauth/v2/accessToken').reply(200, { | ||
| access_token: 'new-propagated-token', | ||
| expires_in: 3600 | ||
| }) | ||
|
|
||
| const onTokenRefresh = jest.fn().mockResolvedValue(undefined) | ||
|
|
||
| await expect( | ||
| testDestination.onEvent( | ||
| event, | ||
| { | ||
| subscription: { | ||
| subscribe: 'type = "track"', | ||
| partnerAction: 'streamConversion', | ||
| mapping: { | ||
| email: { '@path': '$.context.traits.email' }, | ||
| conversionHappenedAt: { '@path': '$.timestamp' }, | ||
| onMappingSave: { | ||
| inputs: {}, | ||
| outputs: { id: 789123 } | ||
| }, | ||
| enable_batching: false, | ||
| batch_size: 5000 | ||
| } | ||
| }, | ||
| oauth: { | ||
| access_token: 'old-not-yet-propagated-token', | ||
| refresh_token: 'refresh-token' | ||
| } | ||
| }, | ||
| { onTokenRefresh } | ||
| ) | ||
| ).rejects.toThrow(RetryableError) | ||
|
|
||
| expect(onTokenRefresh).toHaveBeenCalledWith({ accessToken: 'new-propagated-token' }) | ||
|
harsh-joshi99 marked this conversation as resolved.
Outdated
|
||
| }) | ||
|
|
||
| it('should detect hashed email if feature flag for smart hashing is passed', async () => { | ||
| nock(`${BASE_URL}/conversionEvents`) | ||
| .post('', { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.