From 2ca230c11645765e2367556e72087b1393eb2945 Mon Sep 17 00:00:00 2001 From: Railag Date: Wed, 26 Dec 2018 16:05:25 +0300 Subject: [PATCH] test(core) unit tests for catalog service (EWC-383) --- src/services/catalog-service.js | 194 ++-- src/services/connector-service.js | 1 - src/services/email-activation-code-service.js | 3 - test/src/services/catalog-service.test.js | 906 ++++++++++++++++++ 4 files changed, 999 insertions(+), 105 deletions(-) create mode 100644 test/src/services/catalog-service.test.js diff --git a/src/services/catalog-service.js b/src/services/catalog-service.js index 1fc265605..18274a980 100644 --- a/src/services/catalog-service.js +++ b/src/services/catalog-service.js @@ -20,11 +20,11 @@ const CatalogItemImageManager = require('../sequelize/managers/catalog-item-imag const CatalogItemInputTypeManager = require('../sequelize/managers/catalog-item-input-type-manager'); const CatalogItemOutputTypeManager = require('../sequelize/managers/catalog-item-output-type-manager'); const Op = require('sequelize').Op; -const validator = require('../schemas/index'); +const Validator = require('../schemas/index'); const RegistryManager = require('../sequelize/managers/registry-manager'); const createCatalogItem = async function (data, user, transaction) { - await validator.validate(data, validator.schemas.catalogItemCreate); + await Validator.validate(data, Validator.schemas.catalogItemCreate); await _checkForDuplicateName(data.name, {userId: user.id}, transaction); await _checkForRestrictedPublisher(data.publisher); const catalogItem = await _createCatalogItem(data, user, transaction); @@ -38,7 +38,7 @@ const createCatalogItem = async function (data, user, transaction) { }; const updateCatalogItem = async function (id, data, user, isCLI, transaction) { - await validator.validate(data, validator.schemas.catalogItemUpdate); + await Validator.validate(data, Validator.schemas.catalogItemUpdate); const where = isCLI ? {id: id} @@ -50,76 +50,6 @@ const updateCatalogItem = async function (id, data, user, isCLI, transaction) { await _updateCatalogItemIOTypes(data, where, transaction); }; -const _updateCatalogItem = async function (data, where, transaction) { - let catalogItem = { - name: data.name, - description: data.description, - category: data.category, - configExample: data.configExample, - publisher: data.publisher, - diskRequired: data.diskRequired, - ramRequired: data.ramRequired, - picture: data.picture, - isPublic: data.isPublic, - registryId: data.registryId - }; - - catalogItem = AppHelper.deleteUndefinedFields(catalogItem); - if (!catalogItem || AppHelper.isEmpty(catalogItem)) { - return - } - const registry = await RegistryManager.findOne({id: data.registryId}, transaction); - if (!registry) { - throw new Errors.NotFoundError(AppHelper.formatMessage(ErrorMessages.INVALID_REGISTRY_ID, data.registryId)); - } - - const item = await _checkIfItemExists(where, transaction); - await _checkForDuplicateName(data.name, item, transaction); - await CatalogItemManager.update(where, catalogItem, transaction); -}; - -const _updateCatalogItemImages = async function (data, transaction) { - if (data.images) { - for (let image of data.images) { - switch (image.fogTypeId) { - case 1: - await CatalogItemImageManager.updateOrCreate({ - catalogItemId: data.id, - fogTypeId: 1 - }, image, transaction); - break; - case 2: - await CatalogItemImageManager.updateOrCreate({ - catalogItemId: data.id, - fogTypeId: 2 - }, image, transaction); - break; - } - } - } -}; - -const _updateCatalogItemIOTypes = async function (data, where, transaction) { - if (data.inputType && data.inputType.length != 0) { - let inputType = { - catalogItemId: data.id, - infoType: data.inputType.infoType, - infoFormat: data.inputType.infoFormat - }; - inputType = AppHelper.deleteUndefinedFields(inputType); - await CatalogItemInputTypeManager.updateOrCreate({catalogItemId: data.id}, inputType, transaction); - } - if (data.outputType && data.outputType.length !== 0) { - let outputType = { - catalogItemId: data.id, - infoType: data.outputType.infoType, - infoFormat: data.outputType.infoFormat - }; - outputType = AppHelper.deleteUndefinedFields(outputType); - await CatalogItemOutputTypeManager.updateOrCreate({catalogItemId: data.id}, outputType, transaction); - } -}; - const listCatalogItems = async function (user, isCLI, transaction) { const where = isCLI ? {category: {[Op.ne]: 'SYSTEM'}} @@ -162,6 +92,37 @@ const deleteCatalogItem = async function (id, user, isCLI, transaction) { return affectedRows; }; +async function getNetworkCatalogItem(transaction) { + return await CatalogItemManager.findOne({ + name: 'Networking Tool', + category: 'SYSTEM', + publisher: 'Eclipse ioFog', + registry_id: 1, + user_id: null + }, transaction) +} + +async function getBluetoothCatalogItem(transaction) { + return await CatalogItemManager.findOne({ + name: 'RESTBlue', + category: 'SYSTEM', + publisher: 'Eclipse ioFog', + registry_id: 1, + user_id: null + }, transaction) +} + +async function getHalCatalogItem(transaction) { + return await CatalogItemManager.findOne({ + name: 'HAL', + category: 'SYSTEM', + publisher: 'Eclipse ioFog', + registry_id: 1, + user_id: null + }, transaction) +} + + const _checkForDuplicateName = async function (name, item, transaction) { if (name) { const where = item.id @@ -175,7 +136,7 @@ const _checkForDuplicateName = async function (name, item, transaction) { } }; -const _checkForRestrictedPublisher = async function(publisher) { +const _checkForRestrictedPublisher = async function (publisher) { if (publisher === 'Eclipse ioFog') { throw new Errors.ValidationError(ErrorMessages.RESTRICTED_PUBLISHER); } @@ -267,35 +228,66 @@ const _createCatalogItemOutputType = async function (data, catalogItem, transact return await CatalogItemOutputTypeManager.create(catalogItemOutputType, transaction); }; -async function getNetworkCatalogItem(transaction) { - return await CatalogItemManager.findOne({ - name: 'Networking Tool', - category: 'SYSTEM', - publisher: 'Eclipse ioFog', - registry_id: 1, - user_id: null - }, transaction) -} -async function getBluetoothCatalogItem(transaction) { - return await CatalogItemManager.findOne({ - name: 'RESTBlue', - category: 'SYSTEM', - publisher: 'Eclipse ioFog', - registry_id: 1, - user_id: null - }, transaction) -} +const _updateCatalogItem = async function (data, where, transaction) { + let catalogItem = { + name: data.name, + description: data.description, + category: data.category, + configExample: data.configExample, + publisher: data.publisher, + diskRequired: data.diskRequired, + ramRequired: data.ramRequired, + picture: data.picture, + isPublic: data.isPublic, + registryId: data.registryId + }; -async function getHalCatalogItem(transaction) { - return await CatalogItemManager.findOne({ - name: 'HAL', - category: 'SYSTEM', - publisher: 'Eclipse ioFog', - registry_id: 1, - user_id: null - }, transaction) -} + catalogItem = AppHelper.deleteUndefinedFields(catalogItem); + if (!catalogItem || AppHelper.isEmpty(catalogItem)) { + return + } + const registry = await RegistryManager.findOne({id: data.registryId}, transaction); + if (!registry) { + throw new Errors.NotFoundError(AppHelper.formatMessage(ErrorMessages.INVALID_REGISTRY_ID, data.registryId)); + } + + const item = await _checkIfItemExists(where, transaction); + await _checkForDuplicateName(data.name, item, transaction); + await CatalogItemManager.update(where, catalogItem, transaction); +}; + +const _updateCatalogItemImages = async function (data, transaction) { + if (data.images) { + for (const image of data.images) { + await CatalogItemImageManager.updateOrCreate({ + catalogItemId: data.id, + fogTypeId: image.fogTypeId + }, image, transaction); + } + } +}; + +const _updateCatalogItemIOTypes = async function (data, where, transaction) { + if (data.inputType && data.inputType.length !== 0) { + let inputType = { + catalogItemId: data.id, + infoType: data.inputType.infoType, + infoFormat: data.inputType.infoFormat + }; + inputType = AppHelper.deleteUndefinedFields(inputType); + await CatalogItemInputTypeManager.updateOrCreate({catalogItemId: data.id}, inputType, transaction); + } + if (data.outputType && data.outputType.length !== 0) { + let outputType = { + catalogItemId: data.id, + infoType: data.outputType.infoType, + infoFormat: data.outputType.infoFormat + }; + outputType = AppHelper.deleteUndefinedFields(outputType); + await CatalogItemOutputTypeManager.updateOrCreate({catalogItemId: data.id}, outputType, transaction); + } +}; module.exports = { createCatalogItem: TransactionDecorator.generateTransaction(createCatalogItem), diff --git a/src/services/connector-service.js b/src/services/connector-service.js index 2f1ceab98..787c97ab7 100644 --- a/src/services/connector-service.js +++ b/src/services/connector-service.js @@ -23,7 +23,6 @@ const constants = require('../helpers/constants'); const logger = require('../logger'); const qs = require('qs'); const Op = require('sequelize').Op; -const Sequelize = require('sequelize'); const fs = require('fs'); const ConnectorPortManager = require('../sequelize/managers/connector-port-manager'); diff --git a/src/services/email-activation-code-service.js b/src/services/email-activation-code-service.js index d842ff168..1e63963d8 100644 --- a/src/services/email-activation-code-service.js +++ b/src/services/email-activation-code-service.js @@ -11,9 +11,6 @@ * */ -const async = require('async'); -const logger = require('../logger'); - const EmailActivationCodeManager = require('../sequelize/managers/email-activation-code-manager'); const AppHelper = require('../helpers/app-helper'); const ErrorMessages = require('../helpers/error-messages'); diff --git a/test/src/services/catalog-service.test.js b/test/src/services/catalog-service.test.js new file mode 100644 index 000000000..12aa23567 --- /dev/null +++ b/test/src/services/catalog-service.test.js @@ -0,0 +1,906 @@ +const {expect} = require('chai'); +const sinon = require('sinon'); + +const CatalogItemManager = require('../../../src/sequelize/managers/catalog-item-manager'); +const CatalogService = require('../../../src/services/catalog-service'); +const Validator = require('../../../src/schemas'); +const CatalogItemImageManager = require('../../../src/sequelize/managers/catalog-item-image-manager'); +const CatalogItemInputTypeManager = require('../../../src/sequelize/managers/catalog-item-input-type-manager'); +const CatalogItemOutputTypeManager = require('../../../src/sequelize/managers/catalog-item-output-type-manager'); +const RegistryManager = require('../../../src/sequelize/managers/registry-manager'); +const AppHelper = require('../../../src/helpers/app-helper'); +const Sequelize = require('sequelize'); +const Op = Sequelize.Op; + +describe('Catalog Service', () => { + def('subject', () => CatalogService); + def('sandbox', () => sinon.createSandbox()); + + afterEach(() => $sandbox.restore()); + + describe('.createCatalogItem()', () => { + const transaction = {}; + const error = 'Error!'; + + const user = { + id: 15 + }; + + const data = { + "name": "testName", + "description": "string", + "category": "string", + "images": [ + { + "containerImage": "x86 docker image name", + "fogTypeId": 1 + }, + { + "containerImage": "ARM docker image name", + "fogTypeId": 2 + } + ], + "publisher": "string", + "diskRequired": 0, + "ramRequired": 0, + "picture": "string", + "isPublic": true, + "registryId": 1, + "inputType": { + "infoType": "string", + "infoFormat": "string" + }, + "outputType": { + "infoType": "string", + "infoFormat": "string" + }, + "configExample": "string" + }; + + let catalogItem = { + name: data.name, + description: data.description, + category: data.category, + configExample: data.configExample, + publisher: data.publisher, + diskRequired: data.diskRequired, + ramRequired: data.ramRequired, + picture: data.picture, + isPublic: data.isPublic, + registryId: data.registryId, + userId: user.id + }; + + const catalogItemImages = [ + { + fogTypeId: 1, + catalogItemId: catalogItem.id + }, + { + fogTypeId: 2, + catalogItemId: catalogItem.id + } + ]; + if (data.images) { + for (let image of data.images) { + switch (image.fogTypeId) { + case 1: + catalogItemImages[0].containerImage = image.containerImage; + break; + case 2: + catalogItemImages[1].containerImage = image.containerImage; + break; + } + } + } + + let catalogItemInputType = { + catalogItemId: catalogItem.id + }; + + if (data.inputType) { + catalogItemInputType.infoType = data.inputType.infoType; + catalogItemInputType.infoFormat = data.inputType.infoFormat; + } + + let catalogItemOutputType = { + catalogItemId: catalogItem.id + }; + + if (data.outputType) { + catalogItemOutputType.infoType = data.outputType.infoType; + catalogItemOutputType.infoFormat = data.outputType.infoFormat; + } + + def('subject', () => $subject.createCatalogItem(data, user, transaction)); + + def('validatorResponse', () => Promise.resolve(true)); + def('catalogItemFindResponse', () => Promise.resolve()); + def('deleteUndefinedFieldsResponse1', () => catalogItem); + def('deleteUndefinedFieldsResponse2', () => catalogItemInputType); + def('deleteUndefinedFieldsResponse3', () => catalogItemOutputType); + def('catalogItemCreateResponse', () => Promise.resolve(catalogItem)); + def('catalogItemImageCreateResponse', () => Promise.resolve()); + def('catalogItemInputTypeCreateResponse', () => Promise.resolve()); + def('catalogItemOutputTypeCreateResponse', () => Promise.resolve({})); + + + beforeEach(() => { + $sandbox.stub(Validator, 'validate').returns($validatorResponse); + $sandbox.stub(CatalogItemManager, 'findOne').returns($catalogItemFindResponse); + $sandbox.stub(AppHelper, 'deleteUndefinedFields') + .onFirstCall().returns($deleteUndefinedFieldsResponse1) + .onSecondCall().returns($deleteUndefinedFieldsResponse2) + .onThirdCall().returns($deleteUndefinedFieldsResponse3); + $sandbox.stub(CatalogItemManager, 'create').returns($catalogItemCreateResponse); + $sandbox.stub(CatalogItemImageManager, 'bulkCreate').returns($catalogItemImageCreateResponse); + $sandbox.stub(CatalogItemInputTypeManager, 'create').returns($catalogItemInputTypeCreateResponse); + $sandbox.stub(CatalogItemOutputTypeManager, 'create').returns($catalogItemOutputTypeCreateResponse); + }); + + it('calls Validator#validate() with correct args', async () => { + await $subject; + expect(Validator.validate).to.have.been.calledWith(data, Validator.schemas.catalogItemCreate); + }); + + context('when Validator#validate() fails', () => { + def('validatorResponse', () => Promise.reject(error)); + + it(`fails with ${error}`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when Validator#validate() succeeds', () => { + it('calls CatalogItemManager#findOne() with correct args', async () => { + await $subject; + const where = catalogItem.id + ? {[Op.or]: [{userId: catalogItem.userId}, {userId: null}], name: data.name, id: {[Op.ne]: catalogItem.id}} + : {[Op.or]: [{userId: catalogItem.userId}, {userId: null}], name: data.name}; + expect(CatalogItemManager.findOne).to.have.been.calledWith(where, transaction); + }); + + context('when CatalogItemManager#findOne() fails', () => { + def('catalogItemFindResponse', () => Promise.reject(error)); + + it(`fails with ${error}`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when CatalogItemManager#findOne() succeeds', () => { + it('calls AppHelper#deleteUndefinedFields() with correct args', async () => { + await $subject; + expect(AppHelper.deleteUndefinedFields).to.have.been.calledWith(catalogItem); + }); + + context('when AppHelper#deleteUndefinedFields() fails', () => { + def('deleteUndefinedFieldsResponse1', () => error); + + it(`fails with ${error}`, () => { + return expect($subject).to.eventually.have.property('id') + }) + }); + + context('when AppHelper#deleteUndefinedFields() succeeds', () => { + it('calls CatalogItemManager#create() with correct args', async () => { + await $subject; + expect(CatalogItemManager.create).to.have.been.calledWith(catalogItem, transaction); + }); + + context('when CatalogItemManager#create() fails', () => { + def('catalogItemCreateResponse', () => Promise.reject(error)); + + it(`fails with ${error}`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when CatalogItemManager#create() succeeds', () => { + it('calls CatalogItemImageManager#bulkCreate() with correct args', async () => { + await $subject; + expect(CatalogItemImageManager.bulkCreate).to.have.been.calledWith(catalogItemImages, transaction); + }); + + context('when CatalogItemImageManager#bulkCreate() fails', () => { + def('catalogItemImageCreateResponse', () => Promise.reject(error)); + + it(`fails with ${error}`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when CatalogItemImageManager#bulkCreate() succeeds', () => { + it('calls AppHelper#deleteUndefinedFields() with correct args', async () => { + await $subject; + expect(AppHelper.deleteUndefinedFields).to.have.been.calledWith(catalogItemInputType); + }); + + context('when AppHelper#deleteUndefinedFields() fails', () => { + def('deleteUndefinedFieldsResponse2', () => error); + + it(`fails with ${error}`, () => { + return expect($subject).to.eventually.have.property('id') + }) + }); + + context('when AppHelper#deleteUndefinedFields() succeeds', () => { + it('calls CatalogItemInputTypeManager#create() with correct args', async () => { + await $subject; + expect(CatalogItemInputTypeManager.create).to.have.been.calledWith(catalogItemInputType); + }); + + context('when CatalogItemInputTypeManager#create() fails', () => { + def('catalogItemInputTypeCreateResponse', () => Promise.reject(error)); + + it(`fails with ${error}`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when CatalogItemInputTypeManager#create() succeeds', () => { + it('calls AppHelper#deleteUndefinedFields() with correct args', async () => { + await $subject; + expect(AppHelper.deleteUndefinedFields).to.have.been.calledWith(catalogItemOutputType); + }); + + context('when AppHelper#deleteUndefinedFields() fails', () => { + def('deleteUndefinedFieldsResponse3', () => error); + + it(`fails with ${error}`, () => { + return expect($subject).to.eventually.have.property('id') + }) + }); + + context('when AppHelper#deleteUndefinedFields() succeeds', () => { + it('calls CatalogItemOutputTypeManager#create() with correct args', async () => { + await $subject; + expect(CatalogItemOutputTypeManager.create).to.have.been.calledWith(catalogItemOutputType); + }); + + context('when CatalogItemOutputTypeManager#create() fails', () => { + def('catalogItemOutputTypeCreateResponse', () => Promise.reject(error)); + + it(`fails with ${error}`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when CatalogItemOutputTypeManager#create() succeeds', () => { + it('succeeds', () => { + return expect($subject).to.eventually.have.property('id') + }) + }) + }) + }) + }) + }) + }) + }) + }) + }) + }); + + describe('.updateCatalogItem()', () => { + const transaction = {}; + const error = 'Error!'; + + const user = { + id: 15 + }; + + const id = 25; + + const data = { + "name": "string", + "description": "string", + "category": "string", + "images": [ + { + "containerImage": "x86 docker image name", + "fogTypeId": 1 + }, + { + "containerImage": "ARM docker image name", + "fogTypeId": 2 + } + ], + "publisher": "string", + "diskRequired": 0, + "ramRequired": 0, + "picture": "string", + "isPublic": true, + "registryId": 1, + "inputType": { + "infoType": "string", + "infoFormat": "string" + }, + "outputType": { + "infoType": "string", + "infoFormat": "string" + }, + "configExample": "string" + }; + + const isCLI = false; + const where = isCLI + ? {id: id} + : {id: id, userId: user.id}; + + data.id = id; + + + let catalogItem = { + name: data.name, + description: data.description, + category: data.category, + configExample: data.configExample, + publisher: data.publisher, + diskRequired: data.diskRequired, + ramRequired: data.ramRequired, + picture: data.picture, + isPublic: data.isPublic, + registryId: data.registryId + }; + + const image1 = { + fogTypeId: 1, + catalogItemId: id + }; + const image2 = { + fogTypeId: 2, + catalogItemId: id + }; + const catalogItemImages = [ + image1, image2 + ]; + + if (data.images) { + for (let image of data.images) { + switch (image.fogTypeId) { + case 1: + catalogItemImages[0].containerImage = image.containerImage; + break; + case 2: + catalogItemImages[1].containerImage = image.containerImage; + break; + } + } + } + + const updatedImage1 = { + fogTypeId: 1, + containerImage: "x86 docker image name", + }; + + const updatedImage2 = { + fogTypeId: 2, + containerImage: "ARM docker image name", + }; + + let catalogItemInputType = { + catalogItemId: id + }; + + if (data.inputType) { + catalogItemInputType.infoType = data.inputType.infoType; + catalogItemInputType.infoFormat = data.inputType.infoFormat; + } + + let catalogItemOutputType = { + catalogItemId: id + }; + + if (data.outputType) { + catalogItemOutputType.infoType = data.outputType.infoType; + catalogItemOutputType.infoFormat = data.outputType.infoFormat; + } + + def('subject', () => $subject.updateCatalogItem(id, data, user, isCLI, transaction)); + + def('validatorResponse', () => Promise.resolve(true)); + def('deleteUndefinedFieldsResponse1', () => catalogItem); + def('deleteUndefinedFieldsResponse2', () => catalogItemInputType); + def('deleteUndefinedFieldsResponse3', () => catalogItemOutputType); + def('isEmptyResponse', () => false); + def('registryFindResponse', () => Promise.resolve({})); + def('catalogItemFindResponse1', () => Promise.resolve(catalogItem)); + def('catalogItemFindResponse2', () => Promise.resolve()); + def('catalogItemUpdateResponse', () => Promise.resolve()); + def('catalogItemImageUpdateOrCreateResponse', () => Promise.resolve()); + def('catalogItemInputTypeUpdateOrCreateResponse', () => Promise.resolve()); + def('catalogItemOutputTypeUpdateOrCreateResponse', () => Promise.resolve({})); + + + beforeEach(() => { + $sandbox.stub(Validator, 'validate').returns($validatorResponse); + $sandbox.stub(AppHelper, 'deleteUndefinedFields') + .onFirstCall().returns($deleteUndefinedFieldsResponse1) + .onSecondCall().returns($deleteUndefinedFieldsResponse2) + .onThirdCall().returns($deleteUndefinedFieldsResponse3); + $sandbox.stub(AppHelper, 'isEmpty').returns($isEmptyResponse); + $sandbox.stub(RegistryManager, 'findOne').returns($registryFindResponse); + $sandbox.stub(CatalogItemManager, 'findOne') + .onCall(0).returns($catalogItemFindResponse1) + .onCall(1).returns($catalogItemFindResponse2) + .onCall(2).returns($catalogItemFindResponse1) + .onCall(3).returns($catalogItemFindResponse2); + $sandbox.stub(CatalogItemManager, 'update').returns($catalogItemUpdateResponse); + $sandbox.stub(CatalogItemImageManager, 'updateOrCreate').returns($catalogItemImageUpdateOrCreateResponse); // twice + $sandbox.stub(CatalogItemInputTypeManager, 'updateOrCreate').returns($catalogItemInputTypeUpdateOrCreateResponse); + $sandbox.stub(CatalogItemOutputTypeManager, 'updateOrCreate').returns($catalogItemOutputTypeUpdateOrCreateResponse); + }); + + it('calls Validator#validate() with correct args', async () => { + await $subject; + expect(Validator.validate).to.have.been.calledWith(data, Validator.schemas.catalogItemUpdate); + }); + + context('when Validator#validate() fails', () => { + def('validatorResponse', () => Promise.reject(error)); + + it(`fails with ${error}`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when Validator#validate() succeeds', () => { + it('calls AppHelper#deleteUndefinedFields() with correct args', async () => { + await $subject; + expect(AppHelper.deleteUndefinedFields).to.have.been.calledWith(catalogItem); + }); + + context('when AppHelper#deleteUndefinedFields() fails', () => { + def('deleteUndefinedFieldsResponse1', () => error); + + it(`fails with ${error}`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }); + + context('when AppHelper#deleteUndefinedFields() succeeds', () => { + it('calls AppHelper#isEmpty() with correct args', async () => { + await $subject; + expect(AppHelper.isEmpty).to.have.been.calledWith(catalogItem); + }); + + context('when AppHelper#isEmpty() fails', () => { + def('isEmptyResponse', () => error); + + it(`fails with ${error}`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }); + + context('when AppHelper#isEmpty() succeeds', () => { + it('calls RegistryManager#findOne() with correct args', async () => { + await $subject; + expect(RegistryManager.findOne).to.have.been.calledWith({ + id: data.registryId + }, transaction) + }); + + context('when RegistryManager#findOne() fails', () => { + def('registryFindResponse', () => Promise.reject(error)); + + it(`fails with ${error}`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when RegistryManager#findOne() succeeds', () => { + it('calls CatalogItemManager#findOne() with correct args', async () => { + await $subject; + const whereFind = catalogItem.id + ? { + [Op.or]: [{userId: catalogItem.userId}, {userId: null}], + name: data.name, + id: {[Op.ne]: catalogItem.id} + } + : {[Op.or]: [{userId: catalogItem.userId}, {userId: null}], name: data.name}; + expect(CatalogItemManager.findOne).to.have.been.calledWith(whereFind, transaction); + }); + + context('when CatalogItemManager#findOne() succeeds', () => { + it('calls CatalogItemManager#findOne() with correct args', async () => { + await $subject; + const whereFind = catalogItem.id + ? { + [Op.or]: [{userId: catalogItem.userId}, {userId: null}], + name: data.name, + id: {[Op.ne]: catalogItem.id} + } + : {[Op.or]: [{userId: catalogItem.userId}, {userId: null}], name: data.name}; + expect(CatalogItemManager.findOne).to.have.been.calledWith(whereFind, transaction); + }); + + context('when CatalogItemManager#findOne() succeeds', () => { + it('calls CatalogItemManager#update() with correct args', async () => { + await $subject; + expect(CatalogItemManager.update).to.have.been.calledWith(where, catalogItem, transaction); + }); + + context('when CatalogItemManager#update() fails', () => { + def('catalogItemUpdateResponse', () => Promise.reject(error)); + + it(`fails with ${error}`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when CatalogItemManager#update() succeeds', () => { + it('calls CatalogItemImageManager#updateOrCreate() with correct args', async () => { + await $subject; + expect(CatalogItemImageManager.updateOrCreate).to.have.been.calledWith({ + catalogItemId: data.id, + fogTypeId: image1.fogTypeId + }, updatedImage1, transaction); + }); + + context('when CatalogItemImageManager#updateOrCreate() fails', () => { + def('catalogItemImageUpdateOrCreateResponse', () => error); + + it(`fails with ${error}`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }); + + context('when CatalogItemImageManager#updateOrCreate() succeeds', () => { + it('calls CatalogItemImageManager#updateOrCreate() with correct args', async () => { + await $subject; + expect(CatalogItemImageManager.updateOrCreate).to.have.been.calledWith({ + catalogItemId: id, + fogTypeId: image2.fogTypeId + }, updatedImage2, transaction); + }); + + context('when CatalogItemImageManager#updateOrCreate() fails', () => { + def('catalogItemImageUpdateOrCreateResponse', () => Promise.reject(error)); + + it(`fails with ${error}`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when CatalogItemImageManager#updateOrCreate() succeeds', () => { + it('calls AppHelper#deleteUndefinedFields() with correct args', async () => { + await $subject; + expect(AppHelper.deleteUndefinedFields).to.have.been.calledWith(catalogItemInputType); + }); + + context('when AppHelper#deleteUndefinedFields() fails', () => { + def('deleteUndefinedFieldsResponse2', () => error); + + it(`fails with ${error}`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }); + + context('when AppHelper#deleteUndefinedFields() succeeds', () => { + it('calls CatalogItemInputTypeManager#updateOrCreate() with correct args', async () => { + await $subject; + expect(CatalogItemInputTypeManager.updateOrCreate).to.have.been.calledWith({ + catalogItemId: data.id + }, catalogItemInputType, transaction); + }); + + context('when CatalogItemInputTypeManager#updateOrCreate() fails', () => { + def('catalogItemInputTypeUpdateOrCreateResponse', () => Promise.reject(error)); + + it(`fails with ${error}`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when CatalogItemInputTypeManager#updateOrCreate() succeeds', () => { + it('calls AppHelper#deleteUndefinedFields() with correct args', async () => { + await $subject; + expect(AppHelper.deleteUndefinedFields).to.have.been.calledWith(catalogItemOutputType); + }); + + context('when AppHelper#deleteUndefinedFields() fails', () => { + def('deleteUndefinedFieldsResponse3', () => error); + + it(`fails with ${error}`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }); + + context('when AppHelper#deleteUndefinedFields() succeeds', () => { + it('calls CatalogItemOutputTypeManager#updateOrCreate() with correct args', async () => { + await $subject; + expect(CatalogItemOutputTypeManager.updateOrCreate).to.have.been.calledWith({ + catalogItemId: data.id + }, catalogItemOutputType, transaction); + }); + + context('when CatalogItemOutputTypeManager#updateOrCreate() fails', () => { + def('catalogItemOutputTypeUpdateOrCreateResponse', () => Promise.reject(error)); + + it(`fails with ${error}`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when CatalogItemOutputTypeManager#updateOrCreate() succeeds', () => { + it('succeeds', () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }) + }) + }) + }) + }) + }) + }) + }) + }) + }) + }) + }) + }); + + describe('.listCatalogItems()', () => { + const transaction = {}; + const error = 'Error!'; + + const user = { + id: 15 + }; + + const isCLI = false; + + const where = isCLI + ? {category: {[Op.ne]: 'SYSTEM'}} + : {[Op.or]: [{userId: user.id}, {userId: null}], category: {[Op.ne]: 'SYSTEM'}}; + + const attributes = isCLI + ? {} + : {exclude: ["userId"]}; + + def('subject', () => $subject.listCatalogItems(user, isCLI, transaction)); + + def('catalogItemsFindResponse', () => Promise.resolve()); + + beforeEach(() => { + $sandbox.stub(CatalogItemManager, 'findAllWithDependencies').returns($catalogItemFindResponse); + }); + + it('calls CatalogItemManager#findAllWithDependencies() with correct args', async () => { + await $subject; + expect(CatalogItemManager.findAllWithDependencies).to.have.been.calledWith(where, attributes, transaction); + }); + + context('when CatalogItemManager#findAllWithDependencies() fails', () => { + def('catalogItemsFindResponse', () => Promise.reject(error)); + + it(`fails with ${error}`, () => { + return expect($subject).to.be.eventually.have.property('catalogItems'); + }) + }); + + context('when CatalogItemManager#findAllWithDependencies() succeeds', () => { + it('succeeds', () => { + return expect($subject).to.eventually.have.property('catalogItems') + }) + }) + + }); + + describe('.getCatalogItem()', () => { + const transaction = {}; + const error = 'Error!'; + + const user = { + id: 15 + }; + + const isCLI = false; + + const id = 5; + + const where = isCLI + ? {id: id, category: {[Op.ne]: 'SYSTEM'}} + : {[Op.or]: [{userId: user.id}, {userId: null}], id: id, category: {[Op.ne]: 'SYSTEM'}}; + + const attributes = isCLI + ? {} + : {exclude: ["userId"]}; + + def('subject', () => $subject.getCatalogItem(id, user, isCLI, transaction)); + + def('catalogItemFindResponse', () => Promise.resolve({})); + + beforeEach(() => { + $sandbox.stub(CatalogItemManager, 'findOneWithDependencies').returns($catalogItemFindResponse); + }); + + it('calls CatalogItemManager#findOneWithDependencies() with correct args', async () => { + await $subject; + expect(CatalogItemManager.findOneWithDependencies).to.have.been.calledWith(where, attributes, transaction); + }); + + context('when CatalogItemManager#findOneWithDependencies() fails', () => { + def('catalogItemFindResponse', () => Promise.reject(error)); + + it(`fails with ${error}`, () => { + return expect($subject).to.be.rejectedWith(error); + }) + }); + + context('when CatalogItemManager#findOneWithDependencies() succeeds', () => { + it('succeeds', () => { + return expect($subject).to.eventually.deep.equal({}) + }) + }) + + }); + + describe('.deleteCatalogItem()', () => { + const transaction = {}; + const error = 'Error!'; + + const user = { + id: 15 + }; + + const isCLI = false; + + const id = 5; + + const where = isCLI + ? {id: id} + : {userId: user.id, id: id}; + + def('subject', () => $subject.deleteCatalogItem(id, user, isCLI, transaction)); + + def('response', () => 1); + def('catalogItemDeleteResponse', () => Promise.resolve($response)); + + beforeEach(() => { + $sandbox.stub(CatalogItemManager, 'delete').returns($catalogItemDeleteResponse); + }); + + it('calls CatalogItemManager#delete() with correct args', async () => { + await $subject; + expect(CatalogItemManager.delete).to.have.been.calledWith(where, transaction); + }); + + context('when CatalogItemManager#delete() fails', () => { + def('catalogItemDeleteResponse', () => Promise.reject(error)); + + it(`fails with ${error}`, () => { + return expect($subject).to.be.rejectedWith(error); + }) + }); + + context('when CatalogItemManager#delete() succeeds', () => { + it('succeeds', () => { + return expect($subject).to.eventually.deep.equal($response) + }) + }) + + }); + + describe('.getNetworkCatalogItem()', () => { + const transaction = {}; + const error = 'Error!'; + + def('subject', () => $subject.getNetworkCatalogItem(transaction)); + + def('response', () => 1); + def('catalogItemFindResponse', () => Promise.resolve($response)); + + beforeEach(() => { + $sandbox.stub(CatalogItemManager, 'findOne').returns($catalogItemFindResponse); + }); + + it('calls CatalogItemManager#findOne() with correct args', async () => { + await $subject; + expect(CatalogItemManager.findOne).to.have.been.calledWith({ + name: 'Networking Tool', + category: 'SYSTEM', + publisher: 'Eclipse ioFog', + registry_id: 1, + user_id: null + }, transaction); + }); + + context('when CatalogItemManager#findOne() fails', () => { + def('catalogItemFindResponse', () => Promise.reject(error)); + + it(`fails with ${error}`, () => { + return expect($subject).to.be.rejectedWith(error); + }) + }); + + context('when CatalogItemManager#findOne() succeeds', () => { + it('succeeds', () => { + return expect($subject).to.eventually.deep.equal($response) + }) + }) + + }); + + describe('.getBluetoothCatalogItem()', () => { + const transaction = {}; + const error = 'Error!'; + + def('subject', () => $subject.getBluetoothCatalogItem(transaction)); + + def('response', () => 1); + def('catalogItemFindResponse', () => Promise.resolve($response)); + + beforeEach(() => { + $sandbox.stub(CatalogItemManager, 'findOne').returns($catalogItemFindResponse); + }); + + it('calls CatalogItemManager#findOne() with correct args', async () => { + await $subject; + expect(CatalogItemManager.findOne).to.have.been.calledWith({ + name: 'RESTBlue', + category: 'SYSTEM', + publisher: 'Eclipse ioFog', + registry_id: 1, + user_id: null + }, transaction); + }); + + context('when CatalogItemManager#findOne() fails', () => { + def('catalogItemFindResponse', () => Promise.reject(error)); + + it(`fails with ${error}`, () => { + return expect($subject).to.be.rejectedWith(error); + }) + }); + + context('when CatalogItemManager#findOne() succeeds', () => { + it('succeeds', () => { + return expect($subject).to.eventually.deep.equal($response) + }) + }) + + }); + + describe('.getHalCatalogItem()', () => { + const transaction = {}; + const error = 'Error!'; + + def('subject', () => $subject.getHalCatalogItem(transaction)); + + def('response', () => 1); + def('catalogItemFindResponse', () => Promise.resolve($response)); + + beforeEach(() => { + $sandbox.stub(CatalogItemManager, 'findOne').returns($catalogItemFindResponse); + }); + + it('calls CatalogItemManager#findOne() with correct args', async () => { + await $subject; + expect(CatalogItemManager.findOne).to.have.been.calledWith({ + name: 'HAL', + category: 'SYSTEM', + publisher: 'Eclipse ioFog', + registry_id: 1, + user_id: null + }, transaction); + }); + + context('when CatalogItemManager#findOne() fails', () => { + def('catalogItemFindResponse', () => Promise.reject(error)); + + it(`fails with ${error}`, () => { + return expect($subject).to.be.rejectedWith(error); + }) + }); + + context('when CatalogItemManager#findOne() succeeds', () => { + it('succeeds', () => { + return expect($subject).to.eventually.deep.equal($response) + }) + }) + + }); + +}); \ No newline at end of file