diff options
Diffstat (limited to 'server')
-rw-r--r-- | server/controllers/bots.ts | 2 | ||||
-rw-r--r-- | server/controllers/client.ts | 4 | ||||
-rw-r--r-- | server/controllers/feeds.ts | 2 | ||||
-rw-r--r-- | server/middlewares/validators/oembed.ts | 24 | ||||
-rw-r--r-- | server/models/video/video-playlist.ts | 2 | ||||
-rw-r--r-- | server/models/video/video.ts | 2 | ||||
-rw-r--r-- | server/tests/api/server/services.ts | 104 | ||||
-rw-r--r-- | server/tests/client.ts | 196 | ||||
-rw-r--r-- | server/tools/peertube-watch.ts | 2 |
9 files changed, 191 insertions, 147 deletions
diff --git a/server/controllers/bots.ts b/server/controllers/bots.ts index 8d1fa72f3..9e92063d4 100644 --- a/server/controllers/bots.ts +++ b/server/controllers/bots.ts | |||
@@ -75,7 +75,7 @@ async function getSitemapLocalVideoUrls () { | |||
75 | }) | 75 | }) |
76 | 76 | ||
77 | return data.map(v => ({ | 77 | return data.map(v => ({ |
78 | url: WEBSERVER.URL + '/videos/watch/' + v.uuid, | 78 | url: WEBSERVER.URL + '/w/' + v.uuid, |
79 | video: [ | 79 | video: [ |
80 | { | 80 | { |
81 | title: v.name, | 81 | title: v.name, |
diff --git a/server/controllers/client.ts b/server/controllers/client.ts index 35e5af9d1..fcccc48e0 100644 --- a/server/controllers/client.ts +++ b/server/controllers/client.ts | |||
@@ -19,8 +19,8 @@ const testEmbedPath = join(distPath, 'standalone', 'videos', 'test-embed.html') | |||
19 | 19 | ||
20 | // Special route that add OpenGraph and oEmbed tags | 20 | // Special route that add OpenGraph and oEmbed tags |
21 | // Do not use a template engine for a so little thing | 21 | // Do not use a template engine for a so little thing |
22 | clientsRouter.use('/videos/watch/playlist/:id', asyncMiddleware(generateWatchPlaylistHtmlPage)) | 22 | clientsRouter.use([ '/w/p/:id', '/videos/watch/playlist/:id' ], asyncMiddleware(generateWatchPlaylistHtmlPage)) |
23 | clientsRouter.use('/videos/watch/:id', asyncMiddleware(generateWatchHtmlPage)) | 23 | clientsRouter.use([ '/w/:id', '/videos/watch/:id' ], asyncMiddleware(generateWatchHtmlPage)) |
24 | clientsRouter.use([ '/accounts/:nameWithHost', '/a/:nameWithHost' ], asyncMiddleware(generateAccountHtmlPage)) | 24 | clientsRouter.use([ '/accounts/:nameWithHost', '/a/:nameWithHost' ], asyncMiddleware(generateAccountHtmlPage)) |
25 | clientsRouter.use([ '/video-channels/:nameWithHost', '/c/:nameWithHost' ], asyncMiddleware(generateVideoChannelHtmlPage)) | 25 | clientsRouter.use([ '/video-channels/:nameWithHost', '/c/:nameWithHost' ], asyncMiddleware(generateVideoChannelHtmlPage)) |
26 | clientsRouter.use('/@:nameWithHost', asyncMiddleware(generateActorHtmlPage)) | 26 | clientsRouter.use('/@:nameWithHost', asyncMiddleware(generateActorHtmlPage)) |
diff --git a/server/controllers/feeds.ts b/server/controllers/feeds.ts index f0717bbbc..865f5c2a1 100644 --- a/server/controllers/feeds.ts +++ b/server/controllers/feeds.ts | |||
@@ -293,7 +293,7 @@ function addVideosToFeed (feed, videos: VideoModel[]) { | |||
293 | feed.addItem({ | 293 | feed.addItem({ |
294 | title: video.name, | 294 | title: video.name, |
295 | id: video.url, | 295 | id: video.url, |
296 | link: WEBSERVER.URL + '/videos/watch/' + video.uuid, | 296 | link: WEBSERVER.URL + '/w/' + video.uuid, |
297 | description: video.getTruncatedDescription(), | 297 | description: video.getTruncatedDescription(), |
298 | content: video.description, | 298 | content: video.description, |
299 | author: [ | 299 | author: [ |
diff --git a/server/middlewares/validators/oembed.ts b/server/middlewares/validators/oembed.ts index 2a7dc257b..165eda6d5 100644 --- a/server/middlewares/validators/oembed.ts +++ b/server/middlewares/validators/oembed.ts | |||
@@ -4,15 +4,29 @@ import { join } from 'path' | |||
4 | import { fetchVideo } from '@server/helpers/video' | 4 | import { fetchVideo } from '@server/helpers/video' |
5 | import { VideoPlaylistModel } from '@server/models/video/video-playlist' | 5 | import { VideoPlaylistModel } from '@server/models/video/video-playlist' |
6 | import { VideoPlaylistPrivacy, VideoPrivacy } from '@shared/models' | 6 | import { VideoPlaylistPrivacy, VideoPrivacy } from '@shared/models' |
7 | import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' | ||
7 | import { isTestInstance } from '../../helpers/core-utils' | 8 | import { isTestInstance } from '../../helpers/core-utils' |
8 | import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc' | 9 | import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc' |
9 | import { logger } from '../../helpers/logger' | 10 | import { logger } from '../../helpers/logger' |
10 | import { WEBSERVER } from '../../initializers/constants' | 11 | import { WEBSERVER } from '../../initializers/constants' |
11 | import { areValidationErrors } from './utils' | 12 | import { areValidationErrors } from './utils' |
12 | import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' | ||
13 | 13 | ||
14 | const startVideoPlaylistsURL = WEBSERVER.SCHEME + '://' + join(WEBSERVER.HOST, 'videos', 'watch', 'playlist') + '/' | 14 | const playlistPaths = [ |
15 | const startVideosURL = WEBSERVER.SCHEME + '://' + join(WEBSERVER.HOST, 'videos', 'watch') + '/' | 15 | join('videos', 'watch', 'playlist'), |
16 | join('w', 'p') | ||
17 | ] | ||
18 | |||
19 | const videoPaths = [ | ||
20 | join('videos', 'watch'), | ||
21 | 'w' | ||
22 | ] | ||
23 | |||
24 | function buildUrls (paths: string[]) { | ||
25 | return paths.map(p => WEBSERVER.SCHEME + '://' + join(WEBSERVER.HOST, p) + '/') | ||
26 | } | ||
27 | |||
28 | const startPlaylistURLs = buildUrls(playlistPaths) | ||
29 | const startVideoURLs = buildUrls(videoPaths) | ||
16 | 30 | ||
17 | const watchRegex = /([^/]+)$/ | 31 | const watchRegex = /([^/]+)$/ |
18 | const isURLOptions = { | 32 | const isURLOptions = { |
@@ -43,8 +57,8 @@ const oembedValidator = [ | |||
43 | 57 | ||
44 | const url = req.query.url as string | 58 | const url = req.query.url as string |
45 | 59 | ||
46 | const isPlaylist = url.startsWith(startVideoPlaylistsURL) | 60 | const isPlaylist = startPlaylistURLs.some(u => url.startsWith(u)) |
47 | const isVideo = isPlaylist ? false : url.startsWith(startVideosURL) | 61 | const isVideo = isPlaylist ? false : startVideoURLs.some(u => url.startsWith(u)) |
48 | 62 | ||
49 | const startIsOk = isVideo || isPlaylist | 63 | const startIsOk = isVideo || isPlaylist |
50 | 64 | ||
diff --git a/server/models/video/video-playlist.ts b/server/models/video/video-playlist.ts index c293287d3..98cea1b64 100644 --- a/server/models/video/video-playlist.ts +++ b/server/models/video/video-playlist.ts | |||
@@ -496,7 +496,7 @@ export class VideoPlaylistModel extends Model<Partial<AttributesOnly<VideoPlayli | |||
496 | } | 496 | } |
497 | 497 | ||
498 | getWatchUrl () { | 498 | getWatchUrl () { |
499 | return WEBSERVER.URL + '/videos/watch/playlist/' + this.uuid | 499 | return WEBSERVER.URL + '/w/p/' + this.uuid |
500 | } | 500 | } |
501 | 501 | ||
502 | getEmbedStaticPath () { | 502 | getEmbedStaticPath () { |
diff --git a/server/models/video/video.ts b/server/models/video/video.ts index d4a258187..5af907533 100644 --- a/server/models/video/video.ts +++ b/server/models/video/video.ts | |||
@@ -1920,7 +1920,7 @@ export class VideoModel extends Model<Partial<AttributesOnly<VideoModel>>> { | |||
1920 | } | 1920 | } |
1921 | 1921 | ||
1922 | getWatchStaticPath () { | 1922 | getWatchStaticPath () { |
1923 | return '/videos/watch/' + this.uuid | 1923 | return '/w/' + this.uuid |
1924 | } | 1924 | } |
1925 | 1925 | ||
1926 | getEmbedStaticPath () { | 1926 | getEmbedStaticPath () { |
diff --git a/server/tests/api/server/services.ts b/server/tests/api/server/services.ts index f0fa91674..ea64e4040 100644 --- a/server/tests/api/server/services.ts +++ b/server/tests/api/server/services.ts | |||
@@ -67,61 +67,67 @@ describe('Test services', function () { | |||
67 | }) | 67 | }) |
68 | 68 | ||
69 | it('Should have a valid oEmbed video response', async function () { | 69 | it('Should have a valid oEmbed video response', async function () { |
70 | const oembedUrl = 'http://localhost:' + server.port + '/videos/watch/' + video.uuid | 70 | for (const basePath of [ '/videos/watch/', '/w/' ]) { |
71 | 71 | const oembedUrl = 'http://localhost:' + server.port + basePath + video.uuid | |
72 | const res = await getOEmbed(server.url, oembedUrl) | 72 | |
73 | const expectedHtml = '<iframe width="560" height="315" sandbox="allow-same-origin allow-scripts" ' + | 73 | const res = await getOEmbed(server.url, oembedUrl) |
74 | `title="${video.name}" src="http://localhost:${server.port}/videos/embed/${video.uuid}" ` + | 74 | const expectedHtml = '<iframe width="560" height="315" sandbox="allow-same-origin allow-scripts" ' + |
75 | 'frameborder="0" allowfullscreen></iframe>' | 75 | `title="${video.name}" src="http://localhost:${server.port}/videos/embed/${video.uuid}" ` + |
76 | const expectedThumbnailUrl = 'http://localhost:' + server.port + video.previewPath | 76 | 'frameborder="0" allowfullscreen></iframe>' |
77 | 77 | const expectedThumbnailUrl = 'http://localhost:' + server.port + video.previewPath | |
78 | expect(res.body.html).to.equal(expectedHtml) | 78 | |
79 | expect(res.body.title).to.equal(video.name) | 79 | expect(res.body.html).to.equal(expectedHtml) |
80 | expect(res.body.author_name).to.equal(server.videoChannel.displayName) | 80 | expect(res.body.title).to.equal(video.name) |
81 | expect(res.body.width).to.equal(560) | 81 | expect(res.body.author_name).to.equal(server.videoChannel.displayName) |
82 | expect(res.body.height).to.equal(315) | 82 | expect(res.body.width).to.equal(560) |
83 | expect(res.body.thumbnail_url).to.equal(expectedThumbnailUrl) | 83 | expect(res.body.height).to.equal(315) |
84 | expect(res.body.thumbnail_width).to.equal(850) | 84 | expect(res.body.thumbnail_url).to.equal(expectedThumbnailUrl) |
85 | expect(res.body.thumbnail_height).to.equal(480) | 85 | expect(res.body.thumbnail_width).to.equal(850) |
86 | expect(res.body.thumbnail_height).to.equal(480) | ||
87 | } | ||
86 | }) | 88 | }) |
87 | 89 | ||
88 | it('Should have a valid playlist oEmbed response', async function () { | 90 | it('Should have a valid playlist oEmbed response', async function () { |
89 | const oembedUrl = 'http://localhost:' + server.port + '/videos/watch/playlist/' + playlistUUID | 91 | for (const basePath of [ '/videos/watch/playlist/', '/w/p/' ]) { |
90 | 92 | const oembedUrl = 'http://localhost:' + server.port + basePath + playlistUUID | |
91 | const res = await getOEmbed(server.url, oembedUrl) | 93 | |
92 | const expectedHtml = '<iframe width="560" height="315" sandbox="allow-same-origin allow-scripts" ' + | 94 | const res = await getOEmbed(server.url, oembedUrl) |
93 | `title="${playlistDisplayName}" src="http://localhost:${server.port}/video-playlists/embed/${playlistUUID}" ` + | 95 | const expectedHtml = '<iframe width="560" height="315" sandbox="allow-same-origin allow-scripts" ' + |
94 | 'frameborder="0" allowfullscreen></iframe>' | 96 | `title="${playlistDisplayName}" src="http://localhost:${server.port}/video-playlists/embed/${playlistUUID}" ` + |
95 | 97 | 'frameborder="0" allowfullscreen></iframe>' | |
96 | expect(res.body.html).to.equal(expectedHtml) | 98 | |
97 | expect(res.body.title).to.equal('The Life and Times of Scrooge McDuck') | 99 | expect(res.body.html).to.equal(expectedHtml) |
98 | expect(res.body.author_name).to.equal(server.videoChannel.displayName) | 100 | expect(res.body.title).to.equal('The Life and Times of Scrooge McDuck') |
99 | expect(res.body.width).to.equal(560) | 101 | expect(res.body.author_name).to.equal(server.videoChannel.displayName) |
100 | expect(res.body.height).to.equal(315) | 102 | expect(res.body.width).to.equal(560) |
101 | expect(res.body.thumbnail_url).exist | 103 | expect(res.body.height).to.equal(315) |
102 | expect(res.body.thumbnail_width).to.equal(280) | 104 | expect(res.body.thumbnail_url).exist |
103 | expect(res.body.thumbnail_height).to.equal(157) | 105 | expect(res.body.thumbnail_width).to.equal(280) |
106 | expect(res.body.thumbnail_height).to.equal(157) | ||
107 | } | ||
104 | }) | 108 | }) |
105 | 109 | ||
106 | it('Should have a valid oEmbed response with small max height query', async function () { | 110 | it('Should have a valid oEmbed response with small max height query', async function () { |
107 | const oembedUrl = 'http://localhost:' + server.port + '/videos/watch/' + video.uuid | 111 | for (const basePath of [ '/videos/watch/', '/w/' ]) { |
108 | const format = 'json' | 112 | const oembedUrl = 'http://localhost:' + server.port + basePath + video.uuid |
109 | const maxHeight = 50 | 113 | const format = 'json' |
110 | const maxWidth = 50 | 114 | const maxHeight = 50 |
111 | 115 | const maxWidth = 50 | |
112 | const res = await getOEmbed(server.url, oembedUrl, format, maxHeight, maxWidth) | 116 | |
113 | const expectedHtml = '<iframe width="50" height="50" sandbox="allow-same-origin allow-scripts" ' + | 117 | const res = await getOEmbed(server.url, oembedUrl, format, maxHeight, maxWidth) |
114 | `title="${video.name}" src="http://localhost:${server.port}/videos/embed/${video.uuid}" ` + | 118 | const expectedHtml = '<iframe width="50" height="50" sandbox="allow-same-origin allow-scripts" ' + |
115 | 'frameborder="0" allowfullscreen></iframe>' | 119 | `title="${video.name}" src="http://localhost:${server.port}/videos/embed/${video.uuid}" ` + |
116 | 120 | 'frameborder="0" allowfullscreen></iframe>' | |
117 | expect(res.body.html).to.equal(expectedHtml) | 121 | |
118 | expect(res.body.title).to.equal(video.name) | 122 | expect(res.body.html).to.equal(expectedHtml) |
119 | expect(res.body.author_name).to.equal(server.videoChannel.displayName) | 123 | expect(res.body.title).to.equal(video.name) |
120 | expect(res.body.height).to.equal(50) | 124 | expect(res.body.author_name).to.equal(server.videoChannel.displayName) |
121 | expect(res.body.width).to.equal(50) | 125 | expect(res.body.height).to.equal(50) |
122 | expect(res.body).to.not.have.property('thumbnail_url') | 126 | expect(res.body.width).to.equal(50) |
123 | expect(res.body).to.not.have.property('thumbnail_width') | 127 | expect(res.body).to.not.have.property('thumbnail_url') |
124 | expect(res.body).to.not.have.property('thumbnail_height') | 128 | expect(res.body).to.not.have.property('thumbnail_width') |
129 | expect(res.body).to.not.have.property('thumbnail_height') | ||
130 | } | ||
125 | }) | 131 | }) |
126 | 132 | ||
127 | after(async function () { | 133 | after(async function () { |
diff --git a/server/tests/client.ts b/server/tests/client.ts index f33e5c1da..253a95624 100644 --- a/server/tests/client.ts +++ b/server/tests/client.ts | |||
@@ -54,6 +54,9 @@ describe('Test a client controllers', function () { | |||
54 | 54 | ||
55 | const channelDescription = 'my super channel description' | 55 | const channelDescription = 'my super channel description' |
56 | 56 | ||
57 | const watchVideoBasePaths = [ '/videos/watch/', '/w/' ] | ||
58 | const watchPlaylistBasePaths = [ '/videos/watch/playlist/', '/w/p/' ] | ||
59 | |||
57 | before(async function () { | 60 | before(async function () { |
58 | this.timeout(120000) | 61 | this.timeout(120000) |
59 | 62 | ||
@@ -111,35 +114,40 @@ describe('Test a client controllers', function () { | |||
111 | }) | 114 | }) |
112 | 115 | ||
113 | describe('oEmbed', function () { | 116 | describe('oEmbed', function () { |
117 | |||
114 | it('Should have valid oEmbed discovery tags for videos', async function () { | 118 | it('Should have valid oEmbed discovery tags for videos', async function () { |
115 | const path = '/videos/watch/' + servers[0].video.uuid | 119 | for (const basePath of watchVideoBasePaths) { |
116 | const res = await request(servers[0].url) | 120 | const path = basePath + servers[0].video.uuid |
117 | .get(path) | 121 | const res = await request(servers[0].url) |
118 | .set('Accept', 'text/html') | 122 | .get(path) |
119 | .expect(HttpStatusCode.OK_200) | 123 | .set('Accept', 'text/html') |
124 | .expect(HttpStatusCode.OK_200) | ||
120 | 125 | ||
121 | const port = servers[0].port | 126 | const port = servers[0].port |
122 | 127 | ||
123 | const expectedLink = '<link rel="alternate" type="application/json+oembed" href="http://localhost:' + port + '/services/oembed?' + | 128 | const expectedLink = '<link rel="alternate" type="application/json+oembed" href="http://localhost:' + port + '/services/oembed?' + |
124 | `url=http%3A%2F%2Flocalhost%3A${port}%2Fvideos%2Fwatch%2F${servers[0].video.uuid}" ` + | 129 | `url=http%3A%2F%2Flocalhost%3A${port}%2Fw%2F${servers[0].video.uuid}" ` + |
125 | `title="${servers[0].video.name}" />` | 130 | `title="${servers[0].video.name}" />` |
126 | 131 | ||
127 | expect(res.text).to.contain(expectedLink) | 132 | expect(res.text).to.contain(expectedLink) |
133 | } | ||
128 | }) | 134 | }) |
129 | 135 | ||
130 | it('Should have valid oEmbed discovery tags for a playlist', async function () { | 136 | it('Should have valid oEmbed discovery tags for a playlist', async function () { |
131 | const res = await request(servers[0].url) | 137 | for (const basePath of watchPlaylistBasePaths) { |
132 | .get('/videos/watch/playlist/' + playlistUUID) | 138 | const res = await request(servers[0].url) |
133 | .set('Accept', 'text/html') | 139 | .get(basePath + playlistUUID) |
134 | .expect(HttpStatusCode.OK_200) | 140 | .set('Accept', 'text/html') |
141 | .expect(HttpStatusCode.OK_200) | ||
135 | 142 | ||
136 | const port = servers[0].port | 143 | const port = servers[0].port |
137 | 144 | ||
138 | const expectedLink = '<link rel="alternate" type="application/json+oembed" href="http://localhost:' + port + '/services/oembed?' + | 145 | const expectedLink = '<link rel="alternate" type="application/json+oembed" href="http://localhost:' + port + '/services/oembed?' + |
139 | `url=http%3A%2F%2Flocalhost%3A${port}%2Fvideos%2Fwatch%2Fplaylist%2F${playlistUUID}" ` + | 146 | `url=http%3A%2F%2Flocalhost%3A${port}%2Fw%2Fp%2F${playlistUUID}" ` + |
140 | `title="${playlistName}" />` | 147 | `title="${playlistName}" />` |
141 | 148 | ||
142 | expect(res.text).to.contain(expectedLink) | 149 | expect(res.text).to.contain(expectedLink) |
150 | } | ||
143 | }) | 151 | }) |
144 | }) | 152 | }) |
145 | 153 | ||
@@ -165,6 +173,26 @@ describe('Test a client controllers', function () { | |||
165 | expect(text).to.contain(`<meta property="og:url" content="${servers[0].url}/video-channels/${servers[0].videoChannel.name}" />`) | 173 | expect(text).to.contain(`<meta property="og:url" content="${servers[0].url}/video-channels/${servers[0].videoChannel.name}" />`) |
166 | } | 174 | } |
167 | 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 | |||
168 | it('Should have valid Open Graph tags on the account page', async function () { | 196 | it('Should have valid Open Graph tags on the account page', async function () { |
169 | await accountPageTest('/accounts/' + servers[0].user.username) | 197 | await accountPageTest('/accounts/' + servers[0].user.username) |
170 | await accountPageTest('/a/' + servers[0].user.username) | 198 | await accountPageTest('/a/' + servers[0].user.username) |
@@ -177,40 +205,16 @@ describe('Test a client controllers', function () { | |||
177 | await channelPageTest('/@' + servers[0].videoChannel.name) | 205 | await channelPageTest('/@' + servers[0].videoChannel.name) |
178 | }) | 206 | }) |
179 | 207 | ||
180 | it('Should have valid Open Graph tags on the watch page with video id', async function () { | 208 | it('Should have valid Open Graph tags on the watch page', async function () { |
181 | const res = await request(servers[0].url) | 209 | await watchVideoPageTest('/videos/watch/' + servers[0].video.id) |
182 | .get('/videos/watch/' + servers[0].video.id) | 210 | await watchVideoPageTest('/videos/watch/' + servers[0].video.uuid) |
183 | .set('Accept', 'text/html') | 211 | await watchVideoPageTest('/w/' + servers[0].video.uuid) |
184 | .expect(HttpStatusCode.OK_200) | 212 | await watchVideoPageTest('/w/' + servers[0].video.id) |
185 | |||
186 | expect(res.text).to.contain(`<meta property="og:title" content="${videoName}" />`) | ||
187 | expect(res.text).to.contain(`<meta property="og:description" content="${videoDescriptionPlainText}" />`) | ||
188 | expect(res.text).to.contain('<meta property="og:type" content="video" />') | ||
189 | expect(res.text).to.contain(`<meta property="og:url" content="${servers[0].url}/videos/watch/${servers[0].video.uuid}" />`) | ||
190 | }) | ||
191 | |||
192 | it('Should have valid Open Graph tags on the watch page with video uuid', async function () { | ||
193 | const res = await request(servers[0].url) | ||
194 | .get('/videos/watch/' + servers[0].video.uuid) | ||
195 | .set('Accept', 'text/html') | ||
196 | .expect(HttpStatusCode.OK_200) | ||
197 | |||
198 | expect(res.text).to.contain(`<meta property="og:title" content="${videoName}" />`) | ||
199 | expect(res.text).to.contain(`<meta property="og:description" content="${videoDescriptionPlainText}" />`) | ||
200 | expect(res.text).to.contain('<meta property="og:type" content="video" />') | ||
201 | expect(res.text).to.contain(`<meta property="og:url" content="${servers[0].url}/videos/watch/${servers[0].video.uuid}" />`) | ||
202 | }) | 213 | }) |
203 | 214 | ||
204 | it('Should have valid Open Graph tags on the watch playlist page', async function () { | 215 | it('Should have valid Open Graph tags on the watch playlist page', async function () { |
205 | const res = await request(servers[0].url) | 216 | await watchPlaylistPageTest('/videos/watch/playlist/' + playlistUUID) |
206 | .get('/videos/watch/playlist/' + playlistUUID) | 217 | await watchPlaylistPageTest('/w/p/' + playlistUUID) |
207 | .set('Accept', 'text/html') | ||
208 | .expect(HttpStatusCode.OK_200) | ||
209 | |||
210 | expect(res.text).to.contain(`<meta property="og:title" content="${playlistName}" />`) | ||
211 | expect(res.text).to.contain(`<meta property="og:description" content="${playlistDescription}" />`) | ||
212 | expect(res.text).to.contain('<meta property="og:type" content="video" />') | ||
213 | expect(res.text).to.contain(`<meta property="og:url" content="${servers[0].url}/videos/watch/playlist/${playlistUUID}" />`) | ||
214 | }) | 218 | }) |
215 | }) | 219 | }) |
216 | 220 | ||
@@ -238,28 +242,36 @@ describe('Test a client controllers', function () { | |||
238 | expect(text).to.contain(`<meta property="twitter:description" content="${channelDescription}" />`) | 242 | expect(text).to.contain(`<meta property="twitter:description" content="${channelDescription}" />`) |
239 | } | 243 | } |
240 | 244 | ||
241 | it('Should have valid twitter card on the watch video page', async function () { | 245 | async function watchVideoPageTest (path: string) { |
242 | const res = await request(servers[0].url) | 246 | const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', statusCodeExpected: HttpStatusCode.OK_200 }) |
243 | .get('/videos/watch/' + servers[0].video.uuid) | 247 | const text = res.text |
244 | .set('Accept', 'text/html') | ||
245 | .expect(HttpStatusCode.OK_200) | ||
246 | 248 | ||
247 | expect(res.text).to.contain('<meta property="twitter:card" content="summary_large_image" />') | 249 | expect(text).to.contain('<meta property="twitter:card" content="summary_large_image" />') |
248 | expect(res.text).to.contain('<meta property="twitter:site" content="@Chocobozzz" />') | 250 | expect(text).to.contain('<meta property="twitter:site" content="@Chocobozzz" />') |
249 | expect(res.text).to.contain(`<meta property="twitter:title" content="${videoName}" />`) | 251 | expect(text).to.contain(`<meta property="twitter:title" content="${videoName}" />`) |
250 | expect(res.text).to.contain(`<meta property="twitter:description" content="${videoDescriptionPlainText}" />`) | 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) | ||
251 | }) | 270 | }) |
252 | 271 | ||
253 | it('Should have valid twitter card on the watch playlist page', async function () { | 272 | it('Should have valid twitter card on the watch playlist page', async function () { |
254 | const res = await request(servers[0].url) | 273 | await watchPlaylistPageTest('/videos/watch/playlist/' + playlistUUID) |
255 | .get('/videos/watch/playlist/' + playlistUUID) | 274 | await watchPlaylistPageTest('/w/p/' + playlistUUID) |
256 | .set('Accept', 'text/html') | ||
257 | .expect(HttpStatusCode.OK_200) | ||
258 | |||
259 | expect(res.text).to.contain('<meta property="twitter:card" content="summary" />') | ||
260 | expect(res.text).to.contain('<meta property="twitter:site" content="@Chocobozzz" />') | ||
261 | expect(res.text).to.contain(`<meta property="twitter:title" content="${playlistName}" />`) | ||
262 | expect(res.text).to.contain(`<meta property="twitter:description" content="${playlistDescription}" />`) | ||
263 | }) | 275 | }) |
264 | 276 | ||
265 | it('Should have valid twitter card on the account page', async function () { | 277 | it('Should have valid twitter card on the account page', async function () { |
@@ -304,24 +316,32 @@ describe('Test a client controllers', function () { | |||
304 | expect(text).to.contain('<meta property="twitter:site" content="@Kuja" />') | 316 | expect(text).to.contain('<meta property="twitter:site" content="@Kuja" />') |
305 | } | 317 | } |
306 | 318 | ||
307 | it('Should have valid twitter card on the watch video page', async function () { | 319 | async function watchVideoPageTest (path: string) { |
308 | const res = await request(servers[0].url) | 320 | const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', statusCodeExpected: HttpStatusCode.OK_200 }) |
309 | .get('/videos/watch/' + servers[0].video.uuid) | 321 | const text = res.text |
310 | .set('Accept', 'text/html') | ||
311 | .expect(HttpStatusCode.OK_200) | ||
312 | 322 | ||
313 | expect(res.text).to.contain('<meta property="twitter:card" content="player" />') | 323 | expect(text).to.contain('<meta property="twitter:card" content="player" />') |
314 | expect(res.text).to.contain('<meta property="twitter:site" content="@Kuja" />') | 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) | ||
315 | }) | 340 | }) |
316 | 341 | ||
317 | it('Should have valid twitter card on the watch playlist page', async function () { | 342 | it('Should have valid twitter card on the watch playlist page', async function () { |
318 | const res = await request(servers[0].url) | 343 | await watchPlaylistPageTest('/videos/watch/playlist/' + playlistUUID) |
319 | .get('/videos/watch/playlist/' + playlistUUID) | 344 | await watchPlaylistPageTest('/w/p/' + playlistUUID) |
320 | .set('Accept', 'text/html') | ||
321 | .expect(HttpStatusCode.OK_200) | ||
322 | |||
323 | expect(res.text).to.contain('<meta property="twitter:card" content="player" />') | ||
324 | expect(res.text).to.contain('<meta property="twitter:site" content="@Kuja" />') | ||
325 | }) | 345 | }) |
326 | 346 | ||
327 | it('Should have valid twitter card on the account page', async function () { | 347 | it('Should have valid twitter card on the account page', async function () { |
@@ -378,8 +398,10 @@ describe('Test a client controllers', function () { | |||
378 | }) | 398 | }) |
379 | 399 | ||
380 | it('Should use the original video URL for the canonical tag', async function () { | 400 | it('Should use the original video URL for the canonical tag', async function () { |
381 | const res = await makeHTMLRequest(servers[1].url, '/videos/watch/' + servers[0].video.uuid) | 401 | for (const basePath of watchVideoBasePaths) { |
382 | expect(res.text).to.contain(`<link rel="canonical" href="${servers[0].url}/videos/watch/${servers[0].video.uuid}" />`) | 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 | } | ||
383 | }) | 405 | }) |
384 | 406 | ||
385 | it('Should use the original account URL for the canonical tag', async function () { | 407 | it('Should use the original account URL for the canonical tag', async function () { |
@@ -403,8 +425,10 @@ describe('Test a client controllers', function () { | |||
403 | }) | 425 | }) |
404 | 426 | ||
405 | it('Should use the original playlist URL for the canonical tag', async function () { | 427 | it('Should use the original playlist URL for the canonical tag', async function () { |
406 | const res = await makeHTMLRequest(servers[1].url, '/videos/watch/playlist/' + playlistUUID) | 428 | for (const basePath of watchPlaylistBasePaths) { |
407 | expect(res.text).to.contain(`<link rel="canonical" href="${servers[0].url}/video-playlists/${playlistUUID}" />`) | 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 | } | ||
408 | }) | 432 | }) |
409 | }) | 433 | }) |
410 | 434 | ||
diff --git a/server/tools/peertube-watch.ts b/server/tools/peertube-watch.ts index 6d9cfa3b7..3ca3e242a 100644 --- a/server/tools/peertube-watch.ts +++ b/server/tools/peertube-watch.ts | |||
@@ -30,7 +30,7 @@ function run (url: string, options: program.OptionValues) { | |||
30 | 30 | ||
31 | const cmd = 'node ' + join(__dirname, 'node_modules', 'webtorrent-hybrid', 'bin', 'cmd.js') | 31 | const cmd = 'node ' + join(__dirname, 'node_modules', 'webtorrent-hybrid', 'bin', 'cmd.js') |
32 | const args = ` --${options.gui} ` + | 32 | const args = ` --${options.gui} ` + |
33 | url.replace('videos/watch', 'download/torrents') + | 33 | url.replace(/(\/videos\/watch\/)|\/w\//, '/download/torrents/') + |
34 | `-${options.resolution}.torrent` | 34 | `-${options.resolution}.torrent` |
35 | 35 | ||
36 | try { | 36 | try { |