@playpilot/tpi 8.10.2 → 8.11.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/.env +1 -1
  2. package/dist/editorial.mount.js +9 -9
  3. package/dist/link-injections.js +1 -1
  4. package/dist/mount.js +6 -6
  5. package/package.json +1 -1
  6. package/src/lib/data/translations.ts +5 -0
  7. package/src/lib/enums/TrackingEvent.ts +4 -4
  8. package/src/lib/fakeData.ts +32 -44
  9. package/src/lib/injection.ts +9 -10
  10. package/src/lib/modal.ts +1 -3
  11. package/src/lib/popover.ts +12 -13
  12. package/src/lib/types/injection.d.ts +0 -5
  13. package/src/routes/components/Editorial/Editor.svelte +3 -2
  14. package/src/routes/components/Editorial/EditorItem.svelte +9 -23
  15. package/src/routes/components/Editorial/ManualInjection.svelte +0 -1
  16. package/src/routes/components/Explore/ExploreLayout.svelte +9 -3
  17. package/src/routes/components/Explore/Routes/ExploreHome.svelte +6 -4
  18. package/src/routes/components/ListTitle.svelte +6 -27
  19. package/src/routes/components/Modals/RailModal.svelte +1 -1
  20. package/src/routes/components/Participant.svelte +6 -18
  21. package/src/routes/components/Playlinks/Playlinks.svelte +1 -2
  22. package/src/routes/components/Rails/TitlesRail.svelte +19 -4
  23. package/src/routes/components/Title.svelte +2 -2
  24. package/src/routes/components/{InjectionPopover.svelte → TitlePopover.svelte} +9 -26
  25. package/src/routes/elements/+page.svelte +3 -3
  26. package/src/tests/helpers.js +0 -1
  27. package/src/tests/lib/injection.test.js +3 -44
  28. package/src/tests/lib/popover.test.js +7 -7
  29. package/src/tests/routes/components/Editorial/EditorItem.test.js +0 -10
  30. package/src/tests/routes/components/Editorial/ManualInjection.test.js +0 -4
  31. package/src/tests/routes/components/Editorial/PlaylinkTypeSelect.test.js +0 -2
  32. package/src/tests/routes/components/ListTitle.test.js +0 -7
  33. package/src/tests/routes/components/Participant.test.js +0 -7
  34. package/src/tests/routes/components/Playlinks/AfterArticlePlaylinks.test.js +0 -4
  35. package/src/tests/routes/components/Playlinks/Playlinks.test.js +1 -1
  36. package/src/tests/routes/components/TitlePopover.test.js +78 -0
  37. package/src/tests/routes/components/InjectionPopover.test.js +0 -117
@@ -16,7 +16,7 @@
16
16
  titles: Promise<TitleData[]> | TitleData[]
17
17
  minimumLength?: number,
18
18
  heading?: string,
19
- size?: 'small' | 'large' | 'flexible'
19
+ size?: 'small' | 'large' | 'huge' | 'flexible'
20
20
  aside?: boolean,
21
21
  expandable?: boolean,
22
22
  expandedTitle?: TitleData | null,
@@ -64,7 +64,9 @@
64
64
  recentlyExpanded = true
65
65
  setTimeout(() => recentlyExpanded = false, 500)
66
66
 
67
- if (elementOffsetInParent < activeElement.clientWidth * 2) slider?.setIndex(index - 2)
67
+ if (size === 'flexible' && elementOffsetInParent < activeElement.clientWidth * 2) {
68
+ slider?.setIndex(index - 2)
69
+ }
68
70
 
69
71
  expandTitleIntoTrailer(title)
70
72
 
@@ -206,7 +208,7 @@
206
208
  .titles {
207
209
  --width: #{theme(rail-size-default, margin(6))};
208
210
  --image-height: #{calc(var(--width) * 3 / 2)};
209
- --expanded-width: #{calc(var(--image-height) / 9 * 16)};
211
+ --expanded-width: var(--width);
210
212
  --border-radius: #{theme(rail-border-radius, border-radius)};
211
213
 
212
214
  &.with-aside {
@@ -217,8 +219,13 @@
217
219
  --width: #{theme(rail-size-large, margin(7.5))};
218
220
  }
219
221
 
222
+ &.huge {
223
+ --width: #{theme(rail-size-large, min(explore-width(65), margin(15)))};
224
+ }
225
+
220
226
  &.flexible {
221
- --width: #{theme(rail-size-flexible, clamp(margin(6), explore-width(18), margin(11.5)))};
227
+ --width: #{theme(rail-size-flexible, clamp(margin(8), explore-width(20), margin(11.5)))};
228
+ --expanded-width: #{calc(var(--image-height) / 9 * 16)};
222
229
  }
223
230
  }
224
231
 
@@ -286,6 +293,14 @@
286
293
  :global(iframe) {
287
294
  opacity: 0;
288
295
  animation: fade-iframe 500ms 500ms forwards;
296
+
297
+ @include mobile {
298
+ position: absolute;
299
+ width: 225%;
300
+ top: 50%;
301
+ left: 50%;
302
+ transform: translateX(-50%) translateY(-50%);
303
+ }
289
304
  }
290
305
 
291
306
  :global(+ .poster) {
@@ -55,7 +55,7 @@
55
55
  <TitlePoster {title} onload={() => posterLoaded = true} lazy={false} />
56
56
  </div>
57
57
 
58
- <div class="heading" use:heading={2} class:truncate={small} id="heading">{title.title}</div>
58
+ <div class="heading" use:heading={2} class:truncate={small} id="title">{title.title}</div>
59
59
 
60
60
  <div class="info">
61
61
  <div class="imdb">
@@ -154,7 +154,7 @@
154
154
  }
155
155
 
156
156
  .header {
157
- padding: margin(10) 0 margin(1);
157
+ padding: min(margin(17), 70vw) 0 margin(1);
158
158
 
159
159
  @media (min-width: 390px) {
160
160
  display: grid;
@@ -3,48 +3,35 @@
3
3
  import { track } from '$lib/tracking'
4
4
  import { getFirstAdOfType } from '$lib/api/ads'
5
5
  import type { TitleData } from '$lib/types/title'
6
- import type { ParticipantData } from '$lib/types/participant'
7
- import type { LinkInjectionDataType } from '$lib/types/injection'
8
- import { onMount, setContext } from 'svelte'
6
+ import { onMount } from 'svelte'
9
7
  import { isPixelAllowed } from '$lib/pixel'
10
8
  import { trackViaPixel } from '@playpilot/retargeting-tracking'
11
9
  import Popover from './Popover.svelte'
12
10
  import Title from './Title.svelte'
13
- import Participant from './Participant.svelte'
14
11
  import TopScroll from './Ads/TopScroll.svelte'
15
12
  import Display from './Ads/Display.svelte'
16
13
 
17
14
  interface Props {
18
15
  event: MouseEvent
19
- data: TitleData | ParticipantData
20
- type?: LinkInjectionDataType
16
+ title: TitleData
21
17
  }
22
18
 
23
- const { event, data, type = 'title' }: Props = $props()
24
-
25
- setContext('type', type)
19
+ const { event, title }: Props = $props()
26
20
 
27
21
  const topScroll = getFirstAdOfType('top_scroll')
28
22
  const displayAd = getFirstAdOfType('card')
29
23
 
30
24
  let element: HTMLElement | null = $state(null)
31
25
 
32
- if (type === 'title') track(TrackingEvent.InjectionPopoverView, data as TitleData, { type })
33
- if (type === 'participant') track(TrackingEvent.InjectionPopoverView, null, { type, participant: (data as ParticipantData).name })
26
+ track(TrackingEvent.TitlePopoverView, title)
34
27
 
35
- if (isPixelAllowed() && type === 'title') trackViaPixel(MetaEvent.TitleInterest, { title: (data as TitleData).title, source: MetaSource.Card })
28
+ if (isPixelAllowed()) trackViaPixel(MetaEvent.TitleInterest, { title: title.title, source: MetaSource.Card })
36
29
 
37
30
  onMount(() => {
38
31
  setOffset()
39
32
 
40
33
  const openTimestamp = Date.now()
41
-
42
- return () => {
43
- const endTimestamp = Date.now() - openTimestamp
44
-
45
- if (type === 'title') track(TrackingEvent.InjectionPopoverClose, data as TitleData, { type, time_spent: endTimestamp })
46
- if (type === 'participant') track(TrackingEvent.InjectionPopoverClose, null, { type, participant: (data as ParticipantData).name, time_spent: endTimestamp })
47
- }
34
+ return () => track(TrackingEvent.TitlePopoverClose, title, { time_spent: Date.now() - openTimestamp })
48
35
  })
49
36
 
50
37
  /**
@@ -81,18 +68,14 @@
81
68
  {/if}
82
69
  {/snippet}
83
70
 
84
- <div class="injection-popover" bind:this={element} data-playpilot-injection-popover role="region" aria-labelledby="heading">
71
+ <div class="title-popover" bind:this={element} data-playpilot-title-popover role="region" aria-labelledby="title">
85
72
  <Popover append={displayAd ? append : null} bubble={topScroll ? bubble : null}>
86
- {#if type === 'title'}
87
- <Title title={data as TitleData} small />
88
- {:else if type === 'participant'}
89
- <Participant participant={data as ParticipantData} small />
90
- {/if}
73
+ <Title {title} small />
91
74
  </Popover>
92
75
  </div>
93
76
 
94
77
  <style lang="scss">
95
- .injection-popover {
78
+ .title-popover {
96
79
  position: absolute;
97
80
  }
98
81
  </style>
@@ -16,7 +16,7 @@
16
16
  import RoundButton from '../components/RoundButton.svelte'
17
17
  import SkeletonText from '../components/SkeletonText.svelte'
18
18
  import Title from '../components/Title.svelte'
19
- import InjectionPopover from '../components/InjectionPopover.svelte'
19
+ import TitlePopover from '../components/TitlePopover.svelte'
20
20
  import Tooltip from '../components/Tooltip.svelte'
21
21
  import ExploreRouter from '../components/Explore/ExploreRouter.svelte'
22
22
  import TitlesRail from '../components/Rails/TitlesRail.svelte'
@@ -69,10 +69,10 @@
69
69
  </div>
70
70
 
71
71
  <div>
72
- <h3>InjectionPopover.svelte</h3>
72
+ <h3>TitlePopover.svelte</h3>
73
73
  <div class="item">
74
74
  <div style:height="500px"></div>
75
- <InjectionPopover data={title} event={{} as MouseEvent} />
75
+ <TitlePopover {title} event={{} as MouseEvent} />
76
76
  </div>
77
77
  </div>
78
78
  </div>
@@ -44,6 +44,5 @@ export function generateInjection(sentence, title) {
44
44
  playpilot_url: 'https://some-link.com/',
45
45
  key: 'some-key-' + Math.random().toString(),
46
46
  title_details,
47
- type: 'title',
48
47
  }
49
48
  }
@@ -1,12 +1,11 @@
1
1
  import { fireEvent } from '@testing-library/svelte'
2
2
  import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest'
3
3
 
4
- import { injectLinksInDocument, clearLinkInjections, clearLinkInjection, isAvailableAsManualInjection, filterRemovedAndInactiveInjections, isEquivalentInjection, filterInvalidInTextInjections, filterInvalidAfterArticleInjections, isValidInjection, isValidPlaylinkType, removePlayPilotTitleLinks, hasValidTypeData } from '$lib/injection'
4
+ import { injectLinksInDocument, clearLinkInjections, clearLinkInjection, isAvailableAsManualInjection, filterRemovedAndInactiveInjections, isEquivalentInjection, filterInvalidInTextInjections, filterInvalidAfterArticleInjections, isValidInjection, isValidPlaylinkType, removePlayPilotTitleLinks } from '$lib/injection'
5
5
  import { mount, unmount } from 'svelte'
6
6
  import { fakeFetch, generateInjection } from '../helpers'
7
7
  import { openModalForInjectedLink } from '$lib/modal'
8
8
  import { getLinkInjectionElements } from '$lib/injectionElements'
9
- import { participants } from '$lib/fakeData'
10
9
 
11
10
  vi.mock('svelte', () => ({
12
11
  mount: vi.fn(),
@@ -569,7 +568,7 @@ describe('injection.ts', () => {
569
568
  })
570
569
 
571
570
  it('Should remove all popovers that may not have been removed properly in previous destroy attempts', async () => {
572
- document.body.innerHTML = '<div data-playpilot-injection-popover></div> <p>This is a sentence with an injection.</p>'
571
+ document.body.innerHTML = '<div data-playpilot-title-popover></div> <p>This is a sentence with an injection.</p>'
573
572
 
574
573
  const elements = Array.from(document.body.querySelectorAll('p'))
575
574
  const injection = generateInjection('This is a sentence with an injection.', 'an injection')
@@ -584,7 +583,7 @@ describe('injection.ts', () => {
584
583
  await fireEvent.mouseMove(document.body)
585
584
  vi.advanceTimersByTime(200)
586
585
 
587
- expect(document.querySelectorAll('[data-playpilot-injection-popover]')).toHaveLength(0)
586
+ expect(document.querySelectorAll('[data-playpilot-title-popover]')).toHaveLength(0)
588
587
  })
589
588
 
590
589
  it('Should inject links of the same phrase when multiple are present', () => {
@@ -947,20 +946,6 @@ describe('injection.ts', () => {
947
946
 
948
947
  expect(document.querySelector('a')?.closest('[data-playpilot-injection-key]')).toBeTruthy()
949
948
  })
950
-
951
- describe('Participants', () => {
952
- it('Should inject participants just as a title', () => {
953
- document.body.innerHTML = '<p>This is a sentence with an injection.</p>'
954
-
955
- const elements = Array.from(document.body.querySelectorAll('p'))
956
- const injection = { ...generateInjection('This is a sentence with an injection.', 'an injection'), type: 'participant', participant_details: participants[0] }
957
-
958
- // @ts-ignore
959
- injectLinksInDocument(elements, { aiInjections: [injection], manualInjections: [] })
960
-
961
- expect(document.querySelector('[data-playpilot-injection-key]')).toBeTruthy()
962
- })
963
- })
964
949
  })
965
950
 
966
951
  describe('clearLinkInjections', () => {
@@ -1142,32 +1127,6 @@ describe('injection.ts', () => {
1142
1127
  })
1143
1128
  })
1144
1129
 
1145
- describe('hasValidTypeData', () => {
1146
- it('Should return true if injection has type title and has title_details', () => {
1147
- // @ts-ignore
1148
- expect(hasValidTypeData({ type: 'title', title_details: {} })).toBe(true)
1149
- })
1150
-
1151
- it('Should return true if injection has type participant and has participant_details', () => {
1152
- // @ts-ignore
1153
- expect(hasValidTypeData({ type: 'participant', participant_details: {} })).toBe(true)
1154
- })
1155
-
1156
- it('Should return false if injection has type title but has no title_details', () => {
1157
- // @ts-ignore
1158
- expect(hasValidTypeData({ type: 'title', title_details: null })).toBe(false)
1159
- // @ts-ignore
1160
- expect(hasValidTypeData({ type: 'title' })).toBe(false)
1161
- })
1162
-
1163
- it('Should return false if injection has type participant but has no participant_details', () => {
1164
- // @ts-ignore
1165
- expect(hasValidTypeData({ type: 'participant', participant_details: null })).toBe(false)
1166
- // @ts-ignore
1167
- expect(hasValidTypeData({ type: 'participant' })).toBe(false)
1168
- })
1169
- })
1170
-
1171
1130
  describe('removePlayPilotTitleLinks', () => {
1172
1131
  it('Should remove existing title links', () => {
1173
1132
  document.body.innerHTML = `
@@ -2,7 +2,7 @@ import { describe, it, expect, beforeEach, vi } from 'vitest'
2
2
  import { linkInjections } from '$lib/fakeData'
3
3
  import { mount, unmount } from 'svelte'
4
4
  import { clearCurrentlyHoveredInjection, currentlyHoveredInjection, destroyLinkPopover, isPopoverActive, openPopoverForInjectedLink } from '$lib/popover'
5
- import InjectionPopover from '../../routes/components/InjectionPopover.svelte'
5
+ import TitlePopover from '../../routes/components/TitlePopover.svelte'
6
6
  import { waitFor } from '@testing-library/svelte'
7
7
 
8
8
  vi.mock('svelte', () => ({
@@ -22,17 +22,17 @@ describe('popover.js', () => {
22
22
  describe('openPopoverForInjectedLink', () => {
23
23
  it('Should mount popover', async () => {
24
24
  // @ts-ignore
25
- openPopoverForInjectedLink({ currentTarget: document.querySelector('a') }, linkInjections[0])
25
+ openPopoverForInjectedLink({ currentTarget: document.querySelector('a') }, linkInjections)
26
26
 
27
27
  await waitFor(() => {
28
- expect(mount).toHaveBeenCalledWith(InjectionPopover, expect.any(Object))
28
+ expect(mount).toHaveBeenCalledWith(TitlePopover, expect.any(Object))
29
29
  expect(currentlyHoveredInjection).toBeTruthy()
30
30
  })
31
31
  })
32
32
 
33
33
  it('Should not mount popover if user is no longer hovering after delay', async () => {
34
34
  // @ts-ignore
35
- openPopoverForInjectedLink({ currentTarget: document.querySelector('a') }, linkInjections[0])
35
+ openPopoverForInjectedLink({ currentTarget: document.querySelector('a') }, linkInjections)
36
36
 
37
37
  await new Promise(res => setTimeout(res, 50))
38
38
 
@@ -46,19 +46,19 @@ describe('popover.js', () => {
46
46
 
47
47
  describe('destroyLinkPopover', () => {
48
48
  it('Should not call unmount but still remove potential popover elements if no active popover is set', async () => {
49
- document.body.innerHTML = '<div data-playpilot-injection-popover></div> <div data-playpilot-injection-popover></div>'
49
+ document.body.innerHTML = '<div data-playpilot-title-popover></div> <div data-playpilot-title-popover></div>'
50
50
 
51
51
  destroyLinkPopover()
52
52
 
53
53
  expect(unmount).not.toHaveBeenCalled()
54
- expect(document.querySelectorAll('[data-playpilot-injection-popover]')).toHaveLength(0)
54
+ expect(document.querySelectorAll('[data-playpilot-title-popover]')).toHaveLength(0)
55
55
  })
56
56
  })
57
57
 
58
58
  describe('clearCurrentlyHoveredInjection', () => {
59
59
  it('Should clear currentlyHoveredInjection', async () => {
60
60
  // @ts-ignore
61
- openPopoverForInjectedLink({ currentTarget: document.querySelector('a') }, linkInjections[0])
61
+ openPopoverForInjectedLink({ currentTarget: document.querySelector('a') }, linkInjections)
62
62
 
63
63
  await waitFor(() => expect(currentlyHoveredInjection).toBeTruthy())
64
64
 
@@ -6,7 +6,6 @@ import { injectLinksInDocument } from '$lib/injection'
6
6
  import { track } from '$lib/tracking'
7
7
  import { generateInjection } from '../../../helpers'
8
8
  import { removeImageUrlPrefix } from '$lib/image'
9
- import { linkInjections as fakeLinkInjections } from '$lib/fakeData'
10
9
 
11
10
  vi.mock('$lib/tracking', () => ({
12
11
  track: vi.fn(),
@@ -201,13 +200,4 @@ describe('EditorItem.svelte', () => {
201
200
 
202
201
  expect(getByText('What would you like to report?')).toBeTruthy()
203
202
  })
204
-
205
- it('Should render as participant when type is participant', () => {
206
- const { container, queryByLabelText, getByText } = render(EditorItem, { linkInjection: fakeLinkInjections[4] })
207
-
208
- expect(queryByLabelText('Expand')).not.toBeTruthy()
209
- expect(getByText(fakeLinkInjections[4].participant_details?.name || '-')).toBeTruthy()
210
- expect(container.querySelector('.poster')).not.toBeTruthy()
211
- expect(container.querySelector('.placeholder-image')).toBeTruthy()
212
- })
213
203
  })
@@ -99,7 +99,6 @@ describe('ManualInjection.svelte', () => {
99
99
  manual: true,
100
100
  phrase_before: 'Some',
101
101
  phrase_after: 'in a',
102
- type: 'title',
103
102
  })
104
103
  })
105
104
 
@@ -142,7 +141,6 @@ describe('ManualInjection.svelte', () => {
142
141
  manual: true,
143
142
  phrase_before: '',
144
143
  phrase_after: '',
145
- type: 'title',
146
144
  })
147
145
  })
148
146
 
@@ -185,7 +183,6 @@ describe('ManualInjection.svelte', () => {
185
183
  manual: true,
186
184
  phrase_before: expect.any(String),
187
185
  phrase_after: expect.any(String),
188
- type: 'title',
189
186
  })
190
187
  })
191
188
 
@@ -228,7 +225,6 @@ describe('ManualInjection.svelte', () => {
228
225
  manual: true,
229
226
  phrase_before: expect.any(String),
230
227
  phrase_after: expect.any(String),
231
- type: 'title',
232
228
  })
233
229
  })
234
230
 
@@ -11,8 +11,6 @@ describe('PlaylinkTypeSelect.svelte', () => {
11
11
  sentence: 'Some sentence',
12
12
  playpilot_url: 'https://playpilot.com/movie/example-3/',
13
13
  key: 'some-key',
14
- /** @type {import('$lib/types/injection').LinkInjectionDataType} */
15
- type: 'title',
16
14
  }
17
15
 
18
16
  beforeEach(() => {
@@ -50,13 +50,6 @@ describe('ListTitle.svelte', () => {
50
50
  expect(onclick).toHaveBeenCalled()
51
51
  })
52
52
 
53
- it('Should render as small variant when given', () => {
54
- const { container } = render(ListTitle, { title, compact: true })
55
-
56
- expect(container.querySelector('.compact')).toBeTruthy()
57
- expect(container.querySelector('.description')).not.toBeTruthy()
58
- })
59
-
60
53
  describe('Playlinks', () => {
61
54
  const playlinks = [
62
55
  { name: 'Some playlink', logo_url: 'logo', extra_info: { category: 'SVOD' } },
@@ -73,11 +73,4 @@ describe('Participant.svelte', () => {
73
73
 
74
74
  expect(fetchTitlesForParticipant).toHaveBeenCalledWith(participants[0], { page: 2 })
75
75
  })
76
-
77
- it('Should render as small variant when given', () => {
78
- const { container, queryByText } = render(Participant, { participant: participants[0], small: true })
79
-
80
- expect(queryByText('Credits')).not.toBeTruthy()
81
- expect(container.querySelector('.small')).toBeTruthy()
82
- })
83
76
  })
@@ -23,8 +23,6 @@ const linkInjections = [{
23
23
  poster: 'some-poster',
24
24
  key: 'some-key-1',
25
25
  title_details: title,
26
- /** @type {import('$lib/types/injection').LinkInjectionDataType} */
27
- type: 'title',
28
26
  }, {
29
27
  sid: '2',
30
28
  title: 'a sentence',
@@ -33,8 +31,6 @@ const linkInjections = [{
33
31
  poster: 'some-poster',
34
32
  key: 'some-key-1',
35
33
  title_details: title,
36
- /** @type {import('$lib/types/injection').LinkInjectionDataType} */
37
- type: 'title',
38
34
  }]
39
35
 
40
36
  describe('AfterArticlePlaylinks.svelte', () => {
@@ -85,7 +85,7 @@ describe('Playlinks.svelte', () => {
85
85
 
86
86
  await fireEvent.click(getByText(playlinks[0].name))
87
87
 
88
- expect(track).toHaveBeenCalledWith(TrackingEvent.InjectionPopoverPlaylinkClick, title, { playlink: playlinks[0].name })
88
+ expect(track).toHaveBeenCalledWith(TrackingEvent.TitlePopoverPlaylinkClick, title, { playlink: playlinks[0].name })
89
89
  })
90
90
 
91
91
  it('Should call track function for modal when clicked inside of modal scope', async () => {
@@ -0,0 +1,78 @@
1
+ import { render } from '@testing-library/svelte'
2
+ import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest'
3
+
4
+ import TitlePopover from '../../../routes/components/TitlePopover.svelte'
5
+ import { title } from '$lib/fakeData'
6
+ import { track } from '$lib/tracking'
7
+ import { TrackingEvent } from '$lib/enums/TrackingEvent'
8
+ import { hasConsentedTo } from '$lib/consent'
9
+
10
+ vi.mock('$lib/consent', () => ({
11
+ hasConsentedTo: vi.fn(() => true),
12
+ }))
13
+
14
+ vi.mock('$lib/tracking', () => ({
15
+ track: vi.fn(),
16
+ }))
17
+
18
+ vi.mock('$lib/pixel', () => ({
19
+ isPixelAllowed: vi.fn(),
20
+ }))
21
+
22
+ vi.mock('$lib/api/participants', () => ({
23
+ fetchParticipantsForTitle: vi.fn(),
24
+ }))
25
+
26
+ vi.mock('$lib/api/titles', () => ({
27
+ fetchSimilarTitles: vi.fn(),
28
+ }))
29
+
30
+ describe('TitlePopover.svelte', () => {
31
+ beforeEach(() => {
32
+ vi.resetAllMocks()
33
+ vi.mocked(hasConsentedTo).mockImplementation(() => true)
34
+ })
35
+
36
+ afterEach(() => {
37
+ vi.useRealTimers()
38
+ })
39
+
40
+ it('Should call track function when rendered', () => {
41
+ const event = new MouseEvent('mouseenter')
42
+ render(TitlePopover, { event, title })
43
+
44
+ expect(track).toHaveBeenCalledWith(TrackingEvent.TitlePopoverView, title)
45
+ })
46
+
47
+ it('Should call track function with time_spent when destroyed', async () => {
48
+ vi.useFakeTimers()
49
+
50
+ const event = new MouseEvent('mouseenter')
51
+ const { unmount } = render(TitlePopover, { event, title })
52
+
53
+ vi.advanceTimersByTime(200)
54
+ unmount()
55
+
56
+ expect(track).toHaveBeenCalledWith(TrackingEvent.TitlePopoverClose, title, expect.objectContaining({ time_spent: 200 }))
57
+ })
58
+
59
+ it('Should render top scroll ad when given', () => {
60
+ // @ts-ignore
61
+ window.PlayPilotLinkInjections = { ads: [{ campaign_format: 'top_scroll', content: {}, cta: {} }] }
62
+
63
+ const event = new MouseEvent('mouseenter')
64
+ const { container } = render(TitlePopover, { event, title })
65
+
66
+ expect(container.querySelector('.top-scroll')).toBeTruthy()
67
+ })
68
+
69
+ it('Should not render top scroll ad when not given', () => {
70
+ // @ts-ignore
71
+ window.PlayPilotLinkInjections = { ads: null }
72
+
73
+ const event = new MouseEvent('mouseenter')
74
+ const { container } = render(TitlePopover, { event, title })
75
+
76
+ expect(container.querySelector('.top-scroll')).not.toBeTruthy()
77
+ })
78
+ })
@@ -1,117 +0,0 @@
1
- import { render } from '@testing-library/svelte'
2
- import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest'
3
-
4
- import InjectionPopover from '../../../routes/components/InjectionPopover.svelte'
5
- import { participants, title } from '$lib/fakeData'
6
- import { track } from '$lib/tracking'
7
- import { TrackingEvent } from '$lib/enums/TrackingEvent'
8
- import { hasConsentedTo } from '$lib/consent'
9
-
10
- vi.mock('$lib/consent', () => ({
11
- hasConsentedTo: vi.fn(() => true),
12
- }))
13
-
14
- vi.mock('$lib/tracking', () => ({
15
- track: vi.fn(),
16
- }))
17
-
18
- vi.mock('$lib/pixel', () => ({
19
- isPixelAllowed: vi.fn(),
20
- }))
21
-
22
- vi.mock('$lib/api/participants', () => ({
23
- fetchParticipantsForTitle: vi.fn(),
24
- }))
25
-
26
- vi.mock('$lib/api/titles', () => ({
27
- fetchSimilarTitles: vi.fn(),
28
- }))
29
-
30
- describe('InjectionPopover.svelte', () => {
31
- beforeEach(() => {
32
- vi.resetAllMocks()
33
- vi.mocked(hasConsentedTo).mockImplementation(() => true)
34
- })
35
-
36
- afterEach(() => {
37
- vi.useRealTimers()
38
- })
39
-
40
- it('Should render top scroll ad when given', () => {
41
- // @ts-ignore
42
- window.PlayPilotLinkInjections = { ads: [{ campaign_format: 'top_scroll', content: {}, cta: {} }] }
43
-
44
- const event = new MouseEvent('mouseenter')
45
- const { container } = render(InjectionPopover, { event, type: 'title', data: title })
46
-
47
- expect(container.querySelector('.top-scroll')).toBeTruthy()
48
- })
49
-
50
- it('Should not render top scroll ad when not given', () => {
51
- // @ts-ignore
52
- window.PlayPilotLinkInjections = { ads: null }
53
-
54
- const event = new MouseEvent('mouseenter')
55
- const { container } = render(InjectionPopover, { event, type: 'title', data: title })
56
-
57
- expect(container.querySelector('.top-scroll')).not.toBeTruthy()
58
- })
59
-
60
- describe('Title type', () => {
61
- it('Should render the given title', () => {
62
- const event = new MouseEvent('mouseenter')
63
- const { getByText } = render(InjectionPopover, { event, type: 'title', data: title })
64
-
65
- expect(getByText(title.title)).toBeTruthy()
66
- })
67
-
68
- it('Should call track function when rendered', () => {
69
- const event = new MouseEvent('mouseenter')
70
- render(InjectionPopover, { event, type: 'title', data: title })
71
-
72
- expect(track).toHaveBeenCalledWith(TrackingEvent.InjectionPopoverView, title, { type: 'title' })
73
- })
74
-
75
- it('Should call track function with time_spent when destroyed', async () => {
76
- vi.useFakeTimers()
77
-
78
- const event = new MouseEvent('mouseenter')
79
- const { unmount } = render(InjectionPopover, { event, type: 'title', data: title })
80
-
81
- vi.advanceTimersByTime(200)
82
- unmount()
83
-
84
- expect(track).toHaveBeenCalledWith(TrackingEvent.InjectionPopoverClose, title, expect.objectContaining({ time_spent: 200, type: 'title' }))
85
- })
86
- })
87
-
88
- describe('Participant type', () => {
89
- const participant = participants[0]
90
-
91
- it('Should render the given participant', () => {
92
- const event = new MouseEvent('mouseenter')
93
- const { getByText } = render(InjectionPopover, { event, type: 'participant', data: participant })
94
-
95
- expect(getByText(participant.name)).toBeTruthy()
96
- })
97
-
98
- it('Should call track function when rendered', () => {
99
- const event = new MouseEvent('mouseenter')
100
- render(InjectionPopover, { event, type: 'participant', data: participant })
101
-
102
- expect(track).toHaveBeenCalledWith(TrackingEvent.InjectionPopoverView, null, { type: 'participant', participant: participant.name })
103
- })
104
-
105
- it('Should call track function with time_spent when destroyed', async () => {
106
- vi.useFakeTimers()
107
-
108
- const event = new MouseEvent('mouseenter')
109
- const { unmount } = render(InjectionPopover, { event, type: 'participant', data: participant })
110
-
111
- vi.advanceTimersByTime(200)
112
- unmount()
113
-
114
- expect(track).toHaveBeenCalledWith(TrackingEvent.InjectionPopoverClose, null, expect.objectContaining({ type: 'participant', time_spent: 200, participant: participant.name }))
115
- })
116
- })
117
- })