Skip to content

Commit 1cfa41a

Browse files
authored
feat(recommendations): [DIS-802] Add static utm_source to url (#51)
* feat(recommendations): [DIS-802] Add static utm_source to url * chore(Recommendations): Add test for overriding utm_source
1 parent 9f00f7c commit 1cfa41a

File tree

2 files changed

+44
-2
lines changed

2 files changed

+44
-2
lines changed

src/api/desktop/recommendations/response.spec.ts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import Ajv, { DefinedError } from 'ajv';
22

33
import OpenApiSpec from '../../OpenAPISpec';
44
import Recommendations from '../../../graphql-proxy/recommendations/recommendations';
5-
import { responseTransformer } from './response';
5+
import { appendUtmSource, responseTransformer } from './response';
66
import { WebAuth } from '../../../auth/types';
77

88
jest.mock('../../../graphql-proxy/recommendations/recommendations');
@@ -47,9 +47,38 @@ describe('response', () => {
4747
if (valid) {
4848
// any additional expectations can be defined here
4949
expect(res.data.length).toEqual(30);
50+
expect(res.data[0].url.endsWith('utm_source=pocket-newtab-bff'));
5051
} else {
5152
throw validate.errors;
5253
}
5354
});
5455
});
56+
57+
describe('appendUtmSource', () => {
58+
it('should add a utm_source query parameter when input URL does not have any query parameters', () => {
59+
const url = 'https://example.com';
60+
const expected = 'https://example.com/?utm_source=pocket-newtab-bff';
61+
expect(appendUtmSource(url)).toBe(expected);
62+
});
63+
64+
it('should add a utm_source query parameter when the input URL already has a query parameter', () => {
65+
const url = 'https://example.com?foo=bar';
66+
const expected =
67+
'https://example.com/?foo=bar&utm_source=pocket-newtab-bff';
68+
expect(appendUtmSource(url)).toBe(expected);
69+
});
70+
71+
it('should add utm_source query parameter when the input URL ends with a fragment', () => {
72+
const url = 'https://example.com#my-fragment';
73+
const expected =
74+
'https://example.com/?utm_source=pocket-newtab-bff#my-fragment';
75+
expect(appendUtmSource(url)).toBe(expected);
76+
});
77+
78+
it('should override utm_source query parameter if the url already contains utm_source', () => {
79+
const url = 'https://example.com/?utm_source=fgfeed';
80+
const expected = 'https://example.com/?utm_source=pocket-newtab-bff';
81+
expect(appendUtmSource(url)).toBe(expected);
82+
});
83+
});
5584
});

src/api/desktop/recommendations/response.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,26 @@ export type RecommendationsResponse =
1212
paths['/desktop/v1/recommendations']['get']['responses']['200']['content']['application/json'];
1313
type Recommendation = components['schemas']['Recommendation'];
1414

15+
export const appendUtmSource = (url: string): string => {
16+
const urlObject = new URL(url);
17+
const searchParams = new URLSearchParams(urlObject.search);
18+
19+
// Set a static utm_source to attribute traffic to the new NewTab markets.
20+
// TODO: [DIS-803] Make utm_source unique per ScheduledSurface,
21+
// before migrating Firefox Release en-US to this API.
22+
searchParams.set('utm_source', 'pocket-newtab-bff');
23+
urlObject.search = searchParams.toString();
24+
25+
return urlObject.toString();
26+
};
27+
1528
export const mapRecommendation = (
1629
recommendation: GraphRecommendation
1730
): Recommendation => {
1831
return {
1932
__typename: 'Recommendation',
2033
tileId: recommendation.tileId,
21-
url: recommendation.corpusItem.url,
34+
url: appendUtmSource(recommendation.corpusItem.url),
2235
title: recommendation.corpusItem.title,
2336
excerpt: recommendation.corpusItem.excerpt,
2437
publisher: recommendation.corpusItem.publisher,

0 commit comments

Comments
 (0)