1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
4 import * as chai from 'chai'
5 import * as request from 'supertest'
6 import { Account, VideoPlaylistPrivacy } from '@shared/models'
18 setDefaultVideoChannel,
20 updateCustomSubConfig,
24 } from '../../shared/extra-utils'
26 const expect = chai.expect
28 function checkIndexTags (html: string, title: string, description: string, css: string) {
29 expect(html).to.contain('<title>' + title + '</title>')
30 expect(html).to.contain('<meta name="description" content="' + description + '" />')
31 expect(html).to.contain('<style class="custom-css-style">' + css + '</style>')
34 describe('Test a client controllers', function () {
35 let server: ServerInfo
38 const videoName = 'my super name for server 1'
39 const videoDescription = 'my super description for server 1'
41 const playlistName = 'super playlist name'
42 const playlistDescription = 'super playlist description'
43 let playlistUUID: string
45 const channelDescription = 'my super channel description'
47 before(async function () {
50 server = await flushAndRunServer(1)
51 server.accessToken = await serverLogin(server)
52 await setDefaultVideoChannel([ server ])
54 await updateVideoChannel(server.url, server.accessToken, server.videoChannel.name, { description: channelDescription })
58 const videoAttributes = { name: videoName, description: videoDescription }
59 await uploadVideo(server.url, server.accessToken, videoAttributes)
61 const resVideosRequest = await getVideosList(server.url)
62 const videos = resVideosRequest.body.data
63 expect(videos.length).to.equal(1)
65 server.video = videos[0]
69 const playlistAttrs = {
70 displayName: playlistName,
71 description: playlistDescription,
72 privacy: VideoPlaylistPrivacy.PUBLIC,
73 videoChannelId: server.videoChannel.id
76 const resVideoPlaylistRequest = await createVideoPlaylist({ url: server.url, token: server.accessToken, playlistAttrs })
78 const playlist = resVideoPlaylistRequest.body.videoPlaylist
79 const playlistId = playlist.id
80 playlistUUID = playlist.uuid
82 await addVideoInPlaylist({
84 token: server.accessToken,
86 elementAttrs: { videoId: server.video.id }
91 await updateMyUser({ url: server.url, accessToken: server.accessToken, description: 'my account description' })
93 const resAccountRequest = await getAccount(server.url, `${server.user.username}@${server.host}`)
94 account = resAccountRequest.body
97 it('Should have valid Open Graph tags on the watch page with video id', async function () {
98 const res = await request(server.url)
99 .get('/videos/watch/' + server.video.id)
100 .set('Accept', 'text/html')
103 expect(res.text).to.contain(`<meta property="og:title" content="${videoName}" />`)
104 expect(res.text).to.contain(`<meta property="og:description" content="${videoDescription}" />`)
105 expect(res.text).to.contain('<meta property="og:type" content="video" />')
106 expect(res.text).to.contain(`<meta property="og:url" content="${server.url}/videos/watch/${server.video.uuid}" />`)
109 it('Should have valid Open Graph tags on the watch page with video uuid', async function () {
110 const res = await request(server.url)
111 .get('/videos/watch/' + server.video.uuid)
112 .set('Accept', 'text/html')
115 expect(res.text).to.contain(`<meta property="og:title" content="${videoName}" />`)
116 expect(res.text).to.contain(`<meta property="og:description" content="${videoDescription}" />`)
117 expect(res.text).to.contain('<meta property="og:type" content="video" />')
118 expect(res.text).to.contain(`<meta property="og:url" content="${server.url}/videos/watch/${server.video.uuid}" />`)
121 it('Should have valid Open Graph tags on the watch playlist page', async function () {
122 const res = await request(server.url)
123 .get('/videos/watch/playlist/' + playlistUUID)
124 .set('Accept', 'text/html')
127 expect(res.text).to.contain(`<meta property="og:title" content="${playlistName}" />`)
128 expect(res.text).to.contain(`<meta property="og:description" content="${playlistDescription}" />`)
129 expect(res.text).to.contain('<meta property="og:type" content="video" />')
130 expect(res.text).to.contain(`<meta property="og:url" content="${server.url}/videos/watch/playlist/${playlistUUID}" />`)
133 it('Should have valid Open Graph tags on the account page', async function () {
134 const res = await request(server.url)
135 .get('/accounts/' + server.user.username)
136 .set('Accept', 'text/html')
139 expect(res.text).to.contain(`<meta property="og:title" content="${account.displayName}" />`)
140 expect(res.text).to.contain(`<meta property="og:description" content="${account.description}" />`)
141 expect(res.text).to.contain('<meta property="og:type" content="website" />')
142 expect(res.text).to.contain(`<meta property="og:url" content="${server.url}/accounts/${server.user.username}" />`)
145 it('Should have valid Open Graph tags on the channel page', async function () {
146 const res = await request(server.url)
147 .get('/video-channels/' + server.videoChannel.name)
148 .set('Accept', 'text/html')
151 expect(res.text).to.contain(`<meta property="og:title" content="${server.videoChannel.displayName}" />`)
152 expect(res.text).to.contain(`<meta property="og:description" content="${channelDescription}" />`)
153 expect(res.text).to.contain('<meta property="og:type" content="website" />')
154 expect(res.text).to.contain(`<meta property="og:url" content="${server.url}/video-channels/${server.videoChannel.name}" />`)
157 it('Should have valid oEmbed discovery tags', async function () {
158 const path = '/videos/watch/' + server.video.uuid
159 const res = await request(server.url)
161 .set('Accept', 'text/html')
164 const port = server.port
166 const expectedLink = '<link rel="alternate" type="application/json+oembed" href="http://localhost:' + port + '/services/oembed?' +
167 `url=http%3A%2F%2Flocalhost%3A${port}%2Fvideos%2Fwatch%2F${server.video.uuid}" ` +
168 `title="${server.video.name}" />`
170 expect(res.text).to.contain(expectedLink)
173 it('Should have valid twitter card on the watch video page', async function () {
174 const res = await request(server.url)
175 .get('/videos/watch/' + server.video.uuid)
176 .set('Accept', 'text/html')
179 expect(res.text).to.contain('<meta property="twitter:card" content="summary_large_image" />')
180 expect(res.text).to.contain('<meta property="twitter:site" content="@Chocobozzz" />')
181 expect(res.text).to.contain(`<meta property="twitter:title" content="${videoName}" />`)
182 expect(res.text).to.contain(`<meta property="twitter:description" content="${videoDescription}" />`)
185 it('Should have valid twitter card on the watch playlist page', async function () {
186 const res = await request(server.url)
187 .get('/videos/watch/playlist/' + playlistUUID)
188 .set('Accept', 'text/html')
191 expect(res.text).to.contain('<meta property="twitter:card" content="summary" />')
192 expect(res.text).to.contain('<meta property="twitter:site" content="@Chocobozzz" />')
193 expect(res.text).to.contain(`<meta property="twitter:title" content="${playlistName}" />`)
194 expect(res.text).to.contain(`<meta property="twitter:description" content="${playlistDescription}" />`)
197 it('Should have valid twitter card on the account page', async function () {
198 const res = await request(server.url)
199 .get('/accounts/' + account.name)
200 .set('Accept', 'text/html')
203 expect(res.text).to.contain('<meta property="twitter:card" content="summary" />')
204 expect(res.text).to.contain('<meta property="twitter:site" content="@Chocobozzz" />')
205 expect(res.text).to.contain(`<meta property="twitter:title" content="${account.name}" />`)
206 expect(res.text).to.contain(`<meta property="twitter:description" content="${account.description}" />`)
209 it('Should have valid twitter card on the channel page', async function () {
210 const res = await request(server.url)
211 .get('/video-channels/' + server.videoChannel.name)
212 .set('Accept', 'text/html')
215 expect(res.text).to.contain('<meta property="twitter:card" content="summary" />')
216 expect(res.text).to.contain('<meta property="twitter:site" content="@Chocobozzz" />')
217 expect(res.text).to.contain(`<meta property="twitter:title" content="${server.videoChannel.displayName}" />`)
218 expect(res.text).to.contain(`<meta property="twitter:description" content="${channelDescription}" />`)
221 it('Should have valid twitter card if Twitter is whitelisted', async function () {
222 const res1 = await getCustomConfig(server.url, server.accessToken)
223 const config = res1.body
224 config.services.twitter = {
228 await updateCustomConfig(server.url, server.accessToken, config)
230 const resVideoRequest = await request(server.url)
231 .get('/videos/watch/' + server.video.uuid)
232 .set('Accept', 'text/html')
235 expect(resVideoRequest.text).to.contain('<meta property="twitter:card" content="player" />')
236 expect(resVideoRequest.text).to.contain('<meta property="twitter:site" content="@Kuja" />')
238 const resVideoPlaylistRequest = await request(server.url)
239 .get('/videos/watch/playlist/' + playlistUUID)
240 .set('Accept', 'text/html')
243 expect(resVideoPlaylistRequest.text).to.contain('<meta property="twitter:card" content="summary" />')
244 expect(resVideoPlaylistRequest.text).to.contain('<meta property="twitter:site" content="@Kuja" />')
246 const resAccountRequest = await request(server.url)
247 .get('/accounts/' + account.name)
248 .set('Accept', 'text/html')
251 expect(resAccountRequest.text).to.contain('<meta property="twitter:card" content="summary" />')
252 expect(resAccountRequest.text).to.contain('<meta property="twitter:site" content="@Kuja" />')
254 const resChannelRequest = await request(server.url)
255 .get('/video-channels/' + server.videoChannel.name)
256 .set('Accept', 'text/html')
259 expect(resChannelRequest.text).to.contain('<meta property="twitter:card" content="summary" />')
260 expect(resChannelRequest.text).to.contain('<meta property="twitter:site" content="@Kuja" />')
263 it('Should have valid index html tags (title, description...)', async function () {
264 const res = await makeHTMLRequest(server.url, '/videos/trending')
266 const description = 'PeerTube, an ActivityPub-federated video streaming platform using P2P directly in your web browser.'
267 checkIndexTags(res.text, 'PeerTube', description, '')
270 it('Should update the customized configuration and have the correct index html tags', async function () {
271 await updateCustomSubConfig(server.url, server.accessToken, {
273 name: 'PeerTube updated',
274 shortDescription: 'my short description',
275 description: 'my super description',
276 terms: 'my super terms',
277 defaultClientRoute: '/videos/recently-added',
278 defaultNSFWPolicy: 'blur',
280 javascript: 'alert("coucou")',
281 css: 'body { background-color: red; }'
286 const res = await makeHTMLRequest(server.url, '/videos/trending')
288 checkIndexTags(res.text, 'PeerTube updated', 'my short description', 'body { background-color: red; }')
291 it('Should have valid index html updated tags (title, description...)', async function () {
292 const res = await makeHTMLRequest(server.url, '/videos/trending')
294 checkIndexTags(res.text, 'PeerTube updated', 'my short description', 'body { background-color: red; }')
297 after(async function () {
298 await cleanupTests([ server ])