2020-03-25 15:19:38 +03:00
|
|
|
// Switch these lines once there are useful utils
|
|
|
|
const testUtils = require('./utils');
|
2018-11-12 20:52:36 +03:00
|
|
|
const fs = require('fs-extra');
|
2020-03-25 13:25:25 +03:00
|
|
|
const errors = require('@tryghost/errors');
|
2018-08-30 19:30:36 +03:00
|
|
|
|
2020-03-25 15:19:38 +03:00
|
|
|
const transform = require('../');
|
|
|
|
|
|
|
|
describe('Transform', function () {
|
2018-08-30 19:30:36 +03:00
|
|
|
afterEach(function () {
|
2019-01-21 19:53:44 +03:00
|
|
|
sinon.restore();
|
2020-03-25 15:19:38 +03:00
|
|
|
testUtils.modules.unmockNonExistentModule();
|
2018-08-30 19:30:36 +03:00
|
|
|
});
|
|
|
|
|
2020-07-02 20:00:12 +03:00
|
|
|
describe('canTransformFiles', function () {
|
|
|
|
it('returns true when sharp is available', function () {
|
|
|
|
transform.canTransformFiles().should.be.true;
|
|
|
|
});
|
|
|
|
|
|
|
|
it('returns false when sharp is not available', function () {
|
|
|
|
testUtils.modules.mockNonExistentModule('sharp', new Error(), true);
|
|
|
|
transform.canTransformFiles().should.be.false;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2019-01-03 12:28:37 +03:00
|
|
|
describe('canTransformFileExtension', function () {
|
2022-05-27 17:06:46 +03:00
|
|
|
it('returns true for ".gif"', function () {
|
2019-01-03 12:28:37 +03:00
|
|
|
should.equal(
|
2020-03-25 15:19:38 +03:00
|
|
|
transform.canTransformFileExtension('.gif'),
|
2022-05-27 17:06:46 +03:00
|
|
|
true
|
|
|
|
);
|
|
|
|
});
|
|
|
|
it('returns true for ".svg"', function () {
|
|
|
|
should.equal(
|
|
|
|
transform.canTransformFileExtension('.svg'),
|
|
|
|
true
|
|
|
|
);
|
|
|
|
});
|
|
|
|
it('returns true for ".svgz"', function () {
|
|
|
|
should.equal(
|
|
|
|
transform.canTransformFileExtension('.svgz'),
|
|
|
|
true
|
|
|
|
);
|
|
|
|
});
|
|
|
|
it('returns false for ".ico"', function () {
|
|
|
|
should.equal(
|
|
|
|
transform.canTransformFileExtension('.ico'),
|
2019-01-03 12:28:37 +03:00
|
|
|
false
|
|
|
|
);
|
|
|
|
});
|
2022-05-27 17:06:46 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
describe('shouldResizeFileExtension', function () {
|
|
|
|
it('returns true for ".gif"', function () {
|
|
|
|
should.equal(
|
|
|
|
transform.shouldResizeFileExtension('.gif'),
|
|
|
|
true
|
|
|
|
);
|
|
|
|
});
|
2019-01-03 12:28:37 +03:00
|
|
|
it('returns false for ".svg"', function () {
|
|
|
|
should.equal(
|
2022-05-27 17:06:46 +03:00
|
|
|
transform.shouldResizeFileExtension('.svg'),
|
2019-01-03 12:28:37 +03:00
|
|
|
false
|
|
|
|
);
|
|
|
|
});
|
|
|
|
it('returns false for ".svgz"', function () {
|
|
|
|
should.equal(
|
2022-05-27 17:06:46 +03:00
|
|
|
transform.shouldResizeFileExtension('.svgz'),
|
2019-01-03 12:28:37 +03:00
|
|
|
false
|
|
|
|
);
|
|
|
|
});
|
2019-01-15 20:40:09 +03:00
|
|
|
it('returns false for ".ico"', function () {
|
|
|
|
should.equal(
|
2022-05-27 17:06:46 +03:00
|
|
|
transform.shouldResizeFileExtension('.ico'),
|
2019-01-15 20:40:09 +03:00
|
|
|
false
|
|
|
|
);
|
|
|
|
});
|
2019-01-03 12:28:37 +03:00
|
|
|
});
|
|
|
|
|
2018-08-30 19:30:36 +03:00
|
|
|
describe('cases', function () {
|
|
|
|
let sharp, sharpInstance;
|
|
|
|
|
|
|
|
beforeEach(function () {
|
2019-01-21 19:53:44 +03:00
|
|
|
sinon.stub(fs, 'readFile').resolves('original');
|
|
|
|
sinon.stub(fs, 'writeFile').resolves();
|
2018-11-12 20:52:36 +03:00
|
|
|
|
2018-08-30 19:30:36 +03:00
|
|
|
sharpInstance = {
|
2019-01-21 19:53:44 +03:00
|
|
|
resize: sinon.stub().returnsThis(),
|
|
|
|
rotate: sinon.stub().returnsThis(),
|
2019-07-05 14:40:43 +03:00
|
|
|
toBuffer: sinon.stub()
|
2018-08-30 19:30:36 +03:00
|
|
|
};
|
|
|
|
|
2019-01-21 19:53:44 +03:00
|
|
|
sharp = sinon.stub().callsFake(() => {
|
2018-08-30 19:30:36 +03:00
|
|
|
return sharpInstance;
|
|
|
|
});
|
|
|
|
|
2021-11-05 14:39:24 +03:00
|
|
|
sharp.cache = sinon.stub().returns({});
|
|
|
|
|
2020-03-25 15:19:38 +03:00
|
|
|
testUtils.modules.mockNonExistentModule('sharp', sharp);
|
2018-08-30 19:30:36 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
it('resize image', function () {
|
2018-12-14 07:54:52 +03:00
|
|
|
sharpInstance.toBuffer.resolves('manipulated');
|
2018-08-30 19:30:36 +03:00
|
|
|
|
2020-03-25 15:53:33 +03:00
|
|
|
return transform.resizeFromPath({width: 1000})
|
2018-08-30 19:30:36 +03:00
|
|
|
.then(() => {
|
|
|
|
sharpInstance.resize.calledOnce.should.be.true();
|
|
|
|
sharpInstance.rotate.calledOnce.should.be.true();
|
2018-11-12 20:52:36 +03:00
|
|
|
|
|
|
|
fs.writeFile.calledOnce.should.be.true();
|
|
|
|
fs.writeFile.calledWith('manipulated');
|
2018-08-30 19:30:36 +03:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('skip resizing if image is too small', function () {
|
2018-12-14 07:54:52 +03:00
|
|
|
sharpInstance.toBuffer.resolves('manipulated');
|
2018-08-30 19:30:36 +03:00
|
|
|
|
2020-03-25 15:53:33 +03:00
|
|
|
return transform.resizeFromPath({width: 1000})
|
2018-08-30 19:30:36 +03:00
|
|
|
.then(() => {
|
2018-12-14 07:54:52 +03:00
|
|
|
sharpInstance.resize.calledOnce.should.be.true();
|
|
|
|
should.deepEqual(sharpInstance.resize.args[0][2], {
|
|
|
|
withoutEnlargement: true
|
|
|
|
});
|
2018-11-12 20:52:36 +03:00
|
|
|
|
|
|
|
fs.writeFile.calledOnce.should.be.true();
|
|
|
|
fs.writeFile.calledWith('manipulated');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('uses original image as an output when the size (bytes) is bigger after manipulation', function () {
|
2018-12-14 07:54:52 +03:00
|
|
|
sharpInstance.toBuffer.resolves('manipulated to a very very very very very very very large size');
|
2018-11-12 20:52:36 +03:00
|
|
|
|
2020-03-25 15:53:33 +03:00
|
|
|
return transform.resizeFromPath({width: 1000})
|
2018-11-12 20:52:36 +03:00
|
|
|
.then(() => {
|
|
|
|
sharpInstance.resize.calledOnce.should.be.true();
|
|
|
|
sharpInstance.rotate.calledOnce.should.be.true();
|
|
|
|
sharpInstance.toBuffer.calledOnce.should.be.true();
|
|
|
|
|
|
|
|
fs.writeFile.calledOnce.should.be.true();
|
|
|
|
fs.writeFile.calledWith('original');
|
2018-08-30 19:30:36 +03:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('sharp throws error during processing', function () {
|
2018-12-14 07:54:52 +03:00
|
|
|
sharpInstance.toBuffer.resolves('manipulated');
|
2018-11-12 20:52:36 +03:00
|
|
|
|
|
|
|
fs.writeFile.rejects(new Error('whoops'));
|
2018-08-30 19:30:36 +03:00
|
|
|
|
2020-03-25 15:53:33 +03:00
|
|
|
return transform.resizeFromPath({width: 2000})
|
2018-08-30 19:30:36 +03:00
|
|
|
.then(() => {
|
|
|
|
'1'.should.eql(1, 'Expected to fail');
|
|
|
|
})
|
|
|
|
.catch((err) => {
|
2020-03-25 13:25:25 +03:00
|
|
|
(err instanceof errors.InternalServerError).should.be.true;
|
2018-08-30 19:30:36 +03:00
|
|
|
err.code.should.eql('IMAGE_PROCESSING');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('installation', function () {
|
|
|
|
beforeEach(function () {
|
2020-03-25 15:19:38 +03:00
|
|
|
testUtils.modules.mockNonExistentModule('sharp', new Error(), true);
|
2018-08-30 19:30:36 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
it('sharp was not installed', function () {
|
2020-03-25 15:53:33 +03:00
|
|
|
return transform.resizeFromPath()
|
2018-08-30 19:30:36 +03:00
|
|
|
.then(() => {
|
|
|
|
'1'.should.eql(1, 'Expected to fail');
|
|
|
|
})
|
|
|
|
.catch((err) => {
|
2020-03-25 13:25:25 +03:00
|
|
|
(err instanceof errors.InternalServerError).should.be.true();
|
2018-08-30 19:30:36 +03:00
|
|
|
err.code.should.eql('SHARP_INSTALLATION');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2020-03-25 23:49:55 +03:00
|
|
|
|
|
|
|
describe('generateOriginalImageName', function () {
|
|
|
|
it('correctly adds suffix', function () {
|
|
|
|
transform.generateOriginalImageName('test.jpg').should.eql('test_o.jpg');
|
|
|
|
transform.generateOriginalImageName('content/images/test.jpg').should.eql('content/images/test_o.jpg');
|
|
|
|
transform.generateOriginalImageName('content/images/test_o.jpg').should.eql('content/images/test_o_o.jpg');
|
|
|
|
transform.generateOriginalImageName('content/images/test-1.jpg').should.eql('content/images/test-1_o.jpg');
|
|
|
|
});
|
|
|
|
});
|
2018-08-30 19:30:36 +03:00
|
|
|
});
|