diff --git a/core/server/api/canary/integrations.js b/core/server/api/canary/integrations.js index ca519b72cf..9f3c1093da 100644 --- a/core/server/api/canary/integrations.js +++ b/core/server/api/canary/integrations.js @@ -1,6 +1,12 @@ const i18n = require('../../../shared/i18n'); const errors = require('@tryghost/errors'); const models = require('../../models'); +const getIntegrationsServiceInstance = require('../../services/integrations/integrations-service'); + +const integrationsService = getIntegrationsServiceInstance({ + IntegrationModel: models.Integration, + ApiKeyModel: models.ApiKey +}); module.exports = { docName: 'integrations', @@ -76,36 +82,7 @@ module.exports = { } }, query({data, options}) { - if (options.keyid) { - return models.ApiKey.findOne({id: options.keyid}) - .then(async (model) => { - if (!model) { - throw new errors.NotFoundError({ - message: i18n.t('errors.api.resource.resourceNotFound', { - resource: 'ApiKey' - }) - }); - } - try { - await models.ApiKey.refreshSecret(model.toJSON(), Object.assign({}, options, {id: options.keyid})); - return models.Integration.findOne({id: options.id}, { - withRelated: ['api_keys', 'webhooks'] - }); - } catch (err) { - throw new errors.GhostError({ - err: err - }); - } - }); - } - return models.Integration.edit(data, Object.assign(options, {require: true})) - .catch(models.Integration.NotFoundError, () => { - throw new errors.NotFoundError({ - message: i18n.t('errors.api.resource.resourceNotFound', { - resource: 'Integration' - }) - }); - }); + return integrationsService.edit(data, options); } }, add: { diff --git a/core/server/api/v3/integrations.js b/core/server/api/v3/integrations.js index ca519b72cf..9f3c1093da 100644 --- a/core/server/api/v3/integrations.js +++ b/core/server/api/v3/integrations.js @@ -1,6 +1,12 @@ const i18n = require('../../../shared/i18n'); const errors = require('@tryghost/errors'); const models = require('../../models'); +const getIntegrationsServiceInstance = require('../../services/integrations/integrations-service'); + +const integrationsService = getIntegrationsServiceInstance({ + IntegrationModel: models.Integration, + ApiKeyModel: models.ApiKey +}); module.exports = { docName: 'integrations', @@ -76,36 +82,7 @@ module.exports = { } }, query({data, options}) { - if (options.keyid) { - return models.ApiKey.findOne({id: options.keyid}) - .then(async (model) => { - if (!model) { - throw new errors.NotFoundError({ - message: i18n.t('errors.api.resource.resourceNotFound', { - resource: 'ApiKey' - }) - }); - } - try { - await models.ApiKey.refreshSecret(model.toJSON(), Object.assign({}, options, {id: options.keyid})); - return models.Integration.findOne({id: options.id}, { - withRelated: ['api_keys', 'webhooks'] - }); - } catch (err) { - throw new errors.GhostError({ - err: err - }); - } - }); - } - return models.Integration.edit(data, Object.assign(options, {require: true})) - .catch(models.Integration.NotFoundError, () => { - throw new errors.NotFoundError({ - message: i18n.t('errors.api.resource.resourceNotFound', { - resource: 'Integration' - }) - }); - }); + return integrationsService.edit(data, options); } }, add: { diff --git a/core/server/services/integrations/integrations-service.js b/core/server/services/integrations/integrations-service.js new file mode 100644 index 0000000000..13aeaff005 --- /dev/null +++ b/core/server/services/integrations/integrations-service.js @@ -0,0 +1,61 @@ +const {NotFoundError, GhostError} = require('@tryghost/errors'); +const tpl = require('@tryghost/tpl'); + +const messages = { + notFound: '{resource} not found.' +}; + +class IntegrationsService { + constructor({IntegrationModel, ApiKeyModel}) { + this.IntegrationModel = IntegrationModel; + this.ApiKeyModel = ApiKeyModel; + } + + async edit(data, options) { + if (options.keyid) { + const model = await this.ApiKeyModel.findOne({id: options.keyid}); + + if (!model) { + throw new NotFoundError({ + message: tpl(messages.notFound, { + resource: 'ApiKey' + }) + }); + } + try { + await this.ApiKeyModel.refreshSecret(model.toJSON(), Object.assign({}, options, {id: options.keyid})); + + return await this.IntegrationModel.findOne({id: options.id}, { + withRelated: ['api_keys', 'webhooks'] + }); + } catch (err) { + throw new GhostError({ + err: err + }); + } + } + + try { + return await this.IntegrationModel.edit(data, Object.assign(options, {require: true})); + } catch (error) { + if (error.message === 'NotFound' || error.message === 'EmptyResponse') { + throw new NotFoundError({ + message: tpl(messages.notFound, { + resource: 'Integration' + }) + }); + } + + throw error; + } + } +} + +/** + * @returns {IntegrationsService} instance of the PostsService + */ +const getIntegrationsServiceInstance = ({IntegrationModel, ApiKeyModel}) => { + return new IntegrationsService({IntegrationModel, ApiKeyModel}); +}; + +module.exports = getIntegrationsServiceInstance; diff --git a/test/api-acceptance/admin/integrations.test.js b/test/api-acceptance/admin/integrations.test.js index 96f6134773..161c0078b4 100644 --- a/test/api-acceptance/admin/integrations.test.js +++ b/test/api-acceptance/admin/integrations.test.js @@ -331,5 +331,14 @@ describe('Integrations API', function () { await request.get(localUtils.API.getApiQuery(`integrations/${createdIntegration.id}/`)) .set('Origin', config.get('url')) .expect(404); + + const editRes = await request.put(localUtils.API.getApiQuery(`integrations/${createdIntegration.id}/`)) + .send({ + integrations: [createdIntegration] + }) + .set('Origin', config.get('url')) + .expect(404); + + editRes.body.errors[0].context.should.eql('Integration not found.'); }); });