]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/tests/client.ts
Remove unnecessary await
[github/Chocobozzz/PeerTube.git] / server / tests / client.ts
1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3 import 'mocha'
4 import * as chai from 'chai'
5 import { omit } from 'lodash'
6 import * as request from 'supertest'
7 import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes'
8 import { Account, CustomConfig, HTMLServerConfig, ServerConfig, VideoPlaylistPrivacy } from '@shared/models'
9 import {
10 addVideoInPlaylist,
11 cleanupTests,
12 createVideoPlaylist,
13 doubleFollow,
14 flushAndRunMultipleServers,
15 getAccount,
16 getConfig,
17 getCustomConfig,
18 getVideosList,
19 makeGetRequest,
20 makeHTMLRequest,
21 ServerInfo,
22 setAccessTokensToServers,
23 setDefaultVideoChannel,
24 updateCustomConfig,
25 updateCustomSubConfig,
26 updateMyUser,
27 updateVideoChannel,
28 uploadVideo,
29 waitJobs
30 } from '../../shared/extra-utils'
31
32 const expect = chai.expect
33
34 function checkIndexTags (html: string, title: string, description: string, css: string, config: ServerConfig) {
35 expect(html).to.contain('<title>' + title + '</title>')
36 expect(html).to.contain('<meta name="description" content="' + description + '" />')
37 expect(html).to.contain('<style class="custom-css-style">' + css + '</style>')
38
39 const htmlConfig: HTMLServerConfig = omit(config, 'signup')
40 expect(html).to.contain(`<script type="application/javascript">window.PeerTubeServerConfig = '${JSON.stringify(htmlConfig)}'</script>`)
41 }
42
43 describe('Test a client controllers', function () {
44 let servers: ServerInfo[] = []
45 let account: Account
46
47 const videoName = 'my super name for server 1'
48 const videoDescription = 'my<br> super __description__ for *server* 1<p></p>'
49 const videoDescriptionPlainText = 'my super description for server 1'
50
51 const playlistName = 'super playlist name'
52 const playlistDescription = 'super playlist description'
53 let playlistUUID: string
54
55 const channelDescription = 'my super channel description'
56
57 const watchVideoBasePaths = [ '/videos/watch/', '/w/' ]
58 const watchPlaylistBasePaths = [ '/videos/watch/playlist/', '/w/p/' ]
59
60 before(async function () {
61 this.timeout(120000)
62
63 servers = await flushAndRunMultipleServers(2)
64
65 await setAccessTokensToServers(servers)
66
67 await doubleFollow(servers[0], servers[1])
68
69 await setDefaultVideoChannel(servers)
70
71 await updateVideoChannel(servers[0].url, servers[0].accessToken, servers[0].videoChannel.name, { description: channelDescription })
72
73 // Video
74
75 const videoAttributes = { name: videoName, description: videoDescription }
76 await uploadVideo(servers[0].url, servers[0].accessToken, videoAttributes)
77
78 const resVideosRequest = await getVideosList(servers[0].url)
79 const videos = resVideosRequest.body.data
80 expect(videos.length).to.equal(1)
81
82 servers[0].video = videos[0]
83
84 // Playlist
85
86 const playlistAttrs = {
87 displayName: playlistName,
88 description: playlistDescription,
89 privacy: VideoPlaylistPrivacy.PUBLIC,
90 videoChannelId: servers[0].videoChannel.id
91 }
92
93 const resVideoPlaylistRequest = await createVideoPlaylist({ url: servers[0].url, token: servers[0].accessToken, playlistAttrs })
94
95 const playlist = resVideoPlaylistRequest.body.videoPlaylist
96 const playlistId = playlist.id
97 playlistUUID = playlist.uuid
98
99 await addVideoInPlaylist({
100 url: servers[0].url,
101 token: servers[0].accessToken,
102 playlistId,
103 elementAttrs: { videoId: servers[0].video.id }
104 })
105
106 // Account
107
108 await updateMyUser({ url: servers[0].url, accessToken: servers[0].accessToken, description: 'my account description' })
109
110 const resAccountRequest = await getAccount(servers[0].url, `${servers[0].user.username}@${servers[0].host}`)
111 account = resAccountRequest.body
112
113 await waitJobs(servers)
114 })
115
116 describe('oEmbed', function () {
117
118 it('Should have valid oEmbed discovery tags for videos', async function () {
119 for (const basePath of watchVideoBasePaths) {
120 const path = basePath + servers[0].video.uuid
121 const res = await request(servers[0].url)
122 .get(path)
123 .set('Accept', 'text/html')
124 .expect(HttpStatusCode.OK_200)
125
126 const port = servers[0].port
127
128 const expectedLink = '<link rel="alternate" type="application/json+oembed" href="http://localhost:' + port + '/services/oembed?' +
129 `url=http%3A%2F%2Flocalhost%3A${port}%2Fw%2F${servers[0].video.uuid}" ` +
130 `title="${servers[0].video.name}" />`
131
132 expect(res.text).to.contain(expectedLink)
133 }
134 })
135
136 it('Should have valid oEmbed discovery tags for a playlist', async function () {
137 for (const basePath of watchPlaylistBasePaths) {
138 const res = await request(servers[0].url)
139 .get(basePath + playlistUUID)
140 .set('Accept', 'text/html')
141 .expect(HttpStatusCode.OK_200)
142
143 const port = servers[0].port
144
145 const expectedLink = '<link rel="alternate" type="application/json+oembed" href="http://localhost:' + port + '/services/oembed?' +
146 `url=http%3A%2F%2Flocalhost%3A${port}%2Fw%2Fp%2F${playlistUUID}" ` +
147 `title="${playlistName}" />`
148
149 expect(res.text).to.contain(expectedLink)
150 }
151 })
152 })
153
154 describe('Open Graph', function () {
155
156 async function accountPageTest (path: string) {
157 const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', statusCodeExpected: HttpStatusCode.OK_200 })
158 const text = res.text
159
160 expect(text).to.contain(`<meta property="og:title" content="${account.displayName}" />`)
161 expect(text).to.contain(`<meta property="og:description" content="${account.description}" />`)
162 expect(text).to.contain('<meta property="og:type" content="website" />')
163 expect(text).to.contain(`<meta property="og:url" content="${servers[0].url}/accounts/${servers[0].user.username}" />`)
164 }
165
166 async function channelPageTest (path: string) {
167 const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', statusCodeExpected: HttpStatusCode.OK_200 })
168 const text = res.text
169
170 expect(text).to.contain(`<meta property="og:title" content="${servers[0].videoChannel.displayName}" />`)
171 expect(text).to.contain(`<meta property="og:description" content="${channelDescription}" />`)
172 expect(text).to.contain('<meta property="og:type" content="website" />')
173 expect(text).to.contain(`<meta property="og:url" content="${servers[0].url}/video-channels/${servers[0].videoChannel.name}" />`)
174 }
175
176 async function watchVideoPageTest (path: string) {
177 const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', statusCodeExpected: HttpStatusCode.OK_200 })
178 const text = res.text
179
180 expect(text).to.contain(`<meta property="og:title" content="${videoName}" />`)
181 expect(text).to.contain(`<meta property="og:description" content="${videoDescriptionPlainText}" />`)
182 expect(text).to.contain('<meta property="og:type" content="video" />')
183 expect(text).to.contain(`<meta property="og:url" content="${servers[0].url}/w/${servers[0].video.uuid}" />`)
184 }
185
186 async function watchPlaylistPageTest (path: string) {
187 const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', statusCodeExpected: HttpStatusCode.OK_200 })
188 const text = res.text
189
190 expect(text).to.contain(`<meta property="og:title" content="${playlistName}" />`)
191 expect(text).to.contain(`<meta property="og:description" content="${playlistDescription}" />`)
192 expect(text).to.contain('<meta property="og:type" content="video" />')
193 expect(text).to.contain(`<meta property="og:url" content="${servers[0].url}/w/p/${playlistUUID}" />`)
194 }
195
196 it('Should have valid Open Graph tags on the account page', async function () {
197 await accountPageTest('/accounts/' + servers[0].user.username)
198 await accountPageTest('/a/' + servers[0].user.username)
199 await accountPageTest('/@' + servers[0].user.username)
200 })
201
202 it('Should have valid Open Graph tags on the channel page', async function () {
203 await channelPageTest('/video-channels/' + servers[0].videoChannel.name)
204 await channelPageTest('/c/' + servers[0].videoChannel.name)
205 await channelPageTest('/@' + servers[0].videoChannel.name)
206 })
207
208 it('Should have valid Open Graph tags on the watch page', async function () {
209 await watchVideoPageTest('/videos/watch/' + servers[0].video.id)
210 await watchVideoPageTest('/videos/watch/' + servers[0].video.uuid)
211 await watchVideoPageTest('/w/' + servers[0].video.uuid)
212 await watchVideoPageTest('/w/' + servers[0].video.id)
213 })
214
215 it('Should have valid Open Graph tags on the watch playlist page', async function () {
216 await watchPlaylistPageTest('/videos/watch/playlist/' + playlistUUID)
217 await watchPlaylistPageTest('/w/p/' + playlistUUID)
218 })
219 })
220
221 describe('Twitter card', async function () {
222
223 describe('Not whitelisted', function () {
224
225 async function accountPageTest (path: string) {
226 const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', statusCodeExpected: HttpStatusCode.OK_200 })
227 const text = res.text
228
229 expect(text).to.contain('<meta property="twitter:card" content="summary" />')
230 expect(text).to.contain('<meta property="twitter:site" content="@Chocobozzz" />')
231 expect(text).to.contain(`<meta property="twitter:title" content="${account.name}" />`)
232 expect(text).to.contain(`<meta property="twitter:description" content="${account.description}" />`)
233 }
234
235 async function channelPageTest (path: string) {
236 const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', statusCodeExpected: HttpStatusCode.OK_200 })
237 const text = res.text
238
239 expect(text).to.contain('<meta property="twitter:card" content="summary" />')
240 expect(text).to.contain('<meta property="twitter:site" content="@Chocobozzz" />')
241 expect(text).to.contain(`<meta property="twitter:title" content="${servers[0].videoChannel.displayName}" />`)
242 expect(text).to.contain(`<meta property="twitter:description" content="${channelDescription}" />`)
243 }
244
245 async function watchVideoPageTest (path: string) {
246 const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', statusCodeExpected: HttpStatusCode.OK_200 })
247 const text = res.text
248
249 expect(text).to.contain('<meta property="twitter:card" content="summary_large_image" />')
250 expect(text).to.contain('<meta property="twitter:site" content="@Chocobozzz" />')
251 expect(text).to.contain(`<meta property="twitter:title" content="${videoName}" />`)
252 expect(text).to.contain(`<meta property="twitter:description" content="${videoDescriptionPlainText}" />`)
253 }
254
255 async function watchPlaylistPageTest (path: string) {
256 const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', statusCodeExpected: HttpStatusCode.OK_200 })
257 const text = res.text
258
259 expect(text).to.contain('<meta property="twitter:card" content="summary" />')
260 expect(text).to.contain('<meta property="twitter:site" content="@Chocobozzz" />')
261 expect(text).to.contain(`<meta property="twitter:title" content="${playlistName}" />`)
262 expect(text).to.contain(`<meta property="twitter:description" content="${playlistDescription}" />`)
263 }
264
265 it('Should have valid twitter card on the watch video page', async function () {
266 await watchVideoPageTest('/videos/watch/' + servers[0].video.id)
267 await watchVideoPageTest('/videos/watch/' + servers[0].video.uuid)
268 await watchVideoPageTest('/w/' + servers[0].video.uuid)
269 await watchVideoPageTest('/w/' + servers[0].video.id)
270 })
271
272 it('Should have valid twitter card on the watch playlist page', async function () {
273 await watchPlaylistPageTest('/videos/watch/playlist/' + playlistUUID)
274 await watchPlaylistPageTest('/w/p/' + playlistUUID)
275 })
276
277 it('Should have valid twitter card on the account page', async function () {
278 await accountPageTest('/accounts/' + account.name)
279 await accountPageTest('/a/' + account.name)
280 await accountPageTest('/@' + account.name)
281 })
282
283 it('Should have valid twitter card on the channel page', async function () {
284 await channelPageTest('/video-channels/' + servers[0].videoChannel.name)
285 await channelPageTest('/c/' + servers[0].videoChannel.name)
286 await channelPageTest('/@' + servers[0].videoChannel.name)
287 })
288 })
289
290 describe('Whitelisted', function () {
291
292 before(async function () {
293 const res = await getCustomConfig(servers[0].url, servers[0].accessToken)
294 const config = res.body as CustomConfig
295 config.services.twitter = {
296 username: '@Kuja',
297 whitelisted: true
298 }
299
300 await updateCustomConfig(servers[0].url, servers[0].accessToken, config)
301 })
302
303 async function accountPageTest (path: string) {
304 const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', statusCodeExpected: HttpStatusCode.OK_200 })
305 const text = res.text
306
307 expect(text).to.contain('<meta property="twitter:card" content="summary" />')
308 expect(text).to.contain('<meta property="twitter:site" content="@Kuja" />')
309 }
310
311 async function channelPageTest (path: string) {
312 const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', statusCodeExpected: HttpStatusCode.OK_200 })
313 const text = res.text
314
315 expect(text).to.contain('<meta property="twitter:card" content="summary" />')
316 expect(text).to.contain('<meta property="twitter:site" content="@Kuja" />')
317 }
318
319 async function watchVideoPageTest (path: string) {
320 const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', statusCodeExpected: HttpStatusCode.OK_200 })
321 const text = res.text
322
323 expect(text).to.contain('<meta property="twitter:card" content="player" />')
324 expect(text).to.contain('<meta property="twitter:site" content="@Kuja" />')
325 }
326
327 async function watchPlaylistPageTest (path: string) {
328 const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', statusCodeExpected: HttpStatusCode.OK_200 })
329 const text = res.text
330
331 expect(text).to.contain('<meta property="twitter:card" content="player" />')
332 expect(text).to.contain('<meta property="twitter:site" content="@Kuja" />')
333 }
334
335 it('Should have valid twitter card on the watch video page', async function () {
336 await watchVideoPageTest('/videos/watch/' + servers[0].video.id)
337 await watchVideoPageTest('/videos/watch/' + servers[0].video.uuid)
338 await watchVideoPageTest('/w/' + servers[0].video.uuid)
339 await watchVideoPageTest('/w/' + servers[0].video.id)
340 })
341
342 it('Should have valid twitter card on the watch playlist page', async function () {
343 await watchPlaylistPageTest('/videos/watch/playlist/' + playlistUUID)
344 await watchPlaylistPageTest('/w/p/' + playlistUUID)
345 })
346
347 it('Should have valid twitter card on the account page', async function () {
348 await accountPageTest('/accounts/' + account.name)
349 await accountPageTest('/a/' + account.name)
350 await accountPageTest('/@' + account.name)
351 })
352
353 it('Should have valid twitter card on the channel page', async function () {
354 await channelPageTest('/video-channels/' + servers[0].videoChannel.name)
355 await channelPageTest('/c/' + servers[0].videoChannel.name)
356 await channelPageTest('/@' + servers[0].videoChannel.name)
357 })
358 })
359 })
360
361 describe('Index HTML', function () {
362
363 it('Should have valid index html tags (title, description...)', async function () {
364 const resConfig = await getConfig(servers[0].url)
365 const res = await makeHTMLRequest(servers[0].url, '/videos/trending')
366
367 const description = 'PeerTube, an ActivityPub-federated video streaming platform using P2P directly in your web browser.'
368 checkIndexTags(res.text, 'PeerTube', description, '', resConfig.body)
369 })
370
371 it('Should update the customized configuration and have the correct index html tags', async function () {
372 await updateCustomSubConfig(servers[0].url, servers[0].accessToken, {
373 instance: {
374 name: 'PeerTube updated',
375 shortDescription: 'my short description',
376 description: 'my super description',
377 terms: 'my super terms',
378 defaultNSFWPolicy: 'blur',
379 defaultClientRoute: '/videos/recently-added',
380 customizations: {
381 javascript: 'alert("coucou")',
382 css: 'body { background-color: red; }'
383 }
384 }
385 })
386
387 const resConfig = await getConfig(servers[0].url)
388 const res = await makeHTMLRequest(servers[0].url, '/videos/trending')
389
390 checkIndexTags(res.text, 'PeerTube updated', 'my short description', 'body { background-color: red; }', resConfig.body)
391 })
392
393 it('Should have valid index html updated tags (title, description...)', async function () {
394 const resConfig = await getConfig(servers[0].url)
395 const res = await makeHTMLRequest(servers[0].url, '/videos/trending')
396
397 checkIndexTags(res.text, 'PeerTube updated', 'my short description', 'body { background-color: red; }', resConfig.body)
398 })
399
400 it('Should use the original video URL for the canonical tag', async function () {
401 for (const basePath of watchVideoBasePaths) {
402 const res = await makeHTMLRequest(servers[1].url, basePath + servers[0].video.uuid)
403 expect(res.text).to.contain(`<link rel="canonical" href="${servers[0].url}/videos/watch/${servers[0].video.uuid}" />`)
404 }
405 })
406
407 it('Should use the original account URL for the canonical tag', async function () {
408 const accountURLtest = (res) => {
409 expect(res.text).to.contain(`<link rel="canonical" href="${servers[0].url}/accounts/root" />`)
410 }
411
412 accountURLtest(await makeHTMLRequest(servers[1].url, '/accounts/root@' + servers[0].host))
413 accountURLtest(await makeHTMLRequest(servers[1].url, '/a/root@' + servers[0].host))
414 accountURLtest(await makeHTMLRequest(servers[1].url, '/@root@' + servers[0].host))
415 })
416
417 it('Should use the original channel URL for the canonical tag', async function () {
418 const channelURLtests = (res) => {
419 expect(res.text).to.contain(`<link rel="canonical" href="${servers[0].url}/video-channels/root_channel" />`)
420 }
421
422 channelURLtests(await makeHTMLRequest(servers[1].url, '/video-channels/root_channel@' + servers[0].host))
423 channelURLtests(await makeHTMLRequest(servers[1].url, '/c/root_channel@' + servers[0].host))
424 channelURLtests(await makeHTMLRequest(servers[1].url, '/@root_channel@' + servers[0].host))
425 })
426
427 it('Should use the original playlist URL for the canonical tag', async function () {
428 for (const basePath of watchPlaylistBasePaths) {
429 const res = await makeHTMLRequest(servers[1].url, basePath + playlistUUID)
430 expect(res.text).to.contain(`<link rel="canonical" href="${servers[0].url}/video-playlists/${playlistUUID}" />`)
431 }
432 })
433 })
434
435 describe('Embed HTML', function () {
436
437 it('Should have the correct embed html tags', async function () {
438 const resConfig = await getConfig(servers[0].url)
439 const res = await makeHTMLRequest(servers[0].url, servers[0].video.embedPath)
440
441 checkIndexTags(res.text, 'PeerTube updated', 'my short description', 'body { background-color: red; }', resConfig.body)
442 })
443 })
444
445 after(async function () {
446 await cleanupTests(servers)
447 })
448 })