@playpilot/tpi 3.3.3 → 3.4.0-beta.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/link-injections.js +8 -8
- package/package.json +1 -1
- package/src/lib/api.ts +6 -9
- package/src/lib/hash.ts +4 -0
- package/src/lib/linkInjection.ts +15 -40
- package/src/lib/localization.ts +7 -7
- package/src/lib/scss/_mixins.scss +0 -13
- package/src/lib/scss/global.scss +0 -5
- package/src/lib/scss/variables.scss +1 -1
- package/src/lib/session.ts +78 -0
- package/src/lib/tracking.ts +1 -2
- package/src/lib/types/injection.d.ts +2 -0
- package/src/lib/types/session.d.ts +14 -0
- package/src/routes/+page.svelte +37 -7
- package/src/routes/components/AfterArticlePlaylinks.svelte +6 -5
- package/src/routes/components/Editorial/Editor.svelte +36 -26
- package/src/routes/components/Editorial/Session.svelte +97 -0
- package/src/routes/components/Modal.svelte +1 -3
- package/src/routes/components/Playlinks.svelte +4 -5
- package/src/routes/components/Popover.svelte +1 -3
- package/src/routes/components/Title.svelte +0 -5
- package/src/tests/lib/api.test.js +14 -14
- package/src/tests/lib/linkInjection.test.js +56 -51
- package/src/tests/lib/localization.test.js +0 -7
- package/src/tests/lib/session.test.js +95 -0
- package/src/tests/lib/tracking.test.js +0 -16
- package/src/tests/routes/+page.test.js +14 -4
- package/src/tests/routes/components/Editorial/Editor.test.js +17 -1
- package/src/tests/routes/components/Editorial/EditorItem.test.js +7 -7
- package/src/tests/routes/components/Editorial/Session.test.js +80 -0
- package/src/tests/setup.js +23 -5
- package/src/lib/event.ts +0 -6
- package/src/lib/viewTransition.ts +0 -25
- package/src/tests/lib/event.test.js +0 -22
- package/src/tests/lib/viewTransition.test.js +0 -13
|
@@ -3,7 +3,7 @@ import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest'
|
|
|
3
3
|
|
|
4
4
|
import { injectLinksInDocument, clearLinkInjections, clearLinkInjection, getLinkInjectionElements, insertAfterArticlePlaylinks, getLinkInjectionsParentElement, isAvailableAsManualInjection, filterRemovedAndInactiveInjections, isEquivalentInjection, filterInvalidInTextInjections, filterInvalidAfterArticleInjections, isValidInjection, isValidPlaylinkType } from '$lib/linkInjection'
|
|
5
5
|
import { mount, unmount } from 'svelte'
|
|
6
|
-
import {
|
|
6
|
+
import { generateInjection } from '../helpers'
|
|
7
7
|
|
|
8
8
|
vi.mock('svelte', () => ({
|
|
9
9
|
mount: vi.fn(),
|
|
@@ -23,11 +23,7 @@ function mockMatchMedia(matches = false) {
|
|
|
23
23
|
describe('linkInjection.js', () => {
|
|
24
24
|
beforeEach(() => {
|
|
25
25
|
vi.resetAllMocks()
|
|
26
|
-
clearLinkInjections()
|
|
27
|
-
|
|
28
26
|
mockMatchMedia()
|
|
29
|
-
fakeFetch()
|
|
30
|
-
vi.mocked(mount).mockReturnValueOnce({})
|
|
31
27
|
|
|
32
28
|
// @ts-ignore
|
|
33
29
|
window.PlayPilotLinkInjections = {}
|
|
@@ -46,7 +42,7 @@ describe('linkInjection.js', () => {
|
|
|
46
42
|
|
|
47
43
|
const elements = Array.from(document.querySelectorAll('p'))
|
|
48
44
|
|
|
49
|
-
injectLinksInDocument(elements, { aiInjections: linkInjections, manualInjections: [] })
|
|
45
|
+
injectLinksInDocument(elements, () => null, { aiInjections: linkInjections, manualInjections: [] })
|
|
50
46
|
|
|
51
47
|
const link = /** @type {HTMLAnchorElement} */ (document.querySelector('a'))
|
|
52
48
|
|
|
@@ -65,7 +61,7 @@ describe('linkInjection.js', () => {
|
|
|
65
61
|
|
|
66
62
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
67
63
|
|
|
68
|
-
injectLinksInDocument(elements, { aiInjections: linkInjections, manualInjections: [] })
|
|
64
|
+
injectLinksInDocument(elements, () => null, { aiInjections: linkInjections, manualInjections: [] })
|
|
69
65
|
|
|
70
66
|
const links = /** @type {HTMLAnchorElement[]} */ (Array.from(document.querySelectorAll('a')))
|
|
71
67
|
|
|
@@ -89,7 +85,7 @@ describe('linkInjection.js', () => {
|
|
|
89
85
|
|
|
90
86
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
91
87
|
|
|
92
|
-
injectLinksInDocument(elements, { aiInjections: linkInjections, manualInjections: [] })
|
|
88
|
+
injectLinksInDocument(elements, () => null, { aiInjections: linkInjections, manualInjections: [] })
|
|
93
89
|
|
|
94
90
|
expect(document.body.innerHTML).toBe(`<p>${sentence}</p>`)
|
|
95
91
|
})
|
|
@@ -103,7 +99,7 @@ describe('linkInjection.js', () => {
|
|
|
103
99
|
|
|
104
100
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
105
101
|
|
|
106
|
-
injectLinksInDocument(elements, { aiInjections: linkInjections, manualInjections: [] })
|
|
102
|
+
injectLinksInDocument(elements, () => null, { aiInjections: linkInjections, manualInjections: [] })
|
|
107
103
|
|
|
108
104
|
expect(document.body.innerHTML).toBe(`<p>${sentence}</p>`)
|
|
109
105
|
})
|
|
@@ -121,7 +117,7 @@ describe('linkInjection.js', () => {
|
|
|
121
117
|
manualInjections: [{ ...injection, manual: true, removed: true }],
|
|
122
118
|
}
|
|
123
119
|
|
|
124
|
-
injectLinksInDocument(elements, injections)
|
|
120
|
+
injectLinksInDocument(elements, () => null, injections)
|
|
125
121
|
|
|
126
122
|
expect(document.body.innerHTML).toBe(`<p>${sentence}</p>`)
|
|
127
123
|
})
|
|
@@ -139,7 +135,7 @@ describe('linkInjection.js', () => {
|
|
|
139
135
|
manualInjections: [{ ...injection, manual: true, inactive: true }],
|
|
140
136
|
}
|
|
141
137
|
|
|
142
|
-
injectLinksInDocument(elements, injections)
|
|
138
|
+
injectLinksInDocument(elements, () => null, injections)
|
|
143
139
|
|
|
144
140
|
expect(document.body.innerHTML).toBe(`<p>${sentence}</p>`)
|
|
145
141
|
})
|
|
@@ -152,7 +148,7 @@ describe('linkInjection.js', () => {
|
|
|
152
148
|
|
|
153
149
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
154
150
|
|
|
155
|
-
injectLinksInDocument(elements, { aiInjections: linkInjections, manualInjections: [] })
|
|
151
|
+
injectLinksInDocument(elements, () => null, { aiInjections: linkInjections, manualInjections: [] })
|
|
156
152
|
|
|
157
153
|
const button = /** @type {HTMLButtonElement} */ (document.querySelector('button'))
|
|
158
154
|
|
|
@@ -165,7 +161,7 @@ describe('linkInjection.js', () => {
|
|
|
165
161
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
166
162
|
const injection = generateInjection('I am a title', 'a title')
|
|
167
163
|
|
|
168
|
-
injectLinksInDocument(elements, { aiInjections: [injection], manualInjections: [] })
|
|
164
|
+
injectLinksInDocument(elements, () => null, { aiInjections: [injection], manualInjections: [] })
|
|
169
165
|
|
|
170
166
|
expect(document.body.innerHTML.includes(injection.sentence)).toBeTruthy()
|
|
171
167
|
})
|
|
@@ -176,7 +172,7 @@ describe('linkInjection.js', () => {
|
|
|
176
172
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
177
173
|
const injection = generateInjection('This is a sentence with an injection.', 'an injection')
|
|
178
174
|
|
|
179
|
-
injectLinksInDocument(elements, { aiInjections: [injection], manualInjections: [] })
|
|
175
|
+
injectLinksInDocument(elements, () => null, { aiInjections: [injection], manualInjections: [] })
|
|
180
176
|
|
|
181
177
|
expect(document.body.innerHTML.includes('an injection')).not.toBeTruthy()
|
|
182
178
|
expect(document.body.innerHTML.includes('an')).toBeTruthy()
|
|
@@ -188,7 +184,7 @@ describe('linkInjection.js', () => {
|
|
|
188
184
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
189
185
|
const injection = generateInjection('This is a sentence & an injection.', 'an injection')
|
|
190
186
|
|
|
191
|
-
injectLinksInDocument(elements, { aiInjections: [injection], manualInjections: [] })
|
|
187
|
+
injectLinksInDocument(elements, () => null, { aiInjections: [injection], manualInjections: [] })
|
|
192
188
|
|
|
193
189
|
expect(document.querySelectorAll('a')).toHaveLength(1)
|
|
194
190
|
})
|
|
@@ -199,7 +195,7 @@ describe('linkInjection.js', () => {
|
|
|
199
195
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
200
196
|
const injection = generateInjection('This is a sentence with an injection.', 'a sentence')
|
|
201
197
|
|
|
202
|
-
injectLinksInDocument(elements, { aiInjections: [injection], manualInjections: [] })
|
|
198
|
+
injectLinksInDocument(elements, () => null, { aiInjections: [injection], manualInjections: [] })
|
|
203
199
|
|
|
204
200
|
expect(document.querySelector('[data-playpilot-injection-key]')).not.toBeTruthy()
|
|
205
201
|
})
|
|
@@ -210,7 +206,7 @@ describe('linkInjection.js', () => {
|
|
|
210
206
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
211
207
|
const injection = generateInjection('This is a sentence with an injection.', 'some word')
|
|
212
208
|
|
|
213
|
-
injectLinksInDocument(elements, { aiInjections: [injection], manualInjections: [] })
|
|
209
|
+
injectLinksInDocument(elements, () => null, { aiInjections: [injection], manualInjections: [] })
|
|
214
210
|
|
|
215
211
|
expect(document.querySelector('[data-playpilot-injection-key]')).not.toBeTruthy()
|
|
216
212
|
})
|
|
@@ -221,7 +217,7 @@ describe('linkInjection.js', () => {
|
|
|
221
217
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
222
218
|
const injection = generateInjection('This is a word with a word.', 'a word')
|
|
223
219
|
|
|
224
|
-
injectLinksInDocument(elements, { aiInjections: [injection], manualInjections: [] })
|
|
220
|
+
injectLinksInDocument(elements, () => null, { aiInjections: [injection], manualInjections: [] })
|
|
225
221
|
|
|
226
222
|
expect(document.querySelectorAll('a')).toHaveLength(2)
|
|
227
223
|
expect(Array.from(document.querySelectorAll('a')).filter(a => a.innerText === 'a word')).toHaveLength(2)
|
|
@@ -233,7 +229,7 @@ describe('linkInjection.js', () => {
|
|
|
233
229
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
234
230
|
const injection = generateInjection('This is a word with a word.', 'a word')
|
|
235
231
|
|
|
236
|
-
injectLinksInDocument(elements, { aiInjections: [injection], manualInjections: [] })
|
|
232
|
+
injectLinksInDocument(elements, () => null, { aiInjections: [injection], manualInjections: [] })
|
|
237
233
|
|
|
238
234
|
expect(document.querySelectorAll('a')).toHaveLength(2)
|
|
239
235
|
expect(Array.from(document.querySelectorAll('a')).filter(a => a.innerText === 'a word')).toHaveLength(2)
|
|
@@ -245,7 +241,7 @@ describe('linkInjection.js', () => {
|
|
|
245
241
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
246
242
|
const injection = generateInjection('this is a word with a word.', 'a word')
|
|
247
243
|
|
|
248
|
-
injectLinksInDocument(elements, { aiInjections: [injection], manualInjections: [] })
|
|
244
|
+
injectLinksInDocument(elements, () => null, { aiInjections: [injection], manualInjections: [] })
|
|
249
245
|
|
|
250
246
|
expect(document.querySelectorAll('a')).toHaveLength(2)
|
|
251
247
|
expect(Array.from(document.querySelectorAll('a')).filter(a => a.innerText === 'a word')).toHaveLength(2)
|
|
@@ -258,7 +254,7 @@ describe('linkInjection.js', () => {
|
|
|
258
254
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
259
255
|
const injection = generateInjection('But this sentence is a match.', 'a match')
|
|
260
256
|
|
|
261
|
-
injectLinksInDocument(elements, { aiInjections: [injection], manualInjections: [] })
|
|
257
|
+
injectLinksInDocument(elements, () => null, { aiInjections: [injection], manualInjections: [] })
|
|
262
258
|
|
|
263
259
|
expect(document.body.innerHTML).toContain('This is a match')
|
|
264
260
|
expect(document.querySelectorAll('[data-playpilot-injection-key]')).toHaveLength(1)
|
|
@@ -270,7 +266,7 @@ describe('linkInjection.js', () => {
|
|
|
270
266
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
271
267
|
const injection = generateInjection('This is a sentence with an injection.', 'an injection')
|
|
272
268
|
|
|
273
|
-
injectLinksInDocument(elements, { aiInjections: [injection], manualInjections: [] })
|
|
269
|
+
injectLinksInDocument(elements, () => null, { aiInjections: [injection], manualInjections: [] })
|
|
274
270
|
|
|
275
271
|
expect(document.querySelector('[data-playpilot-injection-key]')).toBeTruthy()
|
|
276
272
|
})
|
|
@@ -283,7 +279,7 @@ describe('linkInjection.js', () => {
|
|
|
283
279
|
/** @type {import('$lib/types/injection').LinkInjection[]} */
|
|
284
280
|
const linkInjections = []
|
|
285
281
|
|
|
286
|
-
injectLinksInDocument(elements, { aiInjections: linkInjections, manualInjections: [] })
|
|
282
|
+
injectLinksInDocument(elements, () => null, { aiInjections: linkInjections, manualInjections: [] })
|
|
287
283
|
|
|
288
284
|
expect(document.body.innerHTML.includes('This is a sentence with an injection.')).toBeTruthy()
|
|
289
285
|
})
|
|
@@ -295,24 +291,25 @@ describe('linkInjection.js', () => {
|
|
|
295
291
|
/** @type {import('$lib/types/injection').LinkInjection[]} */
|
|
296
292
|
const linkInjections = []
|
|
297
293
|
|
|
298
|
-
expect(() => injectLinksInDocument(elements, { aiInjections: linkInjections, manualInjections: [] })).not.toThrow()
|
|
294
|
+
expect(() => injectLinksInDocument(elements, () => null, { aiInjections: linkInjections, manualInjections: [] })).not.toThrow()
|
|
299
295
|
})
|
|
300
296
|
|
|
301
|
-
it('Should
|
|
297
|
+
it('Should fire given onclick function when clicked', async () => {
|
|
302
298
|
document.body.innerHTML = '<p>This is a sentence with an injection.</p>'
|
|
303
299
|
|
|
304
300
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
305
301
|
const injection = generateInjection('This is a sentence with an injection.', 'an injection')
|
|
306
302
|
|
|
307
|
-
|
|
303
|
+
const mock = vi.fn()
|
|
304
|
+
injectLinksInDocument(elements, mock, { aiInjections: [injection], manualInjections: [] })
|
|
308
305
|
|
|
309
306
|
const link = /** @type {HTMLAnchorElement} */ (document.querySelector('a'))
|
|
310
307
|
await fireEvent.click(link)
|
|
311
308
|
|
|
312
|
-
expect(
|
|
309
|
+
expect(mock).toHaveBeenCalledWith(injection)
|
|
313
310
|
})
|
|
314
311
|
|
|
315
|
-
it('Should
|
|
312
|
+
it('Should fire given onclick function when clicked for each link in a sentence if more than 1 injection is present', async () => {
|
|
316
313
|
const sentence = 'This is a sentence with an injection.'
|
|
317
314
|
document.body.innerHTML = `<p>${sentence}</p>`
|
|
318
315
|
|
|
@@ -323,13 +320,14 @@ describe('linkInjection.js', () => {
|
|
|
323
320
|
generateInjection(sentence, 'an injection'),
|
|
324
321
|
]
|
|
325
322
|
|
|
326
|
-
|
|
323
|
+
const mock = vi.fn()
|
|
324
|
+
injectLinksInDocument(elements, mock, { aiInjections: linkInjections, manualInjections: [] })
|
|
327
325
|
|
|
328
326
|
const links = document.querySelectorAll('a')
|
|
329
327
|
await fireEvent.click(links[0])
|
|
330
328
|
await fireEvent.click(links[1])
|
|
331
329
|
|
|
332
|
-
expect(
|
|
330
|
+
expect(mock).toHaveBeenCalledTimes(2)
|
|
333
331
|
})
|
|
334
332
|
|
|
335
333
|
it('Should not fire given onclick function when clicked with modifier keys or not left click', async () => {
|
|
@@ -339,7 +337,7 @@ describe('linkInjection.js', () => {
|
|
|
339
337
|
const injection = generateInjection('This is a sentence with an injection.', 'an injection')
|
|
340
338
|
|
|
341
339
|
const mock = vi.fn()
|
|
342
|
-
injectLinksInDocument(elements, { aiInjections: [injection], manualInjections: [] })
|
|
340
|
+
injectLinksInDocument(elements, mock, { aiInjections: [injection], manualInjections: [] })
|
|
343
341
|
|
|
344
342
|
const link = /** @type {HTMLAnchorElement} */ (document.querySelector('a'))
|
|
345
343
|
|
|
@@ -362,7 +360,7 @@ describe('linkInjection.js', () => {
|
|
|
362
360
|
generateInjection(sentence, 'not an injection'),
|
|
363
361
|
]
|
|
364
362
|
|
|
365
|
-
const results = injectLinksInDocument(elements, { aiInjections: linkInjections, manualInjections: [] })
|
|
363
|
+
const results = injectLinksInDocument(elements, () => null, { aiInjections: linkInjections, manualInjections: [] })
|
|
366
364
|
|
|
367
365
|
expect(results[0].failed).toBe(false)
|
|
368
366
|
expect(results[1].failed).toBe(true)
|
|
@@ -379,7 +377,7 @@ describe('linkInjection.js', () => {
|
|
|
379
377
|
generateInjection('Some unknown sentence', 'nothing'),
|
|
380
378
|
]
|
|
381
379
|
|
|
382
|
-
const results = injectLinksInDocument(elements, { aiInjections: [], manualInjections: linkInjections })
|
|
380
|
+
const results = injectLinksInDocument(elements, () => null, { aiInjections: [], manualInjections: linkInjections })
|
|
383
381
|
|
|
384
382
|
expect(results[0].failed_message).toBe('Given text is already inside of a link.')
|
|
385
383
|
expect(results[1].failed_message).toBe('Given sentence was not found in the article.')
|
|
@@ -391,7 +389,8 @@ describe('linkInjection.js', () => {
|
|
|
391
389
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
392
390
|
const injection = generateInjection('This is a sentence with an injection.', 'an injection')
|
|
393
391
|
|
|
394
|
-
|
|
392
|
+
const mock = vi.fn()
|
|
393
|
+
injectLinksInDocument(elements, mock, { aiInjections: [injection], manualInjections: [] })
|
|
395
394
|
|
|
396
395
|
const link = /** @type {HTMLAnchorElement} */ (document.querySelector('[data-playpilot-injection-key]'))
|
|
397
396
|
|
|
@@ -411,7 +410,8 @@ describe('linkInjection.js', () => {
|
|
|
411
410
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
412
411
|
const injection = generateInjection('This is a sentence with an injection.', 'an injection')
|
|
413
412
|
|
|
414
|
-
|
|
413
|
+
const mock = vi.fn()
|
|
414
|
+
injectLinksInDocument(elements, mock, { aiInjections: [injection], manualInjections: [] })
|
|
415
415
|
|
|
416
416
|
const link = /** @type {HTMLAnchorElement} */ (document.querySelector('[data-playpilot-injection-key]'))
|
|
417
417
|
|
|
@@ -432,7 +432,8 @@ describe('linkInjection.js', () => {
|
|
|
432
432
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
433
433
|
const injection = generateInjection('This is a sentence with an injection.', 'an injection')
|
|
434
434
|
|
|
435
|
-
|
|
435
|
+
const mock = vi.fn()
|
|
436
|
+
injectLinksInDocument(elements, mock, { aiInjections: [injection], manualInjections: [] })
|
|
436
437
|
|
|
437
438
|
const link = /** @type {HTMLAnchorElement} */ (document.querySelector('[data-playpilot-injection-key]'))
|
|
438
439
|
|
|
@@ -452,7 +453,8 @@ describe('linkInjection.js', () => {
|
|
|
452
453
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
453
454
|
const injection = generateInjection('This is a sentence with an injection.', 'an injection')
|
|
454
455
|
|
|
455
|
-
|
|
456
|
+
const mock = vi.fn()
|
|
457
|
+
injectLinksInDocument(elements, mock, { aiInjections: [injection], manualInjections: [] })
|
|
456
458
|
|
|
457
459
|
const link = /** @type {HTMLAnchorElement} */ (document.querySelector('[data-playpilot-injection-key]'))
|
|
458
460
|
|
|
@@ -479,7 +481,7 @@ describe('linkInjection.js', () => {
|
|
|
479
481
|
generateInjection(sentence, 'injection'),
|
|
480
482
|
]
|
|
481
483
|
|
|
482
|
-
injectLinksInDocument(elements, { aiInjections: linkInjections, manualInjections: [] })
|
|
484
|
+
injectLinksInDocument(elements, () => null, { aiInjections: linkInjections, manualInjections: [] })
|
|
483
485
|
|
|
484
486
|
const links = /** @type {HTMLAnchorElement[]} */ (Array.from(document.querySelectorAll('[data-playpilot-injection-key]')))
|
|
485
487
|
|
|
@@ -494,7 +496,7 @@ describe('linkInjection.js', () => {
|
|
|
494
496
|
const elements = Array.from(document.querySelectorAll('p'))
|
|
495
497
|
const injection = { ...generateInjection('This is a sentence with an injection.', 'an injection'), in_text: false }
|
|
496
498
|
|
|
497
|
-
injectLinksInDocument(elements, { aiInjections: [injection], manualInjections: [] })
|
|
499
|
+
injectLinksInDocument(elements, () => null, { aiInjections: [injection], manualInjections: [] })
|
|
498
500
|
|
|
499
501
|
expect(document.querySelector('a')).not.toBeTruthy()
|
|
500
502
|
})
|
|
@@ -507,7 +509,8 @@ describe('linkInjection.js', () => {
|
|
|
507
509
|
const elements = Array.from(document.body.querySelectorAll('p'))
|
|
508
510
|
const injection = generateInjection('This is a sentence with an injection.', 'an injection')
|
|
509
511
|
|
|
510
|
-
|
|
512
|
+
const mock = vi.fn()
|
|
513
|
+
injectLinksInDocument(elements, mock, { aiInjections: [injection], manualInjections: [] })
|
|
511
514
|
|
|
512
515
|
const link = /** @type {HTMLAnchorElement} */ (document.querySelector('a'))
|
|
513
516
|
|
|
@@ -526,7 +529,8 @@ describe('linkInjection.js', () => {
|
|
|
526
529
|
const injection = generateInjection('Some sentence', 'an injection')
|
|
527
530
|
const linkInjections = [{ ...injection, after_article: true, inactive: true }, { ...injection, after_article: true, removed: true }]
|
|
528
531
|
|
|
529
|
-
|
|
532
|
+
const mock = vi.fn()
|
|
533
|
+
injectLinksInDocument(elements, mock, { aiInjections: [], manualInjections: linkInjections })
|
|
530
534
|
|
|
531
535
|
expect(mount).not.toHaveBeenCalled()
|
|
532
536
|
expect(document.querySelector('[data-playpilot-after-article-playlinks]')).not.toBeTruthy()
|
|
@@ -549,7 +553,8 @@ describe('linkInjection.js', () => {
|
|
|
549
553
|
generateInjection('Some fourthtext', 'Some'),
|
|
550
554
|
]
|
|
551
555
|
|
|
552
|
-
|
|
556
|
+
const mock = vi.fn()
|
|
557
|
+
injectLinksInDocument(elements, mock, { aiInjections: [], manualInjections: injections })
|
|
553
558
|
|
|
554
559
|
expect(document.querySelectorAll('a')).toHaveLength(4)
|
|
555
560
|
})
|
|
@@ -569,7 +574,8 @@ describe('linkInjection.js', () => {
|
|
|
569
574
|
generateInjection('Somethird text', 'Some'),
|
|
570
575
|
]
|
|
571
576
|
|
|
572
|
-
|
|
577
|
+
const mock = vi.fn()
|
|
578
|
+
injectLinksInDocument(elements, mock, { aiInjections: [], manualInjections: injections })
|
|
573
579
|
|
|
574
580
|
expect(document.querySelectorAll('a')).toHaveLength(3)
|
|
575
581
|
})
|
|
@@ -593,7 +599,7 @@ describe('linkInjection.js', () => {
|
|
|
593
599
|
generateInjection('First Title Some other title', 'Fourth'),
|
|
594
600
|
]
|
|
595
601
|
|
|
596
|
-
injectLinksInDocument(elements, { aiInjections: [], manualInjections: injections })
|
|
602
|
+
injectLinksInDocument(elements, () => null, { aiInjections: [], manualInjections: injections })
|
|
597
603
|
|
|
598
604
|
expect(document.querySelectorAll('a')).toHaveLength(4)
|
|
599
605
|
})
|
|
@@ -696,7 +702,7 @@ describe('linkInjection.js', () => {
|
|
|
696
702
|
expect(getLinkInjectionElements(parent)[1].tagName).toBe('OL')
|
|
697
703
|
})
|
|
698
704
|
|
|
699
|
-
it('Should ignore links, buttons, script tags, style tags, iframes,
|
|
705
|
+
it('Should ignore links, buttons, script tags, style tags, iframes, and headers', () => {
|
|
700
706
|
document.body.innerHTML = `<section>
|
|
701
707
|
<h1>Some header</h1>
|
|
702
708
|
<h4>Some smaller header</h4>
|
|
@@ -708,7 +714,6 @@ describe('linkInjection.js', () => {
|
|
|
708
714
|
<style>I am styling</style>
|
|
709
715
|
<iframe>I am an iframe</iframe>
|
|
710
716
|
<noscript>I am noscript</noscript>
|
|
711
|
-
<figcaption>I am a figcaption</figcaption>
|
|
712
717
|
|
|
713
718
|
<div>
|
|
714
719
|
<a>I am another link</a>
|
|
@@ -817,7 +822,7 @@ describe('linkInjection.js', () => {
|
|
|
817
822
|
const injection = generateInjection('This is a sentence with an injection.', 'an injection')
|
|
818
823
|
|
|
819
824
|
const elements = getLinkInjectionElements(document.body)
|
|
820
|
-
insertAfterArticlePlaylinks(elements, [injection])
|
|
825
|
+
insertAfterArticlePlaylinks(elements, [injection], () => null)
|
|
821
826
|
|
|
822
827
|
expect(mount).toHaveBeenCalled()
|
|
823
828
|
expect(document.querySelector('p:last-of-type + [data-playpilot-after-article-playlinks]')).toBeTruthy()
|
|
@@ -831,7 +836,7 @@ describe('linkInjection.js', () => {
|
|
|
831
836
|
`
|
|
832
837
|
|
|
833
838
|
const elements = getLinkInjectionElements(document.body)
|
|
834
|
-
insertAfterArticlePlaylinks(elements, [])
|
|
839
|
+
insertAfterArticlePlaylinks(elements, [], () => null)
|
|
835
840
|
|
|
836
841
|
expect(mount).not.toHaveBeenCalled()
|
|
837
842
|
expect(document.querySelector('[data-playpilot-after-article-playlinks]')).not.toBeTruthy()
|
|
@@ -849,7 +854,7 @@ describe('linkInjection.js', () => {
|
|
|
849
854
|
|
|
850
855
|
const injection = generateInjection('This is a sentence with an injection.', 'an injection')
|
|
851
856
|
const elements = getLinkInjectionElements(document.body)
|
|
852
|
-
insertAfterArticlePlaylinks(elements, [injection])
|
|
857
|
+
insertAfterArticlePlaylinks(elements, [injection], () => null)
|
|
853
858
|
|
|
854
859
|
expect(document.querySelector('hr + [data-playpilot-after-article-playlinks]')).toBeTruthy()
|
|
855
860
|
})
|
|
@@ -866,7 +871,7 @@ describe('linkInjection.js', () => {
|
|
|
866
871
|
|
|
867
872
|
const injection = generateInjection('This is a sentence with an injection.', 'an injection')
|
|
868
873
|
const elements = getLinkInjectionElements(document.body)
|
|
869
|
-
insertAfterArticlePlaylinks(elements, [injection])
|
|
874
|
+
insertAfterArticlePlaylinks(elements, [injection], () => null)
|
|
870
875
|
|
|
871
876
|
expect(document.querySelector('hr + [data-playpilot-after-article-playlinks]')).toBeTruthy()
|
|
872
877
|
})
|
|
@@ -884,7 +889,7 @@ describe('linkInjection.js', () => {
|
|
|
884
889
|
|
|
885
890
|
const injection = generateInjection('This is a sentence with an injection.', 'an injection')
|
|
886
891
|
const elements = getLinkInjectionElements(document.body)
|
|
887
|
-
insertAfterArticlePlaylinks(elements, [injection])
|
|
892
|
+
insertAfterArticlePlaylinks(elements, [injection], () => null)
|
|
888
893
|
|
|
889
894
|
expect(document.querySelector('[data-playpilot-after-article-playlinks] + hr')).toBeTruthy()
|
|
890
895
|
})
|
|
@@ -53,13 +53,6 @@ describe('localization.js', () => {
|
|
|
53
53
|
expect(getLanguage()).toBe('sv-SE')
|
|
54
54
|
})
|
|
55
55
|
|
|
56
|
-
it('Should return the language given as document language even when using shorthand', () => {
|
|
57
|
-
const html = /** @type {HTMLElement} */ (document.querySelector('html'))
|
|
58
|
-
html.setAttribute('lang', 'sv')
|
|
59
|
-
|
|
60
|
-
expect(getLanguage()).toBe('sv-SE')
|
|
61
|
-
})
|
|
62
|
-
|
|
63
56
|
it('Should return the default language when document language is invalid', () => {
|
|
64
57
|
const html = /** @type {HTMLElement} */ (document.querySelector('html'))
|
|
65
58
|
html.setAttribute('lang', 'no')
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { describe, it, expect, afterEach, vi } from 'vitest'
|
|
2
|
+
import { fetchAsSession, getSessionId, isAllowedToEdit, sessionKey, setSessionId } from '$lib/session'
|
|
3
|
+
import { fetchLinkInjections } from '$lib/api'
|
|
4
|
+
import { waitFor } from '@testing-library/svelte'
|
|
5
|
+
|
|
6
|
+
vi.mock('$lib/api', () => ({
|
|
7
|
+
fetchLinkInjections: vi.fn(() => {}),
|
|
8
|
+
}))
|
|
9
|
+
|
|
10
|
+
describe('session.ts', () => {
|
|
11
|
+
afterEach(() => {
|
|
12
|
+
sessionStorage.clear()
|
|
13
|
+
vi.resetAllMocks()
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
describe('fetchAsSession', () => {
|
|
17
|
+
it('Should fetch and fetch again when user is allowed to edit', async() => {
|
|
18
|
+
// @ts-ignore
|
|
19
|
+
vi.mocked(fetchLinkInjections).mockResolvedValue({ session_id: 'a', session_last_ping: null })
|
|
20
|
+
|
|
21
|
+
fetchAsSession('abc')
|
|
22
|
+
|
|
23
|
+
await waitFor(() => {
|
|
24
|
+
expect(fetchLinkInjections).toHaveBeenCalledTimes(2)
|
|
25
|
+
})
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
it('Should fetch only once if user is not allowed to edit', async() => {
|
|
29
|
+
// @ts-ignore
|
|
30
|
+
vi.mocked(fetchLinkInjections).mockResolvedValue({ session_id: 'a', session_last_ping: Date.now().toString() })
|
|
31
|
+
|
|
32
|
+
fetchAsSession('abc')
|
|
33
|
+
|
|
34
|
+
await new Promise(res => setTimeout(res, 100)) // Await potential fetch
|
|
35
|
+
|
|
36
|
+
expect(fetchLinkInjections).toHaveBeenCalledOnce()
|
|
37
|
+
})
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
describe('isAllowedToEdit', () => {
|
|
41
|
+
it('Should return true if either argument is null or empty', () => {
|
|
42
|
+
expect(isAllowedToEdit('a', null)).toBe(true)
|
|
43
|
+
expect(isAllowedToEdit('a', '')).toBe(true)
|
|
44
|
+
|
|
45
|
+
expect(isAllowedToEdit(null, Date.now().toString())).toBe(true)
|
|
46
|
+
expect(isAllowedToEdit('', Date.now().toString())).toBe(true)
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
it('Should return true if session id is given and last ping is more than 10 seconds ago', () => {
|
|
50
|
+
expect(isAllowedToEdit('a', '2020-10-10')).toBe(true)
|
|
51
|
+
expect(isAllowedToEdit('a', '0')).toBe(true)
|
|
52
|
+
expect(isAllowedToEdit('a', new Date(Date.now() - 11000).toString())).toBe(true)
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
it('Should return false if session id equals current session id regardless of last ping', () => {
|
|
56
|
+
sessionStorage.setItem(sessionKey, 'me')
|
|
57
|
+
|
|
58
|
+
expect(isAllowedToEdit('me', '2020-10-10')).toBe(true)
|
|
59
|
+
expect(isAllowedToEdit('me', Date.now().toString())).toBe(true)
|
|
60
|
+
})
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
describe('getSessionId', () => {
|
|
64
|
+
it('Should get the item stored in session storage', () => {
|
|
65
|
+
sessionStorage.setItem(sessionKey, 'abc')
|
|
66
|
+
expect(getSessionId()).toBe('abc')
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
it('Should set a new item if no value is stored in session storage', () => {
|
|
70
|
+
sessionStorage.setItem(sessionKey, 'abc')
|
|
71
|
+
|
|
72
|
+
const result = getSessionId()
|
|
73
|
+
|
|
74
|
+
expect(result).toEqual(expect.any(String))
|
|
75
|
+
expect(sessionStorage.getItem(sessionKey)).toBe(result)
|
|
76
|
+
})
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
describe('setSessionId', () => {
|
|
80
|
+
it('Should set a new item in session storage when no previous value is set', () => {
|
|
81
|
+
const result = setSessionId()
|
|
82
|
+
|
|
83
|
+
expect(result).toEqual(expect.any(String))
|
|
84
|
+
expect(sessionStorage.getItem(sessionKey)).toBe(result)
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
it('Should return existing item in session storage when set', () => {
|
|
88
|
+
sessionStorage.setItem(sessionKey, 'abc')
|
|
89
|
+
const result = setSessionId()
|
|
90
|
+
|
|
91
|
+
expect(result).toBe('abc')
|
|
92
|
+
expect(sessionStorage.getItem(sessionKey)).toBe('abc')
|
|
93
|
+
})
|
|
94
|
+
})
|
|
95
|
+
})
|
|
@@ -4,7 +4,6 @@ import { setTrackingSids, track } from '$lib/tracking'
|
|
|
4
4
|
import { title } from '$lib/fakeData'
|
|
5
5
|
import { get } from 'svelte/store'
|
|
6
6
|
import { currentDomainSid, currentOrganizationSid } from '$lib/stores/organization'
|
|
7
|
-
import { getFullUrlPath } from '$lib/url'
|
|
8
7
|
|
|
9
8
|
global.fetch = vi.fn()
|
|
10
9
|
|
|
@@ -41,21 +40,6 @@ describe('$lib/tracking', () => {
|
|
|
41
40
|
)
|
|
42
41
|
})
|
|
43
42
|
|
|
44
|
-
it('Should strip url to full path only', () => {
|
|
45
|
-
window.location.href = 'https://some-url.com/page?key=value'
|
|
46
|
-
|
|
47
|
-
track('Some event')
|
|
48
|
-
|
|
49
|
-
expect(global.fetch).toHaveBeenCalledWith(
|
|
50
|
-
expect.any(String),
|
|
51
|
-
expect.objectContaining({
|
|
52
|
-
body: expect.stringMatching(
|
|
53
|
-
new RegExp(`"url":"${getFullUrlPath()}"`),
|
|
54
|
-
),
|
|
55
|
-
}),
|
|
56
|
-
)
|
|
57
|
-
})
|
|
58
|
-
|
|
59
43
|
it('Should include domain sid in request', () => {
|
|
60
44
|
currentDomainSid.set('some-domain')
|
|
61
45
|
|
|
@@ -11,10 +11,20 @@ import { injectLinksInDocument } from '$lib/linkInjection'
|
|
|
11
11
|
import { isCrawler } from '$lib/crawler'
|
|
12
12
|
|
|
13
13
|
vi.mock('$lib/api', () => ({
|
|
14
|
+
fetchLinkInjections: vi.fn(() => {}),
|
|
14
15
|
pollLinkInjections: vi.fn(() => {}),
|
|
15
16
|
fetchConfig: vi.fn(),
|
|
16
17
|
}))
|
|
17
18
|
|
|
19
|
+
// @ts-ignore
|
|
20
|
+
vi.mock(import('$lib/session'), async (importOriginal) => {
|
|
21
|
+
const actual = await importOriginal()
|
|
22
|
+
return {
|
|
23
|
+
...actual,
|
|
24
|
+
fetchAsSession: vi.fn(() => {}),
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
|
|
18
28
|
vi.mock(import('$lib/linkInjection'), async (importOriginal) => {
|
|
19
29
|
const actual = await importOriginal()
|
|
20
30
|
return {
|
|
@@ -80,8 +90,8 @@ describe('$routes/+page.svelte', () => {
|
|
|
80
90
|
render(page)
|
|
81
91
|
|
|
82
92
|
await waitFor(() => {
|
|
83
|
-
expect(pollLinkInjections).toHaveBeenCalledWith(expect.any(String),
|
|
84
|
-
expect(pollLinkInjections).toHaveBeenCalledWith(expect.any(String),
|
|
93
|
+
expect(pollLinkInjections).toHaveBeenCalledWith(expect.any(String), { maxTries: 1 })
|
|
94
|
+
expect(pollLinkInjections).toHaveBeenCalledWith(expect.any(String), { requireCompletedResult: true, onpoll: expect.any(Function) })
|
|
85
95
|
})
|
|
86
96
|
})
|
|
87
97
|
|
|
@@ -104,7 +114,7 @@ describe('$routes/+page.svelte', () => {
|
|
|
104
114
|
})
|
|
105
115
|
|
|
106
116
|
await waitFor(() => {
|
|
107
|
-
expect(pollLinkInjections).toHaveBeenCalledWith(expect.any(String),
|
|
117
|
+
expect(pollLinkInjections).toHaveBeenCalledWith(expect.any(String), { requireCompletedResult: true, onpoll: expect.any(Function) })
|
|
108
118
|
})
|
|
109
119
|
|
|
110
120
|
expect(pollLinkInjections).toHaveBeenCalledTimes(2)
|
|
@@ -167,7 +177,7 @@ describe('$routes/+page.svelte', () => {
|
|
|
167
177
|
render(page)
|
|
168
178
|
|
|
169
179
|
await waitFor(() => {
|
|
170
|
-
expect(pollLinkInjections).toHaveBeenCalledWith(
|
|
180
|
+
expect(pollLinkInjections).toHaveBeenCalledWith('<p>Here</p>', { maxTries: 1 })
|
|
171
181
|
})
|
|
172
182
|
})
|
|
173
183
|
|
|
@@ -1,21 +1,37 @@
|
|
|
1
1
|
import { fireEvent, render } from '@testing-library/svelte'
|
|
2
|
-
import { describe, expect, it, vi } from 'vitest'
|
|
2
|
+
import { beforeAll, describe, expect, it, vi } from 'vitest'
|
|
3
3
|
|
|
4
4
|
import Editor from '../../../../routes/components/Editorial/Editor.svelte'
|
|
5
5
|
import { title } from '$lib/fakeData'
|
|
6
6
|
import { generateInjection } from '../../../helpers'
|
|
7
7
|
import { track } from '$lib/tracking'
|
|
8
8
|
import { TrackingEvent } from '$lib/enums/TrackingEvent'
|
|
9
|
+
import { fetchLinkInjections } from '$lib/api'
|
|
9
10
|
|
|
10
11
|
vi.mock('$lib/api', () => ({
|
|
11
12
|
saveLinkInjections: vi.fn(),
|
|
13
|
+
fetchLinkInjections: vi.fn(() => {}),
|
|
12
14
|
}))
|
|
13
15
|
|
|
16
|
+
// @ts-ignore
|
|
17
|
+
vi.mock(import('$lib/session'), async (importOriginal) => {
|
|
18
|
+
const actual = await importOriginal()
|
|
19
|
+
return {
|
|
20
|
+
...actual,
|
|
21
|
+
isAllowedToEdit: vi.fn(() => true),
|
|
22
|
+
}
|
|
23
|
+
})
|
|
24
|
+
|
|
14
25
|
vi.mock('$lib/tracking', () => ({
|
|
15
26
|
track: vi.fn(),
|
|
16
27
|
}))
|
|
17
28
|
|
|
18
29
|
describe('Editor.svelte', () => {
|
|
30
|
+
beforeAll(() => {
|
|
31
|
+
// @ts-ignore
|
|
32
|
+
vi.mocked(fetchLinkInjections).mockResolvedValue({})
|
|
33
|
+
})
|
|
34
|
+
|
|
19
35
|
/** @type {import('$lib/types/injection').LinkInjection[]} */
|
|
20
36
|
const linkInjections = [
|
|
21
37
|
generateInjection('This is a sentence with an injection.', 'an injection'),
|