const should = require('should'); const rewire = require('rewire'); const nock = require('nock'); const urlUtils = require('../../../utils/urlUtils'); const ampContentHelper = rewire('../../../../core/frontend/apps/amp/lib/helpers/amp_content'); // TODO: Amperize really needs to get stubbed, so we can test returning errors // properly and make this test faster! describe('{{amp_content}} helper', function () { afterEach(function () { ampContentHelper.__set__('amperizeCache', {}); }); it('can render content', function (done) { const testData = { html: 'Hello World', updated_at: 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)', id: 1 }; const ampResult = ampContentHelper.call(testData); ampResult.then(function (rendered) { should.exist(rendered); rendered.string.should.equal(testData.html); done(); }).catch(done); }); it('returns if no html is provided', function (done) { const testData = { updated_at: 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)', id: 1 }; const ampResult = ampContentHelper.call(testData); ampResult.then(function (rendered) { should.exist(rendered); rendered.string.should.be.equal(''); done(); }).catch(done); }); describe('Cache', function () { it('can render content from cache', function (done) { const testData = { html: 'Hello World', updated_at: 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)', id: 1 }; let ampCachedResult; const ampResult = ampContentHelper.call(testData); const amperizeCache = ampContentHelper.__get__('amperizeCache'); ampResult.then(function (rendered) { should.exist(rendered); should.exist(amperizeCache); rendered.string.should.equal(testData.html); amperizeCache[1].should.have.property('updated_at', 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)'); amperizeCache[1].should.have.property('amp', testData.html); // call it again, to make it fetch from cache ampCachedResult = ampContentHelper.call(testData); ampCachedResult.then(function (cachedResult) { should.exist(cachedResult); should.exist(amperizeCache); amperizeCache[1].should.have.property('updated_at', 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)'); amperizeCache[1].should.have.property('amp', testData.html); done(); }); }).catch(done); }); it('fetches new AMP HTML if post was changed', function (done) { const testData1 = { html: 'Hello World', updated_at: 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)', id: 1 }; const testData2 = { html: 'Hello Ghost', updated_at: 'Wed Jul 30 2016 18:17:22 GMT+0200 (CEST)', id: 1 }; let ampResult = ampContentHelper.call(testData1); const amperizeCache = ampContentHelper.__get__('amperizeCache'); ampResult.then(function (rendered) { should.exist(rendered); should.exist(amperizeCache); rendered.string.should.equal(testData1.html); amperizeCache[1].should.have.property('updated_at', 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)'); amperizeCache[1].should.have.property('amp', testData1.html); // call it again with different values to fetch from Amperize and not from cache ampResult = ampContentHelper.call(testData2); ampResult.then(function (cachedResult) { should.exist(cachedResult); should.exist(amperizeCache); // it should not have the old value, amperizeCache[1].should.not.have.property('Wed Jul 30 2016 18:17:22 GMT+0200 (CEST)'); // only the new one cachedResult.string.should.equal(testData2.html); amperizeCache[1].should.have.property('updated_at', 'Wed Jul 30 2016 18:17:22 GMT+0200 (CEST)'); amperizeCache[1].should.have.property('amp', testData2.html); done(); }); }).catch(done); }); }); describe('Transforms and sanitizes HTML', function () { beforeEach(function () { ampContentHelper.__set__('urlUtils', urlUtils.getInstance({url: 'https://ghost.org/blog/'})); }); afterEach(function () { ampContentHelper.__set__('amperizeCache', {}); }); it('can transform img tags to amp-img', function (done) { const GIF1x1 = Buffer.from('R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==', 'base64'); nock('https://ghost.org/blog/') .get('/content/images/2019/06/test.jpg') .reply(200, GIF1x1); const testData = { html: 'The Ghost Logo', updated_at: 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)', id: 1 }; const expectedResult = ''; const ampResult = ampContentHelper.call(testData); ampResult.then(function (rendered) { should.exist(rendered); rendered.string.should.equal(expectedResult); done(); }).catch(done); }); it('can transform audio tags to amp-audio', function (done) { const testData = { html: '' + '', updated_at: 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)', id: 1 }; const expectedResult = 'Your browser does not support the audio element.' + ''; const ampResult = ampContentHelper.call(testData); ampResult.then(function (rendered) { should.exist(rendered); rendered.string.should.equal(expectedResult); done(); }).catch(done); }); it('removes video tags including source children', function (done) { const testData = { html: '', updated_at: 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)', id: 1 }; const expectedResult = 'Your browser doesn\'t support HTML5 video tag.'; const ampResult = ampContentHelper.call(testData); ampResult.then(function (rendered) { should.exist(rendered); rendered.string.should.equal(expectedResult); done(); }).catch(done); }); it('removes inline style', function (done) { const testData = { html: '' + '

Hello

' + ' ' + ' ' + '
Name:Bill Gates
Telephone:55577854
', updated_at: 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)', id: 1 }; const expectedResult = '

Hello

' + ' ' + ' ' + '
Name:Bill Gates
Telephone:55577854
'; const ampResult = ampContentHelper.call(testData); ampResult.then(function (rendered) { should.exist(rendered); rendered.string.should.equal(expectedResult); done(); }).catch(done); }); it('removes prohibited iframe attributes', function (done) { const testData = { html: '', updated_at: 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)', id: 1 }; const expectedResult = ''; const ampResult = ampContentHelper.call(testData); ampResult.then(function (rendered) { should.exist(rendered); rendered.string.should.equal(expectedResult); done(); }).catch(done); }); it('can handle incomplete HTML tags by returning not Amperized HTML', function (done) { const testData = { html: '', updated_at: 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)', id: 1 }; const ampResult = ampContentHelper.call(testData); let sanitizedHTML; let ampedHTML; ampResult.then(function (rendered) { sanitizedHTML = ampContentHelper.__get__('cleanHTML'); ampedHTML = ampContentHelper.__get__('ampHTML'); should.exist(rendered); rendered.string.should.equal(''); should.exist(ampedHTML); ampedHTML.should.be.equal(''); should.exist(sanitizedHTML); sanitizedHTML.should.be.equal(''); done(); }).catch(done); }); it('can handle not existing img src by returning not Amperized HTML', function (done) { const testData = { html: 'The Ghost Logo', updated_at: 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)', id: 1 }; const ampResult = ampContentHelper.call(testData); let sanitizedHTML; let ampedHTML; ampResult.then(function (rendered) { sanitizedHTML = ampContentHelper.__get__('cleanHTML'); ampedHTML = ampContentHelper.__get__('ampHTML'); should.exist(rendered); rendered.string.should.equal(''); should.exist(ampedHTML); ampedHTML.should.be.equal('The Ghost Logo'); should.exist(sanitizedHTML); sanitizedHTML.should.be.equal(''); done(); }).catch(done); }); it('does not convert internal anchor links starting with "#"', function (done) { const testData = { html: 'Table of Content', updated_at: 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)', id: 1 }; const ampResult = ampContentHelper.call(testData); let sanitizedHTML; let ampedHTML; ampResult.then(function (rendered) { sanitizedHTML = ampContentHelper.__get__('cleanHTML'); ampedHTML = ampContentHelper.__get__('ampHTML'); should.exist(rendered); rendered.string.should.equal('Table of Content'); should.exist(ampedHTML); ampedHTML.should.be.equal('Table of Content'); should.exist(sanitizedHTML); sanitizedHTML.should.be.equal('Table of Content'); done(); }).catch(done); }); it('sanitizes remaining and not valid tags', function (done) { const testData = { html: '' + '' + '', updated_at: 'Wed Jul 27 2016 18:17:22 GMT+0200 (CEST)', id: 1 }; const ampResult = ampContentHelper.call(testData); ampResult.then(function (rendered) { should.exist(rendered); rendered.string.should.be.equal(''); done(); }).catch(done); }); }); });