remote: false,
category: body.category || youtubeDLInfo.category,
licence: body.licence || youtubeDLInfo.licence,
- language: undefined,
+ language: body.language || undefined,
commentsEnabled: body.commentsEnabled || true,
waitTranscoding: body.waitTranscoding || false,
state: VideoState.TO_IMPORT,
videoCreated.VideoChannel = res.locals.videoChannel
// Set tags to the video
- if (youtubeDLInfo.tags !== undefined) {
- const tagInstances = await TagModel.findOrCreateTags(youtubeDLInfo.tags, t)
+ const tags = body.tags ? body.tags : youtubeDLInfo.tags
+ if (tags !== undefined) {
+ const tagInstances = await TagModel.findOrCreateTags(tags, t)
await videoCreated.$set('Tags', tagInstances, sequelizeOptions)
videoCreated.Tags = tagInstances
auditLogger.create(res.locals.oauth.token.User.Account.Actor.getIdentifier(), new VideoImportAuditView(videoImport.toFormattedJSON()))
- return res.json(videoImport.toFormattedJSON())
+ return res.json(videoImport.toFormattedJSON()).end()
}
function getLicence (licence: string) {
if (!licence) return undefined
- if (licence.indexOf('Creative Commons Attribution licence') !== -1) return 1
+ if (licence.indexOf('Creative Commons Attribution') !== -1) return 1
return undefined
}
video.state = CONFIG.TRANSCODING.ENABLED ? VideoState.TO_TRANSCODE : VideoState.PUBLISHED
const videoUpdated = await video.save({ transaction: t })
- // Now we can federate the video
- await federateVideoIfNeeded(video, true, t)
+ // Now we can federate the video (reload from database, we need more attributes)
+ const videoForFederation = await VideoModel.loadByUUIDAndPopulateAccountAndServerAndTags(video.uuid, t)
+ await federateVideoIfNeeded(videoForFederation, true, t)
// Update video import object
videoImport.state = VideoImportState.SUCCESS
]
},
{
- model: () => TagModel,
- required: false
+ model: () => TagModel
}
]
}
static listUserVideoImportsForApi (accountId: number, start: number, count: number, sort: string) {
const query = {
+ distinct: true,
offset: start,
limit: count,
order: getSort(sort),
runServer,
ServerInfo,
setAccessTokensToServers,
+ updateCustomSubConfig,
userLogin
} from '../../utils'
import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params'
+import { getYoutubeVideoUrl } from '../../utils/videos/video-imports'
describe('Test video imports API validator', function () {
const path = '/api/v1/videos/imports'
before(function () {
baseCorrectParams = {
- targetUrl: 'https://youtu.be/msX3jv1XdvM',
+ targetUrl: getYoutubeVideoUrl(),
name: 'my super name',
category: 5,
licence: 1,
await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
})
+ it('Should fail without a target url', async function () {
+ const fields = omit(baseCorrectParams, 'targetUrl')
+ await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 400 })
+ })
+
+ it('Should fail with a bad target url', async function () {
+ const fields = immutableAssign(baseCorrectParams, { targetUrl: 'htt://hello' })
+
+ await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
+ })
+
it('Should fail with a long name', async function () {
const fields = immutableAssign(baseCorrectParams, { name: 'super'.repeat(65) })
it('Should succeed with the correct parameters', async function () {
this.timeout(10000)
- const fields = baseCorrectParams
-
{
await makePostBodyRequest({
url: server.url,
path,
token: server.accessToken,
- fields,
+ fields: baseCorrectParams,
statusCodeExpected: 200
})
}
})
- it('Should forbid importing')
+ it('Should forbid to import videos', async function () {
+ await updateCustomSubConfig(server.url, server.accessToken, {
+ import: {
+ videos: {
+ http: {
+ enabled: false
+ }
+ }
+ }
+ })
+
+ await makePostBodyRequest({
+ url: server.url,
+ path,
+ token: server.accessToken,
+ fields: baseCorrectParams,
+ statusCodeExpected: 409
+ })
+ })
})
after(async function () {
// Order of the tests we want to execute
+import './videos/video-channels'
import './videos/video-transcoder'
import './videos/multiple-servers'
import './server/follows'
import './users/users-multiple-servers'
import './server/handle-down'
import './videos/video-schedule-update'
+import './videos/video-imports'
--- /dev/null
+/* tslint:disable:no-unused-expression */
+
+import * as chai from 'chai'
+import 'mocha'
+import { VideoDetails, VideoPrivacy } from '../../../../shared/models/videos'
+import {
+ doubleFollow,
+ flushAndRunMultipleServers,
+ getMyUserInformation,
+ getMyVideos,
+ getVideo,
+ getVideosList,
+ killallServers,
+ ServerInfo,
+ setAccessTokensToServers
+} from '../../utils'
+import { waitJobs } from '../../utils/server/jobs'
+import { getMyVideoImports, getYoutubeVideoUrl, importVideo } from '../../utils/videos/video-imports'
+
+const expect = chai.expect
+
+describe('Test video imports', function () {
+ let servers: ServerInfo[] = []
+ let channelIdServer1: number
+ let channelIdServer2: number
+
+ async function checkVideoServer1 (url: string, id: number | string) {
+ const res = await getVideo(url, id)
+ const video: VideoDetails = res.body
+
+ expect(video.name).to.equal('small video - youtube')
+ expect(video.category.label).to.equal('News')
+ expect(video.licence.label).to.equal('Attribution')
+ expect(video.language.label).to.equal('Unknown')
+ expect(video.nsfw).to.be.false
+ expect(video.description).to.equal('this is a super description')
+ expect(video.tags).to.deep.equal([ 'tag1', 'tag2' ])
+
+ expect(video.files).to.have.lengthOf(1)
+ }
+
+ async function checkVideoServer2 (url: string, id: number | string) {
+ const res = await getVideo(url, id)
+ const video = res.body
+
+ expect(video.name).to.equal('my super name')
+ expect(video.category.label).to.equal('Entertainment')
+ expect(video.licence.label).to.equal('Public Domain Dedication')
+ expect(video.language.label).to.equal('English')
+ expect(video.nsfw).to.be.false
+ expect(video.description).to.equal('my super description')
+ expect(video.tags).to.deep.equal([ 'supertag1', 'supertag2' ])
+
+ expect(video.files).to.have.lengthOf(1)
+ }
+
+ before(async function () {
+ this.timeout(30000)
+
+ // Run servers
+ servers = await flushAndRunMultipleServers(2)
+
+ await setAccessTokensToServers(servers)
+
+ {
+ const res = await getMyUserInformation(servers[0].url, servers[0].accessToken)
+ channelIdServer1 = res.body.videoChannels[ 0 ].id
+ }
+
+ {
+ const res = await getMyUserInformation(servers[1].url, servers[1].accessToken)
+ channelIdServer2 = res.body.videoChannels[ 0 ].id
+ }
+
+ await doubleFollow(servers[0], servers[1])
+ })
+
+ it('Should import a video on server 1', async function () {
+ this.timeout(60000)
+
+ const attributes = {
+ targetUrl: getYoutubeVideoUrl(),
+ channelId: channelIdServer1,
+ privacy: VideoPrivacy.PUBLIC
+ }
+ const res = await importVideo(servers[0].url, servers[0].accessToken, attributes)
+ expect(res.body.video.name).to.equal('small video - youtube')
+ })
+
+ it('Should list the video to import in my videos on server 1', async function () {
+ const res = await getMyVideos(servers[0].url, servers[0].accessToken, 0, 5)
+
+ expect(res.body.total).to.equal(1)
+
+ const videos = res.body.data
+ expect(videos).to.have.lengthOf(1)
+ expect(videos[0].name).to.equal('small video - youtube')
+ })
+
+ it('Should list the video to import in my imports on server 1', async function () {
+ const res = await getMyVideoImports(servers[0].url, servers[0].accessToken)
+
+ expect(res.body.total).to.equal(1)
+ const videoImports = res.body.data
+ expect(videoImports).to.have.lengthOf(1)
+
+ expect(videoImports[0].targetUrl).to.equal(getYoutubeVideoUrl())
+ expect(videoImports[0].video.name).to.equal('small video - youtube')
+ })
+
+ it('Should have the video listed on the two instances1', async function () {
+ this.timeout(120000)
+
+ await waitJobs(servers)
+
+ for (const server of servers) {
+ const res = await getVideosList(server.url)
+ expect(res.body.total).to.equal(1)
+ expect(res.body.data).to.have.lengthOf(1)
+
+ await checkVideoServer1(server.url, res.body.data[0].uuid)
+ }
+ })
+
+ it('Should import a video on server 2 with some fields', async function () {
+ this.timeout(60000)
+
+ const attributes = {
+ targetUrl: getYoutubeVideoUrl(),
+ channelId: channelIdServer1,
+ privacy: VideoPrivacy.PUBLIC,
+ category: 10,
+ licence: 7,
+ language: 'en',
+ name: 'my super name',
+ description: 'my super description',
+ tags: [ 'supertag1', 'supertag2' ]
+ }
+ const res = await importVideo(servers[1].url, servers[1].accessToken, attributes)
+ expect(res.body.video.name).to.equal('my super name')
+ })
+
+ it('Should have the video listed on the two instances', async function () {
+ this.timeout(120000)
+
+ await waitJobs(servers)
+
+ for (const server of servers) {
+ const res = await getVideosList(server.url)
+ expect(res.body.total).to.equal(2)
+ expect(res.body.data).to.have.lengthOf(2)
+
+ await checkVideoServer2(server.url, res.body.data[0].uuid)
+ await checkVideoServer1(server.url, res.body.data[1].uuid)
+ }
+ })
+
+ after(async function () {
+ killallServers(servers)
+ })
+})
import 'mocha'
import * as chai from 'chai'
import * as request from 'supertest'
-const expect = chai.expect
-
import {
- ServerInfo,
flushTests,
+ getCustomConfig,
+ getVideosList,
+ killallServers,
+ makeHTMLRequest,
runServer,
+ ServerInfo,
serverLogin,
- uploadVideo,
- getVideosList, updateCustomConfig, getCustomConfig, killallServers, makeHTMLRequest
+ updateCustomConfig,
+ updateCustomSubConfig,
+ uploadVideo
} from './utils'
-import { CustomConfig } from '../../shared/models/server/custom-config.model'
+
+const expect = chai.expect
function checkIndexTags (html: string, title: string, description: string, css: string) {
expect(html).to.contain('<title>' + title + '</title>')
})
it('Should update the customized configuration and have the correct index html tags', async function () {
- const newCustomConfig: CustomConfig = {
+ await updateCustomSubConfig(server.url, server.accessToken, {
instance: {
- name: 'PeerTube updated',
- shortDescription: 'my short description',
- description: 'my super description',
- terms: 'my super terms',
- defaultClientRoute: '/videos/recently-added',
- defaultNSFWPolicy: 'blur' as 'blur',
customizations: {
javascript: 'alert("coucou")',
css: 'body { background-color: red; }'
}
- },
- services: {
- twitter: {
- username: '@Kuja',
- whitelisted: true
- }
- },
- cache: {
- previews: {
- size: 2
- },
- captions: {
- size: 3
- }
- },
- signup: {
- enabled: false,
- limit: 5
- },
- admin: {
- email: 'superadmin1@example.com'
- },
- user: {
- videoQuota: 5242881
- },
- transcoding: {
- enabled: true,
- threads: 1,
- resolutions: {
- '240p': false,
- '360p': true,
- '480p': true,
- '720p': false,
- '1080p': false
- }
- },
- import: {
- videos: {
- http: {
- enabled: false
- }
- }
}
- }
- await updateCustomConfig(server.url, server.accessToken, newCustomConfig)
+ })
const res = await makeHTMLRequest(server.url, '/videos/trending')
})
}
+function updateCustomSubConfig (url: string, token: string, newConfig: any) {
+ const updateParams: CustomConfig = {
+ instance: {
+ name: 'PeerTube updated',
+ shortDescription: 'my short description',
+ description: 'my super description',
+ terms: 'my super terms',
+ defaultClientRoute: '/videos/recently-added',
+ defaultNSFWPolicy: 'blur',
+ customizations: {
+ javascript: 'alert("coucou")',
+ css: 'body { background-color: red; }'
+ }
+ },
+ services: {
+ twitter: {
+ username: '@MySuperUsername',
+ whitelisted: true
+ }
+ },
+ cache: {
+ previews: {
+ size: 2
+ },
+ captions: {
+ size: 3
+ }
+ },
+ signup: {
+ enabled: false,
+ limit: 5
+ },
+ admin: {
+ email: 'superadmin1@example.com'
+ },
+ user: {
+ videoQuota: 5242881
+ },
+ transcoding: {
+ enabled: true,
+ threads: 1,
+ resolutions: {
+ '240p': false,
+ '360p': true,
+ '480p': true,
+ '720p': false,
+ '1080p': false
+ }
+ },
+ import: {
+ videos: {
+ http: {
+ enabled: false
+ }
+ }
+ }
+ }
+
+ Object.assign(updateParams, newConfig)
+
+ return updateCustomConfig(url, token, updateParams)
+}
+
function deleteCustomConfig (url: string, token: string, statusCodeExpected = 200) {
const path = '/api/v1/config/custom'
getCustomConfig,
updateCustomConfig,
getAbout,
- deleteCustomConfig
+ deleteCustomConfig,
+ updateCustomSubConfig
}
--- /dev/null
+import { VideoImportCreate } from '../../../../shared/models/videos'
+import { makeGetRequest, makePostBodyRequest } from '..'
+
+function getYoutubeVideoUrl () {
+ return 'https://youtu.be/msX3jv1XdvM'
+}
+
+function importVideo (url: string, token: string, attributes: VideoImportCreate) {
+ const path = '/api/v1/videos/imports'
+
+ return makePostBodyRequest({
+ url,
+ path,
+ token,
+ fields: attributes,
+ statusCodeExpected: 200
+ })
+}
+
+function getMyVideoImports (url: string, token: string) {
+ const path = '/api/v1/users/me/videos/imports'
+
+ return makeGetRequest({
+ url,
+ path,
+ token,
+ statusCodeExpected: 200
+ })
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ getYoutubeVideoUrl,
+ importVideo,
+ getMyVideoImports
+}
export * from './video-state.enum'
export * from './video-caption-update.model'
export * from './video-import-create.model'
-export * from './video-import-update.model'
export * from './video-import-state.enum'
export * from './video-import.model'
export { VideoConstant } from './video-constant.model'
+++ /dev/null
-import { VideoUpdate } from './video-update.model'
-
-export interface VideoImportUpdate extends VideoUpdate {
- targetUrl: string
-}