import 'mocha' ; import { expect } from 'chai' ; import { pick } from '@shared/core-utils' ; import { cleanupTests , createMultipleServers , doubleFollow , makeGetRequest , PeerTubeServer , setAccessTokensToServers , setDefaultVideoChannel , waitJobs } from '@shared/server-commands' ; import { HttpStatusCode , UserRole , Video , VideoDetails , VideoInclude , VideoPrivacy } from '@shared/models' ; describe ( 'Test videos filter' , function ( ) { let servers ; let paths ; let remotePaths ; before ( async function ( ) { this . timeout ( 160000 ) ; servers = await createMultipleServers ( 2 ) ; await setAccessTokensToServers ( servers ) ; await setDefaultVideoChannel ( servers ) ; for ( const server of servers ) { const moderator = { username : 'moderator' , password : 'my super password' } ; await server . users . create ( { username : moderator . username , password : moderator . password , role : UserRole . MODERATOR } ) ; server [ 'moderatorAccessToken' ] = await server . login . getAccessToken ( moderator ) ; await server . videos . upload ( { attributes : { name : 'public ' + server . serverNumber } } ) ; { const attributes = { name : 'unlisted ' + server . serverNumber , privacy : VideoPrivacy . UNLISTED } ; await server . videos . upload ( { attributes } ) ; } { const attributes = { name : 'private ' + server . serverNumber , privacy : VideoPrivacy . PRIVATE } ; await server . videos . upload ( { attributes } ) ; } } await doubleFollow ( servers [ 0 ] , servers [ 1 ] ) ; paths = [ `/api/v1/video-channels/root_channel/videos` , `/api/v1/accounts/root/videos` , '/api/v1/videos' , '/api/v1/search/videos' ] ; remotePaths = [ `/api/v1/video-channels/root_channel@${ servers [ 1 ] . host }/videos` , `/api/v1/accounts/root@${ servers [ 1 ] . host }/videos` , '/api/v1/videos' , '/api/v1/search/videos' ] ; } ) ; describe ( 'Check deprecated videos filter' , function ( ) { async function getVideosNames ( server , token , filter , expectedStatus = HttpStatusCode . OK_200 ) { const videosResults = [ ] ; for ( const path of paths ) { const res = await makeGetRequest ( { url : server . url , path , token , query : { sort : 'createdAt' , filter } , expectedStatus } ) ; videosResults . push ( res . body . data . map ( v => v . name ) ) ; } return videosResults ; } it ( 'Should display local videos' , async function ( ) { for ( const server of servers ) { const namesResults = await getVideosNames ( server , server . accessToken , 'local' ) ; for ( const names of namesResults ) { expect ( names ) . to . have . lengthOf ( 1 ) ; expect ( names [ 0 ] ) . to . equal ( 'public ' + server . serverNumber ) ; } } } ) ; it ( 'Should display all local videos by the admin or the moderator' , async function ( ) { for ( const server of servers ) { for ( const token of [ server . accessToken , server [ 'moderatorAccessToken' ] ] ) { const namesResults = await getVideosNames ( server , token , 'all-local' ) ; for ( const names of namesResults ) { expect ( names ) . to . have . lengthOf ( 3 ) ; expect ( names [ 0 ] ) . to . equal ( 'public ' + server . serverNumber ) ; expect ( names [ 1 ] ) . to . equal ( 'unlisted ' + server . serverNumber ) ; expect ( names [ 2 ] ) . to . equal ( 'private ' + server . serverNumber ) ; } } } } ) ; it ( 'Should display all videos by the admin or the moderator' , async function ( ) { for ( const server of servers ) { for ( const token of [ server . accessToken , server [ 'moderatorAccessToken' ] ] ) { const [ channelVideos , accountVideos , videos , searchVideos ] = await getVideosNames ( server , token , 'all' ) ; expect ( channelVideos ) . to . have . lengthOf ( 3 ) ; expect ( accountVideos ) . to . have . lengthOf ( 3 ) ; expect ( videos ) . to . have . lengthOf ( 5 ) ; expect ( searchVideos ) . to . have . lengthOf ( 5 ) ; } } } ) ; } ) ; describe ( 'Check videos filters' , function ( ) { async function listVideos ( options ) { const res = await makeGetRequest ( { url : options . server . url , path : options . path , token : options . token ?? options . server . accessToken , query : { ... pick ( options , [ 'isLocal' , 'include' , 'category' , 'tagsAllOf' , 'hasWebtorrentFiles' , 'hasHLSFiles' , 'privacyOneOf' ] ) , sort : 'createdAt' } , expectedStatus : options . expectedStatus ?? HttpStatusCode . OK_200 } ) ; return res . body . data as Video [ ] ; } async function getVideosNames ( options ) { const videosResults = [ ] ; for ( const path of paths ) { const videos = await listVideos ( { ... options , path } ) ; videosResults . push ( videos . map ( v => v . name ) ) ; } return videosResults ; } it ( 'Should display local videos' , async function ( ) { for ( const server of servers ) { const namesResults = await getVideosNames ( { server , isLocal : true } ) ; for ( const names of namesResults ) { expect ( names ) . to . have . lengthOf ( 1 ) ; expect ( names [ 0 ] ) . to . equal ( 'public ' + server . serverNumber ) ; } } } ) ; it ( 'Should display local videos with hidden privacy by the admin or the moderator' , async function ( ) { for ( const server of servers ) { for ( const token of [ server . accessToken , server [ 'moderatorAccessToken' ] ] ) { const namesResults = await getVideosNames ( { server , token , isLocal : true , privacyOneOf : [ VideoPrivacy . UNLISTED , VideoPrivacy . PUBLIC , VideoPrivacy . PRIVATE ] } ) ; for ( const names of namesResults ) { expect ( names ) . to . have . lengthOf ( 3 ) ; expect ( names [ 0 ] ) . to . equal ( 'public ' + server . serverNumber ) ; expect ( names [ 1 ] ) . to . equal ( 'unlisted ' + server . serverNumber ) ; expect ( names [ 2 ] ) . to . equal ( 'private ' + server . serverNumber ) ; } } } } ) ; it ( 'Should display all videos by the admin or the moderator' , async function ( ) { for ( const server of servers ) { for ( const token of [ server . accessToken , server [ 'moderatorAccessToken' ] ] ) { const [ channelVideos , accountVideos , videos , searchVideos ] = await getVideosNames ( { server , token , privacyOneOf : [ VideoPrivacy . UNLISTED , VideoPrivacy . PUBLIC , VideoPrivacy . PRIVATE ] } ) ; expect ( channelVideos ) . to . have . lengthOf ( 3 ) ; expect ( accountVideos ) . to . have . lengthOf ( 3 ) ; expect ( videos ) . to . have . lengthOf ( 5 ) ; expect ( searchVideos ) . to . have . lengthOf ( 5 ) ; } } } ) ; it ( 'Should display only remote videos' , async function ( ) { this . timeout ( 40000 ) ; await servers [ 1 ] . videos . upload ( { attributes : { name : 'remote video' } } ) ; await waitJobs ( servers ) ; const finder = ( videos ) => videos . find ( v => v . name === 'remote video' ) ; for ( const path of remotePaths ) { { const videos = await listVideos ( { server : servers [ 0 ] , path } ) ; const video = finder ( videos ) ; expect ( video ) . to . exist ; } { const videos = await listVideos ( { server : servers [ 0 ] , path , isLocal : false } ) ; const video = finder ( videos ) ; expect ( video ) . to . exist ; } { const videos = await listVideos ( { server : servers [ 0 ] , path , isLocal : true } ) ; const video = finder ( videos ) ; expect ( video ) . to . not . exist ; } } } ) ; it ( 'Should include not published videos' , async function ( ) { await servers [ 0 ] . config . enableLive ( { allowReplay : false , transcoding : false } ) ; await servers [ 0 ] . live . create ( { fields : { name : 'live video' , channelId : servers [ 0 ] . store . channel . id , privacy : VideoPrivacy . PUBLIC } } ) ; const finder = ( videos ) => videos . find ( v => v . name === 'live video' ) ; for ( const path of paths ) { { const videos = await listVideos ( { server : servers [ 0 ] , path } ) ; const video = finder ( videos ) ; expect ( video ) . to . not . exist ; expect ( videos [ 0 ] . state ) . to . not . exist ; expect ( videos [ 0 ] . waitTranscoding ) . to . not . exist ; } { const videos = await listVideos ( { server : servers [ 0 ] , path , include : VideoInclude . NOT_PUBLISHED_STATE } ) ; const video = finder ( videos ) ; expect ( video ) . to . exist ; expect ( video . state ) . to . exist ; } } } ) ; it ( 'Should include blacklisted videos' , async function ( ) { const { id } = await servers [ 0 ] . videos . upload ( { attributes : { name : 'blacklisted' } } ) ; await servers [ 0 ] . blacklist . add ( { videoId : id } ) ; const finder = ( videos ) => videos . find ( v => v . name === 'blacklisted' ) ; for ( const path of paths ) { { const videos = await listVideos ( { server : servers [ 0 ] , path } ) ; const video = finder ( videos ) ; expect ( video ) . to . not . exist ; expect ( videos [ 0 ] . blacklisted ) . to . not . exist ; } { const videos = await listVideos ( { server : servers [ 0 ] , path , include : VideoInclude . BLACKLISTED } ) ; const video = finder ( videos ) ; expect ( video ) . to . exist ; expect ( video . blacklisted ) . to . be . true ; } } } ) ; it ( 'Should include videos from muted account' , async function ( ) { const finder = ( videos ) => videos . find ( v => v . name === 'remote video' ) ; await servers [ 0 ] . blocklist . addToServerBlocklist ( { account : 'root@' + servers [ 1 ] . host } ) ; for ( const path of remotePaths ) { { const videos = await listVideos ( { server : servers [ 0 ] , path } ) ; const video = finder ( videos ) ; expect ( video ) . to . not . exist ; if ( videos [ 0 ] ) { expect ( videos [ 0 ] . blockedOwner ) . to . not . exist ; expect ( videos [ 0 ] . blockedServer ) . to . not . exist ; } } { const videos = await listVideos ( { server : servers [ 0 ] , path , include : VideoInclude . BLOCKED_OWNER } ) ; const video = finder ( videos ) ; expect ( video ) . to . exist ; expect ( video . blockedServer ) . to . be . false ; expect ( video . blockedOwner ) . to . be . true ; } } await servers [ 0 ] . blocklist . removeFromServerBlocklist ( { account : 'root@' + servers [ 1 ] . host } ) ; } ) ; it ( 'Should include videos from muted server' , async function ( ) { const finder = ( videos ) => videos . find ( v => v . name === 'remote video' ) ; await servers [ 0 ] . blocklist . addToServerBlocklist ( { server : servers [ 1 ] . host } ) ; for ( const path of remotePaths ) { { const videos = await listVideos ( { server : servers [ 0 ] , path } ) ; const video = finder ( videos ) ; expect ( video ) . to . not . exist ; if ( videos [ 0 ] ) { expect ( videos [ 0 ] . blockedOwner ) . to . not . exist ; expect ( videos [ 0 ] . blockedServer ) . to . not . exist ; } } { const videos = await listVideos ( { server : servers [ 0 ] , path , include : VideoInclude . BLOCKED_OWNER } ) ; const video = finder ( videos ) ; expect ( video ) . to . exist ; expect ( video . blockedServer ) . to . be . true ; expect ( video . blockedOwner ) . to . be . false ; } } await servers [ 0 ] . blocklist . removeFromServerBlocklist ( { server : servers [ 1 ] . host } ) ; } ) ; it ( 'Should include video files' , async function ( ) { for ( const path of paths ) { { const videos = await listVideos ( { server : servers [ 0 ] , path } ) ; for ( const video of videos ) { const videoWithFiles = video as VideoDetails ; expect ( videoWithFiles . files ) . to . not . exist ; expect ( videoWithFiles . streamingPlaylists ) . to . not . exist ; } } { const videos = await listVideos ( { server : servers [ 0 ] , path , include : VideoInclude . FILES } ) ; for ( const video of videos ) { const videoWithFiles = video as VideoDetails ; expect ( videoWithFiles . files ) . to . exist ; expect ( videoWithFiles . files ) . to . have . length . at . least ( 1 ) ; } } } } ) ; it ( 'Should filter by tags and category' , async function ( ) { await servers [ 0 ] . videos . upload ( { attributes : { name : 'tag filter' , tags : [ 'tag1' , 'tag2' ] } } ) ; await servers [ 0 ] . videos . upload ( { attributes : { name : 'tag filter with category' , tags : [ 'tag3' ] , category : 4 } } ) ; for ( const path of paths ) { { const videos = await listVideos ( { server : servers [ 0 ] , path , tagsAllOf : [ 'tag1' , 'tag2' ] } ) ; expect ( videos ) . to . have . lengthOf ( 1 ) ; expect ( videos [ 0 ] . name ) . to . equal ( 'tag filter' ) ; } { const videos = await listVideos ( { server : servers [ 0 ] , path , tagsAllOf : [ 'tag1' , 'tag3' ] } ) ; expect ( videos ) . to . have . lengthOf ( 0 ) ; } { const { data , total } = await servers [ 0 ] . videos . list ( { tagsAllOf : [ 'tag3' ] , categoryOneOf : [ 4 ] } ) ; expect ( total ) . to . equal ( 1 ) ; expect ( data [ 0 ] . name ) . to . equal ( 'tag filter with category' ) ; } { const { total } = await servers [ 0 ] . videos . list ( { tagsAllOf : [ 'tag4' ] , categoryOneOf : [ 4 ] } ) ; expect ( total ) . to . equal ( 0 ) ; } } } ) ; it ( 'Should filter by HLS or WebTorrent files' , async function ( ) { this . timeout ( 360000 ) ; const finderFactory = ( name ) => ( videos ) => videos . some ( v => v . name === name ) ; await servers [ 0 ] . config . enableTranscoding ( true , false ) ; await servers [ 0 ] . videos . upload ( { attributes : { name : 'webtorrent video' } } ) ; const hasWebtorrent = finderFactory ( 'webtorrent video' ) ; await waitJobs ( servers ) ; await servers [ 0 ] . config . enableTranscoding ( false , true ) ; await servers [ 0 ] . videos . upload ( { attributes : { name : 'hls video' } } ) ; const hasHLS = finderFactory ( 'hls video' ) ; await waitJobs ( servers ) ; await servers [ 0 ] . config . enableTranscoding ( true , true ) ; await servers [ 0 ] . videos . upload ( { attributes : { name : 'hls and webtorrent video' } } ) ; const hasBoth = finderFactory ( 'hls and webtorrent video' ) ; await waitJobs ( servers ) ; for ( const path of paths ) { { const videos = await listVideos ( { server : servers [ 0 ] , path , hasWebtorrentFiles : true } ) ; expect ( hasWebtorrent ( videos ) ) . to . be . true ; expect ( hasHLS ( videos ) ) . to . be . false ; expect ( hasBoth ( videos ) ) . to . be . true ; } { const videos = await listVideos ( { server : servers [ 0 ] , path , hasWebtorrentFiles : false } ) ; expect ( hasWebtorrent ( videos ) ) . to . be . false ; expect ( hasHLS ( videos ) ) . to . be . true ; expect ( hasBoth ( videos ) ) . to . be . false ; } { const videos = await listVideos ( { server : servers [ 0 ] , path , hasHLSFiles : true } ) ; expect ( hasWebtorrent ( videos ) ) . to . be . false ; expect ( hasHLS ( videos ) ) . to . be . true ; expect ( hasBoth ( videos ) ) . to . be . true ; } { const videos = await listVideos ( { server : servers [ 0 ] , path , hasHLSFiles : false } ) ; expect ( hasWebtorrent ( videos ) ) . to . be . true ; expect ( hasHLS ( videos ) ) . to . be . false ; expect ( hasBoth ( videos ) ) . to . be . false ; } { const videos = await listVideos ( { server : servers [ 0 ] , path , hasHLSFiles : false , hasWebtorrentFiles : false } ) ; expect ( hasWebtorrent ( videos ) ) . to . be . false ; expect ( hasHLS ( videos ) ) . to . be . false ; expect ( hasBoth ( videos ) ) . to . be . false ; } { const videos = await listVideos ( { server : servers [ 0 ] , path , hasHLSFiles : true , hasWebtorrentFiles : true } ) ; expect ( hasWebtorrent ( videos ) ) . to . be . false ; expect ( hasHLS ( videos ) ) . to . be . false ; expect ( hasBoth ( videos ) ) . to . be . true ; } } } ) ; } ) ; after ( async function ( ) { await cleanupTests ( servers ) ; } ) ; } ) ;