@playpilot/tpi 8.14.0 → 8.15.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/dist/editorial.mount.js +9 -9
- package/dist/link-injections.js +1 -1
- package/dist/mount.js +9 -9
- package/package.json +1 -1
- package/src/lib/api/externalPages.ts +0 -7
- package/src/lib/api/titles.ts +10 -0
- package/src/lib/data/translations.ts +5 -0
- package/src/lib/injection.ts +13 -3
- package/src/lib/routes.ts +4 -0
- package/src/lib/types/config.d.ts +5 -0
- package/src/lib/types/explore.d.ts +1 -0
- package/src/routes/components/Description.svelte +1 -0
- package/src/routes/components/Explore/ExploreRouter.svelte +38 -2
- package/src/routes/components/Explore/Routes/ExploreModal.svelte +38 -0
- package/src/routes/components/Explore/Routes/ExploreResults.svelte +12 -2
- package/src/routes/components/Explore/Routes/ExploreTitle.svelte +94 -0
- package/src/routes/components/Modals/Modal.svelte +3 -1
- package/src/routes/components/Modals/RailModal.svelte +4 -3
- package/src/routes/components/Modals/TitlesRailModal.svelte +5 -4
- package/src/routes/components/Playlinks/Playlinks.svelte +1 -0
- package/src/routes/components/Rails/TitlesRail.svelte +12 -5
- package/src/routes/components/Title.svelte +12 -4
- package/src/routes/components/Widgets/InjectionsWidgetRail.svelte +5 -1
- package/src/routes/explore/+page.svelte +4 -0
- package/src/tests/lib/api/titles.test.js +23 -1
- package/src/tests/lib/injection.test.js +44 -3
- package/src/tests/lib/routes.test.js +14 -2
- package/src/tests/routes/components/Explore/Routes/ExploreTitle.test.js +87 -0
- package/src/tests/routes/components/Rails/TitlesRail.test.js +10 -0
|
@@ -6,6 +6,7 @@ import { mount, unmount } from 'svelte'
|
|
|
6
6
|
import { fakeFetch, generateInjection } from '../helpers'
|
|
7
7
|
import { openModalForInjectedLink } from '$lib/modal'
|
|
8
8
|
import { getLinkInjectionElements } from '$lib/injectionElements'
|
|
9
|
+
import { titleUrl } from '$lib/routes'
|
|
9
10
|
|
|
10
11
|
vi.mock('svelte', () => ({
|
|
11
12
|
mount: vi.fn(),
|
|
@@ -64,8 +65,9 @@ describe('injection.ts', () => {
|
|
|
64
65
|
|
|
65
66
|
const link = /** @type {HTMLAnchorElement} */ (document.querySelector('a'))
|
|
66
67
|
|
|
68
|
+
// @ts-ignore
|
|
69
|
+
expect(link.href).toBe(titleUrl(injection.title_details))
|
|
67
70
|
expect(link.innerText).toBe(injection.title)
|
|
68
|
-
expect(link.href).toBe(injection.playpilot_url)
|
|
69
71
|
})
|
|
70
72
|
|
|
71
73
|
it('Should replace given words as expected when more than 1 injection per sentence is present', () => {
|
|
@@ -83,11 +85,13 @@ describe('injection.ts', () => {
|
|
|
83
85
|
|
|
84
86
|
const links = /** @type {HTMLAnchorElement[]} */ (Array.from(document.querySelectorAll('a')))
|
|
85
87
|
|
|
88
|
+
// @ts-ignore
|
|
89
|
+
expect(links[0].href).toBe(titleUrl(linkInjections[0].title_details))
|
|
86
90
|
expect(links[0].innerText).toBe(linkInjections[0].title)
|
|
87
|
-
expect(links[0].href).toBe(linkInjections[0].playpilot_url)
|
|
88
91
|
|
|
92
|
+
// @ts-ignore
|
|
93
|
+
expect(links[1].href).toBe(titleUrl(linkInjections[1].title_details))
|
|
89
94
|
expect(links[1].innerText).toBe(linkInjections[1].title)
|
|
90
|
-
expect(links[1].href).toBe(linkInjections[1].playpilot_url)
|
|
91
95
|
})
|
|
92
96
|
|
|
93
97
|
it('Should ignore injections that are marked as inactive', () => {
|
|
@@ -946,6 +950,43 @@ describe('injection.ts', () => {
|
|
|
946
950
|
|
|
947
951
|
expect(document.querySelector('a')?.closest('[data-playpilot-injection-key]')).toBeTruthy()
|
|
948
952
|
})
|
|
953
|
+
|
|
954
|
+
describe('config.open_tpi_links_in_explore', () => {
|
|
955
|
+
beforeEach(() => {
|
|
956
|
+
window.PlayPilotLinkInjections.config = {
|
|
957
|
+
open_tpi_links_in_explore: true,
|
|
958
|
+
explore_navigation_path: 'https://some-path.com/explore',
|
|
959
|
+
}
|
|
960
|
+
})
|
|
961
|
+
|
|
962
|
+
it('Should use href with explore links if open_tpi_links_in_explore is true', () => {
|
|
963
|
+
const injection = generateInjection('This is a sentence with an injection.', 'an injection')
|
|
964
|
+
|
|
965
|
+
document.body.innerHTML = `<p>${injection.sentence}</p>`
|
|
966
|
+
|
|
967
|
+
const elements = Array.from(document.querySelectorAll('p'))
|
|
968
|
+
|
|
969
|
+
injectLinksInDocument(elements, { aiInjections: [injection], manualInjections: [] })
|
|
970
|
+
|
|
971
|
+
const link = /** @type {HTMLAnchorElement} */ (document.querySelector('a'))
|
|
972
|
+
expect(link.href).toBe(window.PlayPilotLinkInjections.config.explore_navigation_path + `?route=modal&sid=${injection.title_details?.sid}`)
|
|
973
|
+
expect(link.target).not.toBeTruthy()
|
|
974
|
+
})
|
|
975
|
+
|
|
976
|
+
it('Should not open modal when link is clicked when open_tpi_links_in_explore is true', async () => {
|
|
977
|
+
document.body.innerHTML = '<p>This is a sentence with an injection.</p>'
|
|
978
|
+
|
|
979
|
+
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
980
|
+
const injection = generateInjection('This is a sentence with an injection.', 'an injection')
|
|
981
|
+
|
|
982
|
+
injectLinksInDocument(elements, { aiInjections: [injection], manualInjections: [] })
|
|
983
|
+
|
|
984
|
+
const link = /** @type {HTMLAnchorElement} */ (document.querySelector('a'))
|
|
985
|
+
await fireEvent.click(link)
|
|
986
|
+
|
|
987
|
+
expect(openModalForInjectedLink).not.toHaveBeenCalled()
|
|
988
|
+
})
|
|
989
|
+
})
|
|
949
990
|
})
|
|
950
991
|
|
|
951
992
|
describe('clearLinkInjections', () => {
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest'
|
|
2
|
-
import { titleUrl } from '$lib/routes'
|
|
2
|
+
import { exploreTitleUrl, titleUrl } from '$lib/routes'
|
|
3
3
|
import { playPilotBaseUrl } from '$lib/constants'
|
|
4
|
+
import { title } from '$lib/fakeData'
|
|
4
5
|
|
|
5
6
|
describe('$lib/routes', () => {
|
|
6
|
-
describe('
|
|
7
|
+
describe('titleUrl', () => {
|
|
7
8
|
it('Should return url for given title', () => {
|
|
8
9
|
// @ts-ignore
|
|
9
10
|
expect(titleUrl({ type: 'series', slug: 'some-slug' })).toBe(`${playPilotBaseUrl}/series/some-slug/`)
|
|
@@ -12,4 +13,15 @@ describe('$lib/routes', () => {
|
|
|
12
13
|
expect(titleUrl({ type: 'movie', slug: 'some-other-slug' })).toBe(`${playPilotBaseUrl}/movie/some-other-slug/`)
|
|
13
14
|
})
|
|
14
15
|
})
|
|
16
|
+
|
|
17
|
+
describe('exploreTitleUrl', () => {
|
|
18
|
+
it('Should return url for given title', () => {
|
|
19
|
+
window.PlayPilotLinkInjections.config = {
|
|
20
|
+
open_tpi_links_in_explore: true,
|
|
21
|
+
explore_navigation_path: 'https://some-path.com/explore',
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
expect(exploreTitleUrl(title)).toBe(`https://some-path.com/explore?route=modal&sid=${title.sid}`)
|
|
25
|
+
})
|
|
26
|
+
})
|
|
15
27
|
})
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { render, waitFor, fireEvent } from '@testing-library/svelte'
|
|
2
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
3
|
+
|
|
4
|
+
import TitleDetail from '../../../../../routes/components/Explore/Routes/ExploreTitle.svelte'
|
|
5
|
+
import { fetchTitleBySid } from '$lib/api/titles'
|
|
6
|
+
import { title } from '$lib/fakeData'
|
|
7
|
+
|
|
8
|
+
vi.mock('$lib/api/titles', () => ({
|
|
9
|
+
fetchTitleBySid: vi.fn(),
|
|
10
|
+
}))
|
|
11
|
+
|
|
12
|
+
vi.mock('/src/routes/components/Title.svelte', () => ({
|
|
13
|
+
default: vi.fn(),
|
|
14
|
+
}))
|
|
15
|
+
|
|
16
|
+
describe('ExploreTitle.svelte', () => {
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
vi.resetAllMocks()
|
|
19
|
+
vi.mocked(fetchTitleBySid).mockResolvedValue(title)
|
|
20
|
+
|
|
21
|
+
history.pushState({}, '', '/')
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
it('Should render empty state when no sid is in the URL', async () => {
|
|
25
|
+
const { getByText } = render(TitleDetail)
|
|
26
|
+
|
|
27
|
+
await waitFor(() => {
|
|
28
|
+
expect(getByText('Page not found')).toBeTruthy()
|
|
29
|
+
})
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
it('Should call fetchTitleBySid with sid from URL', async () => {
|
|
33
|
+
history.pushState({}, '', '?sid=some-sid')
|
|
34
|
+
|
|
35
|
+
render(TitleDetail)
|
|
36
|
+
|
|
37
|
+
expect(fetchTitleBySid).toHaveBeenCalledWith('some-sid')
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
it('Should render loading state while fetching', async () => {
|
|
41
|
+
history.pushState({}, '', '?sid=some-sid')
|
|
42
|
+
vi.mocked(fetchTitleBySid).mockReturnValue(new Promise(() => {}))
|
|
43
|
+
|
|
44
|
+
const { getByText } = render(TitleDetail)
|
|
45
|
+
|
|
46
|
+
expect(getByText('Loading...')).toBeTruthy()
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
it('Should render the title when fetchTitleBySid resolves', async () => {
|
|
50
|
+
history.pushState({}, '', '?sid=some-sid')
|
|
51
|
+
|
|
52
|
+
const { getByTestId } = render(TitleDetail)
|
|
53
|
+
|
|
54
|
+
await waitFor(() => {
|
|
55
|
+
expect(getByTestId('title')).toBeTruthy()
|
|
56
|
+
})
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
it('Should render empty state when fetchTitleBySid rejects', async () => {
|
|
60
|
+
history.pushState({}, '', '?sid=some-sid')
|
|
61
|
+
vi.mocked(fetchTitleBySid).mockRejectedValue(new Error('Not found'))
|
|
62
|
+
|
|
63
|
+
const { getByText } = render(TitleDetail)
|
|
64
|
+
|
|
65
|
+
await waitFor(() => {
|
|
66
|
+
expect(getByText('Page not found')).toBeTruthy()
|
|
67
|
+
})
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
it('Should call navigate with "home" when back button is clicked', async () => {
|
|
71
|
+
history.pushState({}, '', '?sid=some-sid')
|
|
72
|
+
|
|
73
|
+
const navigate = vi.fn()
|
|
74
|
+
|
|
75
|
+
const { getByText } = render(TitleDetail, { navigate })
|
|
76
|
+
|
|
77
|
+
await fireEvent.click(getByText('Home'))
|
|
78
|
+
|
|
79
|
+
expect(navigate).toHaveBeenCalledWith('home')
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
it('Should not call fetchTitleBySid when no sid is in the URL', async () => {
|
|
83
|
+
render(TitleDetail)
|
|
84
|
+
|
|
85
|
+
expect(fetchTitleBySid).not.toHaveBeenCalled()
|
|
86
|
+
})
|
|
87
|
+
})
|
|
@@ -213,4 +213,14 @@ describe('TitlesRail.svelte', () => {
|
|
|
213
213
|
|
|
214
214
|
expect(container.querySelector('.titles .slider')).toBeTruthy()
|
|
215
215
|
})
|
|
216
|
+
|
|
217
|
+
it('Should navigate to explore page rather than open modal when navigateToExplore is true', async () => {
|
|
218
|
+
const { getAllByRole } = render(TitlesRail, { titles: [title], navigateToExplore: true })
|
|
219
|
+
|
|
220
|
+
await fireEvent.click(getAllByRole('link')[0])
|
|
221
|
+
|
|
222
|
+
expect(getAllByRole('link')[0].getAttribute('href')).toContain(`?route=modal&sid=${title.sid}`)
|
|
223
|
+
expect(window.location.href).toContain(`?route=modal&sid=${title.sid}`)
|
|
224
|
+
expect(openModal).not.toHaveBeenCalledWith()
|
|
225
|
+
})
|
|
216
226
|
})
|