UNPKG

@unito/integration-cli

Version:

Integration CLI

364 lines (363 loc) 21 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const test_1 = require("@oclif/test"); const sinon_1 = tslib_1.__importDefault(require("sinon")); const ngrok_1 = tslib_1.__importDefault(require("@ngrok/ngrok")); const child_process_1 = tslib_1.__importDefault(require("child_process")); const inquirer_1 = tslib_1.__importDefault(require("inquirer")); const GlobalConfiguration = tslib_1.__importStar(require("../../src/resources/globalConfiguration")); const IntegrationsPlatform = tslib_1.__importStar(require("../../src/services/integrationsPlatform")); const IntegrationResource = tslib_1.__importStar(require("../../src/resources/integrations")); const IntegrationConfiguration = tslib_1.__importStar(require("../../src/resources/configuration")); const errors_1 = require("../../src/errors"); const FileSystem = tslib_1.__importStar(require("../../src/resources/fileSystem")); const integrations_1 = require("../helpers/integrations"); const styles_1 = require("../helpers/styles"); describe('Publish', () => { const integration = (0, integrations_1.generateIntegration)(); beforeEach(() => { sinon_1.default.stub(IntegrationResource, 'validateIsIntegrationDirectory'); sinon_1.default.stub(IntegrationsPlatform, 'setEnvironment'); sinon_1.default.stub(IntegrationsPlatform, 'setApiKey'); sinon_1.default.stub(IntegrationsPlatform, 'publishIntegration'); sinon_1.default.stub(IntegrationsPlatform, 'reencryptData').resolves({ encryptedData: 'newEncryptedSecret' }); sinon_1.default.stub(ngrok_1.default, 'forward'); sinon_1.default.stub(child_process_1.default, 'spawn'); sinon_1.default.stub(IntegrationsPlatform, 'getProfile').resolves({ id: 1, createdAt: '', updatedAt: '', archivedAt: null, email: 'foo@bar.com', defaultUnitoOrganizationId: null, role: 'developer', apiKey: 'foo', termsAcceptedAt: null, }); }); afterEach(() => { sinon_1.default.restore(); }); test_1.test .stdout() .stub(GlobalConfiguration, 'read', stub => stub.returns({ apiKey: 'foo' })) .stub(IntegrationConfiguration, 'getConfiguration', stub => stub.returns({ name: 'a' })) .stub(IntegrationsPlatform, 'getIntegrationByName', stub => stub.returns(undefined)) .stub(FileSystem, 'getFileBuffer', stub => stub.resolves(Buffer.from(''))) .command(['publish']) .it('publish the integration - default', ctx => { (0, test_1.expect)(ctx.stdout).to.contain('published'); }); test_1.test .stdout() .stub(GlobalConfiguration, 'read', stub => stub.returns({ apiKey: 'foo' })) .stub(IntegrationConfiguration, 'getConfiguration', stub => stub.returns({ name: 'a' })) .stub(IntegrationsPlatform, 'getIntegrationByName', stub => stub.returns(undefined)) .stub(FileSystem, 'getFileBuffer', stub => stub.resolves(Buffer.from(''))) .command(['publish', '--config-path', '/custom-config.json']) .it('publish the integration with custom config - default', ctx => { (0, test_1.expect)(ctx.stdout).to.contain('published'); }); test_1.test .stdout() .stub(GlobalConfiguration, 'read', stub => stub.returns({ apiKeyLocal: 'foo' })) .stub(IntegrationConfiguration, 'getConfiguration', stub => stub.returns({ name: 'a' })) .stub(IntegrationsPlatform, 'getIntegrationByName', stub => stub.returns(undefined)) .stub(FileSystem, 'getFileBuffer', stub => stub.resolves(Buffer.from(''))) .command(['publish', '--environment', 'local']) .it('publish the integration - local', ctx => { (0, test_1.expect)(ctx.stdout).to.contain('published'); }); test_1.test .stdout() .stub(GlobalConfiguration, 'read', stub => stub.returns({ apiKeyLocal: 'foo' })) .stub(IntegrationConfiguration, 'getConfigurationPath', stub => stub.returns('/.unito.local.json')) .stub(IntegrationConfiguration, 'getConfiguration', stub => stub.returns({ name: 'a' })) .stub(IntegrationConfiguration, 'writeConfiguration', stub => stub.resolves()) .stub(IntegrationsPlatform, 'getIntegrationByName', stub => stub.returns(undefined)) .stub(FileSystem, 'getFileBuffer', stub => stub.resolves(Buffer.from(''))) .command(['publish', '--environment', 'local']) .it('publish the integration using .unito.local.json - local', ctx => { (0, test_1.expect)(ctx.stdout).to.contain('published'); }); test_1.test .stdout() .stub(GlobalConfiguration, 'read', stub => stub.returns({ apiKeyStaging: 'foo' })) .stub(IntegrationConfiguration, 'getConfigurationPath', stub => stub.returns('/.unito.json')) .stub(IntegrationConfiguration, 'getConfiguration', stub => stub.returns({ name: 'a' })) .stub(IntegrationsPlatform, 'getIntegrationByName', stub => stub.returns(undefined)) .stub(FileSystem, 'getFileBuffer', stub => stub.resolves(Buffer.from(''))) .command(['publish', '--environment', 'staging']) .it('publish the integration - staging', ctx => { (0, test_1.expect)(ctx.stdout).to.contain('published'); }); test_1.test .stdout() .stub(GlobalConfiguration, 'read', stub => stub.returns({ apiKeyStaging: 'foo' })) .stub(IntegrationConfiguration, 'getConfigurationPath', stub => stub.returns('/.unito.staging.json')) .stub(IntegrationConfiguration, 'getConfiguration', stub => stub.returns({})) .stub(IntegrationConfiguration, 'writeConfiguration', stub => stub.resolves()) .stub(IntegrationsPlatform, 'getIntegrationByName', stub => stub.returns(undefined)) .stub(FileSystem, 'getFileBuffer', stub => stub.resolves(Buffer.from(''))) .command(['publish', '--environment', 'staging']) .it('publish the integration using .unito.staging.json - staging', ctx => { (0, test_1.expect)(ctx.stdout).to.contain('published'); }); test_1.test .stdout() .stub(GlobalConfiguration, 'read', stub => stub.returns({ apiKey: 'foo' })) .stub(IntegrationConfiguration, 'getConfigurationPath', stub => stub.returns('/.unito.json')) .stub(IntegrationConfiguration, 'getConfiguration', stub => stub.returns({ name: 'a' })) .stub(IntegrationsPlatform, 'getIntegrationByName', stub => stub.returns(undefined)) .stub(FileSystem, 'getFileBuffer', stub => stub.resolves(Buffer.from(''))) .command(['publish', '--config-path', '/my-awesome-config.json']) .it('publish the integration using custom configuration', ctx => { (0, test_1.expect)(ctx.stdout).to.contain('published'); }); test_1.test .stdout() .stub(GlobalConfiguration, 'read', stub => stub.returns({ apiKey: 'foo' })) .stub(IntegrationConfiguration, 'getConfiguration', stub => stub.returns({})) .stub(IntegrationsPlatform, 'getIntegrationByName', stub => stub.returns(undefined)) .stub(FileSystem, 'getFileBuffer', stub => stub.resolves(Buffer.from(''))) .stub(inquirer_1.default, 'prompt', stub => stub.resolves({ proceed: false })) .command(['publish', '--registry-only']) .it('aborts on user negative input', ctx => { (0, test_1.expect)(ctx.stdout).to.contain('🙊 Abort! You are safe now 🍸 relax'); }); test_1.test .stdout() .stub(GlobalConfiguration, 'read', stub => stub.returns({ apiKey: 'foo' })) .stub(IntegrationConfiguration, 'getConfiguration', stub => stub.returns({})) .stub(IntegrationsPlatform, 'getIntegration', stub => stub.returns(undefined)) .stub(IntegrationsPlatform, 'createIntegration', stub => stub.resolves(integration)) .stub(IntegrationsPlatform, 'updateIntegration', stub => stub.resolves(integration)) .stub(FileSystem, 'getFileBuffer', stub => stub.resolves(Buffer.from(''))) .stub(inquirer_1.default, 'prompt', stub => stub.resolves({ proceed: false })) .command(['publish', '--registry-only', '--force']) .it('bypass user confirmation with --force is active', ctx => { (0, test_1.expect)(ctx.stdout).to.contain('created'); }); test_1.test .stdout() .stub(GlobalConfiguration, 'read', stub => stub.returns({ apiKey: 'foo' })) .stub(IntegrationConfiguration, 'getConfiguration', stub => stub.returns({})) .stub(IntegrationsPlatform, 'getIntegration', stub => stub.returns(undefined)) .stub(IntegrationsPlatform, 'createIntegration', stub => stub.resolves(integration)) .stub(IntegrationsPlatform, 'updateIntegration', stub => stub.resolves(integration)) .stub(FileSystem, 'getFileBuffer', stub => stub.resolves(Buffer.from(''))) .stub(inquirer_1.default, 'prompt', stub => stub.resolves({ proceed: true })) .command(['publish', '--registry-only']) .it('creates the integration in the registry', ctx => { (0, test_1.expect)(ctx.stdout).to.contain('created'); }); test_1.test .stdout() .stub(GlobalConfiguration, 'read', stub => stub.returns({ apiKey: 'foo' })) .stub(IntegrationConfiguration, 'getConfiguration', stub => stub.returns({ name: 'a' })) .stub(IntegrationsPlatform, 'getIntegrationByName', stub => stub.returns({ name: 'a' })) .stub(IntegrationsPlatform, 'createIntegration', stub => stub.resolves(integration)) .stub(IntegrationsPlatform, 'updateIntegration', stub => stub.resolves(integration)) .stub(FileSystem, 'getFileBuffer', stub => stub.resolves(Buffer.from(''))) .stub(inquirer_1.default, 'prompt', stub => stub.resolves({ proceed: true })) .command(['publish', '--registry-only']) .it('updates the integration in the registry', ctx => { (0, test_1.expect)(ctx.stdout).to.contain('updated'); }); test_1.test .stdout() .stub(GlobalConfiguration, 'read', stub => stub.returns({ apiKey: 'foo' })) .stub(IntegrationConfiguration, 'getConfiguration', stub => stub.returns({ authorizations: [{ type: 'custom', development: true }, { type: 'oauth2' }], })) .stub(IntegrationsPlatform, 'getIntegrationByName', stub => stub.returns(undefined)) .stub(IntegrationsPlatform, 'createIntegration', stub => stub.resolves(integration)) .stub(IntegrationsPlatform, 'updateIntegration', stub => stub.resolves(integration)) .stub(FileSystem, 'getFileBuffer', stub => stub.resolves(Buffer.from(''))) .stub(inquirer_1.default, 'prompt', stub => stub.resolves({ proceed: true })) .command(['publish', '--registry-only']) .it('filters out "development" authorizations', ctx => { ctx.sandbox.assert.calledOnceWithMatch( // @ts-expect-error syntax accepted by sinon. IntegrationsPlatform.createIntegration, { authorizations: [ { type: 'oauth2', instructionsImage: 'data:image/png;base64,', instructionsMarkdown: '', }, ], }); // @ts-expect-error syntax accepted by sinon. ctx.sandbox.assert.notCalled(IntegrationsPlatform.updateIntegration); }); test_1.test .stdout() .stub(GlobalConfiguration, 'read', stub => stub.returns({ apiKey: 'foo' })) .stub(IntegrationConfiguration, 'getConfiguration', stub => stub.returns({ name: 'foo' })) .stub(IntegrationsPlatform, 'getIntegrationByName', stub => stub.returns(undefined)) .stub(IntegrationsPlatform, 'createIntegration', stub => stub.resolves(integration)) .stub(IntegrationsPlatform, 'updateIntegration', stub => stub.resolves(integration)) .stub(FileSystem, 'getFileBuffer', stub => stub.resolves(Buffer.from(''))) .command(['publish', '--preview']) .it('preview the integration', ctx => { (0, test_1.expect)(ctx.stdout).to.contain('published'); }); test_1.test .stdout() .stub(GlobalConfiguration, 'read', stub => stub.returns({ apiKey: 'foo' })) .stub(IntegrationConfiguration, 'getConfiguration', stub => stub.returns({ name: 'foo', ui: { displayName: 'Foo' } })) .stub(IntegrationsPlatform, 'getIntegrationByName', stub => stub.returns(undefined)) .stub(IntegrationConfiguration, 'writeConfiguration', stub => stub.returns(integration)) .stub(FileSystem, 'getFileBuffer', stub => stub.resolves(Buffer.from(''))) .command(['publish', '--preview']) .it('preview the integration - override the display name', ctx => { (0, test_1.expect)((0, styles_1.uncolorize)(ctx.stdout)).to.contain('foo-preview-9c88 is being published'); }); test_1.test .stdout() .stub(GlobalConfiguration, 'read', stub => stub.returns({ apiKey: 'foo' })) .stub(IntegrationConfiguration, 'getConfiguration', stub => stub.returns({})) .stub(IntegrationsPlatform, 'getIntegrationByName', stub => stub.returns(undefined)) .stub(IntegrationsPlatform, 'createIntegration', stub => stub.resolves(integration)) .stub(IntegrationsPlatform, 'updateIntegration', stub => stub.resolves(integration)) .stub(FileSystem, 'getFileBuffer', stub => stub.resolves(Buffer.from(''))) .command(['publish', '--live-preview']) .it('live-preview the integration', ctx => { (0, test_1.expect)(ctx.stdout).to.contain('created'); }); test_1.test .stdout() .stub(GlobalConfiguration, 'read', stub => stub.returns({ apiKey: 'foo' })) .stub(IntegrationConfiguration, 'getConfiguration', stub => stub.returns({ ui: { displayName: 'Foo' } })) .stub(IntegrationsPlatform, 'getIntegrationByName', stub => stub.returns(undefined)) .stub(IntegrationsPlatform, 'createIntegration', stub => stub.resolves(integration)) .stub(FileSystem, 'getFileBuffer', stub => stub.resolves(Buffer.from(''))) .command(['publish', '--live-preview']) .it('live-preview the integration - override the display name', ctx => { ctx.sandbox.assert.calledOnceWithMatch( // @ts-expect-error syntax accepted by sinon. IntegrationsPlatform.createIntegration, { ui: { displayName: 'Foo - Live Preview - 9c88' }, name: 'undefined-live-preview-9c88', baseUrl: undefined, }); }); test_1.test .stdout() .stderr() .stub(GlobalConfiguration, 'read', stub => stub.returns({})) .stub(IntegrationConfiguration, 'getConfiguration', stub => stub.returns({})) .stub(IntegrationsPlatform, 'getIntegrationByName', stub => stub.returns(undefined)) .stub(FileSystem, 'getFileBuffer', stub => stub.resolves(Buffer.from(''))) .command(['publish']) .exit(-1) .it('missing api key', ctx => { (0, test_1.expect)(ctx.stderr).to.contain('Your API key is not set!\nMake sure to run the login command first'); }); test_1.test .stdout() .stderr() .stub(GlobalConfiguration, 'read', stub => stub.throws(new errors_1.NoConfigurationFileError())) .stub(FileSystem, 'getFileBuffer', stub => stub.resolves(Buffer.from(''))) .command(['publish']) .exit(-1) .it('handles exception'); test_1.test .stdout() .stub(GlobalConfiguration, 'read', stub => stub.returns({ apiKey: 'foo' })) .stub(IntegrationConfiguration, 'getConfiguration', stub => stub.returns({ name: 'myIntegration', authorizations: [{ name: 'oauth2', oauth2: { clientSecret: 'unito-secret-' } }], secrets: { secret1: 'unito-secret-', invalidSecret: 'Should never happen anyway' }, })) .stub(IntegrationConfiguration, 'writeConfiguration', stub => stub.returns({ name: 'myIntegration', authorizations: [{ name: 'oauth2', oauth2: { clientSecret: 'unito-secret-' } }], secrets: { secret1: 'unito-secret-', invalidSecret: 'Should never happen anyway' }, })) .stub(IntegrationsPlatform, 'getIntegrationByName', stub => stub.returns(undefined)) .stub(FileSystem, 'getFileBuffer', stub => stub.resolves(Buffer.from(''))) .command(['publish', '--preview']) .it('reencrypts the clientSecret on preview', ctx => { (0, test_1.expect)(ctx.stdout).to.contain('Reencrypting oauth2:clientSecret'); (0, test_1.expect)(ctx.stdout).to.contain('Reencrypting secrets:secret1'); (0, test_1.expect)(ctx.stdout).to.contain('Skipping secrets:invalidSecret'); }); test_1.test .stdout() .stub(GlobalConfiguration, 'read', stub => stub.returns({ apiKey: 'foo' })) .stub(IntegrationConfiguration, 'getConfiguration', stub => stub.returns({ name: 'myIntegration', authorizations: [{ name: 'oauth2', oauth2: { clientSecret: 'unito-secret-' } }], secrets: { secret1: 'unito-secret-', invalidSecret: 'Should never happen anyway' }, })) .stub(IntegrationsPlatform, 'getIntegrationByName', stub => stub.returns(undefined)) .stub(IntegrationsPlatform, 'createIntegration', stub => stub.resolves(integration)) .stub(IntegrationsPlatform, 'updateIntegration', stub => stub.resolves(integration)) .stub(FileSystem, 'getFileBuffer', stub => stub.resolves(Buffer.from(''))) .command(['publish', '--live-preview']) .it('reencrypts the clientSecret on live-preview', ctx => { (0, test_1.expect)(ctx.stdout).to.contain('Reencrypting oauth2:clientSecret'); (0, test_1.expect)(ctx.stdout).to.contain('Reencrypting secrets:secret1'); (0, test_1.expect)(ctx.stdout).to.contain('Skipping secrets:invalidSecret'); }); test_1.test .stdout() .stub(GlobalConfiguration, 'read', stub => stub.returns({ apiKey: 'foo' })) .stub(IntegrationConfiguration, 'getConfiguration', stub => stub.returns({ name: 'myIntegration', authorizations: [{ name: 'oauth2', oauth2: { clientSecret: 'toto' } }], })) .stub(IntegrationsPlatform, 'getIntegrationByName', stub => stub.returns(undefined)) .stub(IntegrationsPlatform, 'createIntegration', stub => stub.resolves(integration)) .stub(IntegrationsPlatform, 'updateIntegration', stub => stub.resolves(integration)) .stub(FileSystem, 'getFileBuffer', stub => stub.resolves(Buffer.from(''))) .command(['publish', '--live-preview']) .it('skips reencryption', ctx => { (0, test_1.expect)(ctx.stdout).to.contain('Skipping oauth2:clientSecret'); }); test_1.test .stdout() .stub(GlobalConfiguration, 'read', stub => stub.returns({ apiKey: 'foo' })) .stub(IntegrationConfiguration, 'getConfiguration', stub => stub.returns({ authorizations: [ { name: 'foo', method: 'custom', }, ], })) .stub(IntegrationsPlatform, 'getIntegrationByName', stub => stub.returns(undefined)) .stub(IntegrationsPlatform, 'createIntegration', stub => stub.resolves(integration)) .stub(IntegrationsPlatform, 'updateIntegration', stub => stub.resolves(integration)) .stub(FileSystem, 'getFileBuffer', stub => stub.resolves(Buffer.from('foo'))) .stub(inquirer_1.default, 'prompt', stub => stub.resolves({ proceed: true })) .command(['publish', '--registry-only']) .it('update assets', ctx => { (0, test_1.expect)(ctx.stdout).to.contain('image: <set>'); (0, test_1.expect)(ctx.stdout).to.contain('markdown: <set>'); }); test_1.test .stdout() .stub(GlobalConfiguration, 'read', stub => stub.returns({ apiKey: 'foo' })) .stub(IntegrationConfiguration, 'getConfiguration', stub => stub.returns({ authorizations: [ { name: 'foo', method: 'custom', }, ], })) .stub(IntegrationsPlatform, 'getIntegrationByName', stub => stub.returns(undefined)) .stub(FileSystem, 'getFileBuffer', stub => stub.resolves(null)) .stub(inquirer_1.default, 'prompt', stub => stub.resolves({ proceed: true })) .stub(IntegrationsPlatform, 'createIntegration', stub => stub.resolves(integration)) .stub(IntegrationsPlatform, 'updateIntegration', stub => stub.resolves(integration)) .command(['publish', '--registry-only']) .it('it defaults instructions to null if no file in assets folder', ctx => { (0, test_1.expect)(ctx.stdout).to.contain('image: <unset>'); (0, test_1.expect)(ctx.stdout).to.contain('markdown: <unset>'); }); });