@playpilot/tpi 1.4.3 → 2.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/dist/link-injections.js +7 -7
- package/package.json +1 -1
- package/src/lib/api.js +13 -30
- package/src/lib/fakeData.js +2 -1
- package/src/lib/linkInjection.js +102 -11
- package/src/lib/text.js +0 -1
- package/src/routes/+layout.svelte +3 -1
- package/src/routes/+page.svelte +35 -16
- package/src/routes/components/Editorial/AIIndicator.svelte +133 -0
- package/src/routes/components/Editorial/Editor.svelte +39 -10
- package/src/routes/components/Editorial/EditorItem.svelte +2 -2
- package/src/routes/components/Editorial/ManualInjection.svelte +1 -0
- package/src/routes/components/Editorial/PlaylinkTypeSelect.svelte +2 -2
- package/src/routes/components/Icons/IconAi.svelte +1 -0
- package/src/tests/helpers.js +17 -0
- package/src/tests/lib/api.test.js +13 -26
- package/src/tests/lib/linkInjection.test.js +259 -250
- package/src/tests/routes/+page.test.js +16 -1
- package/src/tests/routes/components/Editorial/AiIndicator.test.js +58 -0
- package/src/tests/routes/components/Editorial/Editor.test.js +18 -20
- package/src/tests/routes/components/Editorial/EditorItem.test.js +12 -17
- package/src/tests/routes/components/Editorial/ManualInjection.test.js +12 -10
- package/src/typedefs.js +27 -12
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { fireEvent } from '@testing-library/svelte'
|
|
2
2
|
import { describe, expect, it, vi, beforeEach } from 'vitest'
|
|
3
3
|
|
|
4
|
-
import { injectLinksInDocument, clearLinkInjections, clearLinkInjection, getLinkInjectionElements, insertAfterArticlePlaylinks, getLinkInjectionsParentElement, sortLinkInjectionsByRange } from '$lib/linkInjection'
|
|
5
|
-
import { title } from '$lib/fakeData'
|
|
4
|
+
import { injectLinksInDocument, clearLinkInjections, clearLinkInjection, getLinkInjectionElements, insertAfterArticlePlaylinks, getLinkInjectionsParentElement, sortLinkInjectionsByRange, isAvailableAsManualInjection, filterRemovedInjections, isEquivalentInjection, filterInvalidInTextInjections, filterInvalidAfterArticleInjections, isValidInjection } from '$lib/linkInjection'
|
|
6
5
|
import { mount, unmount } from 'svelte'
|
|
6
|
+
import { generateInjection } from '../helpers'
|
|
7
7
|
|
|
8
8
|
vi.mock('svelte', () => ({
|
|
9
9
|
mount: vi.fn(),
|
|
@@ -31,98 +31,102 @@ describe('linkInjection.js', () => {
|
|
|
31
31
|
|
|
32
32
|
describe('injectLinksInDocument', () => {
|
|
33
33
|
it('Should replace given words with injections', () => {
|
|
34
|
-
|
|
34
|
+
const injection = generateInjection('This is a sentence with an injection.', 'an injection')
|
|
35
|
+
const linkInjections = [injection]
|
|
35
36
|
|
|
36
|
-
|
|
37
|
+
document.body.innerHTML = `<p>${injection.sentence}</p>`
|
|
37
38
|
|
|
38
|
-
const
|
|
39
|
-
sid: '1',
|
|
40
|
-
title: 'an injection',
|
|
41
|
-
sentence: 'This is a sentence with an injection.',
|
|
42
|
-
playpilot_url: 'https://some-link.com/',
|
|
43
|
-
poster: 'some-poster',
|
|
44
|
-
key: 'some-key',
|
|
45
|
-
}]
|
|
39
|
+
const elements = Array.from(document.querySelectorAll('p'))
|
|
46
40
|
|
|
47
|
-
injectLinksInDocument(elements,
|
|
41
|
+
injectLinksInDocument(elements, () => null, { aiInjections: linkInjections, manualInjections: [] })
|
|
48
42
|
|
|
49
43
|
const link = /** @type {HTMLAnchorElement} */ (document.querySelector('a'))
|
|
50
44
|
|
|
51
|
-
expect(link.innerText).toBe(
|
|
52
|
-
expect(link.href).toBe(
|
|
45
|
+
expect(link.innerText).toBe(injection.title)
|
|
46
|
+
expect(link.href).toBe(injection.playpilot_url)
|
|
53
47
|
})
|
|
54
48
|
|
|
55
49
|
it('Should replace given words as expected when more than 1 injection per sentence is present', () => {
|
|
56
|
-
|
|
50
|
+
const sentence = 'This is a sentence with an injection.'
|
|
51
|
+
const linkInjections = [
|
|
52
|
+
generateInjection(sentence, 'a sentence'),
|
|
53
|
+
generateInjection(sentence, 'an injection'),
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
document.body.innerHTML = `<p>${sentence}</p>`
|
|
57
57
|
|
|
58
58
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
sid: '1',
|
|
62
|
-
title: 'a sentence',
|
|
63
|
-
sentence: 'This is a sentence with an injection.',
|
|
64
|
-
playpilot_url: 'https://some-link.com/',
|
|
65
|
-
poster: 'some-poster',
|
|
66
|
-
key: 'some-key-1',
|
|
67
|
-
title_details: title,
|
|
68
|
-
}, {
|
|
69
|
-
sid: '2',
|
|
70
|
-
title: 'an injection',
|
|
71
|
-
sentence: 'This is a sentence with an injection.',
|
|
72
|
-
playpilot_url: 'https://some-link.com/',
|
|
73
|
-
poster: 'some-poster',
|
|
74
|
-
key: 'some-key-1',
|
|
75
|
-
title_details: title,
|
|
76
|
-
}]
|
|
77
|
-
|
|
78
|
-
injectLinksInDocument(elements, linkInjections, () => null)
|
|
60
|
+
injectLinksInDocument(elements, () => null, { aiInjections: linkInjections, manualInjections: [] })
|
|
79
61
|
|
|
80
62
|
const links = /** @type {HTMLAnchorElement[]} */ (Array.from(document.querySelectorAll('a')))
|
|
81
63
|
|
|
82
|
-
expect(links[0].innerText).toBe(
|
|
83
|
-
expect(links[0].href).toBe(
|
|
84
|
-
|
|
64
|
+
expect(links[0].innerText).toBe(linkInjections[0].title)
|
|
65
|
+
expect(links[0].href).toBe(linkInjections[0].playpilot_url)
|
|
66
|
+
/** @ts-ignore It is defined */
|
|
67
|
+
expect(links[0].dataset.playpilotOriginalTitle).toBe(linkInjections[0].title_details.original_title)
|
|
85
68
|
|
|
86
|
-
expect(links[1].innerText).toBe(
|
|
87
|
-
expect(links[1].href).toBe(
|
|
88
|
-
|
|
69
|
+
expect(links[1].innerText).toBe(linkInjections[1].title)
|
|
70
|
+
expect(links[1].href).toBe(linkInjections[1].playpilot_url)
|
|
71
|
+
/** @ts-ignore It is defined */
|
|
72
|
+
expect(links[1].dataset.playpilotOriginalTitle).toBe(linkInjections[1].title_details.original_title)
|
|
89
73
|
})
|
|
90
74
|
|
|
91
75
|
it('Should ignore injections that are marked as inactive', () => {
|
|
92
|
-
|
|
76
|
+
const sentence = 'This is a sentence with an injection.'
|
|
77
|
+
const injection = generateInjection(sentence, 'an injection')
|
|
78
|
+
const linkInjections = [{ ...injection, inactive: true }]
|
|
79
|
+
|
|
80
|
+
document.body.innerHTML = `<p>${sentence}</p>`
|
|
93
81
|
|
|
94
82
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
95
83
|
|
|
96
|
-
|
|
97
|
-
sid: '1',
|
|
98
|
-
title: 'an injection',
|
|
99
|
-
sentence: 'This is a sentence with an injection.',
|
|
100
|
-
playpilot_url: '',
|
|
101
|
-
poster: 'some-poster',
|
|
102
|
-
key: 'some-key',
|
|
103
|
-
inactive: true,
|
|
104
|
-
}]
|
|
84
|
+
injectLinksInDocument(elements, () => null, { aiInjections: linkInjections, manualInjections: [] })
|
|
105
85
|
|
|
106
|
-
|
|
86
|
+
expect(document.body.innerHTML).toBe(`<p>${sentence}</p>`)
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
it('Should ignore injections that are marked as removed', () => {
|
|
90
|
+
const sentence = 'This is a sentence with an injection.'
|
|
91
|
+
const injection = generateInjection(sentence, 'an injection')
|
|
92
|
+
const linkInjections = [{ ...injection, removed: true }]
|
|
107
93
|
|
|
108
|
-
|
|
94
|
+
document.body.innerHTML = `<p>${sentence}</p>`
|
|
95
|
+
|
|
96
|
+
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
97
|
+
|
|
98
|
+
injectLinksInDocument(elements, () => null, { aiInjections: linkInjections, manualInjections: [] })
|
|
99
|
+
|
|
100
|
+
expect(document.body.innerHTML).toBe(`<p>${sentence}</p>`)
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
it('Should ignore AI injections that are marked as removed as a matching manual injections', () => {
|
|
104
|
+
const sentence = 'This is a sentence with an injection.'
|
|
105
|
+
const injection = generateInjection(sentence, 'an injection')
|
|
106
|
+
|
|
107
|
+
document.body.innerHTML = `<p>${sentence}</p>`
|
|
108
|
+
|
|
109
|
+
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
110
|
+
|
|
111
|
+
const injections = {
|
|
112
|
+
aiInjections: [injection],
|
|
113
|
+
manualInjections: [{ ...injection, manual: true, removed: true }],
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
injectLinksInDocument(elements, () => null, injections)
|
|
117
|
+
|
|
118
|
+
expect(document.body.innerHTML).toBe(`<p>${sentence}</p>`)
|
|
109
119
|
})
|
|
110
120
|
|
|
111
121
|
it('Should keep existing HTML elements intact', () => {
|
|
122
|
+
const injection = generateInjection('This is a sentence with an injection.', 'an injection')
|
|
123
|
+
const linkInjections = [injection]
|
|
124
|
+
|
|
112
125
|
document.body.innerHTML = '<p>This is a <button>sentence</button> with an injection.</p>'
|
|
113
126
|
|
|
114
127
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
115
128
|
|
|
116
|
-
|
|
117
|
-
sid: '1',
|
|
118
|
-
title: 'an injection',
|
|
119
|
-
sentence: 'This is a sentence with an injection.',
|
|
120
|
-
playpilot_url: '',
|
|
121
|
-
poster: 'some-poster',
|
|
122
|
-
key: 'some-key',
|
|
123
|
-
}]
|
|
124
|
-
|
|
125
|
-
injectLinksInDocument(elements, linkInjections, () => null)
|
|
129
|
+
injectLinksInDocument(elements, () => null, { aiInjections: linkInjections, manualInjections: [] })
|
|
126
130
|
|
|
127
131
|
const button = /** @type {HTMLButtonElement} */ (document.querySelector('button'))
|
|
128
132
|
|
|
@@ -133,56 +137,43 @@ describe('linkInjection.js', () => {
|
|
|
133
137
|
document.body.innerHTML = '<h1>I am a title</h1><p>This is a sentence with an injection.</p>'
|
|
134
138
|
|
|
135
139
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
140
|
+
const injection = generateInjection('I am a title', 'a title')
|
|
136
141
|
|
|
137
|
-
|
|
138
|
-
sid: '1',
|
|
139
|
-
title: 'a title',
|
|
140
|
-
sentence: 'I am a title',
|
|
141
|
-
playpilot_url: '',
|
|
142
|
-
poster: 'some-poster',
|
|
143
|
-
key: 'some-key',
|
|
144
|
-
}]
|
|
142
|
+
injectLinksInDocument(elements, () => null, { aiInjections: [injection], manualInjections: [] })
|
|
145
143
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
expect(document.body.innerHTML.includes('I am a title')).toBeTruthy()
|
|
144
|
+
expect(document.body.innerHTML.includes(injection.sentence)).toBeTruthy()
|
|
149
145
|
})
|
|
150
146
|
|
|
151
147
|
it('Should ignore partial matches due to interfering elements', () => {
|
|
152
148
|
document.body.innerHTML = '<p>This is a sentence with <strong>an</strong> injection.</p>'
|
|
153
149
|
|
|
154
150
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
151
|
+
const injection = generateInjection('This is a sentence with an injection.', 'an injection')
|
|
155
152
|
|
|
156
|
-
|
|
157
|
-
sid: '1',
|
|
158
|
-
title: 'an injection',
|
|
159
|
-
sentence: 'This is a sentence with an injection.',
|
|
160
|
-
playpilot_url: '',
|
|
161
|
-
poster: 'some-poster',
|
|
162
|
-
key: 'some-key',
|
|
163
|
-
}]
|
|
164
|
-
|
|
165
|
-
injectLinksInDocument(elements, linkInjections, () => null)
|
|
153
|
+
injectLinksInDocument(elements, () => null, { aiInjections: [injection], manualInjections: [] })
|
|
166
154
|
|
|
167
155
|
expect(document.body.innerHTML.includes('an injection')).not.toBeTruthy()
|
|
168
156
|
expect(document.body.innerHTML.includes('an')).toBeTruthy()
|
|
169
157
|
})
|
|
170
158
|
|
|
159
|
+
it('Should ignore encoded characters in given sentences', () => {
|
|
160
|
+
document.body.innerHTML = '<p>This is a sentence & an injection.</p>'
|
|
161
|
+
|
|
162
|
+
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
163
|
+
const injection = generateInjection('This is a sentence & an injection.', 'an injection')
|
|
164
|
+
|
|
165
|
+
injectLinksInDocument(elements, () => null, { aiInjections: [injection], manualInjections: [] })
|
|
166
|
+
|
|
167
|
+
expect(document.querySelectorAll('a')).toHaveLength(1)
|
|
168
|
+
})
|
|
169
|
+
|
|
171
170
|
it('Should ignore matches due to parent links', () => {
|
|
172
171
|
document.body.innerHTML = '<p>This is <a>a sentence</a> with an injection.</p>'
|
|
173
172
|
|
|
174
173
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
174
|
+
const injection = generateInjection('This is a sentence with an injection.', 'a sentence')
|
|
175
175
|
|
|
176
|
-
|
|
177
|
-
sid: '1',
|
|
178
|
-
title: 'a sentence',
|
|
179
|
-
sentence: 'This is a sentence with an injection.',
|
|
180
|
-
playpilot_url: 'https://some-link.com/',
|
|
181
|
-
poster: 'some-poster',
|
|
182
|
-
key: 'some-key-1',
|
|
183
|
-
}]
|
|
184
|
-
|
|
185
|
-
injectLinksInDocument(elements, linkInjections, () => null)
|
|
176
|
+
injectLinksInDocument(elements, () => null, { aiInjections: [injection], manualInjections: [] })
|
|
186
177
|
|
|
187
178
|
expect(document.querySelector('[data-playpilot-injection-key]')).not.toBeTruthy()
|
|
188
179
|
})
|
|
@@ -191,17 +182,9 @@ describe('linkInjection.js', () => {
|
|
|
191
182
|
document.body.innerHTML = '<p>This is <a data-thing="some word">a sentence</a> with an injection.</p>'
|
|
192
183
|
|
|
193
184
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
185
|
+
const injection = generateInjection('This is a sentence with an injection.', 'some word')
|
|
194
186
|
|
|
195
|
-
|
|
196
|
-
sid: '1',
|
|
197
|
-
title: 'some word',
|
|
198
|
-
sentence: 'This is a sentence with an injection.',
|
|
199
|
-
playpilot_url: 'https://some-link.com/',
|
|
200
|
-
poster: 'some-poster',
|
|
201
|
-
key: 'some-key-1',
|
|
202
|
-
}]
|
|
203
|
-
|
|
204
|
-
injectLinksInDocument(elements, linkInjections, () => null)
|
|
187
|
+
injectLinksInDocument(elements, () => null, { aiInjections: [injection], manualInjections: [] })
|
|
205
188
|
|
|
206
189
|
expect(document.querySelector('[data-playpilot-injection-key]')).not.toBeTruthy()
|
|
207
190
|
})
|
|
@@ -210,17 +193,9 @@ describe('linkInjection.js', () => {
|
|
|
210
193
|
document.body.innerHTML = '<p>This is <a>a word</a> with a word.</p>'
|
|
211
194
|
|
|
212
195
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
196
|
+
const injection = generateInjection('This is a word with a word.', 'a word')
|
|
213
197
|
|
|
214
|
-
|
|
215
|
-
sid: '1',
|
|
216
|
-
title: 'a word',
|
|
217
|
-
sentence: 'This is a word with a word.',
|
|
218
|
-
playpilot_url: 'https://some-link.com/',
|
|
219
|
-
poster: 'some-poster',
|
|
220
|
-
key: 'some-key-1',
|
|
221
|
-
}]
|
|
222
|
-
|
|
223
|
-
injectLinksInDocument(elements, linkInjections, () => null)
|
|
198
|
+
injectLinksInDocument(elements, () => null, { aiInjections: [injection], manualInjections: [] })
|
|
224
199
|
|
|
225
200
|
expect(document.querySelectorAll('a')).toHaveLength(2)
|
|
226
201
|
})
|
|
@@ -229,17 +204,9 @@ describe('linkInjection.js', () => {
|
|
|
229
204
|
document.body.innerHTML = '<p>This is <a>a sentence</a> with an injection.</p>'
|
|
230
205
|
|
|
231
206
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
207
|
+
const injection = generateInjection('This is a sentence with an injection.', 'an injection')
|
|
232
208
|
|
|
233
|
-
|
|
234
|
-
sid: '1',
|
|
235
|
-
title: 'an injection',
|
|
236
|
-
sentence: 'This is a sentence with an injection.',
|
|
237
|
-
playpilot_url: 'https://some-link.com/',
|
|
238
|
-
poster: 'some-poster',
|
|
239
|
-
key: 'some-key-1',
|
|
240
|
-
}]
|
|
241
|
-
|
|
242
|
-
injectLinksInDocument(elements, linkInjections, () => null)
|
|
209
|
+
injectLinksInDocument(elements, () => null, { aiInjections: [injection], manualInjections: [] })
|
|
243
210
|
|
|
244
211
|
expect(document.querySelector('[data-playpilot-injection-key]')).toBeTruthy()
|
|
245
212
|
})
|
|
@@ -252,7 +219,7 @@ describe('linkInjection.js', () => {
|
|
|
252
219
|
/** @type {LinkInjection[]} */
|
|
253
220
|
const linkInjections = []
|
|
254
221
|
|
|
255
|
-
injectLinksInDocument(elements,
|
|
222
|
+
injectLinksInDocument(elements, () => null, { aiInjections: linkInjections, manualInjections: [] })
|
|
256
223
|
|
|
257
224
|
expect(document.body.innerHTML.includes('This is a sentence with an injection.')).toBeTruthy()
|
|
258
225
|
})
|
|
@@ -264,55 +231,37 @@ describe('linkInjection.js', () => {
|
|
|
264
231
|
/** @type {LinkInjection[]} */
|
|
265
232
|
const linkInjections = []
|
|
266
233
|
|
|
267
|
-
expect(() => injectLinksInDocument(elements,
|
|
234
|
+
expect(() => injectLinksInDocument(elements, () => null, { aiInjections: linkInjections, manualInjections: [] })).not.toThrow()
|
|
268
235
|
})
|
|
269
236
|
|
|
270
237
|
it('Should fire given onclick function when clicked', async () => {
|
|
271
238
|
document.body.innerHTML = '<p>This is a sentence with an injection.</p>'
|
|
272
239
|
|
|
273
240
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
274
|
-
|
|
275
|
-
const linkInjections = [{
|
|
276
|
-
sid: '1',
|
|
277
|
-
title: 'an injection',
|
|
278
|
-
sentence: 'This is a sentence with an injection.',
|
|
279
|
-
playpilot_url: 'https://some-link.com/',
|
|
280
|
-
poster: 'some-poster',
|
|
281
|
-
key: 'some-key',
|
|
282
|
-
}]
|
|
241
|
+
const injection = generateInjection('This is a sentence with an injection.', 'an injection')
|
|
283
242
|
|
|
284
243
|
const mock = vi.fn()
|
|
285
|
-
injectLinksInDocument(elements,
|
|
244
|
+
injectLinksInDocument(elements, mock, { aiInjections: [injection], manualInjections: [] })
|
|
286
245
|
|
|
287
246
|
const link = /** @type {HTMLAnchorElement} */ (document.querySelector('a'))
|
|
288
247
|
await fireEvent.click(link)
|
|
289
248
|
|
|
290
|
-
expect(mock).toHaveBeenCalledWith(
|
|
249
|
+
expect(mock).toHaveBeenCalledWith(injection)
|
|
291
250
|
})
|
|
292
251
|
|
|
293
252
|
it('Should fire given onclick function when clicked for each link in a sentence if more than 1 injection is present', async () => {
|
|
294
|
-
|
|
253
|
+
const sentence = 'This is a sentence with an injection.'
|
|
254
|
+
document.body.innerHTML = `<p>${sentence}</p>`
|
|
295
255
|
|
|
296
256
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
297
257
|
|
|
298
|
-
const linkInjections = [
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
playpilot_url: 'https://some-link.com/',
|
|
303
|
-
poster: 'some-poster',
|
|
304
|
-
key: 'some-key-1',
|
|
305
|
-
}, {
|
|
306
|
-
sid: '2',
|
|
307
|
-
title: 'an injection',
|
|
308
|
-
sentence: 'This is a sentence with an injection.',
|
|
309
|
-
playpilot_url: 'https://some-link.com/',
|
|
310
|
-
poster: 'some-poster',
|
|
311
|
-
key: 'some-key-2',
|
|
312
|
-
}]
|
|
258
|
+
const linkInjections = [
|
|
259
|
+
generateInjection(sentence, 'a sentence'),
|
|
260
|
+
generateInjection(sentence, 'an injection'),
|
|
261
|
+
]
|
|
313
262
|
|
|
314
263
|
const mock = vi.fn()
|
|
315
|
-
injectLinksInDocument(elements, linkInjections,
|
|
264
|
+
injectLinksInDocument(elements, mock, { aiInjections: linkInjections, manualInjections: [] })
|
|
316
265
|
|
|
317
266
|
const links = document.querySelectorAll('a')
|
|
318
267
|
await fireEvent.click(links[0])
|
|
@@ -325,18 +274,10 @@ describe('linkInjection.js', () => {
|
|
|
325
274
|
document.body.innerHTML = '<p>This is a sentence with an injection.</p>'
|
|
326
275
|
|
|
327
276
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
328
|
-
|
|
329
|
-
const linkInjections = [{
|
|
330
|
-
sid: '1',
|
|
331
|
-
title: 'an injection',
|
|
332
|
-
sentence: 'This is a sentence with an injection.',
|
|
333
|
-
playpilot_url: 'https://some-link.com/',
|
|
334
|
-
poster: 'some-poster',
|
|
335
|
-
key: 'some-key',
|
|
336
|
-
}]
|
|
277
|
+
const injection = generateInjection('This is a sentence with an injection.', 'an injection')
|
|
337
278
|
|
|
338
279
|
const mock = vi.fn()
|
|
339
|
-
injectLinksInDocument(elements,
|
|
280
|
+
injectLinksInDocument(elements, mock, { aiInjections: [injection], manualInjections: [] })
|
|
340
281
|
|
|
341
282
|
const link = /** @type {HTMLAnchorElement} */ (document.querySelector('a'))
|
|
342
283
|
|
|
@@ -349,48 +290,30 @@ describe('linkInjection.js', () => {
|
|
|
349
290
|
})
|
|
350
291
|
|
|
351
292
|
it('Should return array with failed injections marked as such', () => {
|
|
352
|
-
|
|
293
|
+
const sentence = 'This is a sentence with an injection.'
|
|
294
|
+
document.body.innerHTML = `<p>${sentence}</p>`
|
|
353
295
|
|
|
354
296
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
355
297
|
|
|
356
|
-
const linkInjections = [
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
key: 'some-key-1',
|
|
363
|
-
}, {
|
|
364
|
-
sid: '2',
|
|
365
|
-
title: 'not an injection',
|
|
366
|
-
sentence: 'This is a sentence with an injection.',
|
|
367
|
-
playpilot_url: 'https://some-link.com/',
|
|
368
|
-
poster: 'some-poster',
|
|
369
|
-
key: 'some-key-2',
|
|
370
|
-
}]
|
|
371
|
-
|
|
372
|
-
const results = injectLinksInDocument(elements, linkInjections, () => null)
|
|
298
|
+
const linkInjections = [
|
|
299
|
+
generateInjection(sentence, 'a sentence'),
|
|
300
|
+
generateInjection(sentence, 'not an injection'),
|
|
301
|
+
]
|
|
302
|
+
|
|
303
|
+
const results = injectLinksInDocument(elements, () => null, { aiInjections: linkInjections, manualInjections: [] })
|
|
373
304
|
|
|
374
|
-
expect(results[1].failed).toBe(true)
|
|
375
305
|
expect(results[0].failed).toBe(false)
|
|
306
|
+
expect(results[1].failed).toBe(true)
|
|
376
307
|
})
|
|
377
308
|
|
|
378
309
|
it('Should mount popover component when link is hovered and unmount when link is blurred', async () => {
|
|
379
310
|
document.body.innerHTML = '<p>This is a sentence with an injection.</p>'
|
|
380
311
|
|
|
381
312
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
382
|
-
|
|
383
|
-
const linkInjections = [{
|
|
384
|
-
sid: '1',
|
|
385
|
-
title: 'an injection',
|
|
386
|
-
sentence: 'This is a sentence with an injection.',
|
|
387
|
-
playpilot_url: 'https://some-link.com/',
|
|
388
|
-
poster: 'some-poster',
|
|
389
|
-
key: 'some-key',
|
|
390
|
-
}]
|
|
313
|
+
const injection = generateInjection('This is a sentence with an injection.', 'an injection')
|
|
391
314
|
|
|
392
315
|
const mock = vi.fn()
|
|
393
|
-
injectLinksInDocument(elements,
|
|
316
|
+
injectLinksInDocument(elements, mock, { aiInjections: [injection], manualInjections: [] })
|
|
394
317
|
|
|
395
318
|
const link = /** @type {HTMLAnchorElement} */ (document.querySelector('[data-playpilot-injection-key]'))
|
|
396
319
|
|
|
@@ -406,75 +329,66 @@ describe('linkInjection.js', () => {
|
|
|
406
329
|
|
|
407
330
|
const elements = Array.from(document.querySelectorAll('p'))
|
|
408
331
|
|
|
409
|
-
const
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
sentence
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
}, {
|
|
417
|
-
sid: '2',
|
|
418
|
-
title: 'injection',
|
|
419
|
-
sentence: 'This is a sentence with an injection and another injection',
|
|
420
|
-
playpilot_url: 'https://some-link-2.com/',
|
|
421
|
-
poster: 'some-poster',
|
|
422
|
-
key: 'some-key-2',
|
|
423
|
-
}]
|
|
424
|
-
|
|
425
|
-
injectLinksInDocument(elements, linkInjections, () => null)
|
|
332
|
+
const sentence = 'This is a sentence with an injection and another injection'
|
|
333
|
+
const linkInjections = [
|
|
334
|
+
generateInjection(sentence, 'injection'),
|
|
335
|
+
generateInjection(sentence, 'injection'),
|
|
336
|
+
]
|
|
337
|
+
|
|
338
|
+
injectLinksInDocument(elements, () => null, { aiInjections: linkInjections, manualInjections: [] })
|
|
426
339
|
|
|
427
340
|
const links = /** @type {HTMLAnchorElement[]} */ (Array.from(document.querySelectorAll('[data-playpilot-injection-key]')))
|
|
428
341
|
|
|
429
342
|
expect(links).toHaveLength(2)
|
|
430
|
-
expect(links[0].dataset.playpilotInjectionKey).toBe(
|
|
431
|
-
expect(links[1].dataset.playpilotInjectionKey).toBe(
|
|
343
|
+
expect(links[0].dataset.playpilotInjectionKey).toBe(linkInjections[0].key)
|
|
344
|
+
expect(links[1].dataset.playpilotInjectionKey).toBe(linkInjections[1].key)
|
|
432
345
|
})
|
|
433
346
|
|
|
434
347
|
it('Should not inject injections with in_text set to false', () => {
|
|
435
348
|
document.body.innerHTML = '<p>This is a sentence with an injection.</p>'
|
|
436
349
|
|
|
437
350
|
const elements = Array.from(document.querySelectorAll('p'))
|
|
351
|
+
const injection = { ...generateInjection('This is a sentence with an injection.', 'an injection'), in_text: false }
|
|
438
352
|
|
|
439
|
-
|
|
440
|
-
sid: '1',
|
|
441
|
-
title: 'an injection',
|
|
442
|
-
sentence: 'This is a sentence with an injection.',
|
|
443
|
-
playpilot_url: 'https://some-link.com/',
|
|
444
|
-
poster: 'some-poster',
|
|
445
|
-
key: 'some-key',
|
|
446
|
-
in_text: false,
|
|
447
|
-
}]
|
|
448
|
-
|
|
449
|
-
injectLinksInDocument(elements, linkInjections, () => null)
|
|
353
|
+
injectLinksInDocument(elements, () => null, { aiInjections: [injection], manualInjections: [] })
|
|
450
354
|
|
|
451
355
|
expect(document.querySelector('a')).not.toBeTruthy()
|
|
452
356
|
})
|
|
453
|
-
})
|
|
454
357
|
|
|
455
|
-
|
|
456
|
-
|
|
358
|
+
it('Should not mount popover if user uses touch', async () => {
|
|
359
|
+
mockMatchMedia(true)
|
|
457
360
|
|
|
458
|
-
|
|
361
|
+
document.body.innerHTML = '<p>This is a sentence with an injection.</p>'
|
|
362
|
+
|
|
363
|
+
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
364
|
+
const injection = generateInjection('This is a sentence with an injection.', 'an injection')
|
|
365
|
+
|
|
366
|
+
const mock = vi.fn()
|
|
367
|
+
injectLinksInDocument(elements, mock, { aiInjections: [injection], manualInjections: [] })
|
|
368
|
+
|
|
369
|
+
const link = /** @type {HTMLAnchorElement} */ (document.querySelector('a'))
|
|
459
370
|
|
|
460
|
-
|
|
371
|
+
await fireEvent.mouseEnter(link)
|
|
372
|
+
expect(mount).not.toHaveBeenCalled()
|
|
373
|
+
})
|
|
461
374
|
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
key: 'some-key',
|
|
469
|
-
}]
|
|
375
|
+
it('Should not call insertAfterArticlePlaylinks if injections only contain inactive or removed items', () => {
|
|
376
|
+
document.body.innerHTML = `<section>
|
|
377
|
+
<div>Some text</div>
|
|
378
|
+
<div>Some other text</div>
|
|
379
|
+
</section>
|
|
380
|
+
`
|
|
470
381
|
|
|
471
|
-
|
|
472
|
-
|
|
382
|
+
const elements = Array.from(document.body.querySelectorAll('div'))
|
|
383
|
+
const injection = generateInjection('Some sentence', 'an injection')
|
|
384
|
+
const linkInjections = [{ ...injection, after_article: true, inactive: true }, { ...injection, after_article: true, removed: true }]
|
|
473
385
|
|
|
474
|
-
|
|
386
|
+
const mock = vi.fn()
|
|
387
|
+
injectLinksInDocument(elements, mock, { aiInjections: [], manualInjections: linkInjections })
|
|
475
388
|
|
|
476
|
-
|
|
477
|
-
|
|
389
|
+
expect(mount).not.toHaveBeenCalled()
|
|
390
|
+
expect(document.querySelector('[data-playpilot-after-article-playlinks]')).not.toBeTruthy()
|
|
391
|
+
})
|
|
478
392
|
})
|
|
479
393
|
|
|
480
394
|
describe('clearLinkInjections', () => {
|
|
@@ -679,17 +593,10 @@ describe('linkInjection.js', () => {
|
|
|
679
593
|
</section>
|
|
680
594
|
`
|
|
681
595
|
|
|
682
|
-
const
|
|
683
|
-
sid: '1',
|
|
684
|
-
title: 'an injection',
|
|
685
|
-
sentence: 'This is a sentence with an injection.',
|
|
686
|
-
playpilot_url: 'https://some-link.com/',
|
|
687
|
-
poster: 'some-poster',
|
|
688
|
-
key: 'some-key',
|
|
689
|
-
}]
|
|
596
|
+
const injection = generateInjection('This is a sentence with an injection.', 'an injection')
|
|
690
597
|
|
|
691
598
|
const elements = getLinkInjectionElements(document.body)
|
|
692
|
-
insertAfterArticlePlaylinks(elements,
|
|
599
|
+
insertAfterArticlePlaylinks(elements, [injection], () => null)
|
|
693
600
|
|
|
694
601
|
expect(mount).toHaveBeenCalled()
|
|
695
602
|
expect(document.querySelector('[data-playpilot-after-article-playlinks]')).toBeTruthy()
|
|
@@ -754,4 +661,106 @@ describe('linkInjection.js', () => {
|
|
|
754
661
|
expect(sortedInjections[2].key).toBe('a')
|
|
755
662
|
})
|
|
756
663
|
})
|
|
664
|
+
|
|
665
|
+
describe('isAvailableAsManualInjection', () => {
|
|
666
|
+
it('Should return true if the ai injection has a matching manual injection', () => {
|
|
667
|
+
const aiInjection = generateInjection('Some sentence', 'Some title')
|
|
668
|
+
const manualInjection = { ...aiInjection, manual: true }
|
|
669
|
+
|
|
670
|
+
expect(isAvailableAsManualInjection(aiInjection, 0, [aiInjection, manualInjection]))
|
|
671
|
+
})
|
|
672
|
+
|
|
673
|
+
it('Should return false if the ai injection has no matching manual injection', () => {
|
|
674
|
+
const aiInjection = generateInjection('Some sentence', 'Some title')
|
|
675
|
+
|
|
676
|
+
expect(isAvailableAsManualInjection(aiInjection, 0, [aiInjection]))
|
|
677
|
+
})
|
|
678
|
+
|
|
679
|
+
it('Should return false if the ai injection has a matching ai injection', () => {
|
|
680
|
+
const aiInjection = generateInjection('Some sentence', 'Some title')
|
|
681
|
+
|
|
682
|
+
expect(isAvailableAsManualInjection(aiInjection, 0, [aiInjection, aiInjection]))
|
|
683
|
+
})
|
|
684
|
+
})
|
|
685
|
+
|
|
686
|
+
describe('filterRemovedInjections', () => {
|
|
687
|
+
it('Should not return injections that are removed or have an removed manual equivalent', () => {
|
|
688
|
+
const aiInjection = generateInjection('Some sentence', 'Some title')
|
|
689
|
+
const manualInjection = { ...aiInjection, manual: true, removed: true }
|
|
690
|
+
|
|
691
|
+
expect(filterRemovedInjections([aiInjection, manualInjection])).toEqual([])
|
|
692
|
+
})
|
|
693
|
+
|
|
694
|
+
it('Should return ai injections that have no matching manual injection', () => {
|
|
695
|
+
const aiInjection = generateInjection('Some sentence', 'Some title')
|
|
696
|
+
const manualInjection = { ...generateInjection('Some other sentence', 'Some other title'), manual: true }
|
|
697
|
+
|
|
698
|
+
expect(filterRemovedInjections([aiInjection, manualInjection])).toEqual([aiInjection, manualInjection])
|
|
699
|
+
})
|
|
700
|
+
|
|
701
|
+
it('Should return manual injections that have been removed at one point, but a new injection for the same title was created', () => {
|
|
702
|
+
const manualInjection = { ...generateInjection('Some other sentence', 'Some other title'), manual: true }
|
|
703
|
+
const removedManualInjection = { ...manualInjection, removed: true }
|
|
704
|
+
|
|
705
|
+
expect(filterRemovedInjections([manualInjection, removedManualInjection])).toEqual([manualInjection])
|
|
706
|
+
})
|
|
707
|
+
})
|
|
708
|
+
|
|
709
|
+
describe('isEquivalentInjection', () => {
|
|
710
|
+
it('Should return true if injections have the same title and sentence', () => {
|
|
711
|
+
expect(isEquivalentInjection(generateInjection('a', 'b'), generateInjection('a', 'b'))).toBe(true)
|
|
712
|
+
})
|
|
713
|
+
|
|
714
|
+
it('Should return false if injections have different titles', () => {
|
|
715
|
+
expect(isEquivalentInjection(generateInjection('a', 'b'), generateInjection('a', 'c'))).toBe(false)
|
|
716
|
+
})
|
|
717
|
+
|
|
718
|
+
it('Should return false if injections have different sentences', () => {
|
|
719
|
+
expect(isEquivalentInjection(generateInjection('a', 'b'), generateInjection('b', 'b'))).toBe(false)
|
|
720
|
+
})
|
|
721
|
+
|
|
722
|
+
it('Should return false if injections have both different titles and sentences', () => {
|
|
723
|
+
expect(isEquivalentInjection(generateInjection('a', 'b'), generateInjection('c', 'd'))).toBe(false)
|
|
724
|
+
})
|
|
725
|
+
})
|
|
726
|
+
|
|
727
|
+
describe('isValidInjection', () => {
|
|
728
|
+
it('Should only return true when the injection is valid', () => {
|
|
729
|
+
expect(isValidInjection({ ...generateInjection('a', 'b') })).toBe(true)
|
|
730
|
+
expect(isValidInjection({ ...generateInjection('a', 'b'), inactive: true })).toBe(false)
|
|
731
|
+
expect(isValidInjection({ ...generateInjection('a', 'b'), removed: true })).toBe(false)
|
|
732
|
+
expect(isValidInjection({ ...generateInjection('a', 'b'), duplicate: true })).toBe(false)
|
|
733
|
+
expect(isValidInjection({ ...generateInjection('a', 'b'), title_details: undefined })).toBe(false)
|
|
734
|
+
})
|
|
735
|
+
})
|
|
736
|
+
|
|
737
|
+
describe('filterInvalidInTextInjections', () => {
|
|
738
|
+
it('Should return injections that are valid', () => {
|
|
739
|
+
expect(filterInvalidInTextInjections([generateInjection('a', 'b')])).toHaveLength(1)
|
|
740
|
+
})
|
|
741
|
+
|
|
742
|
+
it('Should return not injections that inactive, removed, duplicate, have no title_details, or are not in_text', () => {
|
|
743
|
+
expect(filterInvalidInTextInjections([{ ...generateInjection('a', 'b'), inactive: true }])).toHaveLength(0)
|
|
744
|
+
expect(filterInvalidInTextInjections([{ ...generateInjection('a', 'b'), removed: true }])).toHaveLength(0)
|
|
745
|
+
expect(filterInvalidInTextInjections([{ ...generateInjection('a', 'b'), duplicate: true }])).toHaveLength(0)
|
|
746
|
+
expect(filterInvalidInTextInjections([{ ...generateInjection('a', 'b'), title_details: undefined }])).toHaveLength(0)
|
|
747
|
+
expect(filterInvalidInTextInjections([{ ...generateInjection('a', 'b'), in_text: false }])).toHaveLength(0)
|
|
748
|
+
|
|
749
|
+
expect(filterInvalidInTextInjections([{ ...generateInjection('a', 'b'), in_text: undefined }])).toHaveLength(1)
|
|
750
|
+
expect(filterInvalidInTextInjections([{ ...generateInjection('a', 'b'), in_text: true }])).toHaveLength(1)
|
|
751
|
+
})
|
|
752
|
+
})
|
|
753
|
+
|
|
754
|
+
describe('filterInvalidAfterArticleInjections', () => {
|
|
755
|
+
it('Should return not injections that inactive, removed, duplicate, have no title_details, or are not after_article', () => {
|
|
756
|
+
expect(filterInvalidAfterArticleInjections([{ ...generateInjection('a', 'b'), inactive: true }])).toHaveLength(0)
|
|
757
|
+
expect(filterInvalidAfterArticleInjections([{ ...generateInjection('a', 'b'), removed: true }])).toHaveLength(0)
|
|
758
|
+
expect(filterInvalidAfterArticleInjections([{ ...generateInjection('a', 'b'), duplicate: true }])).toHaveLength(0)
|
|
759
|
+
expect(filterInvalidAfterArticleInjections([{ ...generateInjection('a', 'b'), title_details: undefined }])).toHaveLength(0)
|
|
760
|
+
expect(filterInvalidAfterArticleInjections([{ ...generateInjection('a', 'b'), after_article: false }])).toHaveLength(0)
|
|
761
|
+
expect(filterInvalidAfterArticleInjections([{ ...generateInjection('a', 'b'), after_article: undefined }])).toHaveLength(0)
|
|
762
|
+
|
|
763
|
+
expect(filterInvalidAfterArticleInjections([{ ...generateInjection('a', 'b'), after_article: true }])).toHaveLength(1)
|
|
764
|
+
})
|
|
765
|
+
})
|
|
757
766
|
})
|