@playpilot/tpi 6.1.1 → 6.2.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/.github/workflows/tests.yml +20 -8
- package/dist/link-injections.js +7 -7
- package/package.json +2 -1
- package/src/lib/types/config.d.ts +6 -1
- package/src/routes/components/Editorial/AIIndicator.svelte +1 -5
- package/src/routes/components/Editorial/Alert.svelte +1 -0
- package/src/routes/components/Explore/Explore.svelte +16 -29
- package/src/routes/components/Playlinks/Playlinks.svelte +1 -1
- package/src/tests/routes/components/Explore/Explore.test.js +15 -16
- package/src/tests/routes/components/Modal.test.js +4 -13
- package/src/tests/routes/components/Playlinks/Playlinks.test.js +24 -2
- package/tsconfig.json +2 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@playpilot/tpi",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "vite dev",
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"@sveltejs/kit": "^2.0.0",
|
|
20
20
|
"@sveltejs/vite-plugin-svelte": "^4.0.0",
|
|
21
21
|
"@testing-library/svelte": "^5.2.6",
|
|
22
|
+
"@types/node": "^25.2.0",
|
|
22
23
|
"@typescript-eslint/eslint-plugin": "^8.32.1",
|
|
23
24
|
"@typescript-eslint/parser": "^8.32.1",
|
|
24
25
|
"eslint": "^9.27.0",
|
|
@@ -33,12 +33,17 @@ export type ConfigResponse = {
|
|
|
33
33
|
*/
|
|
34
34
|
disable_public_injections?: boolean
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
/**
|
|
37
37
|
* Region to fall back on if other methods of getting the region fail. This should be equal to the region most relevant
|
|
38
38
|
* to the partner. Should be lowercase.
|
|
39
39
|
*/
|
|
40
40
|
fallback_region?: string
|
|
41
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Disclaimer text that is shown above playlinks in title cards used to replace the default text
|
|
44
|
+
*/
|
|
45
|
+
playlinks_disclaimer_text?: string
|
|
46
|
+
|
|
42
47
|
/**
|
|
43
48
|
* The following options are all relevant for in text disclaimers, which renders as a disclaimer text within the article,
|
|
44
49
|
* rather than only inside of title cards.
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
|
|
26
26
|
<div>
|
|
27
27
|
{#if !aiEnabled}
|
|
28
|
-
<strong>AI processing is disabled.</strong>
|
|
28
|
+
<strong>AI processing is disabled.</strong>
|
|
29
29
|
{:else if aiRunning}
|
|
30
30
|
<strong>AI links are currently processing.</strong> This can take several minutes. We'll insert all found injections once ready.
|
|
31
31
|
|
|
@@ -70,10 +70,6 @@
|
|
|
70
70
|
{/if}
|
|
71
71
|
|
|
72
72
|
<style lang="scss">
|
|
73
|
-
a {
|
|
74
|
-
color: currentColor;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
73
|
p {
|
|
78
74
|
margin: 0;
|
|
79
75
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { heading } from '$lib/actions/heading'
|
|
3
|
-
import { searchTitles } from '$lib/api/search'
|
|
4
3
|
import { fetchTitles } from '$lib/api/titles'
|
|
5
4
|
import { TrackingEvent } from '$lib/enums/TrackingEvent'
|
|
6
5
|
import { exploreParentSelector } from '$lib/explore'
|
|
@@ -52,40 +51,28 @@
|
|
|
52
51
|
latestRequestId += 1
|
|
53
52
|
const requestId = latestRequestId
|
|
54
53
|
|
|
55
|
-
|
|
54
|
+
const params: Record<string, string | number> = { page_size: 24, page }
|
|
56
55
|
|
|
57
|
-
|
|
58
|
-
// If not, we use fetchTitles with the given params for the filter.
|
|
59
|
-
// This is because the backend does not support filters for search results yet.
|
|
60
|
-
// In the future we will likely merge these two, either by adding filters in the backend
|
|
61
|
-
// or by filtering results in the frontend (this seems like the less good option).
|
|
62
|
-
if (searchQuery) {
|
|
63
|
-
const results: TitleData[] = await searchTitles(searchQuery)
|
|
64
|
-
response = { results, next: null, previous: null }
|
|
56
|
+
if (searchQuery) params.search = searchQuery
|
|
65
57
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
58
|
+
Object.entries(filter).forEach(([key, { type, value }]) => {
|
|
59
|
+
if (type === 'string') {
|
|
60
|
+
params[key] = value as string
|
|
61
|
+
} else if (type === 'array') {
|
|
62
|
+
params[key] = (value as string[]).join(',')
|
|
63
|
+
} else if (type === 'range') {
|
|
64
|
+
const [min, max] = value as number[]
|
|
69
65
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
params[key] = (value as string[]).join(',')
|
|
75
|
-
} else if (type === 'range') {
|
|
76
|
-
const [min, max] = value as number[]
|
|
66
|
+
params[key + '_min'] = min
|
|
67
|
+
params[key + '_max'] = max
|
|
68
|
+
}
|
|
69
|
+
})
|
|
77
70
|
|
|
78
|
-
|
|
79
|
-
params[key + '_max'] = max
|
|
80
|
-
}
|
|
81
|
-
})
|
|
71
|
+
const response = await fetchTitles(params)
|
|
82
72
|
|
|
83
|
-
|
|
73
|
+
if (!response?.results) throw new Error('Something went wrong when fetching titles in Explore')
|
|
84
74
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
if (requestId === latestRequestId) titles = [...titles, ...response.results]
|
|
88
|
-
}
|
|
75
|
+
if (requestId === latestRequestId) titles = [...titles, ...response.results]
|
|
89
76
|
|
|
90
77
|
return response
|
|
91
78
|
}
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
|
|
39
39
|
{#if playlinks.length}
|
|
40
40
|
<div class="disclaimer" data-testid="commission-disclaimer">
|
|
41
|
-
{t('Commission Disclaimer')}
|
|
41
|
+
{window?.PlayPilotLinkInjections?.config?.playlinks_disclaimer_text || t('Commission Disclaimer')}
|
|
42
42
|
<a href="https://playpilot.com/" target="_blank" rel="sponsored">PlayPilot.com</a>
|
|
43
43
|
</div>
|
|
44
44
|
{/if}
|
|
@@ -4,7 +4,6 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
|
4
4
|
import Explore from '../../../../routes/components/Explore/Explore.svelte'
|
|
5
5
|
import { fetchTitles } from '$lib/api/titles'
|
|
6
6
|
import { title } from '$lib/fakeData'
|
|
7
|
-
import { searchTitles } from '$lib/api/search'
|
|
8
7
|
import { TrackingEvent } from '$lib/enums/TrackingEvent'
|
|
9
8
|
import { track } from '$lib/tracking'
|
|
10
9
|
|
|
@@ -103,21 +102,6 @@ describe('Explore.svelte', () => {
|
|
|
103
102
|
expect(queryByTestId('skeleton')).not.toBeTruthy()
|
|
104
103
|
})
|
|
105
104
|
|
|
106
|
-
it('Should fetch using searchTitles when query is given, resetting previous titles', async () => {
|
|
107
|
-
vi.mocked(fetchTitles).mockResolvedValueOnce({ results: [title, title], next: 'truthy', previous: null })
|
|
108
|
-
|
|
109
|
-
const { getByRole, getAllByTestId } = render(Explore)
|
|
110
|
-
|
|
111
|
-
vi.mocked(searchTitles).mockResolvedValueOnce([title])
|
|
112
|
-
|
|
113
|
-
fireEvent.input(getByRole('searchbox'), { target: { value: 'some query' } })
|
|
114
|
-
|
|
115
|
-
await waitFor(() => {
|
|
116
|
-
expect(searchTitles).toHaveBeenCalledWith('some query')
|
|
117
|
-
expect(getAllByTestId('title')).toHaveLength(1)
|
|
118
|
-
})
|
|
119
|
-
})
|
|
120
|
-
|
|
121
105
|
it('Should call fetchTitles with string of comma separated values when filtering with array value', async () => {
|
|
122
106
|
vi.mocked(fetchTitles).mockResolvedValue({ results: [title], next: 'truthy', previous: null })
|
|
123
107
|
|
|
@@ -131,6 +115,21 @@ describe('Explore.svelte', () => {
|
|
|
131
115
|
expect(fetchTitles).toHaveBeenCalledWith({ page: 1, page_size: 24, genres: '101,109' })
|
|
132
116
|
})
|
|
133
117
|
|
|
118
|
+
it('Should include search param when query is given', async () => {
|
|
119
|
+
vi.mocked(fetchTitles).mockResolvedValueOnce({ results: [title, title], next: 'truthy', previous: null })
|
|
120
|
+
|
|
121
|
+
const { getByRole, getAllByTestId } = render(Explore)
|
|
122
|
+
|
|
123
|
+
vi.mocked(fetchTitles).mockResolvedValueOnce({ results: [title], next: 'truthy', previous: null })
|
|
124
|
+
|
|
125
|
+
fireEvent.input(getByRole('searchbox'), { target: { value: 'some query' } })
|
|
126
|
+
|
|
127
|
+
await waitFor(() => {
|
|
128
|
+
expect(fetchTitles).toHaveBeenCalledWith({ page: 1, page_size: 24, search: 'some query' })
|
|
129
|
+
expect(getAllByTestId('title')).toHaveLength(1)
|
|
130
|
+
})
|
|
131
|
+
})
|
|
132
|
+
|
|
134
133
|
it('Should call fetchTitles with min and max values when filtering with range value', async () => {
|
|
135
134
|
vi.mocked(fetchTitles).mockResolvedValue({ results: [title], next: 'truthy', previous: null })
|
|
136
135
|
|
|
@@ -84,26 +84,17 @@ describe('Modal.svelte', () => {
|
|
|
84
84
|
expect(onscroll).toHaveBeenCalled()
|
|
85
85
|
})
|
|
86
86
|
|
|
87
|
-
it('Should set
|
|
87
|
+
it('Should set class on mount', () => {
|
|
88
88
|
render(Modal, { children })
|
|
89
89
|
|
|
90
|
-
expect(document.documentElement.
|
|
90
|
+
expect(document.documentElement.classList).toContain('playpilot-modal-open')
|
|
91
91
|
})
|
|
92
92
|
|
|
93
|
-
it('Should remove
|
|
93
|
+
it('Should remove class when component is unmounted', () => {
|
|
94
94
|
const { unmount } = render(Modal, { children })
|
|
95
95
|
unmount()
|
|
96
96
|
|
|
97
|
-
expect(document.documentElement.
|
|
98
|
-
})
|
|
99
|
-
|
|
100
|
-
it('Should use overflow as it was before the component was mounted when component is unmounted', () => {
|
|
101
|
-
document.documentElement.style.overflowY = 'some-value'
|
|
102
|
-
|
|
103
|
-
const { unmount } = render(Modal, { children })
|
|
104
|
-
unmount()
|
|
105
|
-
|
|
106
|
-
expect(document.documentElement.style.overflowY).toBe('some-value')
|
|
97
|
+
expect(document.documentElement.classList).not.toContain('playpilot-modal-open')
|
|
107
98
|
})
|
|
108
99
|
|
|
109
100
|
it('Should not have tall class by default', () => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { fireEvent, render } 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 Playlinks from '../../../../routes/components/Playlinks/Playlinks.svelte'
|
|
5
5
|
import { title } from '$lib/fakeData'
|
|
@@ -17,6 +17,11 @@ vi.mock('svelte', async (importActual) => ({
|
|
|
17
17
|
}))
|
|
18
18
|
|
|
19
19
|
describe('Playlinks.svelte', () => {
|
|
20
|
+
beforeEach(() => {
|
|
21
|
+
// @ts-ignore
|
|
22
|
+
window.PlayPilotLinkInjections = {}
|
|
23
|
+
})
|
|
24
|
+
|
|
20
25
|
it('Should render each given playlink', () => {
|
|
21
26
|
const playlinks = [
|
|
22
27
|
{ name: 'Some playlink', logo_url: 'logo', extra_info: { category: 'SVOD' } },
|
|
@@ -35,9 +40,26 @@ describe('Playlinks.svelte', () => {
|
|
|
35
40
|
{ name: 'Some other playlink', logo_url: 'logo', extra_info: { category: 'SVOD' } },
|
|
36
41
|
]
|
|
37
42
|
// @ts-ignore
|
|
38
|
-
const { getByTestId } = render(Playlinks, { playlinks, title })
|
|
43
|
+
const { getByTestId, getByText } = render(Playlinks, { playlinks, title })
|
|
39
44
|
|
|
40
45
|
expect(getByTestId('commission-disclaimer')).toBeTruthy()
|
|
46
|
+
expect(getByText('We may earn a commission', { exact: false })).toBeTruthy()
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
it('Should replace default disclaimer text with config value when given', () => {
|
|
50
|
+
// @ts-ignore
|
|
51
|
+
window.PlayPilotLinkInjections = {
|
|
52
|
+
config: { playlinks_disclaimer_text: 'Some disclaimer' },
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const playlinks = [
|
|
56
|
+
{ name: 'Some playlink', logo_url: 'logo', extra_info: { category: 'SVOD' } },
|
|
57
|
+
]
|
|
58
|
+
|
|
59
|
+
// @ts-ignore
|
|
60
|
+
const { getByText } = render(Playlinks, { playlinks, title })
|
|
61
|
+
|
|
62
|
+
expect(getByText('Some disclaimer')).toBeTruthy()
|
|
41
63
|
})
|
|
42
64
|
|
|
43
65
|
it('Should show empty state without commission disclaimer when no playlinks were given', () => {
|
package/tsconfig.json
CHANGED
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
"skipLibCheck": true,
|
|
10
10
|
"sourceMap": true,
|
|
11
11
|
"strict": true,
|
|
12
|
-
"moduleResolution": "bundler"
|
|
12
|
+
"moduleResolution": "bundler",
|
|
13
|
+
"types": ["node"]
|
|
13
14
|
}
|
|
14
15
|
// Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
|
|
15
16
|
// except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
|