Refactor search query options
This commit is contained in:
parent
b033851fb5
commit
d688602710
|
@ -1,6 +1,6 @@
|
|||
import * as express from 'express'
|
||||
import { pickCommonVideoQuery } from '@server/helpers/query'
|
||||
import { getServerActor } from '@server/models/application/application'
|
||||
import { VideosWithSearchCommonQuery } from '@shared/models'
|
||||
import { buildNSFWFilter, getCountVideos, isUserAbleToSearchRemoteURI } from '../../helpers/express-utils'
|
||||
import { getFormattedObjects } from '../../helpers/utils'
|
||||
import { JobQueue } from '../../lib/job-queue'
|
||||
|
@ -159,27 +159,19 @@ async function listAccountVideos (req: express.Request, res: express.Response) {
|
|||
const account = res.locals.account
|
||||
const followerActorId = isUserAbleToSearchRemoteURI(res) ? null : undefined
|
||||
const countVideos = getCountVideos(req)
|
||||
const query = req.query as VideosWithSearchCommonQuery
|
||||
const query = pickCommonVideoQuery(req.query)
|
||||
|
||||
const apiOptions = await Hooks.wrapObject({
|
||||
...query,
|
||||
|
||||
followerActorId,
|
||||
start: query.start,
|
||||
count: query.count,
|
||||
sort: query.sort,
|
||||
search: req.query.search,
|
||||
includeLocalVideos: true,
|
||||
categoryOneOf: query.categoryOneOf,
|
||||
licenceOneOf: query.licenceOneOf,
|
||||
languageOneOf: query.languageOneOf,
|
||||
tagsOneOf: query.tagsOneOf,
|
||||
tagsAllOf: query.tagsAllOf,
|
||||
filter: query.filter,
|
||||
isLive: query.isLive,
|
||||
nsfw: buildNSFWFilter(res, query.nsfw),
|
||||
withFiles: false,
|
||||
accountId: account.id,
|
||||
user: res.locals.oauth ? res.locals.oauth.token.User : undefined,
|
||||
countVideos,
|
||||
search: query.search
|
||||
countVideos
|
||||
}, 'filter:api.accounts.videos.list.params')
|
||||
|
||||
const resultList = await Hooks.wrapPromiseFun(
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import * as express from 'express'
|
||||
import { sanitizeUrl } from '@server/helpers/core-utils'
|
||||
import { pickSearchChannelQuery } from '@server/helpers/query'
|
||||
import { doJSONRequest } from '@server/helpers/requests'
|
||||
import { CONFIG } from '@server/initializers/config'
|
||||
import { WEBSERVER } from '@server/initializers/constants'
|
||||
|
@ -7,7 +8,7 @@ import { Hooks } from '@server/lib/plugins/hooks'
|
|||
import { buildMutedForSearchIndex, isSearchIndexSearch, isURISearch } from '@server/lib/search'
|
||||
import { getServerActor } from '@server/models/application/application'
|
||||
import { HttpStatusCode, ResultList, VideoChannel } from '@shared/models'
|
||||
import { VideoChannelsSearchQuery } from '../../../../shared/models/search'
|
||||
import { VideoChannelsSearchQueryAfterSanitize } from '../../../../shared/models/search'
|
||||
import { isUserAbleToSearchRemoteURI } from '../../../helpers/express-utils'
|
||||
import { logger } from '../../../helpers/logger'
|
||||
import { getFormattedObjects } from '../../../helpers/utils'
|
||||
|
@ -45,7 +46,7 @@ export { searchChannelsRouter }
|
|||
// ---------------------------------------------------------------------------
|
||||
|
||||
function searchVideoChannels (req: express.Request, res: express.Response) {
|
||||
const query: VideoChannelsSearchQuery = req.query
|
||||
const query = pickSearchChannelQuery(req.query)
|
||||
let search = query.search || ''
|
||||
|
||||
const parts = search.split('@')
|
||||
|
@ -66,7 +67,7 @@ function searchVideoChannels (req: express.Request, res: express.Response) {
|
|||
return searchVideoChannelsDB(query, res)
|
||||
}
|
||||
|
||||
async function searchVideoChannelsIndex (query: VideoChannelsSearchQuery, res: express.Response) {
|
||||
async function searchVideoChannelsIndex (query: VideoChannelsSearchQueryAfterSanitize, res: express.Response) {
|
||||
const result = await buildMutedForSearchIndex(res)
|
||||
|
||||
const body = await Hooks.wrapObject(Object.assign(query, result), 'filter:api.search.video-channels.index.list.params')
|
||||
|
@ -90,17 +91,13 @@ async function searchVideoChannelsIndex (query: VideoChannelsSearchQuery, res: e
|
|||
}
|
||||
}
|
||||
|
||||
async function searchVideoChannelsDB (query: VideoChannelsSearchQuery, res: express.Response) {
|
||||
async function searchVideoChannelsDB (query: VideoChannelsSearchQueryAfterSanitize, res: express.Response) {
|
||||
const serverActor = await getServerActor()
|
||||
|
||||
const apiOptions = await Hooks.wrapObject({
|
||||
actorId: serverActor.id,
|
||||
search: query.search,
|
||||
start: query.start,
|
||||
count: query.count,
|
||||
sort: query.sort,
|
||||
host: query.host,
|
||||
handles: query.handles
|
||||
...query,
|
||||
|
||||
actorId: serverActor.id
|
||||
}, 'filter:api.search.video-channels.local.list.params')
|
||||
|
||||
const resultList = await Hooks.wrapPromiseFun(
|
||||
|
|
|
@ -2,6 +2,7 @@ import * as express from 'express'
|
|||
import { sanitizeUrl } from '@server/helpers/core-utils'
|
||||
import { isUserAbleToSearchRemoteURI } from '@server/helpers/express-utils'
|
||||
import { logger } from '@server/helpers/logger'
|
||||
import { pickSearchPlaylistQuery } from '@server/helpers/query'
|
||||
import { doJSONRequest } from '@server/helpers/requests'
|
||||
import { getFormattedObjects } from '@server/helpers/utils'
|
||||
import { CONFIG } from '@server/initializers/config'
|
||||
|
@ -12,7 +13,7 @@ import { buildMutedForSearchIndex, isSearchIndexSearch, isURISearch } from '@ser
|
|||
import { getServerActor } from '@server/models/application/application'
|
||||
import { VideoPlaylistModel } from '@server/models/video/video-playlist'
|
||||
import { MVideoPlaylistFullSummary } from '@server/types/models'
|
||||
import { HttpStatusCode, ResultList, VideoPlaylist, VideoPlaylistsSearchQuery } from '@shared/models'
|
||||
import { HttpStatusCode, ResultList, VideoPlaylist, VideoPlaylistsSearchQueryAfterSanitize } from '@shared/models'
|
||||
import {
|
||||
asyncMiddleware,
|
||||
openapiOperationDoc,
|
||||
|
@ -44,7 +45,7 @@ export { searchPlaylistsRouter }
|
|||
// ---------------------------------------------------------------------------
|
||||
|
||||
function searchVideoPlaylists (req: express.Request, res: express.Response) {
|
||||
const query: VideoPlaylistsSearchQuery = req.query
|
||||
const query = pickSearchPlaylistQuery(req.query)
|
||||
const search = query.search
|
||||
|
||||
if (isURISearch(search)) return searchVideoPlaylistsURI(search, res)
|
||||
|
@ -56,7 +57,7 @@ function searchVideoPlaylists (req: express.Request, res: express.Response) {
|
|||
return searchVideoPlaylistsDB(query, res)
|
||||
}
|
||||
|
||||
async function searchVideoPlaylistsIndex (query: VideoPlaylistsSearchQuery, res: express.Response) {
|
||||
async function searchVideoPlaylistsIndex (query: VideoPlaylistsSearchQueryAfterSanitize, res: express.Response) {
|
||||
const result = await buildMutedForSearchIndex(res)
|
||||
|
||||
const body = await Hooks.wrapObject(Object.assign(query, result), 'filter:api.search.video-playlists.index.list.params')
|
||||
|
@ -80,17 +81,13 @@ async function searchVideoPlaylistsIndex (query: VideoPlaylistsSearchQuery, res:
|
|||
}
|
||||
}
|
||||
|
||||
async function searchVideoPlaylistsDB (query: VideoPlaylistsSearchQuery, res: express.Response) {
|
||||
async function searchVideoPlaylistsDB (query: VideoPlaylistsSearchQueryAfterSanitize, res: express.Response) {
|
||||
const serverActor = await getServerActor()
|
||||
|
||||
const apiOptions = await Hooks.wrapObject({
|
||||
followerActorId: serverActor.id,
|
||||
search: query.search,
|
||||
start: query.start,
|
||||
count: query.count,
|
||||
sort: query.sort,
|
||||
host: query.host,
|
||||
uuids: query.uuids
|
||||
...query,
|
||||
|
||||
followerActorId: serverActor.id
|
||||
}, 'filter:api.search.video-playlists.local.list.params')
|
||||
|
||||
const resultList = await Hooks.wrapPromiseFun(
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import * as express from 'express'
|
||||
import { sanitizeUrl } from '@server/helpers/core-utils'
|
||||
import { pickSearchVideoQuery } from '@server/helpers/query'
|
||||
import { doJSONRequest } from '@server/helpers/requests'
|
||||
import { CONFIG } from '@server/initializers/config'
|
||||
import { WEBSERVER } from '@server/initializers/constants'
|
||||
|
@ -7,7 +8,7 @@ import { getOrCreateAPVideo } from '@server/lib/activitypub/videos'
|
|||
import { Hooks } from '@server/lib/plugins/hooks'
|
||||
import { buildMutedForSearchIndex, isSearchIndexSearch, isURISearch } from '@server/lib/search'
|
||||
import { HttpStatusCode, ResultList, Video } from '@shared/models'
|
||||
import { VideosSearchQuery } from '../../../../shared/models/search'
|
||||
import { VideosSearchQueryAfterSanitize } from '../../../../shared/models/search'
|
||||
import { buildNSFWFilter, isUserAbleToSearchRemoteURI } from '../../../helpers/express-utils'
|
||||
import { logger } from '../../../helpers/logger'
|
||||
import { getFormattedObjects } from '../../../helpers/utils'
|
||||
|
@ -46,7 +47,7 @@ export { searchVideosRouter }
|
|||
// ---------------------------------------------------------------------------
|
||||
|
||||
function searchVideos (req: express.Request, res: express.Response) {
|
||||
const query: VideosSearchQuery = req.query
|
||||
const query = pickSearchVideoQuery(req.query)
|
||||
const search = query.search
|
||||
|
||||
if (isURISearch(search)) {
|
||||
|
@ -60,10 +61,10 @@ function searchVideos (req: express.Request, res: express.Response) {
|
|||
return searchVideosDB(query, res)
|
||||
}
|
||||
|
||||
async function searchVideosIndex (query: VideosSearchQuery, res: express.Response) {
|
||||
async function searchVideosIndex (query: VideosSearchQueryAfterSanitize, res: express.Response) {
|
||||
const result = await buildMutedForSearchIndex(res)
|
||||
|
||||
let body: VideosSearchQuery = Object.assign(query, result)
|
||||
let body = { ...query, ...result }
|
||||
|
||||
// Use the default instance NSFW policy if not specified
|
||||
if (!body.nsfw) {
|
||||
|
@ -97,13 +98,18 @@ async function searchVideosIndex (query: VideosSearchQuery, res: express.Respons
|
|||
}
|
||||
}
|
||||
|
||||
async function searchVideosDB (query: VideosSearchQuery, res: express.Response) {
|
||||
const apiOptions = await Hooks.wrapObject(Object.assign(query, {
|
||||
async function searchVideosDB (query: VideosSearchQueryAfterSanitize, res: express.Response) {
|
||||
const apiOptions = await Hooks.wrapObject({
|
||||
...query,
|
||||
|
||||
includeLocalVideos: true,
|
||||
nsfw: buildNSFWFilter(res, query.nsfw),
|
||||
filter: query.filter,
|
||||
user: res.locals.oauth ? res.locals.oauth.token.User : undefined
|
||||
}), 'filter:api.search.videos.local.list.params')
|
||||
|
||||
nsfw: buildNSFWFilter(res, query.nsfw),
|
||||
user: res.locals.oauth
|
||||
? res.locals.oauth.token.User
|
||||
: undefined
|
||||
}, 'filter:api.search.videos.local.list.params')
|
||||
|
||||
const resultList = await Hooks.wrapPromiseFun(
|
||||
VideoModel.searchAndPopulateAccountAndServer,
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import 'multer'
|
||||
import * as express from 'express'
|
||||
import { pickCommonVideoQuery } from '@server/helpers/query'
|
||||
import { sendUndoFollow } from '@server/lib/activitypub/send'
|
||||
import { VideoChannelModel } from '@server/models/video/video-channel'
|
||||
import { VideosCommonQuery } from '@shared/models'
|
||||
import { HttpStatusCode } from '../../../../shared/models/http/http-error-codes'
|
||||
import { buildNSFWFilter, getCountVideos } from '../../../helpers/express-utils'
|
||||
import { getFormattedObjects } from '../../../helpers/utils'
|
||||
|
@ -170,20 +170,13 @@ async function getUserSubscriptions (req: express.Request, res: express.Response
|
|||
async function getUserSubscriptionVideos (req: express.Request, res: express.Response) {
|
||||
const user = res.locals.oauth.token.User
|
||||
const countVideos = getCountVideos(req)
|
||||
const query = req.query as VideosCommonQuery
|
||||
const query = pickCommonVideoQuery(req.query)
|
||||
|
||||
const resultList = await VideoModel.listForApi({
|
||||
start: query.start,
|
||||
count: query.count,
|
||||
sort: query.sort,
|
||||
...query,
|
||||
|
||||
includeLocalVideos: false,
|
||||
categoryOneOf: query.categoryOneOf,
|
||||
licenceOneOf: query.licenceOneOf,
|
||||
languageOneOf: query.languageOneOf,
|
||||
tagsOneOf: query.tagsOneOf,
|
||||
tagsAllOf: query.tagsAllOf,
|
||||
nsfw: buildNSFWFilter(res, query.nsfw),
|
||||
filter: query.filter,
|
||||
withFiles: false,
|
||||
followerActorId: user.Account.Actor.id,
|
||||
user,
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import * as express from 'express'
|
||||
import { pickCommonVideoQuery } from '@server/helpers/query'
|
||||
import { Hooks } from '@server/lib/plugins/hooks'
|
||||
import { getServerActor } from '@server/models/application/application'
|
||||
import { MChannelBannerAccountDefault } from '@server/types/models'
|
||||
import { ActorImageType, VideoChannelCreate, VideoChannelUpdate, VideosCommonQuery } from '../../../shared'
|
||||
import { ActorImageType, VideoChannelCreate, VideoChannelUpdate } from '../../../shared'
|
||||
import { HttpStatusCode } from '../../../shared/models/http/http-error-codes'
|
||||
import { auditLoggerFactory, getAuditIdFromRes, VideoChannelAuditView } from '../../helpers/audit-logger'
|
||||
import { resetSequelizeInstance } from '../../helpers/database-utils'
|
||||
|
@ -309,20 +310,13 @@ async function listVideoChannelVideos (req: express.Request, res: express.Respon
|
|||
const videoChannelInstance = res.locals.videoChannel
|
||||
const followerActorId = isUserAbleToSearchRemoteURI(res) ? null : undefined
|
||||
const countVideos = getCountVideos(req)
|
||||
const query = req.query as VideosCommonQuery
|
||||
const query = pickCommonVideoQuery(req.query)
|
||||
|
||||
const apiOptions = await Hooks.wrapObject({
|
||||
...query,
|
||||
|
||||
followerActorId,
|
||||
start: query.start,
|
||||
count: query.count,
|
||||
sort: query.sort,
|
||||
includeLocalVideos: true,
|
||||
categoryOneOf: query.categoryOneOf,
|
||||
licenceOneOf: query.licenceOneOf,
|
||||
languageOneOf: query.languageOneOf,
|
||||
tagsOneOf: query.tagsOneOf,
|
||||
tagsAllOf: query.tagsAllOf,
|
||||
filter: query.filter,
|
||||
nsfw: buildNSFWFilter(res, query.nsfw),
|
||||
withFiles: false,
|
||||
videoChannelId: videoChannelInstance.id,
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import * as express from 'express'
|
||||
import toInt from 'validator/lib/toInt'
|
||||
import { pickCommonVideoQuery } from '@server/helpers/query'
|
||||
import { doJSONRequest } from '@server/helpers/requests'
|
||||
import { LiveManager } from '@server/lib/live'
|
||||
import { openapiOperationDoc } from '@server/middlewares/doc'
|
||||
import { getServerActor } from '@server/models/application/application'
|
||||
import { MVideoAccountLight } from '@server/types/models'
|
||||
import { VideosCommonQuery } from '../../../../shared'
|
||||
import { HttpStatusCode } from '../../../../shared/models'
|
||||
import { auditLoggerFactory, getAuditIdFromRes, VideoAuditView } from '../../../helpers/audit-logger'
|
||||
import { buildNSFWFilter, getCountVideos } from '../../../helpers/express-utils'
|
||||
|
@ -211,22 +211,14 @@ async function getVideoFileMetadata (req: express.Request, res: express.Response
|
|||
}
|
||||
|
||||
async function listVideos (req: express.Request, res: express.Response) {
|
||||
const query = req.query as VideosCommonQuery
|
||||
const query = pickCommonVideoQuery(req.query)
|
||||
const countVideos = getCountVideos(req)
|
||||
|
||||
const apiOptions = await Hooks.wrapObject({
|
||||
start: query.start,
|
||||
count: query.count,
|
||||
sort: query.sort,
|
||||
...query,
|
||||
|
||||
includeLocalVideos: true,
|
||||
categoryOneOf: query.categoryOneOf,
|
||||
licenceOneOf: query.licenceOneOf,
|
||||
languageOneOf: query.languageOneOf,
|
||||
tagsOneOf: query.tagsOneOf,
|
||||
tagsAllOf: query.tagsAllOf,
|
||||
nsfw: buildNSFWFilter(res, query.nsfw),
|
||||
isLive: query.isLive,
|
||||
filter: query.filter,
|
||||
withFiles: false,
|
||||
user: res.locals.oauth ? res.locals.oauth.token.User : undefined,
|
||||
countVideos
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
import { pick } from '@shared/core-utils'
|
||||
import {
|
||||
VideoChannelsSearchQueryAfterSanitize,
|
||||
VideoPlaylistsSearchQueryAfterSanitize,
|
||||
VideosCommonQueryAfterSanitize,
|
||||
VideosSearchQueryAfterSanitize
|
||||
} from '@shared/models'
|
||||
|
||||
function pickCommonVideoQuery (query: VideosCommonQueryAfterSanitize) {
|
||||
return pick(query, [
|
||||
'start',
|
||||
'count',
|
||||
'sort',
|
||||
'nsfw',
|
||||
'isLive',
|
||||
'categoryOneOf',
|
||||
'licenceOneOf',
|
||||
'languageOneOf',
|
||||
'tagsOneOf',
|
||||
'tagsAllOf',
|
||||
'filter',
|
||||
'skipCount'
|
||||
])
|
||||
}
|
||||
|
||||
function pickSearchVideoQuery (query: VideosSearchQueryAfterSanitize) {
|
||||
return {
|
||||
...pickCommonVideoQuery(query),
|
||||
|
||||
...pick(query, [
|
||||
'searchTarget',
|
||||
'search',
|
||||
'host',
|
||||
'startDate',
|
||||
'endDate',
|
||||
'originallyPublishedStartDate',
|
||||
'originallyPublishedEndDate',
|
||||
'durationMin',
|
||||
'durationMax',
|
||||
'uuids'
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
function pickSearchChannelQuery (query: VideoChannelsSearchQueryAfterSanitize) {
|
||||
return pick(query, [
|
||||
'searchTarget',
|
||||
'search',
|
||||
'start',
|
||||
'count',
|
||||
'sort',
|
||||
'host',
|
||||
'handles'
|
||||
])
|
||||
}
|
||||
|
||||
function pickSearchPlaylistQuery (query: VideoPlaylistsSearchQueryAfterSanitize) {
|
||||
return pick(query, [
|
||||
'searchTarget',
|
||||
'search',
|
||||
'start',
|
||||
'count',
|
||||
'sort',
|
||||
'host',
|
||||
'uuids'
|
||||
])
|
||||
}
|
||||
|
||||
export {
|
||||
pickCommonVideoQuery,
|
||||
pickSearchVideoQuery,
|
||||
pickSearchPlaylistQuery,
|
||||
pickSearchChannelQuery
|
||||
}
|
|
@ -1070,7 +1070,8 @@ export class VideoModel extends Model<Partial<AttributesOnly<VideoModel>>> {
|
|||
const trendingDays = options.sort.endsWith('trending')
|
||||
? CONFIG.TRENDING.VIDEOS.INTERVAL_DAYS
|
||||
: undefined
|
||||
let trendingAlgorithm
|
||||
|
||||
let trendingAlgorithm: string
|
||||
if (options.sort.endsWith('hot')) trendingAlgorithm = 'hot'
|
||||
if (options.sort.endsWith('best')) trendingAlgorithm = 'best'
|
||||
|
||||
|
|
|
@ -211,6 +211,39 @@ describe('Test videos search', function () {
|
|||
const search = { ...baseSearch, host: 'framatube.org' }
|
||||
await check(search, true)
|
||||
}
|
||||
|
||||
{
|
||||
const goodUUID = '9c9de5e8-0a1e-484a-b099-e80766180a6d'
|
||||
const goodShortUUID = 'kkGMgK9ZtnKfYAgnEtQxbv'
|
||||
const badUUID = 'c29c5b77-4a04-493d-96a9-2e9267e308f0'
|
||||
const badShortUUID = 'rP5RgUeX9XwTSrspCdkDej'
|
||||
|
||||
{
|
||||
const uuidsMatrix = [
|
||||
[ goodUUID ],
|
||||
[ goodUUID, badShortUUID ],
|
||||
[ badShortUUID, goodShortUUID ],
|
||||
[ goodUUID, goodShortUUID ]
|
||||
]
|
||||
|
||||
for (const uuids of uuidsMatrix) {
|
||||
const search = { ...baseSearch, uuids }
|
||||
await check(search, true)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const uuidsMatrix = [
|
||||
[ badUUID ],
|
||||
[ badShortUUID ]
|
||||
]
|
||||
|
||||
for (const uuids of uuidsMatrix) {
|
||||
const search = { ...baseSearch, uuids }
|
||||
await check(search, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
it('Should have a correct pagination', async function () {
|
||||
|
@ -315,6 +348,45 @@ describe('Test videos search', function () {
|
|||
|
||||
describe('Playlists search', async function () {
|
||||
|
||||
async function check (search: VideoPlaylistsSearchQuery, exists = true) {
|
||||
const body = await command.advancedPlaylistSearch({ search })
|
||||
|
||||
if (exists === false) {
|
||||
expect(body.total).to.equal(0)
|
||||
expect(body.data).to.have.lengthOf(0)
|
||||
return
|
||||
}
|
||||
|
||||
expect(body.total).to.be.greaterThan(0)
|
||||
expect(body.data).to.have.length.greaterThan(0)
|
||||
|
||||
const videoPlaylist = body.data[0]
|
||||
|
||||
expect(videoPlaylist.url).to.equal('https://peertube2.cpy.re/videos/watch/playlist/73804a40-da9a-40c2-b1eb-2c6d9eec8f0a')
|
||||
expect(videoPlaylist.thumbnailUrl).to.exist
|
||||
expect(videoPlaylist.embedUrl).to.equal('https://peertube2.cpy.re/video-playlists/embed/73804a40-da9a-40c2-b1eb-2c6d9eec8f0a')
|
||||
|
||||
expect(videoPlaylist.type.id).to.equal(VideoPlaylistType.REGULAR)
|
||||
expect(videoPlaylist.privacy.id).to.equal(VideoPlaylistPrivacy.PUBLIC)
|
||||
expect(videoPlaylist.videosLength).to.exist
|
||||
|
||||
expect(videoPlaylist.createdAt).to.exist
|
||||
expect(videoPlaylist.updatedAt).to.exist
|
||||
|
||||
expect(videoPlaylist.uuid).to.equal('73804a40-da9a-40c2-b1eb-2c6d9eec8f0a')
|
||||
expect(videoPlaylist.displayName).to.exist
|
||||
|
||||
expect(videoPlaylist.ownerAccount.url).to.equal('https://peertube2.cpy.re/accounts/chocobozzz')
|
||||
expect(videoPlaylist.ownerAccount.name).to.equal('chocobozzz')
|
||||
expect(videoPlaylist.ownerAccount.host).to.equal('peertube2.cpy.re')
|
||||
expect(videoPlaylist.ownerAccount.avatar).to.exist
|
||||
|
||||
expect(videoPlaylist.videoChannel.url).to.equal('https://peertube2.cpy.re/video-channels/chocobozzz_channel')
|
||||
expect(videoPlaylist.videoChannel.name).to.equal('chocobozzz_channel')
|
||||
expect(videoPlaylist.videoChannel.host).to.equal('peertube2.cpy.re')
|
||||
expect(videoPlaylist.videoChannel.avatar).to.exist
|
||||
}
|
||||
|
||||
it('Should make a simple search and not have results', async function () {
|
||||
const body = await command.searchPlaylists({ search: 'a'.repeat(500) })
|
||||
|
||||
|
@ -323,49 +395,45 @@ describe('Test videos search', function () {
|
|||
})
|
||||
|
||||
it('Should make a search and have results', async function () {
|
||||
await check({ search: 'E2E playlist', sort: '-match' }, true)
|
||||
})
|
||||
|
||||
async function check (search: VideoPlaylistsSearchQuery, exists = true) {
|
||||
const body = await command.advancedPlaylistSearch({ search })
|
||||
it('Should make host search and have appropriate results', async function () {
|
||||
await check({ search: 'E2E playlist', host: 'example.com' }, false)
|
||||
await check({ search: 'E2E playlist', host: 'peertube2.cpy.re', sort: '-match' }, true)
|
||||
})
|
||||
|
||||
if (exists === false) {
|
||||
expect(body.total).to.equal(0)
|
||||
expect(body.data).to.have.lengthOf(0)
|
||||
return
|
||||
it('Should make a search by uuids and have appropriate results', async function () {
|
||||
const goodUUID = '73804a40-da9a-40c2-b1eb-2c6d9eec8f0a'
|
||||
const goodShortUUID = 'fgei1ws1oa6FCaJ2qZPG29'
|
||||
const badUUID = 'c29c5b77-4a04-493d-96a9-2e9267e308f0'
|
||||
const badShortUUID = 'rP5RgUeX9XwTSrspCdkDej'
|
||||
|
||||
{
|
||||
const uuidsMatrix = [
|
||||
[ goodUUID ],
|
||||
[ goodUUID, badShortUUID ],
|
||||
[ badShortUUID, goodShortUUID ],
|
||||
[ goodUUID, goodShortUUID ]
|
||||
]
|
||||
|
||||
for (const uuids of uuidsMatrix) {
|
||||
const search = { search: 'E2E playlist', sort: '-match', uuids }
|
||||
await check(search, true)
|
||||
}
|
||||
|
||||
expect(body.total).to.be.greaterThan(0)
|
||||
expect(body.data).to.have.length.greaterThan(0)
|
||||
|
||||
const videoPlaylist = body.data[0]
|
||||
|
||||
expect(videoPlaylist.url).to.equal('https://peertube2.cpy.re/videos/watch/playlist/73804a40-da9a-40c2-b1eb-2c6d9eec8f0a')
|
||||
expect(videoPlaylist.thumbnailUrl).to.exist
|
||||
expect(videoPlaylist.embedUrl).to.equal('https://peertube2.cpy.re/video-playlists/embed/73804a40-da9a-40c2-b1eb-2c6d9eec8f0a')
|
||||
|
||||
expect(videoPlaylist.type.id).to.equal(VideoPlaylistType.REGULAR)
|
||||
expect(videoPlaylist.privacy.id).to.equal(VideoPlaylistPrivacy.PUBLIC)
|
||||
expect(videoPlaylist.videosLength).to.exist
|
||||
|
||||
expect(videoPlaylist.createdAt).to.exist
|
||||
expect(videoPlaylist.updatedAt).to.exist
|
||||
|
||||
expect(videoPlaylist.uuid).to.equal('73804a40-da9a-40c2-b1eb-2c6d9eec8f0a')
|
||||
expect(videoPlaylist.displayName).to.exist
|
||||
|
||||
expect(videoPlaylist.ownerAccount.url).to.equal('https://peertube2.cpy.re/accounts/chocobozzz')
|
||||
expect(videoPlaylist.ownerAccount.name).to.equal('chocobozzz')
|
||||
expect(videoPlaylist.ownerAccount.host).to.equal('peertube2.cpy.re')
|
||||
expect(videoPlaylist.ownerAccount.avatar).to.exist
|
||||
|
||||
expect(videoPlaylist.videoChannel.url).to.equal('https://peertube2.cpy.re/video-channels/chocobozzz_channel')
|
||||
expect(videoPlaylist.videoChannel.name).to.equal('chocobozzz_channel')
|
||||
expect(videoPlaylist.videoChannel.host).to.equal('peertube2.cpy.re')
|
||||
expect(videoPlaylist.videoChannel.avatar).to.exist
|
||||
}
|
||||
|
||||
await check({ search: 'E2E playlist', sort: '-match' }, true)
|
||||
await check({ search: 'E2E playlist', host: 'example.com' }, false)
|
||||
await check({ search: 'E2E playlist', host: 'peertube2.cpy.re' }, true)
|
||||
{
|
||||
const uuidsMatrix = [
|
||||
[ badUUID ],
|
||||
[ badShortUUID ]
|
||||
]
|
||||
|
||||
for (const uuids of uuidsMatrix) {
|
||||
const search = { search: 'E2E playlist', sort: '-match', uuids }
|
||||
await check(search, false)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
it('Should have a correct pagination', async function () {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
function pick <T extends object> (object: T, keys: (keyof T)[]) {
|
||||
const result: Partial<T> = {}
|
||||
function pick <O extends object, K extends keyof O> (object: O, keys: K[]): Pick<O, K> {
|
||||
const result: any = {}
|
||||
|
||||
for (const key of keys) {
|
||||
if (Object.prototype.hasOwnProperty.call(object, key)) {
|
||||
|
|
|
@ -10,3 +10,9 @@ export interface VideoChannelsSearchQuery extends SearchTargetQuery {
|
|||
host?: string
|
||||
handles?: string[]
|
||||
}
|
||||
|
||||
export interface VideoChannelsSearchQueryAfterSanitize extends VideoChannelsSearchQuery {
|
||||
start: number
|
||||
count: number
|
||||
sort: string
|
||||
}
|
||||
|
|
|
@ -8,5 +8,13 @@ export interface VideoPlaylistsSearchQuery extends SearchTargetQuery {
|
|||
sort?: string
|
||||
|
||||
host?: string
|
||||
|
||||
// UUIDs or short UUIDs
|
||||
uuids?: string[]
|
||||
}
|
||||
|
||||
export interface VideoPlaylistsSearchQueryAfterSanitize extends VideoPlaylistsSearchQuery {
|
||||
start: number
|
||||
count: number
|
||||
sort: string
|
||||
}
|
||||
|
|
|
@ -25,6 +25,12 @@ export interface VideosCommonQuery {
|
|||
skipCount?: boolean
|
||||
}
|
||||
|
||||
export interface VideosCommonQueryAfterSanitize extends VideosCommonQuery {
|
||||
start: number
|
||||
count: number
|
||||
sort: string
|
||||
}
|
||||
|
||||
export interface VideosWithSearchCommonQuery extends VideosCommonQuery {
|
||||
search?: string
|
||||
}
|
||||
|
|
|
@ -15,6 +15,12 @@ export interface VideosSearchQuery extends SearchTargetQuery, VideosCommonQuery
|
|||
durationMin?: number // seconds
|
||||
durationMax?: number // seconds
|
||||
|
||||
// UUIDs or short
|
||||
// UUIDs or short UUIDs
|
||||
uuids?: string[]
|
||||
}
|
||||
|
||||
export interface VideosSearchQueryAfterSanitize extends VideosSearchQuery {
|
||||
start: number
|
||||
count: number
|
||||
sort: string
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue