Ability for admins to set default upload values
This commit is contained in:
parent
a6f919e455
commit
3cf68b869d
|
@ -21,6 +21,24 @@ export class VideoWatchPage {
|
|||
return this.getVideoNameElement().then(e => e.getText())
|
||||
}
|
||||
|
||||
getPrivacy () {
|
||||
return $('.attribute-privacy .attribute-value').getText()
|
||||
}
|
||||
|
||||
getLicence () {
|
||||
return $('.attribute-licence .attribute-value').getText()
|
||||
}
|
||||
|
||||
async isDownloadEnabled () {
|
||||
await this.clickOnMoreDropdownIcon()
|
||||
|
||||
return $('.dropdown-item .icon-download').isExisting()
|
||||
}
|
||||
|
||||
areCommentsEnabled () {
|
||||
return $('my-video-comment-add').isExisting()
|
||||
}
|
||||
|
||||
async goOnAssociatedEmbed () {
|
||||
let url = await browser.getUrl()
|
||||
url = url.replace('/w/', '/videos/embed/')
|
||||
|
@ -38,10 +56,8 @@ export class VideoWatchPage {
|
|||
}
|
||||
|
||||
async clickOnUpdate () {
|
||||
const dropdown = $('my-video-actions-dropdown .action-button')
|
||||
await dropdown.click()
|
||||
await this.clickOnMoreDropdownIcon()
|
||||
|
||||
await $('.dropdown-menu.show .dropdown-item').waitForDisplayed()
|
||||
const items = await $$('.dropdown-menu.show .dropdown-item')
|
||||
|
||||
for (const item of items) {
|
||||
|
@ -86,6 +102,13 @@ export class VideoWatchPage {
|
|||
}, { timeout: maxTime })
|
||||
}
|
||||
|
||||
async clickOnMoreDropdownIcon () {
|
||||
const dropdown = $('my-video-actions-dropdown .action-button')
|
||||
await dropdown.click()
|
||||
|
||||
await $('.dropdown-menu.show .dropdown-item').waitForDisplayed()
|
||||
}
|
||||
|
||||
private async getVideoNameElement () {
|
||||
// We have 2 video info name block, pick the first that is not empty
|
||||
const elem = async () => {
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
import { LoginPage } from '../po/login.po'
|
||||
import { VideoUploadPage } from '../po/video-upload.po'
|
||||
import { VideoWatchPage } from '../po/video-watch.po'
|
||||
import { isMobileDevice, isSafari, waitServerUp } from '../utils'
|
||||
|
||||
describe('Custom server defaults', () => {
|
||||
let videoUploadPage: VideoUploadPage
|
||||
let loginPage: LoginPage
|
||||
let videoWatchPage: VideoWatchPage
|
||||
|
||||
before(async () => {
|
||||
await waitServerUp()
|
||||
})
|
||||
|
||||
beforeEach(async () => {
|
||||
loginPage = new LoginPage()
|
||||
videoUploadPage = new VideoUploadPage()
|
||||
videoWatchPage = new VideoWatchPage(isMobileDevice(), isSafari())
|
||||
|
||||
await browser.maximizeWindow()
|
||||
})
|
||||
|
||||
it('Should upload a video with custom default values', async function () {
|
||||
await loginPage.loginAsRootUser()
|
||||
await videoUploadPage.navigateTo()
|
||||
await videoUploadPage.uploadVideo()
|
||||
await videoUploadPage.validSecondUploadStep('video')
|
||||
|
||||
await videoWatchPage.waitWatchVideoName('video')
|
||||
|
||||
expect(await videoWatchPage.getPrivacy()).toBe('Internal')
|
||||
expect(await videoWatchPage.getLicence()).toBe('Attribution - Non Commercial')
|
||||
expect(await videoWatchPage.isDownloadEnabled()).toBeFalsy()
|
||||
expect(await videoWatchPage.areCommentsEnabled()).toBeFalsy()
|
||||
})
|
||||
|
||||
})
|
|
@ -4,6 +4,7 @@ import { MyAccountPage } from '../po/my-account'
|
|||
import { VideoListPage } from '../po/video-list.po'
|
||||
import { VideoSearchPage } from '../po/video-search.po'
|
||||
import { VideoUploadPage } from '../po/video-upload.po'
|
||||
import { VideoWatchPage } from '../po/video-watch.po'
|
||||
import { NSFWPolicy } from '../types/common'
|
||||
import { isMobileDevice, isSafari, waitServerUp } from '../utils'
|
||||
|
||||
|
@ -14,6 +15,7 @@ describe('Videos list', () => {
|
|||
let loginPage: LoginPage
|
||||
let myAccountPage: MyAccountPage
|
||||
let videoSearchPage: VideoSearchPage
|
||||
let videoWatchPage: VideoWatchPage
|
||||
|
||||
const seed = Math.random()
|
||||
const nsfwVideo = seed + ' - nsfw'
|
||||
|
@ -108,6 +110,7 @@ describe('Videos list', () => {
|
|||
videoUploadPage = new VideoUploadPage()
|
||||
myAccountPage = new MyAccountPage()
|
||||
videoSearchPage = new VideoSearchPage()
|
||||
videoWatchPage = new VideoWatchPage(isMobileDevice(), isSafari())
|
||||
|
||||
await browser.maximizeWindow()
|
||||
})
|
||||
|
@ -191,5 +194,26 @@ describe('Videos list', () => {
|
|||
await checkCommonVideoListPages('display')
|
||||
await checkSearchPage('display')
|
||||
})
|
||||
|
||||
after(async () => {
|
||||
await loginPage.logout()
|
||||
})
|
||||
})
|
||||
|
||||
describe('Default upload values', function () {
|
||||
|
||||
it('Should have default video values', async function () {
|
||||
await loginPage.loginAsRootUser()
|
||||
await videoUploadPage.navigateTo()
|
||||
await videoUploadPage.uploadVideo()
|
||||
await videoUploadPage.validSecondUploadStep('video')
|
||||
|
||||
await videoWatchPage.waitWatchVideoName('video')
|
||||
|
||||
expect(await videoWatchPage.getPrivacy()).toBe('Public')
|
||||
expect(await videoWatchPage.getLicence()).toBe('Unknown')
|
||||
expect(await videoWatchPage.isDownloadEnabled()).toBeTruthy()
|
||||
expect(await videoWatchPage.areCommentsEnabled()).toBeTruthy()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
import { ChildProcessWithoutNullStreams } from 'child_process'
|
||||
import { basename } from 'path'
|
||||
import { runCommand, runServer } from './server'
|
||||
|
||||
let appInstance: string
|
||||
let app: ChildProcessWithoutNullStreams
|
||||
|
||||
async function beforeLocalSuite (suite: any) {
|
||||
const config = buildConfig(suite.file)
|
||||
|
||||
await runCommand('npm run clean:server:test -- ' + appInstance)
|
||||
app = runServer(appInstance, config)
|
||||
}
|
||||
|
||||
function afterLocalSuite () {
|
||||
app.kill()
|
||||
app = undefined
|
||||
}
|
||||
|
||||
function beforeLocalSession (config: { baseUrl: string }, capabilities: { browserName: string }) {
|
||||
appInstance = capabilities['browserName'] === 'chrome' ? '1' : '2'
|
||||
config.baseUrl = 'http://localhost:900' + appInstance
|
||||
}
|
||||
|
||||
async function onBrowserStackPrepare () {
|
||||
const appInstance = '1'
|
||||
|
||||
await runCommand('npm run clean:server:test -- ' + appInstance)
|
||||
app = runServer(appInstance)
|
||||
}
|
||||
|
||||
function onBrowserStackComplete () {
|
||||
app.kill()
|
||||
app = undefined
|
||||
}
|
||||
|
||||
export {
|
||||
beforeLocalSession,
|
||||
afterLocalSuite,
|
||||
beforeLocalSuite,
|
||||
onBrowserStackPrepare,
|
||||
onBrowserStackComplete
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function buildConfig (suiteFile: string = undefined) {
|
||||
const filename = basename(suiteFile)
|
||||
|
||||
if (filename === 'custom-server-defaults.e2e-spec.ts') {
|
||||
return {
|
||||
defaults: {
|
||||
publish: {
|
||||
download_enabled: false,
|
||||
comments_enabled: false,
|
||||
privacy: 4,
|
||||
licence: 4
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {}
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
export * from './common'
|
||||
export * from './elements'
|
||||
export * from './hooks'
|
||||
export * from './server'
|
||||
export * from './urls'
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
import { exec, spawn } from 'child_process'
|
||||
import { join, resolve } from 'path'
|
||||
|
||||
function runServer (appInstance: string, config: any = {}) {
|
||||
const env = Object.create(process.env)
|
||||
env['NODE_ENV'] = 'test'
|
||||
env['NODE_APP_INSTANCE'] = appInstance
|
||||
|
||||
env['NODE_CONFIG'] = JSON.stringify({
|
||||
rates_limit: {
|
||||
api: {
|
||||
max: 5000
|
||||
},
|
||||
login: {
|
||||
max: 5000
|
||||
}
|
||||
},
|
||||
log: {
|
||||
level: 'warn'
|
||||
},
|
||||
signup: {
|
||||
enabled: false
|
||||
},
|
||||
transcoding: {
|
||||
enabled: false
|
||||
},
|
||||
|
||||
...config
|
||||
})
|
||||
|
||||
const forkOptions = {
|
||||
env,
|
||||
cwd: getRootCWD(),
|
||||
detached: false
|
||||
}
|
||||
|
||||
const p = spawn('node', [ join('dist', 'server.js') ], forkOptions)
|
||||
p.stderr.on('data', data => console.error(data.toString()))
|
||||
p.stdout.on('data', data => console.error(data.toString()))
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
function runCommand (command: string) {
|
||||
return new Promise<void>((res, rej) => {
|
||||
const p = exec(command, { cwd: getRootCWD() })
|
||||
|
||||
p.stderr.on('data', data => console.error(data.toString()))
|
||||
p.on('error', err => rej(err))
|
||||
p.on('exit', () => res())
|
||||
})
|
||||
}
|
||||
|
||||
export {
|
||||
runServer,
|
||||
runCommand
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function getRootCWD () {
|
||||
return resolve('../..')
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
import { onBrowserStackComplete, onBrowserStackPrepare } from './src/utils'
|
||||
import { config as mainConfig } from './wdio.main.conf'
|
||||
|
||||
const user = process.env.BROWSERSTACK_USER
|
||||
|
@ -114,6 +115,10 @@ module.exports = {
|
|||
if (capabilities['bstack:options'].realMobile === true) {
|
||||
capabilities['bstack:options'].local = false
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onPrepare: onBrowserStackPrepare,
|
||||
onComplete: onBrowserStackComplete
|
||||
|
||||
} as WebdriverIO.Config
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { afterLocalSuite, beforeLocalSuite, beforeLocalSession } from './src/utils'
|
||||
import { config as mainConfig } from './wdio.main.conf'
|
||||
|
||||
const prefs = {
|
||||
|
@ -21,12 +22,16 @@ module.exports = {
|
|||
browserName: 'chrome',
|
||||
acceptInsecureCerts: true,
|
||||
'goog:chromeOptions': {
|
||||
args: [ '--headless', '--disable-gpu', '--window-size=1280,1024' ],
|
||||
args: [ '--disable-gpu', '--window-size=1280,1024' ],
|
||||
prefs
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
services: [ 'chromedriver' ]
|
||||
services: [ 'chromedriver' ],
|
||||
|
||||
beforeSession: beforeLocalSession,
|
||||
beforeSuite: beforeLocalSuite,
|
||||
afterSuite: afterLocalSuite
|
||||
} as WebdriverIO.Config
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { afterLocalSuite, beforeLocalSession, beforeLocalSuite } from './src/utils'
|
||||
import { config as mainConfig } from './wdio.main.conf'
|
||||
|
||||
const prefs = {
|
||||
|
@ -11,7 +12,7 @@ module.exports = {
|
|||
|
||||
runner: 'local',
|
||||
|
||||
maxInstances: 2,
|
||||
maxInstancesPerCapability: 1,
|
||||
|
||||
capabilities: [
|
||||
{
|
||||
|
@ -34,12 +35,8 @@ module.exports = {
|
|||
|
||||
services: [ 'chromedriver', 'geckodriver' ],
|
||||
|
||||
beforeSession: function (config, capabilities) {
|
||||
if (capabilities['browserName'] === 'chrome') {
|
||||
config.baseUrl = 'http://localhost:9001'
|
||||
} else {
|
||||
config.baseUrl = 'http://localhost:9002'
|
||||
}
|
||||
}
|
||||
beforeSession: beforeLocalSession,
|
||||
beforeSuite: beforeLocalSuite,
|
||||
afterSuite: afterLocalSuite
|
||||
} as WebdriverIO.Config
|
||||
}
|
||||
|
|
|
@ -110,9 +110,10 @@ export class VideoEditComponent implements OnInit, OnDestroy {
|
|||
updateForm () {
|
||||
const defaultValues: any = {
|
||||
nsfw: 'false',
|
||||
commentsEnabled: 'true',
|
||||
downloadEnabled: 'true',
|
||||
commentsEnabled: this.serverConfig.defaults.publish.commentsEnabled,
|
||||
downloadEnabled: this.serverConfig.defaults.publish.downloadEnabled,
|
||||
waitTranscoding: 'true',
|
||||
licence: this.serverConfig.defaults.publish.licence,
|
||||
tags: []
|
||||
}
|
||||
const obj: any = {
|
||||
|
@ -160,6 +161,8 @@ export class VideoEditComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
|
||||
ngOnInit () {
|
||||
this.serverConfig = this.serverService.getHTMLConfig()
|
||||
|
||||
this.updateForm()
|
||||
|
||||
this.pluginService.ensurePluginsAreLoaded('video-edit')
|
||||
|
@ -200,8 +203,6 @@ export class VideoEditComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
})
|
||||
|
||||
this.serverConfig = this.serverService.getHTMLConfig()
|
||||
|
||||
this.initialVideoCaptions = this.videoCaptions.map(c => c.language.id)
|
||||
|
||||
this.ngZone.runOutsideAngular(() => {
|
||||
|
|
|
@ -70,8 +70,6 @@ export class VideoGoLiveComponent extends VideoSend implements OnInit, AfterView
|
|||
privacy: this.highestPrivacy,
|
||||
nsfw: this.serverConfig.instance.isNSFW,
|
||||
waitTranscoding: true,
|
||||
commentsEnabled: true,
|
||||
downloadEnabled: true,
|
||||
permanentLive: this.firstStepPermanentLive,
|
||||
saveReplay: this.firstStepPermanentLive === false && this.isReplayAllowed(),
|
||||
channelId: this.firstStepChannelId
|
||||
|
|
|
@ -81,8 +81,6 @@ export class VideoImportTorrentComponent extends VideoSend implements OnInit, Af
|
|||
const videoUpdate: VideoUpdate = {
|
||||
privacy: this.highestPrivacy,
|
||||
waitTranscoding: false,
|
||||
commentsEnabled: true,
|
||||
downloadEnabled: true,
|
||||
channelId: this.firstStepChannelId
|
||||
}
|
||||
|
||||
|
|
|
@ -68,8 +68,6 @@ export class VideoImportUrlComponent extends VideoSend implements OnInit, AfterV
|
|||
const videoUpdate: VideoUpdate = {
|
||||
privacy: this.highestPrivacy,
|
||||
waitTranscoding: false,
|
||||
commentsEnabled: true,
|
||||
downloadEnabled: true,
|
||||
channelId: this.firstStepChannelId
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,9 @@ export abstract class VideoSend extends FormReactive implements OnInit {
|
|||
this.serverService.getVideoPrivacies()
|
||||
.subscribe(
|
||||
privacies => {
|
||||
const { videoPrivacies, defaultPrivacyId } = this.videoService.explainedPrivacyLabels(privacies)
|
||||
const defaultPrivacy = this.serverConfig.defaults.publish.privacy
|
||||
|
||||
const { videoPrivacies, defaultPrivacyId } = this.videoService.explainedPrivacyLabels(privacies, defaultPrivacy)
|
||||
|
||||
this.videoPrivacies = videoPrivacies
|
||||
this.firstStepPrivacyId = defaultPrivacyId
|
||||
|
|
|
@ -277,8 +277,6 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy
|
|||
private uploadFile (file: File, previewfile?: File) {
|
||||
const metadata = {
|
||||
waitTranscoding: true,
|
||||
commentsEnabled: true,
|
||||
downloadEnabled: true,
|
||||
channelId: this.firstStepChannelId,
|
||||
nsfw: this.serverConfig.instance.isNSFW,
|
||||
privacy: this.highestPrivacy.toString(),
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
<ng-container *ngIf="!isUserLoggedIn && !video.isLive">
|
||||
<button
|
||||
*ngIf="isVideoDownloadable()" class="action-button action-button-save"
|
||||
*ngIf="isVideoDownloadable()" class="action-button action-button-download"
|
||||
(click)="showDownloadModal()" (keydown.enter)="showDownloadModal()"
|
||||
>
|
||||
<my-global-icon iconName="download" aria-hidden="true"></my-global-icon>
|
||||
|
|
|
@ -49,7 +49,8 @@
|
|||
}
|
||||
}
|
||||
|
||||
&.action-button-save {
|
||||
&.action-button-save,
|
||||
&.action-button-download {
|
||||
my-global-icon {
|
||||
top: 0 !important;
|
||||
right: -1px;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<div class="attribute">
|
||||
<div class="attribute attribute-privacy">
|
||||
<span i18n class="attribute-label">Privacy</span>
|
||||
<span class="attribute-value">{{ video.privacy.label }}</span>
|
||||
</div>
|
||||
|
||||
<div *ngIf="video.isLocal === false" class="attribute">
|
||||
<div *ngIf="video.isLocal === false" class="attribute attribute-origin">
|
||||
<span i18n class="attribute-label">Origin</span>
|
||||
<a
|
||||
class="attribute-value" target="_blank" rel="noopener noreferrer"
|
||||
|
@ -16,12 +16,12 @@
|
|||
></a>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!!video.originallyPublishedAt" class="attribute">
|
||||
<div *ngIf="!!video.originallyPublishedAt" class="attribute attribute-originally-published-at">
|
||||
<span i18n class="attribute-label">Originally published</span>
|
||||
<span class="attribute-value">{{ video.originallyPublishedAt | date: 'dd MMMM yyyy' }}</span>
|
||||
</div>
|
||||
|
||||
<div class="attribute">
|
||||
<div class="attribute attribute-category">
|
||||
<span i18n class="attribute-label">Category</span>
|
||||
<span *ngIf="!video.category.id" class="attribute-value">{{ video.category.label }}</span>
|
||||
<a
|
||||
|
@ -30,7 +30,7 @@
|
|||
>{{ video.category.label }}</a>
|
||||
</div>
|
||||
|
||||
<div class="attribute">
|
||||
<div class="attribute attribute-licence">
|
||||
<span i18n class="attribute-label">Licence</span>
|
||||
<span *ngIf="!video.licence.id" class="attribute-value">{{ video.licence.label }}</span>
|
||||
<a
|
||||
|
@ -39,7 +39,7 @@
|
|||
>{{ video.licence.label }}</a>
|
||||
</div>
|
||||
|
||||
<div class="attribute">
|
||||
<div class="attribute attribute-language">
|
||||
<span i18n class="attribute-label">Language</span>
|
||||
<span *ngIf="!video.language.id" class="attribute-value">{{ video.language.label }}</span>
|
||||
<a
|
||||
|
@ -56,7 +56,7 @@
|
|||
>{{ tag }}</a>
|
||||
</div>
|
||||
|
||||
<div class="attribute" *ngIf="!video.isLive">
|
||||
<div class="attribute attribute-duration" *ngIf="!video.isLive">
|
||||
<span i18n class="attribute-label">Duration</span>
|
||||
<span class="attribute-value">{{ video.duration | myDurationFormatter }}</span>
|
||||
</div>
|
||||
|
|
|
@ -75,18 +75,22 @@ email:
|
|||
subject:
|
||||
prefix: '[PeerTube]'
|
||||
|
||||
# PeerTube client/interface configuration
|
||||
client:
|
||||
videos:
|
||||
miniature:
|
||||
# By default PeerTube client displays author username
|
||||
prefer_author_display_name: false
|
||||
# Update default PeerTube values
|
||||
# Set by API when the field is not provided and put as default value in client
|
||||
defaults:
|
||||
# Change default values when publishing a video (upload/import/go Live)
|
||||
publish:
|
||||
download_enabled: true
|
||||
|
||||
menu:
|
||||
login:
|
||||
# If you enable only one external auth plugin
|
||||
# You can automatically redirect your users on this external platform when they click on the login button
|
||||
redirect_on_single_external_auth: false
|
||||
comments_enabled: true
|
||||
|
||||
# public = 1, unlisted = 2, private = 3, internal = 4
|
||||
privacy: 1
|
||||
|
||||
# CC-BY = 1, CC-SA = 2, CC-ND = 3, CC-NC = 4, CC-NC-SA = 5, CC-NC-ND = 6, Public Domain = 7
|
||||
# You can also choose a custom licence value added by a plugin
|
||||
# No licence by default
|
||||
licence: null
|
||||
|
||||
# From the project root directory
|
||||
storage:
|
||||
|
@ -587,3 +591,16 @@ search:
|
|||
disable_local_search: false
|
||||
# If you did not disable local search, you can decide to use the search index by default
|
||||
is_default_search: false
|
||||
|
||||
# PeerTube client/interface configuration
|
||||
client:
|
||||
videos:
|
||||
miniature:
|
||||
# By default PeerTube client displays author username
|
||||
prefer_author_display_name: false
|
||||
|
||||
menu:
|
||||
login:
|
||||
# If you enable only one external auth plugin
|
||||
# You can automatically redirect your users on this external platform when they click on the login button
|
||||
redirect_on_single_external_auth: false
|
||||
|
|
|
@ -73,18 +73,22 @@ email:
|
|||
subject:
|
||||
prefix: '[PeerTube]'
|
||||
|
||||
# PeerTube client/interface configuration
|
||||
client:
|
||||
videos:
|
||||
miniature:
|
||||
# By default PeerTube client displays author username
|
||||
prefer_author_display_name: false
|
||||
# Update default PeerTube values
|
||||
# Set by API when the field is not provided and put as default value in client
|
||||
defaults:
|
||||
# Change default values when publishing a video (upload/import/go Live)
|
||||
publish:
|
||||
download_enabled: true
|
||||
|
||||
menu:
|
||||
login:
|
||||
# If you enable only one external auth plugin
|
||||
# You can automatically redirect your users on this external platform when they click on the login button
|
||||
redirect_on_single_external_auth: false
|
||||
comments_enabled: true
|
||||
|
||||
# public = 1, unlisted = 2, private = 3, internal = 4
|
||||
privacy: 1
|
||||
|
||||
# CC-BY = 1, CC-SA = 2, CC-ND = 3, CC-NC = 4, CC-NC-SA = 5, CC-NC-ND = 6, Public Domain = 7
|
||||
# You can also choose a custom licence value added by a plugin
|
||||
# No licence by default
|
||||
licence: null
|
||||
|
||||
# From the project root directory
|
||||
storage:
|
||||
|
@ -597,3 +601,16 @@ search:
|
|||
disable_local_search: false
|
||||
# If you did not disable local search, you can decide to use the search index by default
|
||||
is_default_search: false
|
||||
|
||||
# PeerTube client/interface configuration
|
||||
client:
|
||||
videos:
|
||||
miniature:
|
||||
# By default PeerTube client displays author username
|
||||
prefer_author_display_name: false
|
||||
|
||||
menu:
|
||||
login:
|
||||
# If you enable only one external auth plugin
|
||||
# You can automatically redirect your users on this external platform when they click on the login button
|
||||
redirect_on_single_external_auth: false
|
||||
|
|
|
@ -2,8 +2,4 @@
|
|||
|
||||
set -eu
|
||||
|
||||
npm run clean:server:test
|
||||
|
||||
npm run concurrently -- -k -s first \
|
||||
"cd client/e2e && ../node_modules/.bin/wdio run ./wdio.browserstack.conf.ts" \
|
||||
"NODE_ENV=test NODE_APP_INSTANCE=1 NODE_CONFIG='{ \"rates_limit\": { \"api\": { \"max\": 5000 }, \"login\": { \"max\": 5000 } }, \"log\": { \"level\": \"warn\" }, \"signup\": { \"enabled\": false } }' node dist/server"
|
||||
cd client/e2e && ../node_modules/.bin/wdio run ./wdio.browserstack.conf.ts
|
||||
|
|
|
@ -2,16 +2,6 @@
|
|||
|
||||
set -eu
|
||||
|
||||
npm run clean:server:test
|
||||
cd client/e2e
|
||||
|
||||
config="{"
|
||||
config+=" \"rates_limit\": { \"api\": { \"max\": 5000 }, \"login\": { \"max\": 5000 } }"
|
||||
config+=", \"log\": { \"level\": \"warn\" }"
|
||||
config+=", \"signup\": { \"enabled\": false }"
|
||||
config+=", \"transcoding\": { \"enabled\": false }"
|
||||
config+="}"
|
||||
|
||||
npm run concurrently -- -k -s first \
|
||||
"cd client/e2e && ../node_modules/.bin/wdio run ./wdio.local.conf.ts" \
|
||||
"NODE_ENV=test NODE_CONFIG='$config' NODE_APP_INSTANCE=1 node dist/server" \
|
||||
"NODE_ENV=test NODE_CONFIG='$config' NODE_APP_INSTANCE=2 node dist/server"
|
||||
../node_modules/.bin/wdio run ./wdio.local.conf.ts
|
||||
|
|
|
@ -216,10 +216,10 @@ async function buildVideo (channelId: number, body: VideoImportCreate, importDat
|
|||
name: body.name || importData.name || 'Unknown name',
|
||||
remote: false,
|
||||
category: body.category || importData.category,
|
||||
licence: body.licence || importData.licence,
|
||||
licence: body.licence ?? importData.licence ?? CONFIG.DEFAULTS.PUBLISH.LICENCE,
|
||||
language: body.language || importData.language,
|
||||
commentsEnabled: body.commentsEnabled !== false, // If the value is not "false", the default is "true"
|
||||
downloadEnabled: body.downloadEnabled !== false,
|
||||
commentsEnabled: body.commentsEnabled ?? CONFIG.DEFAULTS.PUBLISH.COMMENTS_ENABLED,
|
||||
downloadEnabled: body.downloadEnabled ?? CONFIG.DEFAULTS.PUBLISH.DOWNLOAD_ENABLED,
|
||||
waitTranscoding: body.waitTranscoding || false,
|
||||
state: VideoState.TO_IMPORT,
|
||||
nsfw: body.nsfw || importData.nsfw || false,
|
||||
|
|
|
@ -34,6 +34,7 @@ function checkMissedConfig () {
|
|||
'import.videos.http.enabled', 'import.videos.torrent.enabled', 'import.videos.concurrency', 'auto_blacklist.videos.of_users.enabled',
|
||||
'trending.videos.interval_days',
|
||||
'client.videos.miniature.prefer_author_display_name', 'client.menu.login.redirect_on_single_external_auth',
|
||||
'defaults.publish.download_enabled', 'defaults.publish.comments_enabled', 'defaults.publish.privacy', 'defaults.publish.licence',
|
||||
'instance.name', 'instance.short_description', 'instance.description', 'instance.terms', 'instance.default_client_route',
|
||||
'instance.is_nsfw', 'instance.default_nsfw_policy', 'instance.robots', 'instance.securitytxt',
|
||||
'services.twitter.username', 'services.twitter.whitelisted',
|
||||
|
|
|
@ -4,7 +4,7 @@ import { dirname, join } from 'path'
|
|||
import { decacheModule } from '@server/helpers/decache'
|
||||
import { VideoRedundancyConfigFilter } from '@shared/models/redundancy/video-redundancy-config-filter.type'
|
||||
import { BroadcastMessageLevel } from '@shared/models/server'
|
||||
import { VideosRedundancyStrategy } from '../../shared/models'
|
||||
import { VideoPrivacy, VideosRedundancyStrategy } from '../../shared/models'
|
||||
import { NSFWPolicyType } from '../../shared/models/videos/nsfw-policy.type'
|
||||
import { buildPath, parseBytes, parseDurationToMs, root } from '../helpers/core-utils'
|
||||
|
||||
|
@ -71,6 +71,15 @@ const CONFIG = {
|
|||
}
|
||||
},
|
||||
|
||||
DEFAULTS: {
|
||||
PUBLISH: {
|
||||
DOWNLOAD_ENABLED: config.get<boolean>('defaults.publish.download_enabled'),
|
||||
COMMENTS_ENABLED: config.get<boolean>('defaults.publish.comments_enabled'),
|
||||
PRIVACY: config.get<VideoPrivacy>('defaults.publish.privacy'),
|
||||
LICENCE: config.get<number>('defaults.publish.licence')
|
||||
}
|
||||
},
|
||||
|
||||
STORAGE: {
|
||||
TMP_DIR: buildPath(config.get<string>('storage.tmp')),
|
||||
BIN_DIR: buildPath(config.get<string>('storage.bin')),
|
||||
|
|
|
@ -55,6 +55,15 @@ class ServerConfigManager {
|
|||
}
|
||||
},
|
||||
|
||||
defaults: {
|
||||
publish: {
|
||||
downloadEnabled: CONFIG.DEFAULTS.PUBLISH.DOWNLOAD_ENABLED,
|
||||
commentsEnabled: CONFIG.DEFAULTS.PUBLISH.COMMENTS_ENABLED,
|
||||
privacy: CONFIG.DEFAULTS.PUBLISH.PRIVACY,
|
||||
licence: CONFIG.DEFAULTS.PUBLISH.LICENCE
|
||||
}
|
||||
},
|
||||
|
||||
webadmin: {
|
||||
configuration: {
|
||||
edition: {
|
||||
|
|
|
@ -9,16 +9,17 @@ import { MThumbnail, MUserId, MVideoFile, MVideoTag, MVideoThumbnail, MVideoUUID
|
|||
import { ThumbnailType, VideoCreate, VideoPrivacy, VideoTranscodingPayload } from '@shared/models'
|
||||
import { CreateJobOptions, JobQueue } from './job-queue/job-queue'
|
||||
import { updateVideoMiniatureFromExisting } from './thumbnail'
|
||||
import { CONFIG } from '@server/initializers/config'
|
||||
|
||||
function buildLocalVideoFromReq (videoInfo: VideoCreate, channelId: number): FilteredModelAttributes<VideoModel> {
|
||||
return {
|
||||
name: videoInfo.name,
|
||||
remote: false,
|
||||
category: videoInfo.category,
|
||||
licence: videoInfo.licence,
|
||||
licence: videoInfo.licence ?? CONFIG.DEFAULTS.PUBLISH.LICENCE,
|
||||
language: videoInfo.language,
|
||||
commentsEnabled: videoInfo.commentsEnabled !== false, // If the value is not "false", the default is "true"
|
||||
downloadEnabled: videoInfo.downloadEnabled !== false,
|
||||
commentsEnabled: videoInfo.commentsEnabled ?? CONFIG.DEFAULTS.PUBLISH.COMMENTS_ENABLED,
|
||||
downloadEnabled: videoInfo.downloadEnabled ?? CONFIG.DEFAULTS.PUBLISH.DOWNLOAD_ENABLED,
|
||||
waitTranscoding: videoInfo.waitTranscoding || false,
|
||||
nsfw: videoInfo.nsfw || false,
|
||||
description: videoInfo.description,
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
|
||||
|
||||
import 'mocha'
|
||||
import * as chai from 'chai'
|
||||
import { cleanupTests, createSingleServer, FIXTURE_URLS, PeerTubeServer, setAccessTokensToServers, setDefaultVideoChannel } from '@shared/extra-utils'
|
||||
import { VideoDetails, VideoPrivacy } from '@shared/models'
|
||||
|
||||
const expect = chai.expect
|
||||
|
||||
describe('Test config defaults', function () {
|
||||
let server: PeerTubeServer
|
||||
let channelId: number
|
||||
|
||||
before(async function () {
|
||||
this.timeout(30000)
|
||||
|
||||
const overrideConfig = {
|
||||
defaults: {
|
||||
publish: {
|
||||
comments_enabled: false,
|
||||
download_enabled: false,
|
||||
privacy: VideoPrivacy.INTERNAL,
|
||||
licence: 4
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
server = await createSingleServer(1, overrideConfig)
|
||||
await setAccessTokensToServers([ server ])
|
||||
await setDefaultVideoChannel([ server ])
|
||||
|
||||
channelId = server.store.channel.id
|
||||
})
|
||||
|
||||
describe('Default publish values', function () {
|
||||
const attributes = {
|
||||
name: 'video',
|
||||
downloadEnabled: undefined,
|
||||
commentsEnabled: undefined,
|
||||
licence: undefined,
|
||||
privacy: VideoPrivacy.PUBLIC // Privacy is mandatory for server
|
||||
}
|
||||
|
||||
function checkVideo (video: VideoDetails) {
|
||||
expect(video.downloadEnabled).to.be.false
|
||||
expect(video.commentsEnabled).to.be.false
|
||||
expect(video.licence.id).to.equal(4)
|
||||
}
|
||||
|
||||
before(async function () {
|
||||
await server.config.disableTranscoding()
|
||||
await server.config.enableImports()
|
||||
await server.config.enableLive({ allowReplay: false, transcoding: false })
|
||||
})
|
||||
|
||||
it('Should have the correct server configuration', async function () {
|
||||
const config = await server.config.getConfig()
|
||||
|
||||
expect(config.defaults.publish.commentsEnabled).to.be.false
|
||||
expect(config.defaults.publish.downloadEnabled).to.be.false
|
||||
expect(config.defaults.publish.licence).to.equal(4)
|
||||
expect(config.defaults.publish.privacy).to.equal(VideoPrivacy.INTERNAL)
|
||||
})
|
||||
|
||||
it('Should respect default values when uploading a video', async function () {
|
||||
for (const mode of [ 'legacy' as 'legacy', 'resumable' as 'resumable' ]) {
|
||||
const { id } = await server.videos.upload({ attributes, mode })
|
||||
|
||||
const video = await server.videos.get({ id })
|
||||
checkVideo(video)
|
||||
}
|
||||
})
|
||||
|
||||
it('Should respect default values when importing a video using URL', async function () {
|
||||
const { video: { id } } = await server.imports.importVideo({
|
||||
attributes: {
|
||||
...attributes,
|
||||
channelId,
|
||||
targetUrl: FIXTURE_URLS.goodVideo
|
||||
}
|
||||
})
|
||||
|
||||
const video = await server.videos.get({ id })
|
||||
checkVideo(video)
|
||||
})
|
||||
|
||||
it('Should respect default values when importing a video using magnet URI', async function () {
|
||||
const { video: { id } } = await server.imports.importVideo({
|
||||
attributes: {
|
||||
...attributes,
|
||||
channelId,
|
||||
magnetUri: FIXTURE_URLS.magnet
|
||||
}
|
||||
})
|
||||
|
||||
const video = await server.videos.get({ id })
|
||||
checkVideo(video)
|
||||
})
|
||||
|
||||
it('Should respect default values when creating a live', async function () {
|
||||
const { id } = await server.live.create({
|
||||
fields: {
|
||||
...attributes,
|
||||
channelId
|
||||
}
|
||||
})
|
||||
|
||||
const video = await server.videos.get({ id })
|
||||
checkVideo(video)
|
||||
})
|
||||
})
|
||||
|
||||
after(async function () {
|
||||
await cleanupTests([ server ])
|
||||
})
|
||||
})
|
|
@ -1,4 +1,6 @@
|
|||
import './auto-follows'
|
||||
import './bulk'
|
||||
import './config-defaults'
|
||||
import './config'
|
||||
import './contact-form'
|
||||
import './email'
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { VideoPrivacy } from '../videos/video-privacy.enum'
|
||||
import { ClientScript } from '../plugins/plugin-package-json.model'
|
||||
import { NSFWPolicyType } from '../videos/nsfw-policy.type'
|
||||
import { BroadcastMessageLevel } from './broadcast-message-level.type'
|
||||
|
@ -47,6 +48,15 @@ export interface ServerConfig {
|
|||
}
|
||||
}
|
||||
|
||||
defaults: {
|
||||
publish: {
|
||||
downloadEnabled: boolean
|
||||
commentsEnabled: boolean
|
||||
privacy: VideoPrivacy
|
||||
licence: number
|
||||
}
|
||||
}
|
||||
|
||||
webadmin: {
|
||||
configuration: {
|
||||
edition: {
|
||||
|
|
|
@ -88,13 +88,7 @@ $ BROWSERSTACK_USER=your_user BROWSERSTACK_KEY=your_key npm run e2e:browserstack
|
|||
|
||||
### Add E2E tests
|
||||
|
||||
To add E2E tests and quickly run tests using a local Chrome, first create a test instance:
|
||||
|
||||
```bash
|
||||
$ npm run clean:server:test && NODE_APP_INSTANCE=1 NODE_ENV=test npm start
|
||||
```
|
||||
|
||||
Then, just run your suite using:
|
||||
To add E2E tests and quickly run tests using a local Chrome:
|
||||
|
||||
```bash
|
||||
$ cd client/e2e
|
||||
|
|
Loading…
Reference in New Issue