@playpilot/tpi 7.0.0 → 7.0.2
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/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/participants.ts +12 -1
- package/src/lib/data/translations.ts +15 -0
- package/src/main.ts +2 -1
- package/src/routes/components/ContextMenu.svelte +1 -1
- package/src/routes/components/Debugger.svelte +7 -0
- package/src/routes/components/Editorial/Editor.svelte +1 -2
- package/src/routes/components/Editorial/EditorItem.svelte +1 -0
- package/src/routes/components/ListTitle.svelte +2 -1
- package/src/routes/components/Participant.svelte +2 -2
- package/src/routes/components/RoundButton.svelte +1 -0
- package/src/tests/lib/api/participants.test.js +61 -0
- package/src/tests/lib/api/titles.test.js +3 -1
- package/src/tests/main.test.js +80 -38
- package/src/tests/mount.test.js +63 -0
package/package.json
CHANGED
|
@@ -1,10 +1,21 @@
|
|
|
1
|
+
import { getLanguage } from '$lib/language'
|
|
1
2
|
import { getApiToken } from '$lib/token'
|
|
2
3
|
import type { ParticipantData } from '$lib/types/participant'
|
|
4
|
+
import { paramsToString } from '$lib/url'
|
|
3
5
|
import type { TitleData } from '../types/title'
|
|
4
6
|
import { api } from './api'
|
|
7
|
+
import { getRegionBasedOnIp } from './region'
|
|
5
8
|
|
|
6
9
|
export async function fetchTitlesForParticipant(participant: ParticipantData, { page = 1 }: { page?: number } = {}): Promise<TitleData[]> {
|
|
7
|
-
const
|
|
10
|
+
const params = {
|
|
11
|
+
language: getLanguage(),
|
|
12
|
+
region: await getRegionBasedOnIp(),
|
|
13
|
+
include_count: 'false',
|
|
14
|
+
participant_sid: participant.sid,
|
|
15
|
+
page,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const response = await api<{ results: TitleData[] }>(`/titles/browse?api-token=${getApiToken()}&${paramsToString(params)}`)
|
|
8
19
|
|
|
9
20
|
return response.results
|
|
10
21
|
}
|
|
@@ -236,6 +236,21 @@ export const translations = {
|
|
|
236
236
|
[Language.Swedish]: 'Sök',
|
|
237
237
|
[Language.Danish]: 'Søg',
|
|
238
238
|
},
|
|
239
|
+
'Born On': {
|
|
240
|
+
[Language.English]: 'Born on',
|
|
241
|
+
[Language.Swedish]: 'Född den',
|
|
242
|
+
[Language.Danish]: 'Født den',
|
|
243
|
+
},
|
|
244
|
+
'Died On': {
|
|
245
|
+
[Language.English]: 'Died on',
|
|
246
|
+
[Language.Swedish]: 'Död den',
|
|
247
|
+
[Language.Danish]: 'Død den',
|
|
248
|
+
},
|
|
249
|
+
'Credits': {
|
|
250
|
+
[Language.English]: 'Credits',
|
|
251
|
+
[Language.Swedish]: 'Medverkande',
|
|
252
|
+
[Language.Danish]: 'Medvirkende',
|
|
253
|
+
},
|
|
239
254
|
|
|
240
255
|
// Genres
|
|
241
256
|
'All': {
|
package/src/main.ts
CHANGED
|
@@ -86,12 +86,13 @@ window.PlayPilotLinkInjections = {
|
|
|
86
86
|
|
|
87
87
|
const script = document.createElement('script')
|
|
88
88
|
|
|
89
|
+
script.id = 'playpilot-mount'
|
|
89
90
|
script.src = `https://cdn.jsdelivr.net/npm/@playpilot/tpi@${__SCRIPT_VERSION__}/dist/${shouldLoadEditorial ? 'editorial.' : ''}mount.js`
|
|
90
91
|
// script.src = './dist/mount.js' // Use me during development of this script
|
|
91
92
|
|
|
92
93
|
script.onload = () => window.PlayPilotMount?.mount()
|
|
93
94
|
|
|
94
|
-
|
|
95
|
+
document.body.appendChild(script)
|
|
95
96
|
},
|
|
96
97
|
}
|
|
97
98
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { SplitTest } from '$lib/enums/SplitTest'
|
|
3
|
+
import { getPageTextAndElements } from '$lib/injectionElements'
|
|
3
4
|
import { getFullUrlPath } from '$lib/url'
|
|
4
5
|
import { onDestroy } from 'svelte'
|
|
5
6
|
|
|
@@ -160,6 +161,11 @@
|
|
|
160
161
|
|
|
161
162
|
<hr />
|
|
162
163
|
|
|
164
|
+
<button onclick={() => console.log(getPageTextAndElements(window.PlayPilotLinkInjections.config))}>Output elements in console</button>
|
|
165
|
+
<button onclick={() => console.log(getPageTextAndElements(window.PlayPilotLinkInjections.config).pageText)}>Output text in console</button>
|
|
166
|
+
|
|
167
|
+
<hr />
|
|
168
|
+
|
|
163
169
|
<button onclick={onrerender}>Re-inject</button>
|
|
164
170
|
|
|
165
171
|
{#if isUsingBetaScript}
|
|
@@ -177,6 +183,7 @@
|
|
|
177
183
|
}
|
|
178
184
|
|
|
179
185
|
hr {
|
|
186
|
+
margin: margin(0.5) 0;
|
|
180
187
|
border-color: theme(primary);
|
|
181
188
|
}
|
|
182
189
|
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import IconArrow from './Icons/IconArrow.svelte'
|
|
5
5
|
import IconIMDb from './Icons/IconIMDb.svelte'
|
|
6
6
|
import TitlePoster from './TitlePoster.svelte'
|
|
7
|
+
import { t } from '$lib/localization'
|
|
7
8
|
|
|
8
9
|
interface Props {
|
|
9
10
|
title: TitleData
|
|
@@ -30,7 +31,7 @@
|
|
|
30
31
|
</div>
|
|
31
32
|
|
|
32
33
|
<div>{title.year}</div>
|
|
33
|
-
<div>{title.type}</div>
|
|
34
|
+
<div>{t(`Type: ${title.type}`)}</div>
|
|
34
35
|
|
|
35
36
|
{#if title.length}
|
|
36
37
|
<div>{title.length} min</div>
|
|
@@ -57,13 +57,13 @@
|
|
|
57
57
|
|
|
58
58
|
{#if birth_date}
|
|
59
59
|
<p class="dates">
|
|
60
|
-
Born
|
|
60
|
+
{t('Born On')} <strong>{formatDate(birth_date)}</strong>{#if death_date}, {t('Died On')} <strong>{formatDate(death_date)}</strong>{/if}
|
|
61
61
|
</p>
|
|
62
62
|
{/if}
|
|
63
63
|
</div>
|
|
64
64
|
|
|
65
65
|
<div class="content">
|
|
66
|
-
<div class="heading small" use:heading={3} id="credits">Credits</div>
|
|
66
|
+
<div class="heading small" use:heading={3} id="credits">{t('Credits')}</div>
|
|
67
67
|
|
|
68
68
|
<div class="list">
|
|
69
69
|
{#each titles as title}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import { api } from '$lib/api/api'
|
|
4
|
+
import { fetchTitlesForParticipant } from '$lib/api/participants'
|
|
5
|
+
import { participants, title } from '$lib/fakeData'
|
|
6
|
+
import { getApiToken } from '$lib/token'
|
|
7
|
+
import { fakeFetch } from '../../helpers'
|
|
8
|
+
|
|
9
|
+
vi.mock('$lib/token', () => ({
|
|
10
|
+
getApiToken: vi.fn(),
|
|
11
|
+
}))
|
|
12
|
+
|
|
13
|
+
vi.mock('$lib/api/api', () => ({
|
|
14
|
+
api: vi.fn(),
|
|
15
|
+
}))
|
|
16
|
+
|
|
17
|
+
describe('$lib/api/participants', () => {
|
|
18
|
+
beforeEach(() => {
|
|
19
|
+
// @ts-ignore
|
|
20
|
+
window.PlayPilotLinkInjections = {}
|
|
21
|
+
|
|
22
|
+
vi.resetAllMocks()
|
|
23
|
+
vi.mocked(getApiToken).mockReturnValue('some-token')
|
|
24
|
+
fakeFetch()
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
describe('fetchTitlesForParticipant', () => {
|
|
28
|
+
it('Should call api with given parameters and always include include_count=false and return titles', async () => {
|
|
29
|
+
vi.mocked(api).mockResolvedValueOnce({ results: [title] })
|
|
30
|
+
|
|
31
|
+
const response = await fetchTitlesForParticipant(participants[0])
|
|
32
|
+
|
|
33
|
+
expect(api).toHaveBeenCalledWith(`/titles/browse?api-token=some-token&language=en-US&include_count=false&participant_sid=${participants[0].sid}&page=1`)
|
|
34
|
+
expect(response).toEqual([title])
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
it('Should use given page number', async () => {
|
|
38
|
+
vi.mocked(api).mockResolvedValueOnce({ results: [title] })
|
|
39
|
+
|
|
40
|
+
await fetchTitlesForParticipant(participants[0], { page: 5 })
|
|
41
|
+
|
|
42
|
+
expect(api).toHaveBeenCalledWith(expect.stringContaining('page=5'))
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
it('Should throw when api returns error', async () => {
|
|
46
|
+
vi.mocked(api).mockRejectedValueOnce({ error: 'message' })
|
|
47
|
+
|
|
48
|
+
await expect(async () => await fetchTitlesForParticipant(participants[0])).rejects.toThrow()
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
it('Should include region if set', async () => {
|
|
52
|
+
vi.mocked(api).mockResolvedValueOnce({ results: [] })
|
|
53
|
+
|
|
54
|
+
window.PlayPilotLinkInjections.region = 'nl'
|
|
55
|
+
|
|
56
|
+
await fetchTitlesForParticipant(participants[0])
|
|
57
|
+
|
|
58
|
+
expect(api).toHaveBeenCalledWith(`/titles/browse?api-token=some-token&language=en-US®ion=nl&include_count=false&participant_sid=${participants[0].sid}&page=1`)
|
|
59
|
+
})
|
|
60
|
+
})
|
|
61
|
+
})
|
|
@@ -4,6 +4,7 @@ import { api } from '$lib/api/api'
|
|
|
4
4
|
import { fetchSimilarTitles, fetchTitles } from '$lib/api/titles'
|
|
5
5
|
import { title } from '$lib/fakeData'
|
|
6
6
|
import { getApiToken } from '$lib/token'
|
|
7
|
+
import { fakeFetch } from '../../helpers'
|
|
7
8
|
|
|
8
9
|
vi.mock('$lib/token', () => ({
|
|
9
10
|
getApiToken: vi.fn(),
|
|
@@ -13,10 +14,11 @@ vi.mock('$lib/api/api', () => ({
|
|
|
13
14
|
api: vi.fn(),
|
|
14
15
|
}))
|
|
15
16
|
|
|
16
|
-
describe('$lib/api/
|
|
17
|
+
describe('$lib/api/titles', () => {
|
|
17
18
|
beforeEach(() => {
|
|
18
19
|
vi.resetAllMocks()
|
|
19
20
|
vi.mocked(getApiToken).mockReturnValue('some-token')
|
|
21
|
+
fakeFetch()
|
|
20
22
|
})
|
|
21
23
|
|
|
22
24
|
describe('fetchTitles', () => {
|
package/src/tests/main.test.js
CHANGED
|
@@ -5,6 +5,7 @@ import { fetchConfig } from '$lib/api/config'
|
|
|
5
5
|
import { waitFor } from '@testing-library/svelte'
|
|
6
6
|
import { isUrlExcludedViaConfig } from '$lib/url'
|
|
7
7
|
import { pollLinkInjections } from '$lib/api/externalPages'
|
|
8
|
+
import { getAuthToken, isEditorialModeEnabled } from '$lib/api/auth'
|
|
8
9
|
|
|
9
10
|
vi.mock('$lib/consent', () => ({
|
|
10
11
|
setConsent: vi.fn(),
|
|
@@ -23,8 +24,15 @@ vi.mock('$lib/url', () => ({
|
|
|
23
24
|
isUrlExcludedViaConfig: vi.fn(),
|
|
24
25
|
}))
|
|
25
26
|
|
|
27
|
+
vi.mock('$lib/api/auth', () => ({
|
|
28
|
+
getAuthToken: vi.fn(),
|
|
29
|
+
isEditorialModeEnabled: vi.fn(),
|
|
30
|
+
}))
|
|
31
|
+
|
|
26
32
|
describe('main.ts', () => {
|
|
27
33
|
beforeEach(async () => {
|
|
34
|
+
document.body.innerHTML = ''
|
|
35
|
+
|
|
28
36
|
fakeFetch()
|
|
29
37
|
|
|
30
38
|
vi.resetModules()
|
|
@@ -37,65 +45,99 @@ describe('main.ts', () => {
|
|
|
37
45
|
vi.resetModules()
|
|
38
46
|
})
|
|
39
47
|
|
|
40
|
-
|
|
41
|
-
|
|
48
|
+
describe('initialize', () => {
|
|
49
|
+
it('Should not call setConsent when only a token is passed', () => {
|
|
50
|
+
window.PlayPilotLinkInjections.initialize({ token: 'a' })
|
|
42
51
|
|
|
43
|
-
|
|
52
|
+
expect(setConsent).not.toHaveBeenCalled()
|
|
44
53
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
54
|
+
expect(window.PlayPilotLinkInjections.consents).toEqual({
|
|
55
|
+
ads: false,
|
|
56
|
+
pixels: false,
|
|
57
|
+
tracking: false,
|
|
58
|
+
split_tests: false,
|
|
59
|
+
affiliate: false,
|
|
60
|
+
})
|
|
51
61
|
})
|
|
52
|
-
})
|
|
53
62
|
|
|
54
|
-
|
|
55
|
-
|
|
63
|
+
it('Should call setConsent when require_consent is false', () => {
|
|
64
|
+
window.PlayPilotLinkInjections.initialize({ token: 'a', require_consent: false })
|
|
56
65
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
66
|
+
expect(setConsent).toHaveBeenCalledWith({
|
|
67
|
+
ads: true,
|
|
68
|
+
pixels: true,
|
|
69
|
+
tracking: true,
|
|
70
|
+
split_tests: true,
|
|
71
|
+
affiliate: true,
|
|
72
|
+
})
|
|
63
73
|
})
|
|
64
|
-
})
|
|
65
74
|
|
|
66
|
-
|
|
67
|
-
|
|
75
|
+
it('Should call config object and set the result to the window object', async () => {
|
|
76
|
+
vi.mocked(fetchConfig).mockResolvedValue({ html_selector: 'some_value' })
|
|
68
77
|
|
|
69
|
-
|
|
78
|
+
window.PlayPilotLinkInjections.initialize({ token: 'a' })
|
|
70
79
|
|
|
71
|
-
|
|
80
|
+
expect(fetchConfig).toHaveBeenCalled()
|
|
72
81
|
|
|
73
|
-
|
|
74
|
-
|
|
82
|
+
await waitFor(() => {
|
|
83
|
+
expect(window.PlayPilotLinkInjections.config).toEqual({ html_selector: 'some_value' })
|
|
84
|
+
})
|
|
75
85
|
})
|
|
76
|
-
})
|
|
77
86
|
|
|
78
|
-
|
|
79
|
-
|
|
87
|
+
it('Should not call pollLinkInjections if config object excludes page', async () => {
|
|
88
|
+
vi.mocked(isUrlExcludedViaConfig).mockReturnValue(true)
|
|
89
|
+
|
|
90
|
+
window.PlayPilotLinkInjections.initialize({ token: 'a' })
|
|
91
|
+
|
|
92
|
+
expect(fetchConfig).toHaveBeenCalled()
|
|
93
|
+
|
|
94
|
+
await new Promise(res => setTimeout(res))
|
|
95
|
+
|
|
96
|
+
expect(pollLinkInjections).not.toHaveBeenCalled()
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
it('Should call pollLinkInjections if config object does not page', async () => {
|
|
100
|
+
vi.mocked(isUrlExcludedViaConfig).mockReturnValue(false)
|
|
80
101
|
|
|
81
|
-
|
|
102
|
+
window.PlayPilotLinkInjections.initialize({ token: 'a' })
|
|
82
103
|
|
|
83
|
-
|
|
104
|
+
expect(fetchConfig).toHaveBeenCalled()
|
|
84
105
|
|
|
85
|
-
|
|
106
|
+
await new Promise(res => setTimeout(res))
|
|
86
107
|
|
|
87
|
-
|
|
108
|
+
expect(pollLinkInjections).toHaveBeenCalled()
|
|
109
|
+
})
|
|
88
110
|
})
|
|
89
111
|
|
|
90
|
-
|
|
91
|
-
|
|
112
|
+
describe('mount', () => {
|
|
113
|
+
it('Should insert script tag', () => {
|
|
114
|
+
window.PlayPilotLinkInjections.mount()
|
|
115
|
+
|
|
116
|
+
expect(document.querySelector('script#playpilot-mount')).toBeTruthy()
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
it('Should insert script tag with editorial mode if editiorial mode is enabled', () => {
|
|
120
|
+
vi.mocked(isEditorialModeEnabled).mockReturnValueOnce(true)
|
|
92
121
|
|
|
93
|
-
|
|
122
|
+
window.PlayPilotLinkInjections.mount()
|
|
123
|
+
expect(/** @type {HTMLScriptElement} */(document.querySelector('script#playpilot-mount')).src).toContain('editorial.mount.js')
|
|
124
|
+
})
|
|
94
125
|
|
|
95
|
-
|
|
126
|
+
it('Should insert script tag with editorial mode if editiorial mode is disabled but auth token is present', () => {
|
|
127
|
+
vi.mocked(isEditorialModeEnabled).mockReturnValueOnce(false)
|
|
128
|
+
vi.mocked(getAuthToken).mockReturnValueOnce('abc')
|
|
96
129
|
|
|
97
|
-
|
|
130
|
+
window.PlayPilotLinkInjections.mount()
|
|
131
|
+
expect(/** @type {HTMLScriptElement} */(document.querySelector('script#playpilot-mount')).src).toContain('editorial.mount.js')
|
|
132
|
+
})
|
|
98
133
|
|
|
99
|
-
|
|
134
|
+
it('Should insert script tag without editorial mode if editiorial mode is disabled but auth token is present', () => {
|
|
135
|
+
vi.mocked(isEditorialModeEnabled).mockReturnValueOnce(false)
|
|
136
|
+
vi.mocked(getAuthToken).mockReturnValueOnce('')
|
|
137
|
+
|
|
138
|
+
window.PlayPilotLinkInjections.mount()
|
|
139
|
+
expect(/** @type {HTMLScriptElement} */(document.querySelector('script#playpilot-mount')).src).not.toContain('editorial.mount.js')
|
|
140
|
+
expect(/** @type {HTMLScriptElement} */(document.querySelector('script#playpilot-mount')).src).toContain('mount.js')
|
|
141
|
+
})
|
|
100
142
|
})
|
|
101
143
|
})
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
2
|
+
import { fakeFetch } from './helpers'
|
|
3
|
+
import { clearLinkInjections } from '$lib/injection'
|
|
4
|
+
import { mount } from 'svelte'
|
|
5
|
+
|
|
6
|
+
vi.mock('$lib/injection', () => ({
|
|
7
|
+
clearLinkInjections: vi.fn(),
|
|
8
|
+
}))
|
|
9
|
+
|
|
10
|
+
vi.mock('svelte', () => ({
|
|
11
|
+
mount: vi.fn(),
|
|
12
|
+
}))
|
|
13
|
+
|
|
14
|
+
describe('mount.ts', () => {
|
|
15
|
+
beforeEach(async () => {
|
|
16
|
+
// @ts-ignore
|
|
17
|
+
window.PlayPilotLinkInjections = {}
|
|
18
|
+
document.body.innerHTML = ''
|
|
19
|
+
|
|
20
|
+
fakeFetch()
|
|
21
|
+
|
|
22
|
+
vi.resetModules()
|
|
23
|
+
vi.resetAllMocks()
|
|
24
|
+
|
|
25
|
+
await import('../mount')
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
describe('mount', () => {
|
|
29
|
+
it('Should mount app', () => {
|
|
30
|
+
window.PlayPilotMount.mount()
|
|
31
|
+
|
|
32
|
+
expect(mount).toHaveBeenCalledWith(expect.any(Function), { target: expect.any(HTMLElement) })
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it('Should assign app to window PlayPilotLinkInjections object', () => {
|
|
36
|
+
vi.mocked(mount).mockReturnValueOnce({ some_key: 'Some value' })
|
|
37
|
+
|
|
38
|
+
window.PlayPilotMount.mount()
|
|
39
|
+
|
|
40
|
+
expect(window.PlayPilotLinkInjections.app).toEqual({ some_key: 'Some value' })
|
|
41
|
+
})
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
describe('destroy', () => {
|
|
45
|
+
it('Should call clearLinkInjections and remove link injections element', () => {
|
|
46
|
+
document.body.innerHTML = '<div id="playpilot-link-injection"></div>'
|
|
47
|
+
|
|
48
|
+
window.PlayPilotMount.destroy()
|
|
49
|
+
|
|
50
|
+
expect(document.body.innerHTML).toBe('')
|
|
51
|
+
expect(clearLinkInjections).toHaveBeenCalled()
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it('Should clear app on window PlayPilotLinkInjections object', () => {
|
|
55
|
+
// @ts-ignore
|
|
56
|
+
window.PlayPilotLinkInjections = { app: {} }
|
|
57
|
+
|
|
58
|
+
window.PlayPilotMount.destroy()
|
|
59
|
+
|
|
60
|
+
expect(window.PlayPilotLinkInjections.app).toBe(null)
|
|
61
|
+
})
|
|
62
|
+
})
|
|
63
|
+
})
|