import * as chai from 'chai'
import 'mocha'
-import { flushTests, killallServers, makeActivityPubGetRequest, runServer, ServerInfo, setAccessTokensToServers } from './utils'
+import {
+ flushTests,
+ killallServers,
+ makeActivityPubGetRequest,
+ runServer,
+ ServerInfo,
+ setAccessTokensToServers
+} from '../../shared/utils'
const expect = chai.expect
import 'mocha'
-import { flushTests, killallServers, runServer, ServerInfo } from '../../utils'
-import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params'
-import { getAccount } from '../../utils/users/accounts'
+import { flushTests, killallServers, runServer, ServerInfo } from '../../../../shared/utils'
+import {
+ checkBadCountPagination,
+ checkBadSortPagination,
+ checkBadStartPagination
+} from '../../../../shared/utils/requests/check-api-params'
+import { getAccount } from '../../../../shared/utils/users/accounts'
describe('Test users API validators', function () {
const path = '/api/v1/accounts/'
makePostBodyRequest,
ServerInfo,
setAccessTokensToServers, userLogin
-} from '../../utils'
-import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params'
+} from '../../../../shared/utils'
+import {
+ checkBadCountPagination,
+ checkBadSortPagination,
+ checkBadStartPagination
+} from '../../../../shared/utils/requests/check-api-params'
describe('Test blocklist API validators', function () {
let servers: ServerInfo[]
import {
createUser, flushTests, killallServers, makeDeleteRequest, makeGetRequest, makePutBodyRequest, runServer, ServerInfo,
setAccessTokensToServers, userLogin, immutableAssign
-} from '../../utils'
+} from '../../../../shared/utils'
describe('Test config API validators', function () {
const path = '/api/v1/config/custom'
import {
createUser, flushTests, killallServers, makeDeleteRequest, makePostBodyRequest, runServer, ServerInfo, setAccessTokensToServers,
userLogin
-} from '../../utils'
-import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params'
+} from '../../../../shared/utils'
+import {
+ checkBadCountPagination,
+ checkBadSortPagination,
+ checkBadStartPagination
+} from '../../../../shared/utils/requests/check-api-params'
describe('Test server follows API validators', function () {
let server: ServerInfo
import 'mocha'
-import { createUser, flushTests, killallServers, runServer, ServerInfo, setAccessTokensToServers, userLogin } from '../../utils'
-import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params'
-import { makeGetRequest } from '../../utils/requests/requests'
+import {
+ createUser,
+ flushTests,
+ killallServers,
+ runServer,
+ ServerInfo,
+ setAccessTokensToServers,
+ userLogin
+} from '../../../../shared/utils'
+import {
+ checkBadCountPagination,
+ checkBadSortPagination,
+ checkBadStartPagination
+} from '../../../../shared/utils/requests/check-api-params'
+import { makeGetRequest } from '../../../../shared/utils/requests/requests'
describe('Test jobs API validators', function () {
const path = '/api/v1/jobs/failed'
ServerInfo,
setAccessTokensToServers,
userLogin
-} from '../../utils'
+} from '../../../../shared/utils'
describe('Test server redundancy API validators', function () {
let servers: ServerInfo[]
import 'mocha'
-import { flushTests, immutableAssign, killallServers, makeGetRequest, runServer, ServerInfo } from '../../utils'
-import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params'
+import { flushTests, immutableAssign, killallServers, makeGetRequest, runServer, ServerInfo } from '../../../../shared/utils'
+import {
+ checkBadCountPagination,
+ checkBadSortPagination,
+ checkBadStartPagination
+} from '../../../../shared/utils/requests/check-api-params'
describe('Test videos API validator', function () {
let server: ServerInfo
import 'mocha'
-import { flushTests, killallServers, makeGetRequest, runServer, ServerInfo, setAccessTokensToServers, uploadVideo } from '../../utils'
+import {
+ flushTests,
+ killallServers,
+ makeGetRequest,
+ runServer,
+ ServerInfo,
+ setAccessTokensToServers,
+ uploadVideo
+} from '../../../../shared/utils'
describe('Test services API validators', function () {
let server: ServerInfo
ServerInfo,
setAccessTokensToServers,
userLogin
-} from '../../utils'
-import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params'
+} from '../../../../shared/utils'
+import {
+ checkBadCountPagination,
+ checkBadSortPagination,
+ checkBadStartPagination
+} from '../../../../shared/utils/requests/check-api-params'
describe('Test user subscriptions API validators', function () {
const path = '/api/v1/users/me/subscriptions'
createUser, flushTests, getMyUserInformation, getMyUserVideoRating, getUsersList, immutableAssign, killallServers, makeGetRequest,
makePostBodyRequest, makeUploadRequest, makePutBodyRequest, registerUser, removeUser, runServer, ServerInfo, setAccessTokensToServers,
updateUser, uploadVideo, userLogin, deleteMe, unblockUser, blockUser
-} from '../../utils'
-import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params'
-import { getMagnetURI, getMyVideoImports, getYoutubeVideoUrl, importVideo } from '../../utils/videos/video-imports'
+} from '../../../../shared/utils'
+import {
+ checkBadCountPagination,
+ checkBadSortPagination,
+ checkBadStartPagination
+} from '../../../../shared/utils/requests/check-api-params'
+import { getMagnetURI, getMyVideoImports, getYoutubeVideoUrl, importVideo } from '../../../../shared/utils/videos/video-imports'
import { VideoPrivacy } from '../../../../shared/models/videos'
-import { waitJobs } from '../../utils/server/jobs'
+import { waitJobs } from '../../../../shared/utils/server/jobs'
import { expect } from 'chai'
describe('Test users API validators', function () {
updateVideoAbuse,
uploadVideo,
userLogin
-} from '../../utils'
-import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params'
+} from '../../../../shared/utils'
+import {
+ checkBadCountPagination,
+ checkBadSortPagination,
+ checkBadStartPagination
+} from '../../../../shared/utils/requests/check-api-params'
import { VideoAbuseState } from '../../../../shared/models/videos'
describe('Test video abuses API validators', function () {
setAccessTokensToServers,
uploadVideo,
userLogin
-} from '../../utils'
-import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params'
+} from '../../../../shared/utils'
+import {
+ checkBadCountPagination,
+ checkBadSortPagination,
+ checkBadStartPagination
+} from '../../../../shared/utils/requests/check-api-params'
import { VideoDetails } from '../../../../shared/models/videos'
import { expect } from 'chai'
setAccessTokensToServers,
uploadVideo,
userLogin
-} from '../../utils'
+} from '../../../../shared/utils'
import { join } from 'path'
-import { createVideoCaption } from '../../utils/videos/video-captions'
+import { createVideoCaption } from '../../../../shared/utils/videos/video-captions'
describe('Test video captions API validator', function () {
const path = '/api/v1/videos/'
ServerInfo,
setAccessTokensToServers,
userLogin
-} from '../../utils'
-import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params'
+} from '../../../../shared/utils'
+import {
+ checkBadCountPagination,
+ checkBadSortPagination,
+ checkBadStartPagination
+} from '../../../../shared/utils/requests/check-api-params'
import { User } from '../../../../shared/models/users'
import { join } from 'path'
createUser,
flushTests, killallServers, makeDeleteRequest, makeGetRequest, makePostBodyRequest, runServer, ServerInfo, setAccessTokensToServers,
uploadVideo, userLogin
-} from '../../utils'
-import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params'
-import { addVideoCommentThread } from '../../utils/videos/video-comments'
+} from '../../../../shared/utils'
+import {
+ checkBadCountPagination,
+ checkBadSortPagination,
+ checkBadStartPagination
+} from '../../../../shared/utils/requests/check-api-params'
+import { addVideoCommentThread } from '../../../../shared/utils/videos/video-comments'
const expect = chai.expect
setAccessTokensToServers,
updateCustomSubConfig,
userLogin
-} from '../../utils'
-import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params'
-import { getMagnetURI, getYoutubeVideoUrl } from '../../utils/videos/video-imports'
+} from '../../../../shared/utils'
+import {
+ checkBadCountPagination,
+ checkBadSortPagination,
+ checkBadStartPagination
+} from '../../../../shared/utils/requests/check-api-params'
+import { getMagnetURI, getYoutubeVideoUrl } from '../../../../shared/utils/videos/video-imports'
describe('Test video imports API validator', function () {
const path = '/api/v1/videos/imports'
ServerInfo,
setAccessTokensToServers,
userLogin
-} from '../../utils'
+} from '../../../../shared/utils'
import { UserRole } from '../../../../shared/models/users'
const expect = chai.expect
ServerInfo,
setAccessTokensToServers,
uploadVideo
-} from '../../utils'
+} from '../../../../shared/utils'
const expect = chai.expect
import {
createUser, flushTests, getMyUserInformation, getVideo, getVideosList, immutableAssign, killallServers, makeDeleteRequest,
makeGetRequest, makeUploadRequest, makePutBodyRequest, removeVideo, runServer, ServerInfo, setAccessTokensToServers, userLogin
-} from '../../utils'
-import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params'
-import { getAccountsList } from '../../utils/users/accounts'
+} from '../../../../shared/utils'
+import {
+ checkBadCountPagination,
+ checkBadSortPagination,
+ checkBadStartPagination
+} from '../../../../shared/utils/requests/check-api-params'
+import { getAccountsList } from '../../../../shared/utils/users/accounts'
const expect = chai.expect
wait,
waitUntilLog,
checkVideoFilesWereRemoved, removeVideo
-} from '../../utils'
-import { waitJobs } from '../../utils/server/jobs'
+} from '../../../../shared/utils'
+import { waitJobs } from '../../../../shared/utils/server/jobs'
import * as magnetUtil from 'magnet-uri'
-import { updateRedundancy } from '../../utils/server/redundancy'
+import { updateRedundancy } from '../../../../shared/utils/server/redundancy'
import { ActorFollow } from '../../../../shared/models/actors'
import { readdir } from 'fs-extra'
import { join } from 'path'
import { VideoRedundancyStrategy } from '../../../../shared/models/redundancy'
-import { getStats } from '../../utils/server/stats'
+import { getStats } from '../../../../shared/utils/server/stats'
import { ServerStats } from '../../../../shared/models/server/server-stats.model'
const expect = chai.expect
uploadVideo,
userLogin,
wait
-} from '../../utils'
-import { waitJobs } from '../../utils/server/jobs'
+} from '../../../../shared/utils'
+import { waitJobs } from '../../../../shared/utils/server/jobs'
import { VideoChannel } from '../../../../shared/models/videos'
-import { searchVideoChannel } from '../../utils/search/video-channels'
+import { searchVideoChannel } from '../../../../shared/utils/search/video-channels'
const expect = chai.expect
uploadVideo,
wait,
searchVideo
-} from '../../utils'
-import { waitJobs } from '../../utils/server/jobs'
+} from '../../../../shared/utils'
+import { waitJobs } from '../../../../shared/utils/server/jobs'
import { Video, VideoPrivacy } from '../../../../shared/models/videos'
const expect = chai.expect
uploadVideo,
wait,
immutableAssign
-} from '../../utils'
+} from '../../../../shared/utils'
const expect = chai.expect
import * as chai from 'chai'
import { About } from '../../../../shared/models/server/about.model'
import { CustomConfig } from '../../../../shared/models/server/custom-config.model'
-import { deleteCustomConfig, getAbout, killallServers, reRunServer } from '../../utils'
import {
+ deleteCustomConfig,
+ getAbout,
+ killallServers,
+ reRunServer,
flushTests,
getConfig,
getCustomConfig,
runServer,
setAccessTokensToServers,
updateCustomConfig
-} from '../../utils/index'
+} from '../../../../shared/utils'
const expect = chai.expect
unblockUser,
uploadVideo,
userLogin,
- verifyEmail
-} from '../../utils'
-import { flushTests, killallServers, ServerInfo, setAccessTokensToServers } from '../../utils/index'
-import { mockSmtpServer } from '../../utils/miscs/email'
-import { waitJobs } from '../../utils/server/jobs'
+ verifyEmail,
+ flushTests,
+ killallServers,
+ ServerInfo,
+ setAccessTokensToServers
+} from '../../../../shared/utils'
+import { mockSmtpServer } from '../../../../shared/utils/miscs/email'
+import { waitJobs } from '../../../../shared/utils/server/jobs'
const expect = chai.expect
import 'mocha'
import { Video, VideoPrivacy } from '../../../../shared/models/videos'
import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model'
-import { completeVideoCheck } from '../../utils'
+import { completeVideoCheck } from '../../../../shared/utils'
import {
flushAndRunMultipleServers,
getVideosList,
ServerInfo,
setAccessTokensToServers,
uploadVideo
-} from '../../utils/index'
-import { dateIsValid } from '../../utils/miscs/miscs'
-import { follow, getFollowersListPaginationAndSort, getFollowingListPaginationAndSort, unfollow } from '../../utils/server/follows'
-import { expectAccountFollows } from '../../utils/users/accounts'
-import { userLogin } from '../../utils/users/login'
-import { createUser } from '../../utils/users/users'
+} from '../../../../shared/utils/index'
+import { dateIsValid } from '../../../../shared/utils/miscs/miscs'
+import {
+ follow,
+ getFollowersListPaginationAndSort,
+ getFollowingListPaginationAndSort,
+ unfollow
+} from '../../../../shared/utils/server/follows'
+import { expectAccountFollows } from '../../../../shared/utils/users/accounts'
+import { userLogin } from '../../../../shared/utils/users/login'
+import { createUser } from '../../../../shared/utils/users/users'
import {
addVideoCommentReply,
addVideoCommentThread,
getVideoCommentThreads,
getVideoThreadComments
-} from '../../utils/videos/video-comments'
-import { rateVideo } from '../../utils/videos/videos'
-import { waitJobs } from '../../utils/server/jobs'
-import { createVideoCaption, listVideoCaptions, testCaptionFile } from '../../utils/videos/video-captions'
+} from '../../../../shared/utils/videos/video-comments'
+import { rateVideo } from '../../../../shared/utils/videos/videos'
+import { waitJobs } from '../../../../shared/utils/server/jobs'
+import { createVideoCaption, listVideoCaptions, testCaptionFile } from '../../../../shared/utils/videos/video-captions'
import { VideoCaption } from '../../../../shared/models/videos/caption/video-caption.model'
const expect = chai.expect
import { JobState, Video } from '../../../../shared/models'
import { VideoPrivacy } from '../../../../shared/models/videos'
import { VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model'
-import { completeVideoCheck, getVideo, immutableAssign, reRunServer, unfollow, viewVideo } from '../../utils'
import {
+ completeVideoCheck,
+ getVideo,
+ immutableAssign,
+ reRunServer,
+ unfollow,
+ viewVideo,
flushAndRunMultipleServers,
getVideosList,
killallServers,
setAccessTokensToServers,
uploadVideo,
wait
-} from '../../utils/index'
-import { follow, getFollowersListPaginationAndSort } from '../../utils/server/follows'
-import { getJobsListPaginationAndSort, waitJobs } from '../../utils/server/jobs'
+} from '../../../../shared/utils'
+import { follow, getFollowersListPaginationAndSort } from '../../../../shared/utils/server/follows'
+import { getJobsListPaginationAndSort, waitJobs } from '../../../../shared/utils/server/jobs'
import {
addVideoCommentReply,
addVideoCommentThread,
getVideoCommentThreads,
getVideoThreadComments
-} from '../../utils/videos/video-comments'
+} from '../../../../shared/utils/videos/video-comments'
const expect = chai.expect
import * as chai from 'chai'
import 'mocha'
-import { killallServers, ServerInfo, setAccessTokensToServers } from '../../utils/index'
-import { doubleFollow } from '../../utils/server/follows'
-import { getJobsList, getJobsListPaginationAndSort, waitJobs } from '../../utils/server/jobs'
-import { flushAndRunMultipleServers } from '../../utils/server/servers'
-import { uploadVideo } from '../../utils/videos/videos'
-import { dateIsValid } from '../../utils/miscs/miscs'
+import { killallServers, ServerInfo, setAccessTokensToServers } from '../../../../shared/utils/index'
+import { doubleFollow } from '../../../../shared/utils/server/follows'
+import { getJobsList, getJobsListPaginationAndSort, waitJobs } from '../../../../shared/utils/server/jobs'
+import { flushAndRunMultipleServers } from '../../../../shared/utils/server/servers'
+import { uploadVideo } from '../../../../shared/utils/videos/videos'
+import { dateIsValid } from '../../../../shared/utils/miscs/miscs'
const expect = chai.expect
wait,
waitUntilLog,
checkVideoFilesWereRemoved, removeVideo
-} from '../../utils'
-import { waitJobs } from '../../utils/server/jobs'
+} from '../../../../shared/utils'
+import { waitJobs } from '../../../../shared/utils/server/jobs'
import * as magnetUtil from 'magnet-uri'
-import { updateRedundancy } from '../../utils/server/redundancy'
+import { updateRedundancy } from '../../../../shared/utils/server/redundancy'
import { ActorFollow } from '../../../../shared/models/actors'
import { readdir } from 'fs-extra'
import { join } from 'path'
import { VideoRedundancyStrategy } from '../../../../shared/models/redundancy'
-import { getStats } from '../../utils/server/stats'
+import { getStats } from '../../../../shared/utils/server/stats'
import { ServerStats } from '../../../../shared/models/server/server-stats.model'
const expect = chai.expect
userLogin,
viewVideo,
wait
-} from '../../utils'
+} from '../../../../shared/utils'
const expect = chai.expect
import {
flushTests,
runServer,
registerUser, getCustomConfig, setAccessTokensToServers, updateCustomConfig
-} from '../../utils/index'
+} from '../../../../shared/utils/index'
describe('Test application behind a reverse proxy', function () {
let server = null
uploadVideo,
viewVideo,
wait
-} from '../../utils'
-import { flushTests, setAccessTokensToServers } from '../../utils/index'
-import { getStats } from '../../utils/server/stats'
-import { addVideoCommentThread } from '../../utils/videos/video-comments'
-import { waitJobs } from '../../utils/server/jobs'
+} from '../../../../shared/utils'
+import { flushTests, setAccessTokensToServers } from '../../../../shared/utils/index'
+import { getStats } from '../../../../shared/utils/server/stats'
+import { addVideoCommentThread } from '../../../../shared/utils/videos/video-comments'
+import { waitJobs } from '../../../../shared/utils/server/jobs'
const expect = chai.expect
import * as magnetUtil from 'magnet-uri'
import 'mocha'
-import { getVideo, killallServers, runServer, ServerInfo, uploadVideo } from '../../utils'
-import { flushTests, setAccessTokensToServers } from '../../utils/index'
+import { getVideo, killallServers, runServer, ServerInfo, uploadVideo } from '../../../../shared/utils'
+import { flushTests, setAccessTokensToServers } from '../../../../shared/utils/index'
import { VideoDetails } from '../../../../shared/models/videos'
import * as WebTorrent from 'webtorrent'
ServerInfo,
uploadVideo,
userLogin
-} from '../../utils/index'
-import { setAccessTokensToServers } from '../../utils/users/login'
-import { getVideosListWithToken, getVideosList } from '../../utils/videos/videos'
+} from '../../../../shared/utils/index'
+import { setAccessTokensToServers } from '../../../../shared/utils/users/login'
+import { getVideosListWithToken, getVideosList } from '../../../../shared/utils/videos/videos'
import {
addVideoCommentReply,
addVideoCommentThread,
getVideoCommentThreads,
getVideoThreadComments
-} from '../../utils/videos/video-comments'
-import { waitJobs } from '../../utils/server/jobs'
+} from '../../../../shared/utils/videos/video-comments'
+import { waitJobs } from '../../../../shared/utils/server/jobs'
import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model'
import {
addAccountToAccountBlocklist,
removeAccountFromServerBlocklist,
removeServerFromAccountBlocklist,
removeServerFromServerBlocklist
-} from '../../utils/users/blocklist'
+} from '../../../../shared/utils/users/blocklist'
const expect = chai.expect
import * as chai from 'chai'
import 'mocha'
-import { createUser, doubleFollow, flushAndRunMultipleServers, follow, getVideosList, unfollow, updateVideo, userLogin } from '../../utils'
-import { killallServers, ServerInfo, uploadVideo } from '../../utils/index'
-import { setAccessTokensToServers } from '../../utils/users/login'
+import {
+ createUser,
+ doubleFollow,
+ flushAndRunMultipleServers,
+ follow,
+ getVideosList,
+ unfollow,
+ updateVideo,
+ userLogin
+} from '../../../../shared/utils'
+import { killallServers, ServerInfo, uploadVideo } from '../../../../shared/utils/index'
+import { setAccessTokensToServers } from '../../../../shared/utils/users/login'
import { Video, VideoChannel } from '../../../../shared/models/videos'
-import { waitJobs } from '../../utils/server/jobs'
+import { waitJobs } from '../../../../shared/utils/server/jobs'
import {
addUserSubscription,
listUserSubscriptions,
listUserSubscriptionVideos,
removeUserSubscription,
getUserSubscription, areSubscriptionsExist
-} from '../../utils/users/user-subscriptions'
+} from '../../../../shared/utils/users/user-subscriptions'
const expect = chai.expect
removeUser,
updateMyUser,
userLogin
-} from '../../utils'
-import { getMyUserInformation, killallServers, ServerInfo, testImage, updateMyAvatar, uploadVideo } from '../../utils/index'
-import { checkActorFilesWereRemoved, getAccount, getAccountsList } from '../../utils/users/accounts'
-import { setAccessTokensToServers } from '../../utils/users/login'
+} from '../../../../shared/utils'
+import { getMyUserInformation, killallServers, ServerInfo, testImage, updateMyAvatar, uploadVideo } from '../../../../shared/utils/index'
+import { checkActorFilesWereRemoved, getAccount, getAccountsList } from '../../../../shared/utils/users/accounts'
+import { setAccessTokensToServers } from '../../../../shared/utils/users/login'
import { User } from '../../../../shared/models/users'
import { VideoChannel } from '../../../../shared/models/videos'
-import { waitJobs } from '../../utils/server/jobs'
+import { waitJobs } from '../../../../shared/utils/server/jobs'
const expect = chai.expect
import {
registerUser, flushTests, getUserInformation, getMyUserInformation, killallServers,
userLogin, login, runServer, ServerInfo, verifyEmail, updateCustomSubConfig
-} from '../../utils'
-import { setAccessTokensToServers } from '../../utils/users/login'
-import { mockSmtpServer } from '../../utils/miscs/email'
-import { waitJobs } from '../../utils/server/jobs'
+} from '../../../../shared/utils'
+import { setAccessTokensToServers } from '../../../../shared/utils/users/login'
+import { mockSmtpServer } from '../../../../shared/utils/miscs/email'
+import { waitJobs } from '../../../../shared/utils/server/jobs'
const expect = chai.expect
updateUser,
uploadVideo,
userLogin
-} from '../../utils/index'
-import { follow } from '../../utils/server/follows'
-import { setAccessTokensToServers } from '../../utils/users/login'
-import { getMyVideos } from '../../utils/videos/videos'
+} from '../../../../shared/utils/index'
+import { follow } from '../../../../shared/utils/server/follows'
+import { setAccessTokensToServers } from '../../../../shared/utils/users/login'
+import { getMyVideos } from '../../../../shared/utils/videos/videos'
const expect = chai.expect
viewVideo,
wait,
webtorrentAdd
-} from '../../utils'
+} from '../../../../shared/utils'
import {
addVideoCommentReply,
addVideoCommentThread,
deleteVideoComment,
getVideoCommentThreads,
getVideoThreadComments
-} from '../../utils/videos/video-comments'
-import { waitJobs } from '../../utils/server/jobs'
+} from '../../../../shared/utils/videos/video-comments'
+import { waitJobs } from '../../../../shared/utils/server/jobs'
const expect = chai.expect
import * as chai from 'chai'
import 'mocha'
-import { flushTests, getOEmbed, getVideosList, killallServers, ServerInfo, setAccessTokensToServers, uploadVideo } from '../../utils/index'
-import { runServer } from '../../utils/server/servers'
+import {
+ flushTests,
+ getOEmbed,
+ getVideosList,
+ killallServers,
+ ServerInfo,
+ setAccessTokensToServers,
+ uploadVideo
+} from '../../../../shared/utils/index'
+import { runServer } from '../../../../shared/utils/server/servers'
const expect = chai.expect
uploadVideo,
viewVideo,
wait
-} from '../../utils'
+} from '../../../../shared/utils'
const expect = chai.expect
setAccessTokensToServers,
updateVideoAbuse,
uploadVideo
-} from '../../utils/index'
-import { doubleFollow } from '../../utils/server/follows'
-import { waitJobs } from '../../utils/server/jobs'
+} from '../../../../shared/utils/index'
+import { doubleFollow } from '../../../../shared/utils/server/follows'
+import { waitJobs } from '../../../../shared/utils/server/jobs'
const expect = chai.expect
setAccessTokensToServers,
updateVideoBlacklist,
uploadVideo
-} from '../../utils/index'
-import { doubleFollow } from '../../utils/server/follows'
-import { waitJobs } from '../../utils/server/jobs'
+} from '../../../../shared/utils/index'
+import { doubleFollow } from '../../../../shared/utils/server/follows'
+import { waitJobs } from '../../../../shared/utils/server/jobs'
import { VideoAbuse } from '../../../../shared/models/videos'
const expect = chai.expect
ServerInfo,
setAccessTokensToServers,
uploadVideo
-} from '../../utils/index'
-import { doubleFollow } from '../../utils/server/follows'
-import { waitJobs } from '../../utils/server/jobs'
+} from '../../../../shared/utils/index'
+import { doubleFollow } from '../../../../shared/utils/server/follows'
+import { waitJobs } from '../../../../shared/utils/server/jobs'
const expect = chai.expect
import * as chai from 'chai'
import 'mocha'
-import { checkVideoFilesWereRemoved, doubleFollow, flushAndRunMultipleServers, removeVideo, uploadVideo, wait } from '../../utils'
-import { flushTests, killallServers, ServerInfo, setAccessTokensToServers } from '../../utils/index'
-import { waitJobs } from '../../utils/server/jobs'
-import { createVideoCaption, deleteVideoCaption, listVideoCaptions, testCaptionFile } from '../../utils/videos/video-captions'
+import {
+ checkVideoFilesWereRemoved,
+ doubleFollow,
+ flushAndRunMultipleServers,
+ removeVideo,
+ uploadVideo,
+ wait
+} from '../../../../shared/utils'
+import { flushTests, killallServers, ServerInfo, setAccessTokensToServers } from '../../../../shared/utils/index'
+import { waitJobs } from '../../../../shared/utils/server/jobs'
+import { createVideoCaption, deleteVideoCaption, listVideoCaptions, testCaptionFile } from '../../../../shared/utils/videos/video-captions'
import { VideoCaption } from '../../../../shared/models/videos/caption/video-caption.model'
const expect = chai.expect
uploadVideo,
userLogin,
getVideo
-} from '../../utils'
-import { waitJobs } from '../../utils/server/jobs'
+} from '../../../../shared/utils'
+import { waitJobs } from '../../../../shared/utils/server/jobs'
import { User } from '../../../../shared/models/users'
import { VideoDetails } from '../../../../shared/models/videos'
updateVideo,
updateVideoChannelAvatar,
uploadVideo, wait, userLogin
-} from '../../utils'
+} from '../../../../shared/utils'
import {
addVideoChannel,
deleteVideoChannel,
ServerInfo,
setAccessTokensToServers,
updateVideoChannel
-} from '../../utils/index'
-import { waitJobs } from '../../utils/server/jobs'
+} from '../../../../shared/utils/index'
+import { waitJobs } from '../../../../shared/utils/server/jobs'
const expect = chai.expect
import * as chai from 'chai'
import 'mocha'
import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model'
-import { testImage } from '../../utils'
+import { testImage } from '../../../../shared/utils'
import {
dateIsValid,
flushTests,
setAccessTokensToServers,
updateMyAvatar,
uploadVideo
-} from '../../utils/index'
+} from '../../../../shared/utils/index'
import {
addVideoCommentReply,
addVideoCommentThread,
deleteVideoComment,
getVideoCommentThreads,
getVideoThreadComments
-} from '../../utils/videos/video-comments'
+} from '../../../../shared/utils/videos/video-comments'
const expect = chai.expect
setAccessTokensToServers,
updateVideo,
uploadVideo
-} from '../../utils/index'
-import { doubleFollow } from '../../utils/server/follows'
-import { waitJobs } from '../../utils/server/jobs'
+} from '../../../../shared/utils/index'
+import { doubleFollow } from '../../../../shared/utils/server/follows'
+import { waitJobs } from '../../../../shared/utils/server/jobs'
const expect = chai.expect
killallServers,
ServerInfo,
setAccessTokensToServers
-} from '../../utils'
-import { waitJobs } from '../../utils/server/jobs'
-import { getMagnetURI, getYoutubeVideoUrl, importVideo, getMyVideoImports } from '../../utils/videos/video-imports'
+} from '../../../../shared/utils'
+import { waitJobs } from '../../../../shared/utils/server/jobs'
+import { getMagnetURI, getYoutubeVideoUrl, importVideo, getMyVideoImports } from '../../../../shared/utils/videos/video-imports'
const expect = chai.expect
import * as chai from 'chai'
import 'mocha'
-import { flushTests, getVideosList, killallServers, ServerInfo, setAccessTokensToServers, uploadVideo } from '../../utils/index'
-import { userLogin } from '../../utils/users/login'
-import { createUser } from '../../utils/users/users'
-import { getMyVideos } from '../../utils/videos/videos'
+import {
+ flushTests,
+ getVideosList,
+ killallServers,
+ ServerInfo,
+ setAccessTokensToServers,
+ uploadVideo
+} from '../../../../shared/utils/index'
+import { userLogin } from '../../../../shared/utils/users/login'
+import { createUser } from '../../../../shared/utils/users/users'
+import { getMyVideos } from '../../../../shared/utils/videos/videos'
import {
getAccountVideos,
getConfig,
searchVideoWithToken,
updateCustomConfig,
updateMyUser
-} from '../../utils'
+} from '../../../../shared/utils'
import { ServerConfig } from '../../../../shared/models'
import { CustomConfig } from '../../../../shared/models/server/custom-config.model'
import { User } from '../../../../shared/models/users'
ServerInfo,
setAccessTokensToServers,
uploadVideo
-} from '../../utils/index'
-import { doubleFollow } from '../../utils/server/follows'
-import { userLogin } from '../../utils/users/login'
-import { createUser } from '../../utils/users/users'
-import { getMyVideos, getVideo, getVideoWithToken, updateVideo } from '../../utils/videos/videos'
-import { waitJobs } from '../../utils/server/jobs'
+} from '../../../../shared/utils/index'
+import { doubleFollow } from '../../../../shared/utils/server/follows'
+import { userLogin } from '../../../../shared/utils/users/login'
+import { createUser } from '../../../../shared/utils/users/users'
+import { getMyVideos, getVideo, getVideoWithToken, updateVideo } from '../../../../shared/utils/videos/videos'
+import { waitJobs } from '../../../../shared/utils/server/jobs'
const expect = chai.expect
updateVideo,
uploadVideo,
wait
-} from '../../utils'
+} from '../../../../shared/utils'
import { join } from 'path'
-import { waitJobs } from '../../utils/server/jobs'
+import { waitJobs } from '../../../../shared/utils/server/jobs'
const expect = chai.expect
uploadVideo,
webtorrentAdd,
generateHighBitrateVideo
-} from '../../utils'
+} from '../../../../shared/utils'
import { join } from 'path'
-import { waitJobs } from '../../utils/server/jobs'
+import { waitJobs } from '../../../../shared/utils/server/jobs'
import { pathExists } from 'fs-extra'
import { VIDEO_TRANSCODING_FPS } from '../../../../server/initializers/constants'
setAccessTokensToServers,
uploadVideo,
userLogin
-} from '../../utils'
+} from '../../../../shared/utils'
import { Video, VideoPrivacy } from '../../../../shared/models/videos'
import { UserRole } from '../../../../shared/models/users'
ServerInfo,
setAccessTokensToServers,
uploadVideo
-} from '../../utils'
+} from '../../../../shared/utils'
import { Video, VideoDetails } from '../../../../shared/models/videos'
-import { userWatchVideo } from '../../utils/videos/video-history'
+import { userWatchVideo } from '../../../../shared/utils/videos/video-history'
const expect = chai.expect
import * as chai from 'chai'
import 'mocha'
-import { flushTests, killallServers, runServer, ServerInfo, setAccessTokensToServers, uploadVideo } from '../../utils'
-import { getVideosOverview } from '../../utils/overviews/overviews'
+import { flushTests, killallServers, runServer, ServerInfo, setAccessTokensToServers, uploadVideo } from '../../../../shared/utils'
+import { getVideosOverview } from '../../../../shared/utils/overviews/overviews'
import { VideosOverview } from '../../../../shared/models/overviews'
const expect = chai.expect
ServerInfo,
setAccessTokensToServers,
uploadVideo
-} from '../utils'
-import { waitJobs } from '../utils/server/jobs'
+} from '../../../shared/utils'
+import { waitJobs } from '../../../shared/utils/server/jobs'
const expect = chai.expect
ServerInfo,
setAccessTokensToServers,
uploadVideo, wait
-} from '../utils'
-import { waitJobs } from '../utils/server/jobs'
+} from '../../../shared/utils'
+import { waitJobs } from '../../../shared/utils/server/jobs'
const expect = chai.expect
ServerInfo,
setAccessTokensToServers,
uploadVideo, viewVideo, wait
-} from '../utils'
-import { waitJobs } from '../utils/server/jobs'
+} from '../../../shared/utils'
+import { waitJobs } from '../../../shared/utils/server/jobs'
import { getVideoFileBitrate, getVideoFileFPS, getVideoFileResolution } from '../../helpers/ffmpeg-utils'
import { VIDEO_TRANSCODING_FPS } from '../../initializers'
import { join } from 'path'
runServer,
ServerInfo,
setAccessTokensToServers
-} from '../utils'
+} from '../../../shared/utils'
describe('Test CLI wrapper', function () {
let server: ServerInfo
runServer,
ServerInfo,
setAccessTokensToServers
-} from '../utils'
+} from '../../../shared/utils'
describe('Test reset password scripts', function () {
let server: ServerInfo
import 'mocha'
import * as chai from 'chai'
import { VideoDetails } from '../../../shared/models/videos'
-import { waitJobs } from '../utils/server/jobs'
-import { addVideoCommentThread } from '../utils/videos/video-comments'
+import { waitJobs } from '../../../shared/utils/server/jobs'
+import { addVideoCommentThread } from '../../../shared/utils/videos/video-comments'
import {
addVideoChannel,
createUser,
ServerInfo,
setAccessTokensToServers,
uploadVideo
-} from '../utils'
-import { getAccountsList } from '../utils/users/accounts'
+} from '../../../shared/utils'
+import { getAccountsList } from '../../../shared/utils/users/accounts'
const expect = chai.expect
updateCustomConfig,
updateCustomSubConfig,
uploadVideo
-} from './utils'
+} from '../../shared/utils'
const expect = chai.expect
ServerInfo,
setAccessTokensToServers,
uploadVideo, userLogin
-} from '../utils'
+} from '../../../shared/utils'
import * as libxmljs from 'libxmljs'
-import { addVideoCommentThread } from '../utils/videos/video-comments'
-import { waitJobs } from '../utils/server/jobs'
+import { addVideoCommentThread } from '../../../shared/utils/videos/video-comments'
+import { waitJobs } from '../../../shared/utils/server/jobs'
import { User } from '../../../shared/models/users'
chai.use(require('chai-xml'))
import 'mocha'
import * as chai from 'chai'
-import { flushTests, killallServers, makeGetRequest, runServer, ServerInfo } from './utils'
+import { flushTests, killallServers, makeGetRequest, runServer, ServerInfo } from '../../shared/utils'
const expect = chai.expect
ServerInfo,
setAccessTokensToServers,
uploadVideo
-} from '../utils'
+} from '../../../shared/utils'
import * as Bluebird from 'bluebird'
start()
updateVideo,
uploadVideo, viewVideo,
wait
-} from '../utils'
-import { getJobsListPaginationAndSort } from '../utils/server/jobs'
+} from '../../../shared/utils'
+import { getJobsListPaginationAndSort } from '../../../shared/utils/server/jobs'
interface ServerInfo extends DefaultServerInfo {
requestsNumber: number
+++ /dev/null
-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<string>((res, rej) => {
- exec(command, (err, stdout, stderr) => {
- if (err) return rej(err)
-
- return res(stdout)
- })
- })
-}
-
-// ---------------------------------------------------------------------------
-
-export {
- execCLI,
- getEnvCli
-}
+++ /dev/null
-import * as request from 'supertest'
-
-type FeedType = 'videos' | 'video-comments'
-
-function getXMLfeed (url: string, feed: FeedType, format?: string) {
- const path = '/feeds/' + feed + '.xml'
-
- return request(url)
- .get(path)
- .query((format) ? { format: format } : {})
- .set('Accept', 'application/xml')
- .expect(200)
- .expect('Content-Type', /xml/)
-}
-
-function getJSONfeed (url: string, feed: FeedType, query: any = {}) {
- const path = '/feeds/' + feed + '.json'
-
- return request(url)
- .get(path)
- .query(query)
- .set('Accept', 'application/json')
- .expect(200)
- .expect('Content-Type', /json/)
-}
-
-// ---------------------------------------------------------------------------
-
-export {
- getXMLfeed,
- getJSONfeed
-}
+++ /dev/null
-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'
-export * from './videos/video-change-ownership'
-export * from './feeds/feeds'
-export * from './search/videos'
+++ /dev/null
-import * as MailDev from 'maildev'
-
-function mockSmtpServer (emailsCollection: object[]) {
- const maildev = new MailDev({
- ip: '127.0.0.1',
- smtp: 1025,
- disableWeb: true,
- silent: true
- })
- maildev.on('new', email => emailsCollection.push(email))
-
- return new Promise((res, rej) => {
- maildev.listen(err => {
- if (err) return rej(err)
-
- return res()
- })
- })
-}
-
-// ---------------------------------------------------------------------------
-
-export {
- mockSmtpServer
-}
+++ /dev/null
-/* tslint:disable:no-unused-expression */
-
-import * as chai from 'chai'
-import { isAbsolute, join } from 'path'
-import * as request from 'supertest'
-import * as WebTorrent from 'webtorrent'
-import { pathExists, readFile } from 'fs-extra'
-import * as ffmpeg from 'fluent-ffmpeg'
-
-const expect = chai.expect
-let webtorrent = new WebTorrent()
-
-function immutableAssign <T, U> (target: T, source: U) {
- return Object.assign<{}, T, U>({}, target, source)
-}
-
- // Default interval -> 5 minutes
-function dateIsValid (dateString: string, interval = 300000) {
- 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<WebTorrent.Torrent>(res => webtorrent.add(torrent, res))
-}
-
-function root () {
- // We are in server/tests/utils/miscs
- return join(__dirname, '..', '..', '..', '..')
-}
-
-async function testImage (url: string, imageName: string, imagePath: string, extension = '.jpg') {
- const res = await request(url)
- .get(imagePath)
- .expect(200)
-
- const body = res.body
-
- const data = await readFile(join(__dirname, '..', '..', 'fixtures', imageName + extension))
- const minLength = body.length - ((20 * body.length) / 100)
- const maxLength = body.length + ((20 * body.length) / 100)
-
- expect(data.length).to.be.above(minLength)
- expect(data.length).to.be.below(maxLength)
-}
-
-function buildAbsoluteFixturePath (path: string, customTravisPath = false) {
- if (isAbsolute(path)) {
- return path
- }
-
- if (customTravisPath && process.env.TRAVIS) return join(process.env.HOME, 'fixtures', path)
-
- return join(__dirname, '..', '..', 'fixtures', path)
-}
-
-async function generateHighBitrateVideo () {
- const tempFixturePath = buildAbsoluteFixturePath('video_high_bitrate_1080p.mp4', true)
-
- const exists = await pathExists(tempFixturePath)
- if (!exists) {
-
- // Generate a random, high bitrate video on the fly, so we don't have to include
- // a large file in the repo. The video needs to have a certain minimum length so
- // that FFmpeg properly applies bitrate limits.
- // https://stackoverflow.com/a/15795112
- return new Promise<string>(async (res, rej) => {
- ffmpeg()
- .outputOptions([ '-f rawvideo', '-video_size 1920x1080', '-i /dev/urandom' ])
- .outputOptions([ '-ac 2', '-f s16le', '-i /dev/urandom', '-t 10' ])
- .outputOptions([ '-maxrate 10M', '-bufsize 10M' ])
- .output(tempFixturePath)
- .on('error', rej)
- .on('end', () => res(tempFixturePath))
- .run()
- })
- }
-
- return tempFixturePath
-}
-
-// ---------------------------------------------------------------------------
-
-export {
- dateIsValid,
- wait,
- webtorrentAdd,
- immutableAssign,
- testImage,
- buildAbsoluteFixturePath,
- root,
- generateHighBitrateVideo
-}
+++ /dev/null
-import { makeGetRequest } from '../requests/requests'
-
-function getVideosOverview (url: string, useCache = false) {
- const path = '/api/v1/overviews/videos'
-
- const query = {
- t: useCache ? undefined : new Date().getTime()
- }
-
- return makeGetRequest({
- url,
- path,
- query,
- statusCodeExpected: 200
- })
-}
-
-export { getVideosOverview }
+++ /dev/null
-import { makeGetRequest } from './requests'
-import { immutableAssign } from '..'
-
-function checkBadStartPagination (url: string, path: string, token?: string, query = {}) {
- return makeGetRequest({
- url,
- path,
- token,
- query: immutableAssign(query, { start: 'hello' }),
- statusCodeExpected: 400
- })
-}
-
-function checkBadCountPagination (url: string, path: string, token?: string, query = {}) {
- return makeGetRequest({
- url,
- path,
- token,
- query: immutableAssign(query, { count: 'hello' }),
- statusCodeExpected: 400
- })
-}
-
-function checkBadSortPagination (url: string, path: string, token?: string, query = {}) {
- return makeGetRequest({
- url,
- path,
- token,
- query: immutableAssign(query, { sort: 'hello' }),
- statusCodeExpected: 400
- })
-}
-
-// ---------------------------------------------------------------------------
-
-export {
- checkBadStartPagination,
- checkBadCountPagination,
- checkBadSortPagination
-}
+++ /dev/null
-import * as request from 'supertest'
-import { buildAbsoluteFixturePath } from '../miscs/miscs'
-import { isAbsolute, join } from 'path'
-
-function makeGetRequest (options: {
- url: string,
- path: string,
- query?: any,
- token?: string,
- statusCodeExpected?: number,
- contentType?: string
-}) {
- if (!options.statusCodeExpected) options.statusCodeExpected = 400
- if (options.contentType === undefined) options.contentType = 'application/json'
-
- const req = request(options.url)
- .get(options.path)
-
- if (options.contentType) req.set('Accept', options.contentType)
- if (options.token) req.set('Authorization', 'Bearer ' + options.token)
- if (options.query) req.query(options.query)
-
- return req.expect(options.statusCodeExpected)
-}
-
-function makeDeleteRequest (options: {
- url: string,
- path: string,
- token?: string,
- statusCodeExpected?: number
-}) {
- if (!options.statusCodeExpected) options.statusCodeExpected = 400
-
- const req = request(options.url)
- .delete(options.path)
- .set('Accept', 'application/json')
-
- if (options.token) req.set('Authorization', 'Bearer ' + options.token)
-
- return req.expect(options.statusCodeExpected)
-}
-
-function makeUploadRequest (options: {
- url: string,
- method?: 'POST' | 'PUT',
- path: string,
- token?: string,
- fields: { [ fieldName: string ]: any },
- attaches: { [ attachName: string ]: any | any[] },
- statusCodeExpected?: number
-}) {
- if (!options.statusCodeExpected) options.statusCodeExpected = 400
-
- let req: request.Test
- if (options.method === 'PUT') {
- req = request(options.url).put(options.path)
- } else {
- req = request(options.url).post(options.path)
- }
-
- req.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]
- if (Array.isArray(value)) {
- req.attach(attach, buildAbsoluteFixturePath(value[0]), value[1])
- } else {
- req.attach(attach, buildAbsoluteFixturePath(value))
- }
- })
-
- return req.expect(options.statusCodeExpected)
-}
-
-function makePostBodyRequest (options: {
- url: string,
- path: string,
- token?: string,
- fields?: { [ fieldName: string ]: any },
- statusCodeExpected?: number
-}) {
- if (!options.fields) options.fields = {}
- 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)
-}
-
-function makeHTMLRequest (url: string, path: string) {
- return request(url)
- .get(path)
- .set('Accept', 'text/html')
- .expect(200)
-}
-
-function updateAvatarRequest (options: {
- url: string,
- path: string,
- accessToken: string,
- fixture: string
-}) {
- let filePath = ''
- if (isAbsolute(options.fixture)) {
- filePath = options.fixture
- } else {
- filePath = join(__dirname, '..', '..', 'fixtures', options.fixture)
- }
-
- return makeUploadRequest({
- url: options.url,
- path: options.path,
- token: options.accessToken,
- fields: {},
- attaches: { avatarfile: filePath },
- statusCodeExpected: 200
- })
-}
-
-// ---------------------------------------------------------------------------
-
-export {
- makeHTMLRequest,
- makeGetRequest,
- makeUploadRequest,
- makePostBodyRequest,
- makePutBodyRequest,
- makeDeleteRequest,
- updateAvatarRequest
-}
+++ /dev/null
-import { makeGetRequest } from '../requests/requests'
-
-function searchVideoChannel (url: string, search: string, token?: string, statusCodeExpected = 200) {
- const path = '/api/v1/search/video-channels'
-
- return makeGetRequest({
- url,
- path,
- query: {
- sort: '-createdAt',
- search
- },
- token,
- statusCodeExpected
- })
-}
-
-// ---------------------------------------------------------------------------
-
-export {
- searchVideoChannel
-}
+++ /dev/null
-/* tslint:disable:no-unused-expression */
-
-import * as request from 'supertest'
-import { VideosSearchQuery } from '../../../../shared/models/search'
-import { immutableAssign } from '..'
-
-function searchVideo (url: string, search: string) {
- const path = '/api/v1/search/videos'
- const req = request(url)
- .get(path)
- .query({ sort: '-publishedAt', search })
- .set('Accept', 'application/json')
-
- return req.expect(200)
- .expect('Content-Type', /json/)
-}
-
-function searchVideoWithToken (url: string, search: string, token: string, query: { nsfw?: boolean } = {}) {
- const path = '/api/v1/search/videos'
- const req = request(url)
- .get(path)
- .set('Authorization', 'Bearer ' + token)
- .query(immutableAssign(query, { sort: '-publishedAt', 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/search/videos'
-
- const req = request(url)
- .get(path)
- .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/search/videos'
-
- return request(url)
- .get(path)
- .query({ search })
- .query({ sort })
- .set('Accept', 'application/json')
- .expect(200)
- .expect('Content-Type', /json/)
-}
-
-function advancedVideosSearch (url: string, options: VideosSearchQuery) {
- const path = '/api/v1/search/videos'
-
- return request(url)
- .get(path)
- .query(options)
- .set('Accept', 'application/json')
- .expect(200)
- .expect('Content-Type', /json/)
-}
-
-// ---------------------------------------------------------------------------
-
-export {
- searchVideo,
- advancedVideosSearch,
- searchVideoWithToken,
- searchVideoWithPagination,
- searchVideoWithSort
-}
+++ /dev/null
-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
-}
+++ /dev/null
-import * as request from 'supertest'
-import * as urlUtil from 'url'
-
-function getClient (url: string) {
- const path = '/api/v1/oauth-clients/local'
-
- return request(url)
- .get(path)
- .set('Host', urlUtil.parse(url).host)
- .set('Accept', 'application/json')
- .expect(200)
- .expect('Content-Type', /json/)
-}
-
-// ---------------------------------------------------------------------------
-
-export {
- getClient
-}
+++ /dev/null
-import { makeDeleteRequest, makeGetRequest, makePutBodyRequest } from '../'
-import { CustomConfig } from '../../../../shared/models/server/custom-config.model'
-
-function getConfig (url: string) {
- const path = '/api/v1/config'
-
- return makeGetRequest({
- url,
- path,
- statusCodeExpected: 200
- })
-}
-
-function getAbout (url: string) {
- const path = '/api/v1/config/about'
-
- return makeGetRequest({
- url,
- path,
- statusCodeExpected: 200
- })
-}
-
-function getCustomConfig (url: string, token: string, statusCodeExpected = 200) {
- const path = '/api/v1/config/custom'
-
- return makeGetRequest({
- url,
- token,
- path,
- statusCodeExpected
- })
-}
-
-function updateCustomConfig (url: string, token: string, newCustomConfig: CustomConfig, statusCodeExpected = 200) {
- const path = '/api/v1/config/custom'
-
- return makePutBodyRequest({
- url,
- token,
- path,
- fields: newCustomConfig,
- statusCodeExpected
- })
-}
-
-function updateCustomSubConfig (url: string, token: string, newConfig: any) {
- const updateParams: CustomConfig = {
- instance: {
- name: 'PeerTube updated',
- shortDescription: 'my short description',
- description: 'my super description',
- terms: 'my super terms',
- defaultClientRoute: '/videos/recently-added',
- defaultNSFWPolicy: 'blur',
- customizations: {
- javascript: 'alert("coucou")',
- css: 'body { background-color: red; }'
- }
- },
- services: {
- twitter: {
- username: '@MySuperUsername',
- whitelisted: true
- }
- },
- cache: {
- previews: {
- size: 2
- },
- captions: {
- size: 3
- }
- },
- signup: {
- enabled: false,
- limit: 5,
- requiresEmailVerification: false
- },
- admin: {
- email: 'superadmin1@example.com'
- },
- user: {
- videoQuota: 5242881,
- videoQuotaDaily: 318742
- },
- transcoding: {
- enabled: true,
- threads: 1,
- resolutions: {
- '240p': false,
- '360p': true,
- '480p': true,
- '720p': false,
- '1080p': false
- }
- },
- import: {
- videos: {
- http: {
- enabled: false
- },
- torrent: {
- enabled: false
- }
- }
- }
- }
-
- Object.assign(updateParams, newConfig)
-
- return updateCustomConfig(url, token, updateParams)
-}
-
-function deleteCustomConfig (url: string, token: string, statusCodeExpected = 200) {
- const path = '/api/v1/config/custom'
-
- return makeDeleteRequest({
- url,
- token,
- path,
- statusCodeExpected
- })
-}
-
-// ---------------------------------------------------------------------------
-
-export {
- getConfig,
- getCustomConfig,
- updateCustomConfig,
- getAbout,
- deleteCustomConfig,
- updateCustomSubConfig
-}
+++ /dev/null
-import * as request from 'supertest'
-import { ServerInfo } from './servers'
-import { waitJobs } from './jobs'
-
-function getFollowersListPaginationAndSort (url: string, start: number, count: number, sort: string, search?: string) {
- const path = '/api/v1/server/followers'
-
- return request(url)
- .get(path)
- .query({ start })
- .query({ count })
- .query({ sort })
- .query({ search })
- .set('Accept', 'application/json')
- .expect(200)
- .expect('Content-Type', /json/)
-}
-
-function getFollowingListPaginationAndSort (url: string, start: number, count: number, sort: string, search?: string) {
- const path = '/api/v1/server/following'
-
- return request(url)
- .get(path)
- .query({ start })
- .query({ count })
- .query({ sort })
- .query({ search })
- .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 waitJobs([ server1, server2 ])
-
- return true
-}
-
-// ---------------------------------------------------------------------------
-
-export {
- getFollowersListPaginationAndSort,
- getFollowingListPaginationAndSort,
- unfollow,
- follow,
- doubleFollow
-}
+++ /dev/null
-import * as request from 'supertest'
-import { Job, JobState } from '../../../../shared/models'
-import { ServerInfo, wait } from '../index'
-
-function getJobsList (url: string, accessToken: string, state: JobState) {
- const path = '/api/v1/jobs/' + state
-
- 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, state: JobState, start: number, count: number, sort: string) {
- const path = '/api/v1/jobs/' + state
-
- 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/)
-}
-
-async function waitJobs (serversArg: ServerInfo[] | ServerInfo) {
- let servers: ServerInfo[]
-
- if (Array.isArray(serversArg) === false) servers = [ serversArg as ServerInfo ]
- else servers = serversArg as ServerInfo[]
-
- const states: JobState[] = [ 'waiting', 'active', 'delayed' ]
- const tasks: Promise<any>[] = []
- let pendingRequests: boolean
-
- do {
- pendingRequests = false
-
- // Check if each server has pending request
- for (const server of servers) {
- for (const state of states) {
- const p = getJobsListPaginationAndSort(server.url, server.accessToken, state, 0, 10, '-createdAt')
- .then(res => res.body.data)
- .then((jobs: Job[]) => jobs.filter(j => j.type !== 'videos-views'))
- .then(jobs => {
- if (jobs.length !== 0) pendingRequests = true
- })
- tasks.push(p)
- }
- }
-
- await Promise.all(tasks)
-
- // Retry, in case of new jobs were created
- if (pendingRequests === false) {
- await wait(1000)
-
- await Promise.all(tasks)
- }
-
- if (pendingRequests) {
- await wait(1000)
- }
- } while (pendingRequests)
-}
-
-// ---------------------------------------------------------------------------
-
-export {
- getJobsList,
- waitJobs,
- getJobsListPaginationAndSort
-}
+++ /dev/null
-import { makePutBodyRequest } from '../requests/requests'
-
-async function updateRedundancy (url: string, accessToken: string, host: string, redundancyAllowed: boolean, expectedStatus = 204) {
- const path = '/api/v1/server/redundancy/' + host
-
- return makePutBodyRequest({
- url,
- path,
- token: accessToken,
- fields: { redundancyAllowed },
- statusCodeExpected: expectedStatus
- })
-}
-
-export {
- updateRedundancy
-}
+++ /dev/null
-import { ChildProcess, exec, fork } from 'child_process'
-import { join } from 'path'
-import { root, wait } from '../miscs/miscs'
-import { readFile } from 'fs-extra'
-
-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
- account: {
- name: string
- }
- }
-
- remoteVideo?: {
- id: number
- uuid: string
- }
-}
-
-function flushAndRunMultipleServers (totalServers: number, configOverride?: Object) {
- let apps = []
- let i = 0
-
- return new Promise<ServerInfo[]>(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++) {
- runServer(j, configOverride).then(app => anotherServerDone(j, app))
- }
- })
- })
-}
-
-function flushTests () {
- return new Promise<void>((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': 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<ServerInfo>(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)
- })
- })
-}
-
-async function reRunServer (server: ServerInfo, configOverride?: any) {
- const newServer = await runServer(server.serverNumber, configOverride)
- server.app = newServer.app
-
- return server
-}
-
-function killallServers (servers: ServerInfo[]) {
- for (const server of servers) {
- process.kill(-server.app.pid)
- }
-}
-
-async function waitUntilLog (server: ServerInfo, str: string, count = 1) {
- const logfile = join(root(), 'test' + server.serverNumber, 'logs/peertube.log')
-
- while (true) {
- const buf = await readFile(logfile)
-
- const matches = buf.toString().match(new RegExp(str, 'g'))
- if (matches && matches.length === count) return
-
- await wait(1000)
- }
-}
-
-// ---------------------------------------------------------------------------
-
-export {
- ServerInfo,
- flushAndRunMultipleServers,
- flushTests,
- runServer,
- killallServers,
- reRunServer,
- waitUntilLog
-}
+++ /dev/null
-import { makeGetRequest } from '../'
-
-function getStats (url: string, useCache = false) {
- const path = '/api/v1/server/stats'
-
- const query = {
- t: useCache ? undefined : new Date().getTime()
- }
-
- return makeGetRequest({
- url,
- path,
- query,
- statusCodeExpected: 200
- })
-}
-
-// ---------------------------------------------------------------------------
-
-export {
- getStats
-}
+++ /dev/null
-/* tslint:disable:no-unused-expression */
-
-import { expect } from 'chai'
-import { existsSync, readdir } from 'fs-extra'
-import { join } from 'path'
-import { Account } from '../../../../shared/models/actors'
-import { root } from '../index'
-import { makeGetRequest } from '../requests/requests'
-
-function getAccountsList (url: string, sort = '-createdAt', statusCodeExpected = 200) {
- const path = '/api/v1/accounts'
-
- return makeGetRequest({
- url,
- query: { sort },
- path,
- statusCodeExpected
- })
-}
-
-function getAccount (url: string, accountName: string, statusCodeExpected = 200) {
- const path = '/api/v1/accounts/' + accountName
-
- return makeGetRequest({
- url,
- path,
- statusCodeExpected
- })
-}
-
-async function expectAccountFollows (url: string, nameWithDomain: string, followersCount: number, followingCount: number) {
- const res = await getAccountsList(url)
- const account = res.body.data.find((a: Account) => a.name + '@' + a.host === nameWithDomain)
-
- const message = `${nameWithDomain} on ${url}`
- expect(account.followersCount).to.equal(followersCount, message)
- expect(account.followingCount).to.equal(followingCount, message)
-}
-
-async function checkActorFilesWereRemoved (actorUUID: string, serverNumber: number) {
- const testDirectory = 'test' + serverNumber
-
- for (const directory of [ 'avatars' ]) {
- const directoryPath = join(root(), testDirectory, directory)
-
- const directoryExists = existsSync(directoryPath)
- expect(directoryExists).to.be.true
-
- const files = await readdir(directoryPath)
- for (const file of files) {
- expect(file).to.not.contain(actorUUID)
- }
- }
-}
-
-// ---------------------------------------------------------------------------
-
-export {
- getAccount,
- expectAccountFollows,
- getAccountsList,
- checkActorFilesWereRemoved
-}
+++ /dev/null
-/* tslint:disable:no-unused-expression */
-
-import { makeDeleteRequest, makePostBodyRequest } from '../index'
-import { makeGetRequest } from '../requests/requests'
-
-function getAccountBlocklistByAccount (
- url: string,
- token: string,
- start: number,
- count: number,
- sort = '-createdAt',
- statusCodeExpected = 200
-) {
- const path = '/api/v1/users/me/blocklist/accounts'
-
- return makeGetRequest({
- url,
- token,
- query: { start, count, sort },
- path,
- statusCodeExpected
- })
-}
-
-function addAccountToAccountBlocklist (url: string, token: string, accountToBlock: string, statusCodeExpected = 204) {
- const path = '/api/v1/users/me/blocklist/accounts'
-
- return makePostBodyRequest({
- url,
- path,
- token,
- fields: {
- accountName: accountToBlock
- },
- statusCodeExpected
- })
-}
-
-function removeAccountFromAccountBlocklist (url: string, token: string, accountToUnblock: string, statusCodeExpected = 204) {
- const path = '/api/v1/users/me/blocklist/accounts/' + accountToUnblock
-
- return makeDeleteRequest({
- url,
- path,
- token,
- statusCodeExpected
- })
-}
-
-function getServerBlocklistByAccount (
- url: string,
- token: string,
- start: number,
- count: number,
- sort = '-createdAt',
- statusCodeExpected = 200
-) {
- const path = '/api/v1/users/me/blocklist/servers'
-
- return makeGetRequest({
- url,
- token,
- query: { start, count, sort },
- path,
- statusCodeExpected
- })
-}
-
-function addServerToAccountBlocklist (url: string, token: string, serverToBlock: string, statusCodeExpected = 204) {
- const path = '/api/v1/users/me/blocklist/servers'
-
- return makePostBodyRequest({
- url,
- path,
- token,
- fields: {
- host: serverToBlock
- },
- statusCodeExpected
- })
-}
-
-function removeServerFromAccountBlocklist (url: string, token: string, serverToBlock: string, statusCodeExpected = 204) {
- const path = '/api/v1/users/me/blocklist/servers/' + serverToBlock
-
- return makeDeleteRequest({
- url,
- path,
- token,
- statusCodeExpected
- })
-}
-
-function getAccountBlocklistByServer (
- url: string,
- token: string,
- start: number,
- count: number,
- sort = '-createdAt',
- statusCodeExpected = 200
-) {
- const path = '/api/v1/server/blocklist/accounts'
-
- return makeGetRequest({
- url,
- token,
- query: { start, count, sort },
- path,
- statusCodeExpected
- })
-}
-
-function addAccountToServerBlocklist (url: string, token: string, accountToBlock: string, statusCodeExpected = 204) {
- const path = '/api/v1/server/blocklist/accounts'
-
- return makePostBodyRequest({
- url,
- path,
- token,
- fields: {
- accountName: accountToBlock
- },
- statusCodeExpected
- })
-}
-
-function removeAccountFromServerBlocklist (url: string, token: string, accountToUnblock: string, statusCodeExpected = 204) {
- const path = '/api/v1/server/blocklist/accounts/' + accountToUnblock
-
- return makeDeleteRequest({
- url,
- path,
- token,
- statusCodeExpected
- })
-}
-
-function getServerBlocklistByServer (
- url: string,
- token: string,
- start: number,
- count: number,
- sort = '-createdAt',
- statusCodeExpected = 200
-) {
- const path = '/api/v1/server/blocklist/servers'
-
- return makeGetRequest({
- url,
- token,
- query: { start, count, sort },
- path,
- statusCodeExpected
- })
-}
-
-function addServerToServerBlocklist (url: string, token: string, serverToBlock: string, statusCodeExpected = 204) {
- const path = '/api/v1/server/blocklist/servers'
-
- return makePostBodyRequest({
- url,
- path,
- token,
- fields: {
- host: serverToBlock
- },
- statusCodeExpected
- })
-}
-
-function removeServerFromServerBlocklist (url: string, token: string, serverToBlock: string, statusCodeExpected = 204) {
- const path = '/api/v1/server/blocklist/servers/' + serverToBlock
-
- return makeDeleteRequest({
- url,
- path,
- token,
- statusCodeExpected
- })
-}
-
-// ---------------------------------------------------------------------------
-
-export {
- getAccountBlocklistByAccount,
- addAccountToAccountBlocklist,
- removeAccountFromAccountBlocklist,
- getServerBlocklistByAccount,
- addServerToAccountBlocklist,
- removeServerFromAccountBlocklist,
-
- getAccountBlocklistByServer,
- addAccountToServerBlocklist,
- removeAccountFromServerBlocklist,
- getServerBlocklistByServer,
- addServerToServerBlocklist,
- removeServerFromServerBlocklist
-}
+++ /dev/null
-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 serverLogin (server: Server) {
- const res = await login(server.url, server.client, server.user, 200)
-
- return res.body.access_token as string
-}
-
-async function userLogin (server: Server, user: User, expectedStatus = 200) {
- const res = await login(server.url, server.client, user, expectedStatus)
-
- return res.body.access_token as string
-}
-
-function setAccessTokensToServers (servers: ServerInfo[]) {
- const tasks: Promise<any>[] = []
-
- for (const server of servers) {
- const p = serverLogin(server).then(t => server.accessToken = t)
- tasks.push(p)
- }
-
- return Promise.all(tasks)
-}
-
-// ---------------------------------------------------------------------------
-
-export {
- login,
- serverLogin,
- userLogin,
- setAccessTokensToServers,
- Server,
- Client,
- User
-}
+++ /dev/null
-import { makeDeleteRequest, makeGetRequest, makePostBodyRequest } from '../'
-
-function addUserSubscription (url: string, token: string, targetUri: string, statusCodeExpected = 204) {
- const path = '/api/v1/users/me/subscriptions'
-
- return makePostBodyRequest({
- url,
- path,
- token,
- statusCodeExpected,
- fields: { uri: targetUri }
- })
-}
-
-function listUserSubscriptions (url: string, token: string, sort = '-createdAt', statusCodeExpected = 200) {
- const path = '/api/v1/users/me/subscriptions'
-
- return makeGetRequest({
- url,
- path,
- token,
- statusCodeExpected,
- query: { sort }
- })
-}
-
-function listUserSubscriptionVideos (url: string, token: string, sort = '-createdAt', statusCodeExpected = 200) {
- const path = '/api/v1/users/me/subscriptions/videos'
-
- return makeGetRequest({
- url,
- path,
- token,
- statusCodeExpected,
- query: { sort }
- })
-}
-
-function getUserSubscription (url: string, token: string, uri: string, statusCodeExpected = 200) {
- const path = '/api/v1/users/me/subscriptions/' + uri
-
- return makeGetRequest({
- url,
- path,
- token,
- statusCodeExpected
- })
-}
-
-function removeUserSubscription (url: string, token: string, uri: string, statusCodeExpected = 204) {
- const path = '/api/v1/users/me/subscriptions/' + uri
-
- return makeDeleteRequest({
- url,
- path,
- token,
- statusCodeExpected
- })
-}
-
-function areSubscriptionsExist (url: string, token: string, uris: string[], statusCodeExpected = 200) {
- const path = '/api/v1/users/me/subscriptions/exist'
-
- return makeGetRequest({
- url,
- path,
- query: { 'uris[]': uris },
- token,
- statusCodeExpected
- })
-}
-
-// ---------------------------------------------------------------------------
-
-export {
- areSubscriptionsExist,
- addUserSubscription,
- listUserSubscriptions,
- getUserSubscription,
- listUserSubscriptionVideos,
- removeUserSubscription
-}
+++ /dev/null
-import * as request from 'supertest'
-import { makePostBodyRequest, makePutBodyRequest, updateAvatarRequest } from '../'
-
-import { UserRole } from '../../../../shared/index'
-import { NSFWPolicyType } from '../../../../shared/models/videos/nsfw-policy.type'
-
-function createUser (
- url: string,
- accessToken: string,
- username: string,
- password: string,
- videoQuota = 1000000,
- videoQuotaDaily = -1,
- role: UserRole = UserRole.USER,
- specialStatus = 200
-) {
- const path = '/api/v1/users'
- const body = {
- username,
- password,
- role,
- email: username + '@example.com',
- videoQuota,
- videoQuotaDaily
- }
-
- 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, specialStatus = 200) {
- const path = '/api/v1/users/me'
-
- return request(url)
- .get(path)
- .set('Accept', 'application/json')
- .set('Authorization', 'Bearer ' + accessToken)
- .expect(specialStatus)
- .expect('Content-Type', /json/)
-}
-
-function deleteMe (url: string, accessToken: string, specialStatus = 204) {
- const path = '/api/v1/users/me'
-
- return request(url)
- .delete(path)
- .set('Accept', 'application/json')
- .set('Authorization', 'Bearer ' + accessToken)
- .expect(specialStatus)
-}
-
-function getMyUserVideoQuotaUsed (url: string, accessToken: string, specialStatus = 200) {
- const path = '/api/v1/users/me/video-quota-used'
-
- return request(url)
- .get(path)
- .set('Accept', 'application/json')
- .set('Authorization', 'Bearer ' + accessToken)
- .expect(specialStatus)
- .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 getMyUserVideoRating (url: string, accessToken: string, videoId: number | string, specialStatus = 200) {
- const path = '/api/v1/users/me/videos/' + videoId + '/rating'
-
- return request(url)
- .get(path)
- .set('Accept', 'application/json')
- .set('Authorization', 'Bearer ' + accessToken)
- .expect(specialStatus)
- .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, search?: string) {
- const path = '/api/v1/users'
-
- return request(url)
- .get(path)
- .query({ start })
- .query({ count })
- .query({ sort })
- .query({ search })
- .set('Accept', 'application/json')
- .set('Authorization', 'Bearer ' + accessToken)
- .expect(200)
- .expect('Content-Type', /json/)
-}
-
-function removeUser (url: string, userId: number | string, 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 blockUser (url: string, userId: number | string, accessToken: string, expectedStatus = 204, reason?: string) {
- const path = '/api/v1/users'
- let body: any
- if (reason) body = { reason }
-
- return request(url)
- .post(path + '/' + userId + '/block')
- .send(body)
- .set('Accept', 'application/json')
- .set('Authorization', 'Bearer ' + accessToken)
- .expect(expectedStatus)
-}
-
-function unblockUser (url: string, userId: number | string, accessToken: string, expectedStatus = 204) {
- const path = '/api/v1/users'
-
- return request(url)
- .post(path + '/' + userId + '/unblock')
- .set('Accept', 'application/json')
- .set('Authorization', 'Bearer ' + accessToken)
- .expect(expectedStatus)
-}
-
-function updateMyUser (options: {
- url: string
- accessToken: string,
- currentPassword?: string,
- newPassword?: string,
- nsfwPolicy?: NSFWPolicyType,
- email?: string,
- autoPlayVideo?: boolean
- displayName?: string,
- description?: string
-}) {
- const path = '/api/v1/users/me'
-
- const toSend = {}
- if (options.currentPassword !== undefined && options.currentPassword !== null) toSend['currentPassword'] = options.currentPassword
- if (options.newPassword !== undefined && options.newPassword !== null) toSend['password'] = options.newPassword
- if (options.nsfwPolicy !== undefined && options.nsfwPolicy !== null) toSend['nsfwPolicy'] = options.nsfwPolicy
- if (options.autoPlayVideo !== undefined && options.autoPlayVideo !== null) toSend['autoPlayVideo'] = options.autoPlayVideo
- if (options.email !== undefined && options.email !== null) toSend['email'] = options.email
- if (options.description !== undefined && options.description !== null) toSend['description'] = options.description
- if (options.displayName !== undefined && options.displayName !== null) toSend['displayName'] = options.displayName
-
- return makePutBodyRequest({
- url: options.url,
- path,
- token: options.accessToken,
- fields: toSend,
- statusCodeExpected: 204
- })
-}
-
-function updateMyAvatar (options: {
- url: string,
- accessToken: string,
- fixture: string
-}) {
- const path = '/api/v1/users/me/avatar/pick'
-
- return updateAvatarRequest(Object.assign(options, { path }))
-}
-
-function updateUser (options: {
- url: string
- userId: number,
- accessToken: string,
- email?: string,
- videoQuota?: number,
- videoQuotaDaily?: number,
- role?: UserRole
-}) {
- const path = '/api/v1/users/' + options.userId
-
- const toSend = {}
- if (options.email !== undefined && options.email !== null) toSend['email'] = options.email
- if (options.videoQuota !== undefined && options.videoQuota !== null) toSend['videoQuota'] = options.videoQuota
- if (options.videoQuotaDaily !== undefined && options.videoQuotaDaily !== null) toSend['videoQuotaDaily'] = options.videoQuotaDaily
- if (options.role !== undefined && options.role !== null) toSend['role'] = options.role
-
- return makePutBodyRequest({
- url: options.url,
- path,
- token: options.accessToken,
- fields: toSend,
- statusCodeExpected: 204
- })
-}
-
-function askResetPassword (url: string, email: string) {
- const path = '/api/v1/users/ask-reset-password'
-
- return makePostBodyRequest({
- url,
- path,
- fields: { email },
- statusCodeExpected: 204
- })
-}
-
-function resetPassword (url: string, userId: number, verificationString: string, password: string, statusCodeExpected = 204) {
- const path = '/api/v1/users/' + userId + '/reset-password'
-
- return makePostBodyRequest({
- url,
- path,
- fields: { password, verificationString },
- statusCodeExpected
- })
-}
-
-function askSendVerifyEmail (url: string, email: string) {
- const path = '/api/v1/users/ask-send-verify-email'
-
- return makePostBodyRequest({
- url,
- path,
- fields: { email },
- statusCodeExpected: 204
- })
-}
-
-function verifyEmail (url: string, userId: number, verificationString: string, statusCodeExpected = 204) {
- const path = '/api/v1/users/' + userId + '/verify-email'
-
- return makePostBodyRequest({
- url,
- path,
- fields: { verificationString },
- statusCodeExpected
- })
-}
-
-// ---------------------------------------------------------------------------
-
-export {
- createUser,
- registerUser,
- getMyUserInformation,
- getMyUserVideoRating,
- deleteMe,
- getMyUserVideoQuotaUsed,
- getUsersList,
- getUsersListPaginationAndSort,
- removeUser,
- updateUser,
- updateMyUser,
- getUserInformation,
- blockUser,
- unblockUser,
- askResetPassword,
- resetPassword,
- updateMyAvatar,
- askSendVerifyEmail,
- verifyEmail
-}
+++ /dev/null
-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
-}
+++ /dev/null
-import * as request from 'supertest'
-import { VideoAbuseUpdate } from '../../../../shared/models/videos/abuse/video-abuse-update.model'
-import { makeDeleteRequest, makePutBodyRequest } from '..'
-
-function reportVideoAbuse (url: string, token: string, videoId: number | string, reason: string, specialStatus = 200) {
- 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/)
-}
-
-function updateVideoAbuse (
- url: string,
- token: string,
- videoId: string | number,
- videoAbuseId: number,
- body: VideoAbuseUpdate,
- statusCodeExpected = 204
-) {
- const path = '/api/v1/videos/' + videoId + '/abuse/' + videoAbuseId
-
- return makePutBodyRequest({
- url,
- token,
- path,
- fields: body,
- statusCodeExpected
- })
-}
-
-function deleteVideoAbuse (url: string, token: string, videoId: string | number, videoAbuseId: number, statusCodeExpected = 204) {
- const path = '/api/v1/videos/' + videoId + '/abuse/' + videoAbuseId
-
- return makeDeleteRequest({
- url,
- token,
- path,
- statusCodeExpected
- })
-}
-
-// ---------------------------------------------------------------------------
-
-export {
- reportVideoAbuse,
- getVideoAbusesList,
- updateVideoAbuse,
- deleteVideoAbuse
-}
+++ /dev/null
-import * as request from 'supertest'
-
-function addVideoToBlacklist (url: string, token: string, videoId: number | string, reason?: string, specialStatus = 204) {
- const path = '/api/v1/videos/' + videoId + '/blacklist'
-
- return request(url)
- .post(path)
- .send({ reason })
- .set('Accept', 'application/json')
- .set('Authorization', 'Bearer ' + token)
- .expect(specialStatus)
-}
-
-function updateVideoBlacklist (url: string, token: string, videoId: number, reason?: string, specialStatus = 204) {
- const path = '/api/v1/videos/' + videoId + '/blacklist'
-
- return request(url)
- .put(path)
- .send({ reason })
- .set('Accept', 'application/json')
- .set('Authorization', 'Bearer ' + token)
- .expect(specialStatus)
-}
-
-function removeVideoFromBlacklist (url: string, token: string, videoId: number | string, 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,
- updateVideoBlacklist
-}
+++ /dev/null
-import { makeDeleteRequest, makeGetRequest } from '../'
-import { buildAbsoluteFixturePath, makeUploadRequest } from '../index'
-import * as request from 'supertest'
-import * as chai from 'chai'
-
-const expect = chai.expect
-
-function createVideoCaption (args: {
- url: string,
- accessToken: string
- videoId: string | number
- language: string
- fixture: string,
- mimeType?: string,
- statusCodeExpected?: number
-}) {
- const path = '/api/v1/videos/' + args.videoId + '/captions/' + args.language
-
- const captionfile = buildAbsoluteFixturePath(args.fixture)
- const captionfileAttach = args.mimeType ? [ captionfile, { contentType: args.mimeType } ] : captionfile
-
- return makeUploadRequest({
- method: 'PUT',
- url: args.url,
- path,
- token: args.accessToken,
- fields: {},
- attaches: {
- captionfile: captionfileAttach
- },
- statusCodeExpected: args.statusCodeExpected || 204
- })
-}
-
-function listVideoCaptions (url: string, videoId: string | number) {
- const path = '/api/v1/videos/' + videoId + '/captions'
-
- return makeGetRequest({
- url,
- path,
- statusCodeExpected: 200
- })
-}
-
-function deleteVideoCaption (url: string, token: string, videoId: string | number, language: string) {
- const path = '/api/v1/videos/' + videoId + '/captions/' + language
-
- return makeDeleteRequest({
- url,
- token,
- path,
- statusCodeExpected: 204
- })
-}
-
-async function testCaptionFile (url: string, captionPath: string, containsString: string) {
- const res = await request(url)
- .get(captionPath)
- .expect(200)
-
- expect(res.text).to.contain(containsString)
-}
-
-// ---------------------------------------------------------------------------
-
-export {
- createVideoCaption,
- listVideoCaptions,
- testCaptionFile,
- deleteVideoCaption
-}
+++ /dev/null
-import * as request from 'supertest'
-
-function changeVideoOwnership (url: string, token: string, videoId: number | string, username) {
- const path = '/api/v1/videos/' + videoId + '/give-ownership'
-
- return request(url)
- .post(path)
- .set('Accept', 'application/json')
- .set('Authorization', 'Bearer ' + token)
- .send({ username })
- .expect(204)
-}
-
-function getVideoChangeOwnershipList (url: string, token: string) {
- const path = '/api/v1/videos/ownership'
-
- return request(url)
- .get(path)
- .query({ sort: '-createdAt' })
- .set('Accept', 'application/json')
- .set('Authorization', 'Bearer ' + token)
- .expect(200)
- .expect('Content-Type', /json/)
-}
-
-function acceptChangeOwnership (url: string, token: string, ownershipId: string, channelId: number, expectedStatus = 204) {
- const path = '/api/v1/videos/ownership/' + ownershipId + '/accept'
-
- return request(url)
- .post(path)
- .set('Accept', 'application/json')
- .set('Authorization', 'Bearer ' + token)
- .send({ channelId })
- .expect(expectedStatus)
-}
-
-function refuseChangeOwnership (url: string, token: string, ownershipId: string, expectedStatus = 204) {
- const path = '/api/v1/videos/ownership/' + ownershipId + '/refuse'
-
- return request(url)
- .post(path)
- .set('Accept', 'application/json')
- .set('Authorization', 'Bearer ' + token)
- .expect(expectedStatus)
-}
-
-// ---------------------------------------------------------------------------
-
-export {
- changeVideoOwnership,
- getVideoChangeOwnershipList,
- acceptChangeOwnership,
- refuseChangeOwnership
-}
+++ /dev/null
-import * as request from 'supertest'
-import { VideoChannelCreate, VideoChannelUpdate } from '../../../../shared/models/videos'
-import { updateAvatarRequest } from '../index'
-
-function getVideoChannelsList (url: string, start: number, count: number, sort?: string) {
- const path = '/api/v1/video-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, accountName: string, specialStatus = 200) {
- const path = '/api/v1/accounts/' + accountName + '/video-channels'
-
- return request(url)
- .get(path)
- .set('Accept', 'application/json')
- .expect(specialStatus)
- .expect('Content-Type', /json/)
-}
-
-function addVideoChannel (
- url: string,
- token: string,
- videoChannelAttributesArg: VideoChannelCreate,
- expectedStatus = 200
-) {
- const path = '/api/v1/video-channels/'
-
- // Default attributes
- let attributes = {
- displayName: 'my super video channel',
- description: 'my super channel description',
- support: 'my super channel support'
- }
- 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,
- channelName: string,
- attributes: VideoChannelUpdate,
- expectedStatus = 204
-) {
- const body = {}
- const path = '/api/v1/video-channels/' + channelName
-
- if (attributes.displayName) body['displayName'] = attributes.displayName
- if (attributes.description) body['description'] = attributes.description
- if (attributes.support) body['support'] = attributes.support
-
- return request(url)
- .put(path)
- .send(body)
- .set('Accept', 'application/json')
- .set('Authorization', 'Bearer ' + token)
- .expect(expectedStatus)
-}
-
-function deleteVideoChannel (url: string, token: string, channelName: string, expectedStatus = 204) {
- const path = '/api/v1/video-channels/' + channelName
-
- return request(url)
- .delete(path)
- .set('Accept', 'application/json')
- .set('Authorization', 'Bearer ' + token)
- .expect(expectedStatus)
-}
-
-function getVideoChannel (url: string, channelName: string) {
- const path = '/api/v1/video-channels/' + channelName
-
- return request(url)
- .get(path)
- .set('Accept', 'application/json')
- .expect(200)
- .expect('Content-Type', /json/)
-}
-
-function updateVideoChannelAvatar (options: {
- url: string,
- accessToken: string,
- fixture: string,
- videoChannelName: string | number
-}) {
-
- const path = '/api/v1/video-channels/' + options.videoChannelName + '/avatar/pick'
-
- return updateAvatarRequest(Object.assign(options, { path }))
-}
-
-// ---------------------------------------------------------------------------
-
-export {
- updateVideoChannelAvatar,
- getVideoChannelsList,
- getAccountVideoChannelsList,
- addVideoChannel,
- updateVideoChannel,
- deleteVideoChannel,
- getVideoChannel
-}
+++ /dev/null
-import * as request from 'supertest'
-import { makeDeleteRequest } from '../'
-
-function getVideoCommentThreads (url: string, videoId: number | string, start: number, count: number, sort?: string, token?: 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 })
- if (token) req.set('Authorization', 'Bearer ' + token)
-
- return req.set('Accept', 'application/json')
- .expect(200)
- .expect('Content-Type', /json/)
-}
-
-function getVideoThreadComments (url: string, videoId: number | string, threadId: number, token?: string) {
- const path = '/api/v1/videos/' + videoId + '/comment-threads/' + threadId
-
- const req = request(url)
- .get(path)
- .set('Accept', 'application/json')
-
- if (token) req.set('Authorization', 'Bearer ' + token)
-
- return req.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)
-}
-
-function deleteVideoComment (
- url: string,
- token: string,
- videoId: number | string,
- commentId: number,
- statusCodeExpected = 204
-) {
- const path = '/api/v1/videos/' + videoId + '/comments/' + commentId
-
- return makeDeleteRequest({
- url,
- path,
- token,
- statusCodeExpected
- })
-}
-
-// ---------------------------------------------------------------------------
-
-export {
- getVideoCommentThreads,
- getVideoThreadComments,
- addVideoCommentThread,
- addVideoCommentReply,
- deleteVideoComment
-}
+++ /dev/null
-import { makePutBodyRequest } from '../requests/requests'
-
-function userWatchVideo (url: string, token: string, videoId: number | string, currentTime: number) {
- const path = '/api/v1/videos/' + videoId + '/watching'
- const fields = { currentTime }
-
- return makePutBodyRequest({ url, path, token, fields, statusCodeExpected: 204 })
-}
-
-// ---------------------------------------------------------------------------
-
-export {
- userWatchVideo
-}
+++ /dev/null
-import { VideoImportCreate } from '../../../../shared/models/videos'
-import { makeGetRequest, makeUploadRequest } from '..'
-
-function getYoutubeVideoUrl () {
- return 'https://youtu.be/msX3jv1XdvM'
-}
-
-function getMagnetURI () {
- // tslint:disable:max-line-length
- return 'magnet:?xs=https%3A%2F%2Fpeertube2.cpy.re%2Fstatic%2Ftorrents%2Fb209ca00-c8bb-4b2b-b421-1ede169f3dbc-720.torrent&xt=urn:btih:0f498834733e8057ed5c6f2ee2b4efd8d84a76ee&dn=super+peertube2+video&tr=wss%3A%2F%2Fpeertube2.cpy.re%3A443%2Ftracker%2Fsocket&tr=https%3A%2F%2Fpeertube2.cpy.re%2Ftracker%2Fannounce&ws=https%3A%2F%2Fpeertube2.cpy.re%2Fstatic%2Fwebseed%2Fb209ca00-c8bb-4b2b-b421-1ede169f3dbc-720.mp4'
-}
-
-function importVideo (url: string, token: string, attributes: VideoImportCreate) {
- const path = '/api/v1/videos/imports'
-
- let attaches: any = {}
- if (attributes.torrentfile) attaches = { torrentfile: attributes.torrentfile }
-
- return makeUploadRequest({
- url,
- path,
- token,
- attaches,
- fields: attributes,
- statusCodeExpected: 200
- })
-}
-
-function getMyVideoImports (url: string, token: string, sort?: string) {
- const path = '/api/v1/users/me/videos/imports'
-
- const query = {}
- if (sort) query['sort'] = sort
-
- return makeGetRequest({
- url,
- query,
- path,
- token,
- statusCodeExpected: 200
- })
-}
-
-// ---------------------------------------------------------------------------
-
-export {
- getYoutubeVideoUrl,
- importVideo,
- getMagnetURI,
- getMyVideoImports
-}
+++ /dev/null
-/* tslint:disable:no-unused-expression */
-
-import { expect } from 'chai'
-import { existsSync, readdir, readFile } from 'fs-extra'
-import * as parseTorrent from 'parse-torrent'
-import { extname, join } from 'path'
-import * as request from 'supertest'
-import {
- buildAbsoluteFixturePath,
- getMyUserInformation,
- immutableAssign,
- makeGetRequest,
- makePutBodyRequest,
- makeUploadRequest,
- root,
- ServerInfo,
- testImage
-} from '../'
-import { VideoDetails, VideoPrivacy } from '../../../../shared/models/videos'
-import { VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_PRIVACIES } from '../../../initializers'
-import { dateIsValid, webtorrentAdd } from '../index'
-
-type VideoAttributes = {
- name?: string
- category?: number
- licence?: number
- language?: string
- nsfw?: boolean
- commentsEnabled?: boolean
- waitTranscoding?: boolean
- description?: string
- tags?: string[]
- channelId?: number
- privacy?: VideoPrivacy
- fixture?: string
- thumbnailfile?: string
- previewfile?: string
- scheduleUpdate?: {
- updateAt: string
- privacy?: VideoPrivacy
- }
-}
-
-function getVideoCategories (url: string) {
- const path = '/api/v1/videos/categories'
-
- return makeGetRequest({
- url,
- path,
- statusCodeExpected: 200
- })
-}
-
-function getVideoLicences (url: string) {
- const path = '/api/v1/videos/licences'
-
- return makeGetRequest({
- url,
- path,
- statusCodeExpected: 200
- })
-}
-
-function getVideoLanguages (url: string) {
- const path = '/api/v1/videos/languages'
-
- return makeGetRequest({
- url,
- path,
- statusCodeExpected: 200
- })
-}
-
-function getVideoPrivacies (url: string) {
- const path = '/api/v1/videos/privacies'
-
- return makeGetRequest({
- url,
- path,
- statusCodeExpected: 200
- })
-}
-
-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, xForwardedFor?: string) {
- const path = '/api/v1/videos/' + id + '/views'
-
- const req = request(url)
- .post(path)
- .set('Accept', 'application/json')
-
- if (xForwardedFor) {
- req.set('X-Forwarded-For', xForwardedFor)
- }
-
- return req.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 getVideosListWithToken (url: string, token: string, query: { nsfw?: boolean } = {}) {
- const path = '/api/v1/videos'
-
- return request(url)
- .get(path)
- .set('Authorization', 'Bearer ' + token)
- .query(immutableAssign(query, { sort: 'name' }))
- .set('Accept', 'application/json')
- .expect(200)
- .expect('Content-Type', /json/)
-}
-
-function getLocalVideos (url: string) {
- const path = '/api/v1/videos'
-
- return request(url)
- .get(path)
- .query({ sort: 'name', filter: 'local' })
- .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 getAccountVideos (
- url: string,
- accessToken: string,
- accountName: string,
- start: number,
- count: number,
- sort?: string,
- query: { nsfw?: boolean } = {}
-) {
- const path = '/api/v1/accounts/' + accountName + '/videos'
-
- return makeGetRequest({
- url,
- path,
- query: immutableAssign(query, {
- start,
- count,
- sort
- }),
- token: accessToken,
- statusCodeExpected: 200
- })
-}
-
-function getVideoChannelVideos (
- url: string,
- accessToken: string,
- videoChannelName: string,
- start: number,
- count: number,
- sort?: string,
- query: { nsfw?: boolean } = {}
-) {
- const path = '/api/v1/video-channels/' + videoChannelName + '/videos'
-
- return makeGetRequest({
- url,
- path,
- query: immutableAssign(query, {
- start,
- count,
- sort
- }),
- token: accessToken,
- statusCodeExpected: 200
- })
-}
-
-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 getVideosWithFilters (url: string, query: { tagsAllOf: string[], categoryOneOf: number[] | number }) {
- const path = '/api/v1/videos'
-
- return request(url)
- .get(path)
- .query(query)
- .set('Accept', 'application/json')
- .expect(200)
- .expect('Content-Type', /json/)
-}
-
-function removeVideo (url: string, token: string, id: number | string, expectedStatus = 204) {
- const path = '/api/v1/videos'
-
- return request(url)
- .delete(path + '/' + id)
- .set('Accept', 'application/json')
- .set('Authorization', 'Bearer ' + token)
- .expect(expectedStatus)
-}
-
-async function checkVideoFilesWereRemoved (
- videoUUID: string,
- serverNumber: number,
- directories = [ 'videos', 'thumbnails', 'torrents', 'previews', 'captions' ]
-) {
- const testDirectory = 'test' + serverNumber
-
- for (const directory of directories) {
- const directoryPath = join(root(), testDirectory, directory)
-
- const directoryExists = existsSync(directoryPath)
- expect(directoryExists).to.be.true
-
- const files = await readdir(directoryPath)
- for (const file of files) {
- expect(file).to.not.contain(videoUUID)
- }
- }
-}
-
-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 */ }
-
- // Override default attributes
- const attributes = Object.assign({
- name: 'my super video',
- category: 5,
- licence: 4,
- language: 'zh',
- channelId: defaultChannelId,
- nsfw: true,
- waitTranscoding: false,
- description: 'my super description',
- support: 'my super support text',
- tags: [ 'tag' ],
- privacy: VideoPrivacy.PUBLIC,
- commentsEnabled: true,
- fixture: 'video_short.webm'
- }, videoAttributesArg)
-
- const req = request(url)
- .post(path)
- .set('Accept', 'application/json')
- .set('Authorization', 'Bearer ' + accessToken)
- .field('name', attributes.name)
- .field('nsfw', JSON.stringify(attributes.nsfw))
- .field('commentsEnabled', JSON.stringify(attributes.commentsEnabled))
- .field('waitTranscoding', JSON.stringify(attributes.waitTranscoding))
- .field('privacy', attributes.privacy.toString())
- .field('channelId', attributes.channelId)
-
- if (attributes.description !== undefined) {
- req.field('description', attributes.description)
- }
- if (attributes.language !== undefined) {
- req.field('language', attributes.language.toString())
- }
- if (attributes.category !== undefined) {
- req.field('category', attributes.category.toString())
- }
- if (attributes.licence !== undefined) {
- req.field('licence', attributes.licence.toString())
- }
-
- for (let i = 0; i < attributes.tags.length; i++) {
- req.field('tags[' + i + ']', attributes.tags[i])
- }
-
- if (attributes.thumbnailfile !== undefined) {
- req.attach('thumbnailfile', buildAbsoluteFixturePath(attributes.thumbnailfile))
- }
- if (attributes.previewfile !== undefined) {
- req.attach('previewfile', buildAbsoluteFixturePath(attributes.previewfile))
- }
-
- if (attributes.scheduleUpdate) {
- req.field('scheduleUpdate[updateAt]', attributes.scheduleUpdate.updateAt)
-
- if (attributes.scheduleUpdate.privacy) {
- req.field('scheduleUpdate[privacy]', attributes.scheduleUpdate.privacy)
- }
- }
-
- return req.attach('videofile', buildAbsoluteFixturePath(attributes.fixture))
- .expect(specialStatus)
-}
-
-function updateVideo (url: string, accessToken: string, id: number | string, attributes: VideoAttributes, statusCodeExpected = 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 !== undefined) body['nsfw'] = JSON.stringify(attributes.nsfw)
- if (attributes.commentsEnabled !== undefined) body['commentsEnabled'] = JSON.stringify(attributes.commentsEnabled)
- if (attributes.description) body['description'] = attributes.description
- if (attributes.tags) body['tags'] = attributes.tags
- if (attributes.privacy) body['privacy'] = attributes.privacy
- if (attributes.channelId) body['channelId'] = attributes.channelId
- if (attributes.scheduleUpdate) body['scheduleUpdate'] = attributes.scheduleUpdate
-
- // Upload request
- if (attributes.thumbnailfile || attributes.previewfile) {
- const attaches: any = {}
- if (attributes.thumbnailfile) attaches.thumbnailfile = attributes.thumbnailfile
- if (attributes.previewfile) attaches.previewfile = attributes.previewfile
-
- return makeUploadRequest({
- url,
- method: 'PUT',
- path,
- token: accessToken,
- fields: body,
- attaches,
- statusCodeExpected
- })
- }
-
- return makePutBodyRequest({
- url,
- path,
- fields: body,
- token: accessToken,
- statusCodeExpected
- })
-}
-
-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<any>((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))
- })
- })
-}
-
-async function completeVideoCheck (
- url: string,
- video: any,
- attributes: {
- name: string
- category: number
- licence: number
- language: string
- nsfw: boolean
- commentsEnabled: boolean
- description: string
- publishedAt?: string
- support: string
- account: {
- name: string
- host: string
- }
- isLocal: boolean
- tags: string[]
- privacy: number
- likes?: number
- dislikes?: number
- duration: number
- channel: {
- displayName: string
- name: string
- description
- isLocal: boolean
- }
- fixture: string
- files: {
- resolution: number
- size: number
- }[],
- thumbnailfile?: string
- previewfile?: string
- }
-) {
- if (!attributes.likes) attributes.likes = 0
- if (!attributes.dislikes) attributes.dislikes = 0
-
- expect(video.name).to.equal(attributes.name)
- expect(video.category.id).to.equal(attributes.category)
- expect(video.category.label).to.equal(attributes.category !== null ? VIDEO_CATEGORIES[attributes.category] : 'Misc')
- expect(video.licence.id).to.equal(attributes.licence)
- expect(video.licence.label).to.equal(attributes.licence !== null ? VIDEO_LICENCES[attributes.licence] : 'Unknown')
- expect(video.language.id).to.equal(attributes.language)
- expect(video.language.label).to.equal(attributes.language !== null ? VIDEO_LANGUAGES[attributes.language] : 'Unknown')
- expect(video.privacy.id).to.deep.equal(attributes.privacy)
- expect(video.privacy.label).to.deep.equal(VIDEO_PRIVACIES[attributes.privacy])
- expect(video.nsfw).to.equal(attributes.nsfw)
- expect(video.description).to.equal(attributes.description)
- expect(video.account.id).to.be.a('number')
- expect(video.account.uuid).to.be.a('string')
- expect(video.account.host).to.equal(attributes.account.host)
- expect(video.account.name).to.equal(attributes.account.name)
- expect(video.channel.displayName).to.equal(attributes.channel.displayName)
- expect(video.channel.name).to.equal(attributes.channel.name)
- expect(video.likes).to.equal(attributes.likes)
- expect(video.dislikes).to.equal(attributes.dislikes)
- expect(video.isLocal).to.equal(attributes.isLocal)
- expect(video.duration).to.equal(attributes.duration)
- expect(dateIsValid(video.createdAt)).to.be.true
- expect(dateIsValid(video.publishedAt)).to.be.true
- expect(dateIsValid(video.updatedAt)).to.be.true
-
- if (attributes.publishedAt) {
- expect(video.publishedAt).to.equal(attributes.publishedAt)
- }
-
- const res = await getVideo(url, video.uuid)
- const videoDetails: VideoDetails = res.body
-
- expect(videoDetails.files).to.have.lengthOf(attributes.files.length)
- expect(videoDetails.tags).to.deep.equal(attributes.tags)
- expect(videoDetails.account.name).to.equal(attributes.account.name)
- expect(videoDetails.account.host).to.equal(attributes.account.host)
- expect(video.channel.displayName).to.equal(attributes.channel.displayName)
- expect(video.channel.name).to.equal(attributes.channel.name)
- expect(videoDetails.channel.host).to.equal(attributes.account.host)
- expect(videoDetails.channel.isLocal).to.equal(attributes.channel.isLocal)
- expect(dateIsValid(videoDetails.channel.createdAt.toString())).to.be.true
- expect(dateIsValid(videoDetails.channel.updatedAt.toString())).to.be.true
- expect(videoDetails.commentsEnabled).to.equal(attributes.commentsEnabled)
-
- for (const attributeFile of attributes.files) {
- const file = videoDetails.files.find(f => f.resolution.id === attributeFile.resolution)
- expect(file).not.to.be.undefined
-
- let extension = extname(attributes.fixture)
- // Transcoding enabled on server 2, extension will always be .mp4
- if (attributes.account.host === 'localhost:9002') extension = '.mp4'
-
- const magnetUri = file.magnetUri
- expect(file.magnetUri).to.have.lengthOf.above(2)
- expect(file.torrentUrl).to.equal(`http://${attributes.account.host}/static/torrents/${videoDetails.uuid}-${file.resolution.id}.torrent`)
- expect(file.fileUrl).to.equal(`http://${attributes.account.host}/static/webseed/${videoDetails.uuid}-${file.resolution.id}${extension}`)
- expect(file.resolution.id).to.equal(attributeFile.resolution)
- expect(file.resolution.label).to.equal(attributeFile.resolution + 'p')
-
- const minSize = attributeFile.size - ((10 * attributeFile.size) / 100)
- const maxSize = attributeFile.size + ((10 * attributeFile.size) / 100)
- expect(file.size,
- 'File size for resolution ' + file.resolution.label + ' outside confidence interval (' + minSize + '> size <' + maxSize + ')')
- .to.be.above(minSize).and.below(maxSize)
-
- {
- await testImage(url, attributes.thumbnailfile || attributes.fixture, videoDetails.thumbnailPath)
- }
-
- if (attributes.previewfile) {
- await testImage(url, attributes.previewfile, videoDetails.previewPath)
- }
-
- const torrent = await webtorrentAdd(magnetUri, true)
- 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('')
- }
-}
-
-// ---------------------------------------------------------------------------
-
-export {
- getVideoDescription,
- getVideoCategories,
- getVideoLicences,
- getVideoPrivacies,
- getVideoLanguages,
- getMyVideos,
- getAccountVideos,
- getVideoChannelVideos,
- getVideo,
- getVideoWithToken,
- getVideosList,
- getVideosListPagination,
- getVideosListSort,
- removeVideo,
- getVideosListWithToken,
- uploadVideo,
- getVideosWithFilters,
- updateVideo,
- rateVideo,
- viewVideo,
- parseTorrentVideo,
- getLocalVideos,
- completeVideoCheck,
- checkVideoFilesWereRemoved
-}
Server,
Client,
User
-} from '../tests/utils/index'
+} from '../../shared/utils'
program
.option('-u, --url <url>', 'Server url')
import { VideoPrivacy } from '../../shared/models/videos'
import { doRequestAndSaveToFile } from '../helpers/requests'
import { CONSTRAINTS_FIELDS } from '../initializers'
-import { getClient, getVideoCategories, login, searchVideoWithSort, uploadVideo } from '../tests/utils'
+import { getClient, getVideoCategories, login, searchVideoWithSort, uploadVideo } from '../../shared/utils/index'
import { truncate } from 'lodash'
import * as prompt from 'prompt'
import { remove } from 'fs-extra'
import * as program from 'commander'
import { access, constants } from 'fs-extra'
import { isAbsolute } from 'path'
-import { getClient, login } from '../tests/utils'
-import { uploadVideo } from '../tests/utils/index'
+import { getClient, login } from '../../shared/utils'
+import { uploadVideo } from '../../shared/utils/'
import { VideoPrivacy } from '../../shared/models/videos'
import { netrc, getSettings } from './cli'
--- /dev/null
+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<string>((res, rej) => {
+ exec(command, (err, stdout, stderr) => {
+ if (err) return rej(err)
+
+ return res(stdout)
+ })
+ })
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ execCLI,
+ getEnvCli
+}
--- /dev/null
+import * as request from 'supertest'
+
+type FeedType = 'videos' | 'video-comments'
+
+function getXMLfeed (url: string, feed: FeedType, format?: string) {
+ const path = '/feeds/' + feed + '.xml'
+
+ return request(url)
+ .get(path)
+ .query((format) ? { format: format } : {})
+ .set('Accept', 'application/xml')
+ .expect(200)
+ .expect('Content-Type', /xml/)
+}
+
+function getJSONfeed (url: string, feed: FeedType, query: any = {}) {
+ const path = '/feeds/' + feed + '.json'
+
+ return request(url)
+ .get(path)
+ .query(query)
+ .set('Accept', 'application/json')
+ .expect(200)
+ .expect('Content-Type', /json/)
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ getXMLfeed,
+ getJSONfeed
+}
--- /dev/null
+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'
+export * from './videos/video-change-ownership'
+export * from './feeds/feeds'
+export * from './search/videos'
--- /dev/null
+import * as MailDev from 'maildev'
+
+function mockSmtpServer (emailsCollection: object[]) {
+ const maildev = new MailDev({
+ ip: '127.0.0.1',
+ smtp: 1025,
+ disableWeb: true,
+ silent: true
+ })
+ maildev.on('new', email => emailsCollection.push(email))
+
+ return new Promise((res, rej) => {
+ maildev.listen(err => {
+ if (err) return rej(err)
+
+ return res()
+ })
+ })
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ mockSmtpServer
+}
--- /dev/null
+/* tslint:disable:no-unused-expression */
+
+import * as chai from 'chai'
+import { isAbsolute, join } from 'path'
+import * as request from 'supertest'
+import * as WebTorrent from 'webtorrent'
+import { pathExists, readFile } from 'fs-extra'
+import * as ffmpeg from 'fluent-ffmpeg'
+
+const expect = chai.expect
+let webtorrent = new WebTorrent()
+
+function immutableAssign <T, U> (target: T, source: U) {
+ return Object.assign<{}, T, U>({}, target, source)
+}
+
+ // Default interval -> 5 minutes
+function dateIsValid (dateString: string, interval = 300000) {
+ 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<WebTorrent.Torrent>(res => webtorrent.add(torrent, res))
+}
+
+function root () {
+ // We are in server/tests/utils/miscs
+ return join(__dirname, '..', '..', '..', '..')
+}
+
+async function testImage (url: string, imageName: string, imagePath: string, extension = '.jpg') {
+ const res = await request(url)
+ .get(imagePath)
+ .expect(200)
+
+ const body = res.body
+
+ const data = await readFile(join(__dirname, '..', '..', 'fixtures', imageName + extension))
+ const minLength = body.length - ((20 * body.length) / 100)
+ const maxLength = body.length + ((20 * body.length) / 100)
+
+ expect(data.length).to.be.above(minLength)
+ expect(data.length).to.be.below(maxLength)
+}
+
+function buildAbsoluteFixturePath (path: string, customTravisPath = false) {
+ if (isAbsolute(path)) {
+ return path
+ }
+
+ if (customTravisPath && process.env.TRAVIS) return join(process.env.HOME, 'fixtures', path)
+
+ return join(__dirname, '..', '..', 'fixtures', path)
+}
+
+async function generateHighBitrateVideo () {
+ const tempFixturePath = buildAbsoluteFixturePath('video_high_bitrate_1080p.mp4', true)
+
+ const exists = await pathExists(tempFixturePath)
+ if (!exists) {
+
+ // Generate a random, high bitrate video on the fly, so we don't have to include
+ // a large file in the repo. The video needs to have a certain minimum length so
+ // that FFmpeg properly applies bitrate limits.
+ // https://stackoverflow.com/a/15795112
+ return new Promise<string>(async (res, rej) => {
+ ffmpeg()
+ .outputOptions([ '-f rawvideo', '-video_size 1920x1080', '-i /dev/urandom' ])
+ .outputOptions([ '-ac 2', '-f s16le', '-i /dev/urandom', '-t 10' ])
+ .outputOptions([ '-maxrate 10M', '-bufsize 10M' ])
+ .output(tempFixturePath)
+ .on('error', rej)
+ .on('end', () => res(tempFixturePath))
+ .run()
+ })
+ }
+
+ return tempFixturePath
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ dateIsValid,
+ wait,
+ webtorrentAdd,
+ immutableAssign,
+ testImage,
+ buildAbsoluteFixturePath,
+ root,
+ generateHighBitrateVideo
+}
--- /dev/null
+import { makeGetRequest } from '../requests/requests'
+
+function getVideosOverview (url: string, useCache = false) {
+ const path = '/api/v1/overviews/videos'
+
+ const query = {
+ t: useCache ? undefined : new Date().getTime()
+ }
+
+ return makeGetRequest({
+ url,
+ path,
+ query,
+ statusCodeExpected: 200
+ })
+}
+
+export { getVideosOverview }
--- /dev/null
+import { makeGetRequest } from './requests'
+import { immutableAssign } from '..'
+
+function checkBadStartPagination (url: string, path: string, token?: string, query = {}) {
+ return makeGetRequest({
+ url,
+ path,
+ token,
+ query: immutableAssign(query, { start: 'hello' }),
+ statusCodeExpected: 400
+ })
+}
+
+function checkBadCountPagination (url: string, path: string, token?: string, query = {}) {
+ return makeGetRequest({
+ url,
+ path,
+ token,
+ query: immutableAssign(query, { count: 'hello' }),
+ statusCodeExpected: 400
+ })
+}
+
+function checkBadSortPagination (url: string, path: string, token?: string, query = {}) {
+ return makeGetRequest({
+ url,
+ path,
+ token,
+ query: immutableAssign(query, { sort: 'hello' }),
+ statusCodeExpected: 400
+ })
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ checkBadStartPagination,
+ checkBadCountPagination,
+ checkBadSortPagination
+}
--- /dev/null
+import * as request from 'supertest'
+import { buildAbsoluteFixturePath } from '../miscs/miscs'
+import { isAbsolute, join } from 'path'
+
+function makeGetRequest (options: {
+ url: string,
+ path: string,
+ query?: any,
+ token?: string,
+ statusCodeExpected?: number,
+ contentType?: string
+}) {
+ if (!options.statusCodeExpected) options.statusCodeExpected = 400
+ if (options.contentType === undefined) options.contentType = 'application/json'
+
+ const req = request(options.url)
+ .get(options.path)
+
+ if (options.contentType) req.set('Accept', options.contentType)
+ if (options.token) req.set('Authorization', 'Bearer ' + options.token)
+ if (options.query) req.query(options.query)
+
+ return req.expect(options.statusCodeExpected)
+}
+
+function makeDeleteRequest (options: {
+ url: string,
+ path: string,
+ token?: string,
+ statusCodeExpected?: number
+}) {
+ if (!options.statusCodeExpected) options.statusCodeExpected = 400
+
+ const req = request(options.url)
+ .delete(options.path)
+ .set('Accept', 'application/json')
+
+ if (options.token) req.set('Authorization', 'Bearer ' + options.token)
+
+ return req.expect(options.statusCodeExpected)
+}
+
+function makeUploadRequest (options: {
+ url: string,
+ method?: 'POST' | 'PUT',
+ path: string,
+ token?: string,
+ fields: { [ fieldName: string ]: any },
+ attaches: { [ attachName: string ]: any | any[] },
+ statusCodeExpected?: number
+}) {
+ if (!options.statusCodeExpected) options.statusCodeExpected = 400
+
+ let req: request.Test
+ if (options.method === 'PUT') {
+ req = request(options.url).put(options.path)
+ } else {
+ req = request(options.url).post(options.path)
+ }
+
+ req.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]
+ if (Array.isArray(value)) {
+ req.attach(attach, buildAbsoluteFixturePath(value[0]), value[1])
+ } else {
+ req.attach(attach, buildAbsoluteFixturePath(value))
+ }
+ })
+
+ return req.expect(options.statusCodeExpected)
+}
+
+function makePostBodyRequest (options: {
+ url: string,
+ path: string,
+ token?: string,
+ fields?: { [ fieldName: string ]: any },
+ statusCodeExpected?: number
+}) {
+ if (!options.fields) options.fields = {}
+ 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)
+}
+
+function makeHTMLRequest (url: string, path: string) {
+ return request(url)
+ .get(path)
+ .set('Accept', 'text/html')
+ .expect(200)
+}
+
+function updateAvatarRequest (options: {
+ url: string,
+ path: string,
+ accessToken: string,
+ fixture: string
+}) {
+ let filePath = ''
+ if (isAbsolute(options.fixture)) {
+ filePath = options.fixture
+ } else {
+ filePath = join(__dirname, '..', '..', 'fixtures', options.fixture)
+ }
+
+ return makeUploadRequest({
+ url: options.url,
+ path: options.path,
+ token: options.accessToken,
+ fields: {},
+ attaches: { avatarfile: filePath },
+ statusCodeExpected: 200
+ })
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ makeHTMLRequest,
+ makeGetRequest,
+ makeUploadRequest,
+ makePostBodyRequest,
+ makePutBodyRequest,
+ makeDeleteRequest,
+ updateAvatarRequest
+}
--- /dev/null
+import { makeGetRequest } from '../requests/requests'
+
+function searchVideoChannel (url: string, search: string, token?: string, statusCodeExpected = 200) {
+ const path = '/api/v1/search/video-channels'
+
+ return makeGetRequest({
+ url,
+ path,
+ query: {
+ sort: '-createdAt',
+ search
+ },
+ token,
+ statusCodeExpected
+ })
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ searchVideoChannel
+}
--- /dev/null
+/* tslint:disable:no-unused-expression */
+
+import * as request from 'supertest'
+import { VideosSearchQuery } from '../../../../shared/models/search'
+import { immutableAssign } from '..'
+
+function searchVideo (url: string, search: string) {
+ const path = '/api/v1/search/videos'
+ const req = request(url)
+ .get(path)
+ .query({ sort: '-publishedAt', search })
+ .set('Accept', 'application/json')
+
+ return req.expect(200)
+ .expect('Content-Type', /json/)
+}
+
+function searchVideoWithToken (url: string, search: string, token: string, query: { nsfw?: boolean } = {}) {
+ const path = '/api/v1/search/videos'
+ const req = request(url)
+ .get(path)
+ .set('Authorization', 'Bearer ' + token)
+ .query(immutableAssign(query, { sort: '-publishedAt', 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/search/videos'
+
+ const req = request(url)
+ .get(path)
+ .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/search/videos'
+
+ return request(url)
+ .get(path)
+ .query({ search })
+ .query({ sort })
+ .set('Accept', 'application/json')
+ .expect(200)
+ .expect('Content-Type', /json/)
+}
+
+function advancedVideosSearch (url: string, options: VideosSearchQuery) {
+ const path = '/api/v1/search/videos'
+
+ return request(url)
+ .get(path)
+ .query(options)
+ .set('Accept', 'application/json')
+ .expect(200)
+ .expect('Content-Type', /json/)
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ searchVideo,
+ advancedVideosSearch,
+ searchVideoWithToken,
+ searchVideoWithPagination,
+ searchVideoWithSort
+}
--- /dev/null
+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
+}
--- /dev/null
+import * as request from 'supertest'
+import * as urlUtil from 'url'
+
+function getClient (url: string) {
+ const path = '/api/v1/oauth-clients/local'
+
+ return request(url)
+ .get(path)
+ .set('Host', urlUtil.parse(url).host)
+ .set('Accept', 'application/json')
+ .expect(200)
+ .expect('Content-Type', /json/)
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ getClient
+}
--- /dev/null
+import { makeDeleteRequest, makeGetRequest, makePutBodyRequest } from '../'
+import { CustomConfig } from '../../../../shared/models/server/custom-config.model'
+
+function getConfig (url: string) {
+ const path = '/api/v1/config'
+
+ return makeGetRequest({
+ url,
+ path,
+ statusCodeExpected: 200
+ })
+}
+
+function getAbout (url: string) {
+ const path = '/api/v1/config/about'
+
+ return makeGetRequest({
+ url,
+ path,
+ statusCodeExpected: 200
+ })
+}
+
+function getCustomConfig (url: string, token: string, statusCodeExpected = 200) {
+ const path = '/api/v1/config/custom'
+
+ return makeGetRequest({
+ url,
+ token,
+ path,
+ statusCodeExpected
+ })
+}
+
+function updateCustomConfig (url: string, token: string, newCustomConfig: CustomConfig, statusCodeExpected = 200) {
+ const path = '/api/v1/config/custom'
+
+ return makePutBodyRequest({
+ url,
+ token,
+ path,
+ fields: newCustomConfig,
+ statusCodeExpected
+ })
+}
+
+function updateCustomSubConfig (url: string, token: string, newConfig: any) {
+ const updateParams: CustomConfig = {
+ instance: {
+ name: 'PeerTube updated',
+ shortDescription: 'my short description',
+ description: 'my super description',
+ terms: 'my super terms',
+ defaultClientRoute: '/videos/recently-added',
+ defaultNSFWPolicy: 'blur',
+ customizations: {
+ javascript: 'alert("coucou")',
+ css: 'body { background-color: red; }'
+ }
+ },
+ services: {
+ twitter: {
+ username: '@MySuperUsername',
+ whitelisted: true
+ }
+ },
+ cache: {
+ previews: {
+ size: 2
+ },
+ captions: {
+ size: 3
+ }
+ },
+ signup: {
+ enabled: false,
+ limit: 5,
+ requiresEmailVerification: false
+ },
+ admin: {
+ email: 'superadmin1@example.com'
+ },
+ user: {
+ videoQuota: 5242881,
+ videoQuotaDaily: 318742
+ },
+ transcoding: {
+ enabled: true,
+ threads: 1,
+ resolutions: {
+ '240p': false,
+ '360p': true,
+ '480p': true,
+ '720p': false,
+ '1080p': false
+ }
+ },
+ import: {
+ videos: {
+ http: {
+ enabled: false
+ },
+ torrent: {
+ enabled: false
+ }
+ }
+ }
+ }
+
+ Object.assign(updateParams, newConfig)
+
+ return updateCustomConfig(url, token, updateParams)
+}
+
+function deleteCustomConfig (url: string, token: string, statusCodeExpected = 200) {
+ const path = '/api/v1/config/custom'
+
+ return makeDeleteRequest({
+ url,
+ token,
+ path,
+ statusCodeExpected
+ })
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ getConfig,
+ getCustomConfig,
+ updateCustomConfig,
+ getAbout,
+ deleteCustomConfig,
+ updateCustomSubConfig
+}
--- /dev/null
+import * as request from 'supertest'
+import { ServerInfo } from './servers'
+import { waitJobs } from './jobs'
+
+function getFollowersListPaginationAndSort (url: string, start: number, count: number, sort: string, search?: string) {
+ const path = '/api/v1/server/followers'
+
+ return request(url)
+ .get(path)
+ .query({ start })
+ .query({ count })
+ .query({ sort })
+ .query({ search })
+ .set('Accept', 'application/json')
+ .expect(200)
+ .expect('Content-Type', /json/)
+}
+
+function getFollowingListPaginationAndSort (url: string, start: number, count: number, sort: string, search?: string) {
+ const path = '/api/v1/server/following'
+
+ return request(url)
+ .get(path)
+ .query({ start })
+ .query({ count })
+ .query({ sort })
+ .query({ search })
+ .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 waitJobs([ server1, server2 ])
+
+ return true
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ getFollowersListPaginationAndSort,
+ getFollowingListPaginationAndSort,
+ unfollow,
+ follow,
+ doubleFollow
+}
--- /dev/null
+import * as request from 'supertest'
+import { Job, JobState } from '../../../../shared/models'
+import { ServerInfo, wait } from '../index'
+
+function getJobsList (url: string, accessToken: string, state: JobState) {
+ const path = '/api/v1/jobs/' + state
+
+ 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, state: JobState, start: number, count: number, sort: string) {
+ const path = '/api/v1/jobs/' + state
+
+ 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/)
+}
+
+async function waitJobs (serversArg: ServerInfo[] | ServerInfo) {
+ let servers: ServerInfo[]
+
+ if (Array.isArray(serversArg) === false) servers = [ serversArg as ServerInfo ]
+ else servers = serversArg as ServerInfo[]
+
+ const states: JobState[] = [ 'waiting', 'active', 'delayed' ]
+ const tasks: Promise<any>[] = []
+ let pendingRequests: boolean
+
+ do {
+ pendingRequests = false
+
+ // Check if each server has pending request
+ for (const server of servers) {
+ for (const state of states) {
+ const p = getJobsListPaginationAndSort(server.url, server.accessToken, state, 0, 10, '-createdAt')
+ .then(res => res.body.data)
+ .then((jobs: Job[]) => jobs.filter(j => j.type !== 'videos-views'))
+ .then(jobs => {
+ if (jobs.length !== 0) pendingRequests = true
+ })
+ tasks.push(p)
+ }
+ }
+
+ await Promise.all(tasks)
+
+ // Retry, in case of new jobs were created
+ if (pendingRequests === false) {
+ await wait(1000)
+
+ await Promise.all(tasks)
+ }
+
+ if (pendingRequests) {
+ await wait(1000)
+ }
+ } while (pendingRequests)
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ getJobsList,
+ waitJobs,
+ getJobsListPaginationAndSort
+}
--- /dev/null
+import { makePutBodyRequest } from '../requests/requests'
+
+async function updateRedundancy (url: string, accessToken: string, host: string, redundancyAllowed: boolean, expectedStatus = 204) {
+ const path = '/api/v1/server/redundancy/' + host
+
+ return makePutBodyRequest({
+ url,
+ path,
+ token: accessToken,
+ fields: { redundancyAllowed },
+ statusCodeExpected: expectedStatus
+ })
+}
+
+export {
+ updateRedundancy
+}
--- /dev/null
+import { ChildProcess, exec, fork } from 'child_process'
+import { join } from 'path'
+import { root, wait } from '../miscs/miscs'
+import { readFile } from 'fs-extra'
+
+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
+ account: {
+ name: string
+ }
+ }
+
+ remoteVideo?: {
+ id: number
+ uuid: string
+ }
+}
+
+function flushAndRunMultipleServers (totalServers: number, configOverride?: Object) {
+ let apps = []
+ let i = 0
+
+ return new Promise<ServerInfo[]>(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++) {
+ runServer(j, configOverride).then(app => anotherServerDone(j, app))
+ }
+ })
+ })
+}
+
+function flushTests () {
+ return new Promise<void>((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': 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<ServerInfo>(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)
+ })
+ })
+}
+
+async function reRunServer (server: ServerInfo, configOverride?: any) {
+ const newServer = await runServer(server.serverNumber, configOverride)
+ server.app = newServer.app
+
+ return server
+}
+
+function killallServers (servers: ServerInfo[]) {
+ for (const server of servers) {
+ process.kill(-server.app.pid)
+ }
+}
+
+async function waitUntilLog (server: ServerInfo, str: string, count = 1) {
+ const logfile = join(root(), 'test' + server.serverNumber, 'logs/peertube.log')
+
+ while (true) {
+ const buf = await readFile(logfile)
+
+ const matches = buf.toString().match(new RegExp(str, 'g'))
+ if (matches && matches.length === count) return
+
+ await wait(1000)
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ ServerInfo,
+ flushAndRunMultipleServers,
+ flushTests,
+ runServer,
+ killallServers,
+ reRunServer,
+ waitUntilLog
+}
--- /dev/null
+import { makeGetRequest } from '../'
+
+function getStats (url: string, useCache = false) {
+ const path = '/api/v1/server/stats'
+
+ const query = {
+ t: useCache ? undefined : new Date().getTime()
+ }
+
+ return makeGetRequest({
+ url,
+ path,
+ query,
+ statusCodeExpected: 200
+ })
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ getStats
+}
--- /dev/null
+/* tslint:disable:no-unused-expression */
+
+import { expect } from 'chai'
+import { existsSync, readdir } from 'fs-extra'
+import { join } from 'path'
+import { Account } from '../../../../shared/models/actors'
+import { root } from '../index'
+import { makeGetRequest } from '../requests/requests'
+
+function getAccountsList (url: string, sort = '-createdAt', statusCodeExpected = 200) {
+ const path = '/api/v1/accounts'
+
+ return makeGetRequest({
+ url,
+ query: { sort },
+ path,
+ statusCodeExpected
+ })
+}
+
+function getAccount (url: string, accountName: string, statusCodeExpected = 200) {
+ const path = '/api/v1/accounts/' + accountName
+
+ return makeGetRequest({
+ url,
+ path,
+ statusCodeExpected
+ })
+}
+
+async function expectAccountFollows (url: string, nameWithDomain: string, followersCount: number, followingCount: number) {
+ const res = await getAccountsList(url)
+ const account = res.body.data.find((a: Account) => a.name + '@' + a.host === nameWithDomain)
+
+ const message = `${nameWithDomain} on ${url}`
+ expect(account.followersCount).to.equal(followersCount, message)
+ expect(account.followingCount).to.equal(followingCount, message)
+}
+
+async function checkActorFilesWereRemoved (actorUUID: string, serverNumber: number) {
+ const testDirectory = 'test' + serverNumber
+
+ for (const directory of [ 'avatars' ]) {
+ const directoryPath = join(root(), testDirectory, directory)
+
+ const directoryExists = existsSync(directoryPath)
+ expect(directoryExists).to.be.true
+
+ const files = await readdir(directoryPath)
+ for (const file of files) {
+ expect(file).to.not.contain(actorUUID)
+ }
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ getAccount,
+ expectAccountFollows,
+ getAccountsList,
+ checkActorFilesWereRemoved
+}
--- /dev/null
+/* tslint:disable:no-unused-expression */
+
+import { makeDeleteRequest, makePostBodyRequest } from '../index'
+import { makeGetRequest } from '../requests/requests'
+
+function getAccountBlocklistByAccount (
+ url: string,
+ token: string,
+ start: number,
+ count: number,
+ sort = '-createdAt',
+ statusCodeExpected = 200
+) {
+ const path = '/api/v1/users/me/blocklist/accounts'
+
+ return makeGetRequest({
+ url,
+ token,
+ query: { start, count, sort },
+ path,
+ statusCodeExpected
+ })
+}
+
+function addAccountToAccountBlocklist (url: string, token: string, accountToBlock: string, statusCodeExpected = 204) {
+ const path = '/api/v1/users/me/blocklist/accounts'
+
+ return makePostBodyRequest({
+ url,
+ path,
+ token,
+ fields: {
+ accountName: accountToBlock
+ },
+ statusCodeExpected
+ })
+}
+
+function removeAccountFromAccountBlocklist (url: string, token: string, accountToUnblock: string, statusCodeExpected = 204) {
+ const path = '/api/v1/users/me/blocklist/accounts/' + accountToUnblock
+
+ return makeDeleteRequest({
+ url,
+ path,
+ token,
+ statusCodeExpected
+ })
+}
+
+function getServerBlocklistByAccount (
+ url: string,
+ token: string,
+ start: number,
+ count: number,
+ sort = '-createdAt',
+ statusCodeExpected = 200
+) {
+ const path = '/api/v1/users/me/blocklist/servers'
+
+ return makeGetRequest({
+ url,
+ token,
+ query: { start, count, sort },
+ path,
+ statusCodeExpected
+ })
+}
+
+function addServerToAccountBlocklist (url: string, token: string, serverToBlock: string, statusCodeExpected = 204) {
+ const path = '/api/v1/users/me/blocklist/servers'
+
+ return makePostBodyRequest({
+ url,
+ path,
+ token,
+ fields: {
+ host: serverToBlock
+ },
+ statusCodeExpected
+ })
+}
+
+function removeServerFromAccountBlocklist (url: string, token: string, serverToBlock: string, statusCodeExpected = 204) {
+ const path = '/api/v1/users/me/blocklist/servers/' + serverToBlock
+
+ return makeDeleteRequest({
+ url,
+ path,
+ token,
+ statusCodeExpected
+ })
+}
+
+function getAccountBlocklistByServer (
+ url: string,
+ token: string,
+ start: number,
+ count: number,
+ sort = '-createdAt',
+ statusCodeExpected = 200
+) {
+ const path = '/api/v1/server/blocklist/accounts'
+
+ return makeGetRequest({
+ url,
+ token,
+ query: { start, count, sort },
+ path,
+ statusCodeExpected
+ })
+}
+
+function addAccountToServerBlocklist (url: string, token: string, accountToBlock: string, statusCodeExpected = 204) {
+ const path = '/api/v1/server/blocklist/accounts'
+
+ return makePostBodyRequest({
+ url,
+ path,
+ token,
+ fields: {
+ accountName: accountToBlock
+ },
+ statusCodeExpected
+ })
+}
+
+function removeAccountFromServerBlocklist (url: string, token: string, accountToUnblock: string, statusCodeExpected = 204) {
+ const path = '/api/v1/server/blocklist/accounts/' + accountToUnblock
+
+ return makeDeleteRequest({
+ url,
+ path,
+ token,
+ statusCodeExpected
+ })
+}
+
+function getServerBlocklistByServer (
+ url: string,
+ token: string,
+ start: number,
+ count: number,
+ sort = '-createdAt',
+ statusCodeExpected = 200
+) {
+ const path = '/api/v1/server/blocklist/servers'
+
+ return makeGetRequest({
+ url,
+ token,
+ query: { start, count, sort },
+ path,
+ statusCodeExpected
+ })
+}
+
+function addServerToServerBlocklist (url: string, token: string, serverToBlock: string, statusCodeExpected = 204) {
+ const path = '/api/v1/server/blocklist/servers'
+
+ return makePostBodyRequest({
+ url,
+ path,
+ token,
+ fields: {
+ host: serverToBlock
+ },
+ statusCodeExpected
+ })
+}
+
+function removeServerFromServerBlocklist (url: string, token: string, serverToBlock: string, statusCodeExpected = 204) {
+ const path = '/api/v1/server/blocklist/servers/' + serverToBlock
+
+ return makeDeleteRequest({
+ url,
+ path,
+ token,
+ statusCodeExpected
+ })
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ getAccountBlocklistByAccount,
+ addAccountToAccountBlocklist,
+ removeAccountFromAccountBlocklist,
+ getServerBlocklistByAccount,
+ addServerToAccountBlocklist,
+ removeServerFromAccountBlocklist,
+
+ getAccountBlocklistByServer,
+ addAccountToServerBlocklist,
+ removeAccountFromServerBlocklist,
+ getServerBlocklistByServer,
+ addServerToServerBlocklist,
+ removeServerFromServerBlocklist
+}
--- /dev/null
+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 serverLogin (server: Server) {
+ const res = await login(server.url, server.client, server.user, 200)
+
+ return res.body.access_token as string
+}
+
+async function userLogin (server: Server, user: User, expectedStatus = 200) {
+ const res = await login(server.url, server.client, user, expectedStatus)
+
+ return res.body.access_token as string
+}
+
+function setAccessTokensToServers (servers: ServerInfo[]) {
+ const tasks: Promise<any>[] = []
+
+ for (const server of servers) {
+ const p = serverLogin(server).then(t => server.accessToken = t)
+ tasks.push(p)
+ }
+
+ return Promise.all(tasks)
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ login,
+ serverLogin,
+ userLogin,
+ setAccessTokensToServers,
+ Server,
+ Client,
+ User
+}
--- /dev/null
+import { makeDeleteRequest, makeGetRequest, makePostBodyRequest } from '../'
+
+function addUserSubscription (url: string, token: string, targetUri: string, statusCodeExpected = 204) {
+ const path = '/api/v1/users/me/subscriptions'
+
+ return makePostBodyRequest({
+ url,
+ path,
+ token,
+ statusCodeExpected,
+ fields: { uri: targetUri }
+ })
+}
+
+function listUserSubscriptions (url: string, token: string, sort = '-createdAt', statusCodeExpected = 200) {
+ const path = '/api/v1/users/me/subscriptions'
+
+ return makeGetRequest({
+ url,
+ path,
+ token,
+ statusCodeExpected,
+ query: { sort }
+ })
+}
+
+function listUserSubscriptionVideos (url: string, token: string, sort = '-createdAt', statusCodeExpected = 200) {
+ const path = '/api/v1/users/me/subscriptions/videos'
+
+ return makeGetRequest({
+ url,
+ path,
+ token,
+ statusCodeExpected,
+ query: { sort }
+ })
+}
+
+function getUserSubscription (url: string, token: string, uri: string, statusCodeExpected = 200) {
+ const path = '/api/v1/users/me/subscriptions/' + uri
+
+ return makeGetRequest({
+ url,
+ path,
+ token,
+ statusCodeExpected
+ })
+}
+
+function removeUserSubscription (url: string, token: string, uri: string, statusCodeExpected = 204) {
+ const path = '/api/v1/users/me/subscriptions/' + uri
+
+ return makeDeleteRequest({
+ url,
+ path,
+ token,
+ statusCodeExpected
+ })
+}
+
+function areSubscriptionsExist (url: string, token: string, uris: string[], statusCodeExpected = 200) {
+ const path = '/api/v1/users/me/subscriptions/exist'
+
+ return makeGetRequest({
+ url,
+ path,
+ query: { 'uris[]': uris },
+ token,
+ statusCodeExpected
+ })
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ areSubscriptionsExist,
+ addUserSubscription,
+ listUserSubscriptions,
+ getUserSubscription,
+ listUserSubscriptionVideos,
+ removeUserSubscription
+}
--- /dev/null
+import * as request from 'supertest'
+import { makePostBodyRequest, makePutBodyRequest, updateAvatarRequest } from '../'
+
+import { UserRole } from '../../index'
+import { NSFWPolicyType } from '../../models/videos/nsfw-policy.type'
+
+function createUser (
+ url: string,
+ accessToken: string,
+ username: string,
+ password: string,
+ videoQuota = 1000000,
+ videoQuotaDaily = -1,
+ role: UserRole = UserRole.USER,
+ specialStatus = 200
+) {
+ const path = '/api/v1/users'
+ const body = {
+ username,
+ password,
+ role,
+ email: username + '@example.com',
+ videoQuota,
+ videoQuotaDaily
+ }
+
+ 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, specialStatus = 200) {
+ const path = '/api/v1/users/me'
+
+ return request(url)
+ .get(path)
+ .set('Accept', 'application/json')
+ .set('Authorization', 'Bearer ' + accessToken)
+ .expect(specialStatus)
+ .expect('Content-Type', /json/)
+}
+
+function deleteMe (url: string, accessToken: string, specialStatus = 204) {
+ const path = '/api/v1/users/me'
+
+ return request(url)
+ .delete(path)
+ .set('Accept', 'application/json')
+ .set('Authorization', 'Bearer ' + accessToken)
+ .expect(specialStatus)
+}
+
+function getMyUserVideoQuotaUsed (url: string, accessToken: string, specialStatus = 200) {
+ const path = '/api/v1/users/me/video-quota-used'
+
+ return request(url)
+ .get(path)
+ .set('Accept', 'application/json')
+ .set('Authorization', 'Bearer ' + accessToken)
+ .expect(specialStatus)
+ .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 getMyUserVideoRating (url: string, accessToken: string, videoId: number | string, specialStatus = 200) {
+ const path = '/api/v1/users/me/videos/' + videoId + '/rating'
+
+ return request(url)
+ .get(path)
+ .set('Accept', 'application/json')
+ .set('Authorization', 'Bearer ' + accessToken)
+ .expect(specialStatus)
+ .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, search?: string) {
+ const path = '/api/v1/users'
+
+ return request(url)
+ .get(path)
+ .query({ start })
+ .query({ count })
+ .query({ sort })
+ .query({ search })
+ .set('Accept', 'application/json')
+ .set('Authorization', 'Bearer ' + accessToken)
+ .expect(200)
+ .expect('Content-Type', /json/)
+}
+
+function removeUser (url: string, userId: number | string, 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 blockUser (url: string, userId: number | string, accessToken: string, expectedStatus = 204, reason?: string) {
+ const path = '/api/v1/users'
+ let body: any
+ if (reason) body = { reason }
+
+ return request(url)
+ .post(path + '/' + userId + '/block')
+ .send(body)
+ .set('Accept', 'application/json')
+ .set('Authorization', 'Bearer ' + accessToken)
+ .expect(expectedStatus)
+}
+
+function unblockUser (url: string, userId: number | string, accessToken: string, expectedStatus = 204) {
+ const path = '/api/v1/users'
+
+ return request(url)
+ .post(path + '/' + userId + '/unblock')
+ .set('Accept', 'application/json')
+ .set('Authorization', 'Bearer ' + accessToken)
+ .expect(expectedStatus)
+}
+
+function updateMyUser (options: {
+ url: string
+ accessToken: string,
+ currentPassword?: string,
+ newPassword?: string,
+ nsfwPolicy?: NSFWPolicyType,
+ email?: string,
+ autoPlayVideo?: boolean
+ displayName?: string,
+ description?: string
+}) {
+ const path = '/api/v1/users/me'
+
+ const toSend = {}
+ if (options.currentPassword !== undefined && options.currentPassword !== null) toSend['currentPassword'] = options.currentPassword
+ if (options.newPassword !== undefined && options.newPassword !== null) toSend['password'] = options.newPassword
+ if (options.nsfwPolicy !== undefined && options.nsfwPolicy !== null) toSend['nsfwPolicy'] = options.nsfwPolicy
+ if (options.autoPlayVideo !== undefined && options.autoPlayVideo !== null) toSend['autoPlayVideo'] = options.autoPlayVideo
+ if (options.email !== undefined && options.email !== null) toSend['email'] = options.email
+ if (options.description !== undefined && options.description !== null) toSend['description'] = options.description
+ if (options.displayName !== undefined && options.displayName !== null) toSend['displayName'] = options.displayName
+
+ return makePutBodyRequest({
+ url: options.url,
+ path,
+ token: options.accessToken,
+ fields: toSend,
+ statusCodeExpected: 204
+ })
+}
+
+function updateMyAvatar (options: {
+ url: string,
+ accessToken: string,
+ fixture: string
+}) {
+ const path = '/api/v1/users/me/avatar/pick'
+
+ return updateAvatarRequest(Object.assign(options, { path }))
+}
+
+function updateUser (options: {
+ url: string
+ userId: number,
+ accessToken: string,
+ email?: string,
+ videoQuota?: number,
+ videoQuotaDaily?: number,
+ role?: UserRole
+}) {
+ const path = '/api/v1/users/' + options.userId
+
+ const toSend = {}
+ if (options.email !== undefined && options.email !== null) toSend['email'] = options.email
+ if (options.videoQuota !== undefined && options.videoQuota !== null) toSend['videoQuota'] = options.videoQuota
+ if (options.videoQuotaDaily !== undefined && options.videoQuotaDaily !== null) toSend['videoQuotaDaily'] = options.videoQuotaDaily
+ if (options.role !== undefined && options.role !== null) toSend['role'] = options.role
+
+ return makePutBodyRequest({
+ url: options.url,
+ path,
+ token: options.accessToken,
+ fields: toSend,
+ statusCodeExpected: 204
+ })
+}
+
+function askResetPassword (url: string, email: string) {
+ const path = '/api/v1/users/ask-reset-password'
+
+ return makePostBodyRequest({
+ url,
+ path,
+ fields: { email },
+ statusCodeExpected: 204
+ })
+}
+
+function resetPassword (url: string, userId: number, verificationString: string, password: string, statusCodeExpected = 204) {
+ const path = '/api/v1/users/' + userId + '/reset-password'
+
+ return makePostBodyRequest({
+ url,
+ path,
+ fields: { password, verificationString },
+ statusCodeExpected
+ })
+}
+
+function askSendVerifyEmail (url: string, email: string) {
+ const path = '/api/v1/users/ask-send-verify-email'
+
+ return makePostBodyRequest({
+ url,
+ path,
+ fields: { email },
+ statusCodeExpected: 204
+ })
+}
+
+function verifyEmail (url: string, userId: number, verificationString: string, statusCodeExpected = 204) {
+ const path = '/api/v1/users/' + userId + '/verify-email'
+
+ return makePostBodyRequest({
+ url,
+ path,
+ fields: { verificationString },
+ statusCodeExpected
+ })
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ createUser,
+ registerUser,
+ getMyUserInformation,
+ getMyUserVideoRating,
+ deleteMe,
+ getMyUserVideoQuotaUsed,
+ getUsersList,
+ getUsersListPaginationAndSort,
+ removeUser,
+ updateUser,
+ updateMyUser,
+ getUserInformation,
+ blockUser,
+ unblockUser,
+ askResetPassword,
+ resetPassword,
+ updateMyAvatar,
+ askSendVerifyEmail,
+ verifyEmail
+}
--- /dev/null
+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
+}
--- /dev/null
+import * as request from 'supertest'
+import { VideoAbuseUpdate } from '../../../../shared/models/videos/abuse/video-abuse-update.model'
+import { makeDeleteRequest, makePutBodyRequest } from '..'
+
+function reportVideoAbuse (url: string, token: string, videoId: number | string, reason: string, specialStatus = 200) {
+ 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/)
+}
+
+function updateVideoAbuse (
+ url: string,
+ token: string,
+ videoId: string | number,
+ videoAbuseId: number,
+ body: VideoAbuseUpdate,
+ statusCodeExpected = 204
+) {
+ const path = '/api/v1/videos/' + videoId + '/abuse/' + videoAbuseId
+
+ return makePutBodyRequest({
+ url,
+ token,
+ path,
+ fields: body,
+ statusCodeExpected
+ })
+}
+
+function deleteVideoAbuse (url: string, token: string, videoId: string | number, videoAbuseId: number, statusCodeExpected = 204) {
+ const path = '/api/v1/videos/' + videoId + '/abuse/' + videoAbuseId
+
+ return makeDeleteRequest({
+ url,
+ token,
+ path,
+ statusCodeExpected
+ })
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ reportVideoAbuse,
+ getVideoAbusesList,
+ updateVideoAbuse,
+ deleteVideoAbuse
+}
--- /dev/null
+import * as request from 'supertest'
+
+function addVideoToBlacklist (url: string, token: string, videoId: number | string, reason?: string, specialStatus = 204) {
+ const path = '/api/v1/videos/' + videoId + '/blacklist'
+
+ return request(url)
+ .post(path)
+ .send({ reason })
+ .set('Accept', 'application/json')
+ .set('Authorization', 'Bearer ' + token)
+ .expect(specialStatus)
+}
+
+function updateVideoBlacklist (url: string, token: string, videoId: number, reason?: string, specialStatus = 204) {
+ const path = '/api/v1/videos/' + videoId + '/blacklist'
+
+ return request(url)
+ .put(path)
+ .send({ reason })
+ .set('Accept', 'application/json')
+ .set('Authorization', 'Bearer ' + token)
+ .expect(specialStatus)
+}
+
+function removeVideoFromBlacklist (url: string, token: string, videoId: number | string, 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,
+ updateVideoBlacklist
+}
--- /dev/null
+import { makeDeleteRequest, makeGetRequest } from '../'
+import { buildAbsoluteFixturePath, makeUploadRequest } from '../index'
+import * as request from 'supertest'
+import * as chai from 'chai'
+
+const expect = chai.expect
+
+function createVideoCaption (args: {
+ url: string,
+ accessToken: string
+ videoId: string | number
+ language: string
+ fixture: string,
+ mimeType?: string,
+ statusCodeExpected?: number
+}) {
+ const path = '/api/v1/videos/' + args.videoId + '/captions/' + args.language
+
+ const captionfile = buildAbsoluteFixturePath(args.fixture)
+ const captionfileAttach = args.mimeType ? [ captionfile, { contentType: args.mimeType } ] : captionfile
+
+ return makeUploadRequest({
+ method: 'PUT',
+ url: args.url,
+ path,
+ token: args.accessToken,
+ fields: {},
+ attaches: {
+ captionfile: captionfileAttach
+ },
+ statusCodeExpected: args.statusCodeExpected || 204
+ })
+}
+
+function listVideoCaptions (url: string, videoId: string | number) {
+ const path = '/api/v1/videos/' + videoId + '/captions'
+
+ return makeGetRequest({
+ url,
+ path,
+ statusCodeExpected: 200
+ })
+}
+
+function deleteVideoCaption (url: string, token: string, videoId: string | number, language: string) {
+ const path = '/api/v1/videos/' + videoId + '/captions/' + language
+
+ return makeDeleteRequest({
+ url,
+ token,
+ path,
+ statusCodeExpected: 204
+ })
+}
+
+async function testCaptionFile (url: string, captionPath: string, containsString: string) {
+ const res = await request(url)
+ .get(captionPath)
+ .expect(200)
+
+ expect(res.text).to.contain(containsString)
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ createVideoCaption,
+ listVideoCaptions,
+ testCaptionFile,
+ deleteVideoCaption
+}
--- /dev/null
+import * as request from 'supertest'
+
+function changeVideoOwnership (url: string, token: string, videoId: number | string, username) {
+ const path = '/api/v1/videos/' + videoId + '/give-ownership'
+
+ return request(url)
+ .post(path)
+ .set('Accept', 'application/json')
+ .set('Authorization', 'Bearer ' + token)
+ .send({ username })
+ .expect(204)
+}
+
+function getVideoChangeOwnershipList (url: string, token: string) {
+ const path = '/api/v1/videos/ownership'
+
+ return request(url)
+ .get(path)
+ .query({ sort: '-createdAt' })
+ .set('Accept', 'application/json')
+ .set('Authorization', 'Bearer ' + token)
+ .expect(200)
+ .expect('Content-Type', /json/)
+}
+
+function acceptChangeOwnership (url: string, token: string, ownershipId: string, channelId: number, expectedStatus = 204) {
+ const path = '/api/v1/videos/ownership/' + ownershipId + '/accept'
+
+ return request(url)
+ .post(path)
+ .set('Accept', 'application/json')
+ .set('Authorization', 'Bearer ' + token)
+ .send({ channelId })
+ .expect(expectedStatus)
+}
+
+function refuseChangeOwnership (url: string, token: string, ownershipId: string, expectedStatus = 204) {
+ const path = '/api/v1/videos/ownership/' + ownershipId + '/refuse'
+
+ return request(url)
+ .post(path)
+ .set('Accept', 'application/json')
+ .set('Authorization', 'Bearer ' + token)
+ .expect(expectedStatus)
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ changeVideoOwnership,
+ getVideoChangeOwnershipList,
+ acceptChangeOwnership,
+ refuseChangeOwnership
+}
--- /dev/null
+import * as request from 'supertest'
+import { VideoChannelCreate, VideoChannelUpdate } from '../../../../shared/models/videos'
+import { updateAvatarRequest } from '../index'
+
+function getVideoChannelsList (url: string, start: number, count: number, sort?: string) {
+ const path = '/api/v1/video-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, accountName: string, specialStatus = 200) {
+ const path = '/api/v1/accounts/' + accountName + '/video-channels'
+
+ return request(url)
+ .get(path)
+ .set('Accept', 'application/json')
+ .expect(specialStatus)
+ .expect('Content-Type', /json/)
+}
+
+function addVideoChannel (
+ url: string,
+ token: string,
+ videoChannelAttributesArg: VideoChannelCreate,
+ expectedStatus = 200
+) {
+ const path = '/api/v1/video-channels/'
+
+ // Default attributes
+ let attributes = {
+ displayName: 'my super video channel',
+ description: 'my super channel description',
+ support: 'my super channel support'
+ }
+ 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,
+ channelName: string,
+ attributes: VideoChannelUpdate,
+ expectedStatus = 204
+) {
+ const body = {}
+ const path = '/api/v1/video-channels/' + channelName
+
+ if (attributes.displayName) body['displayName'] = attributes.displayName
+ if (attributes.description) body['description'] = attributes.description
+ if (attributes.support) body['support'] = attributes.support
+
+ return request(url)
+ .put(path)
+ .send(body)
+ .set('Accept', 'application/json')
+ .set('Authorization', 'Bearer ' + token)
+ .expect(expectedStatus)
+}
+
+function deleteVideoChannel (url: string, token: string, channelName: string, expectedStatus = 204) {
+ const path = '/api/v1/video-channels/' + channelName
+
+ return request(url)
+ .delete(path)
+ .set('Accept', 'application/json')
+ .set('Authorization', 'Bearer ' + token)
+ .expect(expectedStatus)
+}
+
+function getVideoChannel (url: string, channelName: string) {
+ const path = '/api/v1/video-channels/' + channelName
+
+ return request(url)
+ .get(path)
+ .set('Accept', 'application/json')
+ .expect(200)
+ .expect('Content-Type', /json/)
+}
+
+function updateVideoChannelAvatar (options: {
+ url: string,
+ accessToken: string,
+ fixture: string,
+ videoChannelName: string | number
+}) {
+
+ const path = '/api/v1/video-channels/' + options.videoChannelName + '/avatar/pick'
+
+ return updateAvatarRequest(Object.assign(options, { path }))
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ updateVideoChannelAvatar,
+ getVideoChannelsList,
+ getAccountVideoChannelsList,
+ addVideoChannel,
+ updateVideoChannel,
+ deleteVideoChannel,
+ getVideoChannel
+}
--- /dev/null
+import * as request from 'supertest'
+import { makeDeleteRequest } from '../'
+
+function getVideoCommentThreads (url: string, videoId: number | string, start: number, count: number, sort?: string, token?: 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 })
+ if (token) req.set('Authorization', 'Bearer ' + token)
+
+ return req.set('Accept', 'application/json')
+ .expect(200)
+ .expect('Content-Type', /json/)
+}
+
+function getVideoThreadComments (url: string, videoId: number | string, threadId: number, token?: string) {
+ const path = '/api/v1/videos/' + videoId + '/comment-threads/' + threadId
+
+ const req = request(url)
+ .get(path)
+ .set('Accept', 'application/json')
+
+ if (token) req.set('Authorization', 'Bearer ' + token)
+
+ return req.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)
+}
+
+function deleteVideoComment (
+ url: string,
+ token: string,
+ videoId: number | string,
+ commentId: number,
+ statusCodeExpected = 204
+) {
+ const path = '/api/v1/videos/' + videoId + '/comments/' + commentId
+
+ return makeDeleteRequest({
+ url,
+ path,
+ token,
+ statusCodeExpected
+ })
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ getVideoCommentThreads,
+ getVideoThreadComments,
+ addVideoCommentThread,
+ addVideoCommentReply,
+ deleteVideoComment
+}
--- /dev/null
+import { makePutBodyRequest } from '../requests/requests'
+
+function userWatchVideo (url: string, token: string, videoId: number | string, currentTime: number) {
+ const path = '/api/v1/videos/' + videoId + '/watching'
+ const fields = { currentTime }
+
+ return makePutBodyRequest({ url, path, token, fields, statusCodeExpected: 204 })
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ userWatchVideo
+}
--- /dev/null
+import { VideoImportCreate } from '../../../../shared/models/videos'
+import { makeGetRequest, makeUploadRequest } from '..'
+
+function getYoutubeVideoUrl () {
+ return 'https://youtu.be/msX3jv1XdvM'
+}
+
+function getMagnetURI () {
+ // tslint:disable:max-line-length
+ return 'magnet:?xs=https%3A%2F%2Fpeertube2.cpy.re%2Fstatic%2Ftorrents%2Fb209ca00-c8bb-4b2b-b421-1ede169f3dbc-720.torrent&xt=urn:btih:0f498834733e8057ed5c6f2ee2b4efd8d84a76ee&dn=super+peertube2+video&tr=wss%3A%2F%2Fpeertube2.cpy.re%3A443%2Ftracker%2Fsocket&tr=https%3A%2F%2Fpeertube2.cpy.re%2Ftracker%2Fannounce&ws=https%3A%2F%2Fpeertube2.cpy.re%2Fstatic%2Fwebseed%2Fb209ca00-c8bb-4b2b-b421-1ede169f3dbc-720.mp4'
+}
+
+function importVideo (url: string, token: string, attributes: VideoImportCreate) {
+ const path = '/api/v1/videos/imports'
+
+ let attaches: any = {}
+ if (attributes.torrentfile) attaches = { torrentfile: attributes.torrentfile }
+
+ return makeUploadRequest({
+ url,
+ path,
+ token,
+ attaches,
+ fields: attributes,
+ statusCodeExpected: 200
+ })
+}
+
+function getMyVideoImports (url: string, token: string, sort?: string) {
+ const path = '/api/v1/users/me/videos/imports'
+
+ const query = {}
+ if (sort) query['sort'] = sort
+
+ return makeGetRequest({
+ url,
+ query,
+ path,
+ token,
+ statusCodeExpected: 200
+ })
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ getYoutubeVideoUrl,
+ importVideo,
+ getMagnetURI,
+ getMyVideoImports
+}
--- /dev/null
+/* tslint:disable:no-unused-expression */
+
+import { expect } from 'chai'
+import { existsSync, readdir, readFile } from 'fs-extra'
+import * as parseTorrent from 'parse-torrent'
+import { extname, join } from 'path'
+import * as request from 'supertest'
+import {
+ buildAbsoluteFixturePath,
+ getMyUserInformation,
+ immutableAssign,
+ makeGetRequest,
+ makePutBodyRequest,
+ makeUploadRequest,
+ root,
+ ServerInfo,
+ testImage
+} from '../'
+import { VideoDetails, VideoPrivacy } from '../../../../shared/models/videos'
+import { VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_PRIVACIES } from '../../../initializers'
+import { dateIsValid, webtorrentAdd } from '../index'
+
+type VideoAttributes = {
+ name?: string
+ category?: number
+ licence?: number
+ language?: string
+ nsfw?: boolean
+ commentsEnabled?: boolean
+ waitTranscoding?: boolean
+ description?: string
+ tags?: string[]
+ channelId?: number
+ privacy?: VideoPrivacy
+ fixture?: string
+ thumbnailfile?: string
+ previewfile?: string
+ scheduleUpdate?: {
+ updateAt: string
+ privacy?: VideoPrivacy
+ }
+}
+
+function getVideoCategories (url: string) {
+ const path = '/api/v1/videos/categories'
+
+ return makeGetRequest({
+ url,
+ path,
+ statusCodeExpected: 200
+ })
+}
+
+function getVideoLicences (url: string) {
+ const path = '/api/v1/videos/licences'
+
+ return makeGetRequest({
+ url,
+ path,
+ statusCodeExpected: 200
+ })
+}
+
+function getVideoLanguages (url: string) {
+ const path = '/api/v1/videos/languages'
+
+ return makeGetRequest({
+ url,
+ path,
+ statusCodeExpected: 200
+ })
+}
+
+function getVideoPrivacies (url: string) {
+ const path = '/api/v1/videos/privacies'
+
+ return makeGetRequest({
+ url,
+ path,
+ statusCodeExpected: 200
+ })
+}
+
+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, xForwardedFor?: string) {
+ const path = '/api/v1/videos/' + id + '/views'
+
+ const req = request(url)
+ .post(path)
+ .set('Accept', 'application/json')
+
+ if (xForwardedFor) {
+ req.set('X-Forwarded-For', xForwardedFor)
+ }
+
+ return req.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 getVideosListWithToken (url: string, token: string, query: { nsfw?: boolean } = {}) {
+ const path = '/api/v1/videos'
+
+ return request(url)
+ .get(path)
+ .set('Authorization', 'Bearer ' + token)
+ .query(immutableAssign(query, { sort: 'name' }))
+ .set('Accept', 'application/json')
+ .expect(200)
+ .expect('Content-Type', /json/)
+}
+
+function getLocalVideos (url: string) {
+ const path = '/api/v1/videos'
+
+ return request(url)
+ .get(path)
+ .query({ sort: 'name', filter: 'local' })
+ .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 getAccountVideos (
+ url: string,
+ accessToken: string,
+ accountName: string,
+ start: number,
+ count: number,
+ sort?: string,
+ query: { nsfw?: boolean } = {}
+) {
+ const path = '/api/v1/accounts/' + accountName + '/videos'
+
+ return makeGetRequest({
+ url,
+ path,
+ query: immutableAssign(query, {
+ start,
+ count,
+ sort
+ }),
+ token: accessToken,
+ statusCodeExpected: 200
+ })
+}
+
+function getVideoChannelVideos (
+ url: string,
+ accessToken: string,
+ videoChannelName: string,
+ start: number,
+ count: number,
+ sort?: string,
+ query: { nsfw?: boolean } = {}
+) {
+ const path = '/api/v1/video-channels/' + videoChannelName + '/videos'
+
+ return makeGetRequest({
+ url,
+ path,
+ query: immutableAssign(query, {
+ start,
+ count,
+ sort
+ }),
+ token: accessToken,
+ statusCodeExpected: 200
+ })
+}
+
+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 getVideosWithFilters (url: string, query: { tagsAllOf: string[], categoryOneOf: number[] | number }) {
+ const path = '/api/v1/videos'
+
+ return request(url)
+ .get(path)
+ .query(query)
+ .set('Accept', 'application/json')
+ .expect(200)
+ .expect('Content-Type', /json/)
+}
+
+function removeVideo (url: string, token: string, id: number | string, expectedStatus = 204) {
+ const path = '/api/v1/videos'
+
+ return request(url)
+ .delete(path + '/' + id)
+ .set('Accept', 'application/json')
+ .set('Authorization', 'Bearer ' + token)
+ .expect(expectedStatus)
+}
+
+async function checkVideoFilesWereRemoved (
+ videoUUID: string,
+ serverNumber: number,
+ directories = [ 'videos', 'thumbnails', 'torrents', 'previews', 'captions' ]
+) {
+ const testDirectory = 'test' + serverNumber
+
+ for (const directory of directories) {
+ const directoryPath = join(root(), testDirectory, directory)
+
+ const directoryExists = existsSync(directoryPath)
+ expect(directoryExists).to.be.true
+
+ const files = await readdir(directoryPath)
+ for (const file of files) {
+ expect(file).to.not.contain(videoUUID)
+ }
+ }
+}
+
+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 */ }
+
+ // Override default attributes
+ const attributes = Object.assign({
+ name: 'my super video',
+ category: 5,
+ licence: 4,
+ language: 'zh',
+ channelId: defaultChannelId,
+ nsfw: true,
+ waitTranscoding: false,
+ description: 'my super description',
+ support: 'my super support text',
+ tags: [ 'tag' ],
+ privacy: VideoPrivacy.PUBLIC,
+ commentsEnabled: true,
+ fixture: 'video_short.webm'
+ }, videoAttributesArg)
+
+ const req = request(url)
+ .post(path)
+ .set('Accept', 'application/json')
+ .set('Authorization', 'Bearer ' + accessToken)
+ .field('name', attributes.name)
+ .field('nsfw', JSON.stringify(attributes.nsfw))
+ .field('commentsEnabled', JSON.stringify(attributes.commentsEnabled))
+ .field('waitTranscoding', JSON.stringify(attributes.waitTranscoding))
+ .field('privacy', attributes.privacy.toString())
+ .field('channelId', attributes.channelId)
+
+ if (attributes.description !== undefined) {
+ req.field('description', attributes.description)
+ }
+ if (attributes.language !== undefined) {
+ req.field('language', attributes.language.toString())
+ }
+ if (attributes.category !== undefined) {
+ req.field('category', attributes.category.toString())
+ }
+ if (attributes.licence !== undefined) {
+ req.field('licence', attributes.licence.toString())
+ }
+
+ for (let i = 0; i < attributes.tags.length; i++) {
+ req.field('tags[' + i + ']', attributes.tags[i])
+ }
+
+ if (attributes.thumbnailfile !== undefined) {
+ req.attach('thumbnailfile', buildAbsoluteFixturePath(attributes.thumbnailfile))
+ }
+ if (attributes.previewfile !== undefined) {
+ req.attach('previewfile', buildAbsoluteFixturePath(attributes.previewfile))
+ }
+
+ if (attributes.scheduleUpdate) {
+ req.field('scheduleUpdate[updateAt]', attributes.scheduleUpdate.updateAt)
+
+ if (attributes.scheduleUpdate.privacy) {
+ req.field('scheduleUpdate[privacy]', attributes.scheduleUpdate.privacy)
+ }
+ }
+
+ return req.attach('videofile', buildAbsoluteFixturePath(attributes.fixture))
+ .expect(specialStatus)
+}
+
+function updateVideo (url: string, accessToken: string, id: number | string, attributes: VideoAttributes, statusCodeExpected = 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 !== undefined) body['nsfw'] = JSON.stringify(attributes.nsfw)
+ if (attributes.commentsEnabled !== undefined) body['commentsEnabled'] = JSON.stringify(attributes.commentsEnabled)
+ if (attributes.description) body['description'] = attributes.description
+ if (attributes.tags) body['tags'] = attributes.tags
+ if (attributes.privacy) body['privacy'] = attributes.privacy
+ if (attributes.channelId) body['channelId'] = attributes.channelId
+ if (attributes.scheduleUpdate) body['scheduleUpdate'] = attributes.scheduleUpdate
+
+ // Upload request
+ if (attributes.thumbnailfile || attributes.previewfile) {
+ const attaches: any = {}
+ if (attributes.thumbnailfile) attaches.thumbnailfile = attributes.thumbnailfile
+ if (attributes.previewfile) attaches.previewfile = attributes.previewfile
+
+ return makeUploadRequest({
+ url,
+ method: 'PUT',
+ path,
+ token: accessToken,
+ fields: body,
+ attaches,
+ statusCodeExpected
+ })
+ }
+
+ return makePutBodyRequest({
+ url,
+ path,
+ fields: body,
+ token: accessToken,
+ statusCodeExpected
+ })
+}
+
+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<any>((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))
+ })
+ })
+}
+
+async function completeVideoCheck (
+ url: string,
+ video: any,
+ attributes: {
+ name: string
+ category: number
+ licence: number
+ language: string
+ nsfw: boolean
+ commentsEnabled: boolean
+ description: string
+ publishedAt?: string
+ support: string
+ account: {
+ name: string
+ host: string
+ }
+ isLocal: boolean
+ tags: string[]
+ privacy: number
+ likes?: number
+ dislikes?: number
+ duration: number
+ channel: {
+ displayName: string
+ name: string
+ description
+ isLocal: boolean
+ }
+ fixture: string
+ files: {
+ resolution: number
+ size: number
+ }[],
+ thumbnailfile?: string
+ previewfile?: string
+ }
+) {
+ if (!attributes.likes) attributes.likes = 0
+ if (!attributes.dislikes) attributes.dislikes = 0
+
+ expect(video.name).to.equal(attributes.name)
+ expect(video.category.id).to.equal(attributes.category)
+ expect(video.category.label).to.equal(attributes.category !== null ? VIDEO_CATEGORIES[attributes.category] : 'Misc')
+ expect(video.licence.id).to.equal(attributes.licence)
+ expect(video.licence.label).to.equal(attributes.licence !== null ? VIDEO_LICENCES[attributes.licence] : 'Unknown')
+ expect(video.language.id).to.equal(attributes.language)
+ expect(video.language.label).to.equal(attributes.language !== null ? VIDEO_LANGUAGES[attributes.language] : 'Unknown')
+ expect(video.privacy.id).to.deep.equal(attributes.privacy)
+ expect(video.privacy.label).to.deep.equal(VIDEO_PRIVACIES[attributes.privacy])
+ expect(video.nsfw).to.equal(attributes.nsfw)
+ expect(video.description).to.equal(attributes.description)
+ expect(video.account.id).to.be.a('number')
+ expect(video.account.uuid).to.be.a('string')
+ expect(video.account.host).to.equal(attributes.account.host)
+ expect(video.account.name).to.equal(attributes.account.name)
+ expect(video.channel.displayName).to.equal(attributes.channel.displayName)
+ expect(video.channel.name).to.equal(attributes.channel.name)
+ expect(video.likes).to.equal(attributes.likes)
+ expect(video.dislikes).to.equal(attributes.dislikes)
+ expect(video.isLocal).to.equal(attributes.isLocal)
+ expect(video.duration).to.equal(attributes.duration)
+ expect(dateIsValid(video.createdAt)).to.be.true
+ expect(dateIsValid(video.publishedAt)).to.be.true
+ expect(dateIsValid(video.updatedAt)).to.be.true
+
+ if (attributes.publishedAt) {
+ expect(video.publishedAt).to.equal(attributes.publishedAt)
+ }
+
+ const res = await getVideo(url, video.uuid)
+ const videoDetails: VideoDetails = res.body
+
+ expect(videoDetails.files).to.have.lengthOf(attributes.files.length)
+ expect(videoDetails.tags).to.deep.equal(attributes.tags)
+ expect(videoDetails.account.name).to.equal(attributes.account.name)
+ expect(videoDetails.account.host).to.equal(attributes.account.host)
+ expect(video.channel.displayName).to.equal(attributes.channel.displayName)
+ expect(video.channel.name).to.equal(attributes.channel.name)
+ expect(videoDetails.channel.host).to.equal(attributes.account.host)
+ expect(videoDetails.channel.isLocal).to.equal(attributes.channel.isLocal)
+ expect(dateIsValid(videoDetails.channel.createdAt.toString())).to.be.true
+ expect(dateIsValid(videoDetails.channel.updatedAt.toString())).to.be.true
+ expect(videoDetails.commentsEnabled).to.equal(attributes.commentsEnabled)
+
+ for (const attributeFile of attributes.files) {
+ const file = videoDetails.files.find(f => f.resolution.id === attributeFile.resolution)
+ expect(file).not.to.be.undefined
+
+ let extension = extname(attributes.fixture)
+ // Transcoding enabled on server 2, extension will always be .mp4
+ if (attributes.account.host === 'localhost:9002') extension = '.mp4'
+
+ const magnetUri = file.magnetUri
+ expect(file.magnetUri).to.have.lengthOf.above(2)
+ expect(file.torrentUrl).to.equal(`http://${attributes.account.host}/static/torrents/${videoDetails.uuid}-${file.resolution.id}.torrent`)
+ expect(file.fileUrl).to.equal(`http://${attributes.account.host}/static/webseed/${videoDetails.uuid}-${file.resolution.id}${extension}`)
+ expect(file.resolution.id).to.equal(attributeFile.resolution)
+ expect(file.resolution.label).to.equal(attributeFile.resolution + 'p')
+
+ const minSize = attributeFile.size - ((10 * attributeFile.size) / 100)
+ const maxSize = attributeFile.size + ((10 * attributeFile.size) / 100)
+ expect(file.size,
+ 'File size for resolution ' + file.resolution.label + ' outside confidence interval (' + minSize + '> size <' + maxSize + ')')
+ .to.be.above(minSize).and.below(maxSize)
+
+ {
+ await testImage(url, attributes.thumbnailfile || attributes.fixture, videoDetails.thumbnailPath)
+ }
+
+ if (attributes.previewfile) {
+ await testImage(url, attributes.previewfile, videoDetails.previewPath)
+ }
+
+ const torrent = await webtorrentAdd(magnetUri, true)
+ 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('')
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ getVideoDescription,
+ getVideoCategories,
+ getVideoLicences,
+ getVideoPrivacies,
+ getVideoLanguages,
+ getMyVideos,
+ getAccountVideos,
+ getVideoChannelVideos,
+ getVideo,
+ getVideoWithToken,
+ getVideosList,
+ getVideosListPagination,
+ getVideosListSort,
+ removeVideo,
+ getVideosListWithToken,
+ uploadVideo,
+ getVideosWithFilters,
+ updateVideo,
+ rateVideo,
+ viewVideo,
+ parseTorrentVideo,
+ getLocalVideos,
+ completeVideoCheck,
+ checkVideoFilesWereRemoved
+}