Make some fields optional when uploading a video
This commit is contained in:
parent
27e1a06c33
commit
8e7f08b5a5
|
@ -0,0 +1,46 @@
|
||||||
|
import * as Sequelize from 'sequelize'
|
||||||
|
import { PeerTubeDatabase } from '../database'
|
||||||
|
|
||||||
|
async function up (utils: {
|
||||||
|
transaction: Sequelize.Transaction,
|
||||||
|
queryInterface: Sequelize.QueryInterface,
|
||||||
|
sequelize: Sequelize.Sequelize,
|
||||||
|
db: PeerTubeDatabase
|
||||||
|
}): Promise<void> {
|
||||||
|
|
||||||
|
{
|
||||||
|
const data = {
|
||||||
|
type: Sequelize.INTEGER,
|
||||||
|
allowNull: true,
|
||||||
|
defaultValue: null
|
||||||
|
}
|
||||||
|
await utils.queryInterface.changeColumn('Videos', 'licence', data)
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const data = {
|
||||||
|
type: Sequelize.INTEGER,
|
||||||
|
allowNull: true,
|
||||||
|
defaultValue: null
|
||||||
|
}
|
||||||
|
await utils.queryInterface.changeColumn('Videos', 'category', data)
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const data = {
|
||||||
|
type: Sequelize.INTEGER,
|
||||||
|
allowNull: true,
|
||||||
|
defaultValue: null
|
||||||
|
}
|
||||||
|
await utils.queryInterface.changeColumn('Videos', 'description', data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function down (options) {
|
||||||
|
throw new Error('Not implemented.')
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
up,
|
||||||
|
down
|
||||||
|
}
|
|
@ -31,11 +31,11 @@ const videosAddValidator = [
|
||||||
+ CONSTRAINTS_FIELDS.VIDEOS.EXTNAME.join(', ')
|
+ CONSTRAINTS_FIELDS.VIDEOS.EXTNAME.join(', ')
|
||||||
),
|
),
|
||||||
body('name').custom(isVideoNameValid).withMessage('Should have a valid name'),
|
body('name').custom(isVideoNameValid).withMessage('Should have a valid name'),
|
||||||
body('category').custom(isVideoCategoryValid).withMessage('Should have a valid category'),
|
body('category').optional().custom(isVideoCategoryValid).withMessage('Should have a valid category'),
|
||||||
body('licence').custom(isVideoLicenceValid).withMessage('Should have a valid licence'),
|
body('licence').optional().custom(isVideoLicenceValid).withMessage('Should have a valid licence'),
|
||||||
body('language').optional().custom(isVideoLanguageValid).withMessage('Should have a valid language'),
|
body('language').optional().custom(isVideoLanguageValid).withMessage('Should have a valid language'),
|
||||||
body('nsfw').custom(isVideoNSFWValid).withMessage('Should have a valid NSFW attribute'),
|
body('nsfw').custom(isVideoNSFWValid).withMessage('Should have a valid NSFW attribute'),
|
||||||
body('description').custom(isVideoDescriptionValid).withMessage('Should have a valid description'),
|
body('description').optional().custom(isVideoDescriptionValid).withMessage('Should have a valid description'),
|
||||||
body('channelId').custom(isIdValid).withMessage('Should have correct video channel id'),
|
body('channelId').custom(isIdValid).withMessage('Should have correct video channel id'),
|
||||||
body('privacy').custom(isVideoPrivacyValid).withMessage('Should have correct video privacy'),
|
body('privacy').custom(isVideoPrivacyValid).withMessage('Should have correct video privacy'),
|
||||||
body('tags').optional().custom(isVideoTagsValid).withMessage('Should have correct tags'),
|
body('tags').optional().custom(isVideoTagsValid).withMessage('Should have correct tags'),
|
||||||
|
|
|
@ -104,7 +104,8 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da
|
||||||
},
|
},
|
||||||
category: {
|
category: {
|
||||||
type: DataTypes.INTEGER,
|
type: DataTypes.INTEGER,
|
||||||
allowNull: false,
|
allowNull: true,
|
||||||
|
defaultValue: null,
|
||||||
validate: {
|
validate: {
|
||||||
categoryValid: value => {
|
categoryValid: value => {
|
||||||
const res = isVideoCategoryValid(value)
|
const res = isVideoCategoryValid(value)
|
||||||
|
@ -114,7 +115,7 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da
|
||||||
},
|
},
|
||||||
licence: {
|
licence: {
|
||||||
type: DataTypes.INTEGER,
|
type: DataTypes.INTEGER,
|
||||||
allowNull: false,
|
allowNull: true,
|
||||||
defaultValue: null,
|
defaultValue: null,
|
||||||
validate: {
|
validate: {
|
||||||
licenceValid: value => {
|
licenceValid: value => {
|
||||||
|
@ -126,6 +127,7 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da
|
||||||
language: {
|
language: {
|
||||||
type: DataTypes.INTEGER,
|
type: DataTypes.INTEGER,
|
||||||
allowNull: true,
|
allowNull: true,
|
||||||
|
defaultValue: null,
|
||||||
validate: {
|
validate: {
|
||||||
languageValid: value => {
|
languageValid: value => {
|
||||||
const res = isVideoLanguageValid(value)
|
const res = isVideoLanguageValid(value)
|
||||||
|
@ -155,7 +157,8 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da
|
||||||
},
|
},
|
||||||
description: {
|
description: {
|
||||||
type: DataTypes.STRING(CONSTRAINTS_FIELDS.VIDEOS.DESCRIPTION.max),
|
type: DataTypes.STRING(CONSTRAINTS_FIELDS.VIDEOS.DESCRIPTION.max),
|
||||||
allowNull: false,
|
allowNull: true,
|
||||||
|
defaultValue: null,
|
||||||
validate: {
|
validate: {
|
||||||
descriptionValid: value => {
|
descriptionValid: value => {
|
||||||
const res = isVideoDescriptionValid(value)
|
const res = isVideoDescriptionValid(value)
|
||||||
|
@ -664,6 +667,8 @@ toActivityPubObject = function (this: VideoInstance) {
|
||||||
}
|
}
|
||||||
|
|
||||||
getTruncatedDescription = function (this: VideoInstance) {
|
getTruncatedDescription = function (this: VideoInstance) {
|
||||||
|
if (!this.description) return null
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
length: CONSTRAINTS_FIELDS.VIDEOS.TRUNCATED_DESCRIPTION.max
|
length: CONSTRAINTS_FIELDS.VIDEOS.TRUNCATED_DESCRIPTION.max
|
||||||
}
|
}
|
||||||
|
@ -754,8 +759,6 @@ getDescriptionPath = function (this: VideoInstance) {
|
||||||
|
|
||||||
getCategoryLabel = function (this: VideoInstance) {
|
getCategoryLabel = function (this: VideoInstance) {
|
||||||
let categoryLabel = VIDEO_CATEGORIES[this.category]
|
let categoryLabel = VIDEO_CATEGORIES[this.category]
|
||||||
|
|
||||||
// Maybe our server is not up to date and there are new categories since our version
|
|
||||||
if (!categoryLabel) categoryLabel = 'Misc'
|
if (!categoryLabel) categoryLabel = 'Misc'
|
||||||
|
|
||||||
return categoryLabel
|
return categoryLabel
|
||||||
|
@ -763,15 +766,12 @@ getCategoryLabel = function (this: VideoInstance) {
|
||||||
|
|
||||||
getLicenceLabel = function (this: VideoInstance) {
|
getLicenceLabel = function (this: VideoInstance) {
|
||||||
let licenceLabel = VIDEO_LICENCES[this.licence]
|
let licenceLabel = VIDEO_LICENCES[this.licence]
|
||||||
|
|
||||||
// Maybe our server is not up to date and there are new licences since our version
|
|
||||||
if (!licenceLabel) licenceLabel = 'Unknown'
|
if (!licenceLabel) licenceLabel = 'Unknown'
|
||||||
|
|
||||||
return licenceLabel
|
return licenceLabel
|
||||||
}
|
}
|
||||||
|
|
||||||
getLanguageLabel = function (this: VideoInstance) {
|
getLanguageLabel = function (this: VideoInstance) {
|
||||||
// Language is an optional attribute
|
|
||||||
let languageLabel = VIDEO_LANGUAGES[this.language]
|
let languageLabel = VIDEO_LANGUAGES[this.language]
|
||||||
if (!languageLabel) languageLabel = 'Unknown'
|
if (!languageLabel) languageLabel = 'Unknown'
|
||||||
|
|
||||||
|
|
|
@ -189,14 +189,6 @@ describe('Test videos API validator', function () {
|
||||||
await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
|
await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should fail without a category', async function () {
|
|
||||||
const fields = getCompleteVideoUploadAttributes()
|
|
||||||
delete fields.category
|
|
||||||
|
|
||||||
const attaches = getVideoUploadAttaches
|
|
||||||
await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Should fail with a bad category', async function () {
|
it('Should fail with a bad category', async function () {
|
||||||
const fields = getCompleteVideoUploadAttributes()
|
const fields = getCompleteVideoUploadAttributes()
|
||||||
fields.category = 125
|
fields.category = 125
|
||||||
|
@ -205,14 +197,6 @@ describe('Test videos API validator', function () {
|
||||||
await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
|
await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should fail without a licence', async function () {
|
|
||||||
const fields = getCompleteVideoUploadAttributes()
|
|
||||||
delete fields.licence
|
|
||||||
|
|
||||||
const attaches = getVideoUploadAttaches()
|
|
||||||
await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Should fail with a bad licence', async function () {
|
it('Should fail with a bad licence', async function () {
|
||||||
const fields = getCompleteVideoUploadAttributes()
|
const fields = getCompleteVideoUploadAttributes()
|
||||||
fields.licence = 125
|
fields.licence = 125
|
||||||
|
@ -245,14 +229,6 @@ describe('Test videos API validator', function () {
|
||||||
await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
|
await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should fail without description', async function () {
|
|
||||||
const fields = getCompleteVideoUploadAttributes()
|
|
||||||
delete fields.description
|
|
||||||
|
|
||||||
const attaches = getVideoUploadAttaches()
|
|
||||||
await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Should fail with a long description', async function () {
|
it('Should fail with a long description', async function () {
|
||||||
const fields = getCompleteVideoUploadAttributes()
|
const fields = getCompleteVideoUploadAttributes()
|
||||||
fields.description = 'my super description which is very very very very very very very very very very very very long'.repeat(35)
|
fields.description = 'my super description which is very very very very very very very very very very very very long'.repeat(35)
|
||||||
|
|
|
@ -1,40 +1,41 @@
|
||||||
/* tslint:disable:no-unused-expression */
|
/* tslint:disable:no-unused-expression */
|
||||||
|
|
||||||
import { keyBy } from 'lodash'
|
|
||||||
import { join } from 'path'
|
|
||||||
import 'mocha'
|
|
||||||
import * as chai from 'chai'
|
import * as chai from 'chai'
|
||||||
const expect = chai.expect
|
import { keyBy } from 'lodash'
|
||||||
|
import 'mocha'
|
||||||
|
import { join } from 'path'
|
||||||
|
import * as request from 'supertest'
|
||||||
import {
|
import {
|
||||||
ServerInfo,
|
|
||||||
flushTests,
|
|
||||||
runServer,
|
|
||||||
uploadVideo,
|
|
||||||
getVideosList,
|
|
||||||
rateVideo,
|
|
||||||
removeVideo,
|
|
||||||
wait,
|
|
||||||
setAccessTokensToServers,
|
|
||||||
searchVideo,
|
|
||||||
killallServers,
|
|
||||||
dateIsValid,
|
dateIsValid,
|
||||||
getVideoCategories,
|
flushTests,
|
||||||
getVideoLicences,
|
|
||||||
getVideoLanguages,
|
|
||||||
getVideoPrivacies,
|
|
||||||
testVideoImage,
|
|
||||||
webtorrentAdd,
|
|
||||||
getVideo,
|
getVideo,
|
||||||
readdirPromise,
|
getVideoCategories,
|
||||||
|
getVideoLanguages,
|
||||||
|
getVideoLicences,
|
||||||
|
getVideoPrivacies,
|
||||||
|
getVideosList,
|
||||||
getVideosListPagination,
|
getVideosListPagination,
|
||||||
searchVideoWithPagination,
|
|
||||||
getVideosListSort,
|
getVideosListSort,
|
||||||
|
killallServers,
|
||||||
|
rateVideo,
|
||||||
|
readdirPromise,
|
||||||
|
removeVideo,
|
||||||
|
runServer,
|
||||||
|
searchVideo,
|
||||||
|
searchVideoWithPagination,
|
||||||
searchVideoWithSort,
|
searchVideoWithSort,
|
||||||
updateVideo
|
ServerInfo,
|
||||||
|
setAccessTokensToServers,
|
||||||
|
testVideoImage,
|
||||||
|
updateVideo,
|
||||||
|
uploadVideo,
|
||||||
|
wait,
|
||||||
|
webtorrentAdd
|
||||||
} from '../utils'
|
} from '../utils'
|
||||||
import { viewVideo } from '../utils/videos'
|
import { viewVideo } from '../utils/videos'
|
||||||
|
|
||||||
|
const expect = chai.expect
|
||||||
|
|
||||||
describe('Test a single server', function () {
|
describe('Test a single server', function () {
|
||||||
let server: ServerInfo = null
|
let server: ServerInfo = null
|
||||||
let videoId = -1
|
let videoId = -1
|
||||||
|
@ -693,6 +694,43 @@ describe('Test a single server', function () {
|
||||||
expect(video.dislikes).to.equal(1)
|
expect(video.dislikes).to.equal(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('Should upload a video with minimum parameters', async function () {
|
||||||
|
const path = '/api/v1/videos/upload'
|
||||||
|
|
||||||
|
const req = request(server.url)
|
||||||
|
.post(path)
|
||||||
|
.set('Accept', 'application/json')
|
||||||
|
.set('Authorization', 'Bearer ' + server.accessToken)
|
||||||
|
.field('name', 'minimum parameters')
|
||||||
|
.field('privacy', '1')
|
||||||
|
.field('nsfw', 'false')
|
||||||
|
.field('channelId', '1')
|
||||||
|
|
||||||
|
const filePath = join(__dirname, '..', 'api', 'fixtures', 'video_short.webm')
|
||||||
|
|
||||||
|
await req.attach('videofile', filePath)
|
||||||
|
.expect(204)
|
||||||
|
|
||||||
|
const res = await getVideosList(server.url)
|
||||||
|
const video = res.body.data.find(v => v.name === 'minimum parameters')
|
||||||
|
|
||||||
|
expect(video.name).to.equal('minimum parameters')
|
||||||
|
expect(video.category).to.equal(null)
|
||||||
|
expect(video.categoryLabel).to.equal('Misc')
|
||||||
|
expect(video.licence).to.equal(null)
|
||||||
|
expect(video.licenceLabel).to.equal('Unknown')
|
||||||
|
expect(video.language).to.equal(null)
|
||||||
|
expect(video.languageLabel).to.equal('Unknown')
|
||||||
|
expect(video.nsfw).to.not.be.ok
|
||||||
|
expect(video.description).to.equal(null)
|
||||||
|
expect(video.serverHost).to.equal('localhost:9001')
|
||||||
|
expect(video.accountName).to.equal('root')
|
||||||
|
expect(video.isLocal).to.be.true
|
||||||
|
expect(video.tags).to.deep.equal([ ])
|
||||||
|
expect(dateIsValid(video.createdAt)).to.be.true
|
||||||
|
expect(dateIsValid(video.updatedAt)).to.be.true
|
||||||
|
})
|
||||||
|
|
||||||
after(async function () {
|
after(async function () {
|
||||||
killallServers([ server ])
|
killallServers([ server ])
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue