@playpilot/tpi 8.17.1 → 8.19.0
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/.env +1 -1
- package/dist/editorial.mount.js +11 -11
- package/dist/link-injections.js +2 -2
- package/dist/mount.js +9 -9
- package/package.json +1 -1
- package/src/lib/api/titles.ts +2 -2
- package/src/lib/constants.ts +1 -0
- package/src/lib/data/translations.ts +5 -0
- package/src/lib/enums/TrackingEvent.ts +4 -4
- package/src/lib/fakeData.ts +44 -32
- package/src/lib/injection.ts +10 -9
- package/src/lib/modal.ts +3 -1
- package/src/lib/popover.ts +13 -12
- package/src/lib/scss/_mixins.scss +29 -0
- package/src/lib/scss/global.scss +0 -27
- package/src/lib/tracking.ts +2 -0
- package/src/lib/types/injection.d.ts +5 -0
- package/src/main.ts +2 -1
- package/src/routes/+page.svelte +3 -3
- package/src/routes/components/Editorial/Editor.svelte +8 -5
- package/src/routes/components/Editorial/EditorItem.svelte +23 -9
- package/src/routes/components/Editorial/ManualInjection.svelte +1 -0
- package/src/routes/components/Explore/ExploreLayout.svelte +5 -3
- package/src/routes/components/Explore/Filter/Dropdown.svelte +3 -1
- package/src/routes/components/Explore/Filter/Filter.svelte +5 -3
- package/src/routes/components/Explore/Routes/ExploreHome.svelte +4 -4
- package/src/routes/components/{TitlePopover.svelte → InjectionPopover.svelte} +26 -9
- package/src/routes/components/ListTitle.svelte +27 -6
- package/src/routes/components/Modals/Modal.svelte +2 -0
- package/src/routes/components/Modals/RailModal.svelte +9 -3
- package/src/routes/components/Participant.svelte +18 -6
- package/src/routes/components/Playlinks/Playlink.svelte +1 -1
- package/src/routes/components/Playlinks/PlaylinkIcon.svelte +1 -1
- package/src/routes/components/Playlinks/Playlinks.svelte +21 -5
- package/src/routes/components/Popover.svelte +2 -1
- package/src/routes/components/Title.svelte +1 -1
- package/src/routes/elements/+page.svelte +3 -3
- package/src/tests/helpers.js +1 -0
- package/src/tests/lib/api/titles.test.js +4 -4
- package/src/tests/lib/injection.test.js +44 -3
- package/src/tests/lib/popover.test.js +7 -7
- package/src/tests/lib/tracking.test.js +8 -0
- package/src/tests/routes/components/Editorial/EditorItem.test.js +10 -0
- package/src/tests/routes/components/Editorial/ManualInjection.test.js +4 -0
- package/src/tests/routes/components/Editorial/PlaylinkTypeSelect.test.js +2 -0
- package/src/tests/routes/components/InjectionPopover.test.js +117 -0
- package/src/tests/routes/components/ListTitle.test.js +7 -0
- package/src/tests/routes/components/Participant.test.js +7 -0
- package/src/tests/routes/components/Playlinks/AfterArticlePlaylinks.test.js +4 -0
- package/src/tests/routes/components/Playlinks/Playlinks.test.js +51 -1
- package/src/tests/routes/components/{TrackAnyClick.test.js → Tracking/TrackAnyClick.test.js} +1 -1
- package/src/tests/routes/components/{TrackingPixels.test.js → Tracking/TrackingPixels.test.js} +1 -1
- package/src/tests/routes/components/TitlePopover.test.js +0 -78
- /package/src/routes/components/{TrackAnyClick.svelte → Tracking/TrackAnyClick.svelte} +0 -0
- /package/src/routes/components/{TrackScrollDistance.svelte → Tracking/TrackScrollDistance.svelte} +0 -0
- /package/src/routes/components/{TrackingPixels.svelte → Tracking/TrackingPixels.svelte} +0 -0
- /package/src/routes/components/{TrackingPixelsForTitleDataPerLink.svelte → Tracking/TrackingPixelsForTitleDataPerLink.svelte} +0 -0
- /package/src/routes/components/{UserJourney.svelte → Tracking/UserJourney.svelte} +0 -0
|
@@ -11,6 +11,8 @@ 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',
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
beforeEach(() => {
|
|
@@ -0,0 +1,117 @@
|
|
|
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
|
+
})
|
|
@@ -50,6 +50,13 @@ 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
|
+
|
|
53
60
|
describe('Playlinks', () => {
|
|
54
61
|
const playlinks = [
|
|
55
62
|
{ name: 'Some playlink', logo_url: 'logo', extra_info: { category: 'SVOD' } },
|
|
@@ -73,4 +73,11 @@ 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
|
+
})
|
|
76
83
|
})
|
|
@@ -23,6 +23,8 @@ 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',
|
|
26
28
|
}, {
|
|
27
29
|
sid: '2',
|
|
28
30
|
title: 'a sentence',
|
|
@@ -31,6 +33,8 @@ const linkInjections = [{
|
|
|
31
33
|
poster: 'some-poster',
|
|
32
34
|
key: 'some-key-1',
|
|
33
35
|
title_details: title,
|
|
36
|
+
/** @type {import('$lib/types/injection').LinkInjectionDataType} */
|
|
37
|
+
type: 'title',
|
|
34
38
|
}]
|
|
35
39
|
|
|
36
40
|
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.
|
|
88
|
+
expect(track).toHaveBeenCalledWith(TrackingEvent.InjectionPopoverPlaylinkClick, 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 () => {
|
|
@@ -176,4 +176,54 @@ describe('Playlinks.svelte', () => {
|
|
|
176
176
|
expect(getByText('Streaming services'))
|
|
177
177
|
expect(getByTestId('category-SVOD').querySelectorAll('[data-playlink]')).toHaveLength(1)
|
|
178
178
|
})
|
|
179
|
+
|
|
180
|
+
it('Should limit number of shown playlinks and shown all playlinks after click of show more button', async () => {
|
|
181
|
+
const playlinks = [
|
|
182
|
+
{ name: 'Some playlink', logo_url: 'logo', extra_info: { category: 'SVOD' } },
|
|
183
|
+
{ name: 'Some playlink', logo_url: 'logo', extra_info: { category: 'SVOD' } },
|
|
184
|
+
{ name: 'Some playlink', logo_url: 'logo', extra_info: { category: 'SVOD' } },
|
|
185
|
+
{ name: 'Some playlink', logo_url: 'logo', extra_info: { category: 'SVOD' } },
|
|
186
|
+
]
|
|
187
|
+
|
|
188
|
+
// @ts-ignore
|
|
189
|
+
const { getAllByText, getByText, getByTestId } = render(Playlinks, { playlinks, title, limit: 3 })
|
|
190
|
+
|
|
191
|
+
expect(getAllByText('Some playlink')).toHaveLength(3)
|
|
192
|
+
expect(getByTestId('show-more')).toBeTruthy()
|
|
193
|
+
|
|
194
|
+
await fireEvent.click(getByText('Show 1 more'))
|
|
195
|
+
|
|
196
|
+
expect(getAllByText('Some playlink')).toHaveLength(4)
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
it('Should not render show more button if fewer playlinks than limit are given', () => {
|
|
200
|
+
const playlinks = [
|
|
201
|
+
{ name: 'Some playlink', logo_url: 'logo', extra_info: { category: 'SVOD' } },
|
|
202
|
+
{ name: 'Some playlink', logo_url: 'logo', extra_info: { category: 'SVOD' } },
|
|
203
|
+
]
|
|
204
|
+
|
|
205
|
+
// @ts-ignore
|
|
206
|
+
const { queryByTestId } = render(Playlinks, { playlinks, title, limit: 3 })
|
|
207
|
+
|
|
208
|
+
expect(queryByTestId('show-more')).not.toBeTruthy()
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
it('Should not render show more button if playlinks are categorized', () => {
|
|
212
|
+
// @ts-ignore
|
|
213
|
+
window.PlayPilotLinkInjections = {
|
|
214
|
+
config: { categorize_playlinks: true },
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const playlinks = [
|
|
218
|
+
{ name: 'Some playlink', logo_url: 'logo', extra_info: { category: 'SVOD' } },
|
|
219
|
+
{ name: 'Some playlink', logo_url: 'logo', extra_info: { category: 'SVOD' } },
|
|
220
|
+
{ name: 'Some playlink', logo_url: 'logo', extra_info: { category: 'SVOD' } },
|
|
221
|
+
{ name: 'Some playlink', logo_url: 'logo', extra_info: { category: 'SVOD' } },
|
|
222
|
+
]
|
|
223
|
+
|
|
224
|
+
// @ts-ignore
|
|
225
|
+
const { queryByTestId } = render(Playlinks, { playlinks, title, limit: 3 })
|
|
226
|
+
|
|
227
|
+
expect(queryByTestId('show-more')).not.toBeTruthy()
|
|
228
|
+
})
|
|
179
229
|
})
|
package/src/tests/routes/components/{TrackAnyClick.test.js → Tracking/TrackAnyClick.test.js}
RENAMED
|
@@ -2,7 +2,7 @@ import { render, fireEvent } from '@testing-library/svelte'
|
|
|
2
2
|
import { describe, expect, it, vi, beforeEach } from 'vitest'
|
|
3
3
|
import { track } from '$lib/tracking'
|
|
4
4
|
import { TrackingEvent } from '$lib/enums/TrackingEvent'
|
|
5
|
-
import ClickTracking from '
|
|
5
|
+
import ClickTracking from '../../../../routes/components/Tracking/TrackAnyClick.svelte'
|
|
6
6
|
|
|
7
7
|
vi.mock('$lib/tracking', () => ({
|
|
8
8
|
track: vi.fn(),
|
package/src/tests/routes/components/{TrackingPixels.test.js → Tracking/TrackingPixels.test.js}
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { render, waitFor } from '@testing-library/svelte'
|
|
2
2
|
import { describe, expect, it, vi } from 'vitest'
|
|
3
3
|
|
|
4
|
-
import TrackingPixels from '
|
|
4
|
+
import TrackingPixels from '../../../../routes/components/Tracking/TrackingPixels.svelte'
|
|
5
5
|
import { hasConsentedTo } from '$lib/consent'
|
|
6
6
|
|
|
7
7
|
vi.mock('$lib/consent', () => ({
|
|
@@ -1,78 +0,0 @@
|
|
|
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
|
-
})
|
|
File without changes
|
/package/src/routes/components/{TrackScrollDistance.svelte → Tracking/TrackScrollDistance.svelte}
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|