@unito/integration-cli 0.55.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +3 -0
- package/README.md +32 -0
- package/bin/run +11 -0
- package/bin/run.cmd +3 -0
- package/dist/.eslintrc.d.ts +10 -0
- package/dist/.eslintrc.js +20 -0
- package/dist/integrationGenerator/errors.d.ts +2 -0
- package/dist/integrationGenerator/errors.js +6 -0
- package/dist/integrationGenerator/index.d.ts +2 -0
- package/dist/integrationGenerator/index.js +5 -0
- package/dist/integrationGenerator/integrationBoilerplate/.dockerignore +3 -0
- package/dist/integrationGenerator/integrationBoilerplate/.eslintrc.js +74 -0
- package/dist/integrationGenerator/integrationBoilerplate/.nvmrc +1 -0
- package/dist/integrationGenerator/integrationBoilerplate/.prettierignore +1 -0
- package/dist/integrationGenerator/integrationBoilerplate/.prettierrc +7 -0
- package/dist/integrationGenerator/integrationBoilerplate/.unito.json +1 -0
- package/dist/integrationGenerator/integrationBoilerplate/Dockerfile +38 -0
- package/dist/integrationGenerator/integrationBoilerplate/README.md +21 -0
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.dockerignore +3 -0
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.eslintrc.js +74 -0
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.nvmrc +1 -0
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.prettierignore +1 -0
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.prettierrc +7 -0
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.unito.json +1 -0
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/Dockerfile +38 -0
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/README.md +21 -0
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/package.json +43 -0
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/src/index.ts +94 -0
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/src/logger.ts +55 -0
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/src/middlewares/additionalLoggingContext.ts +22 -0
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/src/middlewares/correlationId.ts +13 -0
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/src/middlewares/credentials.ts +38 -0
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/src/request.ts +59 -0
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/src/routes/index.ts +11 -0
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/src/routes/me.ts +15 -0
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/src/routes/root.ts +12 -0
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/tsconfig.json +37 -0
- package/dist/integrationGenerator/integrationBoilerplate/package.json +43 -0
- package/dist/integrationGenerator/integrationBoilerplate/src/index.ts +90 -0
- package/dist/integrationGenerator/integrationBoilerplate/src/logger.ts +37 -0
- package/dist/integrationGenerator/integrationBoilerplate/src/middlewares/correlationId.ts +18 -0
- package/dist/integrationGenerator/integrationBoilerplate/src/middlewares/credentials.ts +38 -0
- package/dist/integrationGenerator/integrationBoilerplate/src/request.ts +59 -0
- package/dist/integrationGenerator/integrationBoilerplate/src/routes/index.ts +11 -0
- package/dist/integrationGenerator/integrationBoilerplate/src/routes/me.ts +15 -0
- package/dist/integrationGenerator/integrationBoilerplate/src/routes/root.ts +12 -0
- package/dist/integrationGenerator/integrationBoilerplate/tsconfig.json +37 -0
- package/dist/integrationGenerator/src/index.d.ts +1 -0
- package/dist/integrationGenerator/src/index.js +5 -0
- package/dist/integrationGenerator/src/resources/index.d.ts +1 -0
- package/dist/integrationGenerator/src/resources/index.js +5 -0
- package/dist/integrationGenerator/src/resources/integration.d.ts +9 -0
- package/dist/integrationGenerator/src/resources/integration.js +60 -0
- package/dist/integrationGenerator/test/resources/integration.test.d.ts +1 -0
- package/dist/integrationGenerator/test/resources/integration.test.js +51 -0
- package/dist/schemas/authorization.json +204 -0
- package/dist/schemas/automation.json +81 -0
- package/dist/schemas/configuration.json +89 -0
- package/dist/scripts/generateTypes.d.ts +8 -0
- package/dist/scripts/generateTypes.js +44 -0
- package/dist/src/baseCommand.d.ts +14 -0
- package/dist/src/baseCommand.js +39 -0
- package/dist/src/commands/activity.d.ts +12 -0
- package/dist/src/commands/activity.js +75 -0
- package/dist/src/commands/dev.d.ts +15 -0
- package/dist/src/commands/dev.js +123 -0
- package/dist/src/commands/encrypt.d.ts +11 -0
- package/dist/src/commands/encrypt.js +50 -0
- package/dist/src/commands/init.d.ts +10 -0
- package/dist/src/commands/init.js +51 -0
- package/dist/src/commands/invite.d.ts +11 -0
- package/dist/src/commands/invite.js +71 -0
- package/dist/src/commands/login.d.ts +11 -0
- package/dist/src/commands/login.js +76 -0
- package/dist/src/commands/oauth2.d.ts +10 -0
- package/dist/src/commands/oauth2.js +99 -0
- package/dist/src/commands/publish.d.ts +28 -0
- package/dist/src/commands/publish.js +302 -0
- package/dist/src/commands/test.d.ts +9 -0
- package/dist/src/commands/test.js +165 -0
- package/dist/src/commands/upgrade.d.ts +7 -0
- package/dist/src/commands/upgrade.js +88 -0
- package/dist/src/configurationTypes.d.ts +209 -0
- package/dist/src/configurationTypes.js +49 -0
- package/dist/src/errors.d.ts +38 -0
- package/dist/src/errors.js +159 -0
- package/dist/src/hooks/init/displayLogo.d.ts +3 -0
- package/dist/src/hooks/init/displayLogo.js +37 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +5 -0
- package/dist/src/oauth2Helper/oauth2Helper.d.ts +63 -0
- package/dist/src/oauth2Helper/oauth2Helper.js +235 -0
- package/dist/src/oauth2Helper/types.d.ts +22 -0
- package/dist/src/oauth2Helper/types.js +2 -0
- package/dist/src/resources/configuration.d.ts +30 -0
- package/dist/src/resources/configuration.js +191 -0
- package/dist/src/resources/decryption.d.ts +5 -0
- package/dist/src/resources/decryption.js +62 -0
- package/dist/src/resources/fileSystem.d.ts +2 -0
- package/dist/src/resources/fileSystem.js +22 -0
- package/dist/src/resources/globalConfiguration.d.ts +13 -0
- package/dist/src/resources/globalConfiguration.js +44 -0
- package/dist/src/resources/integrations.d.ts +2 -0
- package/dist/src/resources/integrations.js +17 -0
- package/dist/src/resources/integrationsPlatform.d.ts +2 -0
- package/dist/src/resources/integrationsPlatform.js +33 -0
- package/dist/src/services/integrationsPlatform.d.ts +36 -0
- package/dist/src/services/integrationsPlatform.js +162 -0
- package/dist/src/services/oauth2Helper.d.ts +3 -0
- package/dist/src/services/oauth2Helper.js +34 -0
- package/dist/test/commands/activity.test.d.ts +1 -0
- package/dist/test/commands/activity.test.js +62 -0
- package/dist/test/commands/dev.test.d.ts +1 -0
- package/dist/test/commands/dev.test.js +139 -0
- package/dist/test/commands/encrypt.test.d.ts +1 -0
- package/dist/test/commands/encrypt.test.js +73 -0
- package/dist/test/commands/init.test.d.ts +1 -0
- package/dist/test/commands/init.test.js +45 -0
- package/dist/test/commands/invite.test.d.ts +1 -0
- package/dist/test/commands/invite.test.js +56 -0
- package/dist/test/commands/login.test.d.ts +1 -0
- package/dist/test/commands/login.test.js +90 -0
- package/dist/test/commands/oauth2.test.d.ts +1 -0
- package/dist/test/commands/oauth2.test.js +104 -0
- package/dist/test/commands/publish.test.d.ts +1 -0
- package/dist/test/commands/publish.test.js +429 -0
- package/dist/test/commands/test.test.d.ts +1 -0
- package/dist/test/commands/test.test.js +171 -0
- package/dist/test/commands/upgrade.test.d.ts +1 -0
- package/dist/test/commands/upgrade.test.js +47 -0
- package/dist/test/errors.test.d.ts +1 -0
- package/dist/test/errors.test.js +96 -0
- package/dist/test/helpers/init.d.ts +1 -0
- package/dist/test/helpers/init.js +6 -0
- package/dist/test/mocha.hooks.d.ts +2 -0
- package/dist/test/mocha.hooks.js +37 -0
- package/dist/test/oauth2Helper/oauth2Helper.test.d.ts +1 -0
- package/dist/test/oauth2Helper/oauth2Helper.test.js +150 -0
- package/dist/test/resources/configuration.test.d.ts +1 -0
- package/dist/test/resources/configuration.test.js +586 -0
- package/dist/test/resources/decryption.test.d.ts +1 -0
- package/dist/test/resources/decryption.test.js +68 -0
- package/dist/test/resources/globalConfiguration.test.d.ts +1 -0
- package/dist/test/resources/globalConfiguration.test.js +32 -0
- package/dist/test/services/integrationsPlatform.test.d.ts +1 -0
- package/dist/test/services/integrationsPlatform.test.js +168 -0
- package/dist/test/services/oauth2Helper.test.d.ts +1 -0
- package/dist/test/services/oauth2Helper.test.js +85 -0
- package/oclif.manifest.json +423 -0
- package/package.json +98 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const chai_1 = require("chai");
|
|
5
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
6
|
+
const sinon_1 = tslib_1.__importDefault(require("sinon"));
|
|
7
|
+
const core_1 = require("@oclif/core");
|
|
8
|
+
const path_1 = tslib_1.__importDefault(require("path"));
|
|
9
|
+
const errors_1 = require("../src/errors");
|
|
10
|
+
const configuration_1 = require("../src/resources/configuration");
|
|
11
|
+
describe('handleError', () => {
|
|
12
|
+
let uxLogStub;
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
uxLogStub = sinon_1.default.stub(core_1.ux, 'log');
|
|
15
|
+
});
|
|
16
|
+
afterEach(() => {
|
|
17
|
+
sinon_1.default.restore();
|
|
18
|
+
});
|
|
19
|
+
it('should handle NoIntegrationFoundError', () => {
|
|
20
|
+
const error = new errors_1.NoIntegrationFoundError();
|
|
21
|
+
const handled = (0, errors_1.handleError)(error);
|
|
22
|
+
(0, chai_1.expect)(handled).to.be.true;
|
|
23
|
+
(0, chai_1.expect)(uxLogStub.calledTwice).to.be.true;
|
|
24
|
+
(0, chai_1.expect)(uxLogStub.firstCall.args[0]).to.equal(chalk_1.default.redBright('Your directory does not seem to contain an integration :('));
|
|
25
|
+
(0, chai_1.expect)(uxLogStub.secondCall.args[0]).to.include('Make sure you are in the right directory');
|
|
26
|
+
});
|
|
27
|
+
it('should handle NoConfigurationFileError', () => {
|
|
28
|
+
const error = new errors_1.NoConfigurationFileError();
|
|
29
|
+
const handled = (0, errors_1.handleError)(error);
|
|
30
|
+
(0, chai_1.expect)(handled).to.be.true;
|
|
31
|
+
(0, chai_1.expect)(uxLogStub.calledTwice).to.be.true;
|
|
32
|
+
(0, chai_1.expect)(uxLogStub.firstCall.args[0]).to.equal(chalk_1.default.redBright('This command requires a configuration file for your integration :('));
|
|
33
|
+
(0, chai_1.expect)(uxLogStub.secondCall.args[0]).to.equal(`This file should be located at ${chalk_1.default.yellowBright(path_1.default.relative(process.cwd(), (0, configuration_1.getConfigurationPath)()))}.`);
|
|
34
|
+
});
|
|
35
|
+
it('should handle MissingEnvironmentVariableError', () => {
|
|
36
|
+
const error = new errors_1.MissingEnvironmentVariableError('VAR_NAME');
|
|
37
|
+
const handled = (0, errors_1.handleError)(error);
|
|
38
|
+
(0, chai_1.expect)(handled).to.be.true;
|
|
39
|
+
(0, chai_1.expect)(uxLogStub.calledTwice).to.be.true;
|
|
40
|
+
(0, chai_1.expect)(uxLogStub.firstCall.args[0]).to.equal(chalk_1.default.redBright('This command requires a variable which is missing from your environment :('));
|
|
41
|
+
(0, chai_1.expect)(uxLogStub.secondCall.args[0]).to.equal(`Make sure the environment variable ${chalk_1.default.yellowBright('VAR_NAME')} is defined.`);
|
|
42
|
+
});
|
|
43
|
+
it('should return false for unrecognized error', () => {
|
|
44
|
+
const error = new Error('Unrecognized error');
|
|
45
|
+
const handled = (0, errors_1.handleError)(error);
|
|
46
|
+
(0, chai_1.expect)(handled).to.be.false;
|
|
47
|
+
(0, chai_1.expect)(uxLogStub.called).to.be.false;
|
|
48
|
+
});
|
|
49
|
+
it('should handle MissingEnvironmentVariableError', () => {
|
|
50
|
+
const error = new errors_1.ConfigurationInvalid('VAR_NAME', 'details', 'prettyDetails');
|
|
51
|
+
const handled = (0, errors_1.handleError)(error);
|
|
52
|
+
(0, chai_1.expect)(handled).to.be.true;
|
|
53
|
+
(0, chai_1.expect)(uxLogStub.calledThrice).to.be.true;
|
|
54
|
+
(0, chai_1.expect)(uxLogStub.firstCall.args[0]).to.equal(chalk_1.default.redBright(`Your ${chalk_1.default.yellowBright(path_1.default.basename((0, configuration_1.getConfigurationPath)()))} is invalid!`));
|
|
55
|
+
(0, chai_1.expect)(uxLogStub.thirdCall.args[0]).to.equal('prettyDetails');
|
|
56
|
+
});
|
|
57
|
+
it('should handle NoRefreshTokenError', () => {
|
|
58
|
+
const error = new errors_1.NoRefreshTokenError();
|
|
59
|
+
const handled = (0, errors_1.handleError)(error);
|
|
60
|
+
(0, chai_1.expect)(handled).to.be.true;
|
|
61
|
+
(0, chai_1.expect)(uxLogStub.calledOnce).to.be.true;
|
|
62
|
+
(0, chai_1.expect)(uxLogStub.firstCall.args[0]).to.equal(chalk_1.default.redBright('No refresh token found in your configuration file'));
|
|
63
|
+
});
|
|
64
|
+
it('should handle FailedToRetrieveAccessTokenError', () => {
|
|
65
|
+
const error = new errors_1.FailedToRetrieveAccessTokenError('Credentials invalid');
|
|
66
|
+
const handled = (0, errors_1.handleError)(error);
|
|
67
|
+
(0, chai_1.expect)(handled).to.be.true;
|
|
68
|
+
(0, chai_1.expect)(uxLogStub.calledThrice).to.be.true;
|
|
69
|
+
(0, chai_1.expect)(uxLogStub.firstCall.args[0]).to.equal(chalk_1.default.redBright('Failed to retrieve access token'));
|
|
70
|
+
(0, chai_1.expect)(uxLogStub.thirdCall.args[0]).to.equal('Credentials invalid');
|
|
71
|
+
});
|
|
72
|
+
it('should handle InvalidRequestContentTypeError', () => {
|
|
73
|
+
const error = new errors_1.InvalidRequestContentTypeError('Invalid content type');
|
|
74
|
+
const handled = (0, errors_1.handleError)(error);
|
|
75
|
+
(0, chai_1.expect)(handled).to.be.true;
|
|
76
|
+
(0, chai_1.expect)(uxLogStub.calledThrice).to.be.true;
|
|
77
|
+
(0, chai_1.expect)(uxLogStub.firstCall.args[0]).to.equal(chalk_1.default.redBright('Invalid request content type'));
|
|
78
|
+
(0, chai_1.expect)(uxLogStub.thirdCall.args[0]).to.equal('Invalid content type');
|
|
79
|
+
});
|
|
80
|
+
it('should handle DecryptionAuthenticationError', () => {
|
|
81
|
+
const error = new errors_1.DecryptionAuthenticationError('secrets');
|
|
82
|
+
const handled = (0, errors_1.handleError)(error);
|
|
83
|
+
(0, chai_1.expect)(handled).to.be.true;
|
|
84
|
+
(0, chai_1.expect)(uxLogStub.calledThrice).to.be.true;
|
|
85
|
+
(0, chai_1.expect)(uxLogStub.secondCall.args[0]).to.equal(chalk_1.default.yellowBright('Your configuration contains encrypted secrets.'));
|
|
86
|
+
(0, chai_1.expect)(uxLogStub.thirdCall.args[0]).to.equal('To use them locally, you must be authenticated to Unito.');
|
|
87
|
+
});
|
|
88
|
+
it('should handle EntryDecryptionError', () => {
|
|
89
|
+
const error = new errors_1.EntryDecryptionError('key', 'value', 'staging');
|
|
90
|
+
const handled = (0, errors_1.handleError)(error);
|
|
91
|
+
(0, chai_1.expect)(handled).to.be.true;
|
|
92
|
+
(0, chai_1.expect)(uxLogStub.called).to.be.true;
|
|
93
|
+
(0, chai_1.expect)(uxLogStub.secondCall.args[0]).to.equal(chalk_1.default.yellowBright('Error decrypting entry:'));
|
|
94
|
+
(0, chai_1.expect)(uxLogStub.thirdCall.args[0]).to.equal(chalk_1.default.redBright('key: value'));
|
|
95
|
+
});
|
|
96
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.mochaHooks = void 0;
|
|
27
|
+
const mochaHooks = () => {
|
|
28
|
+
return {
|
|
29
|
+
async beforeAll() {
|
|
30
|
+
// Allow using `chai-as-promised` in all tests.
|
|
31
|
+
const chai = await Promise.resolve().then(() => __importStar(require('chai')));
|
|
32
|
+
const chaiAsPromised = await Promise.resolve().then(() => __importStar(require('chai-as-promised')));
|
|
33
|
+
chai.use(chaiAsPromised.default);
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
exports.mochaHooks = mochaHooks;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
5
|
+
const chai_1 = require("chai");
|
|
6
|
+
const sinon_1 = tslib_1.__importDefault(require("sinon"));
|
|
7
|
+
const oauth2Helper_1 = tslib_1.__importStar(require("../../src/oauth2Helper/oauth2Helper")), oauth2Namespace = oauth2Helper_1;
|
|
8
|
+
const configurationTypes_1 = require("../../src/configurationTypes");
|
|
9
|
+
const errors_1 = require("../../src/errors");
|
|
10
|
+
describe('OAuth2Helper', () => {
|
|
11
|
+
let oauth2Helper;
|
|
12
|
+
let openSpy;
|
|
13
|
+
let fetchStub;
|
|
14
|
+
beforeEach(() => {
|
|
15
|
+
const authorizationInfo = {
|
|
16
|
+
clientId: 'your-client-id',
|
|
17
|
+
clientSecret: 'your-client-secret',
|
|
18
|
+
authorizationUrl: 'https://provider.com/oauth/authorize',
|
|
19
|
+
scopes: [{ name: 'scope1' }, { name: 'scope2' }],
|
|
20
|
+
tokenUrl: 'https://provider.com/oauth/token',
|
|
21
|
+
grantType: configurationTypes_1.GrantType.AUTHORIZATION_CODE,
|
|
22
|
+
requestContentType: configurationTypes_1.RequestContentType.URL_ENCODED,
|
|
23
|
+
responseContentType: configurationTypes_1.RequestContentType.JSON,
|
|
24
|
+
tokenRequestParameters: {
|
|
25
|
+
header: {
|
|
26
|
+
Authorization: 'custom',
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
oauth2Helper = new oauth2Helper_1.default(authorizationInfo);
|
|
31
|
+
fetchStub = sinon_1.default.stub().resolves({ json: sinon_1.default.stub().resolves({}), status: 200 });
|
|
32
|
+
sinon_1.default.stub(oauth2Helper, 'startServer').returns('http://localhost:5050');
|
|
33
|
+
sinon_1.default.stub(oauth2Helper, 'stopServer');
|
|
34
|
+
sinon_1.default.replace(global, 'fetch', fetchStub);
|
|
35
|
+
sinon_1.default.replace(oauth2Namespace, 'open', { open: (_url) => undefined });
|
|
36
|
+
openSpy = sinon_1.default.spy(oauth2Namespace.open, 'open');
|
|
37
|
+
});
|
|
38
|
+
afterEach(() => {
|
|
39
|
+
sinon_1.default.restore();
|
|
40
|
+
});
|
|
41
|
+
describe('handleAuthorize', () => {
|
|
42
|
+
it('should open the authorization URL', async () => {
|
|
43
|
+
const req = {};
|
|
44
|
+
const res = { json: sinon_1.default.stub() };
|
|
45
|
+
await oauth2Helper['handleAuthorize'](req, res);
|
|
46
|
+
sinon_1.default.assert.calledOnce(openSpy);
|
|
47
|
+
sinon_1.default.assert.calledWith(openSpy, 'https://provider.com/oauth/authorize?client_id=your-client-id&redirect_uri=%2Fcredentials%2Fnew%2Foauth2%2Fcallback&scope=scope1+scope2&response_type=code');
|
|
48
|
+
sinon_1.default.assert.calledOnce(res.json);
|
|
49
|
+
});
|
|
50
|
+
it('should maintain the pre-existing query parameters in authorization URL', async () => {
|
|
51
|
+
oauth2Helper['providerAuthorizationUrl'] = 'https://provider.com/oauth/authorize?query1=value1&query2=value2';
|
|
52
|
+
const req = {};
|
|
53
|
+
const res = { json: sinon_1.default.stub() };
|
|
54
|
+
await oauth2Helper['handleAuthorize'](req, res);
|
|
55
|
+
sinon_1.default.assert.calledOnce(openSpy);
|
|
56
|
+
sinon_1.default.assert.calledWith(openSpy, 'https://provider.com/oauth/authorize?query1=value1&query2=value2&client_id=your-client-id&redirect_uri=%2Fcredentials%2Fnew%2Foauth2%2Fcallback&scope=scope1+scope2&response_type=code');
|
|
57
|
+
(0, chai_1.expect)(openSpy.firstCall.args[0]).to.includes('query1=value1');
|
|
58
|
+
(0, chai_1.expect)(openSpy.firstCall.args[0]).to.includes('query2=value2');
|
|
59
|
+
sinon_1.default.assert.calledOnce(res.json);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
describe('handleCallback', () => {
|
|
63
|
+
it('should store the authorization code', async () => {
|
|
64
|
+
const code = 'test-code';
|
|
65
|
+
const req = { query: { code } };
|
|
66
|
+
const res = { json: sinon_1.default.stub() };
|
|
67
|
+
await oauth2Helper['handleCallback'](req, res);
|
|
68
|
+
(0, chai_1.expect)(oauth2Helper['code']).to.equal(code);
|
|
69
|
+
sinon_1.default.assert.calledOnce(res.json);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
describe('handleToken', () => {
|
|
73
|
+
it('should retrieve the access token and return it in the response', async () => {
|
|
74
|
+
const req = { query: {} };
|
|
75
|
+
const res = { json: sinon_1.default.stub() };
|
|
76
|
+
await oauth2Helper['handleToken'](req, res);
|
|
77
|
+
sinon_1.default.assert.calledOnce(fetchStub);
|
|
78
|
+
sinon_1.default.assert.calledWith(fetchStub, 'https://provider.com/oauth/token', {
|
|
79
|
+
headers: {
|
|
80
|
+
'Content-type': 'application/x-www-form-urlencoded',
|
|
81
|
+
Authorization: 'custom',
|
|
82
|
+
},
|
|
83
|
+
body: sinon_1.default.match.string,
|
|
84
|
+
method: 'POST',
|
|
85
|
+
});
|
|
86
|
+
sinon_1.default.assert.calledOnce(res.json);
|
|
87
|
+
});
|
|
88
|
+
it('should handle errors and return 500 status', async () => {
|
|
89
|
+
const req = { query: {} };
|
|
90
|
+
const res = { status: sinon_1.default.stub().returns({ json: sinon_1.default.stub() }) };
|
|
91
|
+
fetchStub.rejects(new Error('Failed to retrieve access token'));
|
|
92
|
+
await oauth2Helper['handleToken'](req, res);
|
|
93
|
+
sinon_1.default.assert.calledWith(res.status, 500);
|
|
94
|
+
});
|
|
95
|
+
it('should return an error 400 if the request content type is not supported', async () => {
|
|
96
|
+
const req = { query: {} };
|
|
97
|
+
const res = { status: sinon_1.default.stub().returns({ json: sinon_1.default.stub() }) };
|
|
98
|
+
oauth2Helper['requestContentType'] = 'random';
|
|
99
|
+
await oauth2Helper['handleToken'](req, res);
|
|
100
|
+
sinon_1.default.assert.calledWith(res.status, 400);
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
describe('updateToken', () => {
|
|
104
|
+
it('should throw an error when no refresh token is available', async () => {
|
|
105
|
+
const response = oauth2Helper.updateToken();
|
|
106
|
+
await (0, chai_1.expect)(response).to.be.rejectedWith(errors_1.NoRefreshTokenError);
|
|
107
|
+
});
|
|
108
|
+
it('should retrieve the access token when a refresh token is available', async () => {
|
|
109
|
+
const refreshToken = 'test-refresh-token';
|
|
110
|
+
oauth2Helper['refreshToken'] = refreshToken;
|
|
111
|
+
const accessToken = 'test-access-token';
|
|
112
|
+
const fetchResponse = { access_token: accessToken, refresh_token: refreshToken };
|
|
113
|
+
fetchStub.resolves({ status: 200, json: sinon_1.default.stub().resolves(fetchResponse) });
|
|
114
|
+
const result = await oauth2Helper.updateToken();
|
|
115
|
+
(0, chai_1.expect)(result).to.deep.equal({ accessToken, refreshToken });
|
|
116
|
+
sinon_1.default.assert.calledOnce(fetchStub);
|
|
117
|
+
});
|
|
118
|
+
it('should throw an error when failing to refresh the access token', async () => {
|
|
119
|
+
const refreshToken = 'test-refresh-token';
|
|
120
|
+
oauth2Helper['refreshToken'] = refreshToken;
|
|
121
|
+
fetchStub.rejects(new Error('Failed to retrieve access token'));
|
|
122
|
+
const response = oauth2Helper.updateToken();
|
|
123
|
+
await (0, chai_1.expect)(response).to.be.rejectedWith(errors_1.FailedToRetrieveAccessTokenError);
|
|
124
|
+
sinon_1.default.assert.calledOnce(fetchStub);
|
|
125
|
+
});
|
|
126
|
+
it("should throw an error if we don't support the request content type", async () => {
|
|
127
|
+
const refreshToken = 'test-refresh-token';
|
|
128
|
+
oauth2Helper['refreshToken'] = refreshToken;
|
|
129
|
+
oauth2Helper['requestContentType'] = 'random';
|
|
130
|
+
const response = oauth2Helper.updateToken();
|
|
131
|
+
await (0, chai_1.expect)(response).to.be.rejectedWith(errors_1.InvalidRequestContentTypeError);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
describe('encodeBody', () => {
|
|
135
|
+
it('should encode body data as URL-encoded when content type is URL_ENCODED', () => {
|
|
136
|
+
const bodyData = { key1: 'value1', key2: 'value2' };
|
|
137
|
+
const contentType = configurationTypes_1.RequestContentType.URL_ENCODED;
|
|
138
|
+
const expectedEncodedBody = 'key1=value1&key2=value2';
|
|
139
|
+
const encodedBody = oauth2Helper['encodeBody'](bodyData, contentType);
|
|
140
|
+
(0, chai_1.expect)(encodedBody).to.equal(expectedEncodedBody);
|
|
141
|
+
});
|
|
142
|
+
it('should encode body data as JSON when content type is JSON', () => {
|
|
143
|
+
const bodyData = { key1: 'value1', key2: 'value2' };
|
|
144
|
+
const contentType = configurationTypes_1.RequestContentType.JSON;
|
|
145
|
+
const expectedEncodedBody = JSON.stringify(bodyData);
|
|
146
|
+
const encodedBody = oauth2Helper['encodeBody'](bodyData, contentType);
|
|
147
|
+
(0, chai_1.expect)(encodedBody).to.equal(expectedEncodedBody);
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|