Server: add ability to update a video
This commit is contained in:
parent
4ff0d86208
commit
7b1f49de22
|
@ -50,6 +50,12 @@ router.get('/',
|
||||||
pagination.setPagination,
|
pagination.setPagination,
|
||||||
listVideos
|
listVideos
|
||||||
)
|
)
|
||||||
|
router.put('/:id',
|
||||||
|
oAuth.authenticate,
|
||||||
|
reqFiles,
|
||||||
|
validatorsVideos.videosUpdate,
|
||||||
|
updateVideo
|
||||||
|
)
|
||||||
router.post('/',
|
router.post('/',
|
||||||
oAuth.authenticate,
|
oAuth.authenticate,
|
||||||
reqFiles,
|
reqFiles,
|
||||||
|
@ -165,7 +171,7 @@ function addVideo (req, res, next) {
|
||||||
},
|
},
|
||||||
|
|
||||||
function sendToFriends (t, video, callback) {
|
function sendToFriends (t, video, callback) {
|
||||||
video.toRemoteJSON(function (err, remoteVideo) {
|
video.toAddRemoteJSON(function (err, remoteVideo) {
|
||||||
if (err) return callback(err)
|
if (err) return callback(err)
|
||||||
|
|
||||||
// Now we'll add the video's meta data to our friends
|
// Now we'll add the video's meta data to our friends
|
||||||
|
@ -193,6 +199,83 @@ function addVideo (req, res, next) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateVideo (req, res, next) {
|
||||||
|
let videoInstance = res.locals.video
|
||||||
|
const videoInfosToUpdate = req.body
|
||||||
|
|
||||||
|
waterfall([
|
||||||
|
|
||||||
|
function startTransaction (callback) {
|
||||||
|
db.sequelize.transaction().asCallback(function (err, t) {
|
||||||
|
return callback(err, t)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
function findOrCreateTags (t, callback) {
|
||||||
|
if (videoInfosToUpdate.tags) {
|
||||||
|
db.Tag.findOrCreateTags(videoInfosToUpdate.tags, t, function (err, tagInstances) {
|
||||||
|
return callback(err, t, tagInstances)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
return callback(null, t, null)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
function updateVideoIntoDB (t, tagInstances, callback) {
|
||||||
|
const options = { transaction: t }
|
||||||
|
|
||||||
|
if (videoInfosToUpdate.name) videoInstance.set('name', videoInfosToUpdate.name)
|
||||||
|
if (videoInfosToUpdate.description) videoInstance.set('description', videoInfosToUpdate.description)
|
||||||
|
|
||||||
|
// Add tags association
|
||||||
|
videoInstance.save(options).asCallback(function (err) {
|
||||||
|
if (err) return callback(err)
|
||||||
|
|
||||||
|
return callback(err, t, tagInstances)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
function associateTagsToVideo (t, tagInstances, callback) {
|
||||||
|
if (tagInstances) {
|
||||||
|
const options = { transaction: t }
|
||||||
|
|
||||||
|
videoInstance.setTags(tagInstances, options).asCallback(function (err) {
|
||||||
|
videoInstance.Tags = tagInstances
|
||||||
|
|
||||||
|
return callback(err, t)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
return callback(null, t)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
function sendToFriends (t, callback) {
|
||||||
|
const json = videoInstance.toUpdateRemoteJSON()
|
||||||
|
|
||||||
|
// Now we'll update the video's meta data to our friends
|
||||||
|
friends.updateVideoToFriends(json)
|
||||||
|
|
||||||
|
return callback(null, t)
|
||||||
|
}
|
||||||
|
|
||||||
|
], function andFinally (err, t) {
|
||||||
|
if (err) {
|
||||||
|
logger.error('Cannot insert the video.')
|
||||||
|
|
||||||
|
// Abort transaction?
|
||||||
|
if (t) t.rollback()
|
||||||
|
|
||||||
|
return next(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Commit transaction
|
||||||
|
t.commit()
|
||||||
|
|
||||||
|
// TODO : include Location of the new video -> 201
|
||||||
|
return res.type('json').status(204).end()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
function getVideo (req, res, next) {
|
function getVideo (req, res, next) {
|
||||||
db.Video.loadAndPopulateAuthorAndPodAndTags(req.params.id, function (err, video) {
|
db.Video.loadAndPopulateAuthorAndPodAndTags(req.params.id, function (err, video) {
|
||||||
if (err) return next(err)
|
if (err) return next(err)
|
||||||
|
|
|
@ -14,6 +14,7 @@ const requests = require('../helpers/requests')
|
||||||
|
|
||||||
const friends = {
|
const friends = {
|
||||||
addVideoToFriends,
|
addVideoToFriends,
|
||||||
|
updateVideoToFriends,
|
||||||
hasFriends,
|
hasFriends,
|
||||||
getMyCertificate,
|
getMyCertificate,
|
||||||
makeFriends,
|
makeFriends,
|
||||||
|
@ -26,6 +27,10 @@ function addVideoToFriends (video) {
|
||||||
createRequest('add', constants.REQUEST_ENDPOINTS.VIDEOS, video)
|
createRequest('add', constants.REQUEST_ENDPOINTS.VIDEOS, video)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateVideoToFriends (video) {
|
||||||
|
createRequest('update', constants.REQUEST_ENDPOINTS.VIDEOS, video)
|
||||||
|
}
|
||||||
|
|
||||||
function hasFriends (callback) {
|
function hasFriends (callback) {
|
||||||
db.Pod.countAll(function (err, count) {
|
db.Pod.countAll(function (err, count) {
|
||||||
if (err) return callback(err)
|
if (err) return callback(err)
|
||||||
|
@ -127,7 +132,7 @@ function sendOwnedVideosToPod (podId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
videosList.forEach(function (video) {
|
videosList.forEach(function (video) {
|
||||||
video.toRemoteJSON(function (err, remoteVideo) {
|
video.toAddRemoteJSON(function (err, remoteVideo) {
|
||||||
if (err) {
|
if (err) {
|
||||||
logger.error('Cannot convert video to remote.', { error: err })
|
logger.error('Cannot convert video to remote.', { error: err })
|
||||||
// Don't break the process
|
// Don't break the process
|
||||||
|
|
|
@ -8,6 +8,7 @@ const logger = require('../../helpers/logger')
|
||||||
|
|
||||||
const validatorsVideos = {
|
const validatorsVideos = {
|
||||||
videosAdd,
|
videosAdd,
|
||||||
|
videosUpdate,
|
||||||
videosGet,
|
videosGet,
|
||||||
videosRemove,
|
videosRemove,
|
||||||
videosSearch
|
videosSearch
|
||||||
|
@ -41,22 +42,26 @@ function videosAdd (req, res, next) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function videosUpdate (req, res, next) {
|
||||||
|
req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4)
|
||||||
|
req.checkBody('name', 'Should have a valid name').optional().isVideoNameValid()
|
||||||
|
req.checkBody('description', 'Should have a valid description').optional().isVideoDescriptionValid()
|
||||||
|
req.checkBody('tags', 'Should have correct tags').optional().isVideoTagsValid()
|
||||||
|
|
||||||
|
logger.debug('Checking videosUpdate parameters', { parameters: req.body })
|
||||||
|
|
||||||
|
checkErrors(req, res, function () {
|
||||||
|
checkVideoExists(req.params.id, res, next)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
function videosGet (req, res, next) {
|
function videosGet (req, res, next) {
|
||||||
req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4)
|
req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4)
|
||||||
|
|
||||||
logger.debug('Checking videosGet parameters', { parameters: req.params })
|
logger.debug('Checking videosGet parameters', { parameters: req.params })
|
||||||
|
|
||||||
checkErrors(req, res, function () {
|
checkErrors(req, res, function () {
|
||||||
db.Video.load(req.params.id, function (err, video) {
|
checkVideoExists(req.params.id, res, next)
|
||||||
if (err) {
|
|
||||||
logger.error('Error in videosGet request validator.', { error: err })
|
|
||||||
return res.sendStatus(500)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!video) return res.status(404).send('Video not found')
|
|
||||||
|
|
||||||
next()
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,3 +99,19 @@ function videosSearch (req, res, next) {
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
module.exports = validatorsVideos
|
module.exports = validatorsVideos
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function checkVideoExists (id, res, callback) {
|
||||||
|
db.Video.loadAndPopulateAuthorAndPodAndTags(id, function (err, video) {
|
||||||
|
if (err) {
|
||||||
|
logger.error('Error in video request validator.', { error: err })
|
||||||
|
return res.sendStatus(500)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!video) return res.status(404).send('Video not found')
|
||||||
|
|
||||||
|
res.locals.video = video
|
||||||
|
callback()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -127,7 +127,8 @@ module.exports = function (sequelize, DataTypes) {
|
||||||
getTorrentName,
|
getTorrentName,
|
||||||
isOwned,
|
isOwned,
|
||||||
toFormatedJSON,
|
toFormatedJSON,
|
||||||
toRemoteJSON
|
toAddRemoteJSON,
|
||||||
|
toUpdateRemoteJSON
|
||||||
},
|
},
|
||||||
hooks: {
|
hooks: {
|
||||||
beforeValidate,
|
beforeValidate,
|
||||||
|
@ -334,7 +335,7 @@ function toFormatedJSON () {
|
||||||
return json
|
return json
|
||||||
}
|
}
|
||||||
|
|
||||||
function toRemoteJSON (callback) {
|
function toAddRemoteJSON (callback) {
|
||||||
const self = this
|
const self = this
|
||||||
|
|
||||||
// Get thumbnail data to send to the other pod
|
// Get thumbnail data to send to the other pod
|
||||||
|
@ -362,6 +363,22 @@ function toRemoteJSON (callback) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toUpdateRemoteJSON (callback) {
|
||||||
|
const json = {
|
||||||
|
name: this.name,
|
||||||
|
description: this.description,
|
||||||
|
infoHash: this.infoHash,
|
||||||
|
remoteId: this.id,
|
||||||
|
author: this.Author.name,
|
||||||
|
duration: this.duration,
|
||||||
|
tags: map(this.Tags, 'name'),
|
||||||
|
createdAt: this.createdAt,
|
||||||
|
extname: this.extname
|
||||||
|
}
|
||||||
|
|
||||||
|
return json
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------ STATICS ------------------------------
|
// ------------------------------ STATICS ------------------------------
|
||||||
|
|
||||||
function generateThumbnailFromData (video, thumbnailData, callback) {
|
function generateThumbnailFromData (video, thumbnailData, callback) {
|
||||||
|
|
|
@ -10,6 +10,7 @@ const loginUtils = require('../utils/login')
|
||||||
const requestsUtils = require('../utils/requests')
|
const requestsUtils = require('../utils/requests')
|
||||||
const serversUtils = require('../utils/servers')
|
const serversUtils = require('../utils/servers')
|
||||||
const usersUtils = require('../utils/users')
|
const usersUtils = require('../utils/users')
|
||||||
|
const videosUtils = require('../utils/videos')
|
||||||
|
|
||||||
describe('Test parameters validator', function () {
|
describe('Test parameters validator', function () {
|
||||||
let server = null
|
let server = null
|
||||||
|
@ -439,6 +440,106 @@ describe('Test parameters validator', function () {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('When updating a video', function () {
|
||||||
|
let videoId
|
||||||
|
|
||||||
|
before(function (done) {
|
||||||
|
videosUtils.getVideosList(server.url, function (err, res) {
|
||||||
|
if (err) throw err
|
||||||
|
|
||||||
|
videoId = res.body.data[0].id
|
||||||
|
|
||||||
|
return done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should fail with nothing', function (done) {
|
||||||
|
const data = {}
|
||||||
|
requestsUtils.makePutBodyRequest(server.url, path + videoId, server.accessToken, data, done)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should fail without a valid uuid', function (done) {
|
||||||
|
const data = {
|
||||||
|
description: 'my super description',
|
||||||
|
tags: [ 'tag1', 'tag2' ]
|
||||||
|
}
|
||||||
|
requestsUtils.makePutBodyRequest(server.url, path + 'blabla', server.accessToken, data, done)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should fail with an unknown id', function (done) {
|
||||||
|
const data = {
|
||||||
|
description: 'my super description',
|
||||||
|
tags: [ 'tag1', 'tag2' ]
|
||||||
|
}
|
||||||
|
requestsUtils.makePutBodyRequest(server.url, path + '4da6fde3-88f7-4d16-b119-108df5630b06', server.accessToken, data, done)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should fail with a long name', function (done) {
|
||||||
|
const data = {
|
||||||
|
name: 'My very very very very very very very very very very very very very very very very long name',
|
||||||
|
description: 'my super description',
|
||||||
|
tags: [ 'tag1', 'tag2' ]
|
||||||
|
}
|
||||||
|
requestsUtils.makePutBodyRequest(server.url, path + videoId, server.accessToken, data, done)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should fail with a long description', function (done) {
|
||||||
|
const data = {
|
||||||
|
name: 'my super name',
|
||||||
|
description: 'my super description which is very very very very very very very very very very very very very very' +
|
||||||
|
'very very very very very very very very very very very very very very very very very very very very very' +
|
||||||
|
'very very very very very very very very very very very very very very very long',
|
||||||
|
tags: [ 'tag1', 'tag2' ]
|
||||||
|
}
|
||||||
|
requestsUtils.makePutBodyRequest(server.url, path + videoId, server.accessToken, data, done)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should fail with too many tags', function (done) {
|
||||||
|
const data = {
|
||||||
|
name: 'my super name',
|
||||||
|
description: 'my super description',
|
||||||
|
tags: [ 'tag1', 'tag2', 'tag3', 'tag4' ]
|
||||||
|
}
|
||||||
|
requestsUtils.makePutBodyRequest(server.url, path + videoId, server.accessToken, data, done)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should fail with not enough tags', function (done) {
|
||||||
|
const data = {
|
||||||
|
name: 'my super name',
|
||||||
|
description: 'my super description',
|
||||||
|
tags: [ ]
|
||||||
|
}
|
||||||
|
requestsUtils.makePutBodyRequest(server.url, path + videoId, server.accessToken, data, done)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should fail with a tag length too low', function (done) {
|
||||||
|
const data = {
|
||||||
|
name: 'my super name',
|
||||||
|
description: 'my super description',
|
||||||
|
tags: [ 'tag1', 't' ]
|
||||||
|
}
|
||||||
|
requestsUtils.makePutBodyRequest(server.url, path + videoId, server.accessToken, data, done)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should fail with a tag length too big', function (done) {
|
||||||
|
const data = {
|
||||||
|
name: 'my super name',
|
||||||
|
description: 'my super description',
|
||||||
|
tags: [ 'mysupertagtoolong', 'tag1' ]
|
||||||
|
}
|
||||||
|
requestsUtils.makePutBodyRequest(server.url, path + videoId, server.accessToken, data, done)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should fail with malformed tags', function (done) {
|
||||||
|
const data = {
|
||||||
|
name: 'my super name',
|
||||||
|
description: 'my super description',
|
||||||
|
tags: [ 'my tag' ]
|
||||||
|
}
|
||||||
|
requestsUtils.makePutBodyRequest(server.url, path + videoId, server.accessToken, data, done)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe('When getting a video', function () {
|
describe('When getting a video', function () {
|
||||||
it('Should return the list of the videos with nothing', function (done) {
|
it('Should return the list of the videos with nothing', function (done) {
|
||||||
request(server.url)
|
request(server.url)
|
||||||
|
|
|
@ -495,10 +495,86 @@ describe('Test a single pod', function () {
|
||||||
expect(videos[2].name === 'video_short2.webm name')
|
expect(videos[2].name === 'video_short2.webm name')
|
||||||
expect(videos[3].name === 'video_short3.webm name')
|
expect(videos[3].name === 'video_short3.webm name')
|
||||||
|
|
||||||
|
videoId = videos[3].id
|
||||||
|
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('Should update a video', function (done) {
|
||||||
|
const name = 'my super video updated'
|
||||||
|
const description = 'my super description updated'
|
||||||
|
const tags = [ 'tagup1', 'tagup2' ]
|
||||||
|
|
||||||
|
videosUtils.updateVideo(server.url, server.accessToken, videoId, name, description, tags, done)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should have the video updated', function (done) {
|
||||||
|
videosUtils.getVideo(server.url, videoId, function (err, res) {
|
||||||
|
if (err) throw err
|
||||||
|
|
||||||
|
const video = res.body
|
||||||
|
|
||||||
|
expect(video.name).to.equal('my super video updated')
|
||||||
|
expect(video.description).to.equal('my super description updated')
|
||||||
|
expect(video.podHost).to.equal('localhost:9001')
|
||||||
|
expect(video.author).to.equal('root')
|
||||||
|
expect(video.isLocal).to.be.true
|
||||||
|
expect(video.tags).to.deep.equal([ 'tagup1', 'tagup2' ])
|
||||||
|
expect(miscsUtils.dateIsValid(video.createdAt)).to.be.true
|
||||||
|
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should update only the tags of a video', function (done) {
|
||||||
|
const tags = [ 'tag1', 'tag2', 'supertag' ]
|
||||||
|
|
||||||
|
videosUtils.updateVideo(server.url, server.accessToken, videoId, null, null, tags, function (err) {
|
||||||
|
if (err) throw err
|
||||||
|
|
||||||
|
videosUtils.getVideo(server.url, videoId, function (err, res) {
|
||||||
|
if (err) throw err
|
||||||
|
|
||||||
|
const video = res.body
|
||||||
|
|
||||||
|
expect(video.name).to.equal('my super video updated')
|
||||||
|
expect(video.description).to.equal('my super description updated')
|
||||||
|
expect(video.podHost).to.equal('localhost:9001')
|
||||||
|
expect(video.author).to.equal('root')
|
||||||
|
expect(video.isLocal).to.be.true
|
||||||
|
expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'supertag' ])
|
||||||
|
expect(miscsUtils.dateIsValid(video.createdAt)).to.be.true
|
||||||
|
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should update only the description of a video', function (done) {
|
||||||
|
const description = 'hello everybody'
|
||||||
|
|
||||||
|
videosUtils.updateVideo(server.url, server.accessToken, videoId, null, description, null, function (err) {
|
||||||
|
if (err) throw err
|
||||||
|
|
||||||
|
videosUtils.getVideo(server.url, videoId, function (err, res) {
|
||||||
|
if (err) throw err
|
||||||
|
|
||||||
|
const video = res.body
|
||||||
|
|
||||||
|
expect(video.name).to.equal('my super video updated')
|
||||||
|
expect(video.description).to.equal('hello everybody')
|
||||||
|
expect(video.podHost).to.equal('localhost:9001')
|
||||||
|
expect(video.author).to.equal('root')
|
||||||
|
expect(video.isLocal).to.be.true
|
||||||
|
expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'supertag' ])
|
||||||
|
expect(miscsUtils.dateIsValid(video.createdAt)).to.be.true
|
||||||
|
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
after(function (done) {
|
after(function (done) {
|
||||||
process.kill(-server.app.pid)
|
process.kill(-server.app.pid)
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,8 @@ const videosUtils = {
|
||||||
searchVideoWithPagination,
|
searchVideoWithPagination,
|
||||||
searchVideoWithSort,
|
searchVideoWithSort,
|
||||||
testVideoImage,
|
testVideoImage,
|
||||||
uploadVideo
|
uploadVideo,
|
||||||
|
updateVideo
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------- Export functions --------------------
|
// ---------------------- Export functions --------------------
|
||||||
|
@ -194,6 +195,31 @@ function uploadVideo (url, accessToken, name, description, tags, fixture, specia
|
||||||
.end(end)
|
.end(end)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateVideo (url, accessToken, id, name, description, tags, specialStatus, end) {
|
||||||
|
if (!end) {
|
||||||
|
end = specialStatus
|
||||||
|
specialStatus = 204
|
||||||
|
}
|
||||||
|
|
||||||
|
const path = '/api/v1/videos/' + id
|
||||||
|
|
||||||
|
const req = request(url)
|
||||||
|
.put(path)
|
||||||
|
.set('Accept', 'application/json')
|
||||||
|
.set('Authorization', 'Bearer ' + accessToken)
|
||||||
|
|
||||||
|
if (name) req.field('name', name)
|
||||||
|
if (description) req.field('description', description)
|
||||||
|
|
||||||
|
if (tags) {
|
||||||
|
for (let i = 0; i < tags.length; i++) {
|
||||||
|
req.field('tags[' + i + ']', tags[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
req.expect(specialStatus).end(end)
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
module.exports = videosUtils
|
module.exports = videosUtils
|
||||||
|
|
Loading…
Reference in New Issue