Improve image test comparison
|
@ -219,7 +219,10 @@
|
||||||
"eslint-plugin-node": "^11.0.0",
|
"eslint-plugin-node": "^11.0.0",
|
||||||
"eslint-plugin-promise": "^6.0.0",
|
"eslint-plugin-promise": "^6.0.0",
|
||||||
"fast-xml-parser": "^4.0.0-beta.8",
|
"fast-xml-parser": "^4.0.0-beta.8",
|
||||||
|
"jpeg-js": "^0.4.4",
|
||||||
"mocha": "^10.0.0",
|
"mocha": "^10.0.0",
|
||||||
|
"pixelmatch": "^5.3.0",
|
||||||
|
"pngjs": "^7.0.0",
|
||||||
"proxy": "^1.0.2",
|
"proxy": "^1.0.2",
|
||||||
"resolve-tspaths": "^0.8.8",
|
"resolve-tspaths": "^0.8.8",
|
||||||
"socket.io-client": "^4.5.4",
|
"socket.io-client": "^4.5.4",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
|
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
|
||||||
|
|
||||||
import { expect } from 'chai'
|
import { expect } from 'chai'
|
||||||
import { testImage } from '@server/tests/shared'
|
import { testImageSize } from '@server/tests/shared'
|
||||||
import { AbuseState, HttpStatusCode, UserAdminFlag, UserRole, VideoPlaylistType } from '@shared/models'
|
import { AbuseState, HttpStatusCode, UserAdminFlag, UserRole, VideoPlaylistType } from '@shared/models'
|
||||||
import { cleanupTests, createSingleServer, PeerTubeServer, setAccessTokensToServers } from '@shared/server-commands'
|
import { cleanupTests, createSingleServer, PeerTubeServer, setAccessTokensToServers } from '@shared/server-commands'
|
||||||
|
|
||||||
|
@ -274,7 +274,7 @@ describe('Test users', function () {
|
||||||
|
|
||||||
const user = await server.users.getMyInfo({ token: userToken })
|
const user = await server.users.getMyInfo({ token: userToken })
|
||||||
for (const avatar of user.account.avatars) {
|
for (const avatar of user.account.avatars) {
|
||||||
await testImage(server.url, `avatar-resized-${avatar.width}x${avatar.width}`, avatar.path, '.gif')
|
await testImageSize(server.url, `avatar-resized-${avatar.width}x${avatar.width}`, avatar.path, '.gif')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -286,7 +286,7 @@ describe('Test users', function () {
|
||||||
|
|
||||||
const user = await server.users.getMyInfo({ token: userToken })
|
const user = await server.users.getMyInfo({ token: userToken })
|
||||||
for (const avatar of user.account.avatars) {
|
for (const avatar of user.account.avatars) {
|
||||||
await testImage(server.url, `avatar-resized-${avatar.width}x${avatar.width}`, avatar.path, extension)
|
await testImageSize(server.url, `avatar-resized-${avatar.width}x${avatar.width}`, avatar.path, extension)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -68,6 +68,8 @@ async function checkVideoServer2 (server: PeerTubeServer, id: number | string) {
|
||||||
expect(video.description).to.equal('my super description')
|
expect(video.description).to.equal('my super description')
|
||||||
expect(video.tags).to.deep.equal([ 'supertag1', 'supertag2' ])
|
expect(video.tags).to.deep.equal([ 'supertag1', 'supertag2' ])
|
||||||
|
|
||||||
|
await testImage(server.url, 'thumbnail', video.thumbnailPath)
|
||||||
|
|
||||||
expect(video.files).to.have.lengthOf(1)
|
expect(video.files).to.have.lengthOf(1)
|
||||||
|
|
||||||
const bodyCaptions = await server.captions.list({ videoId: id })
|
const bodyCaptions = await server.captions.list({ videoId: id })
|
||||||
|
@ -254,18 +256,20 @@ describe('Test video imports', function () {
|
||||||
it('Should import a video on server 2 with some fields', async function () {
|
it('Should import a video on server 2 with some fields', async function () {
|
||||||
this.timeout(60_000)
|
this.timeout(60_000)
|
||||||
|
|
||||||
const attributes = {
|
const { video } = await servers[1].imports.importVideo({
|
||||||
targetUrl: FIXTURE_URLS.youtube,
|
attributes: {
|
||||||
channelId: servers[1].store.channel.id,
|
targetUrl: FIXTURE_URLS.youtube,
|
||||||
privacy: VideoPrivacy.PUBLIC,
|
channelId: servers[1].store.channel.id,
|
||||||
category: 10,
|
privacy: VideoPrivacy.PUBLIC,
|
||||||
licence: 7,
|
category: 10,
|
||||||
language: 'en',
|
licence: 7,
|
||||||
name: 'my super name',
|
language: 'en',
|
||||||
description: 'my super description',
|
name: 'my super name',
|
||||||
tags: [ 'supertag1', 'supertag2' ]
|
description: 'my super description',
|
||||||
}
|
tags: [ 'supertag1', 'supertag2' ],
|
||||||
const { video } = await servers[1].imports.importVideo({ attributes })
|
thumbnailfile: 'thumbnail.jpg'
|
||||||
|
}
|
||||||
|
})
|
||||||
expect(video.name).to.equal('my super name')
|
expect(video.name).to.equal('my super name')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
BIN
server/tests/fixtures/thumbnail-playlist.jpg
vendored
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
BIN
server/tests/fixtures/thumbnail.jpg
vendored
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 10 KiB |
BIN
server/tests/fixtures/video_short.mp4.jpg
vendored
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
BIN
server/tests/fixtures/video_short.ogv.jpg
vendored
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
BIN
server/tests/fixtures/video_short.webm.jpg
vendored
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
BIN
server/tests/fixtures/video_short1-preview.webm.jpg
vendored
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
BIN
server/tests/fixtures/video_short1.webm.jpg
vendored
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.1 KiB |
BIN
server/tests/fixtures/video_short2.webm.jpg
vendored
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
BIN
server/tests/fixtures/video_short3.webm.jpg
vendored
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 5.5 KiB |
|
@ -32,7 +32,7 @@ describe('Image helpers', function () {
|
||||||
const imageDestJPG = join(imageDestDir, 'test.jpg')
|
const imageDestJPG = join(imageDestDir, 'test.jpg')
|
||||||
const imageDestPNG = join(imageDestDir, 'test.png')
|
const imageDestPNG = join(imageDestDir, 'test.png')
|
||||||
|
|
||||||
const thumbnailSize = { width: 223, height: 122 }
|
const thumbnailSize = { width: 280, height: 157 }
|
||||||
|
|
||||||
it('Should skip processing if the source image is okay', async function () {
|
it('Should skip processing if the source image is okay', async function () {
|
||||||
const input = buildAbsoluteFixturePath('thumbnail.jpg')
|
const input = buildAbsoluteFixturePath('thumbnail.jpg')
|
||||||
|
|
|
@ -2,7 +2,10 @@
|
||||||
|
|
||||||
import { expect } from 'chai'
|
import { expect } from 'chai'
|
||||||
import { pathExists, readFile } from 'fs-extra'
|
import { pathExists, readFile } from 'fs-extra'
|
||||||
|
import JPEG from 'jpeg-js'
|
||||||
import { join } from 'path'
|
import { join } from 'path'
|
||||||
|
import pixelmatch from 'pixelmatch'
|
||||||
|
import { PNG } from 'pngjs'
|
||||||
import { root } from '@shared/core-utils'
|
import { root } from '@shared/core-utils'
|
||||||
import { HttpStatusCode } from '@shared/models'
|
import { HttpStatusCode } from '@shared/models'
|
||||||
import { makeGetRequest, PeerTubeServer } from '@shared/server-commands'
|
import { makeGetRequest, PeerTubeServer } from '@shared/server-commands'
|
||||||
|
@ -41,7 +44,7 @@ async function expectLogContain (server: PeerTubeServer, str: string) {
|
||||||
expect(content.toString()).to.contain(str)
|
expect(content.toString()).to.contain(str)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function testImage (url: string, imageName: string, imageHTTPPath: string, extension = '.jpg') {
|
async function testImageSize (url: string, imageName: string, imageHTTPPath: string, extension = '.jpg') {
|
||||||
const res = await makeGetRequest({
|
const res = await makeGetRequest({
|
||||||
url,
|
url,
|
||||||
path: imageHTTPPath,
|
path: imageHTTPPath,
|
||||||
|
@ -58,6 +61,29 @@ async function testImage (url: string, imageName: string, imageHTTPPath: string,
|
||||||
expect(body.length).to.be.below(maxLength, 'the generated image is way larger than the recorded fixture')
|
expect(body.length).to.be.below(maxLength, 'the generated image is way larger than the recorded fixture')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function testImage (url: string, imageName: string, imageHTTPPath: string, extension = '.jpg') {
|
||||||
|
const res = await makeGetRequest({
|
||||||
|
url,
|
||||||
|
path: imageHTTPPath,
|
||||||
|
expectedStatus: HttpStatusCode.OK_200
|
||||||
|
})
|
||||||
|
|
||||||
|
const body = res.body
|
||||||
|
const data = await readFile(join(root(), 'server', 'tests', 'fixtures', imageName + extension))
|
||||||
|
|
||||||
|
const img1 = imageHTTPPath.endsWith('.png')
|
||||||
|
? PNG.sync.read(body)
|
||||||
|
: JPEG.decode(body)
|
||||||
|
|
||||||
|
const img2 = extension === '.png'
|
||||||
|
? PNG.sync.read(data)
|
||||||
|
: JPEG.decode(data)
|
||||||
|
|
||||||
|
const result = pixelmatch(img1.data, img2.data, null, img1.width, img1.height, { threshold: 0.1 })
|
||||||
|
|
||||||
|
expect(result).to.equal(0, `${imageHTTPPath} image is not the same as ${imageName}${extension}`)
|
||||||
|
}
|
||||||
|
|
||||||
async function testFileExistsOrNot (server: PeerTubeServer, directory: string, filePath: string, exist: boolean) {
|
async function testFileExistsOrNot (server: PeerTubeServer, directory: string, filePath: string, exist: boolean) {
|
||||||
const base = server.servers.buildDirectory(directory)
|
const base = server.servers.buildDirectory(directory)
|
||||||
|
|
||||||
|
@ -104,6 +130,7 @@ function checkBadSortPagination (url: string, path: string, token?: string, quer
|
||||||
|
|
||||||
export {
|
export {
|
||||||
dateIsValid,
|
dateIsValid,
|
||||||
|
testImageSize,
|
||||||
testImage,
|
testImage,
|
||||||
expectLogDoesNotContain,
|
expectLogDoesNotContain,
|
||||||
testFileExistsOrNot,
|
testFileExistsOrNot,
|
||||||
|
|
|
@ -7,13 +7,15 @@ import { AbstractCommand, OverrideCommandOptions } from '../shared'
|
||||||
export class ImportsCommand extends AbstractCommand {
|
export class ImportsCommand extends AbstractCommand {
|
||||||
|
|
||||||
importVideo (options: OverrideCommandOptions & {
|
importVideo (options: OverrideCommandOptions & {
|
||||||
attributes: VideoImportCreate & { torrentfile?: string }
|
attributes: (VideoImportCreate | { torrentfile?: string, previewfile?: string, thumbnailfile?: string })
|
||||||
}) {
|
}) {
|
||||||
const { attributes } = options
|
const { attributes } = options
|
||||||
const path = '/api/v1/videos/imports'
|
const path = '/api/v1/videos/imports'
|
||||||
|
|
||||||
let attaches: any = {}
|
let attaches: any = {}
|
||||||
if (attributes.torrentfile) attaches = { torrentfile: attributes.torrentfile }
|
if (attributes.torrentfile) attaches = { torrentfile: attributes.torrentfile }
|
||||||
|
if (attributes.thumbnailfile) attaches = { thumbnailfile: attributes.thumbnailfile }
|
||||||
|
if (attributes.previewfile) attaches = { previewfile: attributes.previewfile }
|
||||||
|
|
||||||
return unwrapBody<VideoImport>(this.postUploadRequest({
|
return unwrapBody<VideoImport>(this.postUploadRequest({
|
||||||
...options,
|
...options,
|
||||||
|
|
12
yarn.lock
|
@ -7592,6 +7592,13 @@ pixelmatch@^4.0.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
pngjs "^3.0.0"
|
pngjs "^3.0.0"
|
||||||
|
|
||||||
|
pixelmatch@^5.3.0:
|
||||||
|
version "5.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/pixelmatch/-/pixelmatch-5.3.0.tgz#5e5321a7abedfb7962d60dbf345deda87cb9560a"
|
||||||
|
integrity sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q==
|
||||||
|
dependencies:
|
||||||
|
pngjs "^6.0.0"
|
||||||
|
|
||||||
please-upgrade-node@^3.2.0:
|
please-upgrade-node@^3.2.0:
|
||||||
version "3.2.0"
|
version "3.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942"
|
resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942"
|
||||||
|
@ -7609,6 +7616,11 @@ pngjs@^6.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-6.0.0.tgz#ca9e5d2aa48db0228a52c419c3308e87720da821"
|
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-6.0.0.tgz#ca9e5d2aa48db0228a52c419c3308e87720da821"
|
||||||
integrity sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==
|
integrity sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==
|
||||||
|
|
||||||
|
pngjs@^7.0.0:
|
||||||
|
version "7.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-7.0.0.tgz#a8b7446020ebbc6ac739db6c5415a65d17090e26"
|
||||||
|
integrity sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==
|
||||||
|
|
||||||
postcss@^8.1.10, postcss@^8.3.11:
|
postcss@^8.1.10, postcss@^8.3.11:
|
||||||
version "8.4.21"
|
version "8.4.21"
|
||||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.21.tgz#c639b719a57efc3187b13a1d765675485f4134f4"
|
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.21.tgz#c639b719a57efc3187b13a1d765675485f4134f4"
|
||||||
|
|