0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-03-11 02:12:21 -05:00

Updated misc unversioned tests to run on canary

refs: https://github.com/TryGhost/Toolbox/issues/168

- All of our unversioned tests should be running against canary already
- These tests are erroneously running on the wrong version

We're going to be dropping the idea of having multiple versions of the API in each Ghost version.
Because this has not achieved the goal of making it easier to make breaking changes, but it has
created an ordinate amount of technical debt and maintenance overhead.

As we know this is going away in the next major, there is no benefit to us constantly running tests
that check if those versions still work, especially given how long they take.

Instead we're starting work to ensure that all of our test work on canary, and that canary has
excellent test coverage so that we can be sure that our one API version works really well and that
any changes, no matter how subtle are deliberate, tracked and understood.
This commit is contained in:
Hannah Wolfe 2022-01-21 12:36:07 +00:00
parent 12e8c974a1
commit 4c8ff38a44
No known key found for this signature in database
GPG key ID: AB586C3B5AE5C037
9 changed files with 59 additions and 196 deletions

View file

@ -9,6 +9,8 @@ const themeEngine = require('../../../core/frontend/services/theme-engine');
describe('Integration - Web - vhosts', function () {
let app;
const ADMIN_API_URL = '/ghost/api/canary/admin';
before(testUtils.teardownDb);
after(function () {
@ -100,7 +102,7 @@ describe('Integration - Web - vhosts', function () {
const req = {
secure: false,
method: 'GET',
url: '/ghost/api/v2/admin/site/',
url: `${ADMIN_API_URL}/site/`,
host: 'example.com'
};
@ -114,7 +116,7 @@ describe('Integration - Web - vhosts', function () {
const req = {
secure: false,
method: 'GET',
url: '/ghost/api/v2/admin/site/',
url: `${ADMIN_API_URL}/site/`,
host: 'localhost'
};
@ -135,7 +137,7 @@ describe('Integration - Web - vhosts', function () {
app = await localUtils.initGhost({backend: true});
sinon.stub(themeEngine.getActive(), 'engine').withArgs('ghost-api').returns('v2');
sinon.stub(themeEngine.getActive(), 'engine').withArgs('ghost-api').returns('canary');
sinon.stub(themeEngine.getActive(), 'config').withArgs('posts_per_page').returns(2);
});
@ -196,7 +198,7 @@ describe('Integration - Web - vhosts', function () {
const req = {
secure: false,
method: 'GET',
url: '/ghost/api/v2/admin/site/',
url: `${ADMIN_API_URL}/site/`,
host: 'example.com'
};
@ -210,7 +212,7 @@ describe('Integration - Web - vhosts', function () {
const req = {
secure: false,
method: 'GET',
url: '/ghost/api/v2/admin/site/',
url: `${ADMIN_API_URL}/site/`,
host: 'localhost'
};
@ -238,7 +240,7 @@ describe('Integration - Web - vhosts', function () {
const req = {
secure: true,
method: 'GET',
url: '/ghost/api/v2/admin/site/',
url: `${ADMIN_API_URL}/site/`,
host: 'admin.example.com'
};
@ -287,7 +289,7 @@ describe('Integration - Web - vhosts', function () {
configUtils.set('admin:url', 'https://admin.example.com');
configUtils.set('admin:redirects', false);
sinon.stub(themeEngine.getActive(), 'engine').withArgs('ghost-api').returns('v2');
sinon.stub(themeEngine.getActive(), 'engine').withArgs('ghost-api').returns('canary');
sinon.stub(themeEngine.getActive(), 'config').withArgs('posts_per_page').returns(2);
app = await localUtils.initGhost({backend: true});
@ -327,7 +329,7 @@ describe('Integration - Web - vhosts', function () {
configUtils.set('url', 'http://example.com');
configUtils.set('admin:url', 'https://example.com');
sinon.stub(themeEngine.getActive(), 'engine').withArgs('ghost-api').returns('v2');
sinon.stub(themeEngine.getActive(), 'engine').withArgs('ghost-api').returns('canary');
sinon.stub(themeEngine.getActive(), 'config').withArgs('posts_per_page').returns(2);
app = await localUtils.initGhost({backend: true});
@ -413,14 +415,14 @@ describe('Integration - Web - vhosts', function () {
const req = {
secure: false,
method: 'GET',
url: '/ghost/api/v2/admin/site/',
url: `${ADMIN_API_URL}/site/`,
host: 'example.com'
};
return localUtils.mockExpress.invoke(app, req)
.then(function (response) {
response.statusCode.should.eql(301);
response.headers.location.should.eql('https://example.com/ghost/api/v2/admin/site/');
response.headers.location.should.eql(`https://example.com${ADMIN_API_URL}/site/`);
});
});
@ -457,7 +459,7 @@ describe('Integration - Web - vhosts', function () {
const req = {
secure: true,
method: 'GET',
url: '/ghost/api/v2/admin/site/',
url: `${ADMIN_API_URL}/site/`,
host: 'example.com'
};
@ -471,14 +473,14 @@ describe('Integration - Web - vhosts', function () {
const req = {
secure: false,
method: 'GET',
url: '/ghost/api/v2/admin/site/',
url: `${ADMIN_API_URL}/site/`,
host: 'localhost'
};
return localUtils.mockExpress.invoke(app, req)
.then(function (response) {
response.statusCode.should.eql(301);
response.headers.location.should.eql('https://example.com/ghost/api/v2/admin/site/');
response.headers.location.should.eql(`https://example.com${ADMIN_API_URL}/site/`);
});
});
});

View file

@ -7,9 +7,13 @@ const {SafeString} = require('../../../../core/frontend/services/rendering');
const get = require('../../../../core/frontend/helpers/get');
const models = require('../../../../core/server/models');
const api = require('../../../../core/server/api');
const proxy = require('../../../../core/frontend/services/proxy');
const API_VERSION = 'canary';
const api = require('../../../../core/server/api')[API_VERSION];
describe('{{#get}} helper', function () {
let fn;
let inverse;
@ -23,7 +27,7 @@ describe('{{#get}} helper', function () {
fn = sinon.spy();
inverse = sinon.spy();
locals = {root: {_locals: {apiVersion: 'v2'}}, globalProp: {foo: 'bar'}};
locals = {root: {_locals: {apiVersion: API_VERSION}}, globalProp: {foo: 'bar'}};
});
afterEach(function () {
@ -37,7 +41,7 @@ describe('{{#get}} helper', function () {
beforeEach(function () {
locals = {root: {_locals: {apiVersion: 'canary'}}};
browsePostsStub = sinon.stub(api.canary, 'postsPublic').get(() => {
browsePostsStub = sinon.stub(api, 'postsPublic').get(() => {
return {
browse: sinon.stub().resolves({posts: [{feature_image_caption: '<a href="#">A link</a>'}], meta: meta})
};
@ -60,74 +64,14 @@ describe('{{#get}} helper', function () {
});
});
describe('authors v2', function () {
let browseAuthorsStub;
const meta = {pagination: {}};
beforeEach(function () {
locals = {root: {_locals: {apiVersion: 'v2'}}};
browseAuthorsStub = sinon.stub(api.v2, 'authorsPublic').get(() => {
return {
browse: sinon.stub().resolves({authors: [], meta: meta})
};
});
});
it('browse authors', function (done) {
get.call(
{},
'authors',
{hash: {}, data: locals, fn: fn, inverse: inverse}
).then(function () {
fn.called.should.be.true();
fn.firstCall.args[0].should.be.an.Object().with.property('authors');
fn.firstCall.args[0].authors.should.eql([]);
inverse.called.should.be.false();
done();
}).catch(done);
});
});
describe('authors canary', function () {
let browseAuthorsStub;
const meta = {pagination: {}};
beforeEach(function () {
locals = {root: {_locals: {apiVersion: 'canary'}}};
locals = {root: {_locals: {apiVersion: API_VERSION}}};
browseAuthorsStub = sinon.stub(api.canary, 'authorsPublic').get(() => {
return {
browse: sinon.stub().resolves({authors: [], meta: meta})
};
});
});
it('browse authors', function (done) {
get.call(
{},
'authors',
{hash: {}, data: locals, fn: fn, inverse: inverse}
).then(function () {
fn.called.should.be.true();
fn.firstCall.args[0].should.be.an.Object().with.property('authors');
fn.firstCall.args[0].authors.should.eql([]);
inverse.called.should.be.false();
done();
}).catch(done);
});
});
describe('authors v3', function () {
let browseAuthorsStub;
const meta = {pagination: {}};
beforeEach(function () {
locals = {root: {_locals: {apiVersion: 'v3'}}};
browseAuthorsStub = sinon.stub(api.v3, 'authorsPublic').get(() => {
browseAuthorsStub = sinon.stub(api, 'authorsPublic').get(() => {
return {
browse: sinon.stub().resolves({authors: [], meta: meta})
};
@ -209,7 +153,7 @@ describe('{{#get}} helper', function () {
beforeEach(function () {
browseStub = sinon.stub().resolves();
readStub = sinon.stub().resolves();
sinon.stub(api.v2, 'postsPublic').get(() => {
sinon.stub(api, 'postsPublic').get(() => {
return {
browse: browseStub,
read: readStub
@ -321,17 +265,8 @@ describe('{{#get}} helper', function () {
beforeEach(function () {
browseStub = sinon.stub().resolves();
sinon.stub(api.v2, 'postsPublic').get(() => {
return {
browse: browseStub
};
});
sinon.stub(api.v3, 'postsPublic').get(() => {
return {
browse: browseStub
};
});
sinon.stub(api.canary, 'postsPublic').get(() => {
sinon.stub(api, 'postsPublic').get(() => {
return {
browse: browseStub
};
@ -339,53 +274,25 @@ describe('{{#get}} helper', function () {
});
it('Behaves normally without config', async function () {
locals = {root: {_locals: {apiVersion: 'v2'}}};
locals = {root: {_locals: {apiVersion: API_VERSION}}};
await get.call(
{},
'posts',
{hash: {limit: 'all'}, data: locals, fn: fn, inverse: inverse}
);
browseStub.firstCall.args[0].limit.should.eql('all');
locals = {root: {_locals: {apiVersion: 'v3'}}};
await get.call(
{},
'posts',
{hash: {limit: 'all'}, data: locals, fn: fn, inverse: inverse}
);
browseStub.secondCall.args[0].limit.should.eql('all');
locals = {root: {_locals: {apiVersion: 'canary'}}};
await get.call(
{},
'posts',
{hash: {limit: 'all'}, data: locals, fn: fn, inverse: inverse}
);
browseStub.thirdCall.args[0].limit.should.eql('all');
});
it('Replaces "all" with "getHelperLimitAllMax" config, if present', async function () {
sinon.stub(proxy.config, 'get').withArgs('getHelperLimitAllMax').returns(2);
locals = {root: {_locals: {apiVersion: 'v2'}}};
locals = {root: {_locals: {apiVersion: API_VERSION}}};
await get.call(
{},
'posts',
{hash: {limit: 'all'}, data: locals, fn: fn, inverse: inverse}
);
browseStub.firstCall.args[0].limit.should.eql(2);
locals = {root: {_locals: {apiVersion: 'v3'}}};
await get.call(
{},
'posts',
{hash: {limit: 'all'}, data: locals, fn: fn, inverse: inverse}
);
browseStub.secondCall.args[0].limit.should.eql(2);
locals = {root: {_locals: {apiVersion: 'canary'}}};
await get.call(
{},
'posts',
{hash: {limit: 'all'}, data: locals, fn: fn, inverse: inverse}
);
browseStub.thirdCall.args[0].limit.should.eql(2);
});
});
});

View file

@ -287,7 +287,7 @@ describe('{{ghost_head}} helper', function () {
sinon.stub(routing.registry, 'getRssUrl').returns('http://localhost:65530/rss/');
sinon.stub(imageLib.imageSize, 'getImageSizeFromUrl').resolves();
sinon.stub(themeEngine, 'getActive').returns({
engine: () => 'v2'
engine: () => 'canary'
});
sinon.stub(settingsCache, 'get');

View file

@ -1,7 +1,8 @@
const should = require('should');
const sinon = require('sinon');
const testUtils = require('../../../../../utils');
const api = require('../../../../../../core/server/api');
const API_VERSION = 'canary';
const api = require('../../../../../../core/server/api')[API_VERSION];
const themeEngine = require('../../../../../../core/frontend/services/theme-engine');
const helpers = require('../../../../../../core/frontend/services/routing/helpers');
const controllers = require('../../../../../../core/frontend/services/routing/controllers');
@ -33,7 +34,7 @@ describe('Unit - services/routing/controllers/static', function () {
formatResponseStub.entries = sinon.stub();
tagsReadStub = sinon.stub().resolves();
sinon.stub(api.v2, 'tagsPublic').get(() => {
sinon.stub(api, 'tagsPublic').get(() => {
return {
read: tagsReadStub
};
@ -74,7 +75,7 @@ describe('Unit - services/routing/controllers/static', function () {
render: sinon.spy(),
redirect: sinon.spy(),
locals: {
apiVersion: 'v2'
apiVersion: API_VERSION
}
};
});

View file

@ -1,6 +1,7 @@
const should = require('should');
const sinon = require('sinon');
const api = require('../../../../../../core/server/api').v2;
const API_VERSION = 'canary';
const api = require('../../../../../../core/server/api')[API_VERSION];
const helpers = require('../../../../../../core/frontend/services/routing/helpers');
const testUtils = require('../../../../../utils');
@ -47,7 +48,7 @@ describe('Unit - services/routing/helpers/fetch-data', function () {
};
});
locals = {apiVersion: 'v2'};
locals = {apiVersion: API_VERSION};
});
afterEach(function () {

View file

@ -6,6 +6,8 @@ const apiKeyAuth = require('../../../../../../core/server/services/auth/api-key'
const models = require('../../../../../../core/server/models');
describe('Admin API Key Auth', function () {
const ADMIN_API_URL = '/ghost/api/canary/admin/';
before(models.init);
beforeEach(function () {
@ -29,31 +31,6 @@ describe('Admin API Key Auth', function () {
sinon.restore();
});
it('should authenticate known+valid v2 API key', function (done) {
const token = jwt.sign({
}, this.secret, {
keyid: this.fakeApiKey.id,
algorithm: 'HS256',
expiresIn: '5m',
audience: '/v2/admin/',
issuer: this.fakeApiKey.id
});
const req = {
originalUrl: '/ghost/api/v2/admin/',
headers: {
authorization: `Ghost ${token}`
}
};
const res = {};
apiKeyAuth.admin.authenticate(req, res, (err) => {
should.not.exist(err);
req.api_key.should.eql(this.fakeApiKey);
done();
});
});
it('should authenticate known+valid canary API key', function (done) {
const token = jwt.sign({
}, this.secret, {
@ -65,32 +42,7 @@ describe('Admin API Key Auth', function () {
});
const req = {
originalUrl: '/ghost/api/canary/admin/',
headers: {
authorization: `Ghost ${token}`
}
};
const res = {};
apiKeyAuth.admin.authenticate(req, res, (err) => {
should.not.exist(err);
req.api_key.should.eql(this.fakeApiKey);
done();
});
});
it('should authenticate known+valid v3 API key', function (done) {
const token = jwt.sign({
}, this.secret, {
keyid: this.fakeApiKey.id,
algorithm: 'HS256',
expiresIn: '5m',
audience: '/v3/admin/',
issuer: this.fakeApiKey.id
});
const req = {
originalUrl: '/ghost/api/v3/admin/',
originalUrl: ADMIN_API_URL,
headers: {
authorization: `Ghost ${token}`
}
@ -151,7 +103,7 @@ describe('Admin API Key Auth', function () {
});
const req = {
originalUrl: '/ghost/api/v2/admin/',
originalUrl: ADMIN_API_URL,
headers: {
authorization: `Ghost ${token}`
}
@ -175,12 +127,12 @@ describe('Admin API Key Auth', function () {
keyid: this.fakeApiKey.id,
algorithm: 'HS256',
expiresIn: '5m',
audience: '/v2/admin/',
audience: '/canary/admin/',
issuer: this.fakeApiKey.id
});
const req = {
originalUrl: '/ghost/api/v2/admin/',
originalUrl: ADMIN_API_URL,
headers: {
authorization: `Ghost ${token}`
}
@ -205,12 +157,12 @@ describe('Admin API Key Auth', function () {
keyid: this.fakeApiKey.id,
algorithm: 'HS256',
expiresIn: '10m',
audience: '/v2/admin/',
audience: '/canary/admin/',
issuer: this.fakeApiKey.id
});
const req = {
originalUrl: '/ghost/api/v2/admin/',
originalUrl: ADMIN_API_URL,
headers: {
authorization: `Ghost ${token}`
}
@ -233,12 +185,12 @@ describe('Admin API Key Auth', function () {
keyid: this.fakeApiKey.id,
algorithm: 'HS256',
expiresIn: '5m',
audience: '/v2/admin/',
audience: '/canary/admin/',
issuer: this.fakeApiKey.id
});
const req = {
originalUrl: '/ghost/api/v2/admin/',
originalUrl: ADMIN_API_URL,
headers: {
authorization: `Ghost ${token}`
}

View file

@ -47,13 +47,13 @@ function createUrlUtilsMock() {
getSiteUrl: configUtils.config.getSiteUrl,
getAdminUrl: configUtils.config.getAdminUrl,
apiVersions: {
all: ['v3'],
v3: {
admin: 'v3/admin',
content: 'v3/content'
all: ['canary'],
canary: {
admin: 'canary/admin',
content: 'canary/content'
}
},
defaultApiVersion: 'v3',
defaultApiVersion: 'canary',
slugs: ['ghost', 'rss', 'amp'],
redirectCacheMaxAge: 31536000,
baseApiPath: '/ghost/api'

View file

@ -48,13 +48,13 @@ function createUrlUtilsMock() {
getSiteUrl: configUtils.config.getSiteUrl,
getAdminUrl: configUtils.config.getAdminUrl,
apiVersions: {
all: ['v3'],
v3: {
admin: 'v3/admin',
content: 'v3/content'
all: ['canary'],
canary: {
admin: 'canary/admin',
content: 'canary/content'
}
},
defaultApiVersion: 'v3',
defaultApiVersion: 'canary',
slugs: ['ghost', 'rss', 'amp'],
redirectCacheMaxAge: 31536000,
baseApiPath: '/ghost/api'

View file

@ -16,7 +16,7 @@ describe('Theme Handler', function () {
sinon.stub(bridge, 'getActiveTheme').callsFake(() => {
return {
engine() {
return 'v3';
return 'canary';
}
};
});
@ -37,7 +37,7 @@ describe('Theme Handler', function () {
should.exist(res.locals.safeVersion);
should.exist(res.locals.apiVersion);
res.locals.relativeUrl.should.equal(req.path);
res.locals.apiVersion.should.equal('v3');
res.locals.apiVersion.should.equal('canary');
next.called.should.be.true();
});
});