Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
221 changes: 116 additions & 105 deletions crates/js/lib/src/integrations/gpt/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,26 @@ interface SlotRenderEvent {
};
}

type TsNamespace = {
adSlots?: unknown;
bids?: unknown;
adInit?: () => void;
prevGptSlots?: unknown;
servicesEnabled?: boolean;
spaHookInstalled?: boolean;
divToSlotId?: Record<string, string>;
};

type TestWindow = Window & {
googletag?: unknown;
__ts_ad_slots?: unknown;
__ts_bids?: unknown;
__tsAdInit?: () => void;
__tsPrevGptSlots?: unknown;
__tsServicesEnabled?: boolean;
__tsSpaHookInstalled?: boolean;
__tsDivToSlotId?: Record<string, string>;
_ts?: TsNamespace;
};

describe('installTsAdInit', () => {
beforeEach(() => {
vi.resetModules();
delete (window as TestWindow).__ts_ad_slots;
delete (window as TestWindow).__ts_bids;
delete (window as TestWindow).__tsAdInit;
delete (window as TestWindow).__tsPrevGptSlots;
delete (window as TestWindow).__tsSpaHookInstalled;
delete (window as TestWindow).__tsDivToSlotId;
(window as TestWindow).__tsServicesEnabled = false;
const tw = window as TestWindow;
delete tw._ts;
// jsdom does not implement navigator.sendBeacon; polyfill it for tests
if (!('sendBeacon' in navigator)) {
Object.defineProperty(navigator, 'sendBeacon', {
Expand All @@ -39,7 +38,7 @@ describe('installTsAdInit', () => {
}
});

it('reads window.__ts_bids synchronously and applies bid targeting before refresh', async () => {
it('reads window._ts.bids synchronously and applies bid targeting before refresh', async () => {
const mockSlot = {
addService: vi.fn().mockReturnThis(),
setTargeting: vi.fn().mockReturnThis(),
Expand All @@ -57,30 +56,32 @@ describe('installTsAdInit', () => {
pubads: vi.fn().mockReturnValue(mockPubads),
enableServices: vi.fn(),
};
(window as TestWindow).__ts_ad_slots = [
{
id: 'atf_sidebar_ad',
gam_unit_path: '/123/atf',
div_id: 'div-atf-sidebar',
formats: [[300, 250]],
targeting: { pos: 'atf' },
},
];
(window as TestWindow).__ts_bids = {
atf_sidebar_ad: {
hb_pb: '1.00',
hb_bidder: 'kargo',
hb_adid: 'abc',
nurl: 'https://ssp/win',
burl: 'https://ssp/bill',
(window as TestWindow)._ts = {
adSlots: [
{
id: 'atf_sidebar_ad',
gam_unit_path: '/123/atf',
div_id: 'div-atf-sidebar',
formats: [[300, 250]],
targeting: { pos: 'atf' },
},
],
bids: {
atf_sidebar_ad: {
hb_pb: '1.00',
hb_bidder: 'kargo',
hb_adid: 'abc',
nurl: 'https://ssp/win',
burl: 'https://ssp/bill',
},
},
};

const fetchSpy = vi.spyOn(global, 'fetch');

const { installTsAdInit } = await import('./index');
installTsAdInit();
(window as TestWindow).__tsAdInit!();
(window as TestWindow)._ts!.adInit!();

expect(fetchSpy).not.toHaveBeenCalled();
expect(mockSlot.setTargeting).toHaveBeenCalledWith('hb_pb', '1.00');
Expand Down Expand Up @@ -114,28 +115,30 @@ describe('installTsAdInit', () => {
pubads: vi.fn().mockReturnValue(mockPubads),
enableServices: vi.fn(),
};
(window as TestWindow).__ts_ad_slots = [
{
id: 'atf_sidebar_ad',
gam_unit_path: '/123/atf',
div_id: 'div-atf-sidebar',
formats: [[300, 250]],
targeting: {},
},
];
(window as TestWindow).__ts_bids = {
atf_sidebar_ad: {
hb_pb: '1.00',
hb_bidder: 'kargo',
hb_adid: 'abc',
nurl: 'https://ssp/win',
burl: 'https://ssp/bill',
(window as TestWindow)._ts = {
adSlots: [
{
id: 'atf_sidebar_ad',
gam_unit_path: '/123/atf',
div_id: 'div-atf-sidebar',
formats: [[300, 250]],
targeting: {},
},
],
bids: {
atf_sidebar_ad: {
hb_pb: '1.00',
hb_bidder: 'kargo',
hb_adid: 'abc',
nurl: 'https://ssp/win',
burl: 'https://ssp/bill',
},
},
};

const { installTsAdInit } = await import('./index');
installTsAdInit();
(window as TestWindow).__tsAdInit!();
(window as TestWindow)._ts!.adInit!();

expect(capturedListener).toBeDefined();
capturedListener!({ isEmpty: false, slot: mockSlot });
Expand Down Expand Up @@ -168,27 +171,29 @@ describe('installTsAdInit', () => {
pubads: vi.fn().mockReturnValue(mockPubads),
enableServices: vi.fn(),
};
(window as TestWindow).__ts_ad_slots = [
{
id: 'atf_sidebar_ad',
gam_unit_path: '/123/atf',
div_id: 'div-atf-sidebar',
formats: [[300, 250]],
targeting: {},
},
];
(window as TestWindow).__ts_bids = {
atf_sidebar_ad: {
hb_pb: '1.50',
hb_bidder: 'aps',
nurl: 'https://aps/win',
burl: 'https://aps/bill',
(window as TestWindow)._ts = {
adSlots: [
{
id: 'atf_sidebar_ad',
gam_unit_path: '/123/atf',
div_id: 'div-atf-sidebar',
formats: [[300, 250]],
targeting: {},
},
],
bids: {
atf_sidebar_ad: {
hb_pb: '1.50',
hb_bidder: 'aps',
nurl: 'https://aps/win',
burl: 'https://aps/bill',
},
},
};

const { installTsAdInit } = await import('./index');
installTsAdInit();
(window as TestWindow).__tsAdInit!();
(window as TestWindow)._ts!.adInit!();

expect(capturedListener).toBeDefined();
capturedListener!({ isEmpty: false, slot: mockSlot });
Expand Down Expand Up @@ -226,28 +231,30 @@ describe('installTsAdInit', () => {
pubads: vi.fn().mockReturnValue(mockPubads),
enableServices: vi.fn(),
};
(window as TestWindow).__ts_ad_slots = [
{
id: 'atf_sidebar_ad',
gam_unit_path: '/123/atf',
div_id: 'div-atf-sidebar',
formats: [[300, 250]],
targeting: {},
},
];
(window as TestWindow).__ts_bids = {
atf_sidebar_ad: {
hb_pb: '1.00',
hb_bidder: 'kargo',
hb_adid: 'abc',
nurl: 'https://ssp/win',
burl: 'https://ssp/bill',
(window as TestWindow)._ts = {
adSlots: [
{
id: 'atf_sidebar_ad',
gam_unit_path: '/123/atf',
div_id: 'div-atf-sidebar',
formats: [[300, 250]],
targeting: {},
},
],
bids: {
atf_sidebar_ad: {
hb_pb: '1.00',
hb_bidder: 'kargo',
hb_adid: 'abc',
nurl: 'https://ssp/win',
burl: 'https://ssp/bill',
},
},
};

const { installTsAdInit } = await import('./index');
installTsAdInit();
(window as TestWindow).__tsAdInit!();
(window as TestWindow)._ts!.adInit!();
capturedListener!({ isEmpty: false, slot: mockSlotNoMatch });

expect(beaconSpy).not.toHaveBeenCalled();
Expand Down Expand Up @@ -281,30 +288,32 @@ describe('installTsAdInit', () => {
pubads: vi.fn().mockReturnValue(mockPubads),
enableServices: vi.fn(),
};
(window as TestWindow).__ts_ad_slots = [
{
id: 'atf_sidebar_ad',
gam_unit_path: '/123/atf',
div_id: 'div-atf-sidebar',
formats: [[300, 250]],
targeting: {},
(window as TestWindow)._ts = {
adSlots: [
{
id: 'atf_sidebar_ad',
gam_unit_path: '/123/atf',
div_id: 'div-atf-sidebar',
formats: [[300, 250]],
targeting: {},
},
],
bids: {
atf_sidebar_ad: { hb_pb: '1.00', hb_bidder: 'kargo', hb_adid: 'abc' },
},
];
(window as TestWindow).__ts_bids = {
atf_sidebar_ad: { hb_pb: '1.00', hb_bidder: 'kargo', hb_adid: 'abc' },
};

const { installTsAdInit } = await import('./index');
installTsAdInit();
(window as TestWindow).__tsAdInit!();
(window as TestWindow)._ts!.adInit!();

capturedListener!({ isEmpty: false, slot: arenaSlot });

expect(beaconSpy).not.toHaveBeenCalled();
beaconSpy.mockRestore();
});

it('calls refresh even when __ts_bids is empty (graceful fallback)', async () => {
it('calls refresh even when _ts.bids is empty (graceful fallback)', async () => {
const mockPubads = {
enableSingleRequest: vi.fn(),
addEventListener: vi.fn(),
Expand All @@ -319,20 +328,22 @@ describe('installTsAdInit', () => {
pubads: vi.fn().mockReturnValue(mockPubads),
enableServices: vi.fn(),
};
(window as TestWindow).__ts_ad_slots = [
{
id: 'atf_sidebar_ad',
gam_unit_path: '/123/atf',
div_id: 'div-atf-sidebar',
formats: [[300, 250]],
targeting: {},
},
];
(window as TestWindow).__ts_bids = {};
(window as TestWindow)._ts = {
adSlots: [
{
id: 'atf_sidebar_ad',
gam_unit_path: '/123/atf',
div_id: 'div-atf-sidebar',
formats: [[300, 250]],
targeting: {},
},
],
bids: {},
};

const { installTsAdInit } = await import('./index');
installTsAdInit();
(window as TestWindow).__tsAdInit!();
(window as TestWindow)._ts!.adInit!();

expect(mockPubads.refresh).toHaveBeenCalled();
});
Expand Down
Loading
Loading