import 'mocha' ; import * as chai from 'chai' ; import { wait } from '@shared/core-utils' ; import { cleanupTests , createMultipleServers , doubleFollow , PeerTubeServer , setAccessTokensToServers , waitJobs } from '@shared/server-commands' ; const expect = chai . expect ; describe ( 'Test AP cleaner' , function ( ) { let servers = [ ] ; let videoUUID1 ; let videoUUID2 ; let videoUUID3 ; let videoUUIDs ; before ( async function ( ) { this . timeout ( 120000 ) ; const config = { federation : { videos : { cleanup_remote_interactions : true } } } ; servers = await createMultipleServers ( 3 , config ) ; await setAccessTokensToServers ( servers ) ; await Promise . all ( [ doubleFollow ( servers [ 0 ] , servers [ 1 ] ) , doubleFollow ( servers [ 1 ] , servers [ 2 ] ) , doubleFollow ( servers [ 0 ] , servers [ 2 ] ) ] ) ; videoUUID1 = ( await servers [ 0 ] . videos . quickUpload ( { name : 'server 1' } ) ) . uuid ; videoUUID2 = ( await servers [ 1 ] . videos . quickUpload ( { name : 'server 2' } ) ) . uuid ; videoUUID3 = ( await servers [ 2 ] . videos . quickUpload ( { name : 'server 3' } ) ) . uuid ; videoUUIDs = [ videoUUID1 , videoUUID2 , videoUUID3 ] ; await waitJobs ( servers ) ; for ( const server of servers ) { for ( const uuid of videoUUIDs ) { await server . videos . rate ( { id : uuid , rating : 'like' } ) ; await server . comments . createThread ( { videoId : uuid , text : 'comment' } ) ; } } await waitJobs ( servers ) ; } ) ; it ( 'Should have the correct likes' , async function ( ) { for ( const server of servers ) { for ( const uuid of videoUUIDs ) { const video = await server . videos . get ( { id : uuid } ) ; expect ( video . likes ) . to . equal ( 3 ) ; expect ( video . dislikes ) . to . equal ( 0 ) ; } } } ) ; it ( 'Should destroy server 3 internal likes and correctly clean them' , async function ( ) { this . timeout ( 20000 ) ; await servers [ 2 ] . sql . deleteAll ( 'accountVideoRate' ) ; for ( const uuid of videoUUIDs ) { await servers [ 2 ] . sql . setVideoField ( uuid , 'likes' , '0' ) ; } await wait ( 5000 ) ; await waitJobs ( servers ) ; { const video = await servers [ 0 ] . videos . get ( { id : videoUUID1 } ) ; expect ( video . likes ) . to . equal ( 2 ) ; expect ( video . dislikes ) . to . equal ( 0 ) ; } { const video = await servers [ 0 ] . videos . get ( { id : videoUUID2 } ) ; expect ( video . likes ) . to . equal ( 3 ) ; expect ( video . dislikes ) . to . equal ( 0 ) ; } } ) ; it ( 'Should update rates to dislikes' , async function ( ) { this . timeout ( 20000 ) ; for ( const server of servers ) { for ( const uuid of videoUUIDs ) { await server . videos . rate ( { id : uuid , rating : 'dislike' } ) ; } } await waitJobs ( servers ) ; for ( const server of servers ) { for ( const uuid of videoUUIDs ) { const video = await server . videos . get ( { id : uuid } ) ; expect ( video . likes ) . to . equal ( 0 ) ; expect ( video . dislikes ) . to . equal ( 3 ) ; } } } ) ; it ( 'Should destroy server 3 internal dislikes and correctly clean them' , async function ( ) { this . timeout ( 20000 ) ; await servers [ 2 ] . sql . deleteAll ( 'accountVideoRate' ) ; for ( const uuid of videoUUIDs ) { await servers [ 2 ] . sql . setVideoField ( uuid , 'dislikes' , '0' ) ; } await wait ( 5000 ) ; await waitJobs ( servers ) ; { const video = await servers [ 0 ] . videos . get ( { id : videoUUID1 } ) ; expect ( video . likes ) . to . equal ( 0 ) ; expect ( video . dislikes ) . to . equal ( 2 ) ; } { const video = await servers [ 0 ] . videos . get ( { id : videoUUID2 } ) ; expect ( video . likes ) . to . equal ( 0 ) ; expect ( video . dislikes ) . to . equal ( 3 ) ; } } ) ; it ( 'Should destroy server 3 internal shares and correctly clean them' , async function ( ) { this . timeout ( 20000 ) ; const preCount = await servers [ 0 ] . sql . getCount ( 'videoShare' ) ; expect ( preCount ) . to . equal ( 6 ) ; await servers [ 2 ] . sql . deleteAll ( 'videoShare' ) ; await wait ( 5000 ) ; await waitJobs ( servers ) ; const postCount = await servers [ 0 ] . sql . getCount ( 'videoShare' ) ; expect ( postCount ) . to . equal ( 6 ) ; } ) ; it ( 'Should destroy server 3 internal comments and correctly clean them' , async function ( ) { this . timeout ( 20000 ) ; { const { total } = await servers [ 0 ] . comments . listThreads ( { videoId : videoUUID1 } ) ; expect ( total ) . to . equal ( 3 ) ; } await servers [ 2 ] . sql . deleteAll ( 'videoComment' ) ; await wait ( 5000 ) ; await waitJobs ( servers ) ; { const { total } = await servers [ 0 ] . comments . listThreads ( { videoId : videoUUID1 } ) ; expect ( total ) . to . equal ( 2 ) ; } } ) ; it ( 'Should correctly update rate URLs' , async function ( ) { this . timeout ( 30000 ) ; async function check ( like , ofServerUrl , urlSuffix , remote ) { const query = `SELECT "videoId", "accountVideoRate".url FROM "accountVideoRate" ` + `INNER JOIN video ON "accountVideoRate"."videoId" = video.id AND remote IS ${ remote } WHERE "accountVideoRate"."url" LIKE '${ like }'` ; const res = await servers [ 0 ] . sql . selectQuery ( query ) ; for ( const rate of res ) { const matcher = new RegExp ( `^${ ofServerUrl }/accounts/root/dislikes/\\d+${ urlSuffix }$` ) ; expect ( rate . url ) . to . match ( matcher ) ; } } async function checkLocal ( ) { const startsWith = 'http://' + servers [ 0 ] . host + '%' ; await check ( startsWith , servers [ 0 ] . url , '' , 'false' ) ; await check ( startsWith , servers [ 0 ] . url , '' , 'true' ) ; } async function checkRemote ( suffix ) { const startsWith = 'http://' + servers [ 1 ] . host + '%' ; await check ( startsWith , servers [ 1 ] . url , suffix , 'false' ) ; await check ( startsWith , servers [ 1 ] . url , '' , 'true' ) ; } await checkLocal ( ) ; await checkRemote ( '' ) ; { const query = `UPDATE "accountVideoRate" SET url = url || 'stan'` ; await servers [ 1 ] . sql . updateQuery ( query ) ; await wait ( 5000 ) ; await waitJobs ( servers ) ; } await checkLocal ( ) ; await checkRemote ( 'stan' ) ; } ) ; it ( 'Should correctly update comment URLs' , async function ( ) { this . timeout ( 30000 ) ; async function check ( like , ofServerUrl , urlSuffix , remote ) { const query = `SELECT "videoId", "videoComment".url, uuid as "videoUUID" FROM "videoComment" ` + `INNER JOIN video ON "videoComment"."videoId" = video.id AND remote IS ${ remote } WHERE "videoComment"."url" LIKE '${ like }'` ; const res = await servers [ 0 ] . sql . selectQuery ( query ) ; for ( const comment of res ) { const matcher = new RegExp ( `${ ofServerUrl }/videos/watch/${ comment . videoUUID }/comments/\\d+${ urlSuffix }` ) ; expect ( comment . url ) . to . match ( matcher ) ; } } async function checkLocal ( ) { const startsWith = 'http://' + servers [ 0 ] . host + '%' ; await check ( startsWith , servers [ 0 ] . url , '' , 'false' ) ; await check ( startsWith , servers [ 0 ] . url , '' , 'true' ) ; } async function checkRemote ( suffix ) { const startsWith = 'http://' + servers [ 1 ] . host + '%' ; await check ( startsWith , servers [ 1 ] . url , suffix , 'false' ) ; await check ( startsWith , servers [ 1 ] . url , '' , 'true' ) ; } { const query = `UPDATE "videoComment" SET url = url || 'kyle'` ; await servers [ 1 ] . sql . updateQuery ( query ) ; await wait ( 5000 ) ; await waitJobs ( servers ) ; } await checkLocal ( ) ; await checkRemote ( 'kyle' ) ; } ) ; it ( 'Should remove unavailable remote resources' , async function ( ) { this . timeout ( 240000 ) ; async function expectNotDeleted ( ) { { const video = await servers [ 0 ] . videos . get ( { id : uuid } ) ; expect ( video . likes ) . to . equal ( 3 ) ; expect ( video . dislikes ) . to . equal ( 0 ) ; } { const { total } = await servers [ 0 ] . comments . listThreads ( { videoId : uuid } ) ; expect ( total ) . to . equal ( 3 ) ; } } async function expectDeleted ( ) { { const video = await servers [ 0 ] . videos . get ( { id : uuid } ) ; expect ( video . likes ) . to . equal ( 2 ) ; expect ( video . dislikes ) . to . equal ( 0 ) ; } { const { total } = await servers [ 0 ] . comments . listThreads ( { videoId : uuid } ) ; expect ( total ) . to . equal ( 2 ) ; } } const uuid = ( await servers [ 0 ] . videos . quickUpload ( { name : 'server 1 video 2' } ) ) . uuid ; await waitJobs ( servers ) ; for ( const server of servers ) { await server . videos . rate ( { id : uuid , rating : 'like' } ) ; await server . comments . createThread ( { videoId : uuid , text : 'comment' } ) ; } await waitJobs ( servers ) ; await expectNotDeleted ( ) ; await servers [ 1 ] . kill ( ) ; await wait ( 5000 ) ; await expectNotDeleted ( ) ; let continueWhile = true ; do { try { await expectDeleted ( ) ; continueWhile = false ; } catch { } } while ( continueWhile ) ; } ) ; after ( async function ( ) { await cleanupTests ( servers ) ; } ) ; } ) ;