]>
Commit | Line | Data |
---|---|---|
a1587156 | 1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/no-floating-promises */ |
a20399c9 C |
2 | |
3 | import { expect } from 'chai' | |
d23dd9fb | 4 | import { pathExists, readdir } from 'fs-extra' |
83903cb6 | 5 | import { basename, join } from 'path' |
ea54cd04 | 6 | import { getLowercaseExtension } from '@server/helpers/core-utils' |
83903cb6 C |
7 | import { uuidRegex } from '@shared/core-utils' |
8 | import { HttpStatusCode, VideoCaption, VideoDetails } from '@shared/models' | |
d23dd9fb C |
9 | import { VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_PRIVACIES } from '../../../server/initializers/constants' |
10 | import { dateIsValid, testImage, webtorrentAdd } from '../miscs' | |
11 | import { makeRawRequest } from '../requests/requests' | |
12 | import { waitJobs } from '../server' | |
254d3579 | 13 | import { PeerTubeServer } from '../server/server' |
d23dd9fb | 14 | import { VideoEdit } from './videos-command' |
68e70a74 | 15 | |
83903cb6 C |
16 | async function checkVideoFilesWereRemoved (options: { |
17 | server: PeerTubeServer | |
18 | video: VideoDetails | |
19 | captions?: VideoCaption[] | |
20 | onlyVideoFiles?: boolean // default false | |
21 | }) { | |
22 | const { video, server, captions = [], onlyVideoFiles = false } = options | |
23 | ||
24 | const webtorrentFiles = video.files || [] | |
25 | const hlsFiles = video.streamingPlaylists[0]?.files || [] | |
26 | ||
27 | const thumbnailName = basename(video.thumbnailPath) | |
28 | const previewName = basename(video.previewPath) | |
29 | ||
30 | const torrentNames = webtorrentFiles.concat(hlsFiles).map(f => basename(f.torrentUrl)) | |
31 | ||
32 | const captionNames = captions.map(c => basename(c.captionPath)) | |
33 | ||
34 | const webtorrentFilenames = webtorrentFiles.map(f => basename(f.fileUrl)) | |
35 | const hlsFilenames = hlsFiles.map(f => basename(f.fileUrl)) | |
36 | ||
37 | let directories: { [ directory: string ]: string[] } = { | |
38 | videos: webtorrentFilenames, | |
39 | redundancy: webtorrentFilenames, | |
40 | [join('playlists', 'hls')]: hlsFilenames, | |
41 | [join('redundancy', 'hls')]: hlsFilenames | |
42 | } | |
43 | ||
44 | if (onlyVideoFiles !== true) { | |
45 | directories = { | |
46 | ...directories, | |
47 | ||
48 | thumbnails: [ thumbnailName ], | |
49 | previews: [ previewName ], | |
50 | torrents: torrentNames, | |
51 | captions: captionNames | |
52 | } | |
53 | } | |
54 | ||
55 | for (const directory of Object.keys(directories)) { | |
89d241a7 | 56 | const directoryPath = server.servers.buildDirectory(directory) |
f05a1c30 | 57 | |
df0b219d C |
58 | const directoryExists = await pathExists(directoryPath) |
59 | if (directoryExists === false) continue | |
f05a1c30 | 60 | |
83903cb6 C |
61 | const existingFiles = await readdir(directoryPath) |
62 | for (const existingFile of existingFiles) { | |
63 | for (const shouldNotExist of directories[directory]) { | |
64 | expect(existingFile, `File ${existingFile} should not exist in ${directoryPath}`).to.not.contain(shouldNotExist) | |
65 | } | |
f05a1c30 C |
66 | } |
67 | } | |
68 | } | |
69 | ||
83903cb6 C |
70 | async function saveVideoInServers (servers: PeerTubeServer[], uuid: string) { |
71 | for (const server of servers) { | |
72 | server.store.videoDetails = await server.videos.get({ id: uuid }) | |
73 | } | |
74 | } | |
75 | ||
f6d6e7f8 | 76 | function checkUploadVideoParam ( |
254d3579 | 77 | server: PeerTubeServer, |
f6d6e7f8 | 78 | token: string, |
d23dd9fb C |
79 | attributes: Partial<VideoEdit>, |
80 | expectedStatus = HttpStatusCode.OK_200, | |
f6d6e7f8 | 81 | mode: 'legacy' | 'resumable' = 'legacy' |
82 | ) { | |
83 | return mode === 'legacy' | |
89d241a7 C |
84 | ? server.videos.buildLegacyUpload({ token, attributes, expectedStatus }) |
85 | : server.videos.buildResumeUpload({ token, attributes, expectedStatus }) | |
fdbda9e3 C |
86 | } |
87 | ||
a20399c9 | 88 | async function completeVideoCheck ( |
254d3579 | 89 | server: PeerTubeServer, |
a20399c9 C |
90 | video: any, |
91 | attributes: { | |
92 | name: string | |
93 | category: number | |
94 | licence: number | |
9d3ef9fe | 95 | language: string |
a20399c9 | 96 | nsfw: boolean |
47564bbe | 97 | commentsEnabled: boolean |
7f2cfe3a | 98 | downloadEnabled: boolean |
a20399c9 | 99 | description: string |
53a61317 | 100 | publishedAt?: string |
2422c46b | 101 | support: string |
a1587156 | 102 | originallyPublishedAt?: string |
b64c950a C |
103 | account: { |
104 | name: string | |
105 | host: string | |
106 | } | |
f6eebcb3 C |
107 | isLocal: boolean |
108 | tags: string[] | |
109 | privacy: number | |
110 | likes?: number | |
111 | dislikes?: number | |
112 | duration: number | |
a20399c9 | 113 | channel: { |
f6eebcb3 C |
114 | displayName: string |
115 | name: string | |
b1f5b93e | 116 | description |
a20399c9 C |
117 | isLocal: boolean |
118 | } | |
f6eebcb3 | 119 | fixture: string |
a20399c9 C |
120 | files: { |
121 | resolution: number | |
122 | size: number | |
a1587156 | 123 | }[] |
ac81d1a0 C |
124 | thumbnailfile?: string |
125 | previewfile?: string | |
a20399c9 C |
126 | } |
127 | ) { | |
b1f5b93e C |
128 | if (!attributes.likes) attributes.likes = 0 |
129 | if (!attributes.dislikes) attributes.dislikes = 0 | |
130 | ||
d23dd9fb | 131 | const host = new URL(server.url).host |
90a8bd30 C |
132 | const originHost = attributes.account.host |
133 | ||
a20399c9 | 134 | expect(video.name).to.equal(attributes.name) |
09700934 | 135 | expect(video.category.id).to.equal(attributes.category) |
9d3ef9fe | 136 | expect(video.category.label).to.equal(attributes.category !== null ? VIDEO_CATEGORIES[attributes.category] : 'Misc') |
09700934 | 137 | expect(video.licence.id).to.equal(attributes.licence) |
9d3ef9fe | 138 | expect(video.licence.label).to.equal(attributes.licence !== null ? VIDEO_LICENCES[attributes.licence] : 'Unknown') |
09700934 | 139 | expect(video.language.id).to.equal(attributes.language) |
9d3ef9fe | 140 | expect(video.language.label).to.equal(attributes.language !== null ? VIDEO_LANGUAGES[attributes.language] : 'Unknown') |
2243730c C |
141 | expect(video.privacy.id).to.deep.equal(attributes.privacy) |
142 | expect(video.privacy.label).to.deep.equal(VIDEO_PRIVACIES[attributes.privacy]) | |
a20399c9 C |
143 | expect(video.nsfw).to.equal(attributes.nsfw) |
144 | expect(video.description).to.equal(attributes.description) | |
03e12d7c | 145 | expect(video.account.id).to.be.a('number') |
b64c950a C |
146 | expect(video.account.host).to.equal(attributes.account.host) |
147 | expect(video.account.name).to.equal(attributes.account.name) | |
f6eebcb3 C |
148 | expect(video.channel.displayName).to.equal(attributes.channel.displayName) |
149 | expect(video.channel.name).to.equal(attributes.channel.name) | |
b1f5b93e C |
150 | expect(video.likes).to.equal(attributes.likes) |
151 | expect(video.dislikes).to.equal(attributes.dislikes) | |
a20399c9 | 152 | expect(video.isLocal).to.equal(attributes.isLocal) |
b1f5b93e | 153 | expect(video.duration).to.equal(attributes.duration) |
a20399c9 | 154 | expect(dateIsValid(video.createdAt)).to.be.true |
c49db162 | 155 | expect(dateIsValid(video.publishedAt)).to.be.true |
a20399c9 C |
156 | expect(dateIsValid(video.updatedAt)).to.be.true |
157 | ||
53a61317 | 158 | if (attributes.publishedAt) { |
53a61317 C |
159 | expect(video.publishedAt).to.equal(attributes.publishedAt) |
160 | } | |
161 | ||
7519127b C |
162 | if (attributes.originallyPublishedAt) { |
163 | expect(video.originallyPublishedAt).to.equal(attributes.originallyPublishedAt) | |
164 | } else { | |
165 | expect(video.originallyPublishedAt).to.be.null | |
166 | } | |
167 | ||
89d241a7 | 168 | const videoDetails = await server.videos.get({ id: video.uuid }) |
a20399c9 C |
169 | |
170 | expect(videoDetails.files).to.have.lengthOf(attributes.files.length) | |
171 | expect(videoDetails.tags).to.deep.equal(attributes.tags) | |
19a3b914 C |
172 | expect(videoDetails.account.name).to.equal(attributes.account.name) |
173 | expect(videoDetails.account.host).to.equal(attributes.account.host) | |
f6eebcb3 C |
174 | expect(video.channel.displayName).to.equal(attributes.channel.displayName) |
175 | expect(video.channel.name).to.equal(attributes.channel.name) | |
0f320037 | 176 | expect(videoDetails.channel.host).to.equal(attributes.account.host) |
a20399c9 | 177 | expect(videoDetails.channel.isLocal).to.equal(attributes.channel.isLocal) |
0f320037 C |
178 | expect(dateIsValid(videoDetails.channel.createdAt.toString())).to.be.true |
179 | expect(dateIsValid(videoDetails.channel.updatedAt.toString())).to.be.true | |
180 | expect(videoDetails.commentsEnabled).to.equal(attributes.commentsEnabled) | |
7f2cfe3a | 181 | expect(videoDetails.downloadEnabled).to.equal(attributes.downloadEnabled) |
a20399c9 C |
182 | |
183 | for (const attributeFile of attributes.files) { | |
5d00a3d7 | 184 | const file = videoDetails.files.find(f => f.resolution.id === attributeFile.resolution) |
a20399c9 C |
185 | expect(file).not.to.be.undefined |
186 | ||
ea54cd04 | 187 | let extension = getLowercaseExtension(attributes.fixture) |
48f07b4a C |
188 | // Transcoding enabled: extension will always be .mp4 |
189 | if (attributes.files.length > 1) extension = '.mp4' | |
b1f5b93e | 190 | |
a20399c9 | 191 | expect(file.magnetUri).to.have.lengthOf.above(2) |
90a8bd30 | 192 | |
83903cb6 C |
193 | expect(file.torrentDownloadUrl).to.match(new RegExp(`http://${host}/download/torrents/${uuidRegex}-${file.resolution.id}.torrent`)) |
194 | expect(file.torrentUrl).to.match(new RegExp(`http://${host}/lazy-static/torrents/${uuidRegex}-${file.resolution.id}.torrent`)) | |
90a8bd30 | 195 | |
83903cb6 C |
196 | expect(file.fileUrl).to.match(new RegExp(`http://${originHost}/static/webseed/${uuidRegex}-${file.resolution.id}${extension}`)) |
197 | expect(file.fileDownloadUrl).to.match(new RegExp(`http://${originHost}/download/videos/${uuidRegex}-${file.resolution.id}${extension}`)) | |
90a8bd30 C |
198 | |
199 | await Promise.all([ | |
200 | makeRawRequest(file.torrentUrl, 200), | |
201 | makeRawRequest(file.torrentDownloadUrl, 200), | |
83903cb6 | 202 | makeRawRequest(file.metadataUrl, 200) |
90a8bd30 C |
203 | ]) |
204 | ||
09700934 C |
205 | expect(file.resolution.id).to.equal(attributeFile.resolution) |
206 | expect(file.resolution.label).to.equal(attributeFile.resolution + 'p') | |
b1f5b93e C |
207 | |
208 | const minSize = attributeFile.size - ((10 * attributeFile.size) / 100) | |
209 | const maxSize = attributeFile.size + ((10 * attributeFile.size) / 100) | |
a1587156 C |
210 | expect( |
211 | file.size, | |
212 | 'File size for resolution ' + file.resolution.label + ' outside confidence interval (' + minSize + '> size <' + maxSize + ')' | |
213 | ).to.be.above(minSize).and.below(maxSize) | |
a20399c9 | 214 | |
d7a25329 | 215 | const torrent = await webtorrentAdd(file.magnetUri, true) |
a20399c9 C |
216 | expect(torrent.files).to.be.an('array') |
217 | expect(torrent.files.length).to.equal(1) | |
218 | expect(torrent.files[0].path).to.exist.and.to.not.equal('') | |
219 | } | |
44d4ee4f | 220 | |
08a47c75 | 221 | expect(videoDetails.thumbnailPath).to.exist |
d23dd9fb | 222 | await testImage(server.url, attributes.thumbnailfile || attributes.fixture, videoDetails.thumbnailPath) |
44d4ee4f C |
223 | |
224 | if (attributes.previewfile) { | |
08a47c75 | 225 | expect(videoDetails.previewPath).to.exist |
d23dd9fb | 226 | await testImage(server.url, attributes.previewfile, videoDetails.previewPath) |
44d4ee4f | 227 | } |
a20399c9 C |
228 | } |
229 | ||
8eb07b01 | 230 | // serverNumber starts from 1 |
d23dd9fb | 231 | async function uploadRandomVideoOnServers ( |
254d3579 | 232 | servers: PeerTubeServer[], |
d23dd9fb C |
233 | serverNumber: number, |
234 | additionalParams?: VideoEdit & { prefixName?: string } | |
235 | ) { | |
8eb07b01 | 236 | const server = servers.find(s => s.serverNumber === serverNumber) |
4c7e60bc | 237 | const res = await server.videos.randomUpload({ wait: false, additionalParams }) |
8eb07b01 C |
238 | |
239 | await waitJobs(servers) | |
240 | ||
241 | return res | |
242 | } | |
243 | ||
0e1dc3e7 C |
244 | // --------------------------------------------------------------------------- |
245 | ||
246 | export { | |
f6d6e7f8 | 247 | checkUploadVideoParam, |
f05a1c30 | 248 | completeVideoCheck, |
d23dd9fb | 249 | uploadRandomVideoOnServers, |
83903cb6 C |
250 | checkVideoFilesWereRemoved, |
251 | saveVideoInServers | |
0e1dc3e7 | 252 | } |