From: Chocobozzz Date: Thu, 28 Dec 2017 12:59:22 +0000 (+0100) Subject: Tests directories refractor X-Git-Tag: v0.0.1-alpha~78 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=c5d31dba56d669c0df0209761c43c5a6ac7cec4a;p=oweals%2Fpeertube.git Tests directories refractor --- diff --git a/server/tests/activitypub.ts b/server/tests/activitypub.ts index 333e02e84..94615c63f 100644 --- a/server/tests/activitypub.ts +++ b/server/tests/activitypub.ts @@ -2,9 +2,7 @@ import * as chai from 'chai' import 'mocha' -import { flushTests, killallServers, ServerInfo, setAccessTokensToServers } from './utils' -import { runServer } from './utils/servers' -import { makeActivityPubGetRequest } from './utils/activitypub' +import { flushTests, killallServers, makeActivityPubGetRequest, runServer, ServerInfo, setAccessTokensToServers } from './utils' const expect = chai.expect diff --git a/server/tests/api/check-params/services.ts b/server/tests/api/check-params/services.ts index 780254df5..f82520574 100644 --- a/server/tests/api/check-params/services.ts +++ b/server/tests/api/check-params/services.ts @@ -9,7 +9,7 @@ import { setAccessTokensToServers, killallServers } from '../../utils' -import { getVideosList, uploadVideo } from '../../utils/videos' +import { getVideosList, uploadVideo } from '../../utils/videos/videos' describe('Test services API validators', function () { let server diff --git a/server/tests/api/check-params/video-comments.ts b/server/tests/api/check-params/video-comments.ts index e8d7ddf38..f3832bd2c 100644 --- a/server/tests/api/check-params/video-comments.ts +++ b/server/tests/api/check-params/video-comments.ts @@ -3,7 +3,7 @@ import 'mocha' import * as request from 'supertest' import { flushTests, killallServers, makePostBodyRequest, runServer, ServerInfo, setAccessTokensToServers, uploadVideo } from '../../utils' -import { addVideoCommentThread } from '../../utils/video-comments' +import { addVideoCommentThread } from '../../utils/videos/video-comments' describe('Test video comments API validator', function () { let pathThread: string diff --git a/server/tests/api/config.ts b/server/tests/api/config.ts deleted file mode 100644 index 61ae57977..000000000 --- a/server/tests/api/config.ts +++ /dev/null @@ -1,54 +0,0 @@ -/* tslint:disable:no-unused-expression */ - -import 'mocha' -import * as chai from 'chai' -const expect = chai.expect - -import { - getConfig, - flushTests, - runServer, - registerUser -} from '../utils' - -describe('Test config', function () { - let server = null - - before(async function () { - this.timeout(10000) - - await flushTests() - server = await runServer(1) - }) - - it('Should have a correct config on a server with registration enabled', async function () { - const res = await getConfig(server.url) - const data = res.body - - expect(data.signup.allowed).to.be.true - }) - - it('Should have a correct config on a server with registration enabled and a users limit', async function () { - this.timeout(5000) - - await Promise.all([ - registerUser(server.url, 'user1', 'super password'), - registerUser(server.url, 'user2', 'super password'), - registerUser(server.url, 'user3', 'super password') - ]) - - const res = await getConfig(server.url) - const data = res.body - - expect(data.signup.allowed).to.be.false - }) - - after(async function () { - process.kill(-server.app.pid) - - // Keep the logs if the test failed - if (this['ok']) { - await flushTests() - } - }) -}) diff --git a/server/tests/api/follows.ts b/server/tests/api/follows.ts deleted file mode 100644 index 2ffa426a0..000000000 --- a/server/tests/api/follows.ts +++ /dev/null @@ -1,315 +0,0 @@ -/* tslint:disable:no-unused-expression */ - -import * as chai from 'chai' -import 'mocha' -import { VideoComment, VideoCommentThreadTree } from '../../../shared/models/videos/video-comment.model' - -import { - flushAndRunMultipleServers, flushTests, getVideosList, killallServers, ServerInfo, setAccessTokensToServers, uploadVideo, - wait -} from '../utils' -import { follow, getFollowersListPaginationAndSort, getFollowingListPaginationAndSort, unfollow } from '../utils/follows' -import { getUserAccessToken } from '../utils/login' -import { dateIsValid, webtorrentAdd } from '../utils/miscs' -import { createUser } from '../utils/users' -import { addVideoCommentReply, addVideoCommentThread, getVideoCommentThreads, getVideoThreadComments } from '../utils/video-comments' -import { getVideo, rateVideo, testVideoImage } from '../utils/videos' - -const expect = chai.expect - -describe('Test follows', function () { - let servers: ServerInfo[] = [] - - before(async function () { - this.timeout(20000) - - servers = await flushAndRunMultipleServers(3) - - // Get the access tokens - await setAccessTokensToServers(servers) - }) - - it('Should not have followers', async function () { - for (const server of servers) { - const res = await getFollowersListPaginationAndSort(server.url, 0, 5, 'createdAt') - const follows = res.body.data - - expect(res.body.total).to.equal(0) - expect(follows).to.be.an('array') - expect(follows.length).to.equal(0) - } - }) - - it('Should not have following', async function () { - for (const server of servers) { - const res = await getFollowingListPaginationAndSort(server.url, 0, 5, 'createdAt') - const follows = res.body.data - - expect(res.body.total).to.equal(0) - expect(follows).to.be.an('array') - expect(follows.length).to.equal(0) - } - }) - - it('Should have server 1 following server 2 and 3', async function () { - this.timeout(10000) - - await follow(servers[0].url, [ servers[1].url, servers[2].url ], servers[0].accessToken) - - await wait(7000) - }) - - it('Should have 2 followings on server 1', async function () { - let res = await getFollowingListPaginationAndSort(servers[0].url, 0, 1, 'createdAt') - let follows = res.body.data - - expect(res.body.total).to.equal(2) - expect(follows).to.be.an('array') - expect(follows.length).to.equal(1) - - res = await getFollowingListPaginationAndSort(servers[0].url, 1, 1, 'createdAt') - follows = follows.concat(res.body.data) - - const server2Follow = follows.find(f => f.following.host === 'localhost:9002') - const server3Follow = follows.find(f => f.following.host === 'localhost:9003') - - expect(server2Follow).to.not.be.undefined - expect(server3Follow).to.not.be.undefined - expect(server2Follow.state).to.equal('accepted') - expect(server3Follow.state).to.equal('accepted') - }) - - it('Should have 0 followings on server 1 and 2', async function () { - for (const server of [ servers[1], servers[2] ]) { - const res = await getFollowingListPaginationAndSort(server.url, 0, 5, 'createdAt') - const follows = res.body.data - - expect(res.body.total).to.equal(0) - expect(follows).to.be.an('array') - expect(follows.length).to.equal(0) - } - }) - - it('Should have 1 followers on server 2 and 3', async function () { - for (const server of [ servers[1], servers[2] ]) { - let res = await getFollowersListPaginationAndSort(server.url, 0, 1, 'createdAt') - - let follows = res.body.data - expect(res.body.total).to.equal(1) - expect(follows).to.be.an('array') - expect(follows.length).to.equal(1) - expect(follows[0].follower.host).to.equal('localhost:9001') - } - }) - - it('Should have 0 followers on server 1', async function () { - const res = await getFollowersListPaginationAndSort(servers[0].url, 0, 5, 'createdAt') - const follows = res.body.data - - expect(res.body.total).to.equal(0) - expect(follows).to.be.an('array') - expect(follows.length).to.equal(0) - }) - - it('Should unfollow server 3 on server 1', async function () { - this.timeout(5000) - - await unfollow(servers[0].url, servers[0].accessToken, servers[2]) - - await wait(3000) - }) - - it('Should not follow server 3 on server 1 anymore', async function () { - const res = await getFollowingListPaginationAndSort(servers[0].url, 0, 2, 'createdAt') - let follows = res.body.data - - expect(res.body.total).to.equal(1) - expect(follows).to.be.an('array') - expect(follows.length).to.equal(1) - - expect(follows[0].following.host).to.equal('localhost:9002') - }) - - it('Should not have server 1 as follower on server 3 anymore', async function () { - const res = await getFollowersListPaginationAndSort(servers[2].url, 0, 1, 'createdAt') - - let follows = res.body.data - expect(res.body.total).to.equal(0) - expect(follows).to.be.an('array') - expect(follows.length).to.equal(0) - }) - - it('Should upload a video on server 2 ans 3 and propagate only the video of server 2', async function () { - this.timeout(10000) - - await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'server2' }) - await uploadVideo(servers[2].url, servers[2].accessToken, { name: 'server3' }) - - await wait(5000) - - let res = await getVideosList(servers[0].url) - expect(res.body.total).to.equal(1) - expect(res.body.data[0].name).to.equal('server2') - - res = await getVideosList(servers[1].url) - expect(res.body.total).to.equal(1) - expect(res.body.data[0].name).to.equal('server2') - - res = await getVideosList(servers[2].url) - expect(res.body.total).to.equal(1) - expect(res.body.data[0].name).to.equal('server3') - }) - - it('Should propagate previous uploaded videos on a new following', async function () { - this.timeout(20000) - - const video4Attributes = { - name: 'server3-4', - category: 2, - nsfw: true, - licence: 6, - tags: [ 'tag1', 'tag2', 'tag3' ] - } - - await uploadVideo(servers[2].url, servers[2].accessToken, { name: 'server3-2' }) - await uploadVideo(servers[2].url, servers[2].accessToken, { name: 'server3-3' }) - await uploadVideo(servers[2].url, servers[2].accessToken, video4Attributes) - await uploadVideo(servers[2].url, servers[2].accessToken, { name: 'server3-5' }) - await uploadVideo(servers[2].url, servers[2].accessToken, { name: 'server3-6' }) - - { - const user = { username: 'captain', password: 'password' } - await createUser(servers[2].url, servers[2].accessToken, user.username, user.password) - const userAccessToken = await getUserAccessToken(servers[2], user) - - const resVideos = await getVideosList(servers[ 2 ].url) - const video4 = resVideos.body.data.find(v => v.name === 'server3-4') - - { - await rateVideo(servers[ 2 ].url, servers[ 2 ].accessToken, video4.id, 'like') - await rateVideo(servers[ 2 ].url, userAccessToken, video4.id, 'dislike') - } - - { - const text = 'my super first comment' - const res = await addVideoCommentThread(servers[ 2 ].url, servers[ 2 ].accessToken, video4.id, text) - const threadId = res.body.comment.id - - const text1 = 'my super answer to thread 1' - const childCommentRes = await addVideoCommentReply(servers[ 2 ].url, servers[ 2 ].accessToken, video4.id, threadId, text1) - const childCommentId = childCommentRes.body.comment.id - - const text2 = 'my super answer to answer of thread 1' - await addVideoCommentReply(servers[ 2 ].url, servers[ 2 ].accessToken, video4.id, childCommentId, text2) - - const text3 = 'my second answer to thread 1' - await addVideoCommentReply(servers[ 2 ].url, servers[ 2 ].accessToken, video4.id, threadId, text3) - } - } - - await wait(5000) - - // Server 1 follows server 3 - await follow(servers[0].url, [ servers[2].url ], servers[0].accessToken) - - await wait(7000) - - let res = await getVideosList(servers[0].url) - expect(res.body.total).to.equal(7) - - const video2 = res.body.data.find(v => v.name === 'server3-2') - const video4 = res.body.data.find(v => v.name === 'server3-4') - const video6 = res.body.data.find(v => v.name === 'server3-6') - - expect(video2).to.not.be.undefined - expect(video4).to.not.be.undefined - expect(video6).to.not.be.undefined - - const res2 = await getVideo(servers[0].url, video4.id) - const videoDetails = res2.body - - expect(videoDetails.name).to.equal('server3-4') - expect(videoDetails.category).to.equal(2) - expect(videoDetails.categoryLabel).to.equal('Films') - expect(videoDetails.licence).to.equal(6) - expect(videoDetails.licenceLabel).to.equal('Attribution - Non Commercial - No Derivatives') - expect(videoDetails.language).to.equal(3) - expect(videoDetails.languageLabel).to.equal('Mandarin') - expect(videoDetails.nsfw).to.be.ok - expect(videoDetails.description).to.equal('my super description') - expect(videoDetails.serverHost).to.equal('localhost:9003') - expect(videoDetails.accountName).to.equal('root') - expect(videoDetails.likes).to.equal(1) - expect(videoDetails.dislikes).to.equal(1) - expect(videoDetails.isLocal).to.be.false - expect(videoDetails.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) - expect(dateIsValid(videoDetails.createdAt)).to.be.true - expect(dateIsValid(videoDetails.updatedAt)).to.be.true - expect(videoDetails.files).to.have.lengthOf(1) - - const file = videoDetails.files[0] - const magnetUri = file.magnetUri - expect(file.magnetUri).to.have.lengthOf.above(2) - expect(file.torrentUrl).to.equal(`${servers[2].url}/static/torrents/${videoDetails.uuid}-${file.resolution}.torrent`) - expect(file.fileUrl).to.equal(`${servers[2].url}/static/webseed/${videoDetails.uuid}-${file.resolution}.webm`) - expect(file.resolution).to.equal(720) - expect(file.resolutionLabel).to.equal('720p') - expect(file.size).to.equal(218910) - - const test = await testVideoImage(servers[2].url, 'video_short.webm', videoDetails.thumbnailPath) - expect(test).to.equal(true) - - const torrent = await webtorrentAdd(magnetUri) - expect(torrent.files).to.be.an('array') - expect(torrent.files.length).to.equal(1) - expect(torrent.files[0].path).to.exist.and.to.not.equal('') - - { - const res1 = await getVideoCommentThreads(servers[0].url, video4.id, 0, 5) - - expect(res1.body.total).to.equal(1) - expect(res1.body.data).to.be.an('array') - expect(res1.body.data).to.have.lengthOf(1) - - const comment: VideoComment = res1.body.data[0] - expect(comment.inReplyToCommentId).to.be.null - expect(comment.text).equal('my super first comment') - expect(comment.videoId).to.equal(video4.id) - expect(comment.id).to.equal(comment.threadId) - expect(comment.account.name).to.equal('root') - expect(comment.account.host).to.equal('localhost:9003') - expect(comment.totalReplies).to.equal(3) - expect(dateIsValid(comment.createdAt as string)).to.be.true - expect(dateIsValid(comment.updatedAt as string)).to.be.true - - const threadId = comment.threadId - - const res2 = await getVideoThreadComments(servers[0].url, video4.id, threadId) - - const tree: VideoCommentThreadTree = res2.body - expect(tree.comment.text).equal('my super first comment') - expect(tree.children).to.have.lengthOf(2) - - const firstChild = tree.children[0] - expect(firstChild.comment.text).to.equal('my super answer to thread 1') - expect(firstChild.children).to.have.lengthOf(1) - - const childOfFirstChild = firstChild.children[0] - expect(childOfFirstChild.comment.text).to.equal('my super answer to answer of thread 1') - expect(childOfFirstChild.children).to.have.lengthOf(0) - - const secondChild = tree.children[1] - expect(secondChild.comment.text).to.equal('my second answer to thread 1') - expect(secondChild.children).to.have.lengthOf(0) - } - }) - - after(async function () { - killallServers(servers) - - // Keep the logs if the test failed - if (this['ok']) { - await flushTests() - } - }) -}) diff --git a/server/tests/api/index-fast.ts b/server/tests/api/index-fast.ts index 35b414383..e591d0fd2 100644 --- a/server/tests/api/index-fast.ts +++ b/server/tests/api/index-fast.ts @@ -1,11 +1,11 @@ // Order of the tests we want to execute -import './config' +import './server/config' import './check-params' -import './users' -import './single-server' -import './video-abuse' -import './video-blacklist' -import './video-blacklist-management' -import './video-description' -import './video-privacy' -import './services' +import './users/users' +import './videos/single-server' +import './videos/video-abuse' +import './videos/video-blacklist' +import './videos/video-blacklist-management' +import './videos/video-description' +import './videos/video-privacy' +import './videos/services' diff --git a/server/tests/api/index-slow.ts b/server/tests/api/index-slow.ts index b525d6f01..23b6526c7 100644 --- a/server/tests/api/index-slow.ts +++ b/server/tests/api/index-slow.ts @@ -1,7 +1,7 @@ // Order of the tests we want to execute // import './multiple-servers' -import './video-transcoder' -import './multiple-servers' -import './follows' -import './jobs' -import './video-comments' +import './videos/video-transcoder' +import './videos/multiple-servers' +import './server/follows' +import './server/jobs' +import './videos/video-comments' diff --git a/server/tests/api/jobs.ts b/server/tests/api/jobs.ts deleted file mode 100644 index 4d9b61392..000000000 --- a/server/tests/api/jobs.ts +++ /dev/null @@ -1,64 +0,0 @@ -/* tslint:disable:no-unused-expression */ - -import * as chai from 'chai' -import 'mocha' -import { flushTests, killallServers, ServerInfo, setAccessTokensToServers, wait } from '../utils' -import { doubleFollow } from '../utils/follows' -import { getJobsList, getJobsListPaginationAndSort } from '../utils/jobs' -import { flushAndRunMultipleServers } from '../utils/servers' -import { uploadVideo } from '../utils/videos' -import { dateIsValid } from '../utils/miscs' - -const expect = chai.expect - -describe('Test jobs', function () { - let servers: ServerInfo[] - - before(async function () { - this.timeout(30000) - - servers = await flushAndRunMultipleServers(2) - - await setAccessTokensToServers(servers) - - // Server 1 and server 2 follow each other - await doubleFollow(servers[0], servers[1]) - }) - - it('Should create some jobs', async function () { - this.timeout(30000) - - await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'video1' }) - await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'video2' }) - - await wait(15000) - }) - - it('Should list jobs', async function () { - const res = await getJobsList(servers[1].url, servers[1].accessToken) - expect(res.body.total).to.be.above(2) - expect(res.body.data).to.have.length.above(2) - }) - - it('Should list jobs with sort and pagination', async function () { - const res = await getJobsListPaginationAndSort(servers[1].url, servers[1].accessToken, 4, 1, 'createdAt') - expect(res.body.total).to.be.above(2) - expect(res.body.data).to.have.lengthOf(1) - - const job = res.body.data[0] - expect(job.state).to.equal('success') - expect(job.category).to.equal('transcoding') - expect(job.handlerName).to.have.length.above(3) - expect(dateIsValid(job.createdAt)).to.be.true - expect(dateIsValid(job.updatedAt)).to.be.true - }) - - after(async function () { - killallServers(servers) - - // Keep the logs if the test failed - if (this['ok']) { - await flushTests() - } - }) -}) diff --git a/server/tests/api/multiple-servers.ts b/server/tests/api/multiple-servers.ts deleted file mode 100644 index 06274d4cc..000000000 --- a/server/tests/api/multiple-servers.ts +++ /dev/null @@ -1,858 +0,0 @@ -/* tslint:disable:no-unused-expression */ - -import * as chai from 'chai' -import 'mocha' -import { join } from 'path' -import * as request from 'supertest' -import { VideoComment, VideoCommentThreadTree } from '../../../shared/models/videos/video-comment.model' - -import { - addVideoChannel, dateIsValid, doubleFollow, flushAndRunMultipleServers, flushTests, getUserAccessToken, getVideo, - getVideoChannelsList, getVideosList, killallServers, rateVideo, removeVideo, ServerInfo, setAccessTokensToServers, testVideoImage, - updateVideo, uploadVideo, wait, webtorrentAdd -} from '../utils' -import { createUser } from '../utils/users' -import { addVideoCommentReply, addVideoCommentThread, getVideoCommentThreads, getVideoThreadComments } from '../utils/video-comments' -import { viewVideo } from '../utils/videos' - -const expect = chai.expect - -describe('Test multiple servers', function () { - let servers: ServerInfo[] = [] - const toRemove = [] - let videoUUID = '' - let videoChannelId: number - - before(async function () { - this.timeout(120000) - - servers = await flushAndRunMultipleServers(3) - - // Get the access tokens - await setAccessTokensToServers(servers) - - const videoChannel = { - name: 'my channel', - description: 'super channel' - } - await addVideoChannel(servers[0].url, servers[0].accessToken, videoChannel) - const channelRes = await getVideoChannelsList(servers[0].url, 0, 1) - videoChannelId = channelRes.body.data[0].id - - // Server 1 and server 2 follow each other - await doubleFollow(servers[0], servers[1]) - // Server 1 and server 3 follow each other - await doubleFollow(servers[0], servers[2]) - // Server 2 and server 3 follow each other - await doubleFollow(servers[1], servers[2]) - }) - - it('Should not have videos for all servers', async function () { - for (const server of servers) { - const res = await getVideosList(server.url) - const videos = res.body.data - expect(videos).to.be.an('array') - expect(videos.length).to.equal(0) - } - }) - - describe('Should upload the video and propagate on each server', function () { - it('Should upload the video on server 1 and propagate on each server', async function () { - this.timeout(25000) - - const videoAttributes = { - name: 'my super name for server 1', - category: 5, - licence: 4, - language: 9, - nsfw: true, - description: 'my super description for server 1', - tags: [ 'tag1p1', 'tag2p1' ], - channelId: videoChannelId, - fixture: 'video_short1.webm' - } - await uploadVideo(servers[0].url, servers[0].accessToken, videoAttributes) - - await wait(10000) - - // All servers should have this video - for (const server of servers) { - let baseMagnet = null - - const res = await getVideosList(server.url) - - const videos = res.body.data - expect(videos).to.be.an('array') - expect(videos.length).to.equal(1) - const video = videos[0] - expect(video.name).to.equal('my super name for server 1') - expect(video.category).to.equal(5) - expect(video.categoryLabel).to.equal('Sports') - expect(video.licence).to.equal(4) - expect(video.licenceLabel).to.equal('Attribution - Non Commercial') - expect(video.language).to.equal(9) - expect(video.languageLabel).to.equal('Japanese') - expect(video.nsfw).to.be.ok - expect(video.description).to.equal('my super description for server 1') - expect(video.serverHost).to.equal('localhost:9001') - expect(video.duration).to.equal(10) - expect(dateIsValid(video.createdAt)).to.be.true - expect(dateIsValid(video.updatedAt)).to.be.true - expect(video.accountName).to.equal('root') - - const res2 = await getVideo(server.url, video.uuid) - const videoDetails = res2.body - - expect(videoDetails.channel.name).to.equal('my channel') - expect(videoDetails.channel.description).to.equal('super channel') - expect(videoDetails.account.name).to.equal('root') - expect(dateIsValid(videoDetails.channel.createdAt)).to.be.true - expect(dateIsValid(videoDetails.channel.updatedAt)).to.be.true - expect(videoDetails.files).to.have.lengthOf(1) - expect(videoDetails.tags).to.deep.equal([ 'tag1p1', 'tag2p1' ]) - - const file = videoDetails.files[0] - const magnetUri = file.magnetUri - expect(file.magnetUri).to.have.lengthOf.above(2) - expect(file.torrentUrl).to - .equal(`http://${videoDetails.serverHost}/static/torrents/${videoDetails.uuid}-${file.resolution}.torrent`) - expect(file.fileUrl).to.equal(`http://${videoDetails.serverHost}/static/webseed/${videoDetails.uuid}-${file.resolution}.webm`) - expect(file.resolution).to.equal(720) - expect(file.resolutionLabel).to.equal('720p') - expect(file.size).to.equal(572456) - - if (server.url !== 'http://localhost:9001') { - expect(video.isLocal).to.be.false - expect(videoDetails.channel.isLocal).to.be.false - } else { - expect(video.isLocal).to.be.true - expect(videoDetails.channel.isLocal).to.be.true - } - - // All servers should have the same magnet Uri - if (baseMagnet === null) { - baseMagnet = magnetUri - } else { - expect(baseMagnet).to.equal(magnetUri) - } - - const test = await testVideoImage(server.url, 'video_short1.webm', video.thumbnailPath) - expect(test).to.equal(true) - } - }) - - it('Should upload the video on server 2 and propagate on each server', async function () { - this.timeout(50000) - - const user = { - username: 'user1', - password: 'super_password' - } - await createUser(servers[1].url, servers[1].accessToken, user.username, user.password) - const userAccessToken = await getUserAccessToken(servers[1], user) - - const videoAttributes = { - name: 'my super name for server 2', - category: 4, - licence: 3, - language: 11, - nsfw: true, - description: 'my super description for server 2', - tags: [ 'tag1p2', 'tag2p2', 'tag3p2' ], - fixture: 'video_short2.webm' - } - await uploadVideo(servers[1].url, userAccessToken, videoAttributes) - - // Transcoding - await wait(30000) - - // All servers should have this video - for (const server of servers) { - let baseMagnet = {} - - const res = await getVideosList(server.url) - - const videos = res.body.data - expect(videos).to.be.an('array') - expect(videos.length).to.equal(2) - const video = videos[1] - expect(video.name).to.equal('my super name for server 2') - expect(video.category).to.equal(4) - expect(video.categoryLabel).to.equal('Art') - expect(video.licence).to.equal(3) - expect(video.licenceLabel).to.equal('Attribution - No Derivatives') - expect(video.language).to.equal(11) - expect(video.languageLabel).to.equal('German') - expect(video.nsfw).to.be.true - expect(video.description).to.equal('my super description for server 2') - expect(video.serverHost).to.equal('localhost:9002') - expect(video.duration).to.equal(5) - expect(dateIsValid(video.createdAt)).to.be.true - expect(dateIsValid(video.updatedAt)).to.be.true - expect(video.accountName).to.equal('user1') - - if (server.url !== 'http://localhost:9002') { - expect(video.isLocal).to.be.false - } else { - expect(video.isLocal).to.be.true - } - - const res2 = await getVideo(server.url, video.uuid) - const videoDetails = res2.body - - expect(videoDetails.channel.name).to.equal('Default user1 channel') - expect(dateIsValid(videoDetails.channel.createdAt)).to.be.true - expect(dateIsValid(videoDetails.channel.updatedAt)).to.be.true - expect(videoDetails.tags).to.deep.equal([ 'tag1p2', 'tag2p2', 'tag3p2' ]) - - expect(videoDetails.files).to.have.lengthOf(4) - - // Check common attributes - for (const file of videoDetails.files) { - expect(file.magnetUri).to.have.lengthOf.above(2) - - // All servers should have the same magnet Uri - if (baseMagnet[file.resolution] === undefined) { - baseMagnet[file.resolution] = file.magnet - } else { - expect(baseMagnet[file.resolution]).to.equal(file.magnet) - } - } - - const file240p = videoDetails.files.find(f => f.resolution === 240) - expect(file240p).not.to.be.undefined - expect(file240p.resolutionLabel).to.equal('240p') - expect(file240p.size).to.be.above(180000).and.below(200000) - - const file360p = videoDetails.files.find(f => f.resolution === 360) - expect(file360p).not.to.be.undefined - expect(file360p.resolutionLabel).to.equal('360p') - expect(file360p.size).to.be.above(270000).and.below(290000) - - const file480p = videoDetails.files.find(f => f.resolution === 480) - expect(file480p).not.to.be.undefined - expect(file480p.resolutionLabel).to.equal('480p') - expect(file480p.size).to.be.above(380000).and.below(400000) - - const file720p = videoDetails.files.find(f => f.resolution === 720) - expect(file720p).not.to.be.undefined - expect(file720p.resolutionLabel).to.equal('720p') - expect(file720p.size).to.be.above(700000).and.below(7200000) - - const test = await testVideoImage(server.url, 'video_short2.webm', videoDetails.thumbnailPath) - expect(test).to.equal(true) - } - }) - - it('Should upload two videos on server 3 and propagate on each server', async function () { - this.timeout(45000) - - const videoAttributes1 = { - name: 'my super name for server 3', - category: 6, - licence: 5, - language: 11, - nsfw: true, - description: 'my super description for server 3', - tags: [ 'tag1p3' ], - fixture: 'video_short3.webm' - } - await uploadVideo(servers[2].url, servers[2].accessToken, videoAttributes1) - - const videoAttributes2 = { - name: 'my super name for server 3-2', - category: 7, - licence: 6, - language: 12, - nsfw: false, - description: 'my super description for server 3-2', - tags: [ 'tag2p3', 'tag3p3', 'tag4p3' ], - fixture: 'video_short.webm' - } - await uploadVideo(servers[2].url, servers[2].accessToken, videoAttributes2) - - await wait(10000) - - let baseMagnet = null - // All servers should have this video - for (const server of servers) { - const res = await getVideosList(server.url) - - const videos = res.body.data - expect(videos).to.be.an('array') - expect(videos.length).to.equal(4) - - // We not sure about the order of the two last uploads - let video1 = null - let video2 = null - if (videos[2].name === 'my super name for server 3') { - video1 = videos[2] - video2 = videos[3] - } else { - video1 = videos[3] - video2 = videos[2] - } - - expect(video1.name).to.equal('my super name for server 3') - expect(video1.category).to.equal(6) - expect(video1.categoryLabel).to.equal('Travels') - expect(video1.licence).to.equal(5) - expect(video1.licenceLabel).to.equal('Attribution - Non Commercial - Share Alike') - expect(video1.language).to.equal(11) - expect(video1.languageLabel).to.equal('German') - expect(video1.nsfw).to.be.ok - expect(video1.description).to.equal('my super description for server 3') - expect(video1.serverHost).to.equal('localhost:9003') - expect(video1.duration).to.equal(5) - expect(video1.accountName).to.equal('root') - expect(dateIsValid(video1.createdAt)).to.be.true - expect(dateIsValid(video1.updatedAt)).to.be.true - - const res2 = await getVideo(server.url, video1.id) - const video1Details = res2.body - expect(video1Details.files).to.have.lengthOf(1) - expect(video1Details.tags).to.deep.equal([ 'tag1p3' ]) - - const file1 = video1Details.files[0] - expect(file1.magnetUri).to.have.lengthOf.above(2) - expect(file1.resolution).to.equal(720) - expect(file1.resolutionLabel).to.equal('720p') - expect(file1.size).to.equal(292677) - - expect(video2.name).to.equal('my super name for server 3-2') - expect(video2.category).to.equal(7) - expect(video2.categoryLabel).to.equal('Gaming') - expect(video2.licence).to.equal(6) - expect(video2.licenceLabel).to.equal('Attribution - Non Commercial - No Derivatives') - expect(video2.language).to.equal(12) - expect(video2.languageLabel).to.equal('Korean') - expect(video2.nsfw).to.be.false - expect(video2.description).to.equal('my super description for server 3-2') - expect(video2.serverHost).to.equal('localhost:9003') - expect(video2.duration).to.equal(5) - expect(video2.accountName).to.equal('root') - expect(dateIsValid(video2.createdAt)).to.be.true - expect(dateIsValid(video2.updatedAt)).to.be.true - - const res3 = await getVideo(server.url, video2.id) - const video2Details = res3.body - expect(video2Details.tags).to.deep.equal([ 'tag2p3', 'tag3p3', 'tag4p3' ]) - - expect(video2Details.files).to.have.lengthOf(1) - - const file2 = video2Details.files[0] - const magnetUri2 = file2.magnetUri - expect(file2.magnetUri).to.have.lengthOf.above(2) - expect(file2.resolution).to.equal(720) - expect(file2.resolutionLabel).to.equal('720p') - expect(file2.size).to.equal(218910) - - if (server.url !== 'http://localhost:9003') { - expect(video1.isLocal).to.be.false - expect(video2.isLocal).to.be.false - } else { - expect(video1.isLocal).to.be.true - expect(video2.isLocal).to.be.true - } - - // All servers should have the same magnet Uri - if (baseMagnet === null) { - baseMagnet = magnetUri2 - } else { - expect(baseMagnet).to.equal(magnetUri2) - } - - const test1 = await testVideoImage(server.url, 'video_short3.webm', video1.thumbnailPath) - expect(test1).to.equal(true) - - const test2 = await testVideoImage(server.url, 'video_short.webm', video2.thumbnailPath) - expect(test2).to.equal(true) - } - }) - }) - - describe('Should seed the uploaded video', function () { - it('Should add the file 1 by asking server 3', async function () { - this.timeout(10000) - - const res = await getVideosList(servers[2].url) - - const video = res.body.data[0] - toRemove.push(res.body.data[2]) - toRemove.push(res.body.data[3]) - - const res2 = await getVideo(servers[2].url, video.id) - const videoDetails = res2.body - - const torrent = await webtorrentAdd(videoDetails.files[0].magnetUri) - expect(torrent.files).to.be.an('array') - expect(torrent.files.length).to.equal(1) - expect(torrent.files[0].path).to.exist.and.to.not.equal('') - }) - - it('Should add the file 2 by asking server 1', async function () { - this.timeout(10000) - - const res = await getVideosList(servers[0].url) - - const video = res.body.data[1] - const res2 = await getVideo(servers[0].url, video.id) - const videoDetails = res2.body - - const torrent = await webtorrentAdd(videoDetails.files[0].magnetUri) - expect(torrent.files).to.be.an('array') - expect(torrent.files.length).to.equal(1) - expect(torrent.files[0].path).to.exist.and.to.not.equal('') - }) - - it('Should add the file 3 by asking server 2', async function () { - this.timeout(10000) - - const res = await getVideosList(servers[1].url) - - const video = res.body.data[2] - const res2 = await getVideo(servers[1].url, video.id) - const videoDetails = res2.body - - const torrent = await webtorrentAdd(videoDetails.files[0].magnetUri) - expect(torrent.files).to.be.an('array') - expect(torrent.files.length).to.equal(1) - expect(torrent.files[0].path).to.exist.and.to.not.equal('') - }) - - it('Should add the file 3-2 by asking server 1', async function () { - this.timeout(10000) - - const res = await getVideosList(servers[0].url) - - const video = res.body.data[3] - const res2 = await getVideo(servers[0].url, video.id) - const videoDetails = res2.body - - const torrent = await webtorrentAdd(videoDetails.files[0].magnetUri) - expect(torrent.files).to.be.an('array') - expect(torrent.files.length).to.equal(1) - expect(torrent.files[0].path).to.exist.and.to.not.equal('') - }) - - it('Should add the file 2 in 360p by asking server 1', async function () { - this.timeout(10000) - - const res = await getVideosList(servers[0].url) - - const video = res.body.data.find(v => v.name === 'my super name for server 2') - const res2 = await getVideo(servers[0].url, video.id) - const videoDetails = res2.body - - const file = videoDetails.files.find(f => f.resolution === 360) - expect(file).not.to.be.undefined - - const torrent = await webtorrentAdd(file.magnetUri) - expect(torrent.files).to.be.an('array') - expect(torrent.files.length).to.equal(1) - expect(torrent.files[0].path).to.exist.and.to.not.equal('') - }) - }) - - describe('Should update video views, likes and dislikes', function () { - let localVideosServer3 = [] - let remoteVideosServer1 = [] - let remoteVideosServer2 = [] - let remoteVideosServer3 = [] - - before(async function () { - const res1 = await getVideosList(servers[0].url) - remoteVideosServer1 = res1.body.data.filter(video => video.isLocal === false).map(video => video.uuid) - - const res2 = await getVideosList(servers[1].url) - remoteVideosServer2 = res2.body.data.filter(video => video.isLocal === false).map(video => video.uuid) - - const res3 = await getVideosList(servers[2].url) - localVideosServer3 = res3.body.data.filter(video => video.isLocal === true).map(video => video.uuid) - remoteVideosServer3 = res3.body.data.filter(video => video.isLocal === false).map(video => video.uuid) - }) - - it('Should view multiple videos on owned servers', async function () { - this.timeout(10000) - - const tasks: Promise[] = [] - tasks.push(viewVideo(servers[2].url, localVideosServer3[0])) - tasks.push(viewVideo(servers[2].url, localVideosServer3[0])) - tasks.push(viewVideo(servers[2].url, localVideosServer3[0])) - tasks.push(viewVideo(servers[2].url, localVideosServer3[1])) - - await Promise.all(tasks) - - await wait(5000) - - for (const server of servers) { - const res = await getVideosList(server.url) - - const videos = res.body.data - const video0 = videos.find(v => v.uuid === localVideosServer3[0]) - const video1 = videos.find(v => v.uuid === localVideosServer3[1]) - - expect(video0.views).to.equal(3) - expect(video1.views).to.equal(1) - } - }) - - it('Should view multiple videos on each servers', async function () { - this.timeout(15000) - - const tasks: Promise[] = [] - tasks.push(viewVideo(servers[0].url, remoteVideosServer1[0])) - tasks.push(viewVideo(servers[1].url, remoteVideosServer2[0])) - tasks.push(viewVideo(servers[1].url, remoteVideosServer2[0])) - tasks.push(viewVideo(servers[2].url, remoteVideosServer3[0])) - tasks.push(viewVideo(servers[2].url, remoteVideosServer3[1])) - tasks.push(viewVideo(servers[2].url, remoteVideosServer3[1])) - tasks.push(viewVideo(servers[2].url, remoteVideosServer3[1])) - tasks.push(viewVideo(servers[2].url, localVideosServer3[1])) - tasks.push(viewVideo(servers[2].url, localVideosServer3[1])) - tasks.push(viewVideo(servers[2].url, localVideosServer3[1])) - - await Promise.all(tasks) - - await wait(10000) - - let baseVideos = null - - for (const server of servers) { - const res = await getVideosList(server.url) - - const videos = res.body.data - - // Initialize base videos for future comparisons - if (baseVideos === null) { - baseVideos = videos - continue - } - - for (const baseVideo of baseVideos) { - const sameVideo = videos.find(video => video.name === baseVideo.name) - expect(baseVideo.views).to.equal(sameVideo.views) - } - } - }) - - it('Should like and dislikes videos on different services', async function () { - this.timeout(20000) - - const tasks: Promise[] = [] - tasks.push(rateVideo(servers[0].url, servers[0].accessToken, remoteVideosServer1[0], 'like')) - tasks.push(rateVideo(servers[0].url, servers[0].accessToken, remoteVideosServer1[0], 'dislike')) - tasks.push(rateVideo(servers[0].url, servers[0].accessToken, remoteVideosServer1[0], 'like')) - tasks.push(rateVideo(servers[2].url, servers[2].accessToken, localVideosServer3[1], 'like')) - tasks.push(rateVideo(servers[2].url, servers[2].accessToken, localVideosServer3[1], 'dislike')) - tasks.push(rateVideo(servers[2].url, servers[2].accessToken, remoteVideosServer3[1], 'dislike')) - tasks.push(rateVideo(servers[2].url, servers[2].accessToken, remoteVideosServer3[0], 'like')) - - await Promise.all(tasks) - - await wait(10000) - - let baseVideos = null - for (const server of servers) { - const res = await getVideosList(server.url) - - const videos = res.body.data - - // Initialize base videos for future comparisons - if (baseVideos === null) { - baseVideos = videos - continue - } - - for (const baseVideo of baseVideos) { - const sameVideo = videos.find(video => video.name === baseVideo.name) - expect(baseVideo.likes).to.equal(sameVideo.likes) - expect(baseVideo.dislikes).to.equal(sameVideo.dislikes) - } - } - }) - }) - - describe('Should manipulate these videos', function () { - it('Should update the video 3 by asking server 3', async function () { - this.timeout(10000) - - const attributes = { - name: 'my super video updated', - category: 10, - licence: 7, - language: 13, - nsfw: true, - description: 'my super description updated', - tags: [ 'tag_up_1', 'tag_up_2' ] - } - - await updateVideo(servers[2].url, servers[2].accessToken, toRemove[0].id, attributes) - - await wait(5000) - }) - - it('Should have the video 3 updated on each server', async function () { - this.timeout(10000) - - for (const server of servers) { - const res = await getVideosList(server.url) - - const videos = res.body.data - const videoUpdated = videos.find(video => video.name === 'my super video updated') - - expect(!!videoUpdated).to.be.true - expect(videoUpdated.category).to.equal(10) - expect(videoUpdated.categoryLabel).to.equal('Entertainment') - expect(videoUpdated.licence).to.equal(7) - expect(videoUpdated.licenceLabel).to.equal('Public Domain Dedication') - expect(videoUpdated.language).to.equal(13) - expect(videoUpdated.languageLabel).to.equal('French') - expect(videoUpdated.nsfw).to.be.ok - expect(videoUpdated.description).to.equal('my super description updated') - expect(dateIsValid(videoUpdated.updatedAt, 20000)).to.be.true - - const res2 = await getVideo(server.url, videoUpdated.uuid) - const videoUpdatedDetails = res2.body - expect(videoUpdatedDetails.tags).to.deep.equal([ 'tag_up_1', 'tag_up_2' ]) - - const file = videoUpdatedDetails.files[0] - expect(file.magnetUri).to.have.lengthOf.above(2) - expect(file.resolution).to.equal(720) - expect(file.resolutionLabel).to.equal('720p') - expect(file.size).to.equal(292677) - - const test = await testVideoImage(server.url, 'video_short3.webm', videoUpdated.thumbnailPath) - expect(test).to.equal(true) - - // Avoid "duplicate torrent" errors - const refreshWebTorrent = true - const torrent = await webtorrentAdd(videoUpdatedDetails .files[0].magnetUri, refreshWebTorrent) - expect(torrent.files).to.be.an('array') - expect(torrent.files.length).to.equal(1) - expect(torrent.files[0].path).to.exist.and.to.not.equal('') - } - }) - - it('Should remove the videos 3 and 3-2 by asking server 3', async function () { - this.timeout(10000) - - await removeVideo(servers[2].url, servers[2].accessToken, toRemove[0].id) - await removeVideo(servers[2].url, servers[2].accessToken, toRemove[1].id) - - await wait(5000) - }) - - it('Should have videos 1 and 3 on each server', async function () { - for (const server of servers) { - const res = await getVideosList(server.url) - - const videos = res.body.data - expect(videos).to.be.an('array') - expect(videos.length).to.equal(2) - expect(videos[0].name).not.to.equal(videos[1].name) - expect(videos[0].name).not.to.equal(toRemove[0].name) - expect(videos[1].name).not.to.equal(toRemove[0].name) - expect(videos[0].name).not.to.equal(toRemove[1].name) - expect(videos[1].name).not.to.equal(toRemove[1].name) - - videoUUID = videos.find(video => video.name === 'my super name for server 1').uuid - } - }) - - it('Should get the same video by UUID on each server', async function () { - let baseVideo = null - for (const server of servers) { - const res = await getVideo(server.url, videoUUID) - - const video = res.body - - if (baseVideo === null) { - baseVideo = video - continue - } - - expect(baseVideo.name).to.equal(video.name) - expect(baseVideo.uuid).to.equal(video.uuid) - expect(baseVideo.category).to.equal(video.category) - expect(baseVideo.language).to.equal(video.language) - expect(baseVideo.licence).to.equal(video.licence) - expect(baseVideo.category).to.equal(video.category) - expect(baseVideo.nsfw).to.equal(video.nsfw) - expect(baseVideo.accountName).to.equal(video.accountName) - expect(baseVideo.tags).to.deep.equal(video.tags) - } - }) - - it('Should get the preview from each server', async function () { - for (const server of servers) { - const res = await getVideo(server.url, videoUUID) - const video = res.body - - const test = await testVideoImage(server.url, 'video_short1-preview.webm', video.previewPath) - expect(test).to.equal(true) - } - }) - }) - - describe('Should comment these videos', function () { - it('Should add comment (threads and replies)', async function () { - this.timeout(25000) - - { - const text = 'my super first comment' - await addVideoCommentThread(servers[ 0 ].url, servers[ 0 ].accessToken, videoUUID, text) - } - - { - const text = 'my super second comment' - await addVideoCommentThread(servers[ 2 ].url, servers[ 2 ].accessToken, videoUUID, text) - } - - await wait(5000) - - { - const res = await getVideoCommentThreads(servers[1].url, videoUUID, 0, 5) - const threadId = res.body.data.find(c => c.text === 'my super first comment').id - - const text = 'my super answer to thread 1' - await addVideoCommentReply(servers[ 1 ].url, servers[ 1 ].accessToken, videoUUID, threadId, text) - } - - await wait(5000) - - { - const res1 = await getVideoCommentThreads(servers[2].url, videoUUID, 0, 5) - const threadId = res1.body.data.find(c => c.text === 'my super first comment').id - - const res2 = await getVideoThreadComments(servers[2].url, videoUUID, threadId) - const childCommentId = res2.body.children[0].comment.id - - const text3 = 'my second answer to thread 1' - await addVideoCommentReply(servers[ 2 ].url, servers[ 2 ].accessToken, videoUUID, threadId, text3) - - const text2 = 'my super answer to answer of thread 1' - await addVideoCommentReply(servers[ 2 ].url, servers[ 2 ].accessToken, videoUUID, childCommentId, text2) - } - - await wait(5000) - }) - - it('Should have these threads', async function () { - for (const server of servers) { - const res = await getVideoCommentThreads(server.url, videoUUID, 0, 5) - - expect(res.body.total).to.equal(2) - expect(res.body.data).to.be.an('array') - expect(res.body.data).to.have.lengthOf(2) - - { - const comment: VideoComment = res.body.data.find(c => c.text === 'my super first comment') - expect(comment).to.not.be.undefined - expect(comment.inReplyToCommentId).to.be.null - expect(comment.account.name).to.equal('root') - expect(comment.account.host).to.equal('localhost:9001') - expect(comment.totalReplies).to.equal(3) - expect(dateIsValid(comment.createdAt as string)).to.be.true - expect(dateIsValid(comment.updatedAt as string)).to.be.true - } - - { - const comment: VideoComment = res.body.data.find(c => c.text === 'my super second comment') - expect(comment).to.not.be.undefined - expect(comment.inReplyToCommentId).to.be.null - expect(comment.account.name).to.equal('root') - expect(comment.account.host).to.equal('localhost:9003') - expect(comment.totalReplies).to.equal(0) - expect(dateIsValid(comment.createdAt as string)).to.be.true - expect(dateIsValid(comment.updatedAt as string)).to.be.true - } - } - }) - - it('Should have these comments', async function () { - for (const server of servers) { - const res1 = await getVideoCommentThreads(server.url, videoUUID, 0, 5) - const threadId = res1.body.data.find(c => c.text === 'my super first comment').id - - const res2 = await getVideoThreadComments(server.url, videoUUID, threadId) - - const tree: VideoCommentThreadTree = res2.body - expect(tree.comment.text).equal('my super first comment') - expect(tree.comment.account.name).equal('root') - expect(tree.comment.account.host).equal('localhost:9001') - expect(tree.children).to.have.lengthOf(2) - - const firstChild = tree.children[0] - expect(firstChild.comment.text).to.equal('my super answer to thread 1') - expect(firstChild.comment.account.name).equal('root') - expect(firstChild.comment.account.host).equal('localhost:9002') - expect(firstChild.children).to.have.lengthOf(1) - - const childOfFirstChild = firstChild.children[0] - expect(childOfFirstChild.comment.text).to.equal('my super answer to answer of thread 1') - expect(childOfFirstChild.comment.account.name).equal('root') - expect(childOfFirstChild.comment.account.host).equal('localhost:9003') - expect(childOfFirstChild.children).to.have.lengthOf(0) - - const secondChild = tree.children[1] - expect(secondChild.comment.text).to.equal('my second answer to thread 1') - expect(secondChild.comment.account.name).equal('root') - expect(secondChild.comment.account.host).equal('localhost:9003') - expect(secondChild.children).to.have.lengthOf(0) - } - }) - }) - - describe('With minimum parameters', function () { - it('Should upload and propagate the video', async function () { - this.timeout(50000) - - const path = '/api/v1/videos/upload' - - const req = request(servers[1].url) - .post(path) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + servers[1].accessToken) - .field('name', 'minimum parameters') - .field('privacy', '1') - .field('nsfw', 'false') - .field('channelId', '1') - - const filePath = join(__dirname, '..', 'api', 'fixtures', 'video_short.webm') - - await req.attach('videofile', filePath) - .expect(200) - - await wait(25000) - - for (const server of servers) { - const res = await getVideosList(server.url) - const video = res.body.data.find(v => v.name === 'minimum parameters') - - expect(video.name).to.equal('minimum parameters') - expect(video.category).to.equal(null) - expect(video.categoryLabel).to.equal('Misc') - expect(video.licence).to.equal(null) - expect(video.licenceLabel).to.equal('Unknown') - expect(video.language).to.equal(null) - expect(video.languageLabel).to.equal('Unknown') - expect(video.nsfw).to.not.be.ok - expect(video.description).to.equal(null) - expect(video.serverHost).to.equal('localhost:9002') - expect(video.accountName).to.equal('root') - expect(dateIsValid(video.createdAt)).to.be.true - expect(dateIsValid(video.updatedAt)).to.be.true - } - }) - }) - - after(async function () { - killallServers(servers) - - // Keep the logs if the test failed - if (this['ok']) { - await flushTests() - } - }) -}) diff --git a/server/tests/api/server/config.ts b/server/tests/api/server/config.ts new file mode 100644 index 000000000..e8846c8db --- /dev/null +++ b/server/tests/api/server/config.ts @@ -0,0 +1,54 @@ +/* tslint:disable:no-unused-expression */ + +import 'mocha' +import * as chai from 'chai' +const expect = chai.expect + +import { + getConfig, + flushTests, + runServer, + registerUser +} from '../../utils/index' + +describe('Test config', function () { + let server = null + + before(async function () { + this.timeout(10000) + + await flushTests() + server = await runServer(1) + }) + + it('Should have a correct config on a server with registration enabled', async function () { + const res = await getConfig(server.url) + const data = res.body + + expect(data.signup.allowed).to.be.true + }) + + it('Should have a correct config on a server with registration enabled and a users limit', async function () { + this.timeout(5000) + + await Promise.all([ + registerUser(server.url, 'user1', 'super password'), + registerUser(server.url, 'user2', 'super password'), + registerUser(server.url, 'user3', 'super password') + ]) + + const res = await getConfig(server.url) + const data = res.body + + expect(data.signup.allowed).to.be.false + }) + + after(async function () { + process.kill(-server.app.pid) + + // Keep the logs if the test failed + if (this['ok']) { + await flushTests() + } + }) +}) diff --git a/server/tests/api/server/follows.ts b/server/tests/api/server/follows.ts new file mode 100644 index 000000000..f77c0c67c --- /dev/null +++ b/server/tests/api/server/follows.ts @@ -0,0 +1,318 @@ +/* tslint:disable:no-unused-expression */ + +import * as chai from 'chai' +import 'mocha' +import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model' + +import { + flushAndRunMultipleServers, flushTests, getVideosList, killallServers, ServerInfo, setAccessTokensToServers, uploadVideo, + wait +} from '../../utils/index' +import { dateIsValid, webtorrentAdd } from '../../utils/miscs/miscs' +import { follow, getFollowersListPaginationAndSort, getFollowingListPaginationAndSort, unfollow } from '../../utils/server/follows' +import { getUserAccessToken } from '../../utils/users/login' +import { createUser } from '../../utils/users/users' +import { + addVideoCommentReply, addVideoCommentThread, getVideoCommentThreads, + getVideoThreadComments +} from '../../utils/videos/video-comments' +import { getVideo, rateVideo, testVideoImage } from '../../utils/videos/videos' + +const expect = chai.expect + +describe('Test follows', function () { + let servers: ServerInfo[] = [] + + before(async function () { + this.timeout(20000) + + servers = await flushAndRunMultipleServers(3) + + // Get the access tokens + await setAccessTokensToServers(servers) + }) + + it('Should not have followers', async function () { + for (const server of servers) { + const res = await getFollowersListPaginationAndSort(server.url, 0, 5, 'createdAt') + const follows = res.body.data + + expect(res.body.total).to.equal(0) + expect(follows).to.be.an('array') + expect(follows.length).to.equal(0) + } + }) + + it('Should not have following', async function () { + for (const server of servers) { + const res = await getFollowingListPaginationAndSort(server.url, 0, 5, 'createdAt') + const follows = res.body.data + + expect(res.body.total).to.equal(0) + expect(follows).to.be.an('array') + expect(follows.length).to.equal(0) + } + }) + + it('Should have server 1 following server 2 and 3', async function () { + this.timeout(10000) + + await follow(servers[0].url, [ servers[1].url, servers[2].url ], servers[0].accessToken) + + await wait(7000) + }) + + it('Should have 2 followings on server 1', async function () { + let res = await getFollowingListPaginationAndSort(servers[0].url, 0, 1, 'createdAt') + let follows = res.body.data + + expect(res.body.total).to.equal(2) + expect(follows).to.be.an('array') + expect(follows.length).to.equal(1) + + res = await getFollowingListPaginationAndSort(servers[0].url, 1, 1, 'createdAt') + follows = follows.concat(res.body.data) + + const server2Follow = follows.find(f => f.following.host === 'localhost:9002') + const server3Follow = follows.find(f => f.following.host === 'localhost:9003') + + expect(server2Follow).to.not.be.undefined + expect(server3Follow).to.not.be.undefined + expect(server2Follow.state).to.equal('accepted') + expect(server3Follow.state).to.equal('accepted') + }) + + it('Should have 0 followings on server 1 and 2', async function () { + for (const server of [ servers[1], servers[2] ]) { + const res = await getFollowingListPaginationAndSort(server.url, 0, 5, 'createdAt') + const follows = res.body.data + + expect(res.body.total).to.equal(0) + expect(follows).to.be.an('array') + expect(follows.length).to.equal(0) + } + }) + + it('Should have 1 followers on server 2 and 3', async function () { + for (const server of [ servers[1], servers[2] ]) { + let res = await getFollowersListPaginationAndSort(server.url, 0, 1, 'createdAt') + + let follows = res.body.data + expect(res.body.total).to.equal(1) + expect(follows).to.be.an('array') + expect(follows.length).to.equal(1) + expect(follows[0].follower.host).to.equal('localhost:9001') + } + }) + + it('Should have 0 followers on server 1', async function () { + const res = await getFollowersListPaginationAndSort(servers[0].url, 0, 5, 'createdAt') + const follows = res.body.data + + expect(res.body.total).to.equal(0) + expect(follows).to.be.an('array') + expect(follows.length).to.equal(0) + }) + + it('Should unfollow server 3 on server 1', async function () { + this.timeout(5000) + + await unfollow(servers[0].url, servers[0].accessToken, servers[2]) + + await wait(3000) + }) + + it('Should not follow server 3 on server 1 anymore', async function () { + const res = await getFollowingListPaginationAndSort(servers[0].url, 0, 2, 'createdAt') + let follows = res.body.data + + expect(res.body.total).to.equal(1) + expect(follows).to.be.an('array') + expect(follows.length).to.equal(1) + + expect(follows[0].following.host).to.equal('localhost:9002') + }) + + it('Should not have server 1 as follower on server 3 anymore', async function () { + const res = await getFollowersListPaginationAndSort(servers[2].url, 0, 1, 'createdAt') + + let follows = res.body.data + expect(res.body.total).to.equal(0) + expect(follows).to.be.an('array') + expect(follows.length).to.equal(0) + }) + + it('Should upload a video on server 2 ans 3 and propagate only the video of server 2', async function () { + this.timeout(10000) + + await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'server2' }) + await uploadVideo(servers[2].url, servers[2].accessToken, { name: 'server3' }) + + await wait(5000) + + let res = await getVideosList(servers[0].url) + expect(res.body.total).to.equal(1) + expect(res.body.data[0].name).to.equal('server2') + + res = await getVideosList(servers[1].url) + expect(res.body.total).to.equal(1) + expect(res.body.data[0].name).to.equal('server2') + + res = await getVideosList(servers[2].url) + expect(res.body.total).to.equal(1) + expect(res.body.data[0].name).to.equal('server3') + }) + + it('Should propagate previous uploaded videos on a new following', async function () { + this.timeout(20000) + + const video4Attributes = { + name: 'server3-4', + category: 2, + nsfw: true, + licence: 6, + tags: [ 'tag1', 'tag2', 'tag3' ] + } + + await uploadVideo(servers[2].url, servers[2].accessToken, { name: 'server3-2' }) + await uploadVideo(servers[2].url, servers[2].accessToken, { name: 'server3-3' }) + await uploadVideo(servers[2].url, servers[2].accessToken, video4Attributes) + await uploadVideo(servers[2].url, servers[2].accessToken, { name: 'server3-5' }) + await uploadVideo(servers[2].url, servers[2].accessToken, { name: 'server3-6' }) + + { + const user = { username: 'captain', password: 'password' } + await createUser(servers[2].url, servers[2].accessToken, user.username, user.password) + const userAccessToken = await getUserAccessToken(servers[2], user) + + const resVideos = await getVideosList(servers[ 2 ].url) + const video4 = resVideos.body.data.find(v => v.name === 'server3-4') + + { + await rateVideo(servers[ 2 ].url, servers[ 2 ].accessToken, video4.id, 'like') + await rateVideo(servers[ 2 ].url, userAccessToken, video4.id, 'dislike') + } + + { + const text = 'my super first comment' + const res = await addVideoCommentThread(servers[ 2 ].url, servers[ 2 ].accessToken, video4.id, text) + const threadId = res.body.comment.id + + const text1 = 'my super answer to thread 1' + const childCommentRes = await addVideoCommentReply(servers[ 2 ].url, servers[ 2 ].accessToken, video4.id, threadId, text1) + const childCommentId = childCommentRes.body.comment.id + + const text2 = 'my super answer to answer of thread 1' + await addVideoCommentReply(servers[ 2 ].url, servers[ 2 ].accessToken, video4.id, childCommentId, text2) + + const text3 = 'my second answer to thread 1' + await addVideoCommentReply(servers[ 2 ].url, servers[ 2 ].accessToken, video4.id, threadId, text3) + } + } + + await wait(5000) + + // Server 1 follows server 3 + await follow(servers[0].url, [ servers[2].url ], servers[0].accessToken) + + await wait(7000) + + let res = await getVideosList(servers[0].url) + expect(res.body.total).to.equal(7) + + const video2 = res.body.data.find(v => v.name === 'server3-2') + const video4 = res.body.data.find(v => v.name === 'server3-4') + const video6 = res.body.data.find(v => v.name === 'server3-6') + + expect(video2).to.not.be.undefined + expect(video4).to.not.be.undefined + expect(video6).to.not.be.undefined + + const res2 = await getVideo(servers[0].url, video4.id) + const videoDetails = res2.body + + expect(videoDetails.name).to.equal('server3-4') + expect(videoDetails.category).to.equal(2) + expect(videoDetails.categoryLabel).to.equal('Films') + expect(videoDetails.licence).to.equal(6) + expect(videoDetails.licenceLabel).to.equal('Attribution - Non Commercial - No Derivatives') + expect(videoDetails.language).to.equal(3) + expect(videoDetails.languageLabel).to.equal('Mandarin') + expect(videoDetails.nsfw).to.be.ok + expect(videoDetails.description).to.equal('my super description') + expect(videoDetails.serverHost).to.equal('localhost:9003') + expect(videoDetails.accountName).to.equal('root') + expect(videoDetails.likes).to.equal(1) + expect(videoDetails.dislikes).to.equal(1) + expect(videoDetails.isLocal).to.be.false + expect(videoDetails.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) + expect(dateIsValid(videoDetails.createdAt)).to.be.true + expect(dateIsValid(videoDetails.updatedAt)).to.be.true + expect(videoDetails.files).to.have.lengthOf(1) + + const file = videoDetails.files[0] + const magnetUri = file.magnetUri + expect(file.magnetUri).to.have.lengthOf.above(2) + expect(file.torrentUrl).to.equal(`${servers[2].url}/static/torrents/${videoDetails.uuid}-${file.resolution}.torrent`) + expect(file.fileUrl).to.equal(`${servers[2].url}/static/webseed/${videoDetails.uuid}-${file.resolution}.webm`) + expect(file.resolution).to.equal(720) + expect(file.resolutionLabel).to.equal('720p') + expect(file.size).to.equal(218910) + + const test = await testVideoImage(servers[2].url, 'video_short.webm', videoDetails.thumbnailPath) + expect(test).to.equal(true) + + const torrent = await webtorrentAdd(magnetUri) + expect(torrent.files).to.be.an('array') + expect(torrent.files.length).to.equal(1) + expect(torrent.files[0].path).to.exist.and.to.not.equal('') + + { + const res1 = await getVideoCommentThreads(servers[0].url, video4.id, 0, 5) + + expect(res1.body.total).to.equal(1) + expect(res1.body.data).to.be.an('array') + expect(res1.body.data).to.have.lengthOf(1) + + const comment: VideoComment = res1.body.data[0] + expect(comment.inReplyToCommentId).to.be.null + expect(comment.text).equal('my super first comment') + expect(comment.videoId).to.equal(video4.id) + expect(comment.id).to.equal(comment.threadId) + expect(comment.account.name).to.equal('root') + expect(comment.account.host).to.equal('localhost:9003') + expect(comment.totalReplies).to.equal(3) + expect(dateIsValid(comment.createdAt as string)).to.be.true + expect(dateIsValid(comment.updatedAt as string)).to.be.true + + const threadId = comment.threadId + + const res2 = await getVideoThreadComments(servers[0].url, video4.id, threadId) + + const tree: VideoCommentThreadTree = res2.body + expect(tree.comment.text).equal('my super first comment') + expect(tree.children).to.have.lengthOf(2) + + const firstChild = tree.children[0] + expect(firstChild.comment.text).to.equal('my super answer to thread 1') + expect(firstChild.children).to.have.lengthOf(1) + + const childOfFirstChild = firstChild.children[0] + expect(childOfFirstChild.comment.text).to.equal('my super answer to answer of thread 1') + expect(childOfFirstChild.children).to.have.lengthOf(0) + + const secondChild = tree.children[1] + expect(secondChild.comment.text).to.equal('my second answer to thread 1') + expect(secondChild.children).to.have.lengthOf(0) + } + }) + + after(async function () { + killallServers(servers) + + // Keep the logs if the test failed + if (this['ok']) { + await flushTests() + } + }) +}) diff --git a/server/tests/api/server/jobs.ts b/server/tests/api/server/jobs.ts new file mode 100644 index 000000000..2e17e71a4 --- /dev/null +++ b/server/tests/api/server/jobs.ts @@ -0,0 +1,64 @@ +/* tslint:disable:no-unused-expression */ + +import * as chai from 'chai' +import 'mocha' +import { flushTests, killallServers, ServerInfo, setAccessTokensToServers, wait } from '../../utils/index' +import { doubleFollow } from '../../utils/server/follows' +import { getJobsList, getJobsListPaginationAndSort } from '../../utils/server/jobs' +import { flushAndRunMultipleServers } from '../../utils/server/servers' +import { uploadVideo } from '../../utils/videos/videos' +import { dateIsValid } from '../../utils/miscs/miscs' + +const expect = chai.expect + +describe('Test jobs', function () { + let servers: ServerInfo[] + + before(async function () { + this.timeout(30000) + + servers = await flushAndRunMultipleServers(2) + + await setAccessTokensToServers(servers) + + // Server 1 and server 2 follow each other + await doubleFollow(servers[0], servers[1]) + }) + + it('Should create some jobs', async function () { + this.timeout(30000) + + await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'video1' }) + await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'video2' }) + + await wait(15000) + }) + + it('Should list jobs', async function () { + const res = await getJobsList(servers[1].url, servers[1].accessToken) + expect(res.body.total).to.be.above(2) + expect(res.body.data).to.have.length.above(2) + }) + + it('Should list jobs with sort and pagination', async function () { + const res = await getJobsListPaginationAndSort(servers[1].url, servers[1].accessToken, 4, 1, 'createdAt') + expect(res.body.total).to.be.above(2) + expect(res.body.data).to.have.lengthOf(1) + + const job = res.body.data[0] + expect(job.state).to.equal('success') + expect(job.category).to.equal('transcoding') + expect(job.handlerName).to.have.length.above(3) + expect(dateIsValid(job.createdAt)).to.be.true + expect(dateIsValid(job.updatedAt)).to.be.true + }) + + after(async function () { + killallServers(servers) + + // Keep the logs if the test failed + if (this['ok']) { + await flushTests() + } + }) +}) diff --git a/server/tests/api/services.ts b/server/tests/api/services.ts deleted file mode 100644 index 4d480c305..000000000 --- a/server/tests/api/services.ts +++ /dev/null @@ -1,85 +0,0 @@ -/* tslint:disable:no-unused-expression */ - -import 'mocha' -import * as chai from 'chai' -const expect = chai.expect - -import { - ServerInfo, - flushTests, - uploadVideo, - getVideosList, - setAccessTokensToServers, - killallServers, - getOEmbed -} from '../utils' -import { runServer } from '../utils/servers' - -describe('Test services', function () { - let server: ServerInfo = null - - before(async function () { - this.timeout(10000) - - await flushTests() - - server = await runServer(1) - - await setAccessTokensToServers([ server ]) - - const videoAttributes = { - name: 'my super name' - } - await uploadVideo(server.url, server.accessToken, videoAttributes) - - const res = await getVideosList(server.url) - server.video = res.body.data[0] - }) - - it('Should have a valid oEmbed response', async function () { - const oembedUrl = 'http://localhost:9001/videos/watch/' + server.video.uuid - - const res = await getOEmbed(server.url, oembedUrl) - const expectedHtml = `' - const expectedThumbnailUrl = 'http://localhost:9001/static/previews/' + server.video.uuid + '.jpg' - - expect(res.body.html).to.equal(expectedHtml) - expect(res.body.title).to.equal(server.video.name) - expect(res.body.author_name).to.equal(server.video.accountName) - expect(res.body.width).to.equal(560) - expect(res.body.height).to.equal(315) - expect(res.body.thumbnail_url).to.equal(expectedThumbnailUrl) - expect(res.body.thumbnail_width).to.equal(560) - expect(res.body.thumbnail_height).to.equal(315) - }) - - it('Should have a valid oEmbed response with small max height query', async function () { - const oembedUrl = 'http://localhost:9001/videos/watch/' + server.video.uuid - const format = 'json' - const maxHeight = 50 - const maxWidth = 50 - - const res = await getOEmbed(server.url, oembedUrl, format, maxHeight, maxWidth) - const expectedHtml = `' - - expect(res.body.html).to.equal(expectedHtml) - expect(res.body.title).to.equal(server.video.name) - expect(res.body.author_name).to.equal(server.video.accountName) - expect(res.body.height).to.equal(50) - expect(res.body.width).to.equal(50) - expect(res.body).to.not.have.property('thumbnail_url') - expect(res.body).to.not.have.property('thumbnail_width') - expect(res.body).to.not.have.property('thumbnail_height') - }) - - after(async function () { - killallServers([ server ]) - - // Keep the logs if the test failed - if (this['ok']) { - await flushTests() - } - }) -}) diff --git a/server/tests/api/single-server.ts b/server/tests/api/single-server.ts deleted file mode 100644 index 7f4351f5e..000000000 --- a/server/tests/api/single-server.ts +++ /dev/null @@ -1,701 +0,0 @@ -/* tslint:disable:no-unused-expression */ - -import * as chai from 'chai' -import { keyBy } from 'lodash' -import 'mocha' -import { join } from 'path' -import { - dateIsValid, - flushTests, - getVideo, - getVideoCategories, - getVideoLanguages, - getVideoLicences, - getVideoPrivacies, - getVideosList, - getVideosListPagination, - getVideosListSort, - killallServers, - rateVideo, - readdirPromise, - removeVideo, - runServer, - searchVideo, - searchVideoWithPagination, - searchVideoWithSort, - ServerInfo, - setAccessTokensToServers, - testVideoImage, - updateVideo, - uploadVideo, - wait, - webtorrentAdd -} from '../utils' -import { viewVideo } from '../utils/videos' - -const expect = chai.expect - -describe('Test a single server', function () { - let server: ServerInfo = null - let videoId = -1 - let videoUUID = '' - let videosListBase: any[] = null - - before(async function () { - this.timeout(10000) - - await flushTests() - - server = await runServer(1) - - await setAccessTokensToServers([ server ]) - }) - - it('Should list video categories', async function () { - const res = await getVideoCategories(server.url) - - const categories = res.body - expect(Object.keys(categories)).to.have.length.above(10) - - expect(categories[11]).to.equal('News') - }) - - it('Should list video licences', async function () { - const res = await getVideoLicences(server.url) - - const licences = res.body - expect(Object.keys(licences)).to.have.length.above(5) - - expect(licences[3]).to.equal('Attribution - No Derivatives') - }) - - it('Should list video languages', async function () { - const res = await getVideoLanguages(server.url) - - const languages = res.body - expect(Object.keys(languages)).to.have.length.above(5) - - expect(languages[3]).to.equal('Mandarin') - }) - - it('Should list video privacies', async function () { - const res = await getVideoPrivacies(server.url) - - const privacies = res.body - expect(Object.keys(privacies)).to.have.length.at.least(3) - - expect(privacies[3]).to.equal('Private') - }) - - it('Should not have videos', async function () { - const res = await getVideosList(server.url) - - expect(res.body.total).to.equal(0) - expect(res.body.data).to.be.an('array') - expect(res.body.data.length).to.equal(0) - }) - - it('Should upload the video', async function () { - const videoAttributes = { - name: 'my super name', - category: 2, - nsfw: true, - licence: 6, - tags: [ 'tag1', 'tag2', 'tag3' ] - } - const res = await uploadVideo(server.url, server.accessToken, videoAttributes) - expect(res.body.video).to.not.be.undefined - expect(res.body.video.id).to.equal(1) - expect(res.body.video.uuid).to.have.length.above(5) - }) - - it('Should seed the uploaded video', async function () { - // Yes, this could be long - this.timeout(60000) - - const res = await getVideosList(server.url) - - expect(res.body.total).to.equal(1) - expect(res.body.data).to.be.an('array') - expect(res.body.data.length).to.equal(1) - - const video = res.body.data[0] - expect(video.name).to.equal('my super name') - expect(video.category).to.equal(2) - expect(video.categoryLabel).to.equal('Films') - expect(video.licence).to.equal(6) - expect(video.licenceLabel).to.equal('Attribution - Non Commercial - No Derivatives') - expect(video.language).to.equal(3) - expect(video.languageLabel).to.equal('Mandarin') - expect(video.nsfw).to.be.ok - expect(video.description).to.equal('my super description') - expect(video.serverHost).to.equal('localhost:9001') - expect(video.accountName).to.equal('root') - expect(video.isLocal).to.be.true - expect(dateIsValid(video.createdAt)).to.be.true - expect(dateIsValid(video.updatedAt)).to.be.true - - const res2 = await getVideo(server.url, res.body.data[0].id) - const videoDetails = res2.body - - expect(videoDetails.files).to.have.lengthOf(1) - - const file = videoDetails.files[0] - const magnetUri = file.magnetUri - expect(file.magnetUri).to.have.lengthOf.above(2) - expect(file.torrentUrl).to.equal(`${server.url}/static/torrents/${videoDetails.uuid}-${file.resolution}.torrent`) - expect(file.fileUrl).to.equal(`${server.url}/static/webseed/${videoDetails.uuid}-${file.resolution}.webm`) - expect(file.resolution).to.equal(720) - expect(file.resolutionLabel).to.equal('720p') - expect(file.size).to.equal(218910) - - const test = await testVideoImage(server.url, 'video_short.webm', videoDetails.thumbnailPath) - expect(test).to.equal(true) - - videoId = videoDetails.id - videoUUID = videoDetails.uuid - - const torrent = await webtorrentAdd(magnetUri) - expect(torrent.files).to.be.an('array') - expect(torrent.files.length).to.equal(1) - expect(torrent.files[0].path).to.exist.and.to.not.equal('') - }) - - it('Should get the video', async function () { - // Yes, this could be long - this.timeout(60000) - - const res = await getVideo(server.url, videoId) - - const video = res.body - expect(video.name).to.equal('my super name') - expect(video.category).to.equal(2) - expect(video.categoryLabel).to.equal('Films') - expect(video.licence).to.equal(6) - expect(video.licenceLabel).to.equal('Attribution - Non Commercial - No Derivatives') - expect(video.language).to.equal(3) - expect(video.languageLabel).to.equal('Mandarin') - expect(video.nsfw).to.be.ok - expect(video.description).to.equal('my super description') - expect(video.serverHost).to.equal('localhost:9001') - expect(video.accountName).to.equal('root') - expect(video.isLocal).to.be.true - expect(dateIsValid(video.createdAt)).to.be.true - expect(dateIsValid(video.updatedAt)).to.be.true - expect(video.channel.name).to.equal('Default root channel') - expect(video.channel.isLocal).to.be.true - expect(dateIsValid(video.channel.createdAt)).to.be.true - expect(dateIsValid(video.channel.updatedAt)).to.be.true - - expect(video.files).to.have.lengthOf(1) - - const file = video.files[0] - expect(file.magnetUri).to.have.lengthOf.above(2) - expect(file.resolution).to.equal(720) - expect(file.resolutionLabel).to.equal('720p') - expect(file.size).to.equal(218910) - - const test = await testVideoImage(server.url, 'video_short.webm', video.thumbnailPath) - expect(test).to.equal(true) - - // Wait the async views increment - await wait(500) - }) - - it('Should get the video by UUID', async function () { - // Yes, this could be long - this.timeout(60000) - - const res = await getVideo(server.url, videoUUID) - - const video = res.body - expect(video.name).to.equal('my super name') - - // Wait the async views increment - await wait(500) - }) - - it('Should have the views updated', async function () { - await viewVideo(server.url, videoId) - await viewVideo(server.url, videoId) - await viewVideo(server.url, videoId) - - const res = await getVideo(server.url, videoId) - - const video = res.body - expect(video.views).to.equal(3) - }) - - it('Should search the video by name', async function () { - const res = await searchVideo(server.url, 'my') - - expect(res.body.total).to.equal(1) - expect(res.body.data).to.be.an('array') - expect(res.body.data.length).to.equal(1) - - const video = res.body.data[0] - expect(video.name).to.equal('my super name') - expect(video.category).to.equal(2) - expect(video.categoryLabel).to.equal('Films') - expect(video.licence).to.equal(6) - expect(video.licenceLabel).to.equal('Attribution - Non Commercial - No Derivatives') - expect(video.language).to.equal(3) - expect(video.languageLabel).to.equal('Mandarin') - expect(video.nsfw).to.be.ok - expect(video.description).to.equal('my super description') - expect(video.serverHost).to.equal('localhost:9001') - expect(video.accountName).to.equal('root') - expect(video.isLocal).to.be.true - expect(dateIsValid(video.createdAt)).to.be.true - expect(dateIsValid(video.updatedAt)).to.be.true - - const test = await testVideoImage(server.url, 'video_short.webm', video.thumbnailPath) - expect(test).to.equal(true) - }) - - // Not implemented yet - // it('Should search the video by serverHost', async function () { - // const res = await videosUtils.searchVideo(server.url, '9001', 'host') - - // expect(res.body.total).to.equal(1) - // expect(res.body.data).to.be.an('array') - // expect(res.body.data.length).to.equal(1) - - // const video = res.body.data[0] - // expect(video.name).to.equal('my super name') - // expect(video.description).to.equal('my super description') - // expect(video.serverHost).to.equal('localhost:9001') - // expect(video.author).to.equal('root') - // expect(video.isLocal).to.be.true - // expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) - // expect(dateIsValid(video.createdAt)).to.be.true - // expect(dateIsValid(video.updatedAt)).to.be.true - - // const test = await testVideoImage(server.url, 'video_short.webm', video.thumbnailPath) - // expect(test).to.equal(true) - - // done() - // }) - // }) - // }) - - // Not implemented yet - // it('Should search the video by tag', async function () { - // const res = await searchVideo(server.url, 'tag1') - // - // expect(res.body.total).to.equal(1) - // expect(res.body.data).to.be.an('array') - // expect(res.body.data.length).to.equal(1) - // - // const video = res.body.data[0] - // expect(video.name).to.equal('my super name') - // expect(video.category).to.equal(2) - // expect(video.categoryLabel).to.equal('Films') - // expect(video.licence).to.equal(6) - // expect(video.licenceLabel).to.equal('Attribution - Non Commercial - No Derivatives') - // expect(video.language).to.equal(3) - // expect(video.languageLabel).to.equal('Mandarin') - // expect(video.nsfw).to.be.ok - // expect(video.description).to.equal('my super description') - // expect(video.serverHost).to.equal('localhost:9001') - // expect(video.accountName).to.equal('root') - // expect(video.isLocal).to.be.true - // expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) - // expect(dateIsValid(video.createdAt)).to.be.true - // expect(dateIsValid(video.updatedAt)).to.be.true - // - // const test = await testVideoImage(server.url, 'video_short.webm', video.thumbnailPath) - // expect(test).to.equal(true) - // }) - - it('Should not find a search by name', async function () { - const res = await searchVideo(server.url, 'hello') - - expect(res.body.total).to.equal(0) - expect(res.body.data).to.be.an('array') - expect(res.body.data.length).to.equal(0) - }) - - // Not implemented yet - // it('Should not find a search by author', async function () { - // const res = await searchVideo(server.url, 'hello') - // - // expect(res.body.total).to.equal(0) - // expect(res.body.data).to.be.an('array') - // expect(res.body.data.length).to.equal(0) - // }) - // - // Not implemented yet - // it('Should not find a search by tag', async function () { - // const res = await searchVideo(server.url, 'hello') - // - // expect(res.body.total).to.equal(0) - // expect(res.body.data).to.be.an('array') - // expect(res.body.data.length).to.equal(0) - // }) - - it('Should remove the video', async function () { - await removeVideo(server.url, server.accessToken, videoId) - - const files1 = await readdirPromise(join(__dirname, '..', '..', '..', 'test1/videos/')) - expect(files1).to.have.lengthOf(0) - - const files2 = await readdirPromise(join(__dirname, '..', '..', '..', 'test1/thumbnails/')) - expect(files2).to.have.lengthOf(0) - }) - - it('Should not have videos', async function () { - const res = await getVideosList(server.url) - - expect(res.body.total).to.equal(0) - expect(res.body.data).to.be.an('array') - expect(res.body.data).to.have.lengthOf(0) - }) - - it('Should upload 6 videos', async function () { - this.timeout(25000) - - const videos = [ - 'video_short.mp4', 'video_short.ogv', 'video_short.webm', - 'video_short1.webm', 'video_short2.webm', 'video_short3.webm' - ] - - const tasks: Promise[] = [] - for (const video of videos) { - const videoAttributes = { - name: video + ' name', - description: video + ' description', - category: 2, - licence: 1, - language: 1, - nsfw: true, - tags: [ 'tag1', 'tag2', 'tag3' ], - fixture: video - } - - const p = uploadVideo(server.url, server.accessToken, videoAttributes) - tasks.push(p) - } - - await Promise.all(tasks) - }) - - it('Should have the correct durations', async function () { - const res = await getVideosList(server.url) - - expect(res.body.total).to.equal(6) - const videos = res.body.data - expect(videos).to.be.an('array') - expect(videos).to.have.lengthOf(6) - - const videosByName = keyBy<{ duration: number }>(videos, 'name') - expect(videosByName['video_short.mp4 name'].duration).to.equal(5) - expect(videosByName['video_short.ogv name'].duration).to.equal(5) - expect(videosByName['video_short.webm name'].duration).to.equal(5) - expect(videosByName['video_short1.webm name'].duration).to.equal(10) - expect(videosByName['video_short2.webm name'].duration).to.equal(5) - expect(videosByName['video_short3.webm name'].duration).to.equal(5) - }) - - it('Should have the correct thumbnails', async function () { - const res = await getVideosList(server.url) - - const videos = res.body.data - // For the next test - videosListBase = videos - - for (const video of videos) { - const videoName = video.name.replace(' name', '') - const test = await testVideoImage(server.url, videoName, video.thumbnailPath) - - expect(test).to.equal(true) - } - }) - - it('Should list only the two first videos', async function () { - const res = await getVideosListPagination(server.url, 0, 2, 'name') - - const videos = res.body.data - expect(res.body.total).to.equal(6) - expect(videos.length).to.equal(2) - expect(videos[0].name).to.equal(videosListBase[0].name) - expect(videos[1].name).to.equal(videosListBase[1].name) - }) - - it('Should list only the next three videos', async function () { - const res = await getVideosListPagination(server.url, 2, 3, 'name') - - const videos = res.body.data - expect(res.body.total).to.equal(6) - expect(videos.length).to.equal(3) - expect(videos[0].name).to.equal(videosListBase[2].name) - expect(videos[1].name).to.equal(videosListBase[3].name) - expect(videos[2].name).to.equal(videosListBase[4].name) - }) - - it('Should list the last video', async function () { - const res = await getVideosListPagination(server.url, 5, 6, 'name') - - const videos = res.body.data - expect(res.body.total).to.equal(6) - expect(videos.length).to.equal(1) - expect(videos[0].name).to.equal(videosListBase[5].name) - }) - - it('Should search the first video', async function () { - const res = await searchVideoWithPagination(server.url, 'webm', 0, 1, 'name') - - const videos = res.body.data - expect(res.body.total).to.equal(4) - expect(videos.length).to.equal(1) - expect(videos[0].name).to.equal('video_short1.webm name') - }) - - it('Should search the last two videos', async function () { - const res = await searchVideoWithPagination(server.url, 'webm', 2, 2, 'name') - - const videos = res.body.data - expect(res.body.total).to.equal(4) - expect(videos.length).to.equal(2) - expect(videos[0].name).to.equal('video_short3.webm name') - expect(videos[1].name).to.equal('video_short.webm name') - }) - - it('Should search all the webm videos', async function () { - const res = await searchVideoWithPagination(server.url, 'webm', 0, 15) - - const videos = res.body.data - expect(res.body.total).to.equal(4) - expect(videos.length).to.equal(4) - }) - - // Not implemented yet - // it('Should search all the root author videos', async function () { - // const res = await searchVideoWithPagination(server.url, 'root', 0, 15) - // - // const videos = res.body.data - // expect(res.body.total).to.equal(6) - // expect(videos.length).to.equal(6) - // }) - - // Not implemented yet - // it('Should search all the 9001 port videos', async function () { - // const res = await videosUtils.searchVideoWithPagination(server.url, '9001', 'host', 0, 15) - - // const videos = res.body.data - // expect(res.body.total).to.equal(6) - // expect(videos.length).to.equal(6) - - // done() - // }) - // }) - - // it('Should search all the localhost videos', async function () { - // const res = await videosUtils.searchVideoWithPagination(server.url, 'localhost', 'host', 0, 15) - - // const videos = res.body.data - // expect(res.body.total).to.equal(6) - // expect(videos.length).to.equal(6) - - // done() - // }) - // }) - - it('Should list and sort by name in descending order', async function () { - const res = await getVideosListSort(server.url, '-name') - - const videos = res.body.data - expect(res.body.total).to.equal(6) - expect(videos.length).to.equal(6) - expect(videos[0].name).to.equal('video_short.webm name') - expect(videos[1].name).to.equal('video_short.ogv name') - expect(videos[2].name).to.equal('video_short.mp4 name') - expect(videos[3].name).to.equal('video_short3.webm name') - expect(videos[4].name).to.equal('video_short2.webm name') - expect(videos[5].name).to.equal('video_short1.webm name') - }) - - it('Should search and sort by name in ascending order', async function () { - const res = await searchVideoWithSort(server.url, 'webm', 'name') - - const videos = res.body.data - expect(res.body.total).to.equal(4) - expect(videos.length).to.equal(4) - - expect(videos[0].name).to.equal('video_short1.webm name') - expect(videos[1].name).to.equal('video_short2.webm name') - expect(videos[2].name).to.equal('video_short3.webm name') - expect(videos[3].name).to.equal('video_short.webm name') - - videoId = videos[2].id - }) - - it('Should update a video', async function () { - const attributes = { - name: 'my super video updated', - category: 4, - licence: 2, - language: 5, - nsfw: false, - description: 'my super description updated', - tags: [ 'tagup1', 'tagup2' ] - } - await updateVideo(server.url, server.accessToken, videoId, attributes) - }) - - it('Should have the video updated', async function () { - this.timeout(60000) - - const res = await getVideo(server.url, videoId) - - const video = res.body - - expect(video.name).to.equal('my super video updated') - expect(video.category).to.equal(4) - expect(video.categoryLabel).to.equal('Art') - expect(video.licence).to.equal(2) - expect(video.licenceLabel).to.equal('Attribution - Share Alike') - expect(video.language).to.equal(5) - expect(video.languageLabel).to.equal('Arabic') - expect(video.nsfw).to.be.ok - expect(video.description).to.equal('my super description updated') - expect(video.serverHost).to.equal('localhost:9001') - expect(video.accountName).to.equal('root') - expect(video.account.name).to.equal('root') - expect(video.isLocal).to.be.true - expect(video.tags).to.deep.equal([ 'tagup1', 'tagup2' ]) - expect(dateIsValid(video.createdAt)).to.be.true - expect(dateIsValid(video.updatedAt)).to.be.true - - expect(video.channel.name).to.equal('Default root channel') - expect(video.channel.isLocal).to.be.true - expect(dateIsValid(video.channel.createdAt)).to.be.true - expect(dateIsValid(video.channel.updatedAt)).to.be.true - - expect(video.files).to.have.lengthOf(1) - - const file = video.files[0] - const magnetUri = file.magnetUri - expect(file.magnetUri).to.have.lengthOf.above(2) - expect(file.resolution).to.equal(720) - expect(file.resolutionLabel).to.equal('720p') - expect(file.size).to.equal(292677) - - const test = await testVideoImage(server.url, 'video_short3.webm', video.thumbnailPath) - expect(test).to.equal(true) - - const torrent = await webtorrentAdd(magnetUri) - expect(torrent.files).to.be.an('array') - expect(torrent.files.length).to.equal(1) - expect(torrent.files[0].path).to.exist.and.to.not.equal('') - }) - - it('Should update only the tags of a video', async function () { - const attributes = { - tags: [ 'tag1', 'tag2', 'supertag' ] - } - - await updateVideo(server.url, server.accessToken, videoId, attributes) - - const res = await getVideo(server.url, videoId) - const video = res.body - - expect(video.name).to.equal('my super video updated') - expect(video.category).to.equal(4) - expect(video.categoryLabel).to.equal('Art') - expect(video.licence).to.equal(2) - expect(video.licenceLabel).to.equal('Attribution - Share Alike') - expect(video.language).to.equal(5) - expect(video.languageLabel).to.equal('Arabic') - expect(video.nsfw).to.be.ok - expect(video.description).to.equal('my super description updated') - expect(video.serverHost).to.equal('localhost:9001') - expect(video.accountName).to.equal('root') - expect(video.isLocal).to.be.true - expect(video.tags).to.deep.equal([ 'supertag', 'tag1', 'tag2' ]) - expect(dateIsValid(video.createdAt)).to.be.true - expect(dateIsValid(video.updatedAt)).to.be.true - - expect(video.channel.name).to.equal('Default root channel') - expect(video.channel.isLocal).to.be.true - expect(dateIsValid(video.channel.createdAt)).to.be.true - expect(dateIsValid(video.channel.updatedAt)).to.be.true - - expect(video.files).to.have.lengthOf(1) - - const file = video.files[0] - expect(file.magnetUri).to.have.lengthOf.above(2) - expect(file.resolution).to.equal(720) - expect(file.resolutionLabel).to.equal('720p') - expect(file.size).to.equal(292677) - }) - - it('Should update only the description of a video', async function () { - const attributes = { - description: 'hello everybody' - } - - await updateVideo(server.url, server.accessToken, videoId, attributes) - - const res = await getVideo(server.url, videoId) - const video = res.body - - expect(video.name).to.equal('my super video updated') - expect(video.category).to.equal(4) - expect(video.categoryLabel).to.equal('Art') - expect(video.licence).to.equal(2) - expect(video.licenceLabel).to.equal('Attribution - Share Alike') - expect(video.language).to.equal(5) - expect(video.languageLabel).to.equal('Arabic') - expect(video.nsfw).to.be.ok - expect(video.description).to.equal('hello everybody') - expect(video.serverHost).to.equal('localhost:9001') - expect(video.accountName).to.equal('root') - expect(video.isLocal).to.be.true - expect(video.tags).to.deep.equal([ 'supertag', 'tag1', 'tag2' ]) - expect(dateIsValid(video.createdAt)).to.be.true - expect(dateIsValid(video.updatedAt)).to.be.true - - expect(video.channel.name).to.equal('Default root channel') - expect(video.channel.isLocal).to.be.true - expect(dateIsValid(video.channel.createdAt)).to.be.true - expect(dateIsValid(video.channel.updatedAt)).to.be.true - - expect(video.files).to.have.lengthOf(1) - - const file = video.files[0] - expect(file.magnetUri).to.have.lengthOf.above(2) - expect(file.resolution).to.equal(720) - expect(file.resolutionLabel).to.equal('720p') - expect(file.size).to.equal(292677) - }) - - it('Should like a video', async function () { - await rateVideo(server.url, server.accessToken, videoId, 'like') - - const res = await getVideo(server.url, videoId) - const video = res.body - - expect(video.likes).to.equal(1) - expect(video.dislikes).to.equal(0) - }) - - it('Should dislike the same video', async function () { - await rateVideo(server.url, server.accessToken, videoId, 'dislike') - - const res = await getVideo(server.url, videoId) - const video = res.body - - expect(video.likes).to.equal(0) - expect(video.dislikes).to.equal(1) - }) - - after(async function () { - killallServers([ server ]) - - // Keep the logs if the test failed - if (this['ok']) { - await flushTests() - } - }) -}) diff --git a/server/tests/api/users.ts b/server/tests/api/users.ts deleted file mode 100644 index 67e4cc8c6..000000000 --- a/server/tests/api/users.ts +++ /dev/null @@ -1,534 +0,0 @@ -/* tslint:disable:no-unused-expression */ - -import * as chai from 'chai' -import 'mocha' -import { UserRole } from '../../../shared' -import { - createUser, - flushTests, - getBlacklistedVideosList, - getMyUserInformation, - getUserInformation, - getUsersList, - getUsersListPaginationAndSort, - getUserVideoRating, - getVideosList, - killallServers, - login, - loginAndGetAccessToken, - makePutBodyRequest, - rateVideo, - registerUser, - removeUser, - removeVideo, - runServer, - ServerInfo, - updateMyUser, - updateUser, - uploadVideo -} from '../utils' -import { follow } from '../utils/follows' -import { getMyVideos } from '../utils/videos' -import { setAccessTokensToServers } from '../utils/login' - -const expect = chai.expect - -describe('Test users', function () { - let server: ServerInfo - let accessToken: string - let accessTokenUser: string - let videoId: number - let userId: number - - before(async function () { - this.timeout(10000) - - await flushTests() - server = await runServer(1) - - await setAccessTokensToServers([ server ]) - }) - - it('Should create a new client') - - it('Should return the first client') - - it('Should remove the last client') - - it('Should not login with an invalid client id', async function () { - const client = { id: 'client', secret: server.client.secret } - const res = await login(server.url, client, server.user, 400) - - expect(res.body.error) - .to - .equal('invalid_client') - }) - - it('Should not login with an invalid client secret', async function () { - const client = { id: server.client.id, secret: 'coucou' } - const res = await login(server.url, client, server.user, 400) - - expect(res.body.error) - .to - .equal('invalid_client') - }) - - it('Should not login with an invalid username', async function () { - const user = { username: 'captain crochet', password: server.user.password } - const res = await login(server.url, server.client, user, 400) - - expect(res.body.error) - .to - .equal('invalid_grant') - }) - - it('Should not login with an invalid password', async function () { - const user = { username: server.user.username, password: 'mew_three' } - const res = await login(server.url, server.client, user, 400) - - expect(res.body.error) - .to - .equal('invalid_grant') - }) - - it('Should not be able to upload a video', async function () { - accessToken = 'my_super_token' - - const videoAttributes = {} - await uploadVideo(server.url, accessToken, videoAttributes, 401) - }) - - it('Should not be able to follow', async function () { - accessToken = 'my_super_token' - await follow(server.url, [ 'http://example.com' ], accessToken, 401) - }) - - it('Should not be able to unfollow') - - it('Should be able to login', async function () { - const res = await login(server.url, server.client, server.user, 200) - - accessToken = res.body.access_token - }) - - it('Should upload the video with the correct token', async function () { - const videoAttributes = {} - await uploadVideo(server.url, accessToken, videoAttributes) - const res = await getVideosList(server.url) - const video = res.body.data[ 0 ] - - expect(video.accountName) - .to - .equal('root') - videoId = video.id - }) - - it('Should upload the video again with the correct token', async function () { - const videoAttributes = {} - await uploadVideo(server.url, accessToken, videoAttributes) - }) - - it('Should retrieve a video rating', async function () { - await rateVideo(server.url, accessToken, videoId, 'like') - const res = await getUserVideoRating(server.url, accessToken, videoId) - const rating = res.body - - expect(rating.videoId) - .to - .equal(videoId) - expect(rating.rating) - .to - .equal('like') - }) - - it('Should not be able to remove the video with an incorrect token', async function () { - await removeVideo(server.url, 'bad_token', videoId, 401) - }) - - it('Should not be able to remove the video with the token of another account') - - it('Should be able to remove the video with the correct token', async function () { - await removeVideo(server.url, accessToken, videoId) - }) - - it('Should logout (revoke token)') - - it('Should not be able to get the user information') - - it('Should not be able to upload a video') - - it('Should not be able to remove a video') - - it('Should not be able to rate a video', async function () { - const path = '/api/v1/videos/' - const data = { - rating: 'likes' - } - - const options = { - url: server.url, - path: path + videoId, - token: 'wrong token', - fields: data, - statusCodeExpected: 401 - } - await makePutBodyRequest(options) - }) - - it('Should be able to login again') - - it('Should have an expired access token') - - it('Should refresh the token') - - it('Should be able to upload a video again') - - it('Should be able to create a new user', async function () { - await createUser(server.url, accessToken, 'user_1', 'super password', 2 * 1024 * 1024) - }) - - it('Should be able to login with this user', async function () { - server.user = { - username: 'user_1', - password: 'super password' - } - - accessTokenUser = await loginAndGetAccessToken(server) - }) - - it('Should be able to get the user information', async function () { - const res = await getMyUserInformation(server.url, accessTokenUser) - const user = res.body - - expect(user.username) - .to - .equal('user_1') - expect(user.email) - .to - .equal('user_1@example.com') - expect(user.displayNSFW).to.be.false - expect(user.videoQuota) - .to - .equal(2 * 1024 * 1024) - expect(user.roleLabel) - .to - .equal('User') - expect(user.id) - .to - .be - .a('number') - }) - - it('Should be able to upload a video with this user', async function () { - this.timeout(5000) - - const videoAttributes = { - name: 'super user video' - } - await uploadVideo(server.url, accessTokenUser, videoAttributes) - }) - - it('Should be able to list my videos', async function () { - const res = await getMyVideos(server.url, accessTokenUser, 0, 5) - expect(res.body.total) - .to - .equal(1) - - const videos = res.body.data - expect(videos) - .to - .have - .lengthOf(1) - - expect(videos[ 0 ].name) - .to - .equal('super user video') - }) - - it('Should list all the users', async function () { - const res = await getUsersList(server.url, server.accessToken) - const result = res.body - const total = result.total - const users = result.data - - expect(total) - .to - .equal(2) - expect(users) - .to - .be - .an('array') - expect(users.length) - .to - .equal(2) - - const user = users[ 0 ] - expect(user.username) - .to - .equal('user_1') - expect(user.email) - .to - .equal('user_1@example.com') - expect(user.displayNSFW).to.be.false - - const rootUser = users[ 1 ] - expect(rootUser.username) - .to - .equal('root') - expect(rootUser.email) - .to - .equal('admin1@example.com') - expect(rootUser.displayNSFW).to.be.false - - userId = user.id - }) - - it('Should list only the first user by username asc', async function () { - const res = await getUsersListPaginationAndSort(server.url, server.accessToken, 0, 1, 'username') - - const result = res.body - const total = result.total - const users = result.data - - expect(total) - .to - .equal(2) - expect(users.length) - .to - .equal(1) - - const user = users[ 0 ] - expect(user.username) - .to - .equal('root') - expect(user.email) - .to - .equal('admin1@example.com') - expect(user.roleLabel) - .to - .equal('Administrator') - expect(user.displayNSFW).to.be.false - }) - - it('Should list only the first user by username desc', async function () { - const res = await getUsersListPaginationAndSort(server.url, server.accessToken, 0, 1, '-username') - const result = res.body - const total = result.total - const users = result.data - - expect(total) - .to - .equal(2) - expect(users.length) - .to - .equal(1) - - const user = users[ 0 ] - expect(user.username) - .to - .equal('user_1') - expect(user.email) - .to - .equal('user_1@example.com') - expect(user.displayNSFW).to.be.false - }) - - it('Should list only the second user by createdAt desc', async function () { - const res = await getUsersListPaginationAndSort(server.url, server.accessToken, 0, 1, '-createdAt') - const result = res.body - const total = result.total - const users = result.data - - expect(total) - .to - .equal(2) - expect(users.length) - .to - .equal(1) - - const user = users[ 0 ] - expect(user.username) - .to - .equal('user_1') - expect(user.email) - .to - .equal('user_1@example.com') - expect(user.displayNSFW).to.be.false - }) - - it('Should list all the users by createdAt asc', async function () { - const res = await getUsersListPaginationAndSort(server.url, server.accessToken, 0, 2, 'createdAt') - const result = res.body - const total = result.total - const users = result.data - - expect(total) - .to - .equal(2) - expect(users.length) - .to - .equal(2) - - expect(users[ 0 ].username) - .to - .equal('root') - expect(users[ 0 ].email) - .to - .equal('admin1@example.com') - expect(users[ 0 ].displayNSFW).to.be.false - - expect(users[ 1 ].username) - .to - .equal('user_1') - expect(users[ 1 ].email) - .to - .equal('user_1@example.com') - expect(users[ 1 ].displayNSFW).to.be.false - }) - - it('Should update my password', async function () { - await updateMyUser(server.url, accessTokenUser, 'new password') - server.user.password = 'new password' - - await login(server.url, server.client, server.user, 200) - }) - - it('Should be able to change the NSFW display attribute', async function () { - await updateMyUser(server.url, accessTokenUser, undefined, true) - - const res = await getMyUserInformation(server.url, accessTokenUser) - const user = res.body - - expect(user.username) - .to - .equal('user_1') - expect(user.email) - .to - .equal('user_1@example.com') - expect(user.displayNSFW).to.be.ok - expect(user.videoQuota) - .to - .equal(2 * 1024 * 1024) - expect(user.id) - .to - .be - .a('number') - }) - - it('Should be able to change the autoPlayVideo attribute', async function () { - await updateMyUser(server.url, accessTokenUser, undefined, undefined, undefined, false) - - const res = await getMyUserInformation(server.url, accessTokenUser) - const user = res.body - - expect(user.autoPlayVideo).to.be.false - }) - - it('Should be able to change the email display attribute', async function () { - await updateMyUser(server.url, accessTokenUser, undefined, undefined, 'updated@example.com') - - const res = await getMyUserInformation(server.url, accessTokenUser) - const user = res.body - - expect(user.username) - .to - .equal('user_1') - expect(user.email) - .to - .equal('updated@example.com') - expect(user.displayNSFW).to.be.ok - expect(user.videoQuota) - .to - .equal(2 * 1024 * 1024) - expect(user.id) - .to - .be - .a('number') - }) - - it('Should be able to update another user', async function () { - await updateUser(server.url, userId, accessToken, 'updated2@example.com', 42, UserRole.MODERATOR) - - const res = await getUserInformation(server.url, accessToken, userId) - const user = res.body - - expect(user.username) - .to - .equal('user_1') - expect(user.email) - .to - .equal('updated2@example.com') - expect(user.displayNSFW).to.be.ok - expect(user.videoQuota) - .to - .equal(42) - expect(user.roleLabel) - .to - .equal('Moderator') - expect(user.id) - .to - .be - .a('number') - }) - - it('Should not be able to delete a user by a moderator', async function () { - await removeUser(server.url, 2, accessTokenUser, 403) - }) - - it('Should be able to list video blacklist by a moderator', async function () { - await getBlacklistedVideosList(server.url, accessTokenUser) - }) - - it('Should be able to remove this user', async function () { - await removeUser(server.url, userId, accessToken) - }) - - it('Should not be able to login with this user', async function () { - // server.user is already set to user 1 - await login(server.url, server.client, server.user, 400) - }) - - it('Should not have videos of this user', async function () { - const res = await getVideosList(server.url) - - expect(res.body.total) - .to - .equal(1) - - const video = res.body.data[ 0 ] - expect(video.accountName) - .to - .equal('root') - }) - - it('Should register a new user', async function () { - await registerUser(server.url, 'user_15', 'my super password') - }) - - it('Should be able to login with this registered user', async function () { - server.user = { - username: 'user_15', - password: 'my super password' - } - - accessToken = await loginAndGetAccessToken(server) - }) - - it('Should have the correct video quota', async function () { - const res = await getMyUserInformation(server.url, accessToken) - const user = res.body - - expect(user.videoQuota) - .to - .equal(5 * 1024 * 1024) - }) - - after(async function () { - killallServers([ server ]) - - // Keep the logs if the test failed - if (this[ 'ok' ]) { - await flushTests() - } - }) -}) diff --git a/server/tests/api/users/users.ts b/server/tests/api/users/users.ts new file mode 100644 index 000000000..2e3a0b94f --- /dev/null +++ b/server/tests/api/users/users.ts @@ -0,0 +1,534 @@ +/* tslint:disable:no-unused-expression */ + +import * as chai from 'chai' +import 'mocha' +import { UserRole } from '../../../../shared/index' +import { + createUser, + flushTests, + getBlacklistedVideosList, + getMyUserInformation, + getUserInformation, + getUsersList, + getUsersListPaginationAndSort, + getUserVideoRating, + getVideosList, + killallServers, + login, + loginAndGetAccessToken, + makePutBodyRequest, + rateVideo, + registerUser, + removeUser, + removeVideo, + runServer, + ServerInfo, + updateMyUser, + updateUser, + uploadVideo +} from '../../utils/index' +import { follow } from '../../utils/server/follows' +import { getMyVideos } from '../../utils/videos/videos' +import { setAccessTokensToServers } from '../../utils/users/login' + +const expect = chai.expect + +describe('Test users', function () { + let server: ServerInfo + let accessToken: string + let accessTokenUser: string + let videoId: number + let userId: number + + before(async function () { + this.timeout(10000) + + await flushTests() + server = await runServer(1) + + await setAccessTokensToServers([ server ]) + }) + + it('Should create a new client') + + it('Should return the first client') + + it('Should remove the last client') + + it('Should not login with an invalid client id', async function () { + const client = { id: 'client', secret: server.client.secret } + const res = await login(server.url, client, server.user, 400) + + expect(res.body.error) + .to + .equal('invalid_client') + }) + + it('Should not login with an invalid client secret', async function () { + const client = { id: server.client.id, secret: 'coucou' } + const res = await login(server.url, client, server.user, 400) + + expect(res.body.error) + .to + .equal('invalid_client') + }) + + it('Should not login with an invalid username', async function () { + const user = { username: 'captain crochet', password: server.user.password } + const res = await login(server.url, server.client, user, 400) + + expect(res.body.error) + .to + .equal('invalid_grant') + }) + + it('Should not login with an invalid password', async function () { + const user = { username: server.user.username, password: 'mew_three' } + const res = await login(server.url, server.client, user, 400) + + expect(res.body.error) + .to + .equal('invalid_grant') + }) + + it('Should not be able to upload a video', async function () { + accessToken = 'my_super_token' + + const videoAttributes = {} + await uploadVideo(server.url, accessToken, videoAttributes, 401) + }) + + it('Should not be able to follow', async function () { + accessToken = 'my_super_token' + await follow(server.url, [ 'http://example.com' ], accessToken, 401) + }) + + it('Should not be able to unfollow') + + it('Should be able to login', async function () { + const res = await login(server.url, server.client, server.user, 200) + + accessToken = res.body.access_token + }) + + it('Should upload the video with the correct token', async function () { + const videoAttributes = {} + await uploadVideo(server.url, accessToken, videoAttributes) + const res = await getVideosList(server.url) + const video = res.body.data[ 0 ] + + expect(video.accountName) + .to + .equal('root') + videoId = video.id + }) + + it('Should upload the video again with the correct token', async function () { + const videoAttributes = {} + await uploadVideo(server.url, accessToken, videoAttributes) + }) + + it('Should retrieve a video rating', async function () { + await rateVideo(server.url, accessToken, videoId, 'like') + const res = await getUserVideoRating(server.url, accessToken, videoId) + const rating = res.body + + expect(rating.videoId) + .to + .equal(videoId) + expect(rating.rating) + .to + .equal('like') + }) + + it('Should not be able to remove the video with an incorrect token', async function () { + await removeVideo(server.url, 'bad_token', videoId, 401) + }) + + it('Should not be able to remove the video with the token of another account') + + it('Should be able to remove the video with the correct token', async function () { + await removeVideo(server.url, accessToken, videoId) + }) + + it('Should logout (revoke token)') + + it('Should not be able to get the user information') + + it('Should not be able to upload a video') + + it('Should not be able to remove a video') + + it('Should not be able to rate a video', async function () { + const path = '/api/v1/videos/' + const data = { + rating: 'likes' + } + + const options = { + url: server.url, + path: path + videoId, + token: 'wrong token', + fields: data, + statusCodeExpected: 401 + } + await makePutBodyRequest(options) + }) + + it('Should be able to login again') + + it('Should have an expired access token') + + it('Should refresh the token') + + it('Should be able to upload a video again') + + it('Should be able to create a new user', async function () { + await createUser(server.url, accessToken, 'user_1', 'super password', 2 * 1024 * 1024) + }) + + it('Should be able to login with this user', async function () { + server.user = { + username: 'user_1', + password: 'super password' + } + + accessTokenUser = await loginAndGetAccessToken(server) + }) + + it('Should be able to get the user information', async function () { + const res = await getMyUserInformation(server.url, accessTokenUser) + const user = res.body + + expect(user.username) + .to + .equal('user_1') + expect(user.email) + .to + .equal('user_1@example.com') + expect(user.displayNSFW).to.be.false + expect(user.videoQuota) + .to + .equal(2 * 1024 * 1024) + expect(user.roleLabel) + .to + .equal('User') + expect(user.id) + .to + .be + .a('number') + }) + + it('Should be able to upload a video with this user', async function () { + this.timeout(5000) + + const videoAttributes = { + name: 'super user video' + } + await uploadVideo(server.url, accessTokenUser, videoAttributes) + }) + + it('Should be able to list my videos', async function () { + const res = await getMyVideos(server.url, accessTokenUser, 0, 5) + expect(res.body.total) + .to + .equal(1) + + const videos = res.body.data + expect(videos) + .to + .have + .lengthOf(1) + + expect(videos[ 0 ].name) + .to + .equal('super user video') + }) + + it('Should list all the users', async function () { + const res = await getUsersList(server.url, server.accessToken) + const result = res.body + const total = result.total + const users = result.data + + expect(total) + .to + .equal(2) + expect(users) + .to + .be + .an('array') + expect(users.length) + .to + .equal(2) + + const user = users[ 0 ] + expect(user.username) + .to + .equal('user_1') + expect(user.email) + .to + .equal('user_1@example.com') + expect(user.displayNSFW).to.be.false + + const rootUser = users[ 1 ] + expect(rootUser.username) + .to + .equal('root') + expect(rootUser.email) + .to + .equal('admin1@example.com') + expect(rootUser.displayNSFW).to.be.false + + userId = user.id + }) + + it('Should list only the first user by username asc', async function () { + const res = await getUsersListPaginationAndSort(server.url, server.accessToken, 0, 1, 'username') + + const result = res.body + const total = result.total + const users = result.data + + expect(total) + .to + .equal(2) + expect(users.length) + .to + .equal(1) + + const user = users[ 0 ] + expect(user.username) + .to + .equal('root') + expect(user.email) + .to + .equal('admin1@example.com') + expect(user.roleLabel) + .to + .equal('Administrator') + expect(user.displayNSFW).to.be.false + }) + + it('Should list only the first user by username desc', async function () { + const res = await getUsersListPaginationAndSort(server.url, server.accessToken, 0, 1, '-username') + const result = res.body + const total = result.total + const users = result.data + + expect(total) + .to + .equal(2) + expect(users.length) + .to + .equal(1) + + const user = users[ 0 ] + expect(user.username) + .to + .equal('user_1') + expect(user.email) + .to + .equal('user_1@example.com') + expect(user.displayNSFW).to.be.false + }) + + it('Should list only the second user by createdAt desc', async function () { + const res = await getUsersListPaginationAndSort(server.url, server.accessToken, 0, 1, '-createdAt') + const result = res.body + const total = result.total + const users = result.data + + expect(total) + .to + .equal(2) + expect(users.length) + .to + .equal(1) + + const user = users[ 0 ] + expect(user.username) + .to + .equal('user_1') + expect(user.email) + .to + .equal('user_1@example.com') + expect(user.displayNSFW).to.be.false + }) + + it('Should list all the users by createdAt asc', async function () { + const res = await getUsersListPaginationAndSort(server.url, server.accessToken, 0, 2, 'createdAt') + const result = res.body + const total = result.total + const users = result.data + + expect(total) + .to + .equal(2) + expect(users.length) + .to + .equal(2) + + expect(users[ 0 ].username) + .to + .equal('root') + expect(users[ 0 ].email) + .to + .equal('admin1@example.com') + expect(users[ 0 ].displayNSFW).to.be.false + + expect(users[ 1 ].username) + .to + .equal('user_1') + expect(users[ 1 ].email) + .to + .equal('user_1@example.com') + expect(users[ 1 ].displayNSFW).to.be.false + }) + + it('Should update my password', async function () { + await updateMyUser(server.url, accessTokenUser, 'new password') + server.user.password = 'new password' + + await login(server.url, server.client, server.user, 200) + }) + + it('Should be able to change the NSFW display attribute', async function () { + await updateMyUser(server.url, accessTokenUser, undefined, true) + + const res = await getMyUserInformation(server.url, accessTokenUser) + const user = res.body + + expect(user.username) + .to + .equal('user_1') + expect(user.email) + .to + .equal('user_1@example.com') + expect(user.displayNSFW).to.be.ok + expect(user.videoQuota) + .to + .equal(2 * 1024 * 1024) + expect(user.id) + .to + .be + .a('number') + }) + + it('Should be able to change the autoPlayVideo attribute', async function () { + await updateMyUser(server.url, accessTokenUser, undefined, undefined, undefined, false) + + const res = await getMyUserInformation(server.url, accessTokenUser) + const user = res.body + + expect(user.autoPlayVideo).to.be.false + }) + + it('Should be able to change the email display attribute', async function () { + await updateMyUser(server.url, accessTokenUser, undefined, undefined, 'updated@example.com') + + const res = await getMyUserInformation(server.url, accessTokenUser) + const user = res.body + + expect(user.username) + .to + .equal('user_1') + expect(user.email) + .to + .equal('updated@example.com') + expect(user.displayNSFW).to.be.ok + expect(user.videoQuota) + .to + .equal(2 * 1024 * 1024) + expect(user.id) + .to + .be + .a('number') + }) + + it('Should be able to update another user', async function () { + await updateUser(server.url, userId, accessToken, 'updated2@example.com', 42, UserRole.MODERATOR) + + const res = await getUserInformation(server.url, accessToken, userId) + const user = res.body + + expect(user.username) + .to + .equal('user_1') + expect(user.email) + .to + .equal('updated2@example.com') + expect(user.displayNSFW).to.be.ok + expect(user.videoQuota) + .to + .equal(42) + expect(user.roleLabel) + .to + .equal('Moderator') + expect(user.id) + .to + .be + .a('number') + }) + + it('Should not be able to delete a user by a moderator', async function () { + await removeUser(server.url, 2, accessTokenUser, 403) + }) + + it('Should be able to list video blacklist by a moderator', async function () { + await getBlacklistedVideosList(server.url, accessTokenUser) + }) + + it('Should be able to remove this user', async function () { + await removeUser(server.url, userId, accessToken) + }) + + it('Should not be able to login with this user', async function () { + // server.user is already set to user 1 + await login(server.url, server.client, server.user, 400) + }) + + it('Should not have videos of this user', async function () { + const res = await getVideosList(server.url) + + expect(res.body.total) + .to + .equal(1) + + const video = res.body.data[ 0 ] + expect(video.accountName) + .to + .equal('root') + }) + + it('Should register a new user', async function () { + await registerUser(server.url, 'user_15', 'my super password') + }) + + it('Should be able to login with this registered user', async function () { + server.user = { + username: 'user_15', + password: 'my super password' + } + + accessToken = await loginAndGetAccessToken(server) + }) + + it('Should have the correct video quota', async function () { + const res = await getMyUserInformation(server.url, accessToken) + const user = res.body + + expect(user.videoQuota) + .to + .equal(5 * 1024 * 1024) + }) + + after(async function () { + killallServers([ server ]) + + // Keep the logs if the test failed + if (this[ 'ok' ]) { + await flushTests() + } + }) +}) diff --git a/server/tests/api/video-abuse.ts b/server/tests/api/video-abuse.ts deleted file mode 100644 index 4a0b6b504..000000000 --- a/server/tests/api/video-abuse.ts +++ /dev/null @@ -1,145 +0,0 @@ -/* tslint:disable:no-unused-expression */ - -import * as chai from 'chai' -import 'mocha' -import { - flushAndRunMultipleServers, - flushTests, - getVideoAbusesList, - getVideosList, - killallServers, - reportVideoAbuse, - ServerInfo, - setAccessTokensToServers, - uploadVideo, - wait -} from '../utils' -import { doubleFollow } from '../utils/follows' - -const expect = chai.expect - -describe('Test video abuses', function () { - let servers: ServerInfo[] = [] - - before(async function () { - this.timeout(50000) - - // Run servers - servers = await flushAndRunMultipleServers(2) - - // Get the access tokens - await setAccessTokensToServers(servers) - - // Server 1 and server 2 follow each other - await doubleFollow(servers[0], servers[1]) - - // Upload some videos on each servers - const video1Attributes = { - name: 'my super name for server 1', - description: 'my super description for server 1' - } - await uploadVideo(servers[0].url, servers[0].accessToken, video1Attributes) - - const video2Attributes = { - name: 'my super name for server 2', - description: 'my super description for server 2' - } - await uploadVideo(servers[1].url, servers[1].accessToken, video2Attributes) - - // Wait videos propagation, server 2 has transcoding enabled - await wait(15000) - - const res = await getVideosList(servers[0].url) - const videos = res.body.data - - expect(videos.length).to.equal(2) - - servers[0].video = videos.find(video => video.name === 'my super name for server 1') - servers[1].video = videos.find(video => video.name === 'my super name for server 2') - }) - - it('Should not have video abuses', async function () { - const res = await getVideoAbusesList(servers[0].url, servers[0].accessToken) - - expect(res.body.total).to.equal(0) - expect(res.body.data).to.be.an('array') - expect(res.body.data.length).to.equal(0) - }) - - it('Should report abuse on a local video', async function () { - this.timeout(10000) - - const reason = 'my super bad reason' - await reportVideoAbuse(servers[0].url, servers[0].accessToken, servers[0].video.id, reason) - - // We wait requests propagation, even if the server 1 is not supposed to make a request to server 2 - await wait(5000) - }) - - it('Should have 1 video abuses on server 1 and 0 on server 2', async function () { - const res1 = await getVideoAbusesList(servers[0].url, servers[0].accessToken) - - expect(res1.body.total).to.equal(1) - expect(res1.body.data).to.be.an('array') - expect(res1.body.data.length).to.equal(1) - - const abuse = res1.body.data[0] - expect(abuse.reason).to.equal('my super bad reason') - expect(abuse.reporterUsername).to.equal('root') - expect(abuse.reporterServerHost).to.equal('localhost:9001') - expect(abuse.videoId).to.equal(servers[0].video.id) - - const res2 = await getVideoAbusesList(servers[1].url, servers[1].accessToken) - expect(res2.body.total).to.equal(0) - expect(res2.body.data).to.be.an('array') - expect(res2.body.data.length).to.equal(0) - }) - - it('Should report abuse on a remote video', async function () { - this.timeout(10000) - - const reason = 'my super bad reason 2' - await reportVideoAbuse(servers[0].url, servers[0].accessToken, servers[1].video.id, reason) - - // We wait requests propagation - await wait(5000) - }) - - it('Should have 2 video abuse on server 1 and 1 on server 2', async function () { - const res1 = await getVideoAbusesList(servers[0].url, servers[0].accessToken) - expect(res1.body.total).to.equal(2) - expect(res1.body.data).to.be.an('array') - expect(res1.body.data.length).to.equal(2) - - const abuse1 = res1.body.data[0] - expect(abuse1.reason).to.equal('my super bad reason') - expect(abuse1.reporterUsername).to.equal('root') - expect(abuse1.reporterServerHost).to.equal('localhost:9001') - expect(abuse1.videoId).to.equal(servers[0].video.id) - - const abuse2 = res1.body.data[1] - expect(abuse2.reason).to.equal('my super bad reason 2') - expect(abuse2.reporterUsername).to.equal('root') - expect(abuse2.reporterServerHost).to.equal('localhost:9001') - expect(abuse2.videoId).to.equal(servers[1].video.id) - - const res2 = await getVideoAbusesList(servers[1].url, servers[1].accessToken) - expect(res2.body.total).to.equal(1) - expect(res2.body.data).to.be.an('array') - expect(res2.body.data.length).to.equal(1) - - const abuse3 = res2.body.data[0] - expect(abuse3.reason).to.equal('my super bad reason 2') - expect(abuse3.reporterUsername).to.equal('root') - expect(abuse3.reporterServerHost).to.equal('localhost:9001') - }) - - after(async function () { - killallServers(servers) - - // Keep the logs if the test failed - if (this['ok']) { - await flushTests() - } - }) -}) diff --git a/server/tests/api/video-blacklist-management.ts b/server/tests/api/video-blacklist-management.ts deleted file mode 100644 index 0c636e094..000000000 --- a/server/tests/api/video-blacklist-management.ts +++ /dev/null @@ -1,162 +0,0 @@ -/* tslint:disable:no-unused-expressions */ - -import * as chai from 'chai' -import * as lodash from 'lodash' -import 'mocha' -import { - addVideoToBlacklist, - flushAndRunMultipleServers, - flushTests, - getBlacklistedVideosList, - getSortedBlacklistedVideosList, - getVideosList, - killallServers, - removeVideoFromBlacklist, - ServerInfo, - setAccessTokensToServers, - uploadVideo, - wait -} from '../utils' -import { doubleFollow } from '../utils/follows' - -const expect = chai.expect -const orderBy = lodash.orderBy - -describe('Test video blacklist management', function () { - let servers: ServerInfo[] = [] - - async function blacklistVideosOnServer (server: ServerInfo) { - const res = await getVideosList(server.url) - - const videos = res.body.data - for (let video of videos) { - await addVideoToBlacklist(server.url, server.accessToken, video.id) - } - } - - before(async function () { - this.timeout(50000) - - // Run servers - servers = await flushAndRunMultipleServers(2) - - // Get the access tokens - await setAccessTokensToServers(servers) - - // Server 1 and server 2 follow each other - await doubleFollow(servers[0], servers[1]) - - // Upload 2 videos on server 2 - await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'My 1st video', description: 'A video on server 2' }) - await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'My 2nd video', description: 'A video on server 2' }) - - // Wait videos propagation, server 2 has transcoding enabled - await wait(15000) - - // Blacklist the two videos on server 1 - await blacklistVideosOnServer(servers[0]) - }) - - describe('When listing blacklisted videos', function () { - it('Should display all the blacklisted videos', async function () { - const res = await getBlacklistedVideosList(servers[0].url, servers[0].accessToken) - - expect(res.body.total).to.equal(2) - - const videos = res.body.data - expect(videos).to.be.an('array') - expect(videos.length).to.equal(2) - }) - - it('Should get the correct sort when sorting by descending id', async function () { - const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-id') - expect(res.body.total).to.equal(2) - - const videos = res.body.data - expect(videos).to.be.an('array') - expect(videos.length).to.equal(2) - - const result = orderBy(res.body.data, [ 'id' ], [ 'desc' ]) - - expect(videos).to.deep.equal(result) - }) - - it('Should get the correct sort when sorting by descending video name', async function () { - const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name') - expect(res.body.total).to.equal(2) - - const videos = res.body.data - expect(videos).to.be.an('array') - expect(videos.length).to.equal(2) - - const result = orderBy(res.body.data, [ 'name' ], [ 'desc' ]) - - expect(videos).to.deep.equal(result) - }) - - it('Should get the correct sort when sorting by ascending creation date', async function () { - const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, 'createdAt') - expect(res.body.total).to.equal(2) - - const videos = res.body.data - expect(videos).to.be.an('array') - expect(videos.length).to.equal(2) - - const result = orderBy(res.body.data, [ 'createdAt' ]) - - expect(videos).to.deep.equal(result) - }) - }) - - describe('When removing a blacklisted video', function () { - let videoToRemove - let blacklist = [] - - it('Should not have any video in videos list on server 1', async function () { - const res = await getVideosList(servers[0].url) - expect(res.body.total).to.equal(0) - expect(res.body.data).to.be.an('array') - expect(res.body.data.length).to.equal(0) - }) - - it('Should remove a video from the blacklist on server 1', async function () { - // Get one video in the blacklist - const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name') - videoToRemove = res.body.data[0] - blacklist = res.body.data.slice(1) - - // Remove it - await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, videoToRemove.videoId) - }) - - it('Should have the ex-blacklisted video in videos list on server 1', async function () { - const res = await getVideosList(servers[0].url) - expect(res.body.total).to.equal(1) - - const videos = res.body.data - expect(videos).to.be.an('array') - expect(videos.length).to.equal(1) - - expect(videos[0].name).to.equal(videoToRemove.name) - expect(videos[0].id).to.equal(videoToRemove.videoId) - }) - - it('Should not have the ex-blacklisted video in videos blacklist list on server 1', async function () { - const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name') - expect(res.body.total).to.equal(1) - - const videos = res.body.data - expect(videos).to.be.an('array') - expect(videos.length).to.equal(1) - expect(videos).to.deep.equal(blacklist) - }) - }) - - after(async function () { - killallServers(servers) - - if (this['ok']) { - await flushTests() - } - }) -}) diff --git a/server/tests/api/video-blacklist.ts b/server/tests/api/video-blacklist.ts deleted file mode 100644 index 3afd8c510..000000000 --- a/server/tests/api/video-blacklist.ts +++ /dev/null @@ -1,98 +0,0 @@ -/* tslint:disable:no-unused-expression */ - -import * as chai from 'chai' -import 'mocha' -import { - addVideoToBlacklist, - flushAndRunMultipleServers, - flushTests, - getVideosList, - killallServers, - searchVideo, - ServerInfo, - setAccessTokensToServers, - uploadVideo, - wait -} from '../utils' -import { doubleFollow } from '../utils/follows' - -const expect = chai.expect - -describe('Test video blacklists', function () { - let servers: ServerInfo[] = [] - - before(async function () { - this.timeout(50000) - - // Run servers - servers = await flushAndRunMultipleServers(2) - - // Get the access tokens - await setAccessTokensToServers(servers) - - // Server 1 and server 2 follow each other - await doubleFollow(servers[0], servers[1]) - - // Upload a video on server 2 - const videoAttributes = { - name: 'my super name for server 2', - description: 'my super description for server 2' - } - await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes) - - // Wait videos propagation, server 2 has transcoding enabled - await wait(10000) - - const res = await getVideosList(servers[0].url) - const videos = res.body.data - - expect(videos.length).to.equal(1) - - servers[0].remoteVideo = videos.find(video => video.name === 'my super name for server 2') - }) - - it('Should blacklist a remote video on server 1', async function () { - await addVideoToBlacklist(servers[0].url, servers[0].accessToken, servers[0].remoteVideo.id) - }) - - it('Should not have the video blacklisted in videos list on server 1', async function () { - const res = await getVideosList(servers[0].url) - - expect(res.body.total).to.equal(0) - expect(res.body.data).to.be.an('array') - expect(res.body.data.length).to.equal(0) - }) - - it('Should not have the video blacklisted in videos search on server 1', async function () { - const res = await searchVideo(servers[0].url, 'name') - - expect(res.body.total).to.equal(0) - expect(res.body.data).to.be.an('array') - expect(res.body.data.length).to.equal(0) - }) - - it('Should have the blacklisted video in videos list on server 2', async function () { - const res = await getVideosList(servers[1].url) - - expect(res.body.total).to.equal(1) - expect(res.body.data).to.be.an('array') - expect(res.body.data.length).to.equal(1) - }) - - it('Should have the video blacklisted in videos search on server 2', async function () { - const res = await searchVideo(servers[1].url, 'name') - - expect(res.body.total).to.equal(1) - expect(res.body.data).to.be.an('array') - expect(res.body.data.length).to.equal(1) - }) - - after(async function () { - killallServers(servers) - - // Keep the logs if the test failed - if (this['ok']) { - await flushTests() - } - }) -}) diff --git a/server/tests/api/video-channels.ts b/server/tests/api/video-channels.ts deleted file mode 100644 index 2d8efb320..000000000 --- a/server/tests/api/video-channels.ts +++ /dev/null @@ -1,139 +0,0 @@ -/* tslint:disable:no-unused-expression */ - -import 'mocha' -import * as chai from 'chai' -const expect = chai.expect - -import { - ServerInfo, - flushTests, - runServer, - setAccessTokensToServers, - killallServers, - getMyUserInformation, - getVideoChannelsList, - addVideoChannel, - getAccountVideoChannelsList, - updateVideoChannel, - deleteVideoChannel, - getVideoChannel -} from '../utils' -import { User } from '../../../shared' - -describe('Test a video channels', function () { - let server: ServerInfo - let userInfo: User - let videoChannelId: number - - before(async function () { - this.timeout(10000) - - await flushTests() - - server = await runServer(1) - - await setAccessTokensToServers([ server ]) - }) - - it('Should have one video channel (created with root)', async () => { - const res = await getVideoChannelsList(server.url, 0, 2) - - expect(res.body.total).to.equal(1) - expect(res.body.data).to.be.an('array') - expect(res.body.data).to.have.lengthOf(1) - }) - - it('Should create another video channel', async () => { - const videoChannel = { - name: 'second video channel', - description: 'super video channel description' - } - await addVideoChannel(server.url, server.accessToken, videoChannel) - }) - - it('Should have two video channels when getting my information', async () => { - const res = await getMyUserInformation(server.url, server.accessToken) - userInfo = res.body - - expect(userInfo.videoChannels).to.be.an('array') - expect(userInfo.videoChannels).to.have.lengthOf(2) - - const videoChannels = userInfo.videoChannels - expect(videoChannels[0].name).to.equal('Default root channel') - expect(videoChannels[1].name).to.equal('second video channel') - expect(videoChannels[1].description).to.equal('super video channel description') - }) - - it('Should have two video channels when getting account channels', async () => { - const res = await getAccountVideoChannelsList(server.url, userInfo.account.uuid) - - expect(res.body.total).to.equal(2) - expect(res.body.data).to.be.an('array') - expect(res.body.data).to.have.lengthOf(2) - - const videoChannels = res.body.data - expect(videoChannels[0].name).to.equal('Default root channel') - expect(videoChannels[1].name).to.equal('second video channel') - expect(videoChannels[1].description).to.equal('super video channel description') - - videoChannelId = videoChannels[1].id - }) - - it('Should list video channels', async () => { - const res = await getVideoChannelsList(server.url, 1, 1, '-name') - - expect(res.body.total).to.equal(2) - expect(res.body.data).to.be.an('array') - expect(res.body.data).to.have.lengthOf(1) - expect(res.body.data[0].name).to.equal('Default root channel') - }) - - it('Should update video channel', async () => { - const videoChannelAttributes = { - name: 'video channel updated', - description: 'video channel description updated' - } - - await updateVideoChannel(server.url, server.accessToken, videoChannelId, videoChannelAttributes) - }) - - it('Should have video channel updated', async () => { - const res = await getVideoChannelsList(server.url, 0, 1, '-name') - - expect(res.body.total).to.equal(2) - expect(res.body.data).to.be.an('array') - expect(res.body.data).to.have.lengthOf(1) - expect(res.body.data[0].name).to.equal('video channel updated') - expect(res.body.data[0].description).to.equal('video channel description updated') - }) - - it('Should get video channel', async () => { - const res = await getVideoChannel(server.url, videoChannelId) - - const videoChannel = res.body - expect(videoChannel.name).to.equal('video channel updated') - expect(videoChannel.description).to.equal('video channel description updated') - }) - - it('Should delete video channel', async () => { - await deleteVideoChannel(server.url, server.accessToken, videoChannelId) - }) - - it('Should have video channel deleted', async () => { - const res = await getVideoChannelsList(server.url, 0, 10) - - expect(res.body.total).to.equal(1) - expect(res.body.data).to.be.an('array') - expect(res.body.data).to.have.lengthOf(1) - expect(res.body.data[0].name).to.equal('Default root channel') - }) - - after(async function () { - killallServers([ server ]) - - // Keep the logs if the test failed - if (this['ok']) { - await flushTests() - } - }) -}) diff --git a/server/tests/api/video-comments.ts b/server/tests/api/video-comments.ts deleted file mode 100644 index f05ca5e81..000000000 --- a/server/tests/api/video-comments.ts +++ /dev/null @@ -1,151 +0,0 @@ -/* tslint:disable:no-unused-expression */ - -import * as chai from 'chai' -import 'mocha' -import { VideoComment, VideoCommentThreadTree } from '../../../shared/models/videos/video-comment.model' -import { dateIsValid, flushTests, killallServers, runServer, ServerInfo, setAccessTokensToServers, uploadVideo } from '../utils' -import { addVideoCommentReply, addVideoCommentThread, getVideoCommentThreads, getVideoThreadComments } from '../utils/video-comments' - -const expect = chai.expect - -describe('Test video comments', function () { - let server: ServerInfo - let videoId - let videoUUID - let threadId - - before(async function () { - this.timeout(10000) - - await flushTests() - - server = await runServer(1) - - await setAccessTokensToServers([ server ]) - - const res = await uploadVideo(server.url, server.accessToken, {}) - videoUUID = res.body.video.uuid - videoId = res.body.video.id - }) - - it('Should not have threads on this video', async function () { - const res = await getVideoCommentThreads(server.url, videoUUID, 0, 5) - - expect(res.body.total).to.equal(0) - expect(res.body.data).to.be.an('array') - expect(res.body.data).to.have.lengthOf(0) - }) - - it('Should create a thread in this video', async function () { - const text = 'my super first comment' - - const res = await addVideoCommentThread(server.url, server.accessToken, videoUUID, text) - const comment = res.body.comment - - expect(comment.inReplyToCommentId).to.be.null - expect(comment.text).equal('my super first comment') - expect(comment.videoId).to.equal(videoId) - expect(comment.id).to.equal(comment.threadId) - expect(comment.account.name).to.equal('root') - expect(comment.account.host).to.equal('localhost:9001') - expect(comment.totalReplies).to.equal(0) - expect(dateIsValid(comment.createdAt as string)).to.be.true - expect(dateIsValid(comment.updatedAt as string)).to.be.true - }) - - it('Should list threads of this video', async function () { - const res = await getVideoCommentThreads(server.url, videoUUID, 0, 5) - - expect(res.body.total).to.equal(1) - expect(res.body.data).to.be.an('array') - expect(res.body.data).to.have.lengthOf(1) - - const comment: VideoComment = res.body.data[0] - expect(comment.inReplyToCommentId).to.be.null - expect(comment.text).equal('my super first comment') - expect(comment.videoId).to.equal(videoId) - expect(comment.id).to.equal(comment.threadId) - expect(comment.account.name).to.equal('root') - expect(comment.account.host).to.equal('localhost:9001') - expect(comment.totalReplies).to.equal(0) - expect(dateIsValid(comment.createdAt as string)).to.be.true - expect(dateIsValid(comment.updatedAt as string)).to.be.true - - threadId = comment.threadId - }) - - it('Should get all the thread created', async function () { - const res = await getVideoThreadComments(server.url, videoUUID, threadId) - - const rootComment = res.body.comment - expect(rootComment.inReplyToCommentId).to.be.null - expect(rootComment.text).equal('my super first comment') - expect(rootComment.videoId).to.equal(videoId) - expect(dateIsValid(rootComment.createdAt as string)).to.be.true - expect(dateIsValid(rootComment.updatedAt as string)).to.be.true - }) - - it('Should create multiple replies in this thread', async function () { - const text1 = 'my super answer to thread 1' - const childCommentRes = await addVideoCommentReply(server.url, server.accessToken, videoId, threadId, text1) - const childCommentId = childCommentRes.body.comment.id - - const text2 = 'my super answer to answer of thread 1' - await addVideoCommentReply(server.url, server.accessToken, videoId, childCommentId, text2) - - const text3 = 'my second answer to thread 1' - await addVideoCommentReply(server.url, server.accessToken, videoId, threadId, text3) - }) - - it('Should get correctly the replies', async function () { - const res = await getVideoThreadComments(server.url, videoUUID, threadId) - - const tree: VideoCommentThreadTree = res.body - expect(tree.comment.text).equal('my super first comment') - expect(tree.children).to.have.lengthOf(2) - - const firstChild = tree.children[0] - expect(firstChild.comment.text).to.equal('my super answer to thread 1') - expect(firstChild.children).to.have.lengthOf(1) - - const childOfFirstChild = firstChild.children[0] - expect(childOfFirstChild.comment.text).to.equal('my super answer to answer of thread 1') - expect(childOfFirstChild.children).to.have.lengthOf(0) - - const secondChild = tree.children[1] - expect(secondChild.comment.text).to.equal('my second answer to thread 1') - expect(secondChild.children).to.have.lengthOf(0) - }) - - it('Should create other threads', async function () { - const text1 = 'super thread 2' - await addVideoCommentThread(server.url, server.accessToken, videoUUID, text1) - - const text2 = 'super thread 3' - await addVideoCommentThread(server.url, server.accessToken, videoUUID, text2) - }) - - it('Should list the threads', async function () { - const res = await getVideoCommentThreads(server.url, videoUUID, 0, 5, 'createdAt') - - expect(res.body.total).to.equal(3) - expect(res.body.data).to.be.an('array') - expect(res.body.data).to.have.lengthOf(3) - - expect(res.body.data[0].text).to.equal('my super first comment') - expect(res.body.data[0].totalReplies).to.equal(3) - expect(res.body.data[1].text).to.equal('super thread 2') - expect(res.body.data[1].totalReplies).to.equal(0) - expect(res.body.data[2].text).to.equal('super thread 3') - expect(res.body.data[2].totalReplies).to.equal(0) - }) - - after(async function () { - killallServers([ server ]) - - // Keep the logs if the test failed - if (this['ok']) { - await flushTests() - } - }) -}) diff --git a/server/tests/api/video-description.ts b/server/tests/api/video-description.ts deleted file mode 100644 index 7ad1c63ae..000000000 --- a/server/tests/api/video-description.ts +++ /dev/null @@ -1,111 +0,0 @@ -/* tslint:disable:no-unused-expression */ - -import * as chai from 'chai' -import 'mocha' -import { - flushAndRunMultipleServers, - flushTests, - getVideo, - getVideoDescription, - getVideosList, - killallServers, - ServerInfo, - setAccessTokensToServers, - updateVideo, - uploadVideo, - wait -} from '../utils' -import { doubleFollow } from '../utils/follows' - -const expect = chai.expect - -describe('Test video description', function () { - let servers: ServerInfo[] = [] - let videoUUID = '' - let videoId: number - let longDescription = 'my super description for server 1'.repeat(50) - - before(async function () { - this.timeout(40000) - - // Run servers - servers = await flushAndRunMultipleServers(2) - - // Get the access tokens - await setAccessTokensToServers(servers) - - // Server 1 and server 2 follow each other - await doubleFollow(servers[0], servers[1]) - }) - - it('Should upload video with long description', async function () { - this.timeout(10000) - - const attributes = { - description: longDescription - } - await uploadVideo(servers[0].url, servers[0].accessToken, attributes) - - await wait(5000) - - const res = await getVideosList(servers[0].url) - - videoId = res.body.data[0].id - videoUUID = res.body.data[0].uuid - }) - - it('Should have a truncated description on each server', async function () { - for (const server of servers) { - const res = await getVideo(server.url, videoUUID) - const video = res.body - - // 30 characters * 6 -> 240 characters - const truncatedDescription = 'my super description for server 1'.repeat(7) + - 'my super descrip...' - - expect(video.description).to.equal(truncatedDescription) - } - }) - - it('Should fetch long description on each server', async function () { - for (const server of servers) { - const res = await getVideo(server.url, videoUUID) - const video = res.body - - const res2 = await getVideoDescription(server.url, video.descriptionPath) - expect(res2.body.description).to.equal(longDescription) - } - }) - - it('Should update with a short description', async function () { - this.timeout(10000) - - const attributes = { - description: 'short description' - } - await updateVideo(servers[0].url, servers[0].accessToken, videoId, attributes) - - await wait(5000) - }) - - it('Should have a small description on each server', async function () { - for (const server of servers) { - const res = await getVideo(server.url, videoUUID) - const video = res.body - - expect(video.description).to.equal('short description') - - const res2 = await getVideoDescription(server.url, video.descriptionPath) - expect(res2.body.description).to.equal('short description') - } - }) - - after(async function () { - killallServers(servers) - - // Keep the logs if the test failed - if (this['ok']) { - await flushTests() - } - }) -}) diff --git a/server/tests/api/video-privacy.ts b/server/tests/api/video-privacy.ts deleted file mode 100644 index 26847efce..000000000 --- a/server/tests/api/video-privacy.ts +++ /dev/null @@ -1,159 +0,0 @@ -/* tslint:disable:no-unused-expression */ - -import * as chai from 'chai' -import 'mocha' -import { VideoPrivacy } from '../../../shared/models/videos/video-privacy.enum' -import { - flushAndRunMultipleServers, - flushTests, - getVideosList, - killallServers, - ServerInfo, - setAccessTokensToServers, - uploadVideo, - wait -} from '../utils' -import { doubleFollow } from '../utils/follows' -import { getUserAccessToken } from '../utils/login' -import { createUser } from '../utils/users' -import { getMyVideos, getVideo, getVideoWithToken, updateVideo } from '../utils/videos' - -const expect = chai.expect - -describe('Test video privacy', function () { - let servers: ServerInfo[] = [] - let privateVideoId - let privateVideoUUID - let unlistedVideoUUID - - before(async function () { - this.timeout(50000) - - // Run servers - servers = await flushAndRunMultipleServers(2) - - // Get the access tokens - await setAccessTokensToServers(servers) - - // Server 1 and server 2 follow each other - await doubleFollow(servers[0], servers[1]) - }) - - it('Should upload a private video on server 1', async function () { - this.timeout(10000) - - const attributes = { - privacy: VideoPrivacy.PRIVATE - } - await uploadVideo(servers[0].url, servers[0].accessToken, attributes) - - await wait(5000) - }) - - it('Should not have this private video on server 2', async function () { - const res = await getVideosList(servers[1].url) - - expect(res.body.total).to.equal(0) - expect(res.body.data).to.have.lengthOf(0) - }) - - it('Should list my (private) videos', async function () { - const res = await getMyVideos(servers[0].url, servers[0].accessToken, 0, 1) - - expect(res.body.total).to.equal(1) - expect(res.body.data).to.have.lengthOf(1) - - privateVideoId = res.body.data[0].id - privateVideoUUID = res.body.data[0].uuid - }) - - it('Should not be able to watch this video with non authenticated user', async function () { - await getVideo(servers[0].url, privateVideoUUID, 401) - }) - - it('Should not be able to watch this private video with another user', async function () { - const user = { - username: 'hello', - password: 'super password' - } - await createUser(servers[0].url, servers[0].accessToken, user.username, user.password) - - const token = await getUserAccessToken(servers[0], user) - await getVideoWithToken(servers[0].url, token, privateVideoUUID, 403) - }) - - it('Should be able to watch this video with the correct user', async function () { - await getVideoWithToken(servers[0].url, servers[0].accessToken, privateVideoUUID) - }) - - it('Should upload an unlisted video on server 2', async function () { - this.timeout(30000) - - const attributes = { - name: 'unlisted video', - privacy: VideoPrivacy.UNLISTED - } - await uploadVideo(servers[1].url, servers[1].accessToken, attributes) - - // Server 2 has transcoding enabled - await wait(10000) - }) - - it('Should not have this unlisted video listed on server 1 and 2', async function () { - for (const server of servers) { - const res = await getVideosList(server.url) - - expect(res.body.total).to.equal(0) - expect(res.body.data).to.have.lengthOf(0) - } - }) - - it('Should list my (unlisted) videos', async function () { - const res = await getMyVideos(servers[1].url, servers[1].accessToken, 0, 1) - - expect(res.body.total).to.equal(1) - expect(res.body.data).to.have.lengthOf(1) - - unlistedVideoUUID = res.body.data[0].uuid - }) - - it('Should be able to get this unlisted video', async function () { - for (const server of servers) { - const res = await getVideo(server.url, unlistedVideoUUID) - - expect(res.body.name).to.equal('unlisted video') - } - }) - - it('Should update the private video to public on server 1', async function () { - this.timeout(10000) - - const attribute = { - name: 'super video public', - privacy: VideoPrivacy.PUBLIC - } - - await updateVideo(servers[0].url, servers[0].accessToken, privateVideoId, attribute) - - await wait(5000) - }) - - it('Should have this new public video listed on server 1 and 2', async function () { - for (const server of servers) { - const res = await getVideosList(server.url) - - expect(res.body.total).to.equal(1) - expect(res.body.data).to.have.lengthOf(1) - expect(res.body.data[0].name).to.equal('super video public') - } - }) - - after(async function () { - killallServers(servers) - - // Keep the logs if the test failed - if (this['ok']) { - await flushTests() - } - }) -}) diff --git a/server/tests/api/video-transcoder.ts b/server/tests/api/video-transcoder.ts deleted file mode 100644 index 9a6e91b76..000000000 --- a/server/tests/api/video-transcoder.ts +++ /dev/null @@ -1,97 +0,0 @@ -/* tslint:disable:no-unused-expression */ - -import 'mocha' -import * as chai from 'chai' -const expect = chai.expect - -import { - ServerInfo, - flushTests, - uploadVideo, - getVideosList, - wait, - setAccessTokensToServers, - flushAndRunMultipleServers, - killallServers, - webtorrentAdd, - getVideo -} from '../utils' - -describe('Test video transcoding', function () { - let servers: ServerInfo[] = [] - - before(async function () { - this.timeout(10000) - - // Run servers - servers = await flushAndRunMultipleServers(2) - - await setAccessTokensToServers(servers) - }) - - it('Should not transcode video on server 1', async function () { - this.timeout(60000) - - const videoAttributes = { - name: 'my super name for server 1', - description: 'my super description for server 1', - fixture: 'video_short.webm' - } - await uploadVideo(servers[0].url, servers[0].accessToken, videoAttributes) - - await wait(10000) - - const res = await getVideosList(servers[0].url) - const video = res.body.data[0] - - const res2 = await getVideo(servers[0].url, video.id) - const videoDetails = res2.body - expect(videoDetails.files).to.have.lengthOf(1) - - const magnetUri = videoDetails.files[0].magnetUri - expect(magnetUri).to.match(/\.webm/) - - const torrent = await webtorrentAdd(magnetUri) - expect(torrent.files).to.be.an('array') - expect(torrent.files.length).to.equal(1) - expect(torrent.files[0].path).match(/\.webm$/) - }) - - it('Should transcode video on server 2', async function () { - this.timeout(60000) - - const videoAttributes = { - name: 'my super name for server 2', - description: 'my super description for server 2', - fixture: 'video_short.webm' - } - await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes) - - await wait(20000) - - const res = await getVideosList(servers[1].url) - - const video = res.body.data[0] - const res2 = await getVideo(servers[1].url, video.id) - const videoDetails = res2.body - - expect(videoDetails.files).to.have.lengthOf(4) - - const magnetUri = videoDetails.files[0].magnetUri - expect(magnetUri).to.match(/\.mp4/) - - const torrent = await webtorrentAdd(magnetUri) - expect(torrent.files).to.be.an('array') - expect(torrent.files.length).to.equal(1) - expect(torrent.files[0].path).match(/\.mp4$/) - }) - - after(async function () { - killallServers(servers) - - // Keep the logs if the test failed - if (this['ok']) { - await flushTests() - } - }) -}) diff --git a/server/tests/api/videos/multiple-servers.ts b/server/tests/api/videos/multiple-servers.ts new file mode 100644 index 000000000..84f730a8e --- /dev/null +++ b/server/tests/api/videos/multiple-servers.ts @@ -0,0 +1,861 @@ +/* tslint:disable:no-unused-expression */ + +import * as chai from 'chai' +import 'mocha' +import { join } from 'path' +import * as request from 'supertest' +import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model' + +import { + addVideoChannel, dateIsValid, doubleFollow, flushAndRunMultipleServers, flushTests, getUserAccessToken, getVideo, + getVideoChannelsList, getVideosList, killallServers, rateVideo, removeVideo, ServerInfo, setAccessTokensToServers, testVideoImage, + updateVideo, uploadVideo, wait, webtorrentAdd +} from '../../utils/index' +import { createUser } from '../../utils/users/users' +import { + addVideoCommentReply, addVideoCommentThread, getVideoCommentThreads, + getVideoThreadComments +} from '../../utils/videos/video-comments' +import { viewVideo } from '../../utils/videos/videos' + +const expect = chai.expect + +describe('Test multiple servers', function () { + let servers: ServerInfo[] = [] + const toRemove = [] + let videoUUID = '' + let videoChannelId: number + + before(async function () { + this.timeout(120000) + + servers = await flushAndRunMultipleServers(3) + + // Get the access tokens + await setAccessTokensToServers(servers) + + const videoChannel = { + name: 'my channel', + description: 'super channel' + } + await addVideoChannel(servers[0].url, servers[0].accessToken, videoChannel) + const channelRes = await getVideoChannelsList(servers[0].url, 0, 1) + videoChannelId = channelRes.body.data[0].id + + // Server 1 and server 2 follow each other + await doubleFollow(servers[0], servers[1]) + // Server 1 and server 3 follow each other + await doubleFollow(servers[0], servers[2]) + // Server 2 and server 3 follow each other + await doubleFollow(servers[1], servers[2]) + }) + + it('Should not have videos for all servers', async function () { + for (const server of servers) { + const res = await getVideosList(server.url) + const videos = res.body.data + expect(videos).to.be.an('array') + expect(videos.length).to.equal(0) + } + }) + + describe('Should upload the video and propagate on each server', function () { + it('Should upload the video on server 1 and propagate on each server', async function () { + this.timeout(25000) + + const videoAttributes = { + name: 'my super name for server 1', + category: 5, + licence: 4, + language: 9, + nsfw: true, + description: 'my super description for server 1', + tags: [ 'tag1p1', 'tag2p1' ], + channelId: videoChannelId, + fixture: 'video_short1.webm' + } + await uploadVideo(servers[0].url, servers[0].accessToken, videoAttributes) + + await wait(10000) + + // All servers should have this video + for (const server of servers) { + let baseMagnet = null + + const res = await getVideosList(server.url) + + const videos = res.body.data + expect(videos).to.be.an('array') + expect(videos.length).to.equal(1) + const video = videos[0] + expect(video.name).to.equal('my super name for server 1') + expect(video.category).to.equal(5) + expect(video.categoryLabel).to.equal('Sports') + expect(video.licence).to.equal(4) + expect(video.licenceLabel).to.equal('Attribution - Non Commercial') + expect(video.language).to.equal(9) + expect(video.languageLabel).to.equal('Japanese') + expect(video.nsfw).to.be.ok + expect(video.description).to.equal('my super description for server 1') + expect(video.serverHost).to.equal('localhost:9001') + expect(video.duration).to.equal(10) + expect(dateIsValid(video.createdAt)).to.be.true + expect(dateIsValid(video.updatedAt)).to.be.true + expect(video.accountName).to.equal('root') + + const res2 = await getVideo(server.url, video.uuid) + const videoDetails = res2.body + + expect(videoDetails.channel.name).to.equal('my channel') + expect(videoDetails.channel.description).to.equal('super channel') + expect(videoDetails.account.name).to.equal('root') + expect(dateIsValid(videoDetails.channel.createdAt)).to.be.true + expect(dateIsValid(videoDetails.channel.updatedAt)).to.be.true + expect(videoDetails.files).to.have.lengthOf(1) + expect(videoDetails.tags).to.deep.equal([ 'tag1p1', 'tag2p1' ]) + + const file = videoDetails.files[0] + const magnetUri = file.magnetUri + expect(file.magnetUri).to.have.lengthOf.above(2) + expect(file.torrentUrl).to + .equal(`http://${videoDetails.serverHost}/static/torrents/${videoDetails.uuid}-${file.resolution}.torrent`) + expect(file.fileUrl).to.equal(`http://${videoDetails.serverHost}/static/webseed/${videoDetails.uuid}-${file.resolution}.webm`) + expect(file.resolution).to.equal(720) + expect(file.resolutionLabel).to.equal('720p') + expect(file.size).to.equal(572456) + + if (server.url !== 'http://localhost:9001') { + expect(video.isLocal).to.be.false + expect(videoDetails.channel.isLocal).to.be.false + } else { + expect(video.isLocal).to.be.true + expect(videoDetails.channel.isLocal).to.be.true + } + + // All servers should have the same magnet Uri + if (baseMagnet === null) { + baseMagnet = magnetUri + } else { + expect(baseMagnet).to.equal(magnetUri) + } + + const test = await testVideoImage(server.url, 'video_short1.webm', video.thumbnailPath) + expect(test).to.equal(true) + } + }) + + it('Should upload the video on server 2 and propagate on each server', async function () { + this.timeout(50000) + + const user = { + username: 'user1', + password: 'super_password' + } + await createUser(servers[1].url, servers[1].accessToken, user.username, user.password) + const userAccessToken = await getUserAccessToken(servers[1], user) + + const videoAttributes = { + name: 'my super name for server 2', + category: 4, + licence: 3, + language: 11, + nsfw: true, + description: 'my super description for server 2', + tags: [ 'tag1p2', 'tag2p2', 'tag3p2' ], + fixture: 'video_short2.webm' + } + await uploadVideo(servers[1].url, userAccessToken, videoAttributes) + + // Transcoding + await wait(30000) + + // All servers should have this video + for (const server of servers) { + let baseMagnet = {} + + const res = await getVideosList(server.url) + + const videos = res.body.data + expect(videos).to.be.an('array') + expect(videos.length).to.equal(2) + const video = videos[1] + expect(video.name).to.equal('my super name for server 2') + expect(video.category).to.equal(4) + expect(video.categoryLabel).to.equal('Art') + expect(video.licence).to.equal(3) + expect(video.licenceLabel).to.equal('Attribution - No Derivatives') + expect(video.language).to.equal(11) + expect(video.languageLabel).to.equal('German') + expect(video.nsfw).to.be.true + expect(video.description).to.equal('my super description for server 2') + expect(video.serverHost).to.equal('localhost:9002') + expect(video.duration).to.equal(5) + expect(dateIsValid(video.createdAt)).to.be.true + expect(dateIsValid(video.updatedAt)).to.be.true + expect(video.accountName).to.equal('user1') + + if (server.url !== 'http://localhost:9002') { + expect(video.isLocal).to.be.false + } else { + expect(video.isLocal).to.be.true + } + + const res2 = await getVideo(server.url, video.uuid) + const videoDetails = res2.body + + expect(videoDetails.channel.name).to.equal('Default user1 channel') + expect(dateIsValid(videoDetails.channel.createdAt)).to.be.true + expect(dateIsValid(videoDetails.channel.updatedAt)).to.be.true + expect(videoDetails.tags).to.deep.equal([ 'tag1p2', 'tag2p2', 'tag3p2' ]) + + expect(videoDetails.files).to.have.lengthOf(4) + + // Check common attributes + for (const file of videoDetails.files) { + expect(file.magnetUri).to.have.lengthOf.above(2) + + // All servers should have the same magnet Uri + if (baseMagnet[file.resolution] === undefined) { + baseMagnet[file.resolution] = file.magnet + } else { + expect(baseMagnet[file.resolution]).to.equal(file.magnet) + } + } + + const file240p = videoDetails.files.find(f => f.resolution === 240) + expect(file240p).not.to.be.undefined + expect(file240p.resolutionLabel).to.equal('240p') + expect(file240p.size).to.be.above(180000).and.below(200000) + + const file360p = videoDetails.files.find(f => f.resolution === 360) + expect(file360p).not.to.be.undefined + expect(file360p.resolutionLabel).to.equal('360p') + expect(file360p.size).to.be.above(270000).and.below(290000) + + const file480p = videoDetails.files.find(f => f.resolution === 480) + expect(file480p).not.to.be.undefined + expect(file480p.resolutionLabel).to.equal('480p') + expect(file480p.size).to.be.above(380000).and.below(400000) + + const file720p = videoDetails.files.find(f => f.resolution === 720) + expect(file720p).not.to.be.undefined + expect(file720p.resolutionLabel).to.equal('720p') + expect(file720p.size).to.be.above(700000).and.below(7200000) + + const test = await testVideoImage(server.url, 'video_short2.webm', videoDetails.thumbnailPath) + expect(test).to.equal(true) + } + }) + + it('Should upload two videos on server 3 and propagate on each server', async function () { + this.timeout(45000) + + const videoAttributes1 = { + name: 'my super name for server 3', + category: 6, + licence: 5, + language: 11, + nsfw: true, + description: 'my super description for server 3', + tags: [ 'tag1p3' ], + fixture: 'video_short3.webm' + } + await uploadVideo(servers[2].url, servers[2].accessToken, videoAttributes1) + + const videoAttributes2 = { + name: 'my super name for server 3-2', + category: 7, + licence: 6, + language: 12, + nsfw: false, + description: 'my super description for server 3-2', + tags: [ 'tag2p3', 'tag3p3', 'tag4p3' ], + fixture: 'video_short.webm' + } + await uploadVideo(servers[2].url, servers[2].accessToken, videoAttributes2) + + await wait(10000) + + let baseMagnet = null + // All servers should have this video + for (const server of servers) { + const res = await getVideosList(server.url) + + const videos = res.body.data + expect(videos).to.be.an('array') + expect(videos.length).to.equal(4) + + // We not sure about the order of the two last uploads + let video1 = null + let video2 = null + if (videos[2].name === 'my super name for server 3') { + video1 = videos[2] + video2 = videos[3] + } else { + video1 = videos[3] + video2 = videos[2] + } + + expect(video1.name).to.equal('my super name for server 3') + expect(video1.category).to.equal(6) + expect(video1.categoryLabel).to.equal('Travels') + expect(video1.licence).to.equal(5) + expect(video1.licenceLabel).to.equal('Attribution - Non Commercial - Share Alike') + expect(video1.language).to.equal(11) + expect(video1.languageLabel).to.equal('German') + expect(video1.nsfw).to.be.ok + expect(video1.description).to.equal('my super description for server 3') + expect(video1.serverHost).to.equal('localhost:9003') + expect(video1.duration).to.equal(5) + expect(video1.accountName).to.equal('root') + expect(dateIsValid(video1.createdAt)).to.be.true + expect(dateIsValid(video1.updatedAt)).to.be.true + + const res2 = await getVideo(server.url, video1.id) + const video1Details = res2.body + expect(video1Details.files).to.have.lengthOf(1) + expect(video1Details.tags).to.deep.equal([ 'tag1p3' ]) + + const file1 = video1Details.files[0] + expect(file1.magnetUri).to.have.lengthOf.above(2) + expect(file1.resolution).to.equal(720) + expect(file1.resolutionLabel).to.equal('720p') + expect(file1.size).to.equal(292677) + + expect(video2.name).to.equal('my super name for server 3-2') + expect(video2.category).to.equal(7) + expect(video2.categoryLabel).to.equal('Gaming') + expect(video2.licence).to.equal(6) + expect(video2.licenceLabel).to.equal('Attribution - Non Commercial - No Derivatives') + expect(video2.language).to.equal(12) + expect(video2.languageLabel).to.equal('Korean') + expect(video2.nsfw).to.be.false + expect(video2.description).to.equal('my super description for server 3-2') + expect(video2.serverHost).to.equal('localhost:9003') + expect(video2.duration).to.equal(5) + expect(video2.accountName).to.equal('root') + expect(dateIsValid(video2.createdAt)).to.be.true + expect(dateIsValid(video2.updatedAt)).to.be.true + + const res3 = await getVideo(server.url, video2.id) + const video2Details = res3.body + expect(video2Details.tags).to.deep.equal([ 'tag2p3', 'tag3p3', 'tag4p3' ]) + + expect(video2Details.files).to.have.lengthOf(1) + + const file2 = video2Details.files[0] + const magnetUri2 = file2.magnetUri + expect(file2.magnetUri).to.have.lengthOf.above(2) + expect(file2.resolution).to.equal(720) + expect(file2.resolutionLabel).to.equal('720p') + expect(file2.size).to.equal(218910) + + if (server.url !== 'http://localhost:9003') { + expect(video1.isLocal).to.be.false + expect(video2.isLocal).to.be.false + } else { + expect(video1.isLocal).to.be.true + expect(video2.isLocal).to.be.true + } + + // All servers should have the same magnet Uri + if (baseMagnet === null) { + baseMagnet = magnetUri2 + } else { + expect(baseMagnet).to.equal(magnetUri2) + } + + const test1 = await testVideoImage(server.url, 'video_short3.webm', video1.thumbnailPath) + expect(test1).to.equal(true) + + const test2 = await testVideoImage(server.url, 'video_short.webm', video2.thumbnailPath) + expect(test2).to.equal(true) + } + }) + }) + + describe('Should seed the uploaded video', function () { + it('Should add the file 1 by asking server 3', async function () { + this.timeout(10000) + + const res = await getVideosList(servers[2].url) + + const video = res.body.data[0] + toRemove.push(res.body.data[2]) + toRemove.push(res.body.data[3]) + + const res2 = await getVideo(servers[2].url, video.id) + const videoDetails = res2.body + + const torrent = await webtorrentAdd(videoDetails.files[0].magnetUri) + expect(torrent.files).to.be.an('array') + expect(torrent.files.length).to.equal(1) + expect(torrent.files[0].path).to.exist.and.to.not.equal('') + }) + + it('Should add the file 2 by asking server 1', async function () { + this.timeout(10000) + + const res = await getVideosList(servers[0].url) + + const video = res.body.data[1] + const res2 = await getVideo(servers[0].url, video.id) + const videoDetails = res2.body + + const torrent = await webtorrentAdd(videoDetails.files[0].magnetUri) + expect(torrent.files).to.be.an('array') + expect(torrent.files.length).to.equal(1) + expect(torrent.files[0].path).to.exist.and.to.not.equal('') + }) + + it('Should add the file 3 by asking server 2', async function () { + this.timeout(10000) + + const res = await getVideosList(servers[1].url) + + const video = res.body.data[2] + const res2 = await getVideo(servers[1].url, video.id) + const videoDetails = res2.body + + const torrent = await webtorrentAdd(videoDetails.files[0].magnetUri) + expect(torrent.files).to.be.an('array') + expect(torrent.files.length).to.equal(1) + expect(torrent.files[0].path).to.exist.and.to.not.equal('') + }) + + it('Should add the file 3-2 by asking server 1', async function () { + this.timeout(10000) + + const res = await getVideosList(servers[0].url) + + const video = res.body.data[3] + const res2 = await getVideo(servers[0].url, video.id) + const videoDetails = res2.body + + const torrent = await webtorrentAdd(videoDetails.files[0].magnetUri) + expect(torrent.files).to.be.an('array') + expect(torrent.files.length).to.equal(1) + expect(torrent.files[0].path).to.exist.and.to.not.equal('') + }) + + it('Should add the file 2 in 360p by asking server 1', async function () { + this.timeout(10000) + + const res = await getVideosList(servers[0].url) + + const video = res.body.data.find(v => v.name === 'my super name for server 2') + const res2 = await getVideo(servers[0].url, video.id) + const videoDetails = res2.body + + const file = videoDetails.files.find(f => f.resolution === 360) + expect(file).not.to.be.undefined + + const torrent = await webtorrentAdd(file.magnetUri) + expect(torrent.files).to.be.an('array') + expect(torrent.files.length).to.equal(1) + expect(torrent.files[0].path).to.exist.and.to.not.equal('') + }) + }) + + describe('Should update video views, likes and dislikes', function () { + let localVideosServer3 = [] + let remoteVideosServer1 = [] + let remoteVideosServer2 = [] + let remoteVideosServer3 = [] + + before(async function () { + const res1 = await getVideosList(servers[0].url) + remoteVideosServer1 = res1.body.data.filter(video => video.isLocal === false).map(video => video.uuid) + + const res2 = await getVideosList(servers[1].url) + remoteVideosServer2 = res2.body.data.filter(video => video.isLocal === false).map(video => video.uuid) + + const res3 = await getVideosList(servers[2].url) + localVideosServer3 = res3.body.data.filter(video => video.isLocal === true).map(video => video.uuid) + remoteVideosServer3 = res3.body.data.filter(video => video.isLocal === false).map(video => video.uuid) + }) + + it('Should view multiple videos on owned servers', async function () { + this.timeout(10000) + + const tasks: Promise[] = [] + tasks.push(viewVideo(servers[2].url, localVideosServer3[0])) + tasks.push(viewVideo(servers[2].url, localVideosServer3[0])) + tasks.push(viewVideo(servers[2].url, localVideosServer3[0])) + tasks.push(viewVideo(servers[2].url, localVideosServer3[1])) + + await Promise.all(tasks) + + await wait(5000) + + for (const server of servers) { + const res = await getVideosList(server.url) + + const videos = res.body.data + const video0 = videos.find(v => v.uuid === localVideosServer3[0]) + const video1 = videos.find(v => v.uuid === localVideosServer3[1]) + + expect(video0.views).to.equal(3) + expect(video1.views).to.equal(1) + } + }) + + it('Should view multiple videos on each servers', async function () { + this.timeout(15000) + + const tasks: Promise[] = [] + tasks.push(viewVideo(servers[0].url, remoteVideosServer1[0])) + tasks.push(viewVideo(servers[1].url, remoteVideosServer2[0])) + tasks.push(viewVideo(servers[1].url, remoteVideosServer2[0])) + tasks.push(viewVideo(servers[2].url, remoteVideosServer3[0])) + tasks.push(viewVideo(servers[2].url, remoteVideosServer3[1])) + tasks.push(viewVideo(servers[2].url, remoteVideosServer3[1])) + tasks.push(viewVideo(servers[2].url, remoteVideosServer3[1])) + tasks.push(viewVideo(servers[2].url, localVideosServer3[1])) + tasks.push(viewVideo(servers[2].url, localVideosServer3[1])) + tasks.push(viewVideo(servers[2].url, localVideosServer3[1])) + + await Promise.all(tasks) + + await wait(10000) + + let baseVideos = null + + for (const server of servers) { + const res = await getVideosList(server.url) + + const videos = res.body.data + + // Initialize base videos for future comparisons + if (baseVideos === null) { + baseVideos = videos + continue + } + + for (const baseVideo of baseVideos) { + const sameVideo = videos.find(video => video.name === baseVideo.name) + expect(baseVideo.views).to.equal(sameVideo.views) + } + } + }) + + it('Should like and dislikes videos on different services', async function () { + this.timeout(20000) + + const tasks: Promise[] = [] + tasks.push(rateVideo(servers[0].url, servers[0].accessToken, remoteVideosServer1[0], 'like')) + tasks.push(rateVideo(servers[0].url, servers[0].accessToken, remoteVideosServer1[0], 'dislike')) + tasks.push(rateVideo(servers[0].url, servers[0].accessToken, remoteVideosServer1[0], 'like')) + tasks.push(rateVideo(servers[2].url, servers[2].accessToken, localVideosServer3[1], 'like')) + tasks.push(rateVideo(servers[2].url, servers[2].accessToken, localVideosServer3[1], 'dislike')) + tasks.push(rateVideo(servers[2].url, servers[2].accessToken, remoteVideosServer3[1], 'dislike')) + tasks.push(rateVideo(servers[2].url, servers[2].accessToken, remoteVideosServer3[0], 'like')) + + await Promise.all(tasks) + + await wait(10000) + + let baseVideos = null + for (const server of servers) { + const res = await getVideosList(server.url) + + const videos = res.body.data + + // Initialize base videos for future comparisons + if (baseVideos === null) { + baseVideos = videos + continue + } + + for (const baseVideo of baseVideos) { + const sameVideo = videos.find(video => video.name === baseVideo.name) + expect(baseVideo.likes).to.equal(sameVideo.likes) + expect(baseVideo.dislikes).to.equal(sameVideo.dislikes) + } + } + }) + }) + + describe('Should manipulate these videos', function () { + it('Should update the video 3 by asking server 3', async function () { + this.timeout(10000) + + const attributes = { + name: 'my super video updated', + category: 10, + licence: 7, + language: 13, + nsfw: true, + description: 'my super description updated', + tags: [ 'tag_up_1', 'tag_up_2' ] + } + + await updateVideo(servers[2].url, servers[2].accessToken, toRemove[0].id, attributes) + + await wait(5000) + }) + + it('Should have the video 3 updated on each server', async function () { + this.timeout(10000) + + for (const server of servers) { + const res = await getVideosList(server.url) + + const videos = res.body.data + const videoUpdated = videos.find(video => video.name === 'my super video updated') + + expect(!!videoUpdated).to.be.true + expect(videoUpdated.category).to.equal(10) + expect(videoUpdated.categoryLabel).to.equal('Entertainment') + expect(videoUpdated.licence).to.equal(7) + expect(videoUpdated.licenceLabel).to.equal('Public Domain Dedication') + expect(videoUpdated.language).to.equal(13) + expect(videoUpdated.languageLabel).to.equal('French') + expect(videoUpdated.nsfw).to.be.ok + expect(videoUpdated.description).to.equal('my super description updated') + expect(dateIsValid(videoUpdated.updatedAt, 20000)).to.be.true + + const res2 = await getVideo(server.url, videoUpdated.uuid) + const videoUpdatedDetails = res2.body + expect(videoUpdatedDetails.tags).to.deep.equal([ 'tag_up_1', 'tag_up_2' ]) + + const file = videoUpdatedDetails.files[0] + expect(file.magnetUri).to.have.lengthOf.above(2) + expect(file.resolution).to.equal(720) + expect(file.resolutionLabel).to.equal('720p') + expect(file.size).to.equal(292677) + + const test = await testVideoImage(server.url, 'video_short3.webm', videoUpdated.thumbnailPath) + expect(test).to.equal(true) + + // Avoid "duplicate torrent" errors + const refreshWebTorrent = true + const torrent = await webtorrentAdd(videoUpdatedDetails .files[0].magnetUri, refreshWebTorrent) + expect(torrent.files).to.be.an('array') + expect(torrent.files.length).to.equal(1) + expect(torrent.files[0].path).to.exist.and.to.not.equal('') + } + }) + + it('Should remove the videos 3 and 3-2 by asking server 3', async function () { + this.timeout(10000) + + await removeVideo(servers[2].url, servers[2].accessToken, toRemove[0].id) + await removeVideo(servers[2].url, servers[2].accessToken, toRemove[1].id) + + await wait(5000) + }) + + it('Should have videos 1 and 3 on each server', async function () { + for (const server of servers) { + const res = await getVideosList(server.url) + + const videos = res.body.data + expect(videos).to.be.an('array') + expect(videos.length).to.equal(2) + expect(videos[0].name).not.to.equal(videos[1].name) + expect(videos[0].name).not.to.equal(toRemove[0].name) + expect(videos[1].name).not.to.equal(toRemove[0].name) + expect(videos[0].name).not.to.equal(toRemove[1].name) + expect(videos[1].name).not.to.equal(toRemove[1].name) + + videoUUID = videos.find(video => video.name === 'my super name for server 1').uuid + } + }) + + it('Should get the same video by UUID on each server', async function () { + let baseVideo = null + for (const server of servers) { + const res = await getVideo(server.url, videoUUID) + + const video = res.body + + if (baseVideo === null) { + baseVideo = video + continue + } + + expect(baseVideo.name).to.equal(video.name) + expect(baseVideo.uuid).to.equal(video.uuid) + expect(baseVideo.category).to.equal(video.category) + expect(baseVideo.language).to.equal(video.language) + expect(baseVideo.licence).to.equal(video.licence) + expect(baseVideo.category).to.equal(video.category) + expect(baseVideo.nsfw).to.equal(video.nsfw) + expect(baseVideo.accountName).to.equal(video.accountName) + expect(baseVideo.tags).to.deep.equal(video.tags) + } + }) + + it('Should get the preview from each server', async function () { + for (const server of servers) { + const res = await getVideo(server.url, videoUUID) + const video = res.body + + const test = await testVideoImage(server.url, 'video_short1-preview.webm', video.previewPath) + expect(test).to.equal(true) + } + }) + }) + + describe('Should comment these videos', function () { + it('Should add comment (threads and replies)', async function () { + this.timeout(25000) + + { + const text = 'my super first comment' + await addVideoCommentThread(servers[ 0 ].url, servers[ 0 ].accessToken, videoUUID, text) + } + + { + const text = 'my super second comment' + await addVideoCommentThread(servers[ 2 ].url, servers[ 2 ].accessToken, videoUUID, text) + } + + await wait(5000) + + { + const res = await getVideoCommentThreads(servers[1].url, videoUUID, 0, 5) + const threadId = res.body.data.find(c => c.text === 'my super first comment').id + + const text = 'my super answer to thread 1' + await addVideoCommentReply(servers[ 1 ].url, servers[ 1 ].accessToken, videoUUID, threadId, text) + } + + await wait(5000) + + { + const res1 = await getVideoCommentThreads(servers[2].url, videoUUID, 0, 5) + const threadId = res1.body.data.find(c => c.text === 'my super first comment').id + + const res2 = await getVideoThreadComments(servers[2].url, videoUUID, threadId) + const childCommentId = res2.body.children[0].comment.id + + const text3 = 'my second answer to thread 1' + await addVideoCommentReply(servers[ 2 ].url, servers[ 2 ].accessToken, videoUUID, threadId, text3) + + const text2 = 'my super answer to answer of thread 1' + await addVideoCommentReply(servers[ 2 ].url, servers[ 2 ].accessToken, videoUUID, childCommentId, text2) + } + + await wait(5000) + }) + + it('Should have these threads', async function () { + for (const server of servers) { + const res = await getVideoCommentThreads(server.url, videoUUID, 0, 5) + + expect(res.body.total).to.equal(2) + expect(res.body.data).to.be.an('array') + expect(res.body.data).to.have.lengthOf(2) + + { + const comment: VideoComment = res.body.data.find(c => c.text === 'my super first comment') + expect(comment).to.not.be.undefined + expect(comment.inReplyToCommentId).to.be.null + expect(comment.account.name).to.equal('root') + expect(comment.account.host).to.equal('localhost:9001') + expect(comment.totalReplies).to.equal(3) + expect(dateIsValid(comment.createdAt as string)).to.be.true + expect(dateIsValid(comment.updatedAt as string)).to.be.true + } + + { + const comment: VideoComment = res.body.data.find(c => c.text === 'my super second comment') + expect(comment).to.not.be.undefined + expect(comment.inReplyToCommentId).to.be.null + expect(comment.account.name).to.equal('root') + expect(comment.account.host).to.equal('localhost:9003') + expect(comment.totalReplies).to.equal(0) + expect(dateIsValid(comment.createdAt as string)).to.be.true + expect(dateIsValid(comment.updatedAt as string)).to.be.true + } + } + }) + + it('Should have these comments', async function () { + for (const server of servers) { + const res1 = await getVideoCommentThreads(server.url, videoUUID, 0, 5) + const threadId = res1.body.data.find(c => c.text === 'my super first comment').id + + const res2 = await getVideoThreadComments(server.url, videoUUID, threadId) + + const tree: VideoCommentThreadTree = res2.body + expect(tree.comment.text).equal('my super first comment') + expect(tree.comment.account.name).equal('root') + expect(tree.comment.account.host).equal('localhost:9001') + expect(tree.children).to.have.lengthOf(2) + + const firstChild = tree.children[0] + expect(firstChild.comment.text).to.equal('my super answer to thread 1') + expect(firstChild.comment.account.name).equal('root') + expect(firstChild.comment.account.host).equal('localhost:9002') + expect(firstChild.children).to.have.lengthOf(1) + + const childOfFirstChild = firstChild.children[0] + expect(childOfFirstChild.comment.text).to.equal('my super answer to answer of thread 1') + expect(childOfFirstChild.comment.account.name).equal('root') + expect(childOfFirstChild.comment.account.host).equal('localhost:9003') + expect(childOfFirstChild.children).to.have.lengthOf(0) + + const secondChild = tree.children[1] + expect(secondChild.comment.text).to.equal('my second answer to thread 1') + expect(secondChild.comment.account.name).equal('root') + expect(secondChild.comment.account.host).equal('localhost:9003') + expect(secondChild.children).to.have.lengthOf(0) + } + }) + }) + + describe('With minimum parameters', function () { + it('Should upload and propagate the video', async function () { + this.timeout(50000) + + const path = '/api/v1/videos/upload' + + const req = request(servers[1].url) + .post(path) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + servers[1].accessToken) + .field('name', 'minimum parameters') + .field('privacy', '1') + .field('nsfw', 'false') + .field('channelId', '1') + + const filePath = join(__dirname, '..', 'api', 'fixtures', 'video_short.webm') + + await req.attach('videofile', filePath) + .expect(200) + + await wait(25000) + + for (const server of servers) { + const res = await getVideosList(server.url) + const video = res.body.data.find(v => v.name === 'minimum parameters') + + expect(video.name).to.equal('minimum parameters') + expect(video.category).to.equal(null) + expect(video.categoryLabel).to.equal('Misc') + expect(video.licence).to.equal(null) + expect(video.licenceLabel).to.equal('Unknown') + expect(video.language).to.equal(null) + expect(video.languageLabel).to.equal('Unknown') + expect(video.nsfw).to.not.be.ok + expect(video.description).to.equal(null) + expect(video.serverHost).to.equal('localhost:9002') + expect(video.accountName).to.equal('root') + expect(dateIsValid(video.createdAt)).to.be.true + expect(dateIsValid(video.updatedAt)).to.be.true + } + }) + }) + + after(async function () { + killallServers(servers) + + // Keep the logs if the test failed + if (this['ok']) { + await flushTests() + } + }) +}) diff --git a/server/tests/api/videos/services.ts b/server/tests/api/videos/services.ts new file mode 100644 index 000000000..1cda464d9 --- /dev/null +++ b/server/tests/api/videos/services.ts @@ -0,0 +1,85 @@ +/* tslint:disable:no-unused-expression */ + +import 'mocha' +import * as chai from 'chai' +const expect = chai.expect + +import { + ServerInfo, + flushTests, + uploadVideo, + getVideosList, + setAccessTokensToServers, + killallServers, + getOEmbed +} from '../../utils/index' +import { runServer } from '../../utils/server/servers' + +describe('Test services', function () { + let server: ServerInfo = null + + before(async function () { + this.timeout(10000) + + await flushTests() + + server = await runServer(1) + + await setAccessTokensToServers([ server ]) + + const videoAttributes = { + name: 'my super name' + } + await uploadVideo(server.url, server.accessToken, videoAttributes) + + const res = await getVideosList(server.url) + server.video = res.body.data[0] + }) + + it('Should have a valid oEmbed response', async function () { + const oembedUrl = 'http://localhost:9001/videos/watch/' + server.video.uuid + + const res = await getOEmbed(server.url, oembedUrl) + const expectedHtml = `' + const expectedThumbnailUrl = 'http://localhost:9001/static/previews/' + server.video.uuid + '.jpg' + + expect(res.body.html).to.equal(expectedHtml) + expect(res.body.title).to.equal(server.video.name) + expect(res.body.author_name).to.equal(server.video.accountName) + expect(res.body.width).to.equal(560) + expect(res.body.height).to.equal(315) + expect(res.body.thumbnail_url).to.equal(expectedThumbnailUrl) + expect(res.body.thumbnail_width).to.equal(560) + expect(res.body.thumbnail_height).to.equal(315) + }) + + it('Should have a valid oEmbed response with small max height query', async function () { + const oembedUrl = 'http://localhost:9001/videos/watch/' + server.video.uuid + const format = 'json' + const maxHeight = 50 + const maxWidth = 50 + + const res = await getOEmbed(server.url, oembedUrl, format, maxHeight, maxWidth) + const expectedHtml = `' + + expect(res.body.html).to.equal(expectedHtml) + expect(res.body.title).to.equal(server.video.name) + expect(res.body.author_name).to.equal(server.video.accountName) + expect(res.body.height).to.equal(50) + expect(res.body.width).to.equal(50) + expect(res.body).to.not.have.property('thumbnail_url') + expect(res.body).to.not.have.property('thumbnail_width') + expect(res.body).to.not.have.property('thumbnail_height') + }) + + after(async function () { + killallServers([ server ]) + + // Keep the logs if the test failed + if (this['ok']) { + await flushTests() + } + }) +}) diff --git a/server/tests/api/videos/single-server.ts b/server/tests/api/videos/single-server.ts new file mode 100644 index 000000000..02723654d --- /dev/null +++ b/server/tests/api/videos/single-server.ts @@ -0,0 +1,701 @@ +/* tslint:disable:no-unused-expression */ + +import * as chai from 'chai' +import { keyBy } from 'lodash' +import 'mocha' +import { join } from 'path' +import { + dateIsValid, + flushTests, + getVideo, + getVideoCategories, + getVideoLanguages, + getVideoLicences, + getVideoPrivacies, + getVideosList, + getVideosListPagination, + getVideosListSort, + killallServers, + rateVideo, + readdirPromise, + removeVideo, + runServer, + searchVideo, + searchVideoWithPagination, + searchVideoWithSort, + ServerInfo, + setAccessTokensToServers, + testVideoImage, + updateVideo, + uploadVideo, + wait, + webtorrentAdd +} from '../../utils/index' +import { viewVideo } from '../../utils/videos/videos' + +const expect = chai.expect + +describe('Test a single server', function () { + let server: ServerInfo = null + let videoId = -1 + let videoUUID = '' + let videosListBase: any[] = null + + before(async function () { + this.timeout(10000) + + await flushTests() + + server = await runServer(1) + + await setAccessTokensToServers([ server ]) + }) + + it('Should list video categories', async function () { + const res = await getVideoCategories(server.url) + + const categories = res.body + expect(Object.keys(categories)).to.have.length.above(10) + + expect(categories[11]).to.equal('News') + }) + + it('Should list video licences', async function () { + const res = await getVideoLicences(server.url) + + const licences = res.body + expect(Object.keys(licences)).to.have.length.above(5) + + expect(licences[3]).to.equal('Attribution - No Derivatives') + }) + + it('Should list video languages', async function () { + const res = await getVideoLanguages(server.url) + + const languages = res.body + expect(Object.keys(languages)).to.have.length.above(5) + + expect(languages[3]).to.equal('Mandarin') + }) + + it('Should list video privacies', async function () { + const res = await getVideoPrivacies(server.url) + + const privacies = res.body + expect(Object.keys(privacies)).to.have.length.at.least(3) + + expect(privacies[3]).to.equal('Private') + }) + + it('Should not have videos', async function () { + const res = await getVideosList(server.url) + + expect(res.body.total).to.equal(0) + expect(res.body.data).to.be.an('array') + expect(res.body.data.length).to.equal(0) + }) + + it('Should upload the video', async function () { + const videoAttributes = { + name: 'my super name', + category: 2, + nsfw: true, + licence: 6, + tags: [ 'tag1', 'tag2', 'tag3' ] + } + const res = await uploadVideo(server.url, server.accessToken, videoAttributes) + expect(res.body.video).to.not.be.undefined + expect(res.body.video.id).to.equal(1) + expect(res.body.video.uuid).to.have.length.above(5) + }) + + it('Should seed the uploaded video', async function () { + // Yes, this could be long + this.timeout(60000) + + const res = await getVideosList(server.url) + + expect(res.body.total).to.equal(1) + expect(res.body.data).to.be.an('array') + expect(res.body.data.length).to.equal(1) + + const video = res.body.data[0] + expect(video.name).to.equal('my super name') + expect(video.category).to.equal(2) + expect(video.categoryLabel).to.equal('Films') + expect(video.licence).to.equal(6) + expect(video.licenceLabel).to.equal('Attribution - Non Commercial - No Derivatives') + expect(video.language).to.equal(3) + expect(video.languageLabel).to.equal('Mandarin') + expect(video.nsfw).to.be.ok + expect(video.description).to.equal('my super description') + expect(video.serverHost).to.equal('localhost:9001') + expect(video.accountName).to.equal('root') + expect(video.isLocal).to.be.true + expect(dateIsValid(video.createdAt)).to.be.true + expect(dateIsValid(video.updatedAt)).to.be.true + + const res2 = await getVideo(server.url, res.body.data[0].id) + const videoDetails = res2.body + + expect(videoDetails.files).to.have.lengthOf(1) + + const file = videoDetails.files[0] + const magnetUri = file.magnetUri + expect(file.magnetUri).to.have.lengthOf.above(2) + expect(file.torrentUrl).to.equal(`${server.url}/static/torrents/${videoDetails.uuid}-${file.resolution}.torrent`) + expect(file.fileUrl).to.equal(`${server.url}/static/webseed/${videoDetails.uuid}-${file.resolution}.webm`) + expect(file.resolution).to.equal(720) + expect(file.resolutionLabel).to.equal('720p') + expect(file.size).to.equal(218910) + + const test = await testVideoImage(server.url, 'video_short.webm', videoDetails.thumbnailPath) + expect(test).to.equal(true) + + videoId = videoDetails.id + videoUUID = videoDetails.uuid + + const torrent = await webtorrentAdd(magnetUri) + expect(torrent.files).to.be.an('array') + expect(torrent.files.length).to.equal(1) + expect(torrent.files[0].path).to.exist.and.to.not.equal('') + }) + + it('Should get the video', async function () { + // Yes, this could be long + this.timeout(60000) + + const res = await getVideo(server.url, videoId) + + const video = res.body + expect(video.name).to.equal('my super name') + expect(video.category).to.equal(2) + expect(video.categoryLabel).to.equal('Films') + expect(video.licence).to.equal(6) + expect(video.licenceLabel).to.equal('Attribution - Non Commercial - No Derivatives') + expect(video.language).to.equal(3) + expect(video.languageLabel).to.equal('Mandarin') + expect(video.nsfw).to.be.ok + expect(video.description).to.equal('my super description') + expect(video.serverHost).to.equal('localhost:9001') + expect(video.accountName).to.equal('root') + expect(video.isLocal).to.be.true + expect(dateIsValid(video.createdAt)).to.be.true + expect(dateIsValid(video.updatedAt)).to.be.true + expect(video.channel.name).to.equal('Default root channel') + expect(video.channel.isLocal).to.be.true + expect(dateIsValid(video.channel.createdAt)).to.be.true + expect(dateIsValid(video.channel.updatedAt)).to.be.true + + expect(video.files).to.have.lengthOf(1) + + const file = video.files[0] + expect(file.magnetUri).to.have.lengthOf.above(2) + expect(file.resolution).to.equal(720) + expect(file.resolutionLabel).to.equal('720p') + expect(file.size).to.equal(218910) + + const test = await testVideoImage(server.url, 'video_short.webm', video.thumbnailPath) + expect(test).to.equal(true) + + // Wait the async views increment + await wait(500) + }) + + it('Should get the video by UUID', async function () { + // Yes, this could be long + this.timeout(60000) + + const res = await getVideo(server.url, videoUUID) + + const video = res.body + expect(video.name).to.equal('my super name') + + // Wait the async views increment + await wait(500) + }) + + it('Should have the views updated', async function () { + await viewVideo(server.url, videoId) + await viewVideo(server.url, videoId) + await viewVideo(server.url, videoId) + + const res = await getVideo(server.url, videoId) + + const video = res.body + expect(video.views).to.equal(3) + }) + + it('Should search the video by name', async function () { + const res = await searchVideo(server.url, 'my') + + expect(res.body.total).to.equal(1) + expect(res.body.data).to.be.an('array') + expect(res.body.data.length).to.equal(1) + + const video = res.body.data[0] + expect(video.name).to.equal('my super name') + expect(video.category).to.equal(2) + expect(video.categoryLabel).to.equal('Films') + expect(video.licence).to.equal(6) + expect(video.licenceLabel).to.equal('Attribution - Non Commercial - No Derivatives') + expect(video.language).to.equal(3) + expect(video.languageLabel).to.equal('Mandarin') + expect(video.nsfw).to.be.ok + expect(video.description).to.equal('my super description') + expect(video.serverHost).to.equal('localhost:9001') + expect(video.accountName).to.equal('root') + expect(video.isLocal).to.be.true + expect(dateIsValid(video.createdAt)).to.be.true + expect(dateIsValid(video.updatedAt)).to.be.true + + const test = await testVideoImage(server.url, 'video_short.webm', video.thumbnailPath) + expect(test).to.equal(true) + }) + + // Not implemented yet + // it('Should search the video by serverHost', async function () { + // const res = await videosUtils.searchVideo(server.url, '9001', 'host') + + // expect(res.body.total).to.equal(1) + // expect(res.body.data).to.be.an('array') + // expect(res.body.data.length).to.equal(1) + + // const video = res.body.data[0] + // expect(video.name).to.equal('my super name') + // expect(video.description).to.equal('my super description') + // expect(video.serverHost).to.equal('localhost:9001') + // expect(video.author).to.equal('root') + // expect(video.isLocal).to.be.true + // expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) + // expect(dateIsValid(video.createdAt)).to.be.true + // expect(dateIsValid(video.updatedAt)).to.be.true + + // const test = await testVideoImage(server.url, 'video_short.webm', video.thumbnailPath) + // expect(test).to.equal(true) + + // done() + // }) + // }) + // }) + + // Not implemented yet + // it('Should search the video by tag', async function () { + // const res = await searchVideo(server.url, 'tag1') + // + // expect(res.body.total).to.equal(1) + // expect(res.body.data).to.be.an('array') + // expect(res.body.data.length).to.equal(1) + // + // const video = res.body.data[0] + // expect(video.name).to.equal('my super name') + // expect(video.category).to.equal(2) + // expect(video.categoryLabel).to.equal('Films') + // expect(video.licence).to.equal(6) + // expect(video.licenceLabel).to.equal('Attribution - Non Commercial - No Derivatives') + // expect(video.language).to.equal(3) + // expect(video.languageLabel).to.equal('Mandarin') + // expect(video.nsfw).to.be.ok + // expect(video.description).to.equal('my super description') + // expect(video.serverHost).to.equal('localhost:9001') + // expect(video.accountName).to.equal('root') + // expect(video.isLocal).to.be.true + // expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) + // expect(dateIsValid(video.createdAt)).to.be.true + // expect(dateIsValid(video.updatedAt)).to.be.true + // + // const test = await testVideoImage(server.url, 'video_short.webm', video.thumbnailPath) + // expect(test).to.equal(true) + // }) + + it('Should not find a search by name', async function () { + const res = await searchVideo(server.url, 'hello') + + expect(res.body.total).to.equal(0) + expect(res.body.data).to.be.an('array') + expect(res.body.data.length).to.equal(0) + }) + + // Not implemented yet + // it('Should not find a search by author', async function () { + // const res = await searchVideo(server.url, 'hello') + // + // expect(res.body.total).to.equal(0) + // expect(res.body.data).to.be.an('array') + // expect(res.body.data.length).to.equal(0) + // }) + // + // Not implemented yet + // it('Should not find a search by tag', async function () { + // const res = await searchVideo(server.url, 'hello') + // + // expect(res.body.total).to.equal(0) + // expect(res.body.data).to.be.an('array') + // expect(res.body.data.length).to.equal(0) + // }) + + it('Should remove the video', async function () { + await removeVideo(server.url, server.accessToken, videoId) + + const files1 = await readdirPromise(join(__dirname, '..', '..', '..', 'test1/videos/')) + expect(files1).to.have.lengthOf(0) + + const files2 = await readdirPromise(join(__dirname, '..', '..', '..', 'test1/thumbnails/')) + expect(files2).to.have.lengthOf(0) + }) + + it('Should not have videos', async function () { + const res = await getVideosList(server.url) + + expect(res.body.total).to.equal(0) + expect(res.body.data).to.be.an('array') + expect(res.body.data).to.have.lengthOf(0) + }) + + it('Should upload 6 videos', async function () { + this.timeout(25000) + + const videos = [ + 'video_short.mp4', 'video_short.ogv', 'video_short.webm', + 'video_short1.webm', 'video_short2.webm', 'video_short3.webm' + ] + + const tasks: Promise[] = [] + for (const video of videos) { + const videoAttributes = { + name: video + ' name', + description: video + ' description', + category: 2, + licence: 1, + language: 1, + nsfw: true, + tags: [ 'tag1', 'tag2', 'tag3' ], + fixture: video + } + + const p = uploadVideo(server.url, server.accessToken, videoAttributes) + tasks.push(p) + } + + await Promise.all(tasks) + }) + + it('Should have the correct durations', async function () { + const res = await getVideosList(server.url) + + expect(res.body.total).to.equal(6) + const videos = res.body.data + expect(videos).to.be.an('array') + expect(videos).to.have.lengthOf(6) + + const videosByName = keyBy<{ duration: number }>(videos, 'name') + expect(videosByName['video_short.mp4 name'].duration).to.equal(5) + expect(videosByName['video_short.ogv name'].duration).to.equal(5) + expect(videosByName['video_short.webm name'].duration).to.equal(5) + expect(videosByName['video_short1.webm name'].duration).to.equal(10) + expect(videosByName['video_short2.webm name'].duration).to.equal(5) + expect(videosByName['video_short3.webm name'].duration).to.equal(5) + }) + + it('Should have the correct thumbnails', async function () { + const res = await getVideosList(server.url) + + const videos = res.body.data + // For the next test + videosListBase = videos + + for (const video of videos) { + const videoName = video.name.replace(' name', '') + const test = await testVideoImage(server.url, videoName, video.thumbnailPath) + + expect(test).to.equal(true) + } + }) + + it('Should list only the two first videos', async function () { + const res = await getVideosListPagination(server.url, 0, 2, 'name') + + const videos = res.body.data + expect(res.body.total).to.equal(6) + expect(videos.length).to.equal(2) + expect(videos[0].name).to.equal(videosListBase[0].name) + expect(videos[1].name).to.equal(videosListBase[1].name) + }) + + it('Should list only the next three videos', async function () { + const res = await getVideosListPagination(server.url, 2, 3, 'name') + + const videos = res.body.data + expect(res.body.total).to.equal(6) + expect(videos.length).to.equal(3) + expect(videos[0].name).to.equal(videosListBase[2].name) + expect(videos[1].name).to.equal(videosListBase[3].name) + expect(videos[2].name).to.equal(videosListBase[4].name) + }) + + it('Should list the last video', async function () { + const res = await getVideosListPagination(server.url, 5, 6, 'name') + + const videos = res.body.data + expect(res.body.total).to.equal(6) + expect(videos.length).to.equal(1) + expect(videos[0].name).to.equal(videosListBase[5].name) + }) + + it('Should search the first video', async function () { + const res = await searchVideoWithPagination(server.url, 'webm', 0, 1, 'name') + + const videos = res.body.data + expect(res.body.total).to.equal(4) + expect(videos.length).to.equal(1) + expect(videos[0].name).to.equal('video_short1.webm name') + }) + + it('Should search the last two videos', async function () { + const res = await searchVideoWithPagination(server.url, 'webm', 2, 2, 'name') + + const videos = res.body.data + expect(res.body.total).to.equal(4) + expect(videos.length).to.equal(2) + expect(videos[0].name).to.equal('video_short3.webm name') + expect(videos[1].name).to.equal('video_short.webm name') + }) + + it('Should search all the webm videos', async function () { + const res = await searchVideoWithPagination(server.url, 'webm', 0, 15) + + const videos = res.body.data + expect(res.body.total).to.equal(4) + expect(videos.length).to.equal(4) + }) + + // Not implemented yet + // it('Should search all the root author videos', async function () { + // const res = await searchVideoWithPagination(server.url, 'root', 0, 15) + // + // const videos = res.body.data + // expect(res.body.total).to.equal(6) + // expect(videos.length).to.equal(6) + // }) + + // Not implemented yet + // it('Should search all the 9001 port videos', async function () { + // const res = await videosUtils.searchVideoWithPagination(server.url, '9001', 'host', 0, 15) + + // const videos = res.body.data + // expect(res.body.total).to.equal(6) + // expect(videos.length).to.equal(6) + + // done() + // }) + // }) + + // it('Should search all the localhost videos', async function () { + // const res = await videosUtils.searchVideoWithPagination(server.url, 'localhost', 'host', 0, 15) + + // const videos = res.body.data + // expect(res.body.total).to.equal(6) + // expect(videos.length).to.equal(6) + + // done() + // }) + // }) + + it('Should list and sort by name in descending order', async function () { + const res = await getVideosListSort(server.url, '-name') + + const videos = res.body.data + expect(res.body.total).to.equal(6) + expect(videos.length).to.equal(6) + expect(videos[0].name).to.equal('video_short.webm name') + expect(videos[1].name).to.equal('video_short.ogv name') + expect(videos[2].name).to.equal('video_short.mp4 name') + expect(videos[3].name).to.equal('video_short3.webm name') + expect(videos[4].name).to.equal('video_short2.webm name') + expect(videos[5].name).to.equal('video_short1.webm name') + }) + + it('Should search and sort by name in ascending order', async function () { + const res = await searchVideoWithSort(server.url, 'webm', 'name') + + const videos = res.body.data + expect(res.body.total).to.equal(4) + expect(videos.length).to.equal(4) + + expect(videos[0].name).to.equal('video_short1.webm name') + expect(videos[1].name).to.equal('video_short2.webm name') + expect(videos[2].name).to.equal('video_short3.webm name') + expect(videos[3].name).to.equal('video_short.webm name') + + videoId = videos[2].id + }) + + it('Should update a video', async function () { + const attributes = { + name: 'my super video updated', + category: 4, + licence: 2, + language: 5, + nsfw: false, + description: 'my super description updated', + tags: [ 'tagup1', 'tagup2' ] + } + await updateVideo(server.url, server.accessToken, videoId, attributes) + }) + + it('Should have the video updated', async function () { + this.timeout(60000) + + const res = await getVideo(server.url, videoId) + + const video = res.body + + expect(video.name).to.equal('my super video updated') + expect(video.category).to.equal(4) + expect(video.categoryLabel).to.equal('Art') + expect(video.licence).to.equal(2) + expect(video.licenceLabel).to.equal('Attribution - Share Alike') + expect(video.language).to.equal(5) + expect(video.languageLabel).to.equal('Arabic') + expect(video.nsfw).to.be.ok + expect(video.description).to.equal('my super description updated') + expect(video.serverHost).to.equal('localhost:9001') + expect(video.accountName).to.equal('root') + expect(video.account.name).to.equal('root') + expect(video.isLocal).to.be.true + expect(video.tags).to.deep.equal([ 'tagup1', 'tagup2' ]) + expect(dateIsValid(video.createdAt)).to.be.true + expect(dateIsValid(video.updatedAt)).to.be.true + + expect(video.channel.name).to.equal('Default root channel') + expect(video.channel.isLocal).to.be.true + expect(dateIsValid(video.channel.createdAt)).to.be.true + expect(dateIsValid(video.channel.updatedAt)).to.be.true + + expect(video.files).to.have.lengthOf(1) + + const file = video.files[0] + const magnetUri = file.magnetUri + expect(file.magnetUri).to.have.lengthOf.above(2) + expect(file.resolution).to.equal(720) + expect(file.resolutionLabel).to.equal('720p') + expect(file.size).to.equal(292677) + + const test = await testVideoImage(server.url, 'video_short3.webm', video.thumbnailPath) + expect(test).to.equal(true) + + const torrent = await webtorrentAdd(magnetUri) + expect(torrent.files).to.be.an('array') + expect(torrent.files.length).to.equal(1) + expect(torrent.files[0].path).to.exist.and.to.not.equal('') + }) + + it('Should update only the tags of a video', async function () { + const attributes = { + tags: [ 'tag1', 'tag2', 'supertag' ] + } + + await updateVideo(server.url, server.accessToken, videoId, attributes) + + const res = await getVideo(server.url, videoId) + const video = res.body + + expect(video.name).to.equal('my super video updated') + expect(video.category).to.equal(4) + expect(video.categoryLabel).to.equal('Art') + expect(video.licence).to.equal(2) + expect(video.licenceLabel).to.equal('Attribution - Share Alike') + expect(video.language).to.equal(5) + expect(video.languageLabel).to.equal('Arabic') + expect(video.nsfw).to.be.ok + expect(video.description).to.equal('my super description updated') + expect(video.serverHost).to.equal('localhost:9001') + expect(video.accountName).to.equal('root') + expect(video.isLocal).to.be.true + expect(video.tags).to.deep.equal([ 'supertag', 'tag1', 'tag2' ]) + expect(dateIsValid(video.createdAt)).to.be.true + expect(dateIsValid(video.updatedAt)).to.be.true + + expect(video.channel.name).to.equal('Default root channel') + expect(video.channel.isLocal).to.be.true + expect(dateIsValid(video.channel.createdAt)).to.be.true + expect(dateIsValid(video.channel.updatedAt)).to.be.true + + expect(video.files).to.have.lengthOf(1) + + const file = video.files[0] + expect(file.magnetUri).to.have.lengthOf.above(2) + expect(file.resolution).to.equal(720) + expect(file.resolutionLabel).to.equal('720p') + expect(file.size).to.equal(292677) + }) + + it('Should update only the description of a video', async function () { + const attributes = { + description: 'hello everybody' + } + + await updateVideo(server.url, server.accessToken, videoId, attributes) + + const res = await getVideo(server.url, videoId) + const video = res.body + + expect(video.name).to.equal('my super video updated') + expect(video.category).to.equal(4) + expect(video.categoryLabel).to.equal('Art') + expect(video.licence).to.equal(2) + expect(video.licenceLabel).to.equal('Attribution - Share Alike') + expect(video.language).to.equal(5) + expect(video.languageLabel).to.equal('Arabic') + expect(video.nsfw).to.be.ok + expect(video.description).to.equal('hello everybody') + expect(video.serverHost).to.equal('localhost:9001') + expect(video.accountName).to.equal('root') + expect(video.isLocal).to.be.true + expect(video.tags).to.deep.equal([ 'supertag', 'tag1', 'tag2' ]) + expect(dateIsValid(video.createdAt)).to.be.true + expect(dateIsValid(video.updatedAt)).to.be.true + + expect(video.channel.name).to.equal('Default root channel') + expect(video.channel.isLocal).to.be.true + expect(dateIsValid(video.channel.createdAt)).to.be.true + expect(dateIsValid(video.channel.updatedAt)).to.be.true + + expect(video.files).to.have.lengthOf(1) + + const file = video.files[0] + expect(file.magnetUri).to.have.lengthOf.above(2) + expect(file.resolution).to.equal(720) + expect(file.resolutionLabel).to.equal('720p') + expect(file.size).to.equal(292677) + }) + + it('Should like a video', async function () { + await rateVideo(server.url, server.accessToken, videoId, 'like') + + const res = await getVideo(server.url, videoId) + const video = res.body + + expect(video.likes).to.equal(1) + expect(video.dislikes).to.equal(0) + }) + + it('Should dislike the same video', async function () { + await rateVideo(server.url, server.accessToken, videoId, 'dislike') + + const res = await getVideo(server.url, videoId) + const video = res.body + + expect(video.likes).to.equal(0) + expect(video.dislikes).to.equal(1) + }) + + after(async function () { + killallServers([ server ]) + + // Keep the logs if the test failed + if (this['ok']) { + await flushTests() + } + }) +}) diff --git a/server/tests/api/videos/video-abuse.ts b/server/tests/api/videos/video-abuse.ts new file mode 100644 index 000000000..3fcf5d8c7 --- /dev/null +++ b/server/tests/api/videos/video-abuse.ts @@ -0,0 +1,145 @@ +/* tslint:disable:no-unused-expression */ + +import * as chai from 'chai' +import 'mocha' +import { + flushAndRunMultipleServers, + flushTests, + getVideoAbusesList, + getVideosList, + killallServers, + reportVideoAbuse, + ServerInfo, + setAccessTokensToServers, + uploadVideo, + wait +} from '../../utils/index' +import { doubleFollow } from '../../utils/server/follows' + +const expect = chai.expect + +describe('Test video abuses', function () { + let servers: ServerInfo[] = [] + + before(async function () { + this.timeout(50000) + + // Run servers + servers = await flushAndRunMultipleServers(2) + + // Get the access tokens + await setAccessTokensToServers(servers) + + // Server 1 and server 2 follow each other + await doubleFollow(servers[0], servers[1]) + + // Upload some videos on each servers + const video1Attributes = { + name: 'my super name for server 1', + description: 'my super description for server 1' + } + await uploadVideo(servers[0].url, servers[0].accessToken, video1Attributes) + + const video2Attributes = { + name: 'my super name for server 2', + description: 'my super description for server 2' + } + await uploadVideo(servers[1].url, servers[1].accessToken, video2Attributes) + + // Wait videos propagation, server 2 has transcoding enabled + await wait(15000) + + const res = await getVideosList(servers[0].url) + const videos = res.body.data + + expect(videos.length).to.equal(2) + + servers[0].video = videos.find(video => video.name === 'my super name for server 1') + servers[1].video = videos.find(video => video.name === 'my super name for server 2') + }) + + it('Should not have video abuses', async function () { + const res = await getVideoAbusesList(servers[0].url, servers[0].accessToken) + + expect(res.body.total).to.equal(0) + expect(res.body.data).to.be.an('array') + expect(res.body.data.length).to.equal(0) + }) + + it('Should report abuse on a local video', async function () { + this.timeout(10000) + + const reason = 'my super bad reason' + await reportVideoAbuse(servers[0].url, servers[0].accessToken, servers[0].video.id, reason) + + // We wait requests propagation, even if the server 1 is not supposed to make a request to server 2 + await wait(5000) + }) + + it('Should have 1 video abuses on server 1 and 0 on server 2', async function () { + const res1 = await getVideoAbusesList(servers[0].url, servers[0].accessToken) + + expect(res1.body.total).to.equal(1) + expect(res1.body.data).to.be.an('array') + expect(res1.body.data.length).to.equal(1) + + const abuse = res1.body.data[0] + expect(abuse.reason).to.equal('my super bad reason') + expect(abuse.reporterUsername).to.equal('root') + expect(abuse.reporterServerHost).to.equal('localhost:9001') + expect(abuse.videoId).to.equal(servers[0].video.id) + + const res2 = await getVideoAbusesList(servers[1].url, servers[1].accessToken) + expect(res2.body.total).to.equal(0) + expect(res2.body.data).to.be.an('array') + expect(res2.body.data.length).to.equal(0) + }) + + it('Should report abuse on a remote video', async function () { + this.timeout(10000) + + const reason = 'my super bad reason 2' + await reportVideoAbuse(servers[0].url, servers[0].accessToken, servers[1].video.id, reason) + + // We wait requests propagation + await wait(5000) + }) + + it('Should have 2 video abuse on server 1 and 1 on server 2', async function () { + const res1 = await getVideoAbusesList(servers[0].url, servers[0].accessToken) + expect(res1.body.total).to.equal(2) + expect(res1.body.data).to.be.an('array') + expect(res1.body.data.length).to.equal(2) + + const abuse1 = res1.body.data[0] + expect(abuse1.reason).to.equal('my super bad reason') + expect(abuse1.reporterUsername).to.equal('root') + expect(abuse1.reporterServerHost).to.equal('localhost:9001') + expect(abuse1.videoId).to.equal(servers[0].video.id) + + const abuse2 = res1.body.data[1] + expect(abuse2.reason).to.equal('my super bad reason 2') + expect(abuse2.reporterUsername).to.equal('root') + expect(abuse2.reporterServerHost).to.equal('localhost:9001') + expect(abuse2.videoId).to.equal(servers[1].video.id) + + const res2 = await getVideoAbusesList(servers[1].url, servers[1].accessToken) + expect(res2.body.total).to.equal(1) + expect(res2.body.data).to.be.an('array') + expect(res2.body.data.length).to.equal(1) + + const abuse3 = res2.body.data[0] + expect(abuse3.reason).to.equal('my super bad reason 2') + expect(abuse3.reporterUsername).to.equal('root') + expect(abuse3.reporterServerHost).to.equal('localhost:9001') + }) + + after(async function () { + killallServers(servers) + + // Keep the logs if the test failed + if (this['ok']) { + await flushTests() + } + }) +}) diff --git a/server/tests/api/videos/video-blacklist-management.ts b/server/tests/api/videos/video-blacklist-management.ts new file mode 100644 index 000000000..db79784c2 --- /dev/null +++ b/server/tests/api/videos/video-blacklist-management.ts @@ -0,0 +1,162 @@ +/* tslint:disable:no-unused-expressions */ + +import * as chai from 'chai' +import * as lodash from 'lodash' +import 'mocha' +import { + addVideoToBlacklist, + flushAndRunMultipleServers, + flushTests, + getBlacklistedVideosList, + getSortedBlacklistedVideosList, + getVideosList, + killallServers, + removeVideoFromBlacklist, + ServerInfo, + setAccessTokensToServers, + uploadVideo, + wait +} from '../../utils/index' +import { doubleFollow } from '../../utils/server/follows' + +const expect = chai.expect +const orderBy = lodash.orderBy + +describe('Test video blacklist management', function () { + let servers: ServerInfo[] = [] + + async function blacklistVideosOnServer (server: ServerInfo) { + const res = await getVideosList(server.url) + + const videos = res.body.data + for (let video of videos) { + await addVideoToBlacklist(server.url, server.accessToken, video.id) + } + } + + before(async function () { + this.timeout(50000) + + // Run servers + servers = await flushAndRunMultipleServers(2) + + // Get the access tokens + await setAccessTokensToServers(servers) + + // Server 1 and server 2 follow each other + await doubleFollow(servers[0], servers[1]) + + // Upload 2 videos on server 2 + await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'My 1st video', description: 'A video on server 2' }) + await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'My 2nd video', description: 'A video on server 2' }) + + // Wait videos propagation, server 2 has transcoding enabled + await wait(15000) + + // Blacklist the two videos on server 1 + await blacklistVideosOnServer(servers[0]) + }) + + describe('When listing blacklisted videos', function () { + it('Should display all the blacklisted videos', async function () { + const res = await getBlacklistedVideosList(servers[0].url, servers[0].accessToken) + + expect(res.body.total).to.equal(2) + + const videos = res.body.data + expect(videos).to.be.an('array') + expect(videos.length).to.equal(2) + }) + + it('Should get the correct sort when sorting by descending id', async function () { + const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-id') + expect(res.body.total).to.equal(2) + + const videos = res.body.data + expect(videos).to.be.an('array') + expect(videos.length).to.equal(2) + + const result = orderBy(res.body.data, [ 'id' ], [ 'desc' ]) + + expect(videos).to.deep.equal(result) + }) + + it('Should get the correct sort when sorting by descending video name', async function () { + const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name') + expect(res.body.total).to.equal(2) + + const videos = res.body.data + expect(videos).to.be.an('array') + expect(videos.length).to.equal(2) + + const result = orderBy(res.body.data, [ 'name' ], [ 'desc' ]) + + expect(videos).to.deep.equal(result) + }) + + it('Should get the correct sort when sorting by ascending creation date', async function () { + const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, 'createdAt') + expect(res.body.total).to.equal(2) + + const videos = res.body.data + expect(videos).to.be.an('array') + expect(videos.length).to.equal(2) + + const result = orderBy(res.body.data, [ 'createdAt' ]) + + expect(videos).to.deep.equal(result) + }) + }) + + describe('When removing a blacklisted video', function () { + let videoToRemove + let blacklist = [] + + it('Should not have any video in videos list on server 1', async function () { + const res = await getVideosList(servers[0].url) + expect(res.body.total).to.equal(0) + expect(res.body.data).to.be.an('array') + expect(res.body.data.length).to.equal(0) + }) + + it('Should remove a video from the blacklist on server 1', async function () { + // Get one video in the blacklist + const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name') + videoToRemove = res.body.data[0] + blacklist = res.body.data.slice(1) + + // Remove it + await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, videoToRemove.videoId) + }) + + it('Should have the ex-blacklisted video in videos list on server 1', async function () { + const res = await getVideosList(servers[0].url) + expect(res.body.total).to.equal(1) + + const videos = res.body.data + expect(videos).to.be.an('array') + expect(videos.length).to.equal(1) + + expect(videos[0].name).to.equal(videoToRemove.name) + expect(videos[0].id).to.equal(videoToRemove.videoId) + }) + + it('Should not have the ex-blacklisted video in videos blacklist list on server 1', async function () { + const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name') + expect(res.body.total).to.equal(1) + + const videos = res.body.data + expect(videos).to.be.an('array') + expect(videos.length).to.equal(1) + expect(videos).to.deep.equal(blacklist) + }) + }) + + after(async function () { + killallServers(servers) + + if (this['ok']) { + await flushTests() + } + }) +}) diff --git a/server/tests/api/videos/video-blacklist.ts b/server/tests/api/videos/video-blacklist.ts new file mode 100644 index 000000000..d1cefa5d7 --- /dev/null +++ b/server/tests/api/videos/video-blacklist.ts @@ -0,0 +1,98 @@ +/* tslint:disable:no-unused-expression */ + +import * as chai from 'chai' +import 'mocha' +import { + addVideoToBlacklist, + flushAndRunMultipleServers, + flushTests, + getVideosList, + killallServers, + searchVideo, + ServerInfo, + setAccessTokensToServers, + uploadVideo, + wait +} from '../../utils/index' +import { doubleFollow } from '../../utils/server/follows' + +const expect = chai.expect + +describe('Test video blacklists', function () { + let servers: ServerInfo[] = [] + + before(async function () { + this.timeout(50000) + + // Run servers + servers = await flushAndRunMultipleServers(2) + + // Get the access tokens + await setAccessTokensToServers(servers) + + // Server 1 and server 2 follow each other + await doubleFollow(servers[0], servers[1]) + + // Upload a video on server 2 + const videoAttributes = { + name: 'my super name for server 2', + description: 'my super description for server 2' + } + await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes) + + // Wait videos propagation, server 2 has transcoding enabled + await wait(10000) + + const res = await getVideosList(servers[0].url) + const videos = res.body.data + + expect(videos.length).to.equal(1) + + servers[0].remoteVideo = videos.find(video => video.name === 'my super name for server 2') + }) + + it('Should blacklist a remote video on server 1', async function () { + await addVideoToBlacklist(servers[0].url, servers[0].accessToken, servers[0].remoteVideo.id) + }) + + it('Should not have the video blacklisted in videos list on server 1', async function () { + const res = await getVideosList(servers[0].url) + + expect(res.body.total).to.equal(0) + expect(res.body.data).to.be.an('array') + expect(res.body.data.length).to.equal(0) + }) + + it('Should not have the video blacklisted in videos search on server 1', async function () { + const res = await searchVideo(servers[0].url, 'name') + + expect(res.body.total).to.equal(0) + expect(res.body.data).to.be.an('array') + expect(res.body.data.length).to.equal(0) + }) + + it('Should have the blacklisted video in videos list on server 2', async function () { + const res = await getVideosList(servers[1].url) + + expect(res.body.total).to.equal(1) + expect(res.body.data).to.be.an('array') + expect(res.body.data.length).to.equal(1) + }) + + it('Should have the video blacklisted in videos search on server 2', async function () { + const res = await searchVideo(servers[1].url, 'name') + + expect(res.body.total).to.equal(1) + expect(res.body.data).to.be.an('array') + expect(res.body.data.length).to.equal(1) + }) + + after(async function () { + killallServers(servers) + + // Keep the logs if the test failed + if (this['ok']) { + await flushTests() + } + }) +}) diff --git a/server/tests/api/videos/video-channels.ts b/server/tests/api/videos/video-channels.ts new file mode 100644 index 000000000..454a96da6 --- /dev/null +++ b/server/tests/api/videos/video-channels.ts @@ -0,0 +1,139 @@ +/* tslint:disable:no-unused-expression */ + +import 'mocha' +import * as chai from 'chai' +const expect = chai.expect + +import { + ServerInfo, + flushTests, + runServer, + setAccessTokensToServers, + killallServers, + getMyUserInformation, + getVideoChannelsList, + addVideoChannel, + getAccountVideoChannelsList, + updateVideoChannel, + deleteVideoChannel, + getVideoChannel +} from '../../utils/index' +import { User } from '../../../../shared/index' + +describe('Test a video channels', function () { + let server: ServerInfo + let userInfo: User + let videoChannelId: number + + before(async function () { + this.timeout(10000) + + await flushTests() + + server = await runServer(1) + + await setAccessTokensToServers([ server ]) + }) + + it('Should have one video channel (created with root)', async () => { + const res = await getVideoChannelsList(server.url, 0, 2) + + expect(res.body.total).to.equal(1) + expect(res.body.data).to.be.an('array') + expect(res.body.data).to.have.lengthOf(1) + }) + + it('Should create another video channel', async () => { + const videoChannel = { + name: 'second video channel', + description: 'super video channel description' + } + await addVideoChannel(server.url, server.accessToken, videoChannel) + }) + + it('Should have two video channels when getting my information', async () => { + const res = await getMyUserInformation(server.url, server.accessToken) + userInfo = res.body + + expect(userInfo.videoChannels).to.be.an('array') + expect(userInfo.videoChannels).to.have.lengthOf(2) + + const videoChannels = userInfo.videoChannels + expect(videoChannels[0].name).to.equal('Default root channel') + expect(videoChannels[1].name).to.equal('second video channel') + expect(videoChannels[1].description).to.equal('super video channel description') + }) + + it('Should have two video channels when getting account channels', async () => { + const res = await getAccountVideoChannelsList(server.url, userInfo.account.uuid) + + expect(res.body.total).to.equal(2) + expect(res.body.data).to.be.an('array') + expect(res.body.data).to.have.lengthOf(2) + + const videoChannels = res.body.data + expect(videoChannels[0].name).to.equal('Default root channel') + expect(videoChannels[1].name).to.equal('second video channel') + expect(videoChannels[1].description).to.equal('super video channel description') + + videoChannelId = videoChannels[1].id + }) + + it('Should list video channels', async () => { + const res = await getVideoChannelsList(server.url, 1, 1, '-name') + + expect(res.body.total).to.equal(2) + expect(res.body.data).to.be.an('array') + expect(res.body.data).to.have.lengthOf(1) + expect(res.body.data[0].name).to.equal('Default root channel') + }) + + it('Should update video channel', async () => { + const videoChannelAttributes = { + name: 'video channel updated', + description: 'video channel description updated' + } + + await updateVideoChannel(server.url, server.accessToken, videoChannelId, videoChannelAttributes) + }) + + it('Should have video channel updated', async () => { + const res = await getVideoChannelsList(server.url, 0, 1, '-name') + + expect(res.body.total).to.equal(2) + expect(res.body.data).to.be.an('array') + expect(res.body.data).to.have.lengthOf(1) + expect(res.body.data[0].name).to.equal('video channel updated') + expect(res.body.data[0].description).to.equal('video channel description updated') + }) + + it('Should get video channel', async () => { + const res = await getVideoChannel(server.url, videoChannelId) + + const videoChannel = res.body + expect(videoChannel.name).to.equal('video channel updated') + expect(videoChannel.description).to.equal('video channel description updated') + }) + + it('Should delete video channel', async () => { + await deleteVideoChannel(server.url, server.accessToken, videoChannelId) + }) + + it('Should have video channel deleted', async () => { + const res = await getVideoChannelsList(server.url, 0, 10) + + expect(res.body.total).to.equal(1) + expect(res.body.data).to.be.an('array') + expect(res.body.data).to.have.lengthOf(1) + expect(res.body.data[0].name).to.equal('Default root channel') + }) + + after(async function () { + killallServers([ server ]) + + // Keep the logs if the test failed + if (this['ok']) { + await flushTests() + } + }) +}) diff --git a/server/tests/api/videos/video-comments.ts b/server/tests/api/videos/video-comments.ts new file mode 100644 index 000000000..3b6578f04 --- /dev/null +++ b/server/tests/api/videos/video-comments.ts @@ -0,0 +1,154 @@ +/* tslint:disable:no-unused-expression */ + +import * as chai from 'chai' +import 'mocha' +import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model' +import { dateIsValid, flushTests, killallServers, runServer, ServerInfo, setAccessTokensToServers, uploadVideo } from '../../utils/index' +import { + addVideoCommentReply, addVideoCommentThread, getVideoCommentThreads, + getVideoThreadComments +} from '../../utils/videos/video-comments' + +const expect = chai.expect + +describe('Test video comments', function () { + let server: ServerInfo + let videoId + let videoUUID + let threadId + + before(async function () { + this.timeout(10000) + + await flushTests() + + server = await runServer(1) + + await setAccessTokensToServers([ server ]) + + const res = await uploadVideo(server.url, server.accessToken, {}) + videoUUID = res.body.video.uuid + videoId = res.body.video.id + }) + + it('Should not have threads on this video', async function () { + const res = await getVideoCommentThreads(server.url, videoUUID, 0, 5) + + expect(res.body.total).to.equal(0) + expect(res.body.data).to.be.an('array') + expect(res.body.data).to.have.lengthOf(0) + }) + + it('Should create a thread in this video', async function () { + const text = 'my super first comment' + + const res = await addVideoCommentThread(server.url, server.accessToken, videoUUID, text) + const comment = res.body.comment + + expect(comment.inReplyToCommentId).to.be.null + expect(comment.text).equal('my super first comment') + expect(comment.videoId).to.equal(videoId) + expect(comment.id).to.equal(comment.threadId) + expect(comment.account.name).to.equal('root') + expect(comment.account.host).to.equal('localhost:9001') + expect(comment.totalReplies).to.equal(0) + expect(dateIsValid(comment.createdAt as string)).to.be.true + expect(dateIsValid(comment.updatedAt as string)).to.be.true + }) + + it('Should list threads of this video', async function () { + const res = await getVideoCommentThreads(server.url, videoUUID, 0, 5) + + expect(res.body.total).to.equal(1) + expect(res.body.data).to.be.an('array') + expect(res.body.data).to.have.lengthOf(1) + + const comment: VideoComment = res.body.data[0] + expect(comment.inReplyToCommentId).to.be.null + expect(comment.text).equal('my super first comment') + expect(comment.videoId).to.equal(videoId) + expect(comment.id).to.equal(comment.threadId) + expect(comment.account.name).to.equal('root') + expect(comment.account.host).to.equal('localhost:9001') + expect(comment.totalReplies).to.equal(0) + expect(dateIsValid(comment.createdAt as string)).to.be.true + expect(dateIsValid(comment.updatedAt as string)).to.be.true + + threadId = comment.threadId + }) + + it('Should get all the thread created', async function () { + const res = await getVideoThreadComments(server.url, videoUUID, threadId) + + const rootComment = res.body.comment + expect(rootComment.inReplyToCommentId).to.be.null + expect(rootComment.text).equal('my super first comment') + expect(rootComment.videoId).to.equal(videoId) + expect(dateIsValid(rootComment.createdAt as string)).to.be.true + expect(dateIsValid(rootComment.updatedAt as string)).to.be.true + }) + + it('Should create multiple replies in this thread', async function () { + const text1 = 'my super answer to thread 1' + const childCommentRes = await addVideoCommentReply(server.url, server.accessToken, videoId, threadId, text1) + const childCommentId = childCommentRes.body.comment.id + + const text2 = 'my super answer to answer of thread 1' + await addVideoCommentReply(server.url, server.accessToken, videoId, childCommentId, text2) + + const text3 = 'my second answer to thread 1' + await addVideoCommentReply(server.url, server.accessToken, videoId, threadId, text3) + }) + + it('Should get correctly the replies', async function () { + const res = await getVideoThreadComments(server.url, videoUUID, threadId) + + const tree: VideoCommentThreadTree = res.body + expect(tree.comment.text).equal('my super first comment') + expect(tree.children).to.have.lengthOf(2) + + const firstChild = tree.children[0] + expect(firstChild.comment.text).to.equal('my super answer to thread 1') + expect(firstChild.children).to.have.lengthOf(1) + + const childOfFirstChild = firstChild.children[0] + expect(childOfFirstChild.comment.text).to.equal('my super answer to answer of thread 1') + expect(childOfFirstChild.children).to.have.lengthOf(0) + + const secondChild = tree.children[1] + expect(secondChild.comment.text).to.equal('my second answer to thread 1') + expect(secondChild.children).to.have.lengthOf(0) + }) + + it('Should create other threads', async function () { + const text1 = 'super thread 2' + await addVideoCommentThread(server.url, server.accessToken, videoUUID, text1) + + const text2 = 'super thread 3' + await addVideoCommentThread(server.url, server.accessToken, videoUUID, text2) + }) + + it('Should list the threads', async function () { + const res = await getVideoCommentThreads(server.url, videoUUID, 0, 5, 'createdAt') + + expect(res.body.total).to.equal(3) + expect(res.body.data).to.be.an('array') + expect(res.body.data).to.have.lengthOf(3) + + expect(res.body.data[0].text).to.equal('my super first comment') + expect(res.body.data[0].totalReplies).to.equal(3) + expect(res.body.data[1].text).to.equal('super thread 2') + expect(res.body.data[1].totalReplies).to.equal(0) + expect(res.body.data[2].text).to.equal('super thread 3') + expect(res.body.data[2].totalReplies).to.equal(0) + }) + + after(async function () { + killallServers([ server ]) + + // Keep the logs if the test failed + if (this['ok']) { + await flushTests() + } + }) +}) diff --git a/server/tests/api/videos/video-description.ts b/server/tests/api/videos/video-description.ts new file mode 100644 index 000000000..c2985194c --- /dev/null +++ b/server/tests/api/videos/video-description.ts @@ -0,0 +1,111 @@ +/* tslint:disable:no-unused-expression */ + +import * as chai from 'chai' +import 'mocha' +import { + flushAndRunMultipleServers, + flushTests, + getVideo, + getVideoDescription, + getVideosList, + killallServers, + ServerInfo, + setAccessTokensToServers, + updateVideo, + uploadVideo, + wait +} from '../../utils/index' +import { doubleFollow } from '../../utils/server/follows' + +const expect = chai.expect + +describe('Test video description', function () { + let servers: ServerInfo[] = [] + let videoUUID = '' + let videoId: number + let longDescription = 'my super description for server 1'.repeat(50) + + before(async function () { + this.timeout(40000) + + // Run servers + servers = await flushAndRunMultipleServers(2) + + // Get the access tokens + await setAccessTokensToServers(servers) + + // Server 1 and server 2 follow each other + await doubleFollow(servers[0], servers[1]) + }) + + it('Should upload video with long description', async function () { + this.timeout(10000) + + const attributes = { + description: longDescription + } + await uploadVideo(servers[0].url, servers[0].accessToken, attributes) + + await wait(5000) + + const res = await getVideosList(servers[0].url) + + videoId = res.body.data[0].id + videoUUID = res.body.data[0].uuid + }) + + it('Should have a truncated description on each server', async function () { + for (const server of servers) { + const res = await getVideo(server.url, videoUUID) + const video = res.body + + // 30 characters * 6 -> 240 characters + const truncatedDescription = 'my super description for server 1'.repeat(7) + + 'my super descrip...' + + expect(video.description).to.equal(truncatedDescription) + } + }) + + it('Should fetch long description on each server', async function () { + for (const server of servers) { + const res = await getVideo(server.url, videoUUID) + const video = res.body + + const res2 = await getVideoDescription(server.url, video.descriptionPath) + expect(res2.body.description).to.equal(longDescription) + } + }) + + it('Should update with a short description', async function () { + this.timeout(10000) + + const attributes = { + description: 'short description' + } + await updateVideo(servers[0].url, servers[0].accessToken, videoId, attributes) + + await wait(5000) + }) + + it('Should have a small description on each server', async function () { + for (const server of servers) { + const res = await getVideo(server.url, videoUUID) + const video = res.body + + expect(video.description).to.equal('short description') + + const res2 = await getVideoDescription(server.url, video.descriptionPath) + expect(res2.body.description).to.equal('short description') + } + }) + + after(async function () { + killallServers(servers) + + // Keep the logs if the test failed + if (this['ok']) { + await flushTests() + } + }) +}) diff --git a/server/tests/api/videos/video-privacy.ts b/server/tests/api/videos/video-privacy.ts new file mode 100644 index 000000000..de709f8f1 --- /dev/null +++ b/server/tests/api/videos/video-privacy.ts @@ -0,0 +1,159 @@ +/* tslint:disable:no-unused-expression */ + +import * as chai from 'chai' +import 'mocha' +import { VideoPrivacy } from '../../../../shared/models/videos/video-privacy.enum' +import { + flushAndRunMultipleServers, + flushTests, + getVideosList, + killallServers, + ServerInfo, + setAccessTokensToServers, + uploadVideo, + wait +} from '../../utils/index' +import { doubleFollow } from '../../utils/server/follows' +import { getUserAccessToken } from '../../utils/users/login' +import { createUser } from '../../utils/users/users' +import { getMyVideos, getVideo, getVideoWithToken, updateVideo } from '../../utils/videos/videos' + +const expect = chai.expect + +describe('Test video privacy', function () { + let servers: ServerInfo[] = [] + let privateVideoId + let privateVideoUUID + let unlistedVideoUUID + + before(async function () { + this.timeout(50000) + + // Run servers + servers = await flushAndRunMultipleServers(2) + + // Get the access tokens + await setAccessTokensToServers(servers) + + // Server 1 and server 2 follow each other + await doubleFollow(servers[0], servers[1]) + }) + + it('Should upload a private video on server 1', async function () { + this.timeout(10000) + + const attributes = { + privacy: VideoPrivacy.PRIVATE + } + await uploadVideo(servers[0].url, servers[0].accessToken, attributes) + + await wait(5000) + }) + + it('Should not have this private video on server 2', async function () { + const res = await getVideosList(servers[1].url) + + expect(res.body.total).to.equal(0) + expect(res.body.data).to.have.lengthOf(0) + }) + + it('Should list my (private) videos', async function () { + const res = await getMyVideos(servers[0].url, servers[0].accessToken, 0, 1) + + expect(res.body.total).to.equal(1) + expect(res.body.data).to.have.lengthOf(1) + + privateVideoId = res.body.data[0].id + privateVideoUUID = res.body.data[0].uuid + }) + + it('Should not be able to watch this video with non authenticated user', async function () { + await getVideo(servers[0].url, privateVideoUUID, 401) + }) + + it('Should not be able to watch this private video with another user', async function () { + const user = { + username: 'hello', + password: 'super password' + } + await createUser(servers[0].url, servers[0].accessToken, user.username, user.password) + + const token = await getUserAccessToken(servers[0], user) + await getVideoWithToken(servers[0].url, token, privateVideoUUID, 403) + }) + + it('Should be able to watch this video with the correct user', async function () { + await getVideoWithToken(servers[0].url, servers[0].accessToken, privateVideoUUID) + }) + + it('Should upload an unlisted video on server 2', async function () { + this.timeout(30000) + + const attributes = { + name: 'unlisted video', + privacy: VideoPrivacy.UNLISTED + } + await uploadVideo(servers[1].url, servers[1].accessToken, attributes) + + // Server 2 has transcoding enabled + await wait(10000) + }) + + it('Should not have this unlisted video listed on server 1 and 2', async function () { + for (const server of servers) { + const res = await getVideosList(server.url) + + expect(res.body.total).to.equal(0) + expect(res.body.data).to.have.lengthOf(0) + } + }) + + it('Should list my (unlisted) videos', async function () { + const res = await getMyVideos(servers[1].url, servers[1].accessToken, 0, 1) + + expect(res.body.total).to.equal(1) + expect(res.body.data).to.have.lengthOf(1) + + unlistedVideoUUID = res.body.data[0].uuid + }) + + it('Should be able to get this unlisted video', async function () { + for (const server of servers) { + const res = await getVideo(server.url, unlistedVideoUUID) + + expect(res.body.name).to.equal('unlisted video') + } + }) + + it('Should update the private video to public on server 1', async function () { + this.timeout(10000) + + const attribute = { + name: 'super video public', + privacy: VideoPrivacy.PUBLIC + } + + await updateVideo(servers[0].url, servers[0].accessToken, privateVideoId, attribute) + + await wait(5000) + }) + + it('Should have this new public video listed on server 1 and 2', async function () { + for (const server of servers) { + const res = await getVideosList(server.url) + + expect(res.body.total).to.equal(1) + expect(res.body.data).to.have.lengthOf(1) + expect(res.body.data[0].name).to.equal('super video public') + } + }) + + after(async function () { + killallServers(servers) + + // Keep the logs if the test failed + if (this['ok']) { + await flushTests() + } + }) +}) diff --git a/server/tests/api/videos/video-transcoder.ts b/server/tests/api/videos/video-transcoder.ts new file mode 100644 index 000000000..27927a594 --- /dev/null +++ b/server/tests/api/videos/video-transcoder.ts @@ -0,0 +1,97 @@ +/* tslint:disable:no-unused-expression */ + +import 'mocha' +import * as chai from 'chai' +const expect = chai.expect + +import { + ServerInfo, + flushTests, + uploadVideo, + getVideosList, + wait, + setAccessTokensToServers, + flushAndRunMultipleServers, + killallServers, + webtorrentAdd, + getVideo +} from '../../utils/index' + +describe('Test video transcoding', function () { + let servers: ServerInfo[] = [] + + before(async function () { + this.timeout(10000) + + // Run servers + servers = await flushAndRunMultipleServers(2) + + await setAccessTokensToServers(servers) + }) + + it('Should not transcode video on server 1', async function () { + this.timeout(60000) + + const videoAttributes = { + name: 'my super name for server 1', + description: 'my super description for server 1', + fixture: 'video_short.webm' + } + await uploadVideo(servers[0].url, servers[0].accessToken, videoAttributes) + + await wait(10000) + + const res = await getVideosList(servers[0].url) + const video = res.body.data[0] + + const res2 = await getVideo(servers[0].url, video.id) + const videoDetails = res2.body + expect(videoDetails.files).to.have.lengthOf(1) + + const magnetUri = videoDetails.files[0].magnetUri + expect(magnetUri).to.match(/\.webm/) + + const torrent = await webtorrentAdd(magnetUri) + expect(torrent.files).to.be.an('array') + expect(torrent.files.length).to.equal(1) + expect(torrent.files[0].path).match(/\.webm$/) + }) + + it('Should transcode video on server 2', async function () { + this.timeout(60000) + + const videoAttributes = { + name: 'my super name for server 2', + description: 'my super description for server 2', + fixture: 'video_short.webm' + } + await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes) + + await wait(20000) + + const res = await getVideosList(servers[1].url) + + const video = res.body.data[0] + const res2 = await getVideo(servers[1].url, video.id) + const videoDetails = res2.body + + expect(videoDetails.files).to.have.lengthOf(4) + + const magnetUri = videoDetails.files[0].magnetUri + expect(magnetUri).to.match(/\.mp4/) + + const torrent = await webtorrentAdd(magnetUri) + expect(torrent.files).to.be.an('array') + expect(torrent.files.length).to.equal(1) + expect(torrent.files[0].path).match(/\.mp4$/) + }) + + after(async function () { + killallServers(servers) + + // Keep the logs if the test failed + if (this['ok']) { + await flushTests() + } + }) +}) diff --git a/server/tests/utils/activitypub.ts b/server/tests/utils/activitypub.ts deleted file mode 100644 index cf3c1c3b3..000000000 --- a/server/tests/utils/activitypub.ts +++ /dev/null @@ -1,15 +0,0 @@ -import * as request from 'supertest' - -function makeActivityPubGetRequest (url: string, path: string) { - return request(url) - .get(path) - .set('Accept', 'application/activity+json,text/html;q=0.9,\\*/\\*;q=0.8') - .expect(200) - .expect('Content-Type', /json/) -} - -// --------------------------------------------------------------------------- - -export { - makeActivityPubGetRequest -} diff --git a/server/tests/utils/cli.ts b/server/tests/utils/cli.ts deleted file mode 100644 index 4098fdf6f..000000000 --- a/server/tests/utils/cli.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { exec } from 'child_process' - -import { ServerInfo } from './servers' - -function getEnvCli (server?: ServerInfo) { - return `NODE_ENV=test NODE_APP_INSTANCE=${server.serverNumber}` -} - -async function execCLI (command: string) { - return new Promise((res, rej) => { - exec(command, (err, stdout, stderr) => { - if (err) return rej(err) - - return res(stdout) - }) - }) -} - -// --------------------------------------------------------------------------- - -export { - execCLI, - getEnvCli -} diff --git a/server/tests/utils/cli/cli.ts b/server/tests/utils/cli/cli.ts new file mode 100644 index 000000000..54d05e9c6 --- /dev/null +++ b/server/tests/utils/cli/cli.ts @@ -0,0 +1,24 @@ +import { exec } from 'child_process' + +import { ServerInfo } from '../server/servers' + +function getEnvCli (server?: ServerInfo) { + return `NODE_ENV=test NODE_APP_INSTANCE=${server.serverNumber}` +} + +async function execCLI (command: string) { + return new Promise((res, rej) => { + exec(command, (err, stdout, stderr) => { + if (err) return rej(err) + + return res(stdout) + }) + }) +} + +// --------------------------------------------------------------------------- + +export { + execCLI, + getEnvCli +} diff --git a/server/tests/utils/clients.ts b/server/tests/utils/clients.ts deleted file mode 100644 index a8c5b51c5..000000000 --- a/server/tests/utils/clients.ts +++ /dev/null @@ -1,17 +0,0 @@ -import * as request from 'supertest' - -function getClient (url: string) { - const path = '/api/v1/oauth-clients/local' - - return request(url) - .get(path) - .set('Accept', 'application/json') - .expect(200) - .expect('Content-Type', /json/) -} - -// --------------------------------------------------------------------------- - -export { - getClient -} diff --git a/server/tests/utils/config.ts b/server/tests/utils/config.ts deleted file mode 100644 index d09c19c60..000000000 --- a/server/tests/utils/config.ts +++ /dev/null @@ -1,17 +0,0 @@ -import * as request from 'supertest' - -function getConfig (url: string) { - const path = '/api/v1/config' - - return request(url) - .get(path) - .set('Accept', 'application/json') - .expect(200) - .expect('Content-Type', /json/) -} - -// --------------------------------------------------------------------------- - -export { - getConfig -} diff --git a/server/tests/utils/follows.ts b/server/tests/utils/follows.ts deleted file mode 100644 index a9f798bcb..000000000 --- a/server/tests/utils/follows.ts +++ /dev/null @@ -1,77 +0,0 @@ -import * as request from 'supertest' -import { wait } from './miscs' -import { ServerInfo } from './servers' - -function getFollowersListPaginationAndSort (url: string, start: number, count: number, sort: string) { - const path = '/api/v1/server/followers' - - return request(url) - .get(path) - .query({ start }) - .query({ count }) - .query({ sort }) - .set('Accept', 'application/json') - .expect(200) - .expect('Content-Type', /json/) -} - -function getFollowingListPaginationAndSort (url: string, start: number, count: number, sort: string) { - const path = '/api/v1/server/following' - - return request(url) - .get(path) - .query({ start }) - .query({ count }) - .query({ sort }) - .set('Accept', 'application/json') - .expect(200) - .expect('Content-Type', /json/) -} - -async function follow (follower: string, following: string[], accessToken: string, expectedStatus = 204) { - const path = '/api/v1/server/following' - - const followingHosts = following.map(f => f.replace(/^http:\/\//, '')) - const res = await request(follower) - .post(path) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + accessToken) - .send({ 'hosts': followingHosts }) - .expect(expectedStatus) - - return res -} - -async function unfollow (url: string, accessToken: string, target: ServerInfo, expectedStatus = 204) { - const path = '/api/v1/server/following/' + target.host - - const res = await request(url) - .delete(path) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + accessToken) - .expect(expectedStatus) - - return res -} - -async function doubleFollow (server1: ServerInfo, server2: ServerInfo) { - await Promise.all([ - follow(server1.url, [ server2.url ], server1.accessToken), - follow(server2.url, [ server1.url ], server2.accessToken) - ]) - - // Wait request propagation - await wait(10000) - - return true -} - -// --------------------------------------------------------------------------- - -export { - getFollowersListPaginationAndSort, - getFollowingListPaginationAndSort, - unfollow, - follow, - doubleFollow -} diff --git a/server/tests/utils/index.ts b/server/tests/utils/index.ts index b918ee83d..d7789e517 100644 --- a/server/tests/utils/index.ts +++ b/server/tests/utils/index.ts @@ -1,15 +1,15 @@ -export * from './activitypub' -export * from './cli' -export * from './clients' -export * from './config' -export * from './login' -export * from './miscs' -export * from './follows' -export * from './requests' -export * from './servers' -export * from './services' -export * from './users' -export * from './video-abuses' -export * from './video-blacklist' -export * from './video-channels' -export * from './videos' +export * from './server/activitypub' +export * from './cli/cli' +export * from './server/clients' +export * from './server/config' +export * from './users/login' +export * from './miscs/miscs' +export * from './server/follows' +export * from './requests/requests' +export * from './server/servers' +export * from './videos/services' +export * from './users/users' +export * from './videos/video-abuses' +export * from './videos/video-blacklist' +export * from './videos/video-channels' +export * from './videos/videos' diff --git a/server/tests/utils/jobs.ts b/server/tests/utils/jobs.ts deleted file mode 100644 index 0a8c51575..000000000 --- a/server/tests/utils/jobs.ts +++ /dev/null @@ -1,33 +0,0 @@ -import * as request from 'supertest' - -function getJobsList (url: string, accessToken: string) { - const path = '/api/v1/jobs' - - return request(url) - .get(path) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + accessToken) - .expect(200) - .expect('Content-Type', /json/) -} - -function getJobsListPaginationAndSort (url: string, accessToken: string, start: number, count: number, sort: string) { - const path = '/api/v1/jobs' - - return request(url) - .get(path) - .query({ start }) - .query({ count }) - .query({ sort }) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + accessToken) - .expect(200) - .expect('Content-Type', /json/) -} - -// --------------------------------------------------------------------------- - -export { - getJobsList, - getJobsListPaginationAndSort -} diff --git a/server/tests/utils/login.ts b/server/tests/utils/login.ts deleted file mode 100644 index 22d37c46f..000000000 --- a/server/tests/utils/login.ts +++ /dev/null @@ -1,59 +0,0 @@ -import * as request from 'supertest' - -import { ServerInfo } from './servers' - -type Client = { id: string, secret: string } -type User = { username: string, password: string } -type Server = { url: string, client: Client, user: User } - -function login (url: string, client: Client, user: User, expectedStatus = 200) { - const path = '/api/v1/users/token' - - const body = { - client_id: client.id, - client_secret: client.secret, - username: user.username, - password: user.password, - response_type: 'code', - grant_type: 'password', - scope: 'upload' - } - - return request(url) - .post(path) - .type('form') - .send(body) - .expect(expectedStatus) -} - -async function loginAndGetAccessToken (server: Server) { - const res = await login(server.url, server.client, server.user, 200) - - return res.body.access_token as string -} - -async function getUserAccessToken (server: Server, user: User) { - const res = await login(server.url, server.client, user, 200) - - return res.body.access_token as string -} - -function setAccessTokensToServers (servers: ServerInfo[]) { - const tasks: Promise[] = [] - - for (const server of servers) { - const p = loginAndGetAccessToken(server).then(t => server.accessToken = t) - tasks.push(p) - } - - return Promise.all(tasks) -} - -// --------------------------------------------------------------------------- - -export { - login, - loginAndGetAccessToken, - getUserAccessToken, - setAccessTokensToServers -} diff --git a/server/tests/utils/miscs.ts b/server/tests/utils/miscs.ts deleted file mode 100644 index 424b0db98..000000000 --- a/server/tests/utils/miscs.ts +++ /dev/null @@ -1,52 +0,0 @@ -import * as WebTorrent from 'webtorrent' -import { readFile, readdir } from 'fs' - -let webtorrent = new WebTorrent() - -function readFilePromise (path: string) { - return new Promise((res, rej) => { - readFile(path, (err, data) => { - if (err) return rej(err) - - return res(data) - }) - }) -} - -function readdirPromise (path: string) { - return new Promise((res, rej) => { - readdir(path, (err, files) => { - if (err) return rej(err) - - return res(files) - }) - }) -} - - // Default interval -> 2 minutes -function dateIsValid (dateString: string, interval = 120000) { - const dateToCheck = new Date(dateString) - const now = new Date() - - return Math.abs(now.getTime() - dateToCheck.getTime()) <= interval -} - -function wait (milliseconds: number) { - return new Promise(resolve => setTimeout(resolve, milliseconds)) -} - -function webtorrentAdd (torrent: string, refreshWebTorrent = false) { - if (refreshWebTorrent === true) webtorrent = new WebTorrent() - - return new Promise(res => webtorrent.add(torrent, res)) -} - -// --------------------------------------------------------------------------- - -export { - readFilePromise, - readdirPromise, - dateIsValid, - wait, - webtorrentAdd -} diff --git a/server/tests/utils/miscs/miscs.ts b/server/tests/utils/miscs/miscs.ts new file mode 100644 index 000000000..424b0db98 --- /dev/null +++ b/server/tests/utils/miscs/miscs.ts @@ -0,0 +1,52 @@ +import * as WebTorrent from 'webtorrent' +import { readFile, readdir } from 'fs' + +let webtorrent = new WebTorrent() + +function readFilePromise (path: string) { + return new Promise((res, rej) => { + readFile(path, (err, data) => { + if (err) return rej(err) + + return res(data) + }) + }) +} + +function readdirPromise (path: string) { + return new Promise((res, rej) => { + readdir(path, (err, files) => { + if (err) return rej(err) + + return res(files) + }) + }) +} + + // Default interval -> 2 minutes +function dateIsValid (dateString: string, interval = 120000) { + const dateToCheck = new Date(dateString) + const now = new Date() + + return Math.abs(now.getTime() - dateToCheck.getTime()) <= interval +} + +function wait (milliseconds: number) { + return new Promise(resolve => setTimeout(resolve, milliseconds)) +} + +function webtorrentAdd (torrent: string, refreshWebTorrent = false) { + if (refreshWebTorrent === true) webtorrent = new WebTorrent() + + return new Promise(res => webtorrent.add(torrent, res)) +} + +// --------------------------------------------------------------------------- + +export { + readFilePromise, + readdirPromise, + dateIsValid, + wait, + webtorrentAdd +} diff --git a/server/tests/utils/requests.ts b/server/tests/utils/requests.ts deleted file mode 100644 index 52b7a4c29..000000000 --- a/server/tests/utils/requests.ts +++ /dev/null @@ -1,92 +0,0 @@ -import * as request from 'supertest' - -function makeGetRequest (url: string, path: string) { - return request(url) - .get(path) - .set('Accept', 'application/json') - .expect(200) - .expect('Content-Type', /json/) -} - -function makePostUploadRequest (options: { - url: string, - path: string, - token: string, - fields: { [ fieldName: string ]: any }, - attaches: { [ attachName: string ]: any }, - statusCodeExpected?: number -}) { - if (!options.statusCodeExpected) options.statusCodeExpected = 400 - - const req = request(options.url) - .post(options.path) - .set('Accept', 'application/json') - - if (options.token) req.set('Authorization', 'Bearer ' + options.token) - - Object.keys(options.fields).forEach(field => { - const value = options.fields[field] - - if (Array.isArray(value)) { - for (let i = 0; i < value.length; i++) { - req.field(field + '[' + i + ']', value[i]) - } - } else { - req.field(field, value) - } - }) - - Object.keys(options.attaches).forEach(attach => { - const value = options.attaches[attach] - req.attach(attach, value) - }) - - return req.expect(options.statusCodeExpected) -} - -function makePostBodyRequest (options: { - url: string, - path: string, - token?: string, - fields: { [ fieldName: string ]: any }, - statusCodeExpected?: number -}) { - if (!options.statusCodeExpected) options.statusCodeExpected = 400 - - const req = request(options.url) - .post(options.path) - .set('Accept', 'application/json') - - if (options.token) req.set('Authorization', 'Bearer ' + options.token) - - return req.send(options.fields) - .expect(options.statusCodeExpected) -} - -function makePutBodyRequest (options: { - url: string, - path: string, - token: string, - fields: { [ fieldName: string ]: any }, - statusCodeExpected?: number -}) { - if (!options.statusCodeExpected) options.statusCodeExpected = 400 - - const req = request(options.url) - .put(options.path) - .set('Accept', 'application/json') - - if (options.token) req.set('Authorization', 'Bearer ' + options.token) - - return req.send(options.fields) - .expect(options.statusCodeExpected) -} - -// --------------------------------------------------------------------------- - -export { - makeGetRequest, - makePostUploadRequest, - makePostBodyRequest, - makePutBodyRequest -} diff --git a/server/tests/utils/requests/requests.ts b/server/tests/utils/requests/requests.ts new file mode 100644 index 000000000..52b7a4c29 --- /dev/null +++ b/server/tests/utils/requests/requests.ts @@ -0,0 +1,92 @@ +import * as request from 'supertest' + +function makeGetRequest (url: string, path: string) { + return request(url) + .get(path) + .set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) +} + +function makePostUploadRequest (options: { + url: string, + path: string, + token: string, + fields: { [ fieldName: string ]: any }, + attaches: { [ attachName: string ]: any }, + statusCodeExpected?: number +}) { + if (!options.statusCodeExpected) options.statusCodeExpected = 400 + + const req = request(options.url) + .post(options.path) + .set('Accept', 'application/json') + + if (options.token) req.set('Authorization', 'Bearer ' + options.token) + + Object.keys(options.fields).forEach(field => { + const value = options.fields[field] + + if (Array.isArray(value)) { + for (let i = 0; i < value.length; i++) { + req.field(field + '[' + i + ']', value[i]) + } + } else { + req.field(field, value) + } + }) + + Object.keys(options.attaches).forEach(attach => { + const value = options.attaches[attach] + req.attach(attach, value) + }) + + return req.expect(options.statusCodeExpected) +} + +function makePostBodyRequest (options: { + url: string, + path: string, + token?: string, + fields: { [ fieldName: string ]: any }, + statusCodeExpected?: number +}) { + if (!options.statusCodeExpected) options.statusCodeExpected = 400 + + const req = request(options.url) + .post(options.path) + .set('Accept', 'application/json') + + if (options.token) req.set('Authorization', 'Bearer ' + options.token) + + return req.send(options.fields) + .expect(options.statusCodeExpected) +} + +function makePutBodyRequest (options: { + url: string, + path: string, + token: string, + fields: { [ fieldName: string ]: any }, + statusCodeExpected?: number +}) { + if (!options.statusCodeExpected) options.statusCodeExpected = 400 + + const req = request(options.url) + .put(options.path) + .set('Accept', 'application/json') + + if (options.token) req.set('Authorization', 'Bearer ' + options.token) + + return req.send(options.fields) + .expect(options.statusCodeExpected) +} + +// --------------------------------------------------------------------------- + +export { + makeGetRequest, + makePostUploadRequest, + makePostBodyRequest, + makePutBodyRequest +} diff --git a/server/tests/utils/server/activitypub.ts b/server/tests/utils/server/activitypub.ts new file mode 100644 index 000000000..cf3c1c3b3 --- /dev/null +++ b/server/tests/utils/server/activitypub.ts @@ -0,0 +1,15 @@ +import * as request from 'supertest' + +function makeActivityPubGetRequest (url: string, path: string) { + return request(url) + .get(path) + .set('Accept', 'application/activity+json,text/html;q=0.9,\\*/\\*;q=0.8') + .expect(200) + .expect('Content-Type', /json/) +} + +// --------------------------------------------------------------------------- + +export { + makeActivityPubGetRequest +} diff --git a/server/tests/utils/server/clients.ts b/server/tests/utils/server/clients.ts new file mode 100644 index 000000000..a8c5b51c5 --- /dev/null +++ b/server/tests/utils/server/clients.ts @@ -0,0 +1,17 @@ +import * as request from 'supertest' + +function getClient (url: string) { + const path = '/api/v1/oauth-clients/local' + + return request(url) + .get(path) + .set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) +} + +// --------------------------------------------------------------------------- + +export { + getClient +} diff --git a/server/tests/utils/server/config.ts b/server/tests/utils/server/config.ts new file mode 100644 index 000000000..d09c19c60 --- /dev/null +++ b/server/tests/utils/server/config.ts @@ -0,0 +1,17 @@ +import * as request from 'supertest' + +function getConfig (url: string) { + const path = '/api/v1/config' + + return request(url) + .get(path) + .set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) +} + +// --------------------------------------------------------------------------- + +export { + getConfig +} diff --git a/server/tests/utils/server/follows.ts b/server/tests/utils/server/follows.ts new file mode 100644 index 000000000..82e89175c --- /dev/null +++ b/server/tests/utils/server/follows.ts @@ -0,0 +1,77 @@ +import * as request from 'supertest' +import { wait } from '../miscs/miscs' +import { ServerInfo } from './servers' + +function getFollowersListPaginationAndSort (url: string, start: number, count: number, sort: string) { + const path = '/api/v1/server/followers' + + return request(url) + .get(path) + .query({ start }) + .query({ count }) + .query({ sort }) + .set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) +} + +function getFollowingListPaginationAndSort (url: string, start: number, count: number, sort: string) { + const path = '/api/v1/server/following' + + return request(url) + .get(path) + .query({ start }) + .query({ count }) + .query({ sort }) + .set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) +} + +async function follow (follower: string, following: string[], accessToken: string, expectedStatus = 204) { + const path = '/api/v1/server/following' + + const followingHosts = following.map(f => f.replace(/^http:\/\//, '')) + const res = await request(follower) + .post(path) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + accessToken) + .send({ 'hosts': followingHosts }) + .expect(expectedStatus) + + return res +} + +async function unfollow (url: string, accessToken: string, target: ServerInfo, expectedStatus = 204) { + const path = '/api/v1/server/following/' + target.host + + const res = await request(url) + .delete(path) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + accessToken) + .expect(expectedStatus) + + return res +} + +async function doubleFollow (server1: ServerInfo, server2: ServerInfo) { + await Promise.all([ + follow(server1.url, [ server2.url ], server1.accessToken), + follow(server2.url, [ server1.url ], server2.accessToken) + ]) + + // Wait request propagation + await wait(10000) + + return true +} + +// --------------------------------------------------------------------------- + +export { + getFollowersListPaginationAndSort, + getFollowingListPaginationAndSort, + unfollow, + follow, + doubleFollow +} diff --git a/server/tests/utils/server/jobs.ts b/server/tests/utils/server/jobs.ts new file mode 100644 index 000000000..0a8c51575 --- /dev/null +++ b/server/tests/utils/server/jobs.ts @@ -0,0 +1,33 @@ +import * as request from 'supertest' + +function getJobsList (url: string, accessToken: string) { + const path = '/api/v1/jobs' + + return request(url) + .get(path) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + accessToken) + .expect(200) + .expect('Content-Type', /json/) +} + +function getJobsListPaginationAndSort (url: string, accessToken: string, start: number, count: number, sort: string) { + const path = '/api/v1/jobs' + + return request(url) + .get(path) + .query({ start }) + .query({ count }) + .query({ sort }) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + accessToken) + .expect(200) + .expect('Content-Type', /json/) +} + +// --------------------------------------------------------------------------- + +export { + getJobsList, + getJobsListPaginationAndSort +} diff --git a/server/tests/utils/server/servers.ts b/server/tests/utils/server/servers.ts new file mode 100644 index 000000000..8340fbc18 --- /dev/null +++ b/server/tests/utils/server/servers.ts @@ -0,0 +1,162 @@ +import { ChildProcess, exec, fork } from 'child_process' +import { join } from 'path' + +interface ServerInfo { + app: ChildProcess, + url: string + host: string + serverNumber: number + + client: { + id: string, + secret: string + } + + user: { + username: string, + password: string, + email?: string + } + + accessToken?: string + + video?: { + id: number + uuid: string + name: string + accountName: string + } + + remoteVideo?: { + id: number + uuid: string + } +} + +function flushAndRunMultipleServers (totalServers) { + let apps = [] + let i = 0 + + return new Promise(res => { + function anotherServerDone (serverNumber, app) { + apps[serverNumber - 1] = app + i++ + if (i === totalServers) { + return res(apps) + } + } + + flushTests() + .then(() => { + for (let j = 1; j <= totalServers; j++) { + // For the virtual buffer + setTimeout(() => { + runServer(j).then(app => anotherServerDone(j, app)) + }, 1000 * (j - 1)) + } + }) + }) +} + +function flushTests () { + return new Promise((res, rej) => { + return exec('npm run clean:server:test', err => { + if (err) return rej(err) + + return res() + }) + }) +} + +function runServer (serverNumber: number, configOverride?: Object) { + const server: ServerInfo = { + app: null, + serverNumber: serverNumber, + url: `http://localhost:${9000 + serverNumber}`, + host: `localhost:${9000 + serverNumber}`, + client: { + id: null, + secret: null + }, + user: { + username: null, + password: null + } + } + + // These actions are async so we need to be sure that they have both been done + const serverRunString = { + 'Server listening on port': false + } + const key = 'Database peertube_test' + serverNumber + ' is ready' + serverRunString[key] = false + + const regexps = { + client_id: 'Client id: (.+)', + client_secret: 'Client secret: (.+)', + user_username: 'Username: (.+)', + user_password: 'User password: (.+)' + } + + // Share the environment + const env = Object.create(process.env) + env['NODE_ENV'] = 'test' + env['NODE_APP_INSTANCE'] = serverNumber.toString() + + if (configOverride !== undefined) { + env['NODE_CONFIG'] = JSON.stringify(configOverride) + } + + const options = { + silent: true, + env: env, + detached: true + } + + return new Promise(res => { + server.app = fork(join(__dirname, '..', '..', '..', 'dist', 'server.js'), [], options) + server.app.stdout.on('data', function onStdout (data) { + let dontContinue = false + + // Capture things if we want to + for (const key of Object.keys(regexps)) { + const regexp = regexps[key] + const matches = data.toString().match(regexp) + if (matches !== null) { + if (key === 'client_id') server.client.id = matches[1] + else if (key === 'client_secret') server.client.secret = matches[1] + else if (key === 'user_username') server.user.username = matches[1] + else if (key === 'user_password') server.user.password = matches[1] + } + } + + // Check if all required sentences are here + for (const key of Object.keys(serverRunString)) { + if (data.toString().indexOf(key) !== -1) serverRunString[key] = true + if (serverRunString[key] === false) dontContinue = true + } + + // If no, there is maybe one thing not already initialized (client/user credentials generation...) + if (dontContinue === true) return + + server.app.stdout.removeListener('data', onStdout) + res(server) + }) + }) +} + +function killallServers (servers: ServerInfo[]) { + for (const server of servers) { + process.kill(-server.app.pid) + } +} + +// --------------------------------------------------------------------------- + +export { + ServerInfo, + flushAndRunMultipleServers, + flushTests, + runServer, + killallServers +} diff --git a/server/tests/utils/servers.ts b/server/tests/utils/servers.ts deleted file mode 100644 index 8340fbc18..000000000 --- a/server/tests/utils/servers.ts +++ /dev/null @@ -1,162 +0,0 @@ -import { ChildProcess, exec, fork } from 'child_process' -import { join } from 'path' - -interface ServerInfo { - app: ChildProcess, - url: string - host: string - serverNumber: number - - client: { - id: string, - secret: string - } - - user: { - username: string, - password: string, - email?: string - } - - accessToken?: string - - video?: { - id: number - uuid: string - name: string - accountName: string - } - - remoteVideo?: { - id: number - uuid: string - } -} - -function flushAndRunMultipleServers (totalServers) { - let apps = [] - let i = 0 - - return new Promise(res => { - function anotherServerDone (serverNumber, app) { - apps[serverNumber - 1] = app - i++ - if (i === totalServers) { - return res(apps) - } - } - - flushTests() - .then(() => { - for (let j = 1; j <= totalServers; j++) { - // For the virtual buffer - setTimeout(() => { - runServer(j).then(app => anotherServerDone(j, app)) - }, 1000 * (j - 1)) - } - }) - }) -} - -function flushTests () { - return new Promise((res, rej) => { - return exec('npm run clean:server:test', err => { - if (err) return rej(err) - - return res() - }) - }) -} - -function runServer (serverNumber: number, configOverride?: Object) { - const server: ServerInfo = { - app: null, - serverNumber: serverNumber, - url: `http://localhost:${9000 + serverNumber}`, - host: `localhost:${9000 + serverNumber}`, - client: { - id: null, - secret: null - }, - user: { - username: null, - password: null - } - } - - // These actions are async so we need to be sure that they have both been done - const serverRunString = { - 'Server listening on port': false - } - const key = 'Database peertube_test' + serverNumber + ' is ready' - serverRunString[key] = false - - const regexps = { - client_id: 'Client id: (.+)', - client_secret: 'Client secret: (.+)', - user_username: 'Username: (.+)', - user_password: 'User password: (.+)' - } - - // Share the environment - const env = Object.create(process.env) - env['NODE_ENV'] = 'test' - env['NODE_APP_INSTANCE'] = serverNumber.toString() - - if (configOverride !== undefined) { - env['NODE_CONFIG'] = JSON.stringify(configOverride) - } - - const options = { - silent: true, - env: env, - detached: true - } - - return new Promise(res => { - server.app = fork(join(__dirname, '..', '..', '..', 'dist', 'server.js'), [], options) - server.app.stdout.on('data', function onStdout (data) { - let dontContinue = false - - // Capture things if we want to - for (const key of Object.keys(regexps)) { - const regexp = regexps[key] - const matches = data.toString().match(regexp) - if (matches !== null) { - if (key === 'client_id') server.client.id = matches[1] - else if (key === 'client_secret') server.client.secret = matches[1] - else if (key === 'user_username') server.user.username = matches[1] - else if (key === 'user_password') server.user.password = matches[1] - } - } - - // Check if all required sentences are here - for (const key of Object.keys(serverRunString)) { - if (data.toString().indexOf(key) !== -1) serverRunString[key] = true - if (serverRunString[key] === false) dontContinue = true - } - - // If no, there is maybe one thing not already initialized (client/user credentials generation...) - if (dontContinue === true) return - - server.app.stdout.removeListener('data', onStdout) - res(server) - }) - }) -} - -function killallServers (servers: ServerInfo[]) { - for (const server of servers) { - process.kill(-server.app.pid) - } -} - -// --------------------------------------------------------------------------- - -export { - ServerInfo, - flushAndRunMultipleServers, - flushTests, - runServer, - killallServers -} diff --git a/server/tests/utils/services.ts b/server/tests/utils/services.ts deleted file mode 100644 index 1a53dd4cf..000000000 --- a/server/tests/utils/services.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as request from 'supertest' - -function getOEmbed (url: string, oembedUrl: string, format?: string, maxHeight?: number, maxWidth?: number) { - const path = '/services/oembed' - const query = { - url: oembedUrl, - format, - maxheight: maxHeight, - maxwidth: maxWidth - } - - return request(url) - .get(path) - .query(query) - .set('Accept', 'application/json') - .expect(200) -} - -// --------------------------------------------------------------------------- - -export { - getOEmbed -} diff --git a/server/tests/utils/users.ts b/server/tests/utils/users.ts deleted file mode 100644 index a37d84ab4..000000000 --- a/server/tests/utils/users.ts +++ /dev/null @@ -1,161 +0,0 @@ -import * as request from 'supertest' - -import { UserRole } from '../../../shared' - -function createUser ( - url: string, - accessToken: string, - username: string, - password: string, - videoQuota = 1000000, - role: UserRole = UserRole.USER, - specialStatus = 204 -) { - const path = '/api/v1/users' - const body = { - username, - password, - role, - email: username + '@example.com', - videoQuota - } - - return request(url) - .post(path) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + accessToken) - .send(body) - .expect(specialStatus) -} - -function registerUser (url: string, username: string, password: string, specialStatus = 204) { - const path = '/api/v1/users/register' - const body = { - username, - password, - email: username + '@example.com' - } - - return request(url) - .post(path) - .set('Accept', 'application/json') - .send(body) - .expect(specialStatus) -} - -function getMyUserInformation (url: string, accessToken: string) { - const path = '/api/v1/users/me' - - return request(url) - .get(path) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + accessToken) - .expect(200) - .expect('Content-Type', /json/) -} - -function getUserInformation (url: string, accessToken: string, userId: number) { - const path = '/api/v1/users/' + userId - - return request(url) - .get(path) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + accessToken) - .expect(200) - .expect('Content-Type', /json/) -} - -function getUserVideoRating (url: string, accessToken: string, videoId: number) { - const path = '/api/v1/users/me/videos/' + videoId + '/rating' - - return request(url) - .get(path) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + accessToken) - .expect(200) - .expect('Content-Type', /json/) -} - -function getUsersList (url: string, accessToken: string) { - const path = '/api/v1/users' - - return request(url) - .get(path) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + accessToken) - .expect(200) - .expect('Content-Type', /json/) -} - -function getUsersListPaginationAndSort (url: string, accessToken: string, start: number, count: number, sort: string) { - const path = '/api/v1/users' - - return request(url) - .get(path) - .query({ start }) - .query({ count }) - .query({ sort }) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + accessToken) - .expect(200) - .expect('Content-Type', /json/) -} - -function removeUser (url: string, userId: number, accessToken: string, expectedStatus = 204) { - const path = '/api/v1/users' - - return request(url) - .delete(path + '/' + userId) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + accessToken) - .expect(expectedStatus) -} - -function updateMyUser (url: string, accessToken: string, newPassword: string, displayNSFW?: boolean, - email?: string, autoPlayVideo?: boolean) { - const path = '/api/v1/users/me' - - const toSend = {} - if (newPassword !== undefined && newPassword !== null) toSend['password'] = newPassword - if (displayNSFW !== undefined && displayNSFW !== null) toSend['displayNSFW'] = displayNSFW - if (autoPlayVideo !== undefined && autoPlayVideo !== null) toSend['autoPlayVideo'] = autoPlayVideo - if (email !== undefined && email !== null) toSend['email'] = email - - return request(url) - .put(path) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + accessToken) - .send(toSend) - .expect(204) -} - -function updateUser (url: string, userId: number, accessToken: string, email: string, videoQuota: number, role: UserRole) { - const path = '/api/v1/users/' + userId - - const toSend = {} - if (email !== undefined && email !== null) toSend['email'] = email - if (videoQuota !== undefined && videoQuota !== null) toSend['videoQuota'] = videoQuota - if (role !== undefined && role !== null) toSend['role'] = role - - return request(url) - .put(path) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + accessToken) - .send(toSend) - .expect(204) -} - -// --------------------------------------------------------------------------- - -export { - createUser, - registerUser, - getMyUserInformation, - getUserVideoRating, - getUsersList, - getUsersListPaginationAndSort, - removeUser, - updateUser, - updateMyUser, - getUserInformation -} diff --git a/server/tests/utils/users/login.ts b/server/tests/utils/users/login.ts new file mode 100644 index 000000000..855c4828d --- /dev/null +++ b/server/tests/utils/users/login.ts @@ -0,0 +1,59 @@ +import * as request from 'supertest' + +import { ServerInfo } from '../server/servers' + +type Client = { id: string, secret: string } +type User = { username: string, password: string } +type Server = { url: string, client: Client, user: User } + +function login (url: string, client: Client, user: User, expectedStatus = 200) { + const path = '/api/v1/users/token' + + const body = { + client_id: client.id, + client_secret: client.secret, + username: user.username, + password: user.password, + response_type: 'code', + grant_type: 'password', + scope: 'upload' + } + + return request(url) + .post(path) + .type('form') + .send(body) + .expect(expectedStatus) +} + +async function loginAndGetAccessToken (server: Server) { + const res = await login(server.url, server.client, server.user, 200) + + return res.body.access_token as string +} + +async function getUserAccessToken (server: Server, user: User) { + const res = await login(server.url, server.client, user, 200) + + return res.body.access_token as string +} + +function setAccessTokensToServers (servers: ServerInfo[]) { + const tasks: Promise[] = [] + + for (const server of servers) { + const p = loginAndGetAccessToken(server).then(t => server.accessToken = t) + tasks.push(p) + } + + return Promise.all(tasks) +} + +// --------------------------------------------------------------------------- + +export { + login, + loginAndGetAccessToken, + getUserAccessToken, + setAccessTokensToServers +} diff --git a/server/tests/utils/users/users.ts b/server/tests/utils/users/users.ts new file mode 100644 index 000000000..bd8d7ab04 --- /dev/null +++ b/server/tests/utils/users/users.ts @@ -0,0 +1,161 @@ +import * as request from 'supertest' + +import { UserRole } from '../../../../shared/index' + +function createUser ( + url: string, + accessToken: string, + username: string, + password: string, + videoQuota = 1000000, + role: UserRole = UserRole.USER, + specialStatus = 204 +) { + const path = '/api/v1/users' + const body = { + username, + password, + role, + email: username + '@example.com', + videoQuota + } + + return request(url) + .post(path) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + accessToken) + .send(body) + .expect(specialStatus) +} + +function registerUser (url: string, username: string, password: string, specialStatus = 204) { + const path = '/api/v1/users/register' + const body = { + username, + password, + email: username + '@example.com' + } + + return request(url) + .post(path) + .set('Accept', 'application/json') + .send(body) + .expect(specialStatus) +} + +function getMyUserInformation (url: string, accessToken: string) { + const path = '/api/v1/users/me' + + return request(url) + .get(path) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + accessToken) + .expect(200) + .expect('Content-Type', /json/) +} + +function getUserInformation (url: string, accessToken: string, userId: number) { + const path = '/api/v1/users/' + userId + + return request(url) + .get(path) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + accessToken) + .expect(200) + .expect('Content-Type', /json/) +} + +function getUserVideoRating (url: string, accessToken: string, videoId: number) { + const path = '/api/v1/users/me/videos/' + videoId + '/rating' + + return request(url) + .get(path) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + accessToken) + .expect(200) + .expect('Content-Type', /json/) +} + +function getUsersList (url: string, accessToken: string) { + const path = '/api/v1/users' + + return request(url) + .get(path) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + accessToken) + .expect(200) + .expect('Content-Type', /json/) +} + +function getUsersListPaginationAndSort (url: string, accessToken: string, start: number, count: number, sort: string) { + const path = '/api/v1/users' + + return request(url) + .get(path) + .query({ start }) + .query({ count }) + .query({ sort }) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + accessToken) + .expect(200) + .expect('Content-Type', /json/) +} + +function removeUser (url: string, userId: number, accessToken: string, expectedStatus = 204) { + const path = '/api/v1/users' + + return request(url) + .delete(path + '/' + userId) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + accessToken) + .expect(expectedStatus) +} + +function updateMyUser (url: string, accessToken: string, newPassword: string, displayNSFW?: boolean, + email?: string, autoPlayVideo?: boolean) { + const path = '/api/v1/users/me' + + const toSend = {} + if (newPassword !== undefined && newPassword !== null) toSend['password'] = newPassword + if (displayNSFW !== undefined && displayNSFW !== null) toSend['displayNSFW'] = displayNSFW + if (autoPlayVideo !== undefined && autoPlayVideo !== null) toSend['autoPlayVideo'] = autoPlayVideo + if (email !== undefined && email !== null) toSend['email'] = email + + return request(url) + .put(path) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + accessToken) + .send(toSend) + .expect(204) +} + +function updateUser (url: string, userId: number, accessToken: string, email: string, videoQuota: number, role: UserRole) { + const path = '/api/v1/users/' + userId + + const toSend = {} + if (email !== undefined && email !== null) toSend['email'] = email + if (videoQuota !== undefined && videoQuota !== null) toSend['videoQuota'] = videoQuota + if (role !== undefined && role !== null) toSend['role'] = role + + return request(url) + .put(path) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + accessToken) + .send(toSend) + .expect(204) +} + +// --------------------------------------------------------------------------- + +export { + createUser, + registerUser, + getMyUserInformation, + getUserVideoRating, + getUsersList, + getUsersListPaginationAndSort, + removeUser, + updateUser, + updateMyUser, + getUserInformation +} diff --git a/server/tests/utils/video-abuses.ts b/server/tests/utils/video-abuses.ts deleted file mode 100644 index f00809234..000000000 --- a/server/tests/utils/video-abuses.ts +++ /dev/null @@ -1,31 +0,0 @@ -import * as request from 'supertest' - -function reportVideoAbuse (url: string, token: string, videoId: number, reason: string, specialStatus = 204) { - const path = '/api/v1/videos/' + videoId + '/abuse' - - return request(url) - .post(path) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + token) - .send({ reason }) - .expect(specialStatus) -} - -function getVideoAbusesList (url: string, token: string) { - const path = '/api/v1/videos/abuse' - - return request(url) - .get(path) - .query({ sort: 'createdAt' }) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + token) - .expect(200) - .expect('Content-Type', /json/) -} - -// --------------------------------------------------------------------------- - -export { - reportVideoAbuse, - getVideoAbusesList -} diff --git a/server/tests/utils/video-blacklist.ts b/server/tests/utils/video-blacklist.ts deleted file mode 100644 index 3a499f46a..000000000 --- a/server/tests/utils/video-blacklist.ts +++ /dev/null @@ -1,54 +0,0 @@ -import * as request from 'supertest' - -function addVideoToBlacklist (url: string, token: string, videoId: number, specialStatus = 204) { - const path = '/api/v1/videos/' + videoId + '/blacklist' - - return request(url) - .post(path) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + token) - .expect(specialStatus) -} - -function removeVideoFromBlacklist (url: string, token: string, videoId: number, specialStatus = 204) { - const path = '/api/v1/videos/' + videoId + '/blacklist' - - return request(url) - .delete(path) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + token) - .expect(specialStatus) -} - -function getBlacklistedVideosList (url: string, token: string, specialStatus = 200) { - const path = '/api/v1/videos/blacklist/' - - return request(url) - .get(path) - .query({ sort: 'createdAt' }) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + token) - .expect(specialStatus) - .expect('Content-Type', /json/) -} - -function getSortedBlacklistedVideosList (url: string, token: string, sort: string, specialStatus = 200) { - const path = '/api/v1/videos/blacklist/' - - return request(url) - .get(path) - .query({ sort: sort }) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + token) - .expect(specialStatus) - .expect('Content-Type', /json/) -} - -// --------------------------------------------------------------------------- - -export { - addVideoToBlacklist, - removeVideoFromBlacklist, - getBlacklistedVideosList, - getSortedBlacklistedVideosList -} diff --git a/server/tests/utils/video-channels.ts b/server/tests/utils/video-channels.ts deleted file mode 100644 index 0fb80d331..000000000 --- a/server/tests/utils/video-channels.ts +++ /dev/null @@ -1,95 +0,0 @@ -import * as request from 'supertest' - -type VideoChannelAttributes = { - name?: string - description?: string -} - -function getVideoChannelsList (url: string, start: number, count: number, sort?: string) { - const path = '/api/v1/videos/channels' - - const req = request(url) - .get(path) - .query({ start: start }) - .query({ count: count }) - - if (sort) req.query({ sort }) - - return req.set('Accept', 'application/json') - .expect(200) - .expect('Content-Type', /json/) -} - -function getAccountVideoChannelsList (url: string, accountId: number | string) { - const path = '/api/v1/videos/accounts/' + accountId + '/channels' - - return request(url) - .get(path) - .set('Accept', 'application/json') - .expect(200) - .expect('Content-Type', /json/) -} - -function addVideoChannel (url: string, token: string, videoChannelAttributesArg: VideoChannelAttributes, expectedStatus = 204) { - const path = '/api/v1/videos/channels' - - // Default attributes - let attributes = { - name: 'my super video channel', - description: 'my super channel description' - } - attributes = Object.assign(attributes, videoChannelAttributesArg) - - return request(url) - .post(path) - .send(attributes) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + token) - .expect(expectedStatus) -} - -function updateVideoChannel (url: string, token: string, channelId: number, attributes: VideoChannelAttributes, expectedStatus = 204) { - const body = {} - const path = '/api/v1/videos/channels/' + channelId - - if (attributes.name) body['name'] = attributes.name - if (attributes.description) body['description'] = attributes.description - - return request(url) - .put(path) - .send(body) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + token) - .expect(expectedStatus) -} - -function deleteVideoChannel (url: string, token: string, channelId: number, expectedStatus = 204) { - const path = '/api/v1/videos/channels/' - - return request(url) - .delete(path + channelId) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + token) - .expect(expectedStatus) -} - -function getVideoChannel (url: string, channelId: number) { - const path = '/api/v1/videos/channels/' + channelId - - return request(url) - .get(path) - .set('Accept', 'application/json') - .expect(200) - .expect('Content-Type', /json/) -} - -// --------------------------------------------------------------------------- - -export { - getVideoChannelsList, - getAccountVideoChannelsList, - addVideoChannel, - updateVideoChannel, - deleteVideoChannel, - getVideoChannel -} diff --git a/server/tests/utils/video-comments.ts b/server/tests/utils/video-comments.ts deleted file mode 100644 index 878147049..000000000 --- a/server/tests/utils/video-comments.ts +++ /dev/null @@ -1,64 +0,0 @@ -import * as request from 'supertest' - -function getVideoCommentThreads (url: string, videoId: number | string, start: number, count: number, sort?: string) { - const path = '/api/v1/videos/' + videoId + '/comment-threads' - - const req = request(url) - .get(path) - .query({ start: start }) - .query({ count: count }) - - if (sort) req.query({ sort }) - - return req.set('Accept', 'application/json') - .expect(200) - .expect('Content-Type', /json/) -} - -function getVideoThreadComments (url: string, videoId: number | string, threadId: number) { - const path = '/api/v1/videos/' + videoId + '/comment-threads/' + threadId - - return request(url) - .get(path) - .set('Accept', 'application/json') - .expect(200) - .expect('Content-Type', /json/) -} - -function addVideoCommentThread (url: string, token: string, videoId: number | string, text: string, expectedStatus = 200) { - const path = '/api/v1/videos/' + videoId + '/comment-threads' - - return request(url) - .post(path) - .send({ text }) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + token) - .expect(expectedStatus) -} - -function addVideoCommentReply ( - url: string, - token: string, - videoId: number | string, - inReplyToCommentId: number, - text: string, - expectedStatus = 200 -) { - const path = '/api/v1/videos/' + videoId + '/comments/' + inReplyToCommentId - - return request(url) - .post(path) - .send({ text }) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + token) - .expect(expectedStatus) -} - -// --------------------------------------------------------------------------- - -export { - getVideoCommentThreads, - getVideoThreadComments, - addVideoCommentThread, - addVideoCommentReply -} diff --git a/server/tests/utils/videos.ts b/server/tests/utils/videos.ts deleted file mode 100644 index fb758cf29..000000000 --- a/server/tests/utils/videos.ts +++ /dev/null @@ -1,327 +0,0 @@ -import { readFile } from 'fs' -import * as request from 'supertest' -import { join, isAbsolute } from 'path' -import * as parseTorrent from 'parse-torrent' - -import { makeGetRequest } from './requests' -import { readFilePromise } from './miscs' -import { ServerInfo } from './servers' -import { getMyUserInformation } from './users' -import { VideoPrivacy } from '../../../shared' - -type VideoAttributes = { - name?: string - category?: number - licence?: number - language?: number - nsfw?: boolean - description?: string - tags?: string[] - channelId?: number - privacy?: VideoPrivacy - fixture?: string -} - -function getVideoCategories (url: string) { - const path = '/api/v1/videos/categories' - - return makeGetRequest(url, path) -} - -function getVideoLicences (url: string) { - const path = '/api/v1/videos/licences' - - return makeGetRequest(url, path) -} - -function getVideoLanguages (url: string) { - const path = '/api/v1/videos/languages' - - return makeGetRequest(url, path) -} - -function getVideoPrivacies (url: string) { - const path = '/api/v1/videos/privacies' - - return makeGetRequest(url, path) -} - -function getVideo (url: string, id: number | string, expectedStatus = 200) { - const path = '/api/v1/videos/' + id - - return request(url) - .get(path) - .set('Accept', 'application/json') - .expect(expectedStatus) -} - -function viewVideo (url: string, id: number | string, expectedStatus = 204) { - const path = '/api/v1/videos/' + id + '/views' - - return request(url) - .post(path) - .set('Accept', 'application/json') - .expect(expectedStatus) -} - -function getVideoWithToken (url: string, token: string, id: number | string, expectedStatus = 200) { - const path = '/api/v1/videos/' + id - - return request(url) - .get(path) - .set('Authorization', 'Bearer ' + token) - .set('Accept', 'application/json') - .expect(expectedStatus) -} - -function getVideoDescription (url: string, descriptionPath: string) { - return request(url) - .get(descriptionPath) - .set('Accept', 'application/json') - .expect(200) - .expect('Content-Type', /json/) -} - -function getVideosList (url: string) { - const path = '/api/v1/videos' - - return request(url) - .get(path) - .query({ sort: 'name' }) - .set('Accept', 'application/json') - .expect(200) - .expect('Content-Type', /json/) -} - -function getMyVideos (url: string, accessToken: string, start: number, count: number, sort?: string) { - const path = '/api/v1/users/me/videos' - - const req = request(url) - .get(path) - .query({ start: start }) - .query({ count: count }) - - if (sort) req.query({ sort }) - - return req.set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + accessToken) - .expect(200) - .expect('Content-Type', /json/) -} - -function getVideosListPagination (url: string, start: number, count: number, sort?: string) { - const path = '/api/v1/videos' - - const req = request(url) - .get(path) - .query({ start: start }) - .query({ count: count }) - - if (sort) req.query({ sort }) - - return req.set('Accept', 'application/json') - .expect(200) - .expect('Content-Type', /json/) -} - -function getVideosListSort (url: string, sort: string) { - const path = '/api/v1/videos' - - return request(url) - .get(path) - .query({ sort: sort }) - .set('Accept', 'application/json') - .expect(200) - .expect('Content-Type', /json/) -} - -function removeVideo (url: string, token: string, id: number, expectedStatus = 204) { - const path = '/api/v1/videos' - - return request(url) - .delete(path + '/' + id) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + token) - .expect(expectedStatus) -} - -function searchVideo (url: string, search: string) { - const path = '/api/v1/videos' - const req = request(url) - .get(path + '/search') - .query({ search }) - .set('Accept', 'application/json') - - return req.expect(200) - .expect('Content-Type', /json/) -} - -function searchVideoWithPagination (url: string, search: string, start: number, count: number, sort?: string) { - const path = '/api/v1/videos' - - const req = request(url) - .get(path + '/search') - .query({ start }) - .query({ search }) - .query({ count }) - - if (sort) req.query({ sort }) - - return req.set('Accept', 'application/json') - .expect(200) - .expect('Content-Type', /json/) -} - -function searchVideoWithSort (url: string, search: string, sort: string) { - const path = '/api/v1/videos' - - return request(url) - .get(path + '/search') - .query({ search }) - .query({ sort }) - .set('Accept', 'application/json') - .expect(200) - .expect('Content-Type', /json/) -} - -async function testVideoImage (url: string, imageName: string, imagePath: string) { - // Don't test images if the node env is not set - // Because we need a special ffmpeg version for this test - if (process.env['NODE_TEST_IMAGE']) { - const res = await request(url) - .get(imagePath) - .expect(200) - - const data = await readFilePromise(join(__dirname, '..', 'api', 'fixtures', imageName + '.jpg')) - - return data.equals(res.body) - } else { - console.log('Do not test images. Enable it by setting NODE_TEST_IMAGE env variable.') - return true - } -} - -async function uploadVideo (url: string, accessToken: string, videoAttributesArg: VideoAttributes, specialStatus = 200) { - const path = '/api/v1/videos/upload' - let defaultChannelId = '1' - - try { - const res = await getMyUserInformation(url, accessToken) - defaultChannelId = res.body.videoChannels[0].id - } catch (e) { /* empty */ } - - // Default attributes - let attributes = { - name: 'my super video', - category: 5, - licence: 4, - language: 3, - channelId: defaultChannelId, - nsfw: true, - description: 'my super description', - tags: [ 'tag' ], - privacy: VideoPrivacy.PUBLIC, - fixture: 'video_short.webm' - } - attributes = Object.assign(attributes, videoAttributesArg) - - const req = request(url) - .post(path) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + accessToken) - .field('name', attributes.name) - .field('category', attributes.category.toString()) - .field('licence', attributes.licence.toString()) - .field('nsfw', JSON.stringify(attributes.nsfw)) - .field('description', attributes.description) - .field('privacy', attributes.privacy.toString()) - .field('channelId', attributes.channelId) - - if (attributes.language !== undefined) { - req.field('language', attributes.language.toString()) - } - - for (let i = 0; i < attributes.tags.length; i++) { - req.field('tags[' + i + ']', attributes.tags[i]) - } - - let filePath = '' - if (isAbsolute(attributes.fixture)) { - filePath = attributes.fixture - } else { - filePath = join(__dirname, '..', 'api', 'fixtures', attributes.fixture) - } - - return req.attach('videofile', filePath) - .expect(specialStatus) -} - -function updateVideo (url: string, accessToken: string, id: number, attributes: VideoAttributes, specialStatus = 204) { - const path = '/api/v1/videos/' + id - const body = {} - - if (attributes.name) body['name'] = attributes.name - if (attributes.category) body['category'] = attributes.category - if (attributes.licence) body['licence'] = attributes.licence - if (attributes.language) body['language'] = attributes.language - if (attributes.nsfw) body['nsfw'] = attributes.nsfw - if (attributes.description) body['description'] = attributes.description - if (attributes.tags) body['tags'] = attributes.tags - if (attributes.privacy) body['privacy'] = attributes.privacy - - return request(url) - .put(path) - .send(body) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + accessToken) - .expect(specialStatus) -} - -function rateVideo (url: string, accessToken: string, id: number, rating: string, specialStatus = 204) { - const path = '/api/v1/videos/' + id + '/rate' - - return request(url) - .put(path) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + accessToken) - .send({ rating }) - .expect(specialStatus) -} - -function parseTorrentVideo (server: ServerInfo, videoUUID: string, resolution: number) { - return new Promise((res, rej) => { - const torrentName = videoUUID + '-' + resolution + '.torrent' - const torrentPath = join(__dirname, '..', '..', '..', 'test' + server.serverNumber, 'torrents', torrentName) - readFile(torrentPath, (err, data) => { - if (err) return rej(err) - - return res(parseTorrent(data)) - }) - }) -} - -// --------------------------------------------------------------------------- - -export { - getVideoDescription, - getVideoCategories, - getVideoLicences, - getVideoPrivacies, - getVideoLanguages, - getMyVideos, - getVideo, - getVideoWithToken, - getVideosList, - getVideosListPagination, - getVideosListSort, - removeVideo, - searchVideo, - searchVideoWithPagination, - searchVideoWithSort, - testVideoImage, - uploadVideo, - updateVideo, - rateVideo, - viewVideo, - parseTorrentVideo -} diff --git a/server/tests/utils/videos/services.ts b/server/tests/utils/videos/services.ts new file mode 100644 index 000000000..1a53dd4cf --- /dev/null +++ b/server/tests/utils/videos/services.ts @@ -0,0 +1,23 @@ +import * as request from 'supertest' + +function getOEmbed (url: string, oembedUrl: string, format?: string, maxHeight?: number, maxWidth?: number) { + const path = '/services/oembed' + const query = { + url: oembedUrl, + format, + maxheight: maxHeight, + maxwidth: maxWidth + } + + return request(url) + .get(path) + .query(query) + .set('Accept', 'application/json') + .expect(200) +} + +// --------------------------------------------------------------------------- + +export { + getOEmbed +} diff --git a/server/tests/utils/videos/video-abuses.ts b/server/tests/utils/videos/video-abuses.ts new file mode 100644 index 000000000..f00809234 --- /dev/null +++ b/server/tests/utils/videos/video-abuses.ts @@ -0,0 +1,31 @@ +import * as request from 'supertest' + +function reportVideoAbuse (url: string, token: string, videoId: number, reason: string, specialStatus = 204) { + const path = '/api/v1/videos/' + videoId + '/abuse' + + return request(url) + .post(path) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + token) + .send({ reason }) + .expect(specialStatus) +} + +function getVideoAbusesList (url: string, token: string) { + const path = '/api/v1/videos/abuse' + + return request(url) + .get(path) + .query({ sort: 'createdAt' }) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + token) + .expect(200) + .expect('Content-Type', /json/) +} + +// --------------------------------------------------------------------------- + +export { + reportVideoAbuse, + getVideoAbusesList +} diff --git a/server/tests/utils/videos/video-blacklist.ts b/server/tests/utils/videos/video-blacklist.ts new file mode 100644 index 000000000..3a499f46a --- /dev/null +++ b/server/tests/utils/videos/video-blacklist.ts @@ -0,0 +1,54 @@ +import * as request from 'supertest' + +function addVideoToBlacklist (url: string, token: string, videoId: number, specialStatus = 204) { + const path = '/api/v1/videos/' + videoId + '/blacklist' + + return request(url) + .post(path) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + token) + .expect(specialStatus) +} + +function removeVideoFromBlacklist (url: string, token: string, videoId: number, specialStatus = 204) { + const path = '/api/v1/videos/' + videoId + '/blacklist' + + return request(url) + .delete(path) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + token) + .expect(specialStatus) +} + +function getBlacklistedVideosList (url: string, token: string, specialStatus = 200) { + const path = '/api/v1/videos/blacklist/' + + return request(url) + .get(path) + .query({ sort: 'createdAt' }) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + token) + .expect(specialStatus) + .expect('Content-Type', /json/) +} + +function getSortedBlacklistedVideosList (url: string, token: string, sort: string, specialStatus = 200) { + const path = '/api/v1/videos/blacklist/' + + return request(url) + .get(path) + .query({ sort: sort }) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + token) + .expect(specialStatus) + .expect('Content-Type', /json/) +} + +// --------------------------------------------------------------------------- + +export { + addVideoToBlacklist, + removeVideoFromBlacklist, + getBlacklistedVideosList, + getSortedBlacklistedVideosList +} diff --git a/server/tests/utils/videos/video-channels.ts b/server/tests/utils/videos/video-channels.ts new file mode 100644 index 000000000..0fb80d331 --- /dev/null +++ b/server/tests/utils/videos/video-channels.ts @@ -0,0 +1,95 @@ +import * as request from 'supertest' + +type VideoChannelAttributes = { + name?: string + description?: string +} + +function getVideoChannelsList (url: string, start: number, count: number, sort?: string) { + const path = '/api/v1/videos/channels' + + const req = request(url) + .get(path) + .query({ start: start }) + .query({ count: count }) + + if (sort) req.query({ sort }) + + return req.set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) +} + +function getAccountVideoChannelsList (url: string, accountId: number | string) { + const path = '/api/v1/videos/accounts/' + accountId + '/channels' + + return request(url) + .get(path) + .set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) +} + +function addVideoChannel (url: string, token: string, videoChannelAttributesArg: VideoChannelAttributes, expectedStatus = 204) { + const path = '/api/v1/videos/channels' + + // Default attributes + let attributes = { + name: 'my super video channel', + description: 'my super channel description' + } + attributes = Object.assign(attributes, videoChannelAttributesArg) + + return request(url) + .post(path) + .send(attributes) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + token) + .expect(expectedStatus) +} + +function updateVideoChannel (url: string, token: string, channelId: number, attributes: VideoChannelAttributes, expectedStatus = 204) { + const body = {} + const path = '/api/v1/videos/channels/' + channelId + + if (attributes.name) body['name'] = attributes.name + if (attributes.description) body['description'] = attributes.description + + return request(url) + .put(path) + .send(body) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + token) + .expect(expectedStatus) +} + +function deleteVideoChannel (url: string, token: string, channelId: number, expectedStatus = 204) { + const path = '/api/v1/videos/channels/' + + return request(url) + .delete(path + channelId) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + token) + .expect(expectedStatus) +} + +function getVideoChannel (url: string, channelId: number) { + const path = '/api/v1/videos/channels/' + channelId + + return request(url) + .get(path) + .set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) +} + +// --------------------------------------------------------------------------- + +export { + getVideoChannelsList, + getAccountVideoChannelsList, + addVideoChannel, + updateVideoChannel, + deleteVideoChannel, + getVideoChannel +} diff --git a/server/tests/utils/videos/video-comments.ts b/server/tests/utils/videos/video-comments.ts new file mode 100644 index 000000000..878147049 --- /dev/null +++ b/server/tests/utils/videos/video-comments.ts @@ -0,0 +1,64 @@ +import * as request from 'supertest' + +function getVideoCommentThreads (url: string, videoId: number | string, start: number, count: number, sort?: string) { + const path = '/api/v1/videos/' + videoId + '/comment-threads' + + const req = request(url) + .get(path) + .query({ start: start }) + .query({ count: count }) + + if (sort) req.query({ sort }) + + return req.set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) +} + +function getVideoThreadComments (url: string, videoId: number | string, threadId: number) { + const path = '/api/v1/videos/' + videoId + '/comment-threads/' + threadId + + return request(url) + .get(path) + .set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) +} + +function addVideoCommentThread (url: string, token: string, videoId: number | string, text: string, expectedStatus = 200) { + const path = '/api/v1/videos/' + videoId + '/comment-threads' + + return request(url) + .post(path) + .send({ text }) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + token) + .expect(expectedStatus) +} + +function addVideoCommentReply ( + url: string, + token: string, + videoId: number | string, + inReplyToCommentId: number, + text: string, + expectedStatus = 200 +) { + const path = '/api/v1/videos/' + videoId + '/comments/' + inReplyToCommentId + + return request(url) + .post(path) + .send({ text }) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + token) + .expect(expectedStatus) +} + +// --------------------------------------------------------------------------- + +export { + getVideoCommentThreads, + getVideoThreadComments, + addVideoCommentThread, + addVideoCommentReply +} diff --git a/server/tests/utils/videos/videos.ts b/server/tests/utils/videos/videos.ts new file mode 100644 index 000000000..6de1b8c92 --- /dev/null +++ b/server/tests/utils/videos/videos.ts @@ -0,0 +1,323 @@ +import { readFile } from 'fs' +import * as parseTorrent from 'parse-torrent' +import { isAbsolute, join } from 'path' +import * as request from 'supertest' +import { getMyUserInformation, makeGetRequest, readFilePromise, ServerInfo } from '../' +import { VideoPrivacy } from '../../../../shared/models/videos' + +type VideoAttributes = { + name?: string + category?: number + licence?: number + language?: number + nsfw?: boolean + description?: string + tags?: string[] + channelId?: number + privacy?: VideoPrivacy + fixture?: string +} + +function getVideoCategories (url: string) { + const path = '/api/v1/videos/categories' + + return makeGetRequest(url, path) +} + +function getVideoLicences (url: string) { + const path = '/api/v1/videos/licences' + + return makeGetRequest(url, path) +} + +function getVideoLanguages (url: string) { + const path = '/api/v1/videos/languages' + + return makeGetRequest(url, path) +} + +function getVideoPrivacies (url: string) { + const path = '/api/v1/videos/privacies' + + return makeGetRequest(url, path) +} + +function getVideo (url: string, id: number | string, expectedStatus = 200) { + const path = '/api/v1/videos/' + id + + return request(url) + .get(path) + .set('Accept', 'application/json') + .expect(expectedStatus) +} + +function viewVideo (url: string, id: number | string, expectedStatus = 204) { + const path = '/api/v1/videos/' + id + '/views' + + return request(url) + .post(path) + .set('Accept', 'application/json') + .expect(expectedStatus) +} + +function getVideoWithToken (url: string, token: string, id: number | string, expectedStatus = 200) { + const path = '/api/v1/videos/' + id + + return request(url) + .get(path) + .set('Authorization', 'Bearer ' + token) + .set('Accept', 'application/json') + .expect(expectedStatus) +} + +function getVideoDescription (url: string, descriptionPath: string) { + return request(url) + .get(descriptionPath) + .set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) +} + +function getVideosList (url: string) { + const path = '/api/v1/videos' + + return request(url) + .get(path) + .query({ sort: 'name' }) + .set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) +} + +function getMyVideos (url: string, accessToken: string, start: number, count: number, sort?: string) { + const path = '/api/v1/users/me/videos' + + const req = request(url) + .get(path) + .query({ start: start }) + .query({ count: count }) + + if (sort) req.query({ sort }) + + return req.set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + accessToken) + .expect(200) + .expect('Content-Type', /json/) +} + +function getVideosListPagination (url: string, start: number, count: number, sort?: string) { + const path = '/api/v1/videos' + + const req = request(url) + .get(path) + .query({ start: start }) + .query({ count: count }) + + if (sort) req.query({ sort }) + + return req.set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) +} + +function getVideosListSort (url: string, sort: string) { + const path = '/api/v1/videos' + + return request(url) + .get(path) + .query({ sort: sort }) + .set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) +} + +function removeVideo (url: string, token: string, id: number, expectedStatus = 204) { + const path = '/api/v1/videos' + + return request(url) + .delete(path + '/' + id) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + token) + .expect(expectedStatus) +} + +function searchVideo (url: string, search: string) { + const path = '/api/v1/videos' + const req = request(url) + .get(path + '/search') + .query({ search }) + .set('Accept', 'application/json') + + return req.expect(200) + .expect('Content-Type', /json/) +} + +function searchVideoWithPagination (url: string, search: string, start: number, count: number, sort?: string) { + const path = '/api/v1/videos' + + const req = request(url) + .get(path + '/search') + .query({ start }) + .query({ search }) + .query({ count }) + + if (sort) req.query({ sort }) + + return req.set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) +} + +function searchVideoWithSort (url: string, search: string, sort: string) { + const path = '/api/v1/videos' + + return request(url) + .get(path + '/search') + .query({ search }) + .query({ sort }) + .set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) +} + +async function testVideoImage (url: string, imageName: string, imagePath: string) { + // Don't test images if the node env is not set + // Because we need a special ffmpeg version for this test + if (process.env['NODE_TEST_IMAGE']) { + const res = await request(url) + .get(imagePath) + .expect(200) + + const data = await readFilePromise(join(__dirname, '..', 'api', 'fixtures', imageName + '.jpg')) + + return data.equals(res.body) + } else { + console.log('Do not test images. Enable it by setting NODE_TEST_IMAGE env variable.') + return true + } +} + +async function uploadVideo (url: string, accessToken: string, videoAttributesArg: VideoAttributes, specialStatus = 200) { + const path = '/api/v1/videos/upload' + let defaultChannelId = '1' + + try { + const res = await getMyUserInformation(url, accessToken) + defaultChannelId = res.body.videoChannels[0].id + } catch (e) { /* empty */ } + + // Default attributes + let attributes = { + name: 'my super video', + category: 5, + licence: 4, + language: 3, + channelId: defaultChannelId, + nsfw: true, + description: 'my super description', + tags: [ 'tag' ], + privacy: VideoPrivacy.PUBLIC, + fixture: 'video_short.webm' + } + attributes = Object.assign(attributes, videoAttributesArg) + + const req = request(url) + .post(path) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + accessToken) + .field('name', attributes.name) + .field('category', attributes.category.toString()) + .field('licence', attributes.licence.toString()) + .field('nsfw', JSON.stringify(attributes.nsfw)) + .field('description', attributes.description) + .field('privacy', attributes.privacy.toString()) + .field('channelId', attributes.channelId) + + if (attributes.language !== undefined) { + req.field('language', attributes.language.toString()) + } + + for (let i = 0; i < attributes.tags.length; i++) { + req.field('tags[' + i + ']', attributes.tags[i]) + } + + let filePath = '' + if (isAbsolute(attributes.fixture)) { + filePath = attributes.fixture + } else { + filePath = join(__dirname, '..', 'api', 'fixtures', attributes.fixture) + } + + return req.attach('videofile', filePath) + .expect(specialStatus) +} + +function updateVideo (url: string, accessToken: string, id: number, attributes: VideoAttributes, specialStatus = 204) { + const path = '/api/v1/videos/' + id + const body = {} + + if (attributes.name) body['name'] = attributes.name + if (attributes.category) body['category'] = attributes.category + if (attributes.licence) body['licence'] = attributes.licence + if (attributes.language) body['language'] = attributes.language + if (attributes.nsfw) body['nsfw'] = attributes.nsfw + if (attributes.description) body['description'] = attributes.description + if (attributes.tags) body['tags'] = attributes.tags + if (attributes.privacy) body['privacy'] = attributes.privacy + + return request(url) + .put(path) + .send(body) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + accessToken) + .expect(specialStatus) +} + +function rateVideo (url: string, accessToken: string, id: number, rating: string, specialStatus = 204) { + const path = '/api/v1/videos/' + id + '/rate' + + return request(url) + .put(path) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + accessToken) + .send({ rating }) + .expect(specialStatus) +} + +function parseTorrentVideo (server: ServerInfo, videoUUID: string, resolution: number) { + return new Promise((res, rej) => { + const torrentName = videoUUID + '-' + resolution + '.torrent' + const torrentPath = join(__dirname, '..', '..', '..', 'test' + server.serverNumber, 'torrents', torrentName) + readFile(torrentPath, (err, data) => { + if (err) return rej(err) + + return res(parseTorrent(data)) + }) + }) +} + +// --------------------------------------------------------------------------- + +export { + getVideoDescription, + getVideoCategories, + getVideoLicences, + getVideoPrivacies, + getVideoLanguages, + getMyVideos, + getVideo, + getVideoWithToken, + getVideosList, + getVideosListPagination, + getVideosListSort, + removeVideo, + searchVideo, + searchVideoWithPagination, + searchVideoWithSort, + testVideoImage, + uploadVideo, + updateVideo, + rateVideo, + viewVideo, + parseTorrentVideo +}