diff options
Diffstat (limited to 'server/tests/shared/videos.ts')
-rw-r--r-- | server/tests/shared/videos.ts | 187 |
1 files changed, 120 insertions, 67 deletions
diff --git a/server/tests/shared/videos.ts b/server/tests/shared/videos.ts index f8ec65752..856fabd11 100644 --- a/server/tests/shared/videos.ts +++ b/server/tests/shared/videos.ts | |||
@@ -4,16 +4,106 @@ import { expect } from 'chai' | |||
4 | import { pathExists, readdir } from 'fs-extra' | 4 | import { pathExists, readdir } from 'fs-extra' |
5 | import { basename, join } from 'path' | 5 | import { basename, join } from 'path' |
6 | import { loadLanguages, VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_PRIVACIES } from '@server/initializers/constants' | 6 | import { loadLanguages, VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_PRIVACIES } from '@server/initializers/constants' |
7 | import { getLowercaseExtension, uuidRegex } from '@shared/core-utils' | 7 | import { getLowercaseExtension, pick, uuidRegex } from '@shared/core-utils' |
8 | import { HttpStatusCode, VideoCaption, VideoDetails } from '@shared/models' | 8 | import { HttpStatusCode, VideoCaption, VideoDetails, VideoPrivacy, VideoResolution } from '@shared/models' |
9 | import { makeRawRequest, PeerTubeServer, VideoEdit, waitJobs, webtorrentAdd } from '@shared/server-commands' | 9 | import { makeRawRequest, PeerTubeServer, VideoEdit, waitJobs } from '@shared/server-commands' |
10 | import { dateIsValid, testImage } from './checks' | 10 | import { dateIsValid, expectStartWith, testImage } from './checks' |
11 | import { checkWebTorrentWorks } from './webtorrent' | ||
11 | 12 | ||
12 | loadLanguages() | 13 | loadLanguages() |
13 | 14 | ||
14 | async function completeVideoCheck ( | 15 | async function completeWebVideoFilesCheck (options: { |
15 | server: PeerTubeServer, | 16 | server: PeerTubeServer |
16 | video: any, | 17 | originServer: PeerTubeServer |
18 | videoUUID: string | ||
19 | fixture: string | ||
20 | files: { | ||
21 | resolution: number | ||
22 | size?: number | ||
23 | }[] | ||
24 | objectStorageBaseUrl?: string | ||
25 | }) { | ||
26 | const { originServer, server, videoUUID, files, fixture, objectStorageBaseUrl } = options | ||
27 | const video = await server.videos.getWithToken({ id: videoUUID }) | ||
28 | const serverConfig = await originServer.config.getConfig() | ||
29 | const requiresAuth = video.privacy.id === VideoPrivacy.PRIVATE || video.privacy.id === VideoPrivacy.INTERNAL | ||
30 | |||
31 | const transcodingEnabled = serverConfig.transcoding.webtorrent.enabled | ||
32 | |||
33 | for (const attributeFile of files) { | ||
34 | const file = video.files.find(f => f.resolution.id === attributeFile.resolution) | ||
35 | expect(file, `resolution ${attributeFile.resolution} does not exist`).not.to.be.undefined | ||
36 | |||
37 | let extension = getLowercaseExtension(fixture) | ||
38 | // Transcoding enabled: extension will always be .mp4 | ||
39 | if (transcodingEnabled) extension = '.mp4' | ||
40 | |||
41 | expect(file.id).to.exist | ||
42 | expect(file.magnetUri).to.have.lengthOf.above(2) | ||
43 | |||
44 | { | ||
45 | const privatePath = requiresAuth | ||
46 | ? 'private/' | ||
47 | : '' | ||
48 | const nameReg = `${uuidRegex}-${file.resolution.id}` | ||
49 | |||
50 | expect(file.torrentDownloadUrl).to.match(new RegExp(`${server.url}/download/torrents/${nameReg}.torrent`)) | ||
51 | expect(file.torrentUrl).to.match(new RegExp(`${server.url}/lazy-static/torrents/${nameReg}.torrent`)) | ||
52 | |||
53 | if (objectStorageBaseUrl && requiresAuth) { | ||
54 | expect(file.fileUrl).to.match(new RegExp(`${originServer.url}/object-storage-proxy/webseed/${privatePath}${nameReg}${extension}`)) | ||
55 | } else if (objectStorageBaseUrl) { | ||
56 | expectStartWith(file.fileUrl, objectStorageBaseUrl) | ||
57 | } else { | ||
58 | expect(file.fileUrl).to.match(new RegExp(`${originServer.url}/static/webseed/${privatePath}${nameReg}${extension}`)) | ||
59 | } | ||
60 | |||
61 | expect(file.fileDownloadUrl).to.match(new RegExp(`${originServer.url}/download/videos/${nameReg}${extension}`)) | ||
62 | } | ||
63 | |||
64 | { | ||
65 | const token = requiresAuth | ||
66 | ? server.accessToken | ||
67 | : undefined | ||
68 | |||
69 | await Promise.all([ | ||
70 | makeRawRequest({ url: file.torrentUrl, token, expectedStatus: HttpStatusCode.OK_200 }), | ||
71 | makeRawRequest({ url: file.torrentDownloadUrl, token, expectedStatus: HttpStatusCode.OK_200 }), | ||
72 | makeRawRequest({ url: file.metadataUrl, token, expectedStatus: HttpStatusCode.OK_200 }), | ||
73 | makeRawRequest({ url: file.fileUrl, token, expectedStatus: HttpStatusCode.OK_200 }), | ||
74 | makeRawRequest({ | ||
75 | url: file.fileDownloadUrl, | ||
76 | token, | ||
77 | expectedStatus: objectStorageBaseUrl ? HttpStatusCode.FOUND_302 : HttpStatusCode.OK_200 | ||
78 | }) | ||
79 | ]) | ||
80 | } | ||
81 | |||
82 | expect(file.resolution.id).to.equal(attributeFile.resolution) | ||
83 | |||
84 | if (file.resolution.id === VideoResolution.H_NOVIDEO) { | ||
85 | expect(file.resolution.label).to.equal('Audio') | ||
86 | } else { | ||
87 | expect(file.resolution.label).to.equal(attributeFile.resolution + 'p') | ||
88 | } | ||
89 | |||
90 | if (attributeFile.size) { | ||
91 | const minSize = attributeFile.size - ((10 * attributeFile.size) / 100) | ||
92 | const maxSize = attributeFile.size + ((10 * attributeFile.size) / 100) | ||
93 | expect( | ||
94 | file.size, | ||
95 | 'File size for resolution ' + file.resolution.label + ' outside confidence interval (' + minSize + '> size <' + maxSize + ')' | ||
96 | ).to.be.above(minSize).and.below(maxSize) | ||
97 | } | ||
98 | |||
99 | await checkWebTorrentWorks(file.magnetUri) | ||
100 | } | ||
101 | } | ||
102 | |||
103 | async function completeVideoCheck (options: { | ||
104 | server: PeerTubeServer | ||
105 | originServer: PeerTubeServer | ||
106 | videoUUID: string | ||
17 | attributes: { | 107 | attributes: { |
18 | name: string | 108 | name: string |
19 | category: number | 109 | category: number |
@@ -50,13 +140,14 @@ async function completeVideoCheck ( | |||
50 | thumbnailfile?: string | 140 | thumbnailfile?: string |
51 | previewfile?: string | 141 | previewfile?: string |
52 | } | 142 | } |
53 | ) { | 143 | }) { |
144 | const { attributes, originServer, server, videoUUID } = options | ||
145 | |||
146 | const video = await server.videos.get({ id: videoUUID }) | ||
147 | |||
54 | if (!attributes.likes) attributes.likes = 0 | 148 | if (!attributes.likes) attributes.likes = 0 |
55 | if (!attributes.dislikes) attributes.dislikes = 0 | 149 | if (!attributes.dislikes) attributes.dislikes = 0 |
56 | 150 | ||
57 | const host = new URL(server.url).host | ||
58 | const originHost = attributes.account.host | ||
59 | |||
60 | expect(video.name).to.equal(attributes.name) | 151 | expect(video.name).to.equal(attributes.name) |
61 | expect(video.category.id).to.equal(attributes.category) | 152 | expect(video.category.id).to.equal(attributes.category) |
62 | expect(video.category.label).to.equal(attributes.category !== null ? VIDEO_CATEGORIES[attributes.category] : 'Unknown') | 153 | expect(video.category.label).to.equal(attributes.category !== null ? VIDEO_CATEGORIES[attributes.category] : 'Unknown') |
@@ -77,7 +168,7 @@ async function completeVideoCheck ( | |||
77 | expect(video.dislikes).to.equal(attributes.dislikes) | 168 | expect(video.dislikes).to.equal(attributes.dislikes) |
78 | expect(video.isLocal).to.equal(attributes.isLocal) | 169 | expect(video.isLocal).to.equal(attributes.isLocal) |
79 | expect(video.duration).to.equal(attributes.duration) | 170 | expect(video.duration).to.equal(attributes.duration) |
80 | expect(video.url).to.contain(originHost) | 171 | expect(video.url).to.contain(originServer.host) |
81 | expect(dateIsValid(video.createdAt)).to.be.true | 172 | expect(dateIsValid(video.createdAt)).to.be.true |
82 | expect(dateIsValid(video.publishedAt)).to.be.true | 173 | expect(dateIsValid(video.publishedAt)).to.be.true |
83 | expect(dateIsValid(video.updatedAt)).to.be.true | 174 | expect(dateIsValid(video.updatedAt)).to.be.true |
@@ -92,67 +183,28 @@ async function completeVideoCheck ( | |||
92 | expect(video.originallyPublishedAt).to.be.null | 183 | expect(video.originallyPublishedAt).to.be.null |
93 | } | 184 | } |
94 | 185 | ||
95 | const videoDetails = await server.videos.get({ id: video.uuid }) | 186 | expect(video.files).to.have.lengthOf(attributes.files.length) |
96 | 187 | expect(video.tags).to.deep.equal(attributes.tags) | |
97 | expect(videoDetails.files).to.have.lengthOf(attributes.files.length) | 188 | expect(video.account.name).to.equal(attributes.account.name) |
98 | expect(videoDetails.tags).to.deep.equal(attributes.tags) | 189 | expect(video.account.host).to.equal(attributes.account.host) |
99 | expect(videoDetails.account.name).to.equal(attributes.account.name) | ||
100 | expect(videoDetails.account.host).to.equal(attributes.account.host) | ||
101 | expect(video.channel.displayName).to.equal(attributes.channel.displayName) | 190 | expect(video.channel.displayName).to.equal(attributes.channel.displayName) |
102 | expect(video.channel.name).to.equal(attributes.channel.name) | 191 | expect(video.channel.name).to.equal(attributes.channel.name) |
103 | expect(videoDetails.channel.host).to.equal(attributes.account.host) | 192 | expect(video.channel.host).to.equal(attributes.account.host) |
104 | expect(videoDetails.channel.isLocal).to.equal(attributes.channel.isLocal) | 193 | expect(video.channel.isLocal).to.equal(attributes.channel.isLocal) |
105 | expect(dateIsValid(videoDetails.channel.createdAt.toString())).to.be.true | 194 | expect(dateIsValid(video.channel.createdAt.toString())).to.be.true |
106 | expect(dateIsValid(videoDetails.channel.updatedAt.toString())).to.be.true | 195 | expect(dateIsValid(video.channel.updatedAt.toString())).to.be.true |
107 | expect(videoDetails.commentsEnabled).to.equal(attributes.commentsEnabled) | 196 | expect(video.commentsEnabled).to.equal(attributes.commentsEnabled) |
108 | expect(videoDetails.downloadEnabled).to.equal(attributes.downloadEnabled) | 197 | expect(video.downloadEnabled).to.equal(attributes.downloadEnabled) |
109 | |||
110 | for (const attributeFile of attributes.files) { | ||
111 | const file = videoDetails.files.find(f => f.resolution.id === attributeFile.resolution) | ||
112 | expect(file).not.to.be.undefined | ||
113 | |||
114 | let extension = getLowercaseExtension(attributes.fixture) | ||
115 | // Transcoding enabled: extension will always be .mp4 | ||
116 | if (attributes.files.length > 1) extension = '.mp4' | ||
117 | |||
118 | expect(file.id).to.exist | ||
119 | expect(file.magnetUri).to.have.lengthOf.above(2) | ||
120 | |||
121 | expect(file.torrentDownloadUrl).to.match(new RegExp(`http://${host}/download/torrents/${uuidRegex}-${file.resolution.id}.torrent`)) | ||
122 | expect(file.torrentUrl).to.match(new RegExp(`http://${host}/lazy-static/torrents/${uuidRegex}-${file.resolution.id}.torrent`)) | ||
123 | |||
124 | expect(file.fileUrl).to.match(new RegExp(`http://${originHost}/static/webseed/${uuidRegex}-${file.resolution.id}${extension}`)) | ||
125 | expect(file.fileDownloadUrl).to.match(new RegExp(`http://${originHost}/download/videos/${uuidRegex}-${file.resolution.id}${extension}`)) | ||
126 | 198 | ||
127 | await Promise.all([ | 199 | expect(video.thumbnailPath).to.exist |
128 | makeRawRequest({ url: file.torrentUrl, expectedStatus: HttpStatusCode.OK_200 }), | 200 | await testImage(server.url, attributes.thumbnailfile || attributes.fixture, video.thumbnailPath) |
129 | makeRawRequest({ url: file.torrentDownloadUrl, expectedStatus: HttpStatusCode.OK_200 }), | ||
130 | makeRawRequest({ url: file.metadataUrl, expectedStatus: HttpStatusCode.OK_200 }) | ||
131 | ]) | ||
132 | |||
133 | expect(file.resolution.id).to.equal(attributeFile.resolution) | ||
134 | expect(file.resolution.label).to.equal(attributeFile.resolution + 'p') | ||
135 | |||
136 | const minSize = attributeFile.size - ((10 * attributeFile.size) / 100) | ||
137 | const maxSize = attributeFile.size + ((10 * attributeFile.size) / 100) | ||
138 | expect( | ||
139 | file.size, | ||
140 | 'File size for resolution ' + file.resolution.label + ' outside confidence interval (' + minSize + '> size <' + maxSize + ')' | ||
141 | ).to.be.above(minSize).and.below(maxSize) | ||
142 | |||
143 | const torrent = await webtorrentAdd(file.magnetUri, true) | ||
144 | expect(torrent.files).to.be.an('array') | ||
145 | expect(torrent.files.length).to.equal(1) | ||
146 | expect(torrent.files[0].path).to.exist.and.to.not.equal('') | ||
147 | } | ||
148 | |||
149 | expect(videoDetails.thumbnailPath).to.exist | ||
150 | await testImage(server.url, attributes.thumbnailfile || attributes.fixture, videoDetails.thumbnailPath) | ||
151 | 201 | ||
152 | if (attributes.previewfile) { | 202 | if (attributes.previewfile) { |
153 | expect(videoDetails.previewPath).to.exist | 203 | expect(video.previewPath).to.exist |
154 | await testImage(server.url, attributes.previewfile, videoDetails.previewPath) | 204 | await testImage(server.url, attributes.previewfile, video.previewPath) |
155 | } | 205 | } |
206 | |||
207 | await completeWebVideoFilesCheck({ server, originServer, videoUUID: video.uuid, ...pick(attributes, [ 'fixture', 'files' ]) }) | ||
156 | } | 208 | } |
157 | 209 | ||
158 | async function checkVideoFilesWereRemoved (options: { | 210 | async function checkVideoFilesWereRemoved (options: { |
@@ -245,6 +297,7 @@ async function uploadRandomVideoOnServers ( | |||
245 | 297 | ||
246 | export { | 298 | export { |
247 | completeVideoCheck, | 299 | completeVideoCheck, |
300 | completeWebVideoFilesCheck, | ||
248 | checkUploadVideoParam, | 301 | checkUploadVideoParam, |
249 | uploadRandomVideoOnServers, | 302 | uploadRandomVideoOnServers, |
250 | checkVideoFilesWereRemoved, | 303 | checkVideoFilesWereRemoved, |