From 77e4be6b81337bf2e8e82a215d466351e54ecd02 Mon Sep 17 00:00:00 2001 From: Aileen Nowak Date: Tue, 9 Aug 2022 11:15:30 +0100 Subject: [PATCH] Updated tests to incl. host limit cases for core integrations - added core and builtin integrations to test fixtures - allowed passing a custom api key id to generate JWT - updated admin key auth test to make successful request with a `core` integration, which doesn't work atm because relations are not returned --- .../test/e2e-api/admin/integrations.test.js | 5 ++- .../e2e-api/admin/key-authentication.test.js | 16 +++++++-- ghost/core/test/e2e-api/admin/utils.js | 6 ++-- .../content/key_authentication.test.js | 15 ++++++-- .../test/utils/fixtures/data-generator.js | 35 +++++++++++++++++-- 5 files changed, 65 insertions(+), 12 deletions(-) diff --git a/ghost/core/test/e2e-api/admin/integrations.test.js b/ghost/core/test/e2e-api/admin/integrations.test.js index 37cfd421f6..55f8d139f7 100644 --- a/ghost/core/test/e2e-api/admin/integrations.test.js +++ b/ghost/core/test/e2e-api/admin/integrations.test.js @@ -23,7 +23,7 @@ describe('Integrations API', function () { .expect('Cache-Control', testUtils.cacheRules.private) .expect(200); - should.equal(res.body.integrations.length, 3); + should.equal(res.body.integrations.length, 5); // there is no enforced order for integrations which makes order different on SQLite and MySQL const zapierIntegration = _.find(res.body.integrations, {name: 'Zapier'}); // from migrations @@ -31,6 +31,9 @@ describe('Integrations API', function () { const testIntegration = _.find(res.body.integrations, {name: 'Test Integration'}); // from fixtures should.exist(testIntegration); + + const exploreIntegration = _.find(res.body.integrations, {name: 'Test Core Integration'}); // from fixtures + should.exist(exploreIntegration); }); it('Can not read internal integration', async function () { diff --git a/ghost/core/test/e2e-api/admin/key-authentication.test.js b/ghost/core/test/e2e-api/admin/key-authentication.test.js index d872c8dec3..a6139e823d 100644 --- a/ghost/core/test/e2e-api/admin/key-authentication.test.js +++ b/ghost/core/test/e2e-api/admin/key-authentication.test.js @@ -85,16 +85,26 @@ describe('Admin API key authentication', function () { // NOTE: need to do a full reboot to reinitialize hostSettings await localUtils.startGhost(); + await testUtils.initFixtures('integrations'); await testUtils.initFixtures('api_keys'); - const response = await request.get(localUtils.API.getApiQuery('posts/')) + const firstResponse = await request.get(localUtils.API.getApiQuery('posts/')) .set('Authorization', `Ghost ${localUtils.getValidAdminToken('/admin/')}`) .expect('Content-Type', /json/) .expect('Cache-Control', testUtils.cacheRules.private) .expect(403); - response.body.errors[0].type.should.equal('HostLimitError'); - response.body.errors[0].message.should.equal('Custom limit error message'); + firstResponse.body.errors[0].type.should.equal('HostLimitError'); + firstResponse.body.errors[0].message.should.equal('Custom limit error message'); + + // CASE: Test with a different API key, related to a core integration + const secondResponse = await request.get(localUtils.API.getApiQuery('explore/')) + .set('Authorization', `Ghost ${localUtils.getValidAdminToken('/admin/', 4)}`) + .expect('Content-Type', /json/) + .expect('Cache-Control', testUtils.cacheRules.private) + .expect(200); + + should.exist(secondResponse.body.explore); }); }); }); diff --git a/ghost/core/test/e2e-api/admin/utils.js b/ghost/core/test/e2e-api/admin/utils.js index 3778737eec..a736d28e75 100644 --- a/ghost/core/test/e2e-api/admin/utils.js +++ b/ghost/core/test/e2e-api/admin/utils.js @@ -219,10 +219,10 @@ module.exports = { return testUtils.API.doAuth(`${API_URL}session/`, ...args); }, - getValidAdminToken(audience) { + getValidAdminToken(audience, keyid = 0) { const jwt = require('jsonwebtoken'); const JWT_OPTIONS = { - keyid: testUtils.DataGenerator.Content.api_keys[0].id, + keyid: testUtils.DataGenerator.Content.api_keys[keyid].id, algorithm: 'HS256', expiresIn: '5m', audience: audience @@ -230,7 +230,7 @@ module.exports = { return jwt.sign( {}, - Buffer.from(testUtils.DataGenerator.Content.api_keys[0].secret, 'hex'), + Buffer.from(testUtils.DataGenerator.Content.api_keys[keyid].secret, 'hex'), JWT_OPTIONS ); }, diff --git a/ghost/core/test/e2e-api/content/key_authentication.test.js b/ghost/core/test/e2e-api/content/key_authentication.test.js index 27c1217c07..9fb9e8a3b0 100644 --- a/ghost/core/test/e2e-api/content/key_authentication.test.js +++ b/ghost/core/test/e2e-api/content/key_authentication.test.js @@ -45,17 +45,26 @@ describe('Content API key authentication', function () { // NOTE: need to do a full reboot to reinitialize hostSettings await localUtils.startGhost(); + await testUtils.initFixtures('integrations'); await testUtils.initFixtures('api_keys'); const key = localUtils.getValidKey(); - const response = await request.get(localUtils.API.getApiQuery(`posts/?key=${key}`)) + const firstResponse = await request.get(localUtils.API.getApiQuery(`posts/?key=${key}`)) .expect('Content-Type', /json/) .expect('Cache-Control', testUtils.cacheRules.private) .expect(403); - response.body.errors[0].type.should.equal('HostLimitError'); - response.body.errors[0].message.should.equal('Custom limit error message'); + firstResponse.body.errors[0].type.should.equal('HostLimitError'); + firstResponse.body.errors[0].message.should.equal('Custom limit error message'); + + // CASE: explore endpoint can only be reached by Admin API + const secondResponse = await request.get(localUtils.API.getApiQuery('explore/')) + .expect('Content-Type', /json/) + .expect('Cache-Control', testUtils.cacheRules.private) + .expect(404); + + secondResponse.body.errors[0].type.should.equal('NotFoundError'); }); }); }); diff --git a/ghost/core/test/utils/fixtures/data-generator.js b/ghost/core/test/utils/fixtures/data-generator.js index 025d9b8b0b..2885741980 100644 --- a/ghost/core/test/utils/fixtures/data-generator.js +++ b/ghost/core/test/utils/fixtures/data-generator.js @@ -651,6 +651,18 @@ DataGenerator.Content = { name: 'Test Internal Integration', slug: 'test-internal-integration', type: 'internal' + }, + { + id: ObjectId().toHexString(), + name: 'Test Builtin Integration', + slug: 'test-builtin-integration', + type: 'builtin' + }, + { + id: ObjectId().toHexString(), + name: 'Test Core Integration', + slug: 'test-core-integration', + type: 'core' } ], @@ -670,7 +682,20 @@ DataGenerator.Content = { { id: ObjectId().toHexString(), type: 'admin', + secret: _.repeat('b', 64), integration_id: undefined // "internal" + }, + { + id: ObjectId().toHexString(), + type: 'admin', + secret: _.repeat('d', 26), + integration_id: undefined // "builtin" + }, + { + id: ObjectId().toHexString(), + type: 'admin', + secret: _.repeat('e', 64), + integration_id: undefined // "core" } ], @@ -800,6 +825,8 @@ DataGenerator.Content = { // set up belongs_to relationships DataGenerator.Content.api_keys[0].integration_id = DataGenerator.Content.integrations[0].id; DataGenerator.Content.api_keys[1].integration_id = DataGenerator.Content.integrations[0].id; +DataGenerator.Content.api_keys[3].integration_id = DataGenerator.Content.integrations[2].id; +DataGenerator.Content.api_keys[4].integration_id = DataGenerator.Content.integrations[3].id; DataGenerator.Content.webhooks[0].integration_id = DataGenerator.Content.integrations[0].id; DataGenerator.Content.webhooks[1].integration_id = DataGenerator.Content.integrations[0].id; DataGenerator.Content.emails[0].post_id = DataGenerator.Content.posts[0].id; @@ -1464,13 +1491,17 @@ DataGenerator.forKnex = (function () { const integrations = [ createBasic(DataGenerator.Content.integrations[0]), - createBasic(DataGenerator.Content.integrations[1]) + createBasic(DataGenerator.Content.integrations[1]), + createBasic(DataGenerator.Content.integrations[2]), + createBasic(DataGenerator.Content.integrations[3]) ]; const api_keys = [ createBasic(DataGenerator.Content.api_keys[0]), createBasic(DataGenerator.Content.api_keys[1]), - createBasic(DataGenerator.Content.api_keys[2]) + createBasic(DataGenerator.Content.api_keys[2]), + createBasic(DataGenerator.Content.api_keys[3]), + createBasic(DataGenerator.Content.api_keys[4]) ]; const emails = [