const should = require('should'); const sinon = require('sinon'); const _ = require('lodash'); const testUtils = require('../../utils'); const mockUtils = require('../../utils/mocks'); const configUtils = require('../../utils/configUtils'); const urlUtils = require('../../utils/urlUtils'); const appService = require('../../../core/frontend/services/apps'); const themeService = require('../../../core/frontend/services/themes'); const siteApp = require('../../../core/server/web/parent/app'); describe('Integration - Web - vhosts', function () { let app; before(testUtils.integrationTesting.urlService.resetGenerators); before(testUtils.teardownDb); before(testUtils.setup('users:roles', 'posts')); after(function () { configUtils.restore(); urlUtils.restore(); sinon.restore(); }); describe('no separate admin', function () { before(function () { testUtils.integrationTesting.urlService.resetGenerators(); testUtils.integrationTesting.defaultMocks(sinon, {amp: true}); testUtils.integrationTesting.overrideGhostConfig(configUtils); configUtils.set('url', 'http://example.com'); configUtils.set('admin:url', null); return testUtils.integrationTesting.initGhost() .then(function () { sinon.stub(themeService.getActive(), 'engine').withArgs('ghost-api').returns('v2'); sinon.stub(themeService.getActive(), 'config').withArgs('posts_per_page').returns(2); app = siteApp({start: true}); return testUtils.integrationTesting.urlServiceInitAndWait(); }) .then(() => { return appService.init(); }); }); before(function () { configUtils.set('url', 'http://example.com'); configUtils.set('admin:url', null); urlUtils.stubUrlUtilsFromConfig(); }); after(function () { configUtils.restore(); urlUtils.restore(); sinon.restore(); }); it('loads the front-end on configured url', function () { const req = { secure: false, method: 'GET', url: '/', host: 'example.com' }; return mockUtils.express.invoke(app, req) .then(function (response) { response.statusCode.should.eql(200); }); }); it('loads the front-end on localhost', function () { const req = { secure: false, method: 'GET', url: '/', host: 'localhost' }; return mockUtils.express.invoke(app, req) .then(function (response) { response.statusCode.should.eql(200); }); }); it('loads the admin', function () { const req = { secure: false, method: 'GET', url: '/ghost/', host: 'example.com' }; return mockUtils.express.invoke(app, req) .then(function (response) { response.statusCode.should.eql(200); }); }); it('loads the admin on localhost', function () { const req = { secure: false, method: 'GET', url: '/ghost/', host: 'localhost' }; return mockUtils.express.invoke(app, req) .then(function (response) { response.statusCode.should.eql(200); }); }); it('loads the api', function () { const req = { secure: false, method: 'GET', url: '/ghost/api/v2/admin/site/', host: 'example.com' }; return mockUtils.express.invoke(app, req) .then(function (response) { response.statusCode.should.eql(200); }); }); it('loads the api on localhost', function () { const req = { secure: false, method: 'GET', url: '/ghost/api/v2/admin/site/', host: 'localhost' }; return mockUtils.express.invoke(app, req) .then(function (response) { response.statusCode.should.eql(200); }); }); }); describe('separate admin host', function () { before(function () { testUtils.integrationTesting.urlService.resetGenerators(); testUtils.integrationTesting.defaultMocks(sinon, {amp: true}); testUtils.integrationTesting.overrideGhostConfig(configUtils); configUtils.set('url', 'http://example.com'); configUtils.set('admin:url', 'https://admin.example.com'); return testUtils.integrationTesting.initGhost() .then(function () { sinon.stub(themeService.getActive(), 'engine').withArgs('ghost-api').returns('v2'); sinon.stub(themeService.getActive(), 'config').withArgs('posts_per_page').returns(2); app = siteApp({start: true}); return testUtils.integrationTesting.urlServiceInitAndWait(); }) .then(() => { return appService.init(); }); }); before(function () { urlUtils.stubUrlUtilsFromConfig(); }); after(function () { configUtils.restore(); urlUtils.restore(); sinon.restore(); }); it('loads the front-end on configured url', function () { const req = { secure: false, method: 'GET', url: '/', host: 'example.com' }; return mockUtils.express.invoke(app, req) .then(function (response) { response.statusCode.should.eql(200); }); }); it('loads the front-end on localhost', function () { const req = { secure: false, method: 'GET', url: '/', host: 'localhost' }; return mockUtils.express.invoke(app, req) .then(function (response) { response.statusCode.should.eql(200); }); }); it('redirects /ghost/ on configured url', function () { const req = { secure: false, method: 'GET', url: '/ghost/', host: 'example.com' }; return mockUtils.express.invoke(app, req) .then(function (response) { response.statusCode.should.eql(301); response.headers.location.should.eql('https://admin.example.com/ghost/'); }); }); it('404s the api on configured url', function () { const req = { secure: false, method: 'GET', url: '/ghost/api/v2/admin/site/', host: 'example.com' }; return mockUtils.express.invoke(app, req) .then(function (response) { response.statusCode.should.eql(404); }); }); it('404s the api on localhost', function () { const req = { secure: false, method: 'GET', url: '/ghost/api/v2/admin/site/', host: 'localhost' }; return mockUtils.express.invoke(app, req) .then(function (response) { response.statusCode.should.eql(404); }); }); it('loads the admin on configured admin url', function () { const req = { secure: true, method: 'GET', url: '/ghost/', host: 'admin.example.com' }; return mockUtils.express.invoke(app, req) .then(function (response) { response.statusCode.should.eql(200); }); }); it('loads the api on configured admin url', function () { const req = { secure: true, method: 'GET', url: '/ghost/api/v2/admin/site/', host: 'admin.example.com' }; return mockUtils.express.invoke(app, req) .then(function (response) { response.statusCode.should.eql(200); }); }); it('redirects to the correct protocol on configured admin url', function () { const req = { secure: false, method: 'GET', url: '/ghost/', host: 'admin.example.com' }; return mockUtils.express.invoke(app, req) .then(function (response) { response.statusCode.should.eql(301); response.headers.location.should.eql('https://admin.example.com/ghost/'); }); }); it('404s the front-end on configured admin url', function () { const req = { secure: false, method: 'GET', url: '/', host: 'admin.example.com' }; return mockUtils.express.invoke(app, req) .then(function (response) { response.statusCode.should.eql(404); }); }); }); describe('separate admin host w/ admin redirects disabled', function () { before(function () { testUtils.integrationTesting.urlService.resetGenerators(); testUtils.integrationTesting.defaultMocks(sinon, {amp: true}); testUtils.integrationTesting.overrideGhostConfig(configUtils); configUtils.set('url', 'http://example.com'); configUtils.set('admin:url', 'https://admin.example.com'); configUtils.set('admin:redirects', false); return testUtils.integrationTesting.initGhost() .then(function () { sinon.stub(themeService.getActive(), 'engine').withArgs('ghost-api').returns('v2'); sinon.stub(themeService.getActive(), 'config').withArgs('posts_per_page').returns(2); app = siteApp({start: true}); return testUtils.integrationTesting.urlServiceInitAndWait(); }) .then(() => { return appService.init(); }); }); before(function () { urlUtils.stubUrlUtilsFromConfig(); }); after(function () { configUtils.restore(); urlUtils.restore(); sinon.restore(); }); it('does not redirect /ghost/ on configured url', function () { const req = { secure: false, method: 'GET', url: '/ghost/', host: 'example.com' }; return mockUtils.express.invoke(app, req) .then(function (response) { response.statusCode.should.eql(404); }); }); }); describe('same host separate protocol', function () { before(function () { testUtils.integrationTesting.urlService.resetGenerators(); testUtils.integrationTesting.defaultMocks(sinon, {amp: true}); testUtils.integrationTesting.overrideGhostConfig(configUtils); configUtils.set('url', 'http://example.com'); configUtils.set('admin:url', 'https://example.com'); return testUtils.integrationTesting.initGhost() .then(function () { sinon.stub(themeService.getActive(), 'engine').withArgs('ghost-api').returns('v2'); sinon.stub(themeService.getActive(), 'config').withArgs('posts_per_page').returns(2); app = siteApp({start: true}); return testUtils.integrationTesting.urlServiceInitAndWait(); }) .then(() => { return appService.init(); }); }); before(function () { urlUtils.stubUrlUtilsFromConfig(); }); it('loads the front-end on configured url (http)', function () { const req = { secure: false, method: 'GET', url: '/', host: 'example.com' }; return mockUtils.express.invoke(app, req) .then(function (response) { response.statusCode.should.eql(200); }); }); it('404s the front-end on configured url (https)', function () { const req = { secure: true, method: 'GET', url: '/', host: 'example.com' }; return mockUtils.express.invoke(app, req) .then(function (response) { response.statusCode.should.eql(200); }); }); it('loads the front-end on localhost', function () { const req = { secure: false, method: 'GET', url: '/', host: 'localhost' }; return mockUtils.express.invoke(app, req) .then(function (response) { response.statusCode.should.eql(200); }); }); it('redirects /ghost/ on configured url', function () { const req = { secure: false, method: 'GET', url: '/ghost/', host: 'example.com' }; return mockUtils.express.invoke(app, req) .then(function (response) { response.statusCode.should.eql(301); response.headers.location.should.eql('https://example.com/ghost/'); }); }); it('redirects /ghost/ on localhost', function () { const req = { secure: false, method: 'GET', url: '/ghost/', host: 'localhost' }; return mockUtils.express.invoke(app, req) .then(function (response) { response.statusCode.should.eql(301); response.headers.location.should.eql('https://example.com/ghost/'); }); }); it('redirects api to correct protocol on configured admin url', function () { const req = { secure: false, method: 'GET', url: '/ghost/api/v2/admin/site/', host: 'example.com' }; return mockUtils.express.invoke(app, req) .then(function (response) { response.statusCode.should.eql(301); response.headers.location.should.eql('https://example.com/ghost/api/v2/admin/site/'); }); }); it('loads the admin on configured admin url', function () { const req = { secure: true, method: 'GET', url: '/ghost/', host: 'example.com' }; return mockUtils.express.invoke(app, req) .then(function (response) { response.statusCode.should.eql(200); }); }); it('redirects the admin on localhost', function () { const req = { secure: false, method: 'GET', url: '/ghost/', host: 'localhost' }; return mockUtils.express.invoke(app, req) .then(function (response) { response.statusCode.should.eql(301); response.headers.location.should.eql('https://example.com/ghost/'); }); }); it('loads the api on configured admin url', function () { const req = { secure: true, method: 'GET', url: '/ghost/api/v2/admin/site/', host: 'example.com' }; return mockUtils.express.invoke(app, req) .then(function (response) { response.statusCode.should.eql(200); }); }); it('redirects the api on localhost', function () { const req = { secure: false, method: 'GET', url: '/ghost/api/v2/admin/site/', host: 'localhost' }; return mockUtils.express.invoke(app, req) .then(function (response) { response.statusCode.should.eql(301); response.headers.location.should.eql('https://example.com/ghost/api/v2/admin/site/'); }); }); }); });