@playpilot/tpi 7.0.0-beta.7 → 7.0.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/README.md +21 -4
- package/dist/editorial.mount.js +8 -8
- package/dist/link-injections.js +2 -2
- package/dist/mount.js +6 -6
- package/package.json +1 -1
- package/src/lib/api/ads.ts +1 -0
- package/src/lib/api/auth.ts +1 -1
- package/src/lib/tracking.ts +1 -0
- package/src/lib/types/config.d.ts +6 -0
- package/src/lib/types/script.d.ts +4 -0
- package/src/main.ts +6 -2
- package/src/routes/+page.svelte +2 -0
- package/src/routes/components/Explore/ExploreCallToAction.svelte +0 -3
- package/src/routes/components/ListTitle.svelte +11 -2
- package/src/routes/components/Title.svelte +6 -2
- package/src/tests/lib/api/ads.test.js +8 -1
- package/src/tests/lib/tracking.test.js +32 -1
- package/src/tests/main.test.js +60 -7
- package/src/tests/routes/+page.test.js +33 -0
- package/src/tests/routes/components/ListTitle.test.js +11 -0
- package/src/tests/routes/components/Title.test.js +24 -0
- package/vite.config.js +22 -24
package/package.json
CHANGED
package/src/lib/api/ads.ts
CHANGED
|
@@ -30,6 +30,7 @@ export async function fetchAds(): Promise<Campaign[]> {
|
|
|
30
30
|
*/
|
|
31
31
|
export function getFirstAdOfType(format: CampaignFormat): Campaign | null {
|
|
32
32
|
if (!hasConsentedTo('ads')) return null
|
|
33
|
+
if (window.PlayPilotLinkInjections.no_affiliate) return null
|
|
33
34
|
|
|
34
35
|
return (window.PlayPilotLinkInjections?.ads || []).find(i => i.campaign_format === format) || null
|
|
35
36
|
}
|
package/src/lib/api/auth.ts
CHANGED
|
@@ -5,7 +5,7 @@ const cookieName = 'EncryptedToken'
|
|
|
5
5
|
const urlParam = 'articleReplacementEditToken'
|
|
6
6
|
const editorialParam = 'playpilot-editorial-mode'
|
|
7
7
|
|
|
8
|
-
export async function authorize({ href, throwError }: { href?: string, throwError?: boolean } = {
|
|
8
|
+
export async function authorize({ href = window.location.href, throwError = false }: { href?: string, throwError?: boolean } = {}): Promise<boolean> {
|
|
9
9
|
try {
|
|
10
10
|
const apiToken = getApiToken()
|
|
11
11
|
if (!apiToken) throw new Error('No token was provided')
|
package/src/lib/tracking.ts
CHANGED
|
@@ -37,6 +37,7 @@ export async function track(event: string, title: TitleData | null = null, paylo
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
payload.version = __SCRIPT_VERSION__
|
|
40
|
+
payload.time_since_initialize = window.PlayPilotLinkInjections?.time_at_initialize ? Date.now() - window.PlayPilotLinkInjections.time_at_initialize : 0
|
|
40
41
|
payload.url = getFullUrlPath()
|
|
41
42
|
payload.organization_sid = window.PlayPilotLinkInjections?.organization_sid || 'undefined'
|
|
42
43
|
payload.domain_sid = window.PlayPilotLinkInjections?.domain_sid || 'undefined'
|
|
@@ -44,6 +44,12 @@ export type ConfigResponse = {
|
|
|
44
44
|
*/
|
|
45
45
|
playlinks_disclaimer_text?: string
|
|
46
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Some partners may want to display titles without affiliate links, which currently comes down to no playlinks.
|
|
49
|
+
* This can also be set via the config on the script itself.
|
|
50
|
+
*/
|
|
51
|
+
no_affiliate?: boolean
|
|
52
|
+
|
|
47
53
|
/**
|
|
48
54
|
* Whether or not we can insert retargeting pixels. Not all third parties allow this and it is disabled by default
|
|
49
55
|
*/
|
|
@@ -34,6 +34,8 @@ export type ScriptConfig = {
|
|
|
34
34
|
initial_link_injections_promise?: Promise<LinkInjectionResponse> | null
|
|
35
35
|
// By default the script requires consent from the user through tcfapi. Can be disabled using this setting.
|
|
36
36
|
require_consent?: boolean
|
|
37
|
+
// Some partners may want to display titles without affiliate links, which currently comes down to no playlinks.
|
|
38
|
+
no_affiliate?: boolean
|
|
37
39
|
// Used to check if a user has consented via tcfapi to various consent categories.
|
|
38
40
|
consents?: ConsentOptions
|
|
39
41
|
// The config response from the api, saved to the window object to be used without having to pass the response around.
|
|
@@ -42,4 +44,6 @@ export type ScriptConfig = {
|
|
|
42
44
|
ads?: Campaign[]
|
|
43
45
|
// The region the user is in, either fetched from an external service or based on the default region in the config object
|
|
44
46
|
region?: string | null
|
|
47
|
+
// The time at which the script was initialized
|
|
48
|
+
time_at_initialize?: number
|
|
45
49
|
}
|
package/src/main.ts
CHANGED
|
@@ -22,8 +22,10 @@ window.PlayPilotLinkInjections = {
|
|
|
22
22
|
split_test_identifiers: {},
|
|
23
23
|
evaluated_link_injections: [],
|
|
24
24
|
initial_link_injections_promise: null,
|
|
25
|
+
time_at_initialize: 0,
|
|
25
26
|
ads: [],
|
|
26
27
|
require_consent: true,
|
|
28
|
+
no_affiliate: false,
|
|
27
29
|
consents: {
|
|
28
30
|
ads: false,
|
|
29
31
|
pixels: false,
|
|
@@ -34,7 +36,7 @@ window.PlayPilotLinkInjections = {
|
|
|
34
36
|
config: {},
|
|
35
37
|
app: null,
|
|
36
38
|
|
|
37
|
-
async initialize(options = { token: '', selector: '', after_article_selector: '', after_article_insert_position: '', language: null, region: null, organization_sid: null, domain_sid: null, editorial_token: '', require_consent: true }): Promise<void> {
|
|
39
|
+
async initialize(options = { token: '', selector: '', after_article_selector: '', after_article_insert_position: '', language: null, region: null, organization_sid: null, domain_sid: null, editorial_token: '', require_consent: true, no_affiliate: false }): Promise<void> {
|
|
38
40
|
if (!options.token) {
|
|
39
41
|
console.error('An API token is required.')
|
|
40
42
|
return
|
|
@@ -51,6 +53,8 @@ window.PlayPilotLinkInjections = {
|
|
|
51
53
|
this.organization_sid = options.organization_sid
|
|
52
54
|
this.domain_sid = options.domain_sid
|
|
53
55
|
this.require_consent = options.require_consent
|
|
56
|
+
this.no_affiliate = options.no_affiliate
|
|
57
|
+
this.time_at_initialize = Date.now()
|
|
54
58
|
|
|
55
59
|
if (this.require_consent === false) {
|
|
56
60
|
setConsent({
|
|
@@ -87,7 +91,7 @@ window.PlayPilotLinkInjections = {
|
|
|
87
91
|
|
|
88
92
|
script.onload = () => window.PlayPilotMount?.mount()
|
|
89
93
|
|
|
90
|
-
document.body.insertAdjacentElement('beforeend', script)
|
|
94
|
+
if (process.env.NODE_ENV !== 'test') document.body.insertAdjacentElement('beforeend', script)
|
|
91
95
|
},
|
|
92
96
|
}
|
|
93
97
|
|
package/src/routes/+page.svelte
CHANGED
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
track(TrackingEvent.ArticlePageView)
|
|
59
59
|
|
|
60
60
|
if (!aiInjections.length && !manualInjections.length) return
|
|
61
|
+
if (window.PlayPilotLinkInjections.no_affiliate) return
|
|
61
62
|
|
|
62
63
|
window.PlayPilotLinkInjections.ads = await fetchAds()
|
|
63
64
|
}
|
|
@@ -77,6 +78,7 @@
|
|
|
77
78
|
|
|
78
79
|
if (config?.custom_style) insertCustomStyle(config.custom_style || '')
|
|
79
80
|
if (config?.explore_navigation_selector) insertExploreIntoNavigation()
|
|
81
|
+
if (config?.no_affiliate) window.PlayPilotLinkInjections.no_affiliate = true
|
|
80
82
|
|
|
81
83
|
isUrlExcluded = isUrlExcludedViaConfig(config)
|
|
82
84
|
if (isUrlExcluded) return
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import IconArrow from '../Icons/IconArrow.svelte'
|
|
3
|
-
import ImageTitlesList from '$lib/images/titles-list.webp'
|
|
4
3
|
import { openModal } from '$lib/modal'
|
|
5
4
|
</script>
|
|
6
5
|
|
|
7
6
|
<button class="call-to-action" onclick={() => openModal({ type: 'explore' })}>
|
|
8
|
-
<img src={ImageTitlesList} alt="" width="70" height="57" />
|
|
9
|
-
|
|
10
7
|
<div>
|
|
11
8
|
<strong>Looking for something else?</strong>
|
|
12
9
|
<div>Use our streamingguide</div>
|
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
const { title, onclick = () => null }: Props = $props()
|
|
14
|
+
|
|
15
|
+
const noAffiliate = !!window.PlayPilotLinkInjections?.no_affiliate
|
|
14
16
|
</script>
|
|
15
17
|
|
|
16
18
|
<button class="title" {onclick} data-testid="title">
|
|
@@ -35,11 +37,13 @@
|
|
|
35
37
|
{/if}
|
|
36
38
|
</div>
|
|
37
39
|
|
|
38
|
-
<div class="description">
|
|
40
|
+
<div class="description" class:large={noAffiliate}>
|
|
39
41
|
{title.description}
|
|
40
42
|
</div>
|
|
41
43
|
|
|
42
|
-
|
|
44
|
+
{#if !noAffiliate}
|
|
45
|
+
<PlaylinksCompact playlinks={title.providers} />
|
|
46
|
+
{/if}
|
|
43
47
|
</div>
|
|
44
48
|
|
|
45
49
|
<div class="action">
|
|
@@ -129,6 +133,11 @@
|
|
|
129
133
|
-webkit-box-orient: vertical;
|
|
130
134
|
font-size: theme(detail-font-size-small, font-size-small);
|
|
131
135
|
color: theme(list-item-description-text-color, text-color);
|
|
136
|
+
|
|
137
|
+
&.large {
|
|
138
|
+
line-clamp: 2;
|
|
139
|
+
-webkit-line-clamp: 2;
|
|
140
|
+
}
|
|
132
141
|
}
|
|
133
142
|
|
|
134
143
|
.action {
|
|
@@ -24,9 +24,11 @@
|
|
|
24
24
|
|
|
25
25
|
const { title, small = false }: Props = $props()
|
|
26
26
|
|
|
27
|
+
const noAffiliate = !!window.PlayPilotLinkInjections?.no_affiliate
|
|
28
|
+
|
|
27
29
|
setContext('title', title)
|
|
28
30
|
|
|
29
|
-
const showDescription = $derived(!small && title.description)
|
|
31
|
+
const showDescription = $derived((!small || noAffiliate) && title.description)
|
|
30
32
|
|
|
31
33
|
let posterLoaded = $state(false)
|
|
32
34
|
let backgroundLoaded = $state(false)
|
|
@@ -71,7 +73,9 @@
|
|
|
71
73
|
<Description text={title.description!} blurb={title.blurb} onclick={() => track(TrackingEvent.ExpandTitleDescription, title)} />
|
|
72
74
|
{/if}
|
|
73
75
|
|
|
74
|
-
|
|
76
|
+
{#if !noAffiliate}
|
|
77
|
+
<Playlinks playlinks={title.providers} {title} />
|
|
78
|
+
{/if}
|
|
75
79
|
|
|
76
80
|
<ParticipantsRail {title} />
|
|
77
81
|
<SimilarRail {title} />
|
|
@@ -81,7 +81,7 @@ describe('$lib/api/ads', () => {
|
|
|
81
81
|
expect(getFirstAdOfType('top_scroll')).toBe(null)
|
|
82
82
|
})
|
|
83
83
|
|
|
84
|
-
it('Should not return ads if valid ad was given but user did not consent to ads',
|
|
84
|
+
it('Should not return ads if valid ad was given but user did not consent to ads', () => {
|
|
85
85
|
vi.mocked(hasConsentedTo).mockImplementation(() => false)
|
|
86
86
|
|
|
87
87
|
// @ts-ignore
|
|
@@ -89,5 +89,12 @@ describe('$lib/api/ads', () => {
|
|
|
89
89
|
|
|
90
90
|
expect(getFirstAdOfType('top_scroll')).toBe(null)
|
|
91
91
|
})
|
|
92
|
+
|
|
93
|
+
it('Should not return ads even if given if no_affiliate is true', () => {
|
|
94
|
+
// @ts-ignore
|
|
95
|
+
window.PlayPilotLinkInjections = { ads: [{ campaign_format: 'top_scroll' }], no_affiliate: true }
|
|
96
|
+
|
|
97
|
+
expect(getFirstAdOfType('top_scroll')).toBe(null)
|
|
98
|
+
})
|
|
92
99
|
})
|
|
93
100
|
})
|
|
@@ -21,6 +21,7 @@ describe('$lib/tracking', () => {
|
|
|
21
21
|
window.PlayPilotLinkInjections = {}
|
|
22
22
|
|
|
23
23
|
vi.resetAllMocks()
|
|
24
|
+
vi.useRealTimers()
|
|
24
25
|
|
|
25
26
|
fakeFetch()
|
|
26
27
|
vi.mocked(hasConsentedTo).mockImplementation(() => true)
|
|
@@ -72,7 +73,7 @@ describe('$lib/tracking', () => {
|
|
|
72
73
|
expect(global.fetch).toHaveBeenCalledWith(
|
|
73
74
|
expect.any(String),
|
|
74
75
|
expect.objectContaining({
|
|
75
|
-
|
|
76
|
+
|
|
76
77
|
body: expect.stringContaining(`"version":"${__SCRIPT_VERSION__}"`),
|
|
77
78
|
}),
|
|
78
79
|
)
|
|
@@ -175,6 +176,36 @@ describe('$lib/tracking', () => {
|
|
|
175
176
|
|
|
176
177
|
expect(global.fetch).not.toHaveBeenCalled()
|
|
177
178
|
})
|
|
179
|
+
|
|
180
|
+
it('Should include time_since_initialize', async () => {
|
|
181
|
+
vi.useFakeTimers()
|
|
182
|
+
|
|
183
|
+
window.PlayPilotLinkInjections.time_at_initialize = Date.now()
|
|
184
|
+
|
|
185
|
+
vi.advanceTimersByTime(150)
|
|
186
|
+
|
|
187
|
+
track('Some Event')
|
|
188
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
189
|
+
expect.any(String),
|
|
190
|
+
expect.objectContaining({
|
|
191
|
+
body: expect.stringContaining('"time_since_initialize":150'),
|
|
192
|
+
}),
|
|
193
|
+
)
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
it('Should include time_since_initialize set to 0 if window object was not present', async () => {
|
|
197
|
+
vi.useFakeTimers()
|
|
198
|
+
|
|
199
|
+
vi.advanceTimersByTime(150)
|
|
200
|
+
|
|
201
|
+
track('Some Event')
|
|
202
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
203
|
+
expect.any(String),
|
|
204
|
+
expect.objectContaining({
|
|
205
|
+
body: expect.stringContaining('"time_since_initialize":0'),
|
|
206
|
+
}),
|
|
207
|
+
)
|
|
208
|
+
})
|
|
178
209
|
})
|
|
179
210
|
|
|
180
211
|
describe('setTrackingSids', () => {
|
package/src/tests/main.test.js
CHANGED
|
@@ -1,24 +1,43 @@
|
|
|
1
1
|
import { setConsent } from '$lib/consent'
|
|
2
2
|
import { afterAll, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
3
|
+
import { fakeFetch } from './helpers'
|
|
4
|
+
import { fetchConfig } from '$lib/api/config'
|
|
5
|
+
import { waitFor } from '@testing-library/svelte'
|
|
6
|
+
import { isUrlExcludedViaConfig } from '$lib/url'
|
|
7
|
+
import { pollLinkInjections } from '$lib/api/externalPages'
|
|
3
8
|
|
|
4
9
|
vi.mock('$lib/consent', () => ({
|
|
5
10
|
setConsent: vi.fn(),
|
|
6
11
|
hasConsentedTo: vi.fn(),
|
|
7
12
|
}))
|
|
8
13
|
|
|
14
|
+
vi.mock('$lib/api/config', () => ({
|
|
15
|
+
fetchConfig: vi.fn(),
|
|
16
|
+
}))
|
|
17
|
+
|
|
18
|
+
vi.mock('$lib/api/externalPages', () => ({
|
|
19
|
+
pollLinkInjections: vi.fn(),
|
|
20
|
+
}))
|
|
21
|
+
|
|
22
|
+
vi.mock('$lib/url', () => ({
|
|
23
|
+
isUrlExcludedViaConfig: vi.fn(),
|
|
24
|
+
}))
|
|
25
|
+
|
|
9
26
|
describe('main.ts', () => {
|
|
10
|
-
beforeEach(() => {
|
|
27
|
+
beforeEach(async () => {
|
|
28
|
+
fakeFetch()
|
|
29
|
+
|
|
11
30
|
vi.resetModules()
|
|
12
31
|
vi.resetAllMocks()
|
|
32
|
+
|
|
33
|
+
await import('../main')
|
|
13
34
|
})
|
|
14
35
|
|
|
15
36
|
afterAll(() => {
|
|
16
37
|
vi.resetModules()
|
|
17
38
|
})
|
|
18
39
|
|
|
19
|
-
it('Should not call setConsent when only a token is passed',
|
|
20
|
-
await import('../main')
|
|
21
|
-
|
|
40
|
+
it('Should not call setConsent when only a token is passed', () => {
|
|
22
41
|
window.PlayPilotLinkInjections.initialize({ token: 'a' })
|
|
23
42
|
|
|
24
43
|
expect(setConsent).not.toHaveBeenCalled()
|
|
@@ -32,9 +51,7 @@ describe('main.ts', () => {
|
|
|
32
51
|
})
|
|
33
52
|
})
|
|
34
53
|
|
|
35
|
-
it('Should call setConsent when require_consent is false',
|
|
36
|
-
await import('../main')
|
|
37
|
-
|
|
54
|
+
it('Should call setConsent when require_consent is false', () => {
|
|
38
55
|
window.PlayPilotLinkInjections.initialize({ token: 'a', require_consent: false })
|
|
39
56
|
|
|
40
57
|
expect(setConsent).toHaveBeenCalledWith({
|
|
@@ -45,4 +62,40 @@ describe('main.ts', () => {
|
|
|
45
62
|
affiliate: true,
|
|
46
63
|
})
|
|
47
64
|
})
|
|
65
|
+
|
|
66
|
+
it('Should call config object and set the result to the window object', async () => {
|
|
67
|
+
vi.mocked(fetchConfig).mockResolvedValue({ html_selector: 'some_value' })
|
|
68
|
+
|
|
69
|
+
window.PlayPilotLinkInjections.initialize({ token: 'a' })
|
|
70
|
+
|
|
71
|
+
expect(fetchConfig).toHaveBeenCalled()
|
|
72
|
+
|
|
73
|
+
await waitFor(() => {
|
|
74
|
+
expect(window.PlayPilotLinkInjections.config).toEqual({ html_selector: 'some_value' })
|
|
75
|
+
})
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
it('Should not call pollLinkInjections if config object excludes page', async () => {
|
|
79
|
+
vi.mocked(isUrlExcludedViaConfig).mockReturnValue(true)
|
|
80
|
+
|
|
81
|
+
window.PlayPilotLinkInjections.initialize({ token: 'a' })
|
|
82
|
+
|
|
83
|
+
expect(fetchConfig).toHaveBeenCalled()
|
|
84
|
+
|
|
85
|
+
await new Promise(res => setTimeout(res))
|
|
86
|
+
|
|
87
|
+
expect(pollLinkInjections).not.toHaveBeenCalled()
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
it('Should call pollLinkInjections if config object does not page', async () => {
|
|
91
|
+
vi.mocked(isUrlExcludedViaConfig).mockReturnValue(false)
|
|
92
|
+
|
|
93
|
+
window.PlayPilotLinkInjections.initialize({ token: 'a' })
|
|
94
|
+
|
|
95
|
+
expect(fetchConfig).toHaveBeenCalled()
|
|
96
|
+
|
|
97
|
+
await new Promise(res => setTimeout(res))
|
|
98
|
+
|
|
99
|
+
expect(pollLinkInjections).toHaveBeenCalled()
|
|
100
|
+
})
|
|
48
101
|
})
|
|
@@ -475,6 +475,19 @@ describe('$routes/+page.svelte', () => {
|
|
|
475
475
|
expect(fetchAds).not.toHaveBeenCalled()
|
|
476
476
|
})
|
|
477
477
|
|
|
478
|
+
it('Should not fetch ads if no_affilite is true', async () => {
|
|
479
|
+
// @ts-ignore
|
|
480
|
+
vi.mocked(pollLinkInjections).mockResolvedValueOnce({ ai_injections: [{}], manual_injections: [{}] })
|
|
481
|
+
// @ts-ignore
|
|
482
|
+
window.PlayPilotLinkInjections = { no_affiliate: true }
|
|
483
|
+
|
|
484
|
+
render(page)
|
|
485
|
+
|
|
486
|
+
await new Promise(res => setTimeout(res, 100)) // Await possible fetches
|
|
487
|
+
|
|
488
|
+
expect(fetchAds).not.toHaveBeenCalled()
|
|
489
|
+
})
|
|
490
|
+
|
|
478
491
|
describe('Config', () => {
|
|
479
492
|
describe('exclude_urls_pattern', () => {
|
|
480
493
|
it('Should not inject if config exclude_urls_pattern matches current url', async () => {
|
|
@@ -633,5 +646,25 @@ describe('$routes/+page.svelte', () => {
|
|
|
633
646
|
expect(document.querySelector('#playpilot-custom-style')).not.toBeTruthy()
|
|
634
647
|
})
|
|
635
648
|
})
|
|
649
|
+
|
|
650
|
+
describe('no_affiliate', () => {
|
|
651
|
+
it('Should not set window object if value is not given', async () => {
|
|
652
|
+
vi.mocked(fetchConfig).mockResolvedValueOnce({})
|
|
653
|
+
|
|
654
|
+
render(page)
|
|
655
|
+
|
|
656
|
+
await new Promise(res => setTimeout(res, 100)) // Await all fetches
|
|
657
|
+
expect(window.PlayPilotLinkInjections.no_affiliate).not.toBe(true)
|
|
658
|
+
})
|
|
659
|
+
|
|
660
|
+
it('Should set window object if value is true', async () => {
|
|
661
|
+
vi.mocked(fetchConfig).mockResolvedValueOnce({ no_affiliate: true })
|
|
662
|
+
|
|
663
|
+
render(page)
|
|
664
|
+
|
|
665
|
+
await new Promise(res => setTimeout(res, 100)) // Await all fetches
|
|
666
|
+
expect(window.PlayPilotLinkInjections.no_affiliate).toBe(true)
|
|
667
|
+
})
|
|
668
|
+
})
|
|
636
669
|
})
|
|
637
670
|
})
|
|
@@ -15,6 +15,8 @@ vi.mock('svelte', async (importActual) => ({
|
|
|
15
15
|
|
|
16
16
|
describe('ListTitle.svelte', () => {
|
|
17
17
|
beforeEach(() => {
|
|
18
|
+
// @ts-ignore
|
|
19
|
+
window.PlayPilotLinkInjections = {}
|
|
18
20
|
vi.resetAllMocks()
|
|
19
21
|
})
|
|
20
22
|
|
|
@@ -80,5 +82,14 @@ describe('ListTitle.svelte', () => {
|
|
|
80
82
|
|
|
81
83
|
expect(onclick).not.toHaveBeenCalled()
|
|
82
84
|
})
|
|
85
|
+
|
|
86
|
+
it('Should not render playlinks if no_affiliate is given in window object', () => {
|
|
87
|
+
window.PlayPilotLinkInjections.no_affiliate = true
|
|
88
|
+
|
|
89
|
+
// @ts-ignore
|
|
90
|
+
const { container } = render(ListTitle, { title: { ...title, providers: playlinks } })
|
|
91
|
+
|
|
92
|
+
expect(container.querySelectorAll('.playlink')).toHaveLength(0)
|
|
93
|
+
})
|
|
83
94
|
})
|
|
84
95
|
})
|
|
@@ -26,6 +26,8 @@ vi.mock('svelte', async (importActual) => ({
|
|
|
26
26
|
|
|
27
27
|
describe('Title.svelte', () => {
|
|
28
28
|
beforeEach(() => {
|
|
29
|
+
// @ts-ignore
|
|
30
|
+
window.PlayPilotLinkInjections = {}
|
|
29
31
|
vi.resetAllMocks()
|
|
30
32
|
})
|
|
31
33
|
|
|
@@ -104,4 +106,26 @@ describe('Title.svelte', () => {
|
|
|
104
106
|
|
|
105
107
|
expect(queryByText('Watch trailer')).not.toBeTruthy()
|
|
106
108
|
})
|
|
109
|
+
|
|
110
|
+
it('Should render playlinks by default', () => {
|
|
111
|
+
const { getByText } = render(Title, { title })
|
|
112
|
+
|
|
113
|
+
expect(getByText('Where to stream online')).toBeTruthy()
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
it('Should not render playlinks if no_affiliate is true on config', () => {
|
|
117
|
+
window.PlayPilotLinkInjections.no_affiliate = true
|
|
118
|
+
|
|
119
|
+
const { queryByText } = render(Title, { title })
|
|
120
|
+
|
|
121
|
+
expect(queryByText('Where to stream online')).not.toBeTruthy()
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
it('Should render description if no_affiliate is true even if small is true', () => {
|
|
125
|
+
window.PlayPilotLinkInjections.no_affiliate = true
|
|
126
|
+
|
|
127
|
+
const { getByText } = render(Title, { title: { ...title, description: 'Some description' }, small: true })
|
|
128
|
+
|
|
129
|
+
expect(getByText('Some description')).toBeTruthy()
|
|
130
|
+
})
|
|
107
131
|
})
|
package/vite.config.js
CHANGED
|
@@ -6,32 +6,30 @@ import packageJson from './package.json'
|
|
|
6
6
|
|
|
7
7
|
dotenv.config({ path: '.env' })
|
|
8
8
|
|
|
9
|
-
export default defineConfig(() => {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
],
|
|
9
|
+
export default defineConfig(() => ({
|
|
10
|
+
plugins: [
|
|
11
|
+
sveltekit(),
|
|
12
|
+
],
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
server: {
|
|
15
|
+
port: 3000,
|
|
16
|
+
},
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
test: {
|
|
19
|
+
environment: 'happy-dom',
|
|
20
|
+
include: ['src/**/*.{test,spec}.{js,ts}'],
|
|
21
|
+
setupFiles: ['src/tests/setup.js'],
|
|
22
|
+
},
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
},
|
|
24
|
+
resolve: {
|
|
25
|
+
conditions: process.env.VITEST ? ['browser'] : [],
|
|
26
|
+
alias: {
|
|
27
|
+
'$lib': path.resolve(__dirname, './src/lib'),
|
|
30
28
|
},
|
|
29
|
+
},
|
|
31
30
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
})
|
|
31
|
+
define: {
|
|
32
|
+
__SCRIPT_VERSION__: JSON.stringify(packageJson.version),
|
|
33
|
+
__IS_EDITORIAL_SCRIPT__: true,
|
|
34
|
+
},
|
|
35
|
+
}))
|