Support '/w/' and '/w/p/' for watch page
And use them as default in client
This commit is contained in:
parent
012580d98f
commit
a1eda903a4
|
@ -61,7 +61,7 @@ export class MyAccountPage {
|
|||
|
||||
async goOnAssociatedPlaylistEmbed () {
|
||||
let url = await browser.getCurrentUrl()
|
||||
url = url.replace('/videos/watch/playlist/', '/video-playlists/embed/')
|
||||
url = url.replace('/w/p/', '/video-playlists/embed/')
|
||||
url = url.replace(':3333', ':9001')
|
||||
|
||||
return browser.get(url)
|
||||
|
|
|
@ -41,7 +41,7 @@ export class VideoUploadPage {
|
|||
|
||||
await this.getSecondStepSubmitButton().click()
|
||||
|
||||
return browser.wait(browser.ExpectedConditions.urlContains('/watch/'))
|
||||
return browser.wait(browser.ExpectedConditions.urlContains('/w/'))
|
||||
}
|
||||
|
||||
private getSecondStepSubmitButton () {
|
||||
|
|
|
@ -43,7 +43,7 @@ export class VideoWatchPage {
|
|||
|
||||
async goOnAssociatedEmbed () {
|
||||
let url = await browser.getCurrentUrl()
|
||||
url = url.replace('/watch/', '/embed/')
|
||||
url = url.replace('/w/', '/embed/')
|
||||
url = url.replace(':3333', ':9001')
|
||||
|
||||
return browser.get(url)
|
||||
|
@ -65,7 +65,7 @@ export class VideoWatchPage {
|
|||
await browser.wait(browser.ExpectedConditions.elementToBeClickable(video))
|
||||
await video.click()
|
||||
|
||||
await browser.wait(browser.ExpectedConditions.urlContains('/watch/'))
|
||||
await browser.wait(browser.ExpectedConditions.urlContains('/w/'))
|
||||
}
|
||||
|
||||
async clickOnFirstVideo () {
|
||||
|
@ -78,7 +78,7 @@ export class VideoWatchPage {
|
|||
const textToReturn = videoName.getText()
|
||||
await video.click()
|
||||
|
||||
await browser.wait(browser.ExpectedConditions.urlContains('/watch/'))
|
||||
await browser.wait(browser.ExpectedConditions.urlContains('/w/'))
|
||||
return textToReturn
|
||||
}
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ describe('Videos workflow', () => {
|
|||
let videoNameToExcept = videoName
|
||||
|
||||
if (await isMobileDevice() || await isSafari()) {
|
||||
await browser.get('https://peertube2.cpy.re/videos/watch/122d093a-1ede-43bd-bd34-59d2931ffc5e')
|
||||
await browser.get('https://peertube2.cpy.re/w/122d093a-1ede-43bd-bd34-59d2931ffc5e')
|
||||
videoNameToExcept = 'E2E tests'
|
||||
} else {
|
||||
await videoWatchPage.clickOnVideo(videoName)
|
||||
|
|
|
@ -489,7 +489,7 @@
|
|||
<ng-container i18n>
|
||||
If your instance is explicitly allowed by Twitter, a video player will be embedded in the Twitter feed on PeerTube video share.<br />
|
||||
If the instance is not, we use an image link card that will redirect to your PeerTube instance.<br /><br />
|
||||
Check this checkbox, save the configuration and test with a video URL of your instance (https://example.com/videos/watch/blabla) on
|
||||
Check this checkbox, save the configuration and test with a video URL of your instance (https://example.com/w/blabla) on
|
||||
<a target='_blank' rel='noopener noreferrer' href='https://cards-dev.twitter.com/validator'>https://cards-dev.twitter.com/validator</a>
|
||||
to see if you instance is allowed.
|
||||
</ng-container>
|
||||
|
|
|
@ -55,7 +55,7 @@ export class MyVideoImportsComponent extends RestTable implements OnInit {
|
|||
}
|
||||
|
||||
getVideoUrl (video: { uuid: string }) {
|
||||
return '/videos/watch/' + video.uuid
|
||||
return '/w/' + video.uuid
|
||||
}
|
||||
|
||||
getEditVideoUrl (video: { uuid: string }) {
|
||||
|
|
|
@ -2,8 +2,6 @@ import { Component, OnInit } from '@angular/core'
|
|||
import { Title } from '@angular/platform-browser'
|
||||
import { Router } from '@angular/router'
|
||||
import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes'
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'my-page-not-found',
|
||||
templateUrl: './page-not-found.component.html',
|
||||
|
|
|
@ -39,7 +39,7 @@ export class RemoteInteractionComponent implements OnInit {
|
|||
if (videoResult.data.length !== 0) {
|
||||
const video = videoResult.data[0]
|
||||
|
||||
redirectUrl = '/videos/watch/' + video.uuid
|
||||
redirectUrl = '/w/' + video.uuid
|
||||
} else if (channelResult.data.length !== 0) {
|
||||
const channel = new VideoChannel(channelResult.data[0])
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ export class VideoLazyLoadResolver implements Resolve<any> {
|
|||
|
||||
const video = result.data[0]
|
||||
|
||||
return this.router.navigateByUrl('/videos/watch/' + video.uuid)
|
||||
return this.router.navigateByUrl('/w/' + video.uuid)
|
||||
})
|
||||
)
|
||||
}
|
||||
|
|
|
@ -127,7 +127,7 @@ export class VideoGoLiveComponent extends VideoSend implements OnInit, AfterView
|
|||
() => {
|
||||
this.notifier.success($localize`Live published.`)
|
||||
|
||||
this.router.navigate(['/videos/watch', video.uuid])
|
||||
this.router.navigate(['/w', video.uuid])
|
||||
},
|
||||
|
||||
err => {
|
||||
|
|
|
@ -244,7 +244,7 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy
|
|||
this.isUploadingVideo = false
|
||||
|
||||
this.notifier.success($localize`Video published.`)
|
||||
this.router.navigate([ '/videos/watch', video.uuid ])
|
||||
this.router.navigate([ '/w', video.uuid ])
|
||||
},
|
||||
|
||||
err => {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<div class="margin-content">
|
||||
<div class="title-page title-page-single">
|
||||
<span class="mr-1" i18n>Update</span>
|
||||
<a [routerLink]="[ '/videos/watch', video.uuid ]">{{ video?.name }}</a>
|
||||
<a [routerLink]="[ '/w', video.uuid ]">{{ video?.name }}</a>
|
||||
</div>
|
||||
|
||||
<form novalidate [formGroup]="form">
|
||||
|
|
|
@ -156,7 +156,7 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
|
|||
this.isUpdatingVideo = false
|
||||
this.loadingBar.useRef().complete()
|
||||
this.notifier.success($localize`Video updated.`)
|
||||
this.router.navigate([ '/videos/watch', this.video.uuid ])
|
||||
this.router.navigate([ '/w', this.video.uuid ])
|
||||
},
|
||||
|
||||
err => {
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
</a>
|
||||
</div>
|
||||
|
||||
<a [routerLink]="['/videos/watch', video.uuid, { 'threadId': comment.threadId }]" class="comment-date" [title]="comment.createdAt">
|
||||
<a [routerLink]="['/w', video.uuid, { 'threadId': comment.threadId }]" class="comment-date" [title]="comment.createdAt">
|
||||
{{ comment.createdAt | myFromNow }}
|
||||
</a>
|
||||
</div>
|
||||
|
@ -45,7 +45,7 @@
|
|||
<ng-container *ngIf="comment.isDeleted">
|
||||
<div class="comment-account-date">
|
||||
<span class="comment-account" i18n>Deleted</span>
|
||||
<a [routerLink]="['/videos/watch', video.uuid, { 'threadId': comment.threadId }]"
|
||||
<a [routerLink]="['/w', video.uuid, { 'threadId': comment.threadId }]"
|
||||
class="comment-date">{{ comment.createdAt | myFromNow }}</a>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import { VideoWatchComponent } from './video-watch.component'
|
|||
|
||||
const videoWatchRoutes: Routes = [
|
||||
{
|
||||
path: 'playlist/:playlistId',
|
||||
path: 'p/:playlistId',
|
||||
component: VideoWatchComponent
|
||||
},
|
||||
{
|
||||
|
|
|
@ -690,7 +690,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
|||
if (this.playlist) {
|
||||
this.zone.run(() => this.videoWatchPlaylist.navigateToNextPlaylistVideo())
|
||||
} else if (this.nextVideoUuid) {
|
||||
this.router.navigate([ '/videos/watch', this.nextVideoUuid ])
|
||||
this.router.navigate([ '/w', this.nextVideoUuid ])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -74,31 +74,6 @@ const videosRoutes: Routes = [
|
|||
key: 'local-videos-list'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'upload',
|
||||
loadChildren: () => import('@app/+videos/+video-edit/video-add.module').then(m => m.VideoAddModule),
|
||||
data: {
|
||||
meta: {
|
||||
title: $localize`Upload a video`
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'update/:uuid',
|
||||
loadChildren: () => import('@app/+videos/+video-edit/video-update.module').then(m => m.VideoUpdateModule),
|
||||
data: {
|
||||
meta: {
|
||||
title: $localize`Edit a video`
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'watch',
|
||||
loadChildren: () => import('@app/+videos/+video-watch/video-watch.module').then(m => m.VideoWatchModule),
|
||||
data: {
|
||||
preload: 3000
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -36,16 +36,27 @@ const routes: Routes = [
|
|||
loadChildren: () => import('./+signup/+verify-account/verify-account.module').then(m => m.VerifyAccountModule),
|
||||
canActivateChild: [ MetaGuard ]
|
||||
},
|
||||
|
||||
{
|
||||
path: 'accounts',
|
||||
redirectTo: 'a'
|
||||
},
|
||||
{
|
||||
path: 'a',
|
||||
loadChildren: () => import('./+accounts/accounts.module').then(m => m.AccountsModule),
|
||||
canActivateChild: [ MetaGuard ]
|
||||
},
|
||||
|
||||
{
|
||||
path: 'video-channels',
|
||||
redirectTo: 'c'
|
||||
},
|
||||
{
|
||||
path: 'c',
|
||||
loadChildren: () => import('./+video-channels/video-channels.module').then(m => m.VideoChannelsModule),
|
||||
canActivateChild: [ MetaGuard ]
|
||||
},
|
||||
|
||||
{
|
||||
path: 'about',
|
||||
loadChildren: () => import('./+about/about.module').then(m => m.AboutModule),
|
||||
|
@ -71,31 +82,60 @@ const routes: Routes = [
|
|||
loadChildren: () => import('./+search/search.module').then(m => m.SearchModule),
|
||||
canActivateChild: [ MetaGuard ]
|
||||
},
|
||||
|
||||
{
|
||||
path: 'videos/upload',
|
||||
loadChildren: () => import('@app/+videos/+video-edit/video-add.module').then(m => m.VideoAddModule),
|
||||
data: {
|
||||
meta: {
|
||||
title: $localize`Upload a video`
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'videos/update/:uuid',
|
||||
loadChildren: () => import('@app/+videos/+video-edit/video-update.module').then(m => m.VideoUpdateModule),
|
||||
data: {
|
||||
meta: {
|
||||
title: $localize`Edit a video`
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
path: 'videos/watch/playlist',
|
||||
redirectTo: 'w/p'
|
||||
},
|
||||
{
|
||||
path: 'videos/watch',
|
||||
redirectTo: 'w'
|
||||
},
|
||||
{
|
||||
path: 'w',
|
||||
loadChildren: () => import('@app/+videos/+video-watch/video-watch.module').then(m => m.VideoWatchModule),
|
||||
data: {
|
||||
preload: 3000
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'videos',
|
||||
loadChildren: () => import('./+videos/videos.module').then(m => m.VideosModule),
|
||||
canActivateChild: [ MetaGuard ]
|
||||
},
|
||||
{
|
||||
path: 'video-playlists/watch',
|
||||
redirectTo: 'videos/watch/playlist'
|
||||
},
|
||||
|
||||
{
|
||||
path: 'remote-interaction',
|
||||
loadChildren: () => import('./+remote-interaction/remote-interaction.module').then(m => m.RemoteInteractionModule),
|
||||
canActivateChild: [ MetaGuard ]
|
||||
},
|
||||
{
|
||||
path: 'video-playlists/watch',
|
||||
redirectTo: 'videos/watch/playlist'
|
||||
},
|
||||
{
|
||||
path: 'accounts',
|
||||
redirectTo: 'a'
|
||||
},
|
||||
{
|
||||
path: 'video-channels',
|
||||
redirectTo: 'c'
|
||||
},
|
||||
|
||||
// Matches /@:actorName
|
||||
{
|
||||
matcher: (url): UrlMatchResult => {
|
||||
// Matches /@:actorName
|
||||
const regex = new RegExp(`^@(${USER_USERNAME_REGEX_CHARACTERS}+)$`)
|
||||
if (url.length !== 1) return null
|
||||
|
||||
|
@ -113,6 +153,7 @@ const routes: Routes = [
|
|||
canActivate: [ ActorRedirectGuard ],
|
||||
component: EmptyComponent
|
||||
},
|
||||
|
||||
{
|
||||
path: '',
|
||||
component: EmptyComponent // Avoid 404, app component will redirect dynamically
|
||||
|
|
|
@ -238,7 +238,7 @@ export class UserNotification implements UserNotificationServer {
|
|||
}
|
||||
|
||||
private buildVideoUrl (video: { uuid: string }) {
|
||||
return '/videos/watch/' + video.uuid
|
||||
return '/w/' + video.uuid
|
||||
}
|
||||
|
||||
private buildAccountUrl (account: { name: string, host: string }) {
|
||||
|
|
|
@ -88,7 +88,7 @@ export class Video implements VideoServerModel {
|
|||
pluginData?: any
|
||||
|
||||
static buildClientUrl (videoUUID: string) {
|
||||
return '/videos/watch/' + videoUUID
|
||||
return '/w/' + videoUUID
|
||||
}
|
||||
|
||||
constructor (hash: VideoServerModel, translations = {}) {
|
||||
|
|
|
@ -98,14 +98,14 @@ export class VideoShareComponent {
|
|||
|
||||
getVideoUrl () {
|
||||
let baseUrl = this.customizations.originUrl ? this.video.originInstanceUrl : window.location.origin
|
||||
baseUrl += '/videos/watch/' + this.video.uuid
|
||||
baseUrl += '/w/' + this.video.uuid
|
||||
const options = this.getVideoOptions(baseUrl)
|
||||
|
||||
return buildVideoLink(options)
|
||||
}
|
||||
|
||||
getPlaylistUrl () {
|
||||
const base = window.location.origin + '/videos/watch/playlist/' + this.playlist.uuid
|
||||
const base = window.location.origin + '/w/p/' + this.playlist.uuid
|
||||
|
||||
if (!this.includeVideoInPlaylist) return base
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ export class VideoThumbnailComponent {
|
|||
getVideoRouterLink () {
|
||||
if (this.videoRouterLink) return this.videoRouterLink
|
||||
|
||||
return [ '/videos/watch', this.video.uuid ]
|
||||
return [ '/w', this.video.uuid ]
|
||||
}
|
||||
|
||||
onWatchLaterClick (event: Event) {
|
||||
|
|
|
@ -85,7 +85,7 @@ export class VideoCommentAdmin implements VideoCommentAdminServerModel {
|
|||
id: hash.video.id,
|
||||
uuid: hash.video.uuid,
|
||||
name: hash.video.name,
|
||||
localUrl: '/videos/watch/' + hash.video.uuid
|
||||
localUrl: '/w/' + hash.video.uuid
|
||||
}
|
||||
|
||||
this.localUrl = this.video.localUrl + ';threadId=' + this.threadId
|
||||
|
|
|
@ -125,7 +125,7 @@ export class VideoMiniatureComponent implements OnInit {
|
|||
|
||||
buildVideoLink () {
|
||||
if (this.videoLinkType === 'internal' || !this.video.url) {
|
||||
this.videoRouterLink = [ '/videos/watch', this.video.uuid ]
|
||||
this.videoRouterLink = [ '/w', this.video.uuid ]
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ export class VideoPlaylistElementMiniatureComponent implements OnInit {
|
|||
buildRouterLink () {
|
||||
if (!this.playlist) return null
|
||||
|
||||
return [ '/videos/watch/playlist', this.playlist.uuid ]
|
||||
return [ '/w/p', this.playlist.uuid ]
|
||||
}
|
||||
|
||||
buildRouterQuery () {
|
||||
|
|
|
@ -18,6 +18,6 @@ export class VideoPlaylistMiniatureComponent {
|
|||
if (this.toManage) return [ '/my-library/video-playlists', this.playlist.uuid ]
|
||||
if (this.playlist.videosLength === 0) return null
|
||||
|
||||
return [ '/videos/watch/playlist', this.playlist.uuid ]
|
||||
return [ '/w/p', this.playlist.uuid ]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ function buildVideoLink (options: {
|
|||
|
||||
const url = baseUrl
|
||||
? baseUrl
|
||||
: window.location.origin + window.location.pathname.replace('/embed/', '/watch/')
|
||||
: window.location.origin + window.location.pathname.replace('/embed/', '/w/')
|
||||
|
||||
const params = generateParams(window.location.search)
|
||||
|
||||
|
@ -101,7 +101,7 @@ function buildPlaylistLink (options: {
|
|||
|
||||
const url = baseUrl
|
||||
? baseUrl
|
||||
: window.location.origin + window.location.pathname.replace('/video-playlists/embed/', '/videos/watch/playlist/')
|
||||
: window.location.origin + window.location.pathname.replace('/video-playlists/embed/', '/w/p/')
|
||||
|
||||
const params = generateParams(window.location.search)
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ async function getSitemapLocalVideoUrls () {
|
|||
})
|
||||
|
||||
return data.map(v => ({
|
||||
url: WEBSERVER.URL + '/videos/watch/' + v.uuid,
|
||||
url: WEBSERVER.URL + '/w/' + v.uuid,
|
||||
video: [
|
||||
{
|
||||
title: v.name,
|
||||
|
|
|
@ -19,8 +19,8 @@ const testEmbedPath = join(distPath, 'standalone', 'videos', 'test-embed.html')
|
|||
|
||||
// Special route that add OpenGraph and oEmbed tags
|
||||
// Do not use a template engine for a so little thing
|
||||
clientsRouter.use('/videos/watch/playlist/:id', asyncMiddleware(generateWatchPlaylistHtmlPage))
|
||||
clientsRouter.use('/videos/watch/:id', asyncMiddleware(generateWatchHtmlPage))
|
||||
clientsRouter.use([ '/w/p/:id', '/videos/watch/playlist/:id' ], asyncMiddleware(generateWatchPlaylistHtmlPage))
|
||||
clientsRouter.use([ '/w/:id', '/videos/watch/:id' ], asyncMiddleware(generateWatchHtmlPage))
|
||||
clientsRouter.use([ '/accounts/:nameWithHost', '/a/:nameWithHost' ], asyncMiddleware(generateAccountHtmlPage))
|
||||
clientsRouter.use([ '/video-channels/:nameWithHost', '/c/:nameWithHost' ], asyncMiddleware(generateVideoChannelHtmlPage))
|
||||
clientsRouter.use('/@:nameWithHost', asyncMiddleware(generateActorHtmlPage))
|
||||
|
|
|
@ -293,7 +293,7 @@ function addVideosToFeed (feed, videos: VideoModel[]) {
|
|||
feed.addItem({
|
||||
title: video.name,
|
||||
id: video.url,
|
||||
link: WEBSERVER.URL + '/videos/watch/' + video.uuid,
|
||||
link: WEBSERVER.URL + '/w/' + video.uuid,
|
||||
description: video.getTruncatedDescription(),
|
||||
content: video.description,
|
||||
author: [
|
||||
|
|
|
@ -4,15 +4,29 @@ import { join } from 'path'
|
|||
import { fetchVideo } from '@server/helpers/video'
|
||||
import { VideoPlaylistModel } from '@server/models/video/video-playlist'
|
||||
import { VideoPlaylistPrivacy, VideoPrivacy } from '@shared/models'
|
||||
import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
|
||||
import { isTestInstance } from '../../helpers/core-utils'
|
||||
import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc'
|
||||
import { logger } from '../../helpers/logger'
|
||||
import { WEBSERVER } from '../../initializers/constants'
|
||||
import { areValidationErrors } from './utils'
|
||||
import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
|
||||
|
||||
const startVideoPlaylistsURL = WEBSERVER.SCHEME + '://' + join(WEBSERVER.HOST, 'videos', 'watch', 'playlist') + '/'
|
||||
const startVideosURL = WEBSERVER.SCHEME + '://' + join(WEBSERVER.HOST, 'videos', 'watch') + '/'
|
||||
const playlistPaths = [
|
||||
join('videos', 'watch', 'playlist'),
|
||||
join('w', 'p')
|
||||
]
|
||||
|
||||
const videoPaths = [
|
||||
join('videos', 'watch'),
|
||||
'w'
|
||||
]
|
||||
|
||||
function buildUrls (paths: string[]) {
|
||||
return paths.map(p => WEBSERVER.SCHEME + '://' + join(WEBSERVER.HOST, p) + '/')
|
||||
}
|
||||
|
||||
const startPlaylistURLs = buildUrls(playlistPaths)
|
||||
const startVideoURLs = buildUrls(videoPaths)
|
||||
|
||||
const watchRegex = /([^/]+)$/
|
||||
const isURLOptions = {
|
||||
|
@ -43,8 +57,8 @@ const oembedValidator = [
|
|||
|
||||
const url = req.query.url as string
|
||||
|
||||
const isPlaylist = url.startsWith(startVideoPlaylistsURL)
|
||||
const isVideo = isPlaylist ? false : url.startsWith(startVideosURL)
|
||||
const isPlaylist = startPlaylistURLs.some(u => url.startsWith(u))
|
||||
const isVideo = isPlaylist ? false : startVideoURLs.some(u => url.startsWith(u))
|
||||
|
||||
const startIsOk = isVideo || isPlaylist
|
||||
|
||||
|
|
|
@ -496,7 +496,7 @@ export class VideoPlaylistModel extends Model<Partial<AttributesOnly<VideoPlayli
|
|||
}
|
||||
|
||||
getWatchUrl () {
|
||||
return WEBSERVER.URL + '/videos/watch/playlist/' + this.uuid
|
||||
return WEBSERVER.URL + '/w/p/' + this.uuid
|
||||
}
|
||||
|
||||
getEmbedStaticPath () {
|
||||
|
|
|
@ -1920,7 +1920,7 @@ export class VideoModel extends Model<Partial<AttributesOnly<VideoModel>>> {
|
|||
}
|
||||
|
||||
getWatchStaticPath () {
|
||||
return '/videos/watch/' + this.uuid
|
||||
return '/w/' + this.uuid
|
||||
}
|
||||
|
||||
getEmbedStaticPath () {
|
||||
|
|
|
@ -67,61 +67,67 @@ describe('Test services', function () {
|
|||
})
|
||||
|
||||
it('Should have a valid oEmbed video response', async function () {
|
||||
const oembedUrl = 'http://localhost:' + server.port + '/videos/watch/' + video.uuid
|
||||
for (const basePath of [ '/videos/watch/', '/w/' ]) {
|
||||
const oembedUrl = 'http://localhost:' + server.port + basePath + video.uuid
|
||||
|
||||
const res = await getOEmbed(server.url, oembedUrl)
|
||||
const expectedHtml = '<iframe width="560" height="315" sandbox="allow-same-origin allow-scripts" ' +
|
||||
`title="${video.name}" src="http://localhost:${server.port}/videos/embed/${video.uuid}" ` +
|
||||
'frameborder="0" allowfullscreen></iframe>'
|
||||
const expectedThumbnailUrl = 'http://localhost:' + server.port + video.previewPath
|
||||
const res = await getOEmbed(server.url, oembedUrl)
|
||||
const expectedHtml = '<iframe width="560" height="315" sandbox="allow-same-origin allow-scripts" ' +
|
||||
`title="${video.name}" src="http://localhost:${server.port}/videos/embed/${video.uuid}" ` +
|
||||
'frameborder="0" allowfullscreen></iframe>'
|
||||
const expectedThumbnailUrl = 'http://localhost:' + server.port + video.previewPath
|
||||
|
||||
expect(res.body.html).to.equal(expectedHtml)
|
||||
expect(res.body.title).to.equal(video.name)
|
||||
expect(res.body.author_name).to.equal(server.videoChannel.displayName)
|
||||
expect(res.body.width).to.equal(560)
|
||||
expect(res.body.height).to.equal(315)
|
||||
expect(res.body.thumbnail_url).to.equal(expectedThumbnailUrl)
|
||||
expect(res.body.thumbnail_width).to.equal(850)
|
||||
expect(res.body.thumbnail_height).to.equal(480)
|
||||
expect(res.body.html).to.equal(expectedHtml)
|
||||
expect(res.body.title).to.equal(video.name)
|
||||
expect(res.body.author_name).to.equal(server.videoChannel.displayName)
|
||||
expect(res.body.width).to.equal(560)
|
||||
expect(res.body.height).to.equal(315)
|
||||
expect(res.body.thumbnail_url).to.equal(expectedThumbnailUrl)
|
||||
expect(res.body.thumbnail_width).to.equal(850)
|
||||
expect(res.body.thumbnail_height).to.equal(480)
|
||||
}
|
||||
})
|
||||
|
||||
it('Should have a valid playlist oEmbed response', async function () {
|
||||
const oembedUrl = 'http://localhost:' + server.port + '/videos/watch/playlist/' + playlistUUID
|
||||
for (const basePath of [ '/videos/watch/playlist/', '/w/p/' ]) {
|
||||
const oembedUrl = 'http://localhost:' + server.port + basePath + playlistUUID
|
||||
|
||||
const res = await getOEmbed(server.url, oembedUrl)
|
||||
const expectedHtml = '<iframe width="560" height="315" sandbox="allow-same-origin allow-scripts" ' +
|
||||
`title="${playlistDisplayName}" src="http://localhost:${server.port}/video-playlists/embed/${playlistUUID}" ` +
|
||||
'frameborder="0" allowfullscreen></iframe>'
|
||||
const res = await getOEmbed(server.url, oembedUrl)
|
||||
const expectedHtml = '<iframe width="560" height="315" sandbox="allow-same-origin allow-scripts" ' +
|
||||
`title="${playlistDisplayName}" src="http://localhost:${server.port}/video-playlists/embed/${playlistUUID}" ` +
|
||||
'frameborder="0" allowfullscreen></iframe>'
|
||||
|
||||
expect(res.body.html).to.equal(expectedHtml)
|
||||
expect(res.body.title).to.equal('The Life and Times of Scrooge McDuck')
|
||||
expect(res.body.author_name).to.equal(server.videoChannel.displayName)
|
||||
expect(res.body.width).to.equal(560)
|
||||
expect(res.body.height).to.equal(315)
|
||||
expect(res.body.thumbnail_url).exist
|
||||
expect(res.body.thumbnail_width).to.equal(280)
|
||||
expect(res.body.thumbnail_height).to.equal(157)
|
||||
expect(res.body.html).to.equal(expectedHtml)
|
||||
expect(res.body.title).to.equal('The Life and Times of Scrooge McDuck')
|
||||
expect(res.body.author_name).to.equal(server.videoChannel.displayName)
|
||||
expect(res.body.width).to.equal(560)
|
||||
expect(res.body.height).to.equal(315)
|
||||
expect(res.body.thumbnail_url).exist
|
||||
expect(res.body.thumbnail_width).to.equal(280)
|
||||
expect(res.body.thumbnail_height).to.equal(157)
|
||||
}
|
||||
})
|
||||
|
||||
it('Should have a valid oEmbed response with small max height query', async function () {
|
||||
const oembedUrl = 'http://localhost:' + server.port + '/videos/watch/' + video.uuid
|
||||
const format = 'json'
|
||||
const maxHeight = 50
|
||||
const maxWidth = 50
|
||||
for (const basePath of [ '/videos/watch/', '/w/' ]) {
|
||||
const oembedUrl = 'http://localhost:' + server.port + basePath + video.uuid
|
||||
const format = 'json'
|
||||
const maxHeight = 50
|
||||
const maxWidth = 50
|
||||
|
||||
const res = await getOEmbed(server.url, oembedUrl, format, maxHeight, maxWidth)
|
||||
const expectedHtml = '<iframe width="50" height="50" sandbox="allow-same-origin allow-scripts" ' +
|
||||
`title="${video.name}" src="http://localhost:${server.port}/videos/embed/${video.uuid}" ` +
|
||||
'frameborder="0" allowfullscreen></iframe>'
|
||||
const res = await getOEmbed(server.url, oembedUrl, format, maxHeight, maxWidth)
|
||||
const expectedHtml = '<iframe width="50" height="50" sandbox="allow-same-origin allow-scripts" ' +
|
||||
`title="${video.name}" src="http://localhost:${server.port}/videos/embed/${video.uuid}" ` +
|
||||
'frameborder="0" allowfullscreen></iframe>'
|
||||
|
||||
expect(res.body.html).to.equal(expectedHtml)
|
||||
expect(res.body.title).to.equal(video.name)
|
||||
expect(res.body.author_name).to.equal(server.videoChannel.displayName)
|
||||
expect(res.body.height).to.equal(50)
|
||||
expect(res.body.width).to.equal(50)
|
||||
expect(res.body).to.not.have.property('thumbnail_url')
|
||||
expect(res.body).to.not.have.property('thumbnail_width')
|
||||
expect(res.body).to.not.have.property('thumbnail_height')
|
||||
expect(res.body.html).to.equal(expectedHtml)
|
||||
expect(res.body.title).to.equal(video.name)
|
||||
expect(res.body.author_name).to.equal(server.videoChannel.displayName)
|
||||
expect(res.body.height).to.equal(50)
|
||||
expect(res.body.width).to.equal(50)
|
||||
expect(res.body).to.not.have.property('thumbnail_url')
|
||||
expect(res.body).to.not.have.property('thumbnail_width')
|
||||
expect(res.body).to.not.have.property('thumbnail_height')
|
||||
}
|
||||
})
|
||||
|
||||
after(async function () {
|
||||
|
|
|
@ -54,6 +54,9 @@ describe('Test a client controllers', function () {
|
|||
|
||||
const channelDescription = 'my super channel description'
|
||||
|
||||
const watchVideoBasePaths = [ '/videos/watch/', '/w/' ]
|
||||
const watchPlaylistBasePaths = [ '/videos/watch/playlist/', '/w/p/' ]
|
||||
|
||||
before(async function () {
|
||||
this.timeout(120000)
|
||||
|
||||
|
@ -111,35 +114,40 @@ describe('Test a client controllers', function () {
|
|||
})
|
||||
|
||||
describe('oEmbed', function () {
|
||||
|
||||
it('Should have valid oEmbed discovery tags for videos', async function () {
|
||||
const path = '/videos/watch/' + servers[0].video.uuid
|
||||
const res = await request(servers[0].url)
|
||||
.get(path)
|
||||
.set('Accept', 'text/html')
|
||||
.expect(HttpStatusCode.OK_200)
|
||||
for (const basePath of watchVideoBasePaths) {
|
||||
const path = basePath + servers[0].video.uuid
|
||||
const res = await request(servers[0].url)
|
||||
.get(path)
|
||||
.set('Accept', 'text/html')
|
||||
.expect(HttpStatusCode.OK_200)
|
||||
|
||||
const port = servers[0].port
|
||||
const port = servers[0].port
|
||||
|
||||
const expectedLink = '<link rel="alternate" type="application/json+oembed" href="http://localhost:' + port + '/services/oembed?' +
|
||||
`url=http%3A%2F%2Flocalhost%3A${port}%2Fvideos%2Fwatch%2F${servers[0].video.uuid}" ` +
|
||||
`title="${servers[0].video.name}" />`
|
||||
const expectedLink = '<link rel="alternate" type="application/json+oembed" href="http://localhost:' + port + '/services/oembed?' +
|
||||
`url=http%3A%2F%2Flocalhost%3A${port}%2Fw%2F${servers[0].video.uuid}" ` +
|
||||
`title="${servers[0].video.name}" />`
|
||||
|
||||
expect(res.text).to.contain(expectedLink)
|
||||
expect(res.text).to.contain(expectedLink)
|
||||
}
|
||||
})
|
||||
|
||||
it('Should have valid oEmbed discovery tags for a playlist', async function () {
|
||||
const res = await request(servers[0].url)
|
||||
.get('/videos/watch/playlist/' + playlistUUID)
|
||||
.set('Accept', 'text/html')
|
||||
.expect(HttpStatusCode.OK_200)
|
||||
for (const basePath of watchPlaylistBasePaths) {
|
||||
const res = await request(servers[0].url)
|
||||
.get(basePath + playlistUUID)
|
||||
.set('Accept', 'text/html')
|
||||
.expect(HttpStatusCode.OK_200)
|
||||
|
||||
const port = servers[0].port
|
||||
const port = servers[0].port
|
||||
|
||||
const expectedLink = '<link rel="alternate" type="application/json+oembed" href="http://localhost:' + port + '/services/oembed?' +
|
||||
`url=http%3A%2F%2Flocalhost%3A${port}%2Fvideos%2Fwatch%2Fplaylist%2F${playlistUUID}" ` +
|
||||
`title="${playlistName}" />`
|
||||
const expectedLink = '<link rel="alternate" type="application/json+oembed" href="http://localhost:' + port + '/services/oembed?' +
|
||||
`url=http%3A%2F%2Flocalhost%3A${port}%2Fw%2Fp%2F${playlistUUID}" ` +
|
||||
`title="${playlistName}" />`
|
||||
|
||||
expect(res.text).to.contain(expectedLink)
|
||||
expect(res.text).to.contain(expectedLink)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -165,6 +173,26 @@ describe('Test a client controllers', function () {
|
|||
expect(text).to.contain(`<meta property="og:url" content="${servers[0].url}/video-channels/${servers[0].videoChannel.name}" />`)
|
||||
}
|
||||
|
||||
async function watchVideoPageTest (path: string) {
|
||||
const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', statusCodeExpected: HttpStatusCode.OK_200 })
|
||||
const text = res.text
|
||||
|
||||
expect(text).to.contain(`<meta property="og:title" content="${videoName}" />`)
|
||||
expect(text).to.contain(`<meta property="og:description" content="${videoDescriptionPlainText}" />`)
|
||||
expect(text).to.contain('<meta property="og:type" content="video" />')
|
||||
expect(text).to.contain(`<meta property="og:url" content="${servers[0].url}/w/${servers[0].video.uuid}" />`)
|
||||
}
|
||||
|
||||
async function watchPlaylistPageTest (path: string) {
|
||||
const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', statusCodeExpected: HttpStatusCode.OK_200 })
|
||||
const text = res.text
|
||||
|
||||
expect(text).to.contain(`<meta property="og:title" content="${playlistName}" />`)
|
||||
expect(text).to.contain(`<meta property="og:description" content="${playlistDescription}" />`)
|
||||
expect(text).to.contain('<meta property="og:type" content="video" />')
|
||||
expect(text).to.contain(`<meta property="og:url" content="${servers[0].url}/w/p/${playlistUUID}" />`)
|
||||
}
|
||||
|
||||
it('Should have valid Open Graph tags on the account page', async function () {
|
||||
await accountPageTest('/accounts/' + servers[0].user.username)
|
||||
await accountPageTest('/a/' + servers[0].user.username)
|
||||
|
@ -177,40 +205,16 @@ describe('Test a client controllers', function () {
|
|||
await channelPageTest('/@' + servers[0].videoChannel.name)
|
||||
})
|
||||
|
||||
it('Should have valid Open Graph tags on the watch page with video id', async function () {
|
||||
const res = await request(servers[0].url)
|
||||
.get('/videos/watch/' + servers[0].video.id)
|
||||
.set('Accept', 'text/html')
|
||||
.expect(HttpStatusCode.OK_200)
|
||||
|
||||
expect(res.text).to.contain(`<meta property="og:title" content="${videoName}" />`)
|
||||
expect(res.text).to.contain(`<meta property="og:description" content="${videoDescriptionPlainText}" />`)
|
||||
expect(res.text).to.contain('<meta property="og:type" content="video" />')
|
||||
expect(res.text).to.contain(`<meta property="og:url" content="${servers[0].url}/videos/watch/${servers[0].video.uuid}" />`)
|
||||
})
|
||||
|
||||
it('Should have valid Open Graph tags on the watch page with video uuid', async function () {
|
||||
const res = await request(servers[0].url)
|
||||
.get('/videos/watch/' + servers[0].video.uuid)
|
||||
.set('Accept', 'text/html')
|
||||
.expect(HttpStatusCode.OK_200)
|
||||
|
||||
expect(res.text).to.contain(`<meta property="og:title" content="${videoName}" />`)
|
||||
expect(res.text).to.contain(`<meta property="og:description" content="${videoDescriptionPlainText}" />`)
|
||||
expect(res.text).to.contain('<meta property="og:type" content="video" />')
|
||||
expect(res.text).to.contain(`<meta property="og:url" content="${servers[0].url}/videos/watch/${servers[0].video.uuid}" />`)
|
||||
it('Should have valid Open Graph tags on the watch page', async function () {
|
||||
await watchVideoPageTest('/videos/watch/' + servers[0].video.id)
|
||||
await watchVideoPageTest('/videos/watch/' + servers[0].video.uuid)
|
||||
await watchVideoPageTest('/w/' + servers[0].video.uuid)
|
||||
await watchVideoPageTest('/w/' + servers[0].video.id)
|
||||
})
|
||||
|
||||
it('Should have valid Open Graph tags on the watch playlist page', async function () {
|
||||
const res = await request(servers[0].url)
|
||||
.get('/videos/watch/playlist/' + playlistUUID)
|
||||
.set('Accept', 'text/html')
|
||||
.expect(HttpStatusCode.OK_200)
|
||||
|
||||
expect(res.text).to.contain(`<meta property="og:title" content="${playlistName}" />`)
|
||||
expect(res.text).to.contain(`<meta property="og:description" content="${playlistDescription}" />`)
|
||||
expect(res.text).to.contain('<meta property="og:type" content="video" />')
|
||||
expect(res.text).to.contain(`<meta property="og:url" content="${servers[0].url}/videos/watch/playlist/${playlistUUID}" />`)
|
||||
await watchPlaylistPageTest('/videos/watch/playlist/' + playlistUUID)
|
||||
await watchPlaylistPageTest('/w/p/' + playlistUUID)
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -238,28 +242,36 @@ describe('Test a client controllers', function () {
|
|||
expect(text).to.contain(`<meta property="twitter:description" content="${channelDescription}" />`)
|
||||
}
|
||||
|
||||
it('Should have valid twitter card on the watch video page', async function () {
|
||||
const res = await request(servers[0].url)
|
||||
.get('/videos/watch/' + servers[0].video.uuid)
|
||||
.set('Accept', 'text/html')
|
||||
.expect(HttpStatusCode.OK_200)
|
||||
async function watchVideoPageTest (path: string) {
|
||||
const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', statusCodeExpected: HttpStatusCode.OK_200 })
|
||||
const text = res.text
|
||||
|
||||
expect(res.text).to.contain('<meta property="twitter:card" content="summary_large_image" />')
|
||||
expect(res.text).to.contain('<meta property="twitter:site" content="@Chocobozzz" />')
|
||||
expect(res.text).to.contain(`<meta property="twitter:title" content="${videoName}" />`)
|
||||
expect(res.text).to.contain(`<meta property="twitter:description" content="${videoDescriptionPlainText}" />`)
|
||||
expect(text).to.contain('<meta property="twitter:card" content="summary_large_image" />')
|
||||
expect(text).to.contain('<meta property="twitter:site" content="@Chocobozzz" />')
|
||||
expect(text).to.contain(`<meta property="twitter:title" content="${videoName}" />`)
|
||||
expect(text).to.contain(`<meta property="twitter:description" content="${videoDescriptionPlainText}" />`)
|
||||
}
|
||||
|
||||
async function watchPlaylistPageTest (path: string) {
|
||||
const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', statusCodeExpected: HttpStatusCode.OK_200 })
|
||||
const text = res.text
|
||||
|
||||
expect(text).to.contain('<meta property="twitter:card" content="summary" />')
|
||||
expect(text).to.contain('<meta property="twitter:site" content="@Chocobozzz" />')
|
||||
expect(text).to.contain(`<meta property="twitter:title" content="${playlistName}" />`)
|
||||
expect(text).to.contain(`<meta property="twitter:description" content="${playlistDescription}" />`)
|
||||
}
|
||||
|
||||
it('Should have valid twitter card on the watch video page', async function () {
|
||||
await watchVideoPageTest('/videos/watch/' + servers[0].video.id)
|
||||
await watchVideoPageTest('/videos/watch/' + servers[0].video.uuid)
|
||||
await watchVideoPageTest('/w/' + servers[0].video.uuid)
|
||||
await watchVideoPageTest('/w/' + servers[0].video.id)
|
||||
})
|
||||
|
||||
it('Should have valid twitter card on the watch playlist page', async function () {
|
||||
const res = await request(servers[0].url)
|
||||
.get('/videos/watch/playlist/' + playlistUUID)
|
||||
.set('Accept', 'text/html')
|
||||
.expect(HttpStatusCode.OK_200)
|
||||
|
||||
expect(res.text).to.contain('<meta property="twitter:card" content="summary" />')
|
||||
expect(res.text).to.contain('<meta property="twitter:site" content="@Chocobozzz" />')
|
||||
expect(res.text).to.contain(`<meta property="twitter:title" content="${playlistName}" />`)
|
||||
expect(res.text).to.contain(`<meta property="twitter:description" content="${playlistDescription}" />`)
|
||||
await watchPlaylistPageTest('/videos/watch/playlist/' + playlistUUID)
|
||||
await watchPlaylistPageTest('/w/p/' + playlistUUID)
|
||||
})
|
||||
|
||||
it('Should have valid twitter card on the account page', async function () {
|
||||
|
@ -304,24 +316,32 @@ describe('Test a client controllers', function () {
|
|||
expect(text).to.contain('<meta property="twitter:site" content="@Kuja" />')
|
||||
}
|
||||
|
||||
it('Should have valid twitter card on the watch video page', async function () {
|
||||
const res = await request(servers[0].url)
|
||||
.get('/videos/watch/' + servers[0].video.uuid)
|
||||
.set('Accept', 'text/html')
|
||||
.expect(HttpStatusCode.OK_200)
|
||||
async function watchVideoPageTest (path: string) {
|
||||
const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', statusCodeExpected: HttpStatusCode.OK_200 })
|
||||
const text = res.text
|
||||
|
||||
expect(res.text).to.contain('<meta property="twitter:card" content="player" />')
|
||||
expect(res.text).to.contain('<meta property="twitter:site" content="@Kuja" />')
|
||||
expect(text).to.contain('<meta property="twitter:card" content="player" />')
|
||||
expect(text).to.contain('<meta property="twitter:site" content="@Kuja" />')
|
||||
}
|
||||
|
||||
async function watchPlaylistPageTest (path: string) {
|
||||
const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', statusCodeExpected: HttpStatusCode.OK_200 })
|
||||
const text = res.text
|
||||
|
||||
expect(text).to.contain('<meta property="twitter:card" content="player" />')
|
||||
expect(text).to.contain('<meta property="twitter:site" content="@Kuja" />')
|
||||
}
|
||||
|
||||
it('Should have valid twitter card on the watch video page', async function () {
|
||||
await watchVideoPageTest('/videos/watch/' + servers[0].video.id)
|
||||
await watchVideoPageTest('/videos/watch/' + servers[0].video.uuid)
|
||||
await watchVideoPageTest('/w/' + servers[0].video.uuid)
|
||||
await watchVideoPageTest('/w/' + servers[0].video.id)
|
||||
})
|
||||
|
||||
it('Should have valid twitter card on the watch playlist page', async function () {
|
||||
const res = await request(servers[0].url)
|
||||
.get('/videos/watch/playlist/' + playlistUUID)
|
||||
.set('Accept', 'text/html')
|
||||
.expect(HttpStatusCode.OK_200)
|
||||
|
||||
expect(res.text).to.contain('<meta property="twitter:card" content="player" />')
|
||||
expect(res.text).to.contain('<meta property="twitter:site" content="@Kuja" />')
|
||||
await watchPlaylistPageTest('/videos/watch/playlist/' + playlistUUID)
|
||||
await watchPlaylistPageTest('/w/p/' + playlistUUID)
|
||||
})
|
||||
|
||||
it('Should have valid twitter card on the account page', async function () {
|
||||
|
@ -378,8 +398,10 @@ describe('Test a client controllers', function () {
|
|||
})
|
||||
|
||||
it('Should use the original video URL for the canonical tag', async function () {
|
||||
const res = await makeHTMLRequest(servers[1].url, '/videos/watch/' + servers[0].video.uuid)
|
||||
expect(res.text).to.contain(`<link rel="canonical" href="${servers[0].url}/videos/watch/${servers[0].video.uuid}" />`)
|
||||
for (const basePath of watchVideoBasePaths) {
|
||||
const res = await makeHTMLRequest(servers[1].url, basePath + servers[0].video.uuid)
|
||||
expect(res.text).to.contain(`<link rel="canonical" href="${servers[0].url}/videos/watch/${servers[0].video.uuid}" />`)
|
||||
}
|
||||
})
|
||||
|
||||
it('Should use the original account URL for the canonical tag', async function () {
|
||||
|
@ -403,8 +425,10 @@ describe('Test a client controllers', function () {
|
|||
})
|
||||
|
||||
it('Should use the original playlist URL for the canonical tag', async function () {
|
||||
const res = await makeHTMLRequest(servers[1].url, '/videos/watch/playlist/' + playlistUUID)
|
||||
expect(res.text).to.contain(`<link rel="canonical" href="${servers[0].url}/video-playlists/${playlistUUID}" />`)
|
||||
for (const basePath of watchPlaylistBasePaths) {
|
||||
const res = await makeHTMLRequest(servers[1].url, basePath + playlistUUID)
|
||||
expect(res.text).to.contain(`<link rel="canonical" href="${servers[0].url}/video-playlists/${playlistUUID}" />`)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ function run (url: string, options: program.OptionValues) {
|
|||
|
||||
const cmd = 'node ' + join(__dirname, 'node_modules', 'webtorrent-hybrid', 'bin', 'cmd.js')
|
||||
const args = ` --${options.gui} ` +
|
||||
url.replace('videos/watch', 'download/torrents') +
|
||||
url.replace(/(\/videos\/watch\/)|\/w\//, '/download/torrents/') +
|
||||
`-${options.resolution}.torrent`
|
||||
|
||||
try {
|
||||
|
|
Loading…
Reference in New Issue