/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
-import 'mocha'
import { expect } from 'chai'
import { pick } from '@shared/core-utils'
+import { HttpStatusCode, UserRole, Video, VideoDetails, VideoInclude, VideoPrivacy } from '@shared/models'
import {
cleanupTests,
createMultipleServers,
makeGetRequest,
PeerTubeServer,
setAccessTokensToServers,
+ setDefaultAccountAvatar,
setDefaultVideoChannel,
waitJobs
-} from '@shared/extra-utils'
-import { HttpStatusCode, UserRole, Video, VideoInclude, VideoPrivacy } from '@shared/models'
+} from '@shared/server-commands'
describe('Test videos filter', function () {
let servers: PeerTubeServer[]
let paths: string[]
let remotePaths: string[]
+ const subscriptionVideosPath = '/api/v1/users/me/subscriptions/videos'
+
// ---------------------------------------------------------------
before(async function () {
- this.timeout(160000)
+ this.timeout(240000)
servers = await createMultipleServers(2)
await setAccessTokensToServers(servers)
await setDefaultVideoChannel(servers)
+ await setDefaultAccountAvatar(servers)
+
+ await servers[1].config.enableMinimumTranscoding()
for (const server of servers) {
const moderator = { username: 'moderator', password: 'my super password' }
const attributes = { name: 'private ' + server.serverNumber, privacy: VideoPrivacy.PRIVATE }
await server.videos.upload({ attributes })
}
+
+ // Subscribing to itself
+ await server.subscriptions.add({ targetUri: 'root_channel@' + server.host })
}
await doubleFollow(servers[0], servers[1])
`/api/v1/video-channels/root_channel/videos`,
`/api/v1/accounts/root/videos`,
'/api/v1/videos',
- '/api/v1/search/videos'
+ '/api/v1/search/videos',
+ subscriptionVideosPath
]
remotePaths = [
describe('Check deprecated videos filter', function () {
- async function getVideosNames (server: PeerTubeServer, token: string, filter: string, expectedStatus = HttpStatusCode.OK_200) {
+ async function getVideosNames (options: {
+ server: PeerTubeServer
+ token: string
+ filter: string
+ skipSubscription?: boolean
+ expectedStatus?: HttpStatusCode
+ }) {
+ const { server, token, filter, skipSubscription = false, expectedStatus = HttpStatusCode.OK_200 } = options
+
const videosResults: Video[][] = []
for (const path of paths) {
+ if (skipSubscription && path === subscriptionVideosPath) continue
+
const res = await makeGetRequest({
url: server.url,
path,
it('Should display local videos', async function () {
for (const server of servers) {
- const namesResults = await getVideosNames(server, server.accessToken, 'local')
+ const namesResults = await getVideosNames({ server, token: server.accessToken, filter: 'local' })
for (const names of namesResults) {
expect(names).to.have.lengthOf(1)
expect(names[0]).to.equal('public ' + server.serverNumber)
for (const server of servers) {
for (const token of [ server.accessToken, server['moderatorAccessToken'] ]) {
- const namesResults = await getVideosNames(server, token, 'all-local')
+ const namesResults = await getVideosNames({ server, token, filter: 'all-local', skipSubscription: true })
for (const names of namesResults) {
expect(names).to.have.lengthOf(3)
for (const server of servers) {
for (const token of [ server.accessToken, server['moderatorAccessToken'] ]) {
- const [ channelVideos, accountVideos, videos, searchVideos ] = await getVideosNames(server, token, 'all')
+ const [ channelVideos, accountVideos, videos, searchVideos ] = await getVideosNames({ server, token, filter: 'all' })
expect(channelVideos).to.have.lengthOf(3)
expect(accountVideos).to.have.lengthOf(3)
server: PeerTubeServer
path: string
isLocal?: boolean
+ hasWebtorrentFiles?: boolean
+ hasHLSFiles?: boolean
include?: VideoInclude
+ privacyOneOf?: VideoPrivacy[]
category?: number
tagsAllOf?: string[]
token?: string
expectedStatus?: HttpStatusCode
+ excludeAlreadyWatched?: boolean
}) {
const res = await makeGetRequest({
url: options.server.url,
path: options.path,
token: options.token ?? options.server.accessToken,
query: {
- ...pick(options, [ 'isLocal', 'include', 'category', 'tagsAllOf' ]),
+ ...pick(options, [
+ 'isLocal',
+ 'include',
+ 'category',
+ 'tagsAllOf',
+ 'hasWebtorrentFiles',
+ 'hasHLSFiles',
+ 'privacyOneOf',
+ 'excludeAlreadyWatched'
+ ]),
sort: 'createdAt'
},
return res.body.data as Video[]
}
- async function getVideosNames (options: {
- server: PeerTubeServer
- isLocal?: boolean
- include?: VideoInclude
- token?: string
- expectedStatus?: HttpStatusCode
- }) {
+ async function getVideosNames (
+ options: {
+ server: PeerTubeServer
+ isLocal?: boolean
+ include?: VideoInclude
+ privacyOneOf?: VideoPrivacy[]
+ token?: string
+ expectedStatus?: HttpStatusCode
+ skipSubscription?: boolean
+ excludeAlreadyWatched?: boolean
+ }
+ ) {
+ const { skipSubscription = false } = options
const videosResults: string[][] = []
for (const path of paths) {
+ if (skipSubscription && path === subscriptionVideosPath) continue
+
const videos = await listVideos({ ...options, path })
videosResults.push(videos.map(v => v.name))
for (const server of servers) {
for (const token of [ server.accessToken, server['moderatorAccessToken'] ]) {
- const namesResults = await getVideosNames({
- server,
- token,
- isLocal: true,
- include: VideoInclude.HIDDEN_PRIVACY
- })
+ const namesResults = await getVideosNames(
+ {
+ server,
+ token,
+ isLocal: true,
+ privacyOneOf: [ VideoPrivacy.UNLISTED, VideoPrivacy.PUBLIC, VideoPrivacy.PRIVATE ],
+ skipSubscription: true
+ }
+ )
for (const names of namesResults) {
expect(names).to.have.lengthOf(3)
const [ channelVideos, accountVideos, videos, searchVideos ] = await getVideosNames({
server,
token,
- include: VideoInclude.HIDDEN_PRIVACY
+ privacyOneOf: [ VideoPrivacy.UNLISTED, VideoPrivacy.PUBLIC, VideoPrivacy.PRIVATE ]
})
expect(channelVideos).to.have.lengthOf(3)
})
it('Should display only remote videos', async function () {
- this.timeout(40000)
+ this.timeout(120000)
await servers[1].videos.upload({ attributes: { name: 'remote video' } })
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')
-
}
{
}
}
})
+
+ it('Should filter by HLS or WebTorrent files', async function () {
+ this.timeout(360000)
+
+ const finderFactory = (name: string) => (videos: Video[]) => 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
+ }
+ }
+ })
+
+ it('Should filter already watched videos by the user', async function () {
+ const { id } = await servers[0].videos.upload({ attributes: { name: 'video for history' } })
+
+ for (const path of paths) {
+ const videos = await listVideos({ server: servers[0], path, isLocal: true, excludeAlreadyWatched: true })
+ const foundVideo = videos.find(video => video.id === id)
+
+ expect(foundVideo).to.not.be.undefined
+ }
+ await servers[0].views.view({ id, token: servers[0].accessToken })
+
+ for (const path of paths) {
+ const videos = await listVideos({ server: servers[0], path, excludeAlreadyWatched: true })
+ const foundVideo = videos.find(video => video.id === id)
+
+ expect(foundVideo).to.be.undefined
+ }
+ })
})
after(async function () {