From 11682bb8a70f6f449aa59ba322900848799e8ee2 Mon Sep 17 00:00:00 2001 From: Hannah Wolfe Date: Fri, 20 Mar 2020 10:23:56 +0000 Subject: [PATCH] Added frontend acceptance tests - Basic set of tests checks that our default behaviour works as expected - Moved current acceptance tests to api-acceptance, and added this in frontend-acceptance - This reduces nesting, and will help when we eventually separate the frontend out entirely --- Gruntfile.js | 3 +- .../{acceptance => api-acceptance}/README.md | 0 .../admin/actions_spec.js | 0 .../admin/config_spec.js | 0 .../admin/db_spec.js | 0 .../admin/email_preview_spec.js | 0 .../admin/emails_spec.js | 0 .../admin/images_spec.js | 0 .../admin/integrations_spec.js | 0 .../admin/invites_spec.js | 0 .../admin/key_authentication_spec.js | 0 .../admin/mail_spec.js | 0 .../admin/notifications_spec.js | 0 .../admin/oembed_spec.js | 0 .../admin/pages_spec.js | 0 .../admin/posts_spec.js | 0 .../admin/roles_spec.js | 0 .../admin/settings_spec.js | 0 .../admin/slugs_spec.js | 0 .../admin/tags_spec.js | 0 .../admin/themes_spec.js | 0 .../admin/users_spec.js | 0 .../admin/utils.js | 0 .../admin/webhooks_spec.js | 0 .../content/authors_spec.js | 0 .../content/key_authentication_spec.js | 0 .../content/pages_spec.js | 0 .../content/posts_spec.js | 0 .../content/settings_spec.js | 0 .../content/tags_spec.js | 0 .../content/utils.js | 0 .../default_routes_spec.js | 407 ++++++++++++++++++ core/test/regression/site/frontend_spec.js | 287 +----------- 33 files changed, 415 insertions(+), 282 deletions(-) rename core/test/{acceptance => api-acceptance}/README.md (100%) rename core/test/{acceptance => api-acceptance}/admin/actions_spec.js (100%) rename core/test/{acceptance => api-acceptance}/admin/config_spec.js (100%) rename core/test/{acceptance => api-acceptance}/admin/db_spec.js (100%) rename core/test/{acceptance => api-acceptance}/admin/email_preview_spec.js (100%) rename core/test/{acceptance => api-acceptance}/admin/emails_spec.js (100%) rename core/test/{acceptance => api-acceptance}/admin/images_spec.js (100%) rename core/test/{acceptance => api-acceptance}/admin/integrations_spec.js (100%) rename core/test/{acceptance => api-acceptance}/admin/invites_spec.js (100%) rename core/test/{acceptance => api-acceptance}/admin/key_authentication_spec.js (100%) rename core/test/{acceptance => api-acceptance}/admin/mail_spec.js (100%) rename core/test/{acceptance => api-acceptance}/admin/notifications_spec.js (100%) rename core/test/{acceptance => api-acceptance}/admin/oembed_spec.js (100%) rename core/test/{acceptance => api-acceptance}/admin/pages_spec.js (100%) rename core/test/{acceptance => api-acceptance}/admin/posts_spec.js (100%) rename core/test/{acceptance => api-acceptance}/admin/roles_spec.js (100%) rename core/test/{acceptance => api-acceptance}/admin/settings_spec.js (100%) rename core/test/{acceptance => api-acceptance}/admin/slugs_spec.js (100%) rename core/test/{acceptance => api-acceptance}/admin/tags_spec.js (100%) rename core/test/{acceptance => api-acceptance}/admin/themes_spec.js (100%) rename core/test/{acceptance => api-acceptance}/admin/users_spec.js (100%) rename core/test/{acceptance => api-acceptance}/admin/utils.js (100%) rename core/test/{acceptance => api-acceptance}/admin/webhooks_spec.js (100%) rename core/test/{acceptance => api-acceptance}/content/authors_spec.js (100%) rename core/test/{acceptance => api-acceptance}/content/key_authentication_spec.js (100%) rename core/test/{acceptance => api-acceptance}/content/pages_spec.js (100%) rename core/test/{acceptance => api-acceptance}/content/posts_spec.js (100%) rename core/test/{acceptance => api-acceptance}/content/settings_spec.js (100%) rename core/test/{acceptance => api-acceptance}/content/tags_spec.js (100%) rename core/test/{acceptance => api-acceptance}/content/utils.js (100%) create mode 100644 core/test/frontend-acceptance/default_routes_spec.js diff --git a/Gruntfile.js b/Gruntfile.js index 10b6099c37..04acc3f21b 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -129,7 +129,8 @@ const configureGrunt = function (grunt) { acceptance: { src: [ - 'core/test/acceptance/**/*_spec.js' + 'core/test/api-acceptance/**/*_spec.js', + 'core/test/frontend-acceptance/**/*_spec.js' ] }, diff --git a/core/test/acceptance/README.md b/core/test/api-acceptance/README.md similarity index 100% rename from core/test/acceptance/README.md rename to core/test/api-acceptance/README.md diff --git a/core/test/acceptance/admin/actions_spec.js b/core/test/api-acceptance/admin/actions_spec.js similarity index 100% rename from core/test/acceptance/admin/actions_spec.js rename to core/test/api-acceptance/admin/actions_spec.js diff --git a/core/test/acceptance/admin/config_spec.js b/core/test/api-acceptance/admin/config_spec.js similarity index 100% rename from core/test/acceptance/admin/config_spec.js rename to core/test/api-acceptance/admin/config_spec.js diff --git a/core/test/acceptance/admin/db_spec.js b/core/test/api-acceptance/admin/db_spec.js similarity index 100% rename from core/test/acceptance/admin/db_spec.js rename to core/test/api-acceptance/admin/db_spec.js diff --git a/core/test/acceptance/admin/email_preview_spec.js b/core/test/api-acceptance/admin/email_preview_spec.js similarity index 100% rename from core/test/acceptance/admin/email_preview_spec.js rename to core/test/api-acceptance/admin/email_preview_spec.js diff --git a/core/test/acceptance/admin/emails_spec.js b/core/test/api-acceptance/admin/emails_spec.js similarity index 100% rename from core/test/acceptance/admin/emails_spec.js rename to core/test/api-acceptance/admin/emails_spec.js diff --git a/core/test/acceptance/admin/images_spec.js b/core/test/api-acceptance/admin/images_spec.js similarity index 100% rename from core/test/acceptance/admin/images_spec.js rename to core/test/api-acceptance/admin/images_spec.js diff --git a/core/test/acceptance/admin/integrations_spec.js b/core/test/api-acceptance/admin/integrations_spec.js similarity index 100% rename from core/test/acceptance/admin/integrations_spec.js rename to core/test/api-acceptance/admin/integrations_spec.js diff --git a/core/test/acceptance/admin/invites_spec.js b/core/test/api-acceptance/admin/invites_spec.js similarity index 100% rename from core/test/acceptance/admin/invites_spec.js rename to core/test/api-acceptance/admin/invites_spec.js diff --git a/core/test/acceptance/admin/key_authentication_spec.js b/core/test/api-acceptance/admin/key_authentication_spec.js similarity index 100% rename from core/test/acceptance/admin/key_authentication_spec.js rename to core/test/api-acceptance/admin/key_authentication_spec.js diff --git a/core/test/acceptance/admin/mail_spec.js b/core/test/api-acceptance/admin/mail_spec.js similarity index 100% rename from core/test/acceptance/admin/mail_spec.js rename to core/test/api-acceptance/admin/mail_spec.js diff --git a/core/test/acceptance/admin/notifications_spec.js b/core/test/api-acceptance/admin/notifications_spec.js similarity index 100% rename from core/test/acceptance/admin/notifications_spec.js rename to core/test/api-acceptance/admin/notifications_spec.js diff --git a/core/test/acceptance/admin/oembed_spec.js b/core/test/api-acceptance/admin/oembed_spec.js similarity index 100% rename from core/test/acceptance/admin/oembed_spec.js rename to core/test/api-acceptance/admin/oembed_spec.js diff --git a/core/test/acceptance/admin/pages_spec.js b/core/test/api-acceptance/admin/pages_spec.js similarity index 100% rename from core/test/acceptance/admin/pages_spec.js rename to core/test/api-acceptance/admin/pages_spec.js diff --git a/core/test/acceptance/admin/posts_spec.js b/core/test/api-acceptance/admin/posts_spec.js similarity index 100% rename from core/test/acceptance/admin/posts_spec.js rename to core/test/api-acceptance/admin/posts_spec.js diff --git a/core/test/acceptance/admin/roles_spec.js b/core/test/api-acceptance/admin/roles_spec.js similarity index 100% rename from core/test/acceptance/admin/roles_spec.js rename to core/test/api-acceptance/admin/roles_spec.js diff --git a/core/test/acceptance/admin/settings_spec.js b/core/test/api-acceptance/admin/settings_spec.js similarity index 100% rename from core/test/acceptance/admin/settings_spec.js rename to core/test/api-acceptance/admin/settings_spec.js diff --git a/core/test/acceptance/admin/slugs_spec.js b/core/test/api-acceptance/admin/slugs_spec.js similarity index 100% rename from core/test/acceptance/admin/slugs_spec.js rename to core/test/api-acceptance/admin/slugs_spec.js diff --git a/core/test/acceptance/admin/tags_spec.js b/core/test/api-acceptance/admin/tags_spec.js similarity index 100% rename from core/test/acceptance/admin/tags_spec.js rename to core/test/api-acceptance/admin/tags_spec.js diff --git a/core/test/acceptance/admin/themes_spec.js b/core/test/api-acceptance/admin/themes_spec.js similarity index 100% rename from core/test/acceptance/admin/themes_spec.js rename to core/test/api-acceptance/admin/themes_spec.js diff --git a/core/test/acceptance/admin/users_spec.js b/core/test/api-acceptance/admin/users_spec.js similarity index 100% rename from core/test/acceptance/admin/users_spec.js rename to core/test/api-acceptance/admin/users_spec.js diff --git a/core/test/acceptance/admin/utils.js b/core/test/api-acceptance/admin/utils.js similarity index 100% rename from core/test/acceptance/admin/utils.js rename to core/test/api-acceptance/admin/utils.js diff --git a/core/test/acceptance/admin/webhooks_spec.js b/core/test/api-acceptance/admin/webhooks_spec.js similarity index 100% rename from core/test/acceptance/admin/webhooks_spec.js rename to core/test/api-acceptance/admin/webhooks_spec.js diff --git a/core/test/acceptance/content/authors_spec.js b/core/test/api-acceptance/content/authors_spec.js similarity index 100% rename from core/test/acceptance/content/authors_spec.js rename to core/test/api-acceptance/content/authors_spec.js diff --git a/core/test/acceptance/content/key_authentication_spec.js b/core/test/api-acceptance/content/key_authentication_spec.js similarity index 100% rename from core/test/acceptance/content/key_authentication_spec.js rename to core/test/api-acceptance/content/key_authentication_spec.js diff --git a/core/test/acceptance/content/pages_spec.js b/core/test/api-acceptance/content/pages_spec.js similarity index 100% rename from core/test/acceptance/content/pages_spec.js rename to core/test/api-acceptance/content/pages_spec.js diff --git a/core/test/acceptance/content/posts_spec.js b/core/test/api-acceptance/content/posts_spec.js similarity index 100% rename from core/test/acceptance/content/posts_spec.js rename to core/test/api-acceptance/content/posts_spec.js diff --git a/core/test/acceptance/content/settings_spec.js b/core/test/api-acceptance/content/settings_spec.js similarity index 100% rename from core/test/acceptance/content/settings_spec.js rename to core/test/api-acceptance/content/settings_spec.js diff --git a/core/test/acceptance/content/tags_spec.js b/core/test/api-acceptance/content/tags_spec.js similarity index 100% rename from core/test/acceptance/content/tags_spec.js rename to core/test/api-acceptance/content/tags_spec.js diff --git a/core/test/acceptance/content/utils.js b/core/test/api-acceptance/content/utils.js similarity index 100% rename from core/test/acceptance/content/utils.js rename to core/test/api-acceptance/content/utils.js diff --git a/core/test/frontend-acceptance/default_routes_spec.js b/core/test/frontend-acceptance/default_routes_spec.js new file mode 100644 index 0000000000..b0bff9753f --- /dev/null +++ b/core/test/frontend-acceptance/default_routes_spec.js @@ -0,0 +1,407 @@ +// # Default Frontend Routing Test +// These tests check the default out-of-the-box behaviour of Ghost is working as expected. + +// Test Structure +// As it stands, these tests depend on the database, and as such are integration tests. +// Mocking out the models to not touch the DB would turn these into unit tests, and should probably be done in future, +// But then again testing real code, rather than mock code, might be more useful... +var should = require('should'), + sinon = require('sinon'), + supertest = require('supertest'), + moment = require('moment'), + cheerio = require('cheerio'), + _ = require('lodash'), + testUtils = require('../utils'), + configUtils = require('../utils/configUtils'), + urlUtils = require('../utils/urlUtils'), + config = require('../../server/config'), + settingsCache = require('../../server/services/settings/cache'), + origCache = _.cloneDeep(settingsCache), + ghost = testUtils.startGhost, + request; + +describe('Default Frontend routing', function () { + function doEnd(done) { + return function (err, res) { + if (err) { + return done(err); + } + + should.not.exist(res.headers['x-cache-invalidate']); + should.not.exist(res.headers['X-CSRF-Token']); + should.not.exist(res.headers['set-cookie']); + should.exist(res.headers.date); + + done(); + }; + } + + function addPosts(done) { + testUtils.clearData().then(function () { + return testUtils.initData(); + }).then(function () { + return testUtils.fixtures.insertPostsAndTags(); + }).then(function () { + done(); + }); + } + + afterEach(function () { + sinon.restore(); + }); + + before(function () { + return ghost() + .then(function () { + request = supertest.agent(config.get('url')); + }); + }); + + describe('Error', function () { + it('should 404 for unknown post', function (done) { + request.get('/spectacular/') + .expect('Cache-Control', testUtils.cacheRules.private) + .expect(404) + .expect(/Page not found/) + .end(doEnd(done)); + }); + + it('should 404 for unknown file', function (done) { + request.get('/content/images/some/file/that/doesnt-exist.jpg') + .expect('Cache-Control', testUtils.cacheRules.private) + .expect(404) + .expect(/404 Image not found/) + .end(doEnd(done)); + }); + }); + + describe('Main Routes', function () { + it('/ should respond with valid HTML', function (done) { + request.get('/') + .expect('Content-Type', /html/) + .expect('Cache-Control', testUtils.cacheRules.public) + .expect(200) + .end(function (err, res) { + var $ = cheerio.load(res.text); + + // NOTE: "Ghost" is the title from the settings. + $('title').text().should.equal('Ghost'); + + $('body.home-template').length.should.equal(1); + $('article.post').length.should.equal(7); + $('article.tag-getting-started').length.should.equal(7); + + doEnd(done)(err, res); + }); + }); + + it('/author/ghost/ should respond with valid HTML', function (done) { + request.get('/author/ghost/') + .expect('Content-Type', /html/) + .expect('Cache-Control', testUtils.cacheRules.public) + .expect(200) + .end(function (err, res) { + var $ = cheerio.load(res.text); + + // NOTE: "Ghost" is the title from the settings. + $('title').text().should.equal('Ghost - Ghost'); + + $('body.author-template').length.should.equal(1); + $('article.post').length.should.equal(7); + $('article.tag-getting-started').length.should.equal(7); + + doEnd(done)(err, res); + }); + }); + + it('/tag/getting-started/ should respond with valid HTML', function (done) { + request.get('/tag/getting-started/') + .expect('Content-Type', /html/) + .expect('Cache-Control', testUtils.cacheRules.public) + .expect(200) + .end(function (err, res) { + var $ = cheerio.load(res.text); + + // NOTE: "Ghost" is the title from the settings. + $('title').text().should.equal('Getting Started - Ghost'); + + $('body.tag-template').length.should.equal(1); + $('article.post').length.should.equal(7); + $('article.tag-getting-started').length.should.equal(7); + + doEnd(done)(err, res); + }); + }); + }); + + describe('Single post', function () { + it('/welcome/ should respond with valid HTML', function (done) { + request.get('/welcome/') + .expect('Content-Type', /html/) + .expect('Cache-Control', testUtils.cacheRules.public) + .expect(200) + .end(function (err, res) { + var $ = cheerio.load(res.text); + + // NOTE: This is the title from the settings. + $('title').text().should.equal('Welcome to Ghost'); + + $('body.post-template').length.should.equal(1); + $('body.tag-getting-started').length.should.equal(1); + $('article.post').length.should.equal(2); + $('article.tag-getting-started').length.should.equal(2); + + doEnd(done)(err, res); + }); + }); + + it('should not work with date permalinks', function (done) { + // get today's date + var date = moment().format('YYYY/MM/DD'); + + request.get('/' + date + '/welcome/') + .expect('Cache-Control', testUtils.cacheRules.private) + .expect(404) + .expect(/Page not found/) + .end(doEnd(done)); + }); + }); + + describe('Post edit', function () { + it('should redirect to editor', function (done) { + request.get('/welcome/edit/') + .expect('Location', /ghost\/editor\/\w+/) + .expect('Cache-Control', testUtils.cacheRules.public) + .expect(302) + .end(doEnd(done)); + }); + + it('should 404 for non-edit parameter', function (done) { + request.get('/welcome/notedit/') + .expect('Cache-Control', testUtils.cacheRules.private) + .expect(404) + .expect(/Page not found/) + .end(doEnd(done)); + }); + + describe('Admin Redirects Disabled', function () { + before(function () { + configUtils.set('admin:redirects', false); + + return ghost({forceStart: true}) + .then(function () { + request = supertest.agent(config.get('url')); + }); + }); + + after(function () { + configUtils.restore(); + + return ghost({forceStart: true}) + .then(function () { + request = supertest.agent(config.get('url')); + }); + }); + + it('/edit/ should NOT redirect to the editor', function (done) { + request.get('/welcome/edit/') + .expect('Cache-Control', testUtils.cacheRules.private) + .expect(404) + .end(doEnd(done)); + }); + }); + }); + + describe('AMP post', function () { + it('should respond with html for valid url', function (done) { + request.get('/welcome/amp/') + .expect('Content-Type', /html/) + .expect('Cache-Control', testUtils.cacheRules.public) + .expect(200) + .end(function (err, res) { + if (err) { + return done(err); + } + + var $ = cheerio.load(res.text); + + should.not.exist(res.headers['x-cache-invalidate']); + should.not.exist(res.headers['X-CSRF-Token']); + should.not.exist(res.headers['set-cookie']); + should.exist(res.headers.date); + + $('title').text().should.equal('Welcome to Ghost'); + + $('.content .post').length.should.equal(1); + $('.poweredby').text().should.equal('Proudly published with Ghost'); + $('body.amp-template').length.should.equal(1); + $('article.post').length.should.equal(1); + + done(); + }); + }); + + it('should not work with date permalinks', function (done) { + // get today's date + var date = moment().format('YYYY/MM/DD'); + + request.get('/' + date + '/welcome/amp/') + .expect('Cache-Control', testUtils.cacheRules.private) + .expect(404) + .expect(/Page not found/) + .end(doEnd(done)); + }); + + describe('AMP Disabled', function () { + it('/amp/ should redirect to regular post, including any query params', function (done) { + sinon.stub(settingsCache, 'get').callsFake(function (key, options) { + if (key === 'amp' && !options) { + return false; + } + return origCache.get(key, options); + }); + + request.get('/welcome/amp/?q=a') + .expect('Location', '/welcome/?q=a') + .expect(301) + .end(doEnd(done)); + }); + }); + }); + + describe('RSS', function () { + it('/rss/ should serve an RSS feed', function (done) { + request.get('/rss/') + .expect(200) + .expect('Cache-Control', testUtils.cacheRules.public) + .expect('Content-Type', 'text/xml; charset=utf-8') + .end(function (err, res) { + res.text.should.match(//); + doEnd(done)(err, res); + }); + }); + + it('/author/ghost/rss/ should serve an RSS feed', function (done) { + request.get('/author/ghost/rss/') + .expect(200) + .expect('Cache-Control', testUtils.cacheRules.public) + .expect('Content-Type', 'text/xml; charset=utf-8') + .end(function (err, res) { + res.text.should.match(//); + doEnd(done)(err, res); + }); + }); + + it('/tag/getting-started/rss/ should serve an RSS feed', function (done) { + request.get('/tag/getting-started/rss/') + .expect(200) + .expect('Cache-Control', testUtils.cacheRules.public) + .expect('Content-Type', 'text/xml; charset=utf-8') + .end(function (err, res) { + res.text.should.match(//); + doEnd(done)(err, res); + }); + }); + }); + + describe('Static assets', function () { + it('should retrieve theme assets', function (done) { + request.get('/assets/css/screen.css') + .expect('Cache-Control', testUtils.cacheRules.year) + .expect(200) + .end(doEnd(done)); + }); + + it('should retrieve default robots.txt', function (done) { + request.get('/robots.txt') + .expect('Cache-Control', testUtils.cacheRules.hour) + .expect('ETag', /[0-9a-f]{32}/i) + .expect(200) + .end(doEnd(done)); + }); + + it('should retrieve default favicon.ico', function (done) { + request.get('/favicon.ico') + .expect('Cache-Control', testUtils.cacheRules.day) + .expect('ETag', /[0-9a-f]{32}/i) + .expect(200) + .end(doEnd(done)); + }); + }); + + describe('Site Map', function () { + before(function (done) { + testUtils.clearData().then(function () { + return testUtils.initData(); + }).then(function () { + done(); + }).catch(done); + }); + + it('should serve sitemap.xml', function (done) { + request.get('/sitemap.xml') + .expect(200) + .expect('Cache-Control', testUtils.cacheRules.hour) + .expect('Content-Type', 'text/xml; charset=utf-8') + .end(function (err, res) { + res.text.should.match(/sitemapindex/); + doEnd(done)(err, res); + }); + }); + + it('should serve sitemap-posts.xml', function (done) { + request.get('/sitemap-posts.xml') + .expect(200) + .expect('Cache-Control', testUtils.cacheRules.hour) + .expect('Content-Type', 'text/xml; charset=utf-8') + .end(function (err, res) { + res.text.should.match(/urlset/); + doEnd(done)(err, res); + }); + }); + + it('should serve sitemap-pages.xml', function (done) { + request.get('/sitemap-pages.xml') + .expect(200) + .expect('Cache-Control', testUtils.cacheRules.hour) + .expect('Content-Type', 'text/xml; charset=utf-8') + .end(function (err, res) { + res.text.should.match(/urlset/); + doEnd(done)(err, res); + }); + }); + + it('should serve sitemap-tags.xml', function (done) { + request.get('/sitemap-tags.xml') + .expect(200) + .expect('Cache-Control', testUtils.cacheRules.hour) + .expect('Content-Type', 'text/xml; charset=utf-8') + .end(function (err, res) { + res.text.should.match(/urlset/); + doEnd(done)(err, res); + }); + }); + + it('should serve sitemap-users.xml', function (done) { + request.get('/sitemap-users.xml') + .expect(200) + .expect('Cache-Control', testUtils.cacheRules.hour) + .expect('Content-Type', 'text/xml; charset=utf-8') + .end(function (err, res) { + res.text.should.match(/urlset/); + doEnd(done)(err, res); + }); + }); + + it('should serve sitemap.xsl', function (done) { + request.get('/sitemap.xsl') + .expect(200) + .expect('Cache-Control', testUtils.cacheRules.day) + .expect('Content-Type', 'text/xsl') + .end(function (err, res) { + res.text.should.match(/urlset/); + doEnd(done)(err, res); + }); + }); + }); +}); diff --git a/core/test/regression/site/frontend_spec.js b/core/test/regression/site/frontend_spec.js index 70fd5672ca..ae04fb6710 100644 --- a/core/test/regression/site/frontend_spec.js +++ b/core/test/regression/site/frontend_spec.js @@ -56,14 +56,6 @@ describe('Frontend Routing', function () { describe('Test with Initial Fixtures', function () { describe('Error', function () { - it('should 404 for unknown post', function (done) { - request.get('/spectacular/') - .expect('Cache-Control', testUtils.cacheRules.private) - .expect(404) - .expect(/Page not found/) - .end(doEnd(done)); - }); - it('should 404 for unknown post with invalid characters', function (done) { request.get('/$pec+acular~/') .expect('Cache-Control', testUtils.cacheRules.private) @@ -88,18 +80,10 @@ describe('Frontend Routing', function () { .expect(/Page not found/) .end(doEnd(done)); }); - - it('should 404 for unknown file', function (done) { - request.get('/content/images/some/file/that/doesnt-exist.jpg') - .expect('Cache-Control', testUtils.cacheRules.private) - .expect(404) - .expect(/404 Image not found/) - .end(doEnd(done)); - }); }); - describe('Single post', function () { - it('should redirect without slash', function (done) { + describe('Default Redirects (clean URLS)', function () { + it('Single post should redirect without slash', function (done) { request.get('/welcome') .expect('Location', '/welcome/') .expect('Cache-Control', testUtils.cacheRules.year) @@ -107,7 +91,7 @@ describe('Frontend Routing', function () { .end(doEnd(done)); }); - it('should redirect uppercase', function (done) { + it('Single post should redirect uppercase', function (done) { request.get('/Welcome/') .expect('Location', '/welcome/') .expect('Cache-Control', testUtils.cacheRules.year) @@ -115,7 +99,7 @@ describe('Frontend Routing', function () { .end(doEnd(done)); }); - it('should sanitize double slashes when redirecting uppercase', function (done) { + it('Single post should sanitize double slashes when redirecting uppercase', function (done) { request.get('///Google.com/') .expect('Location', '/google.com/') .expect('Cache-Control', testUtils.cacheRules.year) @@ -123,101 +107,7 @@ describe('Frontend Routing', function () { .end(doEnd(done)); }); - it('should respond with html for valid post url', function (done) { - request.get('/welcome/') - .expect('Content-Type', /html/) - .expect('Cache-Control', testUtils.cacheRules.public) - .expect(200) - .end(function (err, res) { - var $ = cheerio.load(res.text); - - // NOTE: This is the title from the settings. - $('title').text().should.equal('Welcome to Ghost'); - - $('body.post-template').length.should.equal(1); - $('body.tag-getting-started').length.should.equal(1); - $('article.post').length.should.equal(2); - $('article.tag-getting-started').length.should.equal(2); - - doEnd(done)(err, res); - }); - }); - - it('should not work with date permalinks', function (done) { - // get today's date - var date = moment().format('YYYY/MM/DD'); - - request.get('/' + date + '/welcome/') - .expect('Cache-Control', testUtils.cacheRules.private) - .expect(404) - .expect(/Page not found/) - .end(doEnd(done)); - }); - }); - - describe('Post edit', function () { - it('should redirect without slash', function (done) { - request.get('/welcome/edit') - .expect('Location', '/welcome/edit/') - .expect('Cache-Control', testUtils.cacheRules.year) - .expect(301) - .end(doEnd(done)); - }); - - it('should redirect to editor', function (done) { - request.get('/welcome/edit/') - .expect('Location', /ghost\/editor\/\w+/) - .expect('Cache-Control', testUtils.cacheRules.public) - .expect(302) - .end(doEnd(done)); - }); - - it('should 404 for non-edit parameter', function (done) { - request.get('/welcome/notedit/') - .expect('Cache-Control', testUtils.cacheRules.private) - .expect(404) - .expect(/Page not found/) - .end(doEnd(done)); - }); - }); - - describe('Post edit with admin redirects disabled', function () { - before(function () { - configUtils.set('admin:redirects', false); - - return ghost({forceStart: true}) - .then(function () { - request = supertest.agent(config.get('url')); - }); - }); - - after(function () { - configUtils.restore(); - - return ghost({forceStart: true}) - .then(function () { - request = supertest.agent(config.get('url')); - }); - }); - - it('should redirect without slash', function (done) { - request.get('/welcome/edit') - .expect('Location', '/welcome/edit/') - .expect('Cache-Control', testUtils.cacheRules.year) - .expect(301) - .end(doEnd(done)); - }); - - it('should not redirect to editor', function (done) { - request.get('/welcome/edit/') - .expect('Cache-Control', testUtils.cacheRules.private) - .expect(404) - .end(doEnd(done)); - }); - }); - - describe('AMP post', function () { - it('should redirect without slash', function (done) { + it('AMP post should redirect without slash', function (done) { request.get('/welcome/amp') .expect('Location', '/welcome/amp/') .expect('Cache-Control', testUtils.cacheRules.year) @@ -225,112 +115,13 @@ describe('Frontend Routing', function () { .end(doEnd(done)); }); - it('should redirect uppercase', function (done) { + it('AMP post should redirect uppercase', function (done) { request.get('/Welcome/AMP/') .expect('Location', '/welcome/amp/') .expect('Cache-Control', testUtils.cacheRules.year) .expect(301) .end(doEnd(done)); }); - - it('should respond with html for valid url', function (done) { - request.get('/welcome/amp/') - .expect('Content-Type', /html/) - .expect('Cache-Control', testUtils.cacheRules.public) - .expect(200) - .end(function (err, res) { - if (err) { - return done(err); - } - - var $ = cheerio.load(res.text); - - should.not.exist(res.headers['x-cache-invalidate']); - should.not.exist(res.headers['X-CSRF-Token']); - should.not.exist(res.headers['set-cookie']); - should.exist(res.headers.date); - - $('title').text().should.equal('Welcome to Ghost'); - - $('.content .post').length.should.equal(1); - $('.poweredby').text().should.equal('Proudly published with Ghost'); - $('body.amp-template').length.should.equal(1); - $('article.post').length.should.equal(1); - - done(); - }); - }); - - it('should not work with date permalinks', function (done) { - // get today's date - var date = moment().format('YYYY/MM/DD'); - - request.get('/' + date + '/welcome/amp/') - .expect('Cache-Control', testUtils.cacheRules.private) - .expect(404) - .expect(/Page not found/) - .end(doEnd(done)); - }); - - it('should redirect to regular post when AMP is disabled', function (done) { - sinon.stub(settingsCache, 'get').callsFake(function (key, options) { - if (key === 'amp' && !options) { - return false; - } - return origCache.get(key, options); - }); - - request.get('/welcome/amp/') - .expect('Location', '/welcome/') - .expect(301) - .end(doEnd(done)); - }); - - it('should redirect to regular post with query params when AMP is disabled', function (done) { - sinon.stub(settingsCache, 'get').callsFake(function (key, options) { - if (key === 'amp' && !options) { - return false; - } - return origCache.get(key, options); - }); - - request.get('/welcome/amp/?q=a') - .expect('Location', '/welcome/?q=a') - .expect(301) - .end(doEnd(done)); - }); - }); - - describe('Static assets', function () { - it('should retrieve theme assets', function (done) { - request.get('/assets/css/screen.css') - .expect('Cache-Control', testUtils.cacheRules.year) - .expect(200) - .end(doEnd(done)); - }); - - it('should retrieve default robots.txt', function (done) { - request.get('/robots.txt') - .expect('Cache-Control', testUtils.cacheRules.hour) - .expect('ETag', /[0-9a-f]{32}/i) - .expect(200) - .end(doEnd(done)); - }); - - it('should retrieve default favicon.ico', function (done) { - request.get('/favicon.ico') - .expect('Cache-Control', testUtils.cacheRules.day) - .expect('ETag', /[0-9a-f]{32}/i) - .expect(200) - .end(doEnd(done)); - }); - - // at the moment there is no image fixture to test - // it('should retrieve image assets', function (done) { - // request.get('/content/images/some.jpg') - // .expect('Cache-Control', testUtils.cacheRules.year) - // .end(doEnd(done)); - // }); }); }); @@ -498,72 +289,6 @@ describe('Frontend Routing', function () { }); }); - describe('Site Map', function () { - before(function (done) { - testUtils.clearData().then(function () { - return testUtils.initData(); - }).then(function () { - done(); - }).catch(done); - }); - - it('should serve sitemap.xml', function (done) { - request.get('/sitemap.xml') - .expect(200) - .expect('Cache-Control', testUtils.cacheRules.hour) - .expect('Content-Type', 'text/xml; charset=utf-8') - .end(function (err, res) { - res.text.should.match(/sitemapindex/); - doEnd(done)(err, res); - }); - }); - - it('should serve sitemap-posts.xml', function (done) { - request.get('/sitemap-posts.xml') - .expect(200) - .expect('Cache-Control', testUtils.cacheRules.hour) - .expect('Content-Type', 'text/xml; charset=utf-8') - .end(function (err, res) { - res.text.should.match(/urlset/); - doEnd(done)(err, res); - }); - }); - - it('should serve sitemap-pages.xml', function (done) { - request.get('/sitemap-pages.xml') - .expect(200) - .expect('Cache-Control', testUtils.cacheRules.hour) - .expect('Content-Type', 'text/xml; charset=utf-8') - .end(function (err, res) { - res.text.should.match(/urlset/); - doEnd(done)(err, res); - }); - }); - - it('should serve sitemap-tags.xml', function (done) { - request.get('/sitemap-tags.xml') - .expect(200) - .expect('Cache-Control', testUtils.cacheRules.hour) - .expect('Content-Type', 'text/xml; charset=utf-8') - .end(function (err, res) { - res.text.should.match(/urlset/); - doEnd(done)(err, res); - }); - }); - - it('should serve sitemap-users.xml', function (done) { - request.get('/sitemap-users.xml') - .expect(200) - .expect('Cache-Control', testUtils.cacheRules.hour) - .expect('Content-Type', 'text/xml; charset=utf-8') - .end(function (err, res) { - res.text.should.match(/urlset/); - doEnd(done)(err, res); - }); - }); - // TODO: Other pages and verify content - }); - describe('Subdirectory (no slash)', function () { var ghostServer;