@playpilot/tpi 5.22.0 → 5.23.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.
package/events.md CHANGED
@@ -37,6 +37,7 @@ Event | Action | Info | Payload
37
37
  `ali_participant_modal_view` | _Fires any time a title modal is viewed_ | The title modal opens when viewing a participant modal both on desktop and mobile | `participant` (name of the participant)
38
38
  `ali_participant_modal_close` | _Fires any time a title modal is closed_ | | `participant` (name of the participant) `time_spent` (time between modal_view and modal_close milliseconds)
39
39
  'ali_similar_title_click' | _Fires any time a similar titles rail item is clicked_ | Title | `title_source` (original name of the title the rail item was clicked in)
40
+ 'ali_participant_click' | _Fires any time a participants rail item is clicked_ | null | `title_source` (original name of the title the rail item was clicked in), `participant` (name of the clicked participant)
40
41
 
41
42
  ### Popover
42
43
  Event | Action | Info | Payload
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@playpilot/tpi",
3
- "version": "5.22.0",
3
+ "version": "5.23.0-beta.1",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "dev": "vite dev",
@@ -0,0 +1,16 @@
1
+ import { getApiToken } from '$lib/token'
2
+ import type { ParticipantData } from '$lib/types/participant'
3
+ import type { TitleData } from '../types/title'
4
+ import { api } from './api'
5
+
6
+ export async function fetchTitlesForParticipant(participant: ParticipantData, { page = 1 }: { page?: number } = {}): Promise<TitleData[]> {
7
+ const response = await api<{ results: TitleData[] }>(`/titles/browse?api-token=${getApiToken()}&participant_sid=${participant.sid}&page=${page}`)
8
+
9
+ return response.results
10
+ }
11
+
12
+ export async function fetchParticipantsForTitle(title: TitleData): Promise<ParticipantData[]> {
13
+ const response = await api<{ results: ParticipantData[] }>(`/participants/browse?api-token=${getApiToken()}&title_sid=${title.sid}`)
14
+
15
+ return response.results
16
+ }
@@ -0,0 +1,9 @@
1
+ import { getApiToken } from '$lib/token'
2
+ import type { TitleData } from '../types/title'
3
+ import { api } from './api'
4
+
5
+ export async function fetchSimilarTitles(title: TitleData): Promise<TitleData[]> {
6
+ const response = await api<{ results: TitleData[] }>(`/titles/browse?api-token=${getApiToken()}&related_to_sid=${title.sid}`)
7
+
8
+ return response.results
9
+ }
@@ -101,6 +101,11 @@ export const translations = {
101
101
  [Language.Swedish]: 'Få',
102
102
  [Language.Danish]: 'Få',
103
103
  },
104
+ 'Show More': {
105
+ [Language.English]: 'Show more',
106
+ [Language.Swedish]: 'Visa mer',
107
+ [Language.Danish]: 'Vis mere',
108
+ },
104
109
 
105
110
  // Genres
106
111
  'All': {
@@ -22,6 +22,7 @@ export const TrackingEvent = Object.freeze({
22
22
 
23
23
  // Rails
24
24
  SimilarTitleClick: 'ali_similar_title_click',
25
+ ParticipantClick: 'ali_title_participant_click',
25
26
 
26
27
  // After article
27
28
  AfterArticlePlaylinkClick: 'ali_after_article_playlink_click',
@@ -29,7 +29,7 @@
29
29
  }
30
30
  </script>
31
31
 
32
- <a class="title" href={titleUrl(title)} {onclick}>
32
+ <a class="title" href={titleUrl(title)} {onclick} data-testid="title">
33
33
  <div class="poster">
34
34
  <TitlePoster {title} width={30} height={43} />
35
35
  </div>
@@ -89,7 +89,7 @@
89
89
  display: flex;
90
90
  align-items: center;
91
91
  width: 100%;
92
- background: var(--playpilot-list-item-background, var(--playpilot-lighter));
92
+ background: var(--playpilot-list-item-background, var(--playpilot-playlink-background, var(--playpilot-lighter)));
93
93
  padding: margin(0.5);
94
94
  border: 0;
95
95
  border-radius: var(--playpilot-list-item-border-radius, margin(0.5));
@@ -97,7 +97,7 @@
97
97
  font-style: normal !important;
98
98
 
99
99
  &:hover {
100
- background: var(--playpilot-list-item-hover-background, var(--playpilot-content));
100
+ filter: var(--playpilot-list-item-hover-filter, var(--playpilot-playlink-hover-filter, brightness(1.1)));
101
101
  }
102
102
 
103
103
  &:last-child {
@@ -112,7 +112,7 @@
112
112
  width: margin(4.125);
113
113
  aspect-ratio: 2/3;
114
114
  border-radius: var(--playpilot-detail-image-border-radius, margin(0.5));
115
- background: var(--playpilot-detail-image-background, var(--playpilot-content));
115
+ background: var(--playpilot-detail-image-background, var(--playpilot-genre-background, var(--playpilot-content)));
116
116
  overflow: hidden;
117
117
  }
118
118
 
@@ -1,10 +1,14 @@
1
1
  <script lang="ts">
2
+ import { onMount } from 'svelte'
2
3
  import { heading } from '$lib/actions/heading'
4
+ import { fetchTitlesForParticipant } from '$lib/api/participants'
3
5
  import { SplitTest } from '$lib/enums/SplitTest'
4
6
  import { openModal } from '$lib/modal'
5
7
  import { trackSplitTestView } from '$lib/splitTest'
6
8
  import type { ParticipantData } from '$lib/types/participant'
9
+ import type { TitleData } from '$lib/types/title'
7
10
  import ListTitle from './ListTitle.svelte'
11
+ import { t } from '$lib/localization'
8
12
 
9
13
  interface Props {
10
14
  participant: ParticipantData
@@ -14,12 +18,37 @@
14
18
 
15
19
  const { name, birth_date, death_date } = $derived(participant)
16
20
 
21
+ const pageSize = 30
22
+
17
23
  trackSplitTestView(SplitTest.ParticipantPlaylinkFormat)
18
24
 
25
+ let titles: TitleData[] = $state([])
26
+ let page = $state(1)
27
+ let hasMorePages = $state(true)
28
+ let loading = $state(true)
29
+
30
+ onMount(loadMore)
31
+
19
32
  function formatDate(dateString: string): string {
20
33
  const date = new Date(dateString)
21
34
  return date.toLocaleDateString(undefined, { year: 'numeric', month: 'long', day: 'numeric' })
22
35
  }
36
+
37
+ async function loadMore() {
38
+ loading = true
39
+
40
+ try {
41
+ const results = await fetchTitlesForParticipant(participant, { page })
42
+
43
+ titles = [...titles, ...results]
44
+ hasMorePages = results?.length >= pageSize
45
+ } catch {
46
+ hasMorePages = false
47
+ } finally {
48
+ loading = false
49
+ page += 1
50
+ }
51
+ }
23
52
  </script>
24
53
 
25
54
  <div class="header">
@@ -36,11 +65,17 @@
36
65
  <div class="heading small" use:heading={3} id="credits">Credits</div>
37
66
 
38
67
  <div class="list">
39
- {#each window.PlayPilotLinkInjections?.evaluated_link_injections?.map(i => i.title_details) || [] as title}
40
- {#if title}
41
- <ListTitle {title} onclick={(event) => openModal({ event, data: title })} />
42
- {/if}
68
+ {#each titles as title}
69
+ <ListTitle {title} onclick={(event) => openModal({ event, data: title })} />
43
70
  {/each}
71
+
72
+ {#if loading}
73
+ {#each { length: 6 }}
74
+ <div class="skeleton" data-testid="skeleton"></div>
75
+ {/each}
76
+ {:else if hasMorePages}
77
+ <button class="more" onclick={loadMore}>{t('Show More')}</button>
78
+ {/if}
44
79
  </div>
45
80
  </div>
46
81
 
@@ -89,4 +124,26 @@
89
124
  flex-direction: column;
90
125
  gap: margin(0.5);
91
126
  }
127
+
128
+ .skeleton {
129
+ min-height: margin(7.25);
130
+ border-radius: var(--playpilot-playlink-border-radius, margin(0.5));
131
+ background: var(--playpilot-list-item-background, var(--playpilot-lighter));
132
+ }
133
+
134
+ .more {
135
+ cursor: pointer;
136
+ appearance: none;
137
+ padding: margin(0.5) margin(1);
138
+ border: 0;
139
+ border-radius: var(--playpilot-participants-load-more-border-radius, var(--playpilot-list-item-border-radius, margin(0.5)));
140
+ background: var(--playpilot-participants-load-more-background, var(--playpilot-button-background, var(--playpilot-content)));
141
+ color: inherit;
142
+ font-size: inherit;
143
+ font-family: inherit;
144
+
145
+ &:hover {
146
+ filter: brightness(1.2);
147
+ }
148
+ }
92
149
  </style>
@@ -1,18 +1,25 @@
1
1
  <script lang="ts">
2
- import { participants } from '$lib/fakeData'
2
+ import { fetchParticipantsForTitle } from '$lib/api/participants'
3
+ import { TrackingEvent } from '$lib/enums/TrackingEvent'
3
4
  import { openModal } from '$lib/modal'
5
+ import { track } from '$lib/tracking'
4
6
  import type { ParticipantData } from '$lib/types/participant'
7
+ import type { TitleData } from '$lib/types/title'
5
8
  import Rail from './Rail.svelte'
6
9
 
7
- async function fetchParticipants(): Promise<ParticipantData[]> {
8
- // This is just a fake loading state for now
9
- await new Promise(res => setTimeout(res, 500))
10
+ interface Props {
11
+ title: TitleData
12
+ }
13
+
14
+ const { title }: Props = $props()
10
15
 
11
- return participants
16
+ function onclick(event: MouseEvent, participant: ParticipantData): void {
17
+ openModal({ event, type: 'participant', data: participant })
18
+ track(TrackingEvent.ParticipantClick, null, { title_source: title.original_title, participant: participant.name })
12
19
  }
13
20
  </script>
14
21
 
15
- {#await fetchParticipants()}
22
+ {#await fetchParticipantsForTitle(title)}
16
23
  <Rail heading="Cast">
17
24
  {#each { length: 5 }}
18
25
  <div class="participant"></div>
@@ -22,10 +29,12 @@
22
29
  {#if participants?.length}
23
30
  <Rail heading="Cast">
24
31
  {#each participants.slice(0, 15) as participant}
25
- <button class="participant" data-testid="participant" onclick={event => openModal({ event, type: 'participant', data: participant })}>
32
+ <button class="participant" data-testid="participant" onclick={event => onclick(event, participant)}>
26
33
  <span class="truncate">{participant.name}</span>
27
34
 
28
- <div class="character truncate">{participant.character}</div>
35
+ {#if participant.character}
36
+ <div class="character truncate">{participant.character}</div>
37
+ {/if}
29
38
  </button>
30
39
  {/each}
31
40
  </Rail>
@@ -34,7 +43,8 @@
34
43
 
35
44
  <style lang="scss">
36
45
  .participant {
37
- display: block;
46
+ display: flex;
47
+ flex-direction: column;
38
48
  flex: 0 0 10rem;
39
49
  width: 10rem;
40
50
  min-height: margin(3.375); // Matches 54 pixels, the height of a card with both name and character
@@ -1,4 +1,5 @@
1
1
  <script lang="ts">
2
+ import { fetchSimilarTitles } from '$lib/api/titles'
2
3
  import { TrackingEvent } from '$lib/enums/TrackingEvent'
3
4
  import { track } from '$lib/tracking'
4
5
  import type { TitleData } from '$lib/types/title'
@@ -10,15 +11,7 @@
10
11
 
11
12
  const { title }: Props = $props()
12
13
 
13
- const titles = fetchTitles()
14
-
15
- async function fetchTitles(): Promise<TitleData[]> {
16
- // This is just a fake loading state for now
17
- await new Promise(res => setTimeout(res, 500))
18
-
19
- // Imagine this being a fetch request that returns titles instead.
20
- return (window.PlayPilotLinkInjections?.evaluated_link_injections?.map(i => i.title_details) || []) as TitleData[]
21
- }
14
+ const titles = fetchSimilarTitles(title)
22
15
  </script>
23
16
 
24
17
  <TitlesRail {titles} heading="Similar movies & shows" onclick={(targetTitle) => track(TrackingEvent.SimilarTitleClick, targetTitle, { title_source: title.original_title })} />
@@ -55,11 +55,8 @@
55
55
  <Description text={title.description} blurb={title.blurb} />
56
56
  {/if}
57
57
 
58
- <!-- Temporarily not available on production as there is not yet an API endpoint for either -->
59
- {#if process.env.NODE_ENV !== 'production'}
60
- <ParticipantsRail />
61
- <SimilarRail {title} />
62
- {/if}
58
+ <ParticipantsRail {title} />
59
+ <SimilarRail {title} />
63
60
  </div>
64
61
  </div>
65
62
 
@@ -26,5 +26,6 @@
26
26
  display: block;
27
27
  width: 100%;
28
28
  height: auto;
29
+ color: var(--playpilot-detail-text-color, var(--playpilot-text-color-alt));
29
30
  }
30
31
  </style>
@@ -0,0 +1,76 @@
1
+ import { fireEvent, render, waitFor } from '@testing-library/svelte'
2
+ import { describe, expect, it, vi, beforeEach } from 'vitest'
3
+
4
+ import Participant from '../../../routes/components/Participant.svelte'
5
+ import { participants, title } from '$lib/fakeData'
6
+ import { fetchTitlesForParticipant } from '$lib/api/participants'
7
+
8
+ vi.mock('$lib/tracking', () => ({
9
+ track: vi.fn(),
10
+ }))
11
+
12
+ vi.mock('$lib/api/participants', () => ({
13
+ fetchTitlesForParticipant: vi.fn(),
14
+ }))
15
+
16
+ describe('Participant.svelte', () => {
17
+ beforeEach(() => {
18
+ vi.resetAllMocks()
19
+ })
20
+
21
+ it('Should call fetchTitlesForParticipant on mount', () => {
22
+ render(Participant, { participant: participants[0] })
23
+
24
+ expect(fetchTitlesForParticipant).toHaveBeenCalledWith(participants[0], { page: 1 })
25
+ })
26
+
27
+ it('Should render fetched titles after showing skeletons', async () => {
28
+ vi.mocked(fetchTitlesForParticipant).mockResolvedValueOnce([title, title])
29
+
30
+ const { getAllByTestId } = render(Participant, { participant: participants[0] })
31
+
32
+ expect(getAllByTestId('skeleton')).toHaveLength(6)
33
+
34
+ await waitFor(() => {
35
+ expect(getAllByTestId('title')).toHaveLength(2)
36
+ })
37
+ })
38
+
39
+ it('Should not show load more button while loading and when fewer than page size of titles are fetched', async () => {
40
+ vi.mocked(fetchTitlesForParticipant).mockResolvedValueOnce([title, title])
41
+
42
+ const { queryByText, getAllByTestId } = render(Participant, { participant: participants[0] })
43
+
44
+ expect(queryByText('Show More')).not.toBeTruthy()
45
+
46
+ await waitFor(() => {
47
+ expect(getAllByTestId('title')).toHaveLength(2)
48
+ })
49
+
50
+ expect(queryByText('Show More')).not.toBeTruthy()
51
+ })
52
+
53
+ it('Should show load more button after loading and if more than page size of titles are fetched', async () => {
54
+ const resolved = Array(30).fill(title)
55
+ vi.mocked(fetchTitlesForParticipant).mockResolvedValueOnce(resolved)
56
+
57
+ const { getByText } = render(Participant, { participant: participants[0] })
58
+
59
+ await waitFor(() => {
60
+ expect(getByText('Show more')).toBeTruthy()
61
+ })
62
+ })
63
+
64
+ it('Should fetch more titles when load more button is clicked', async () => {
65
+ const resolved = Array(30).fill(title)
66
+ vi.mocked(fetchTitlesForParticipant).mockResolvedValueOnce(resolved)
67
+
68
+ const { getByText } = render(Participant, { participant: participants[0] })
69
+
70
+ await waitFor(() => getByText('Show more'))
71
+
72
+ await fireEvent.click(getByText('Show more'))
73
+
74
+ expect(fetchTitlesForParticipant).toHaveBeenCalledWith(participants[0], { page: 2 })
75
+ })
76
+ })
@@ -14,6 +14,10 @@ vi.mock('$lib/tracking', () => ({
14
14
  track: vi.fn(),
15
15
  }))
16
16
 
17
+ vi.mock('$lib/api/participants', () => ({
18
+ fetchTitlesForParticipant: vi.fn(),
19
+ }))
20
+
17
21
  describe('ParticipantModal.svelte', () => {
18
22
  beforeEach(() => {
19
23
  vi.resetAllMocks()
@@ -1,18 +1,31 @@
1
1
  import { fireEvent, render, waitFor } from '@testing-library/svelte'
2
- import { describe, expect, it, vi } from 'vitest'
2
+ import { beforeEach, describe, expect, it, vi } from 'vitest'
3
3
 
4
4
  import ParticipantsRail from '../../../../routes/components/Rails/ParticipantsRail.svelte'
5
5
  import { openModal } from '$lib/modal'
6
- import { participants } from '$lib/fakeData'
6
+ import { participants, title } from '$lib/fakeData'
7
+ import { track } from '$lib/tracking'
8
+ import { TrackingEvent } from '$lib/enums/TrackingEvent'
9
+ import { fetchParticipantsForTitle } from '$lib/api/participants'
7
10
 
8
11
  vi.mock('$lib/modal', () => ({
9
12
  openModal: vi.fn(),
10
13
  }))
11
14
 
15
+ vi.mock('$lib/tracking', () => ({
16
+ track: vi.fn(),
17
+ }))
18
+
19
+ vi.mock('$lib/api/participants', () => ({
20
+ fetchParticipantsForTitle: vi.fn(),
21
+ }))
22
+
12
23
  describe('ParticipantsRail.svelte', () => {
13
24
  it('Should render each given participant', async () => {
25
+ vi.mocked(fetchParticipantsForTitle).mockResolvedValueOnce(participants)
26
+
14
27
  // @ts-ignore
15
- const { getByText } = render(ParticipantsRail)
28
+ const { getByText } = render(ParticipantsRail, { title })
16
29
 
17
30
  await waitFor(() => {
18
31
  expect(getByText(participants[0].name)).toBeTruthy()
@@ -20,15 +33,20 @@ describe('ParticipantsRail.svelte', () => {
20
33
  })
21
34
  })
22
35
 
23
- // TODO: Re-enable when participants are actually fetched
24
- // it('Should not render when no participants are returned', () => {
25
- // const { container } = render(ParticipantsRail)
36
+ it('Should not render when no participants are returned', async () => {
37
+ vi.mocked(fetchParticipantsForTitle).mockResolvedValueOnce([])
26
38
 
27
- // expect(container.querySelectorAll('.participant').length).toBe(0)
28
- // })
39
+ const { container } = render(ParticipantsRail)
40
+
41
+ await waitFor(() => {
42
+ expect(container.querySelectorAll('.participant').length).toBe(0)
43
+ })
44
+ })
29
45
 
30
46
  it('Should open modal on click of participant', async () => {
31
- const { getAllByTestId } = render(ParticipantsRail)
47
+ vi.mocked(fetchParticipantsForTitle).mockResolvedValueOnce(participants)
48
+
49
+ const { getAllByTestId } = render(ParticipantsRail, { title })
32
50
 
33
51
  await waitFor(async () => {
34
52
  await fireEvent.click(getAllByTestId('participant')[0])
@@ -36,4 +54,16 @@ describe('ParticipantsRail.svelte', () => {
36
54
 
37
55
  expect(openModal).toHaveBeenCalledWith({ event: expect.any(Object), type: 'participant', data: participants[0] })
38
56
  })
57
+
58
+ it('Should fire track event on click of participant', async () => {
59
+ vi.mocked(fetchParticipantsForTitle).mockResolvedValueOnce(participants)
60
+
61
+ const { getAllByTestId } = render(ParticipantsRail, { title })
62
+
63
+ await waitFor(async () => {
64
+ await fireEvent.click(getAllByTestId('participant')[0])
65
+ })
66
+
67
+ expect(track).toHaveBeenCalledWith(TrackingEvent.ParticipantClick, null, { title_source: title.original_title, participant: participants[0].name })
68
+ })
39
69
  })
@@ -0,0 +1,26 @@
1
+ import { render } from '@testing-library/svelte'
2
+ import { describe, expect, it, vi } from 'vitest'
3
+
4
+ import { title } from '$lib/fakeData'
5
+ import SimilarRail from '../../../../routes/components/Rails/SimilarRail.svelte'
6
+ import { fetchSimilarTitles } from '$lib/api/titles'
7
+
8
+ vi.mock('$lib/modal', () => ({
9
+ openModal: vi.fn(),
10
+ }))
11
+
12
+ vi.mock('$lib/tracking', () => ({
13
+ track: vi.fn(),
14
+ }))
15
+
16
+ vi.mock('$lib/api/titles', () => ({
17
+ fetchSimilarTitles: vi.fn(),
18
+ }))
19
+
20
+ describe('ParticipantsRail.svelte', () => {
21
+ it('Should fetch titles', async () => {
22
+ render(SimilarRail, { title })
23
+
24
+ expect(fetchSimilarTitles).toHaveBeenCalledWith(title)
25
+ })
26
+ })
@@ -3,11 +3,21 @@ import { describe, expect, it, vi, beforeEach } from 'vitest'
3
3
 
4
4
  import Title from '../../../routes/components/Title.svelte'
5
5
  import { title } from '$lib/fakeData'
6
+ import { fetchParticipantsForTitle } from '$lib/api/participants'
7
+ import { fetchSimilarTitles } from '$lib/api/titles'
6
8
 
7
9
  vi.mock('$lib/tracking', () => ({
8
10
  track: vi.fn(),
9
11
  }))
10
12
 
13
+ vi.mock('$lib/api/participants', () => ({
14
+ fetchParticipantsForTitle: vi.fn(),
15
+ }))
16
+
17
+ vi.mock('$lib/api/titles', () => ({
18
+ fetchSimilarTitles: vi.fn(),
19
+ }))
20
+
11
21
  vi.mock('svelte', async (importActual) => ({
12
22
  ...(await importActual()),
13
23
  getContext: vi.fn(),
@@ -74,4 +84,11 @@ describe('Title.svelte', () => {
74
84
 
75
85
  expect(container.querySelector('.paragraph')).not.toBeTruthy()
76
86
  })
87
+
88
+ it('Should call fetches for participants and similar titles', () => {
89
+ render(Title, { title })
90
+
91
+ expect(fetchParticipantsForTitle).toHaveBeenCalled()
92
+ expect(fetchSimilarTitles).toHaveBeenCalled()
93
+ })
77
94
  })
@@ -15,6 +15,14 @@ vi.mock('$lib/tracking', () => ({
15
15
  track: vi.fn(),
16
16
  }))
17
17
 
18
+ vi.mock('$lib/api/participants', () => ({
19
+ fetchParticipantsForTitle: vi.fn(),
20
+ }))
21
+
22
+ vi.mock('$lib/api/titles', () => ({
23
+ fetchSimilarTitles: vi.fn(),
24
+ }))
25
+
18
26
  describe('TitleModal.svelte', () => {
19
27
  beforeEach(() => {
20
28
  vi.resetAllMocks()
@@ -25,16 +33,14 @@ describe('TitleModal.svelte', () => {
25
33
  vi.useRealTimers()
26
34
  })
27
35
 
28
- const onclose = vi.fn()
29
-
30
36
  it('Should call track function when rendered', () => {
31
- render(TitleModal, { onclose, title })
37
+ render(TitleModal, { title })
32
38
 
33
39
  expect(track).toHaveBeenCalledWith(TrackingEvent.TitleModalView, title)
34
40
  })
35
41
 
36
42
  it('Should call track function when scrolled', async () => {
37
- const { getByRole } = render(TitleModal, { onclose, title })
43
+ const { getByRole } = render(TitleModal, { title })
38
44
 
39
45
  await fireEvent.scroll(getByRole('dialog'))
40
46
 
@@ -44,7 +50,7 @@ describe('TitleModal.svelte', () => {
44
50
  it('Should call track function with time_spent when destroyed', async () => {
45
51
  vi.useFakeTimers()
46
52
 
47
- const { unmount } = render(TitleModal, { onclose, title })
53
+ const { unmount } = render(TitleModal, { title })
48
54
 
49
55
  vi.advanceTimersByTime(200)
50
56
  unmount()
@@ -56,7 +62,7 @@ describe('TitleModal.svelte', () => {
56
62
  // @ts-ignore
57
63
  window.PlayPilotLinkInjections = { ads: [{ campaign_format: 'top_scroll', content: {}, cta: {} }] }
58
64
 
59
- const { container } = render(TitleModal, { onclose, title })
65
+ const { container } = render(TitleModal, { title })
60
66
 
61
67
  expect(container.querySelector('.top-scroll')).toBeTruthy()
62
68
  })
@@ -65,7 +71,7 @@ describe('TitleModal.svelte', () => {
65
71
  // @ts-ignore
66
72
  window.PlayPilotLinkInjections = { ads: null }
67
73
 
68
- const { container } = render(TitleModal, { onclose, title })
74
+ const { container } = render(TitleModal, { title })
69
75
 
70
76
  expect(container.querySelector('.top-scroll')).not.toBeTruthy()
71
77
  })
@@ -74,7 +80,7 @@ describe('TitleModal.svelte', () => {
74
80
  // @ts-ignore
75
81
  window.PlayPilotLinkInjections = { ads: [{ campaign_format: 'card', content: {}, cta: {} }] }
76
82
 
77
- const { container } = render(TitleModal, { onclose, title })
83
+ const { container } = render(TitleModal, { title })
78
84
 
79
85
  expect(container.querySelector('.display')).toBeTruthy()
80
86
  })
@@ -83,7 +89,7 @@ describe('TitleModal.svelte', () => {
83
89
  // @ts-ignore
84
90
  window.PlayPilotLinkInjections = { ads: null }
85
91
 
86
- const { container } = render(TitleModal, { onclose, title })
92
+ const { container } = render(TitleModal, { title })
87
93
 
88
94
  expect(container.querySelector('.display')).not.toBeTruthy()
89
95
  })
@@ -15,6 +15,14 @@ vi.mock('$lib/tracking', () => ({
15
15
  track: vi.fn(),
16
16
  }))
17
17
 
18
+ vi.mock('$lib/api/participants', () => ({
19
+ fetchParticipantsForTitle: vi.fn(),
20
+ }))
21
+
22
+ vi.mock('$lib/api/titles', () => ({
23
+ fetchSimilarTitles: vi.fn(),
24
+ }))
25
+
18
26
  describe('TitlePopover.svelte', () => {
19
27
  beforeEach(() => {
20
28
  vi.resetAllMocks()