diff options
-rw-r--r-- | server/lib/client-html.ts | 37 | ||||
-rw-r--r-- | server/models/account/account.ts | 32 | ||||
-rw-r--r-- | server/models/video/video-channel.ts | 5 | ||||
-rw-r--r-- | server/tests/client.ts | 148 | ||||
-rw-r--r-- | shared/extra-utils/server/servers.ts | 1 |
5 files changed, 139 insertions, 84 deletions
diff --git a/server/lib/client-html.ts b/server/lib/client-html.ts index 211ac3342..d97d23180 100644 --- a/server/lib/client-html.ts +++ b/server/lib/client-html.ts | |||
@@ -117,7 +117,16 @@ export class ClientHtml { | |||
117 | const schemaType = 'VideoObject' | 117 | const schemaType = 'VideoObject' |
118 | 118 | ||
119 | customHtml = ClientHtml.addTags(customHtml, { | 119 | customHtml = ClientHtml.addTags(customHtml, { |
120 | url, originUrl, siteName, title, description, image, embed, ogType, twitterCard, schemaType | 120 | url, |
121 | originUrl, | ||
122 | siteName, | ||
123 | title, | ||
124 | description, | ||
125 | image, | ||
126 | embed, | ||
127 | ogType, | ||
128 | twitterCard, | ||
129 | schemaType | ||
121 | }) | 130 | }) |
122 | 131 | ||
123 | return customHtml | 132 | return customHtml |
@@ -168,7 +177,17 @@ export class ClientHtml { | |||
168 | const schemaType = 'ItemList' | 177 | const schemaType = 'ItemList' |
169 | 178 | ||
170 | customHtml = ClientHtml.addTags(customHtml, { | 179 | customHtml = ClientHtml.addTags(customHtml, { |
171 | url, originUrl, siteName, embed, title, description, image, list, ogType, twitterCard, schemaType | 180 | url, |
181 | originUrl, | ||
182 | siteName, | ||
183 | embed, | ||
184 | title, | ||
185 | description, | ||
186 | image, | ||
187 | list, | ||
188 | ogType, | ||
189 | twitterCard, | ||
190 | schemaType | ||
172 | }) | 191 | }) |
173 | 192 | ||
174 | return customHtml | 193 | return customHtml |
@@ -216,7 +235,7 @@ export class ClientHtml { | |||
216 | let customHtml = ClientHtml.addTitleTag(html, escapeHTML(entity.getDisplayName())) | 235 | let customHtml = ClientHtml.addTitleTag(html, escapeHTML(entity.getDisplayName())) |
217 | customHtml = ClientHtml.addDescriptionTag(customHtml, escapeHTML(entity.description)) | 236 | customHtml = ClientHtml.addDescriptionTag(customHtml, escapeHTML(entity.description)) |
218 | 237 | ||
219 | const url = entity.Actor.url | 238 | const url = entity.getLocalUrl() |
220 | const originUrl = entity.Actor.url | 239 | const originUrl = entity.Actor.url |
221 | const siteName = escapeHTML(CONFIG.INSTANCE.NAME) | 240 | const siteName = escapeHTML(CONFIG.INSTANCE.NAME) |
222 | const title = escapeHTML(entity.getDisplayName()) | 241 | const title = escapeHTML(entity.getDisplayName()) |
@@ -232,7 +251,17 @@ export class ClientHtml { | |||
232 | const twitterCard = 'summary' | 251 | const twitterCard = 'summary' |
233 | const schemaType = 'ProfilePage' | 252 | const schemaType = 'ProfilePage' |
234 | 253 | ||
235 | customHtml = ClientHtml.addTags(customHtml, { url, originUrl, title, siteName, description, image, ogType, twitterCard, schemaType }) | 254 | customHtml = ClientHtml.addTags(customHtml, { |
255 | url, | ||
256 | originUrl, | ||
257 | title, | ||
258 | siteName, | ||
259 | description, | ||
260 | image, | ||
261 | ogType, | ||
262 | twitterCard, | ||
263 | schemaType | ||
264 | }) | ||
236 | 265 | ||
237 | return customHtml | 266 | return customHtml |
238 | } | 267 | } |
diff --git a/server/models/account/account.ts b/server/models/account/account.ts index 1162643be..8c244d432 100644 --- a/server/models/account/account.ts +++ b/server/models/account/account.ts | |||
@@ -1,3 +1,5 @@ | |||
1 | import * as Bluebird from 'bluebird' | ||
2 | import { FindOptions, IncludeOptions, Op, Transaction, WhereOptions } from 'sequelize' | ||
1 | import { | 3 | import { |
2 | AllowNull, | 4 | AllowNull, |
3 | BeforeDestroy, | 5 | BeforeDestroy, |
@@ -15,27 +17,33 @@ import { | |||
15 | Table, | 17 | Table, |
16 | UpdatedAt | 18 | UpdatedAt |
17 | } from 'sequelize-typescript' | 19 | } from 'sequelize-typescript' |
20 | import { ModelCache } from '@server/models/model-cache' | ||
18 | import { Account, AccountSummary } from '../../../shared/models/actors' | 21 | import { Account, AccountSummary } from '../../../shared/models/actors' |
19 | import { isAccountDescriptionValid } from '../../helpers/custom-validators/accounts' | 22 | import { isAccountDescriptionValid } from '../../helpers/custom-validators/accounts' |
23 | import { CONSTRAINTS_FIELDS, SERVER_ACTOR_NAME, WEBSERVER } from '../../initializers/constants' | ||
20 | import { sendDeleteActor } from '../../lib/activitypub/send' | 24 | import { sendDeleteActor } from '../../lib/activitypub/send' |
25 | import { | ||
26 | MAccount, | ||
27 | MAccountActor, | ||
28 | MAccountAP, | ||
29 | MAccountDefault, | ||
30 | MAccountFormattable, | ||
31 | MAccountSummaryFormattable, | ||
32 | MChannelActor | ||
33 | } from '../../types/models' | ||
21 | import { ActorModel } from '../activitypub/actor' | 34 | import { ActorModel } from '../activitypub/actor' |
35 | import { ActorFollowModel } from '../activitypub/actor-follow' | ||
22 | import { ApplicationModel } from '../application/application' | 36 | import { ApplicationModel } from '../application/application' |
37 | import { AvatarModel } from '../avatar/avatar' | ||
23 | import { ServerModel } from '../server/server' | 38 | import { ServerModel } from '../server/server' |
39 | import { ServerBlocklistModel } from '../server/server-blocklist' | ||
24 | import { getSort, throwIfNotValid } from '../utils' | 40 | import { getSort, throwIfNotValid } from '../utils' |
41 | import { VideoModel } from '../video/video' | ||
25 | import { VideoChannelModel } from '../video/video-channel' | 42 | import { VideoChannelModel } from '../video/video-channel' |
26 | import { VideoCommentModel } from '../video/video-comment' | 43 | import { VideoCommentModel } from '../video/video-comment' |
27 | import { UserModel } from './user' | ||
28 | import { AvatarModel } from '../avatar/avatar' | ||
29 | import { VideoPlaylistModel } from '../video/video-playlist' | 44 | import { VideoPlaylistModel } from '../video/video-playlist' |
30 | import { CONSTRAINTS_FIELDS, SERVER_ACTOR_NAME, WEBSERVER } from '../../initializers/constants' | ||
31 | import { FindOptions, IncludeOptions, Op, Transaction, WhereOptions } from 'sequelize' | ||
32 | import { AccountBlocklistModel } from './account-blocklist' | 45 | import { AccountBlocklistModel } from './account-blocklist' |
33 | import { ServerBlocklistModel } from '../server/server-blocklist' | 46 | import { UserModel } from './user' |
34 | import { ActorFollowModel } from '../activitypub/actor-follow' | ||
35 | import { MAccountActor, MAccountAP, MAccountDefault, MAccountFormattable, MAccountSummaryFormattable, MAccount } from '../../types/models' | ||
36 | import * as Bluebird from 'bluebird' | ||
37 | import { ModelCache } from '@server/models/model-cache' | ||
38 | import { VideoModel } from '../video/video' | ||
39 | 47 | ||
40 | export enum ScopeNames { | 48 | export enum ScopeNames { |
41 | SUMMARY = 'SUMMARY' | 49 | SUMMARY = 'SUMMARY' |
@@ -441,6 +449,10 @@ export class AccountModel extends Model<AccountModel> { | |||
441 | return this.name | 449 | return this.name |
442 | } | 450 | } |
443 | 451 | ||
452 | getLocalUrl (this: MAccountActor | MChannelActor) { | ||
453 | return WEBSERVER.URL + `/accounts/` + this.Actor.preferredUsername | ||
454 | } | ||
455 | |||
444 | isBlocked () { | 456 | isBlocked () { |
445 | return this.BlockedAccounts && this.BlockedAccounts.length !== 0 | 457 | return this.BlockedAccounts && this.BlockedAccounts.length !== 0 |
446 | } | 458 | } |
diff --git a/server/models/video/video-channel.ts b/server/models/video/video-channel.ts index 202dc513f..0c8aef18f 100644 --- a/server/models/video/video-channel.ts +++ b/server/models/video/video-channel.ts | |||
@@ -18,6 +18,7 @@ import { | |||
18 | Table, | 18 | Table, |
19 | UpdatedAt | 19 | UpdatedAt |
20 | } from 'sequelize-typescript' | 20 | } from 'sequelize-typescript' |
21 | import { MAccountActor } from '@server/types/models' | ||
21 | import { ActivityPubActor } from '../../../shared/models/activitypub' | 22 | import { ActivityPubActor } from '../../../shared/models/activitypub' |
22 | import { VideoChannel, VideoChannelSummary } from '../../../shared/models/videos' | 23 | import { VideoChannel, VideoChannelSummary } from '../../../shared/models/videos' |
23 | import { | 24 | import { |
@@ -628,6 +629,10 @@ export class VideoChannelModel extends Model<VideoChannelModel> { | |||
628 | }) | 629 | }) |
629 | } | 630 | } |
630 | 631 | ||
632 | getLocalUrl (this: MAccountActor | MChannelActor) { | ||
633 | return WEBSERVER.URL + `/video-channels/` + this.Actor.preferredUsername | ||
634 | } | ||
635 | |||
631 | getDisplayName () { | 636 | getDisplayName () { |
632 | return this.name | 637 | return this.name |
633 | } | 638 | } |
diff --git a/server/tests/client.ts b/server/tests/client.ts index 7bcb999ea..7572fd34a 100644 --- a/server/tests/client.ts +++ b/server/tests/client.ts | |||
@@ -8,20 +8,21 @@ import { | |||
8 | addVideoInPlaylist, | 8 | addVideoInPlaylist, |
9 | cleanupTests, | 9 | cleanupTests, |
10 | createVideoPlaylist, | 10 | createVideoPlaylist, |
11 | doubleFollow, | ||
12 | flushAndRunMultipleServers, | ||
11 | getAccount, | 13 | getAccount, |
12 | getCustomConfig, | 14 | getCustomConfig, |
13 | getVideosList, | 15 | getVideosList, |
14 | makeHTMLRequest, | 16 | makeHTMLRequest, |
15 | ServerInfo, | 17 | ServerInfo, |
18 | setAccessTokensToServers, | ||
16 | setDefaultVideoChannel, | 19 | setDefaultVideoChannel, |
17 | updateCustomConfig, | 20 | updateCustomConfig, |
18 | updateCustomSubConfig, | 21 | updateCustomSubConfig, |
19 | uploadVideo, | ||
20 | updateMyUser, | 22 | updateMyUser, |
21 | updateVideoChannel, | 23 | updateVideoChannel, |
22 | doubleFollow, | 24 | uploadVideo, |
23 | flushAndRunMultipleServers, | 25 | waitJobs |
24 | setAccessTokensToServers | ||
25 | } from '../../shared/extra-utils' | 26 | } from '../../shared/extra-utils' |
26 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' | 27 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' |
27 | 28 | ||
@@ -35,10 +36,7 @@ function checkIndexTags (html: string, title: string, description: string, css: | |||
35 | 36 | ||
36 | describe('Test a client controllers', function () { | 37 | describe('Test a client controllers', function () { |
37 | let servers: ServerInfo[] = [] | 38 | let servers: ServerInfo[] = [] |
38 | let server: ServerInfo | ||
39 | let account: Account | 39 | let account: Account |
40 | let videoUUID: string | ||
41 | let videoOriginalUrl: string | ||
42 | 40 | ||
43 | const videoName = 'my super name for server 1' | 41 | const videoName = 'my super name for server 1' |
44 | const videoDescription = 'my super description for server 1' | 42 | const videoDescription = 'my super description for server 1' |
@@ -53,32 +51,25 @@ describe('Test a client controllers', function () { | |||
53 | this.timeout(120000) | 51 | this.timeout(120000) |
54 | 52 | ||
55 | servers = await flushAndRunMultipleServers(2) | 53 | servers = await flushAndRunMultipleServers(2) |
56 | const server = servers[0] | ||
57 | 54 | ||
58 | await setAccessTokensToServers(servers) | 55 | await setAccessTokensToServers(servers) |
59 | 56 | ||
60 | { | ||
61 | const res = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video' }) | ||
62 | videoUUID = res.body.video.uuid | ||
63 | videoOriginalUrl = res.body.video.url | ||
64 | } | ||
65 | |||
66 | await doubleFollow(servers[0], servers[1]) | 57 | await doubleFollow(servers[0], servers[1]) |
67 | 58 | ||
68 | await setDefaultVideoChannel([ server ]) | 59 | await setDefaultVideoChannel(servers) |
69 | 60 | ||
70 | await updateVideoChannel(server.url, server.accessToken, server.videoChannel.name, { description: channelDescription }) | 61 | await updateVideoChannel(servers[0].url, servers[0].accessToken, servers[0].videoChannel.name, { description: channelDescription }) |
71 | 62 | ||
72 | // Video | 63 | // Video |
73 | 64 | ||
74 | const videoAttributes = { name: videoName, description: videoDescription } | 65 | const videoAttributes = { name: videoName, description: videoDescription } |
75 | await uploadVideo(server.url, server.accessToken, videoAttributes) | 66 | await uploadVideo(servers[0].url, servers[0].accessToken, videoAttributes) |
76 | 67 | ||
77 | const resVideosRequest = await getVideosList(server.url) | 68 | const resVideosRequest = await getVideosList(servers[0].url) |
78 | const videos = resVideosRequest.body.data | 69 | const videos = resVideosRequest.body.data |
79 | expect(videos.length).to.equal(1) | 70 | expect(videos.length).to.equal(1) |
80 | 71 | ||
81 | server.video = videos[0] | 72 | servers[0].video = videos[0] |
82 | 73 | ||
83 | // Playlist | 74 | // Playlist |
84 | 75 | ||
@@ -86,54 +77,56 @@ describe('Test a client controllers', function () { | |||
86 | displayName: playlistName, | 77 | displayName: playlistName, |
87 | description: playlistDescription, | 78 | description: playlistDescription, |
88 | privacy: VideoPlaylistPrivacy.PUBLIC, | 79 | privacy: VideoPlaylistPrivacy.PUBLIC, |
89 | videoChannelId: server.videoChannel.id | 80 | videoChannelId: servers[0].videoChannel.id |
90 | } | 81 | } |
91 | 82 | ||
92 | const resVideoPlaylistRequest = await createVideoPlaylist({ url: server.url, token: server.accessToken, playlistAttrs }) | 83 | const resVideoPlaylistRequest = await createVideoPlaylist({ url: servers[0].url, token: servers[0].accessToken, playlistAttrs }) |
93 | 84 | ||
94 | const playlist = resVideoPlaylistRequest.body.videoPlaylist | 85 | const playlist = resVideoPlaylistRequest.body.videoPlaylist |
95 | const playlistId = playlist.id | 86 | const playlistId = playlist.id |
96 | playlistUUID = playlist.uuid | 87 | playlistUUID = playlist.uuid |
97 | 88 | ||
98 | await addVideoInPlaylist({ | 89 | await addVideoInPlaylist({ |
99 | url: server.url, | 90 | url: servers[0].url, |
100 | token: server.accessToken, | 91 | token: servers[0].accessToken, |
101 | playlistId, | 92 | playlistId, |
102 | elementAttrs: { videoId: server.video.id } | 93 | elementAttrs: { videoId: servers[0].video.id } |
103 | }) | 94 | }) |
104 | 95 | ||
105 | // Account | 96 | // Account |
106 | 97 | ||
107 | await updateMyUser({ url: server.url, accessToken: server.accessToken, description: 'my account description' }) | 98 | await updateMyUser({ url: servers[0].url, accessToken: servers[0].accessToken, description: 'my account description' }) |
108 | 99 | ||
109 | const resAccountRequest = await getAccount(server.url, `${server.user.username}@${server.host}`) | 100 | const resAccountRequest = await getAccount(servers[0].url, `${servers[0].user.username}@${servers[0].host}`) |
110 | account = resAccountRequest.body | 101 | account = resAccountRequest.body |
102 | |||
103 | await waitJobs(servers) | ||
111 | }) | 104 | }) |
112 | 105 | ||
113 | describe('oEmbed', function () { | 106 | describe('oEmbed', function () { |
114 | it('Should have valid oEmbed discovery tags for videos', async function () { | 107 | it('Should have valid oEmbed discovery tags for videos', async function () { |
115 | const path = '/videos/watch/' + server.video.uuid | 108 | const path = '/videos/watch/' + servers[0].video.uuid |
116 | const res = await request(server.url) | 109 | const res = await request(servers[0].url) |
117 | .get(path) | 110 | .get(path) |
118 | .set('Accept', 'text/html') | 111 | .set('Accept', 'text/html') |
119 | .expect(HttpStatusCode.OK_200) | 112 | .expect(HttpStatusCode.OK_200) |
120 | 113 | ||
121 | const port = server.port | 114 | const port = servers[0].port |
122 | 115 | ||
123 | const expectedLink = '<link rel="alternate" type="application/json+oembed" href="http://localhost:' + port + '/services/oembed?' + | 116 | 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${server.video.uuid}" ` + | 117 | `url=http%3A%2F%2Flocalhost%3A${port}%2Fvideos%2Fwatch%2F${servers[0].video.uuid}" ` + |
125 | `title="${server.video.name}" />` | 118 | `title="${servers[0].video.name}" />` |
126 | 119 | ||
127 | expect(res.text).to.contain(expectedLink) | 120 | expect(res.text).to.contain(expectedLink) |
128 | }) | 121 | }) |
129 | 122 | ||
130 | it('Should have valid oEmbed discovery tags for a playlist', async function () { | 123 | it('Should have valid oEmbed discovery tags for a playlist', async function () { |
131 | const res = await request(server.url) | 124 | const res = await request(servers[0].url) |
132 | .get('/videos/watch/playlist/' + playlistUUID) | 125 | .get('/videos/watch/playlist/' + playlistUUID) |
133 | .set('Accept', 'text/html') | 126 | .set('Accept', 'text/html') |
134 | .expect(HttpStatusCode.OK_200) | 127 | .expect(HttpStatusCode.OK_200) |
135 | 128 | ||
136 | const port = server.port | 129 | const port = servers[0].port |
137 | 130 | ||
138 | const expectedLink = '<link rel="alternate" type="application/json+oembed" href="http://localhost:' + port + '/services/oembed?' + | 131 | 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}" ` + | 132 | `url=http%3A%2F%2Flocalhost%3A${port}%2Fvideos%2Fwatch%2Fplaylist%2F${playlistUUID}" ` + |
@@ -146,55 +139,55 @@ describe('Test a client controllers', function () { | |||
146 | describe('Open Graph', function () { | 139 | describe('Open Graph', function () { |
147 | 140 | ||
148 | it('Should have valid Open Graph tags on the account page', async function () { | 141 | it('Should have valid Open Graph tags on the account page', async function () { |
149 | const res = await request(server.url) | 142 | const res = await request(servers[0].url) |
150 | .get('/accounts/' + server.user.username) | 143 | .get('/accounts/' + servers[0].user.username) |
151 | .set('Accept', 'text/html') | 144 | .set('Accept', 'text/html') |
152 | .expect(HttpStatusCode.OK_200) | 145 | .expect(HttpStatusCode.OK_200) |
153 | 146 | ||
154 | expect(res.text).to.contain(`<meta property="og:title" content="${account.displayName}" />`) | 147 | expect(res.text).to.contain(`<meta property="og:title" content="${account.displayName}" />`) |
155 | expect(res.text).to.contain(`<meta property="og:description" content="${account.description}" />`) | 148 | expect(res.text).to.contain(`<meta property="og:description" content="${account.description}" />`) |
156 | expect(res.text).to.contain('<meta property="og:type" content="website" />') | 149 | expect(res.text).to.contain('<meta property="og:type" content="website" />') |
157 | expect(res.text).to.contain(`<meta property="og:url" content="${server.url}/accounts/${server.user.username}" />`) | 150 | expect(res.text).to.contain(`<meta property="og:url" content="${servers[0].url}/accounts/${servers[0].user.username}" />`) |
158 | }) | 151 | }) |
159 | 152 | ||
160 | it('Should have valid Open Graph tags on the channel page', async function () { | 153 | it('Should have valid Open Graph tags on the channel page', async function () { |
161 | const res = await request(server.url) | 154 | const res = await request(servers[0].url) |
162 | .get('/video-channels/' + server.videoChannel.name) | 155 | .get('/video-channels/' + servers[0].videoChannel.name) |
163 | .set('Accept', 'text/html') | 156 | .set('Accept', 'text/html') |
164 | .expect(HttpStatusCode.OK_200) | 157 | .expect(HttpStatusCode.OK_200) |
165 | 158 | ||
166 | expect(res.text).to.contain(`<meta property="og:title" content="${server.videoChannel.displayName}" />`) | 159 | expect(res.text).to.contain(`<meta property="og:title" content="${servers[0].videoChannel.displayName}" />`) |
167 | expect(res.text).to.contain(`<meta property="og:description" content="${channelDescription}" />`) | 160 | expect(res.text).to.contain(`<meta property="og:description" content="${channelDescription}" />`) |
168 | expect(res.text).to.contain('<meta property="og:type" content="website" />') | 161 | expect(res.text).to.contain('<meta property="og:type" content="website" />') |
169 | expect(res.text).to.contain(`<meta property="og:url" content="${server.url}/video-channels/${server.videoChannel.name}" />`) | 162 | expect(res.text).to.contain(`<meta property="og:url" content="${servers[0].url}/video-channels/${servers[0].videoChannel.name}" />`) |
170 | }) | 163 | }) |
171 | 164 | ||
172 | it('Should have valid Open Graph tags on the watch page with video id', async function () { | 165 | it('Should have valid Open Graph tags on the watch page with video id', async function () { |
173 | const res = await request(server.url) | 166 | const res = await request(servers[0].url) |
174 | .get('/videos/watch/' + server.video.id) | 167 | .get('/videos/watch/' + servers[0].video.id) |
175 | .set('Accept', 'text/html') | 168 | .set('Accept', 'text/html') |
176 | .expect(HttpStatusCode.OK_200) | 169 | .expect(HttpStatusCode.OK_200) |
177 | 170 | ||
178 | expect(res.text).to.contain(`<meta property="og:title" content="${videoName}" />`) | 171 | expect(res.text).to.contain(`<meta property="og:title" content="${videoName}" />`) |
179 | expect(res.text).to.contain(`<meta property="og:description" content="${videoDescription}" />`) | 172 | expect(res.text).to.contain(`<meta property="og:description" content="${videoDescription}" />`) |
180 | expect(res.text).to.contain('<meta property="og:type" content="video" />') | 173 | expect(res.text).to.contain('<meta property="og:type" content="video" />') |
181 | expect(res.text).to.contain(`<meta property="og:url" content="${server.url}/videos/watch/${server.video.uuid}" />`) | 174 | expect(res.text).to.contain(`<meta property="og:url" content="${servers[0].url}/videos/watch/${servers[0].video.uuid}" />`) |
182 | }) | 175 | }) |
183 | 176 | ||
184 | it('Should have valid Open Graph tags on the watch page with video uuid', async function () { | 177 | it('Should have valid Open Graph tags on the watch page with video uuid', async function () { |
185 | const res = await request(server.url) | 178 | const res = await request(servers[0].url) |
186 | .get('/videos/watch/' + server.video.uuid) | 179 | .get('/videos/watch/' + servers[0].video.uuid) |
187 | .set('Accept', 'text/html') | 180 | .set('Accept', 'text/html') |
188 | .expect(HttpStatusCode.OK_200) | 181 | .expect(HttpStatusCode.OK_200) |
189 | 182 | ||
190 | expect(res.text).to.contain(`<meta property="og:title" content="${videoName}" />`) | 183 | expect(res.text).to.contain(`<meta property="og:title" content="${videoName}" />`) |
191 | expect(res.text).to.contain(`<meta property="og:description" content="${videoDescription}" />`) | 184 | expect(res.text).to.contain(`<meta property="og:description" content="${videoDescription}" />`) |
192 | expect(res.text).to.contain('<meta property="og:type" content="video" />') | 185 | expect(res.text).to.contain('<meta property="og:type" content="video" />') |
193 | expect(res.text).to.contain(`<meta property="og:url" content="${server.url}/videos/watch/${server.video.uuid}" />`) | 186 | expect(res.text).to.contain(`<meta property="og:url" content="${servers[0].url}/videos/watch/${servers[0].video.uuid}" />`) |
194 | }) | 187 | }) |
195 | 188 | ||
196 | it('Should have valid Open Graph tags on the watch playlist page', async function () { | 189 | it('Should have valid Open Graph tags on the watch playlist page', async function () { |
197 | const res = await request(server.url) | 190 | const res = await request(servers[0].url) |
198 | .get('/videos/watch/playlist/' + playlistUUID) | 191 | .get('/videos/watch/playlist/' + playlistUUID) |
199 | .set('Accept', 'text/html') | 192 | .set('Accept', 'text/html') |
200 | .expect(HttpStatusCode.OK_200) | 193 | .expect(HttpStatusCode.OK_200) |
@@ -202,15 +195,15 @@ describe('Test a client controllers', function () { | |||
202 | expect(res.text).to.contain(`<meta property="og:title" content="${playlistName}" />`) | 195 | expect(res.text).to.contain(`<meta property="og:title" content="${playlistName}" />`) |
203 | expect(res.text).to.contain(`<meta property="og:description" content="${playlistDescription}" />`) | 196 | expect(res.text).to.contain(`<meta property="og:description" content="${playlistDescription}" />`) |
204 | expect(res.text).to.contain('<meta property="og:type" content="video" />') | 197 | expect(res.text).to.contain('<meta property="og:type" content="video" />') |
205 | expect(res.text).to.contain(`<meta property="og:url" content="${server.url}/videos/watch/playlist/${playlistUUID}" />`) | 198 | expect(res.text).to.contain(`<meta property="og:url" content="${servers[0].url}/videos/watch/playlist/${playlistUUID}" />`) |
206 | }) | 199 | }) |
207 | }) | 200 | }) |
208 | 201 | ||
209 | describe('Twitter card', async function () { | 202 | describe('Twitter card', async function () { |
210 | 203 | ||
211 | it('Should have valid twitter card on the watch video page', async function () { | 204 | it('Should have valid twitter card on the watch video page', async function () { |
212 | const res = await request(server.url) | 205 | const res = await request(servers[0].url) |
213 | .get('/videos/watch/' + server.video.uuid) | 206 | .get('/videos/watch/' + servers[0].video.uuid) |
214 | .set('Accept', 'text/html') | 207 | .set('Accept', 'text/html') |
215 | .expect(HttpStatusCode.OK_200) | 208 | .expect(HttpStatusCode.OK_200) |
216 | 209 | ||
@@ -221,7 +214,7 @@ describe('Test a client controllers', function () { | |||
221 | }) | 214 | }) |
222 | 215 | ||
223 | it('Should have valid twitter card on the watch playlist page', async function () { | 216 | it('Should have valid twitter card on the watch playlist page', async function () { |
224 | const res = await request(server.url) | 217 | const res = await request(servers[0].url) |
225 | .get('/videos/watch/playlist/' + playlistUUID) | 218 | .get('/videos/watch/playlist/' + playlistUUID) |
226 | .set('Accept', 'text/html') | 219 | .set('Accept', 'text/html') |
227 | .expect(HttpStatusCode.OK_200) | 220 | .expect(HttpStatusCode.OK_200) |
@@ -233,7 +226,7 @@ describe('Test a client controllers', function () { | |||
233 | }) | 226 | }) |
234 | 227 | ||
235 | it('Should have valid twitter card on the account page', async function () { | 228 | it('Should have valid twitter card on the account page', async function () { |
236 | const res = await request(server.url) | 229 | const res = await request(servers[0].url) |
237 | .get('/accounts/' + account.name) | 230 | .get('/accounts/' + account.name) |
238 | .set('Accept', 'text/html') | 231 | .set('Accept', 'text/html') |
239 | .expect(HttpStatusCode.OK_200) | 232 | .expect(HttpStatusCode.OK_200) |
@@ -245,35 +238,35 @@ describe('Test a client controllers', function () { | |||
245 | }) | 238 | }) |
246 | 239 | ||
247 | it('Should have valid twitter card on the channel page', async function () { | 240 | it('Should have valid twitter card on the channel page', async function () { |
248 | const res = await request(server.url) | 241 | const res = await request(servers[0].url) |
249 | .get('/video-channels/' + server.videoChannel.name) | 242 | .get('/video-channels/' + servers[0].videoChannel.name) |
250 | .set('Accept', 'text/html') | 243 | .set('Accept', 'text/html') |
251 | .expect(HttpStatusCode.OK_200) | 244 | .expect(HttpStatusCode.OK_200) |
252 | 245 | ||
253 | expect(res.text).to.contain('<meta property="twitter:card" content="summary" />') | 246 | expect(res.text).to.contain('<meta property="twitter:card" content="summary" />') |
254 | expect(res.text).to.contain('<meta property="twitter:site" content="@Chocobozzz" />') | 247 | expect(res.text).to.contain('<meta property="twitter:site" content="@Chocobozzz" />') |
255 | expect(res.text).to.contain(`<meta property="twitter:title" content="${server.videoChannel.displayName}" />`) | 248 | expect(res.text).to.contain(`<meta property="twitter:title" content="${servers[0].videoChannel.displayName}" />`) |
256 | expect(res.text).to.contain(`<meta property="twitter:description" content="${channelDescription}" />`) | 249 | expect(res.text).to.contain(`<meta property="twitter:description" content="${channelDescription}" />`) |
257 | }) | 250 | }) |
258 | 251 | ||
259 | it('Should have valid twitter card if Twitter is whitelisted', async function () { | 252 | it('Should have valid twitter card if Twitter is whitelisted', async function () { |
260 | const res1 = await getCustomConfig(server.url, server.accessToken) | 253 | const res1 = await getCustomConfig(servers[0].url, servers[0].accessToken) |
261 | const config = res1.body | 254 | const config = res1.body |
262 | config.services.twitter = { | 255 | config.services.twitter = { |
263 | username: '@Kuja', | 256 | username: '@Kuja', |
264 | whitelisted: true | 257 | whitelisted: true |
265 | } | 258 | } |
266 | await updateCustomConfig(server.url, server.accessToken, config) | 259 | await updateCustomConfig(servers[0].url, servers[0].accessToken, config) |
267 | 260 | ||
268 | const resVideoRequest = await request(server.url) | 261 | const resVideoRequest = await request(servers[0].url) |
269 | .get('/videos/watch/' + server.video.uuid) | 262 | .get('/videos/watch/' + servers[0].video.uuid) |
270 | .set('Accept', 'text/html') | 263 | .set('Accept', 'text/html') |
271 | .expect(HttpStatusCode.OK_200) | 264 | .expect(HttpStatusCode.OK_200) |
272 | 265 | ||
273 | expect(resVideoRequest.text).to.contain('<meta property="twitter:card" content="player" />') | 266 | expect(resVideoRequest.text).to.contain('<meta property="twitter:card" content="player" />') |
274 | expect(resVideoRequest.text).to.contain('<meta property="twitter:site" content="@Kuja" />') | 267 | expect(resVideoRequest.text).to.contain('<meta property="twitter:site" content="@Kuja" />') |
275 | 268 | ||
276 | const resVideoPlaylistRequest = await request(server.url) | 269 | const resVideoPlaylistRequest = await request(servers[0].url) |
277 | .get('/videos/watch/playlist/' + playlistUUID) | 270 | .get('/videos/watch/playlist/' + playlistUUID) |
278 | .set('Accept', 'text/html') | 271 | .set('Accept', 'text/html') |
279 | .expect(HttpStatusCode.OK_200) | 272 | .expect(HttpStatusCode.OK_200) |
@@ -281,7 +274,7 @@ describe('Test a client controllers', function () { | |||
281 | expect(resVideoPlaylistRequest.text).to.contain('<meta property="twitter:card" content="player" />') | 274 | expect(resVideoPlaylistRequest.text).to.contain('<meta property="twitter:card" content="player" />') |
282 | expect(resVideoPlaylistRequest.text).to.contain('<meta property="twitter:site" content="@Kuja" />') | 275 | expect(resVideoPlaylistRequest.text).to.contain('<meta property="twitter:site" content="@Kuja" />') |
283 | 276 | ||
284 | const resAccountRequest = await request(server.url) | 277 | const resAccountRequest = await request(servers[0].url) |
285 | .get('/accounts/' + account.name) | 278 | .get('/accounts/' + account.name) |
286 | .set('Accept', 'text/html') | 279 | .set('Accept', 'text/html') |
287 | .expect(HttpStatusCode.OK_200) | 280 | .expect(HttpStatusCode.OK_200) |
@@ -289,8 +282,8 @@ describe('Test a client controllers', function () { | |||
289 | expect(resAccountRequest.text).to.contain('<meta property="twitter:card" content="summary" />') | 282 | expect(resAccountRequest.text).to.contain('<meta property="twitter:card" content="summary" />') |
290 | expect(resAccountRequest.text).to.contain('<meta property="twitter:site" content="@Kuja" />') | 283 | expect(resAccountRequest.text).to.contain('<meta property="twitter:site" content="@Kuja" />') |
291 | 284 | ||
292 | const resChannelRequest = await request(server.url) | 285 | const resChannelRequest = await request(servers[0].url) |
293 | .get('/video-channels/' + server.videoChannel.name) | 286 | .get('/video-channels/' + servers[0].videoChannel.name) |
294 | .set('Accept', 'text/html') | 287 | .set('Accept', 'text/html') |
295 | .expect(HttpStatusCode.OK_200) | 288 | .expect(HttpStatusCode.OK_200) |
296 | 289 | ||
@@ -302,14 +295,14 @@ describe('Test a client controllers', function () { | |||
302 | describe('Index HTML', function () { | 295 | describe('Index HTML', function () { |
303 | 296 | ||
304 | it('Should have valid index html tags (title, description...)', async function () { | 297 | it('Should have valid index html tags (title, description...)', async function () { |
305 | const res = await makeHTMLRequest(server.url, '/videos/trending') | 298 | const res = await makeHTMLRequest(servers[0].url, '/videos/trending') |
306 | 299 | ||
307 | const description = 'PeerTube, an ActivityPub-federated video streaming platform using P2P directly in your web browser.' | 300 | const description = 'PeerTube, an ActivityPub-federated video streaming platform using P2P directly in your web browser.' |
308 | checkIndexTags(res.text, 'PeerTube', description, '') | 301 | checkIndexTags(res.text, 'PeerTube', description, '') |
309 | }) | 302 | }) |
310 | 303 | ||
311 | it('Should update the customized configuration and have the correct index html tags', async function () { | 304 | it('Should update the customized configuration and have the correct index html tags', async function () { |
312 | await updateCustomSubConfig(server.url, server.accessToken, { | 305 | await updateCustomSubConfig(servers[0].url, servers[0].accessToken, { |
313 | instance: { | 306 | instance: { |
314 | name: 'PeerTube updated', | 307 | name: 'PeerTube updated', |
315 | shortDescription: 'my short description', | 308 | shortDescription: 'my short description', |
@@ -324,24 +317,39 @@ describe('Test a client controllers', function () { | |||
324 | } | 317 | } |
325 | }) | 318 | }) |
326 | 319 | ||
327 | const res = await makeHTMLRequest(server.url, '/videos/trending') | 320 | const res = await makeHTMLRequest(servers[0].url, '/videos/trending') |
328 | 321 | ||
329 | checkIndexTags(res.text, 'PeerTube updated', 'my short description', 'body { background-color: red; }') | 322 | checkIndexTags(res.text, 'PeerTube updated', 'my short description', 'body { background-color: red; }') |
330 | }) | 323 | }) |
331 | 324 | ||
332 | it('Should have valid index html updated tags (title, description...)', async function () { | 325 | it('Should have valid index html updated tags (title, description...)', async function () { |
333 | const res = await makeHTMLRequest(server.url, '/videos/trending') | 326 | const res = await makeHTMLRequest(servers[0].url, '/videos/trending') |
334 | 327 | ||
335 | checkIndexTags(res.text, 'PeerTube updated', 'my short description', 'body { background-color: red; }') | 328 | checkIndexTags(res.text, 'PeerTube updated', 'my short description', 'body { background-color: red; }') |
336 | }) | 329 | }) |
337 | 330 | ||
338 | it('Should use the original video URL for the canonical tag', async function () { | 331 | it('Should use the original video URL for the canonical tag', async function () { |
339 | const res = await makeHTMLRequest(servers[1].url, '/videos/watch/' + videoUUID) | 332 | const res = await makeHTMLRequest(servers[1].url, '/videos/watch/' + servers[0].video.uuid) |
340 | expect(res.text).to.contain(`<link rel="canonical" href="${videoOriginalUrl}" />`) | 333 | expect(res.text).to.contain(`<link rel="canonical" href="${servers[0].url}/videos/watch/${servers[0].video.uuid}" />`) |
334 | }) | ||
335 | |||
336 | it('Should use the original account URL for the canonical tag', async function () { | ||
337 | const res = await makeHTMLRequest(servers[1].url, '/accounts/root@' + servers[0].host) | ||
338 | expect(res.text).to.contain(`<link rel="canonical" href="${servers[0].url}/accounts/root" />`) | ||
339 | }) | ||
340 | |||
341 | it('Should use the original channel URL for the canonical tag', async function () { | ||
342 | const res = await makeHTMLRequest(servers[1].url, '/video-channels/root_channel@' + servers[0].host) | ||
343 | expect(res.text).to.contain(`<link rel="canonical" href="${servers[0].url}/video-channels/root_channel" />`) | ||
344 | }) | ||
345 | |||
346 | it('Should use the original playlist URL for the canonical tag', async function () { | ||
347 | const res = await makeHTMLRequest(servers[1].url, '/videos/watch/playlist/' + playlistUUID) | ||
348 | expect(res.text).to.contain(`<link rel="canonical" href="${servers[0].url}/video-playlists/${playlistUUID}" />`) | ||
341 | }) | 349 | }) |
342 | }) | 350 | }) |
343 | 351 | ||
344 | after(async function () { | 352 | after(async function () { |
345 | await cleanupTests([ server ]) | 353 | await cleanupTests(servers) |
346 | }) | 354 | }) |
347 | }) | 355 | }) |
diff --git a/shared/extra-utils/server/servers.ts b/shared/extra-utils/server/servers.ts index 4ad3eb14a..e88482e49 100644 --- a/shared/extra-utils/server/servers.ts +++ b/shared/extra-utils/server/servers.ts | |||
@@ -42,6 +42,7 @@ interface ServerInfo { | |||
42 | id: number | 42 | id: number |
43 | uuid: string | 43 | uuid: string |
44 | name?: string | 44 | name?: string |
45 | url?: string | ||
45 | account?: { | 46 | account?: { |
46 | name: string | 47 | name: string |
47 | } | 48 | } |