@unito/integration-cli 0.57.1 → 0.58.0
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/dist/.eslintrc.d.ts +6 -0
- package/dist/.eslintrc.js +9 -2
- package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/src/index.ts +1 -3
- package/dist/src/commands/activity.d.ts +2 -2
- package/dist/src/commands/activity.js +2 -2
- package/dist/src/commands/dev.d.ts +8 -4
- package/dist/src/commands/dev.js +42 -5
- package/dist/src/commands/encrypt.d.ts +1 -1
- package/dist/src/commands/encrypt.js +1 -1
- package/dist/src/commands/init.d.ts +1 -1
- package/dist/src/commands/init.js +3 -3
- package/dist/src/commands/invite.d.ts +1 -1
- package/dist/src/commands/invite.js +2 -2
- package/dist/src/commands/login.d.ts +1 -1
- package/dist/src/commands/login.js +1 -1
- package/dist/src/commands/oauth2.d.ts +3 -3
- package/dist/src/commands/oauth2.js +19 -14
- package/dist/src/commands/publish.d.ts +2 -2
- package/dist/src/commands/publish.js +12 -12
- package/dist/src/commands/test.js +32 -8
- package/dist/src/commands/upgrade.js +3 -3
- package/dist/src/errors.d.ts +8 -0
- package/dist/src/errors.js +35 -18
- package/dist/src/resources/configuration.js +0 -2
- package/dist/src/resources/credentials.d.ts +3 -0
- package/dist/src/resources/credentials.js +26 -0
- package/dist/src/resources/integrations.d.ts +1 -0
- package/dist/src/resources/integrations.js +37 -2
- package/dist/src/resources/oauth2Helper.d.ts +4 -0
- package/dist/src/resources/oauth2Helper.js +30 -0
- package/dist/src/services/integrationsPlatform.d.ts +1 -0
- package/dist/src/services/integrationsPlatform.js +5 -1
- package/dist/src/services/oauth2Helper.d.ts +78 -3
- package/dist/src/services/oauth2Helper.js +229 -29
- package/dist/test/commands/activity.test.js +12 -9
- package/dist/test/commands/dev.test.js +59 -10
- package/dist/test/commands/encrypt.test.js +6 -7
- package/dist/test/commands/init.test.js +7 -9
- package/dist/test/commands/invite.test.js +11 -11
- package/dist/test/commands/login.test.js +20 -23
- package/dist/test/commands/oauth2.test.js +6 -2
- package/dist/test/commands/publish.test.js +152 -218
- package/dist/test/commands/test.test.js +65 -13
- package/dist/test/commands/upgrade.test.js +4 -6
- package/dist/test/errors.test.js +36 -36
- package/dist/test/helpers/integrations.d.ts +26 -0
- package/dist/test/helpers/integrations.js +25 -0
- package/dist/test/helpers/styles.d.ts +1 -0
- package/dist/test/helpers/styles.js +8 -0
- package/dist/test/oauth2Helper/oauth2Helper.test.js +112 -128
- package/dist/test/resources/configuration.test.js +24 -24
- package/dist/test/resources/decryption.test.js +9 -9
- package/dist/test/resources/globalConfiguration.test.js +4 -4
- package/dist/test/resources/integrations.test.js +37 -0
- package/dist/test/resources/oauth2Helper.test.js +55 -0
- package/dist/test/services/integrationsPlatform.test.js +20 -20
- package/oclif.manifest.json +64 -9
- package/package.json +10 -14
- package/dist/integrationGenerator/errors.d.ts +0 -2
- package/dist/integrationGenerator/errors.js +0 -6
- package/dist/integrationGenerator/index.d.ts +0 -2
- package/dist/integrationGenerator/index.js +0 -5
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.dockerignore +0 -3
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.eslintrc.js +0 -74
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.nvmrc +0 -1
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.prettierignore +0 -1
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.prettierrc +0 -7
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.unito.json +0 -1
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/Dockerfile +0 -38
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/README.md +0 -21
- package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/src/index.ts +0 -94
- package/dist/integrationGenerator/integrationBoilerplate/package.json +0 -43
- package/dist/integrationGenerator/integrationBoilerplate/src/logger.ts +0 -55
- package/dist/integrationGenerator/integrationBoilerplate/src/middlewares/additionalLoggingContext.ts +0 -22
- package/dist/integrationGenerator/integrationBoilerplate/src/middlewares/correlationId.ts +0 -13
- package/dist/integrationGenerator/integrationBoilerplate/src/middlewares/credentials.ts +0 -38
- package/dist/integrationGenerator/integrationBoilerplate/src/request.ts +0 -59
- package/dist/integrationGenerator/integrationBoilerplate/src/routes/index.ts +0 -11
- package/dist/integrationGenerator/integrationBoilerplate/src/routes/me.ts +0 -15
- package/dist/integrationGenerator/integrationBoilerplate/src/routes/root.ts +0 -12
- package/dist/integrationGenerator/integrationBoilerplate/tsconfig.json +0 -37
- package/dist/integrationGenerator/src/index.d.ts +0 -1
- package/dist/integrationGenerator/src/index.js +0 -5
- package/dist/integrationGenerator/src/resources/index.d.ts +0 -1
- package/dist/integrationGenerator/src/resources/index.js +0 -5
- package/dist/integrationGenerator/src/resources/integration.d.ts +0 -9
- package/dist/integrationGenerator/src/resources/integration.js +0 -60
- package/dist/integrationGenerator/test/resources/integration.test.js +0 -51
- package/dist/src/oauth2Helper/oauth2Helper.d.ts +0 -63
- package/dist/src/oauth2Helper/oauth2Helper.js +0 -235
- package/dist/src/oauth2Helper/types.d.ts +0 -22
- package/dist/src/oauth2Helper/types.js +0 -2
- package/dist/test/mocha.hooks.d.ts +0 -2
- package/dist/test/mocha.hooks.js +0 -37
- package/dist/test/services/oauth2Helper.test.js +0 -85
- /package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/.dockerignore +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/.eslintrc.js +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/.nvmrc +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/.prettierignore +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/.prettierrc +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/.unito.json +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/Dockerfile +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/README.md +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/package.json +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/src/logger.ts +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/src/middlewares/additionalLoggingContext.ts +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/src/middlewares/correlationId.ts +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/src/middlewares/credentials.ts +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/src/request.ts +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/src/routes/index.ts +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/src/routes/me.ts +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/src/routes/root.ts +0 -0
- /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/tsconfig.json +0 -0
- /package/dist/{integrationGenerator/test/resources/integration.test.d.ts → test/resources/integrations.test.d.ts} +0 -0
- /package/dist/test/{services → resources}/oauth2Helper.test.d.ts +0 -0
|
@@ -2,149 +2,133 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
5
|
-
const
|
|
5
|
+
const strict_1 = tslib_1.__importDefault(require("node:assert/strict"));
|
|
6
6
|
const sinon_1 = tslib_1.__importDefault(require("sinon"));
|
|
7
|
-
const oauth2Helper_1 = tslib_1.__importStar(require("../../src/
|
|
7
|
+
const oauth2Helper_1 = tslib_1.__importStar(require("../../src/services/oauth2Helper")), oauth2Namespace = oauth2Helper_1;
|
|
8
8
|
const configurationTypes_1 = require("../../src/configurationTypes");
|
|
9
9
|
const errors_1 = require("../../src/errors");
|
|
10
10
|
describe('OAuth2Helper', () => {
|
|
11
11
|
let oauth2Helper;
|
|
12
12
|
let openSpy;
|
|
13
13
|
let fetchStub;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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);
|
|
14
|
+
describe('constructor', () => {
|
|
15
|
+
it('should throw an error if the request content type is not supported', async () => {
|
|
16
|
+
try {
|
|
17
|
+
new oauth2Helper_1.default({ scopes: [], requestContentType: 'random' });
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
(0, strict_1.default)(err instanceof errors_1.UnsupportedContentTypeError);
|
|
21
|
+
}
|
|
70
22
|
});
|
|
71
23
|
});
|
|
72
|
-
describe('
|
|
73
|
-
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
24
|
+
describe('endpoints', () => {
|
|
25
|
+
beforeEach(() => {
|
|
26
|
+
const authorizationInfo = {
|
|
27
|
+
clientId: 'your-client-id',
|
|
28
|
+
clientSecret: 'your-client-secret',
|
|
29
|
+
authorizationUrl: 'https://provider.com/oauth/authorize',
|
|
30
|
+
scopes: [{ name: 'scope1' }, { name: 'scope2' }],
|
|
31
|
+
tokenUrl: 'https://provider.com/oauth/token',
|
|
32
|
+
grantType: configurationTypes_1.GrantType.AUTHORIZATION_CODE,
|
|
33
|
+
requestContentType: configurationTypes_1.RequestContentType.URL_ENCODED,
|
|
34
|
+
responseContentType: configurationTypes_1.RequestContentType.JSON,
|
|
35
|
+
tokenRequestParameters: {
|
|
36
|
+
header: {
|
|
37
|
+
Authorization: 'custom',
|
|
38
|
+
},
|
|
82
39
|
},
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
});
|
|
86
|
-
sinon_1.default.
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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);
|
|
40
|
+
};
|
|
41
|
+
oauth2Helper = new oauth2Helper_1.default(authorizationInfo);
|
|
42
|
+
fetchStub = sinon_1.default.stub().resolves({ json: sinon_1.default.stub().resolves({}), status: 200 });
|
|
43
|
+
sinon_1.default.stub(oauth2Helper, 'startServer').resolves('http://localhost:5050');
|
|
44
|
+
sinon_1.default.stub(oauth2Helper, 'stopServer');
|
|
45
|
+
sinon_1.default.replace(global, 'fetch', fetchStub);
|
|
46
|
+
sinon_1.default.replace(oauth2Namespace, 'open', { open: (_url) => undefined });
|
|
47
|
+
openSpy = sinon_1.default.stub(oauth2Namespace.open, 'open');
|
|
107
48
|
});
|
|
108
|
-
|
|
109
|
-
|
|
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);
|
|
49
|
+
afterEach(() => {
|
|
50
|
+
sinon_1.default.restore();
|
|
117
51
|
});
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
52
|
+
describe('handleAuthorize', () => {
|
|
53
|
+
it('should open the authorization URL', async () => {
|
|
54
|
+
await oauth2Helper.authorize();
|
|
55
|
+
sinon_1.default.assert.calledOnce(openSpy);
|
|
56
|
+
sinon_1.default.assert.calledWith(openSpy, 'https://provider.com/oauth/authorize?client_id=your-client-id&redirect_uri=https%3A%2F%2Fintegrations-platform.unito.io%2Fcredentials%2Fnew%2Foauth2%2Fcallback-cli&state=eyJjbGlDYWxsYmFja1VybCI6Ii9vYXV0aDIvY2FsbGJhY2sifQ%3D%3D&scope=scope1+scope2&response_type=code');
|
|
57
|
+
});
|
|
58
|
+
it('should maintain the pre-existing query parameters in authorization URL', async () => {
|
|
59
|
+
oauth2Helper['providerAuthorizationUrl'] = 'https://provider.com/oauth/authorize?query1=value1&query2=value2';
|
|
60
|
+
await oauth2Helper.authorize();
|
|
61
|
+
sinon_1.default.assert.calledOnce(openSpy);
|
|
62
|
+
sinon_1.default.assert.calledWith(openSpy, 'https://provider.com/oauth/authorize?query1=value1&query2=value2&client_id=your-client-id&redirect_uri=https%3A%2F%2Fintegrations-platform.unito.io%2Fcredentials%2Fnew%2Foauth2%2Fcallback-cli&state=eyJjbGlDYWxsYmFja1VybCI6Ii9vYXV0aDIvY2FsbGJhY2sifQ%3D%3D&scope=scope1+scope2&response_type=code');
|
|
63
|
+
});
|
|
125
64
|
});
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
65
|
+
describe('handleCallback', () => {
|
|
66
|
+
it('should retrieve the access token and return it in the response', async () => {
|
|
67
|
+
const code = 'test-code';
|
|
68
|
+
const req = { query: { code } };
|
|
69
|
+
const res = { send: sinon_1.default.stub(), setHeader: sinon_1.default.stub() };
|
|
70
|
+
await oauth2Helper['handleCallback'](req, res);
|
|
71
|
+
sinon_1.default.assert.calledOnce(fetchStub);
|
|
72
|
+
sinon_1.default.assert.calledWith(fetchStub, 'https://provider.com/oauth/token', {
|
|
73
|
+
headers: {
|
|
74
|
+
'Content-type': 'application/x-www-form-urlencoded',
|
|
75
|
+
Authorization: 'custom',
|
|
76
|
+
},
|
|
77
|
+
body: sinon_1.default.match.string,
|
|
78
|
+
method: 'POST',
|
|
79
|
+
});
|
|
80
|
+
sinon_1.default.assert.calledOnce(res.send);
|
|
81
|
+
sinon_1.default.assert.calledWith(res.send, oauth2Namespace.HTML_SUCCESS_MSG);
|
|
82
|
+
});
|
|
83
|
+
it('should handle errors and return 500 status', async () => {
|
|
84
|
+
const code = 'test-code';
|
|
85
|
+
const req = { query: { code } };
|
|
86
|
+
const res = { send: sinon_1.default.stub(), setHeader: sinon_1.default.stub() };
|
|
87
|
+
fetchStub.rejects(new Error('Failed to retrieve access token'));
|
|
88
|
+
await oauth2Helper['handleCallback'](req, res);
|
|
89
|
+
sinon_1.default.assert.calledOnce(res.send);
|
|
90
|
+
sinon_1.default.assert.calledWith(res.send, oauth2Namespace.HTML_ERROR_MSG);
|
|
91
|
+
});
|
|
132
92
|
});
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
93
|
+
describe('updateToken', () => {
|
|
94
|
+
it('should retrieve the access token when a refresh token is available', async () => {
|
|
95
|
+
const refreshToken = 'test-refresh-token';
|
|
96
|
+
const accessToken = 'test-access-token';
|
|
97
|
+
const fetchResponse = { access_token: accessToken, refresh_token: refreshToken };
|
|
98
|
+
fetchStub.resolves({ status: 200, json: sinon_1.default.stub().resolves(fetchResponse) });
|
|
99
|
+
const result = await oauth2Helper.updateToken(refreshToken);
|
|
100
|
+
strict_1.default.deepEqual(result, { accessToken, refreshToken });
|
|
101
|
+
sinon_1.default.assert.calledOnce(fetchStub);
|
|
102
|
+
});
|
|
103
|
+
it('should throw an error when failing to refresh the access token', async () => {
|
|
104
|
+
const refreshToken = 'test-refresh-token';
|
|
105
|
+
fetchStub.rejects(new Error('Failed to retrieve access token'));
|
|
106
|
+
const response = oauth2Helper.updateToken(refreshToken);
|
|
107
|
+
await strict_1.default.rejects(response, errors_1.FailedToRetrieveAccessTokenError);
|
|
108
|
+
sinon_1.default.assert.calledOnce(fetchStub);
|
|
109
|
+
});
|
|
110
|
+
it("should throw an error if we don't support the request content type", async () => {
|
|
111
|
+
const refreshToken = 'test-refresh-token';
|
|
112
|
+
oauth2Helper['requestContentType'] = 'random';
|
|
113
|
+
const response = oauth2Helper.updateToken(refreshToken);
|
|
114
|
+
await strict_1.default.rejects(response, errors_1.InvalidRequestContentTypeError);
|
|
115
|
+
});
|
|
141
116
|
});
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
117
|
+
describe('encodeBody', () => {
|
|
118
|
+
it('should encode body data as URL-encoded when content type is URL_ENCODED', () => {
|
|
119
|
+
const bodyData = { key1: 'value1', key2: 'value2' };
|
|
120
|
+
const contentType = configurationTypes_1.RequestContentType.URL_ENCODED;
|
|
121
|
+
const expectedEncodedBody = 'key1=value1&key2=value2';
|
|
122
|
+
const encodedBody = oauth2Helper['encodeBody'](bodyData, contentType);
|
|
123
|
+
strict_1.default.equal(encodedBody, expectedEncodedBody);
|
|
124
|
+
});
|
|
125
|
+
it('should encode body data as JSON when content type is JSON', () => {
|
|
126
|
+
const bodyData = { key1: 'value1', key2: 'value2' };
|
|
127
|
+
const contentType = configurationTypes_1.RequestContentType.JSON;
|
|
128
|
+
const expectedEncodedBody = JSON.stringify(bodyData);
|
|
129
|
+
const encodedBody = oauth2Helper['encodeBody'](bodyData, contentType);
|
|
130
|
+
strict_1.default.equal(encodedBody, expectedEncodedBody);
|
|
131
|
+
});
|
|
148
132
|
});
|
|
149
133
|
});
|
|
150
134
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
|
-
const
|
|
4
|
+
const strict_1 = tslib_1.__importDefault(require("node:assert/strict"));
|
|
5
5
|
const tmp_1 = tslib_1.__importDefault(require("tmp"));
|
|
6
6
|
const fs_1 = tslib_1.__importDefault(require("fs"));
|
|
7
7
|
const sinon = tslib_1.__importStar(require("sinon"));
|
|
@@ -41,19 +41,19 @@ describe('configuration', () => {
|
|
|
41
41
|
throw Error('Should have thrown NoConfigurationFileError');
|
|
42
42
|
}
|
|
43
43
|
catch (error) {
|
|
44
|
-
(0,
|
|
44
|
+
(0, strict_1.default)(error instanceof errors_2.NoConfigurationFileError);
|
|
45
45
|
}
|
|
46
46
|
});
|
|
47
47
|
it('handles missing specific environment file', async () => {
|
|
48
48
|
const configuration = await Configuration.getConfiguration(globalConfiguration_1.Environment.Staging);
|
|
49
|
-
|
|
49
|
+
strict_1.default.equal(configuration.name, originalConfiguration.name);
|
|
50
50
|
});
|
|
51
51
|
it('returns existing specific environment file', async () => {
|
|
52
52
|
await fs_1.default.promises.writeFile(`${process.cwd()}/.unito.${globalConfiguration_1.Environment.Staging}.json`, JSON.stringify({
|
|
53
53
|
name: 'foo',
|
|
54
54
|
}, null, 2));
|
|
55
55
|
const configuration = await Configuration.getConfiguration(globalConfiguration_1.Environment.Staging);
|
|
56
|
-
|
|
56
|
+
strict_1.default.equal(configuration.name, 'foo');
|
|
57
57
|
});
|
|
58
58
|
it('throws on missing custom configuration file', async () => {
|
|
59
59
|
try {
|
|
@@ -61,7 +61,7 @@ describe('configuration', () => {
|
|
|
61
61
|
throw Error('Should have thrown NoConfigurationFileError');
|
|
62
62
|
}
|
|
63
63
|
catch (error) {
|
|
64
|
-
(0,
|
|
64
|
+
(0, strict_1.default)(error instanceof errors_2.NoConfigurationFileError);
|
|
65
65
|
}
|
|
66
66
|
});
|
|
67
67
|
it('returns existing specific environment file', async () => {
|
|
@@ -69,7 +69,7 @@ describe('configuration', () => {
|
|
|
69
69
|
name: 'foo',
|
|
70
70
|
}, null, 2));
|
|
71
71
|
const configuration = await Configuration.getConfiguration(globalConfiguration_1.Environment.Staging, '/custom-config.json');
|
|
72
|
-
|
|
72
|
+
strict_1.default.equal(configuration.name, 'foo');
|
|
73
73
|
});
|
|
74
74
|
it('sets default values for "oauth2"', async () => {
|
|
75
75
|
await fs_1.default.promises.writeFile(Configuration.getConfigurationPath(), JSON.stringify({
|
|
@@ -90,9 +90,9 @@ describe('configuration', () => {
|
|
|
90
90
|
}, null, 2));
|
|
91
91
|
const configuration = await Configuration.getConfiguration(globalConfiguration_1.Environment.Production);
|
|
92
92
|
const oauth2 = configuration.authorizations?.at(0)?.oauth2;
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
93
|
+
strict_1.default.equal(oauth2?.requestContentType, configurationTypes_1.RequestContentType.URL_ENCODED);
|
|
94
|
+
strict_1.default.equal(oauth2?.responseContentType, configurationTypes_1.RequestContentType.JSON);
|
|
95
|
+
strict_1.default.equal(oauth2?.grantType, configurationTypes_1.GrantType.AUTHORIZATION_CODE);
|
|
96
96
|
});
|
|
97
97
|
it('accepts password grant for "oauth2"', async () => {
|
|
98
98
|
await fs_1.default.promises.writeFile(Configuration.getConfigurationPath(), JSON.stringify({
|
|
@@ -114,7 +114,7 @@ describe('configuration', () => {
|
|
|
114
114
|
}, null, 2));
|
|
115
115
|
const configuration = await Configuration.getConfiguration(globalConfiguration_1.Environment.Production);
|
|
116
116
|
const oauth2 = configuration.authorizations?.at(0)?.oauth2;
|
|
117
|
-
|
|
117
|
+
strict_1.default.equal(oauth2?.grantType, configurationTypes_1.GrantType.PASSWORD);
|
|
118
118
|
});
|
|
119
119
|
it('accepts request parameters for "oauth2"', async () => {
|
|
120
120
|
await fs_1.default.promises.writeFile(Configuration.getConfigurationPath(), JSON.stringify({
|
|
@@ -149,7 +149,7 @@ describe('configuration', () => {
|
|
|
149
149
|
}, null, 2));
|
|
150
150
|
const configuration = await Configuration.getConfiguration(globalConfiguration_1.Environment.Production);
|
|
151
151
|
const oauth2 = configuration.authorizations?.at(0)?.oauth2;
|
|
152
|
-
|
|
152
|
+
strict_1.default.deepEqual(oauth2?.tokenRequestParameters, {
|
|
153
153
|
header: {
|
|
154
154
|
a: 'yo',
|
|
155
155
|
},
|
|
@@ -157,7 +157,7 @@ describe('configuration', () => {
|
|
|
157
157
|
b: false,
|
|
158
158
|
},
|
|
159
159
|
});
|
|
160
|
-
|
|
160
|
+
strict_1.default.deepEqual(oauth2?.refreshRequestParameters, {
|
|
161
161
|
body: {
|
|
162
162
|
c: 1,
|
|
163
163
|
},
|
|
@@ -172,7 +172,7 @@ describe('configuration', () => {
|
|
|
172
172
|
},
|
|
173
173
|
}, null, 2));
|
|
174
174
|
const configuration = await Configuration.getConfiguration(globalConfiguration_1.Environment.Production);
|
|
175
|
-
|
|
175
|
+
strict_1.default.deepEqual(configuration.secrets, { foo: 'unito-secret-v1://bar' });
|
|
176
176
|
});
|
|
177
177
|
it('invalid secret - type', async () => {
|
|
178
178
|
await fs_1.default.promises.writeFile(Configuration.getConfigurationPath(), JSON.stringify({
|
|
@@ -181,7 +181,7 @@ describe('configuration', () => {
|
|
|
181
181
|
foo: 123,
|
|
182
182
|
},
|
|
183
183
|
}, null, 2));
|
|
184
|
-
await
|
|
184
|
+
await strict_1.default.rejects(Configuration.getConfiguration(globalConfiguration_1.Environment.Production), errors_1.ConfigurationInvalid);
|
|
185
185
|
});
|
|
186
186
|
it('invalid secret - pattern', async () => {
|
|
187
187
|
await fs_1.default.promises.writeFile(Configuration.getConfigurationPath(), JSON.stringify({
|
|
@@ -190,7 +190,7 @@ describe('configuration', () => {
|
|
|
190
190
|
foo: 'nope',
|
|
191
191
|
},
|
|
192
192
|
}, null, 2));
|
|
193
|
-
await
|
|
193
|
+
await strict_1.default.rejects(Configuration.getConfiguration(globalConfiguration_1.Environment.Production), errors_1.ConfigurationInvalid);
|
|
194
194
|
});
|
|
195
195
|
});
|
|
196
196
|
describe('validates test accounts - custom', () => {
|
|
@@ -245,8 +245,8 @@ describe('configuration', () => {
|
|
|
245
245
|
const configuration = await Configuration.getConfiguration(globalConfiguration_1.Environment.Production);
|
|
246
246
|
const developmentKey = configuration.testAccounts?.development?.apiKey;
|
|
247
247
|
const complianceKey = configuration.testAccounts?.compliance?.apiKey;
|
|
248
|
-
|
|
249
|
-
|
|
248
|
+
strict_1.default.equal(developmentKey, 'xyz');
|
|
249
|
+
strict_1.default.equal(complianceKey, 'xyzw');
|
|
250
250
|
});
|
|
251
251
|
it('invalid test accounts', async () => {
|
|
252
252
|
await fs_1.default.promises.writeFile(Configuration.getConfigurationPath(), JSON.stringify({
|
|
@@ -284,7 +284,7 @@ describe('configuration', () => {
|
|
|
284
284
|
},
|
|
285
285
|
},
|
|
286
286
|
}, null, 2));
|
|
287
|
-
await
|
|
287
|
+
await strict_1.default.rejects(Configuration.getConfiguration(globalConfiguration_1.Environment.Production), errors_1.ConfigurationInvalid);
|
|
288
288
|
});
|
|
289
289
|
});
|
|
290
290
|
describe('validates test accounts - oauth', () => {
|
|
@@ -364,8 +364,8 @@ describe('configuration', () => {
|
|
|
364
364
|
const configuration = await Configuration.getConfiguration(globalConfiguration_1.Environment.Production);
|
|
365
365
|
const developmentKey = configuration.testAccounts?.development?.accessToken;
|
|
366
366
|
const complianceKey = configuration.testAccounts?.compliance?.accessToken;
|
|
367
|
-
|
|
368
|
-
|
|
367
|
+
strict_1.default.equal(developmentKey, 'Super_Secret_token');
|
|
368
|
+
strict_1.default.equal(complianceKey, 'Super_Secret_token_2');
|
|
369
369
|
});
|
|
370
370
|
it('invalid test accounts', async () => {
|
|
371
371
|
await fs_1.default.promises.writeFile(Configuration.getConfigurationPath(), JSON.stringify({
|
|
@@ -415,7 +415,7 @@ describe('configuration', () => {
|
|
|
415
415
|
},
|
|
416
416
|
},
|
|
417
417
|
}, null, 2));
|
|
418
|
-
await
|
|
418
|
+
await strict_1.default.rejects(Configuration.getConfiguration(globalConfiguration_1.Environment.Production), errors_1.ConfigurationInvalid);
|
|
419
419
|
});
|
|
420
420
|
});
|
|
421
421
|
describe('validates test accounts - multiple authorization methods', () => {
|
|
@@ -509,8 +509,8 @@ describe('configuration', () => {
|
|
|
509
509
|
const configuration = await Configuration.getConfiguration(globalConfiguration_1.Environment.Production);
|
|
510
510
|
const developmentKey = configuration.testAccounts?.development?.accessToken;
|
|
511
511
|
const complianceKey = configuration.testAccounts?.compliance?.apiKey;
|
|
512
|
-
|
|
513
|
-
|
|
512
|
+
strict_1.default.equal(developmentKey, 'Super_Secret_token');
|
|
513
|
+
strict_1.default.equal(complianceKey, 'Super_Secret_api_key_2');
|
|
514
514
|
});
|
|
515
515
|
it('invalid test accounts', async () => {
|
|
516
516
|
await fs_1.default.promises.writeFile(Configuration.getConfigurationPath(), JSON.stringify({
|
|
@@ -579,7 +579,7 @@ describe('configuration', () => {
|
|
|
579
579
|
},
|
|
580
580
|
},
|
|
581
581
|
}, null, 2));
|
|
582
|
-
await
|
|
582
|
+
await strict_1.default.rejects(Configuration.getConfiguration(globalConfiguration_1.Environment.Production), errors_1.ConfigurationInvalid);
|
|
583
583
|
});
|
|
584
584
|
});
|
|
585
585
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
|
-
const
|
|
4
|
+
const strict_1 = tslib_1.__importDefault(require("node:assert/strict"));
|
|
5
5
|
const sinon_1 = tslib_1.__importDefault(require("sinon"));
|
|
6
6
|
const IntegrationsPlatformResources = tslib_1.__importStar(require("../../src/resources/integrationsPlatform"));
|
|
7
7
|
const IntegrationsPlatform = tslib_1.__importStar(require("../../src/services/integrationsPlatform"));
|
|
@@ -40,8 +40,8 @@ describe('decryption helper', () => {
|
|
|
40
40
|
accessToken: 'developmentToken',
|
|
41
41
|
accessToken1: 'developmentToken1',
|
|
42
42
|
});
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
strict_1.default.deepEqual(decryptionResult.decryptedKeys, []);
|
|
44
|
+
strict_1.default.deepEqual(decryptionResult.entries, {
|
|
45
45
|
accessToken1: 'developmentToken1',
|
|
46
46
|
accessToken: 'developmentToken',
|
|
47
47
|
});
|
|
@@ -51,8 +51,8 @@ describe('decryption helper', () => {
|
|
|
51
51
|
accessToken: 'token',
|
|
52
52
|
encryptedToken: `${configuration_1.ENCRYPTION_PREFIX}decrypt-me`,
|
|
53
53
|
});
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
strict_1.default.deepEqual(decryptionResult.decryptedKeys, ['encryptedToken']);
|
|
55
|
+
strict_1.default.deepEqual(decryptionResult.entries, {
|
|
56
56
|
accessToken: 'token',
|
|
57
57
|
encryptedToken: `decrypted-me`,
|
|
58
58
|
});
|
|
@@ -62,16 +62,16 @@ describe('decryption helper', () => {
|
|
|
62
62
|
encryptedSecret1: `${configuration_1.ENCRYPTION_PREFIX}decrypt-me`,
|
|
63
63
|
encryptedSecret2: `${configuration_1.ENCRYPTION_PREFIX}decrypt-me`,
|
|
64
64
|
});
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
strict_1.default.deepEqual(decryptionResult.decryptedKeys, ['encryptedSecret1', 'encryptedSecret2']);
|
|
66
|
+
strict_1.default.deepEqual(decryptionResult.entries, {
|
|
67
67
|
encryptedSecret1: 'decrypted-me',
|
|
68
68
|
encryptedSecret2: 'decrypted-me',
|
|
69
69
|
});
|
|
70
70
|
});
|
|
71
71
|
it('support empty object', async () => {
|
|
72
72
|
const decryptionResult = await decryptionHelper.decryptEntries(configuration.name, GlobalConfiguration.Environment.Local, '/path/to/config', {});
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
strict_1.default.deepEqual(decryptionResult.decryptedKeys, []);
|
|
74
|
+
strict_1.default.deepEqual(decryptionResult.entries, {});
|
|
75
75
|
});
|
|
76
76
|
});
|
|
77
77
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
|
-
const
|
|
4
|
+
const strict_1 = tslib_1.__importDefault(require("node:assert/strict"));
|
|
5
5
|
const fs_1 = tslib_1.__importDefault(require("fs"));
|
|
6
6
|
const sinon = tslib_1.__importStar(require("sinon"));
|
|
7
7
|
const GlobalConfiguration = tslib_1.__importStar(require("../../src/resources/globalConfiguration"));
|
|
@@ -10,16 +10,16 @@ describe('globalConfiguration', () => {
|
|
|
10
10
|
sinon.restore();
|
|
11
11
|
});
|
|
12
12
|
it('reads', async function () {
|
|
13
|
-
const configuration =
|
|
13
|
+
const configuration = GlobalConfiguration.getDefault();
|
|
14
14
|
configuration.apiKey = 'foo';
|
|
15
15
|
sinon.stub(fs_1.default.promises, 'mkdir').resolves('');
|
|
16
16
|
sinon.stub(fs_1.default.promises, 'readFile').resolves(JSON.stringify(configuration));
|
|
17
|
-
|
|
17
|
+
strict_1.default.deepEqual(await GlobalConfiguration.read('bar'), configuration);
|
|
18
18
|
});
|
|
19
19
|
it('reads - error', async function () {
|
|
20
20
|
sinon.stub(fs_1.default.promises, 'mkdir').resolves('');
|
|
21
21
|
sinon.stub(fs_1.default.promises, 'readFile').throws();
|
|
22
|
-
|
|
22
|
+
strict_1.default.deepEqual(await GlobalConfiguration.read('bar'), GlobalConfiguration.getDefault());
|
|
23
23
|
});
|
|
24
24
|
it('writes', async function () {
|
|
25
25
|
const configuration = GlobalConfiguration.getDefault();
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const strict_1 = tslib_1.__importDefault(require("node:assert/strict"));
|
|
5
|
+
const path = tslib_1.__importStar(require("path"));
|
|
6
|
+
const tmp_1 = tslib_1.__importDefault(require("tmp"));
|
|
7
|
+
const fs_1 = tslib_1.__importDefault(require("fs"));
|
|
8
|
+
const Integration = tslib_1.__importStar(require("../../src/resources/integrations"));
|
|
9
|
+
const errors_1 = require("../../src/errors");
|
|
10
|
+
describe('integrations', () => {
|
|
11
|
+
let tempDir;
|
|
12
|
+
const boilerplatePath = path.join(__dirname, '../../boilerplate');
|
|
13
|
+
describe('copyBoilerplate', () => {
|
|
14
|
+
beforeEach(() => {
|
|
15
|
+
tempDir = tmp_1.default.dirSync().name;
|
|
16
|
+
});
|
|
17
|
+
it('copy files', async () => {
|
|
18
|
+
const result = await Integration.copyBoilerplate('foo', tempDir);
|
|
19
|
+
strict_1.default.equal(result, path.join(tempDir, 'foo'));
|
|
20
|
+
(0, strict_1.default)(fs_1.default.existsSync(result));
|
|
21
|
+
const expectedFiles = await fs_1.default.promises.readdir(boilerplatePath);
|
|
22
|
+
expectedFiles.push('.npmrc');
|
|
23
|
+
const createdFiles = await fs_1.default.promises.readdir(result);
|
|
24
|
+
strict_1.default.deepEqual(createdFiles, expectedFiles.sort());
|
|
25
|
+
createdFiles.forEach(createdField => (0, strict_1.default)(expectedFiles.includes(createdField)));
|
|
26
|
+
});
|
|
27
|
+
it('already exists', async () => {
|
|
28
|
+
strict_1.default.doesNotThrow(async () => await Integration.copyBoilerplate('foo', tempDir));
|
|
29
|
+
strict_1.default.rejects(Integration.copyBoilerplate('foo', tempDir), errors_1.IntegrationAlreadyExistsError);
|
|
30
|
+
});
|
|
31
|
+
it('generates an .npmrc file', async () => {
|
|
32
|
+
const result = await Integration.copyBoilerplate('foo', tempDir);
|
|
33
|
+
const npmrc = await fs_1.default.promises.readFile(`${result}/.npmrc`, 'utf-8');
|
|
34
|
+
(0, strict_1.default)(npmrc.includes('engine-strict=true'));
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const strict_1 = tslib_1.__importDefault(require("node:assert/strict"));
|
|
5
|
+
const sinon_1 = tslib_1.__importDefault(require("sinon"));
|
|
6
|
+
const oauth2Helper_1 = tslib_1.__importDefault(require("../../src/services/oauth2Helper"));
|
|
7
|
+
const configurationTypes_1 = require("../../src/configurationTypes");
|
|
8
|
+
const oauth2HelperResource = tslib_1.__importStar(require("../../src/resources/oauth2Helper"));
|
|
9
|
+
const errors_1 = require("../../src/errors");
|
|
10
|
+
const inquirer_1 = tslib_1.__importDefault(require("inquirer"));
|
|
11
|
+
describe('OAuth2Helper', () => {
|
|
12
|
+
let fetchStub;
|
|
13
|
+
const authorizationInfo = {
|
|
14
|
+
clientId: 'your-client-id',
|
|
15
|
+
clientSecret: 'your-client-secret',
|
|
16
|
+
authorizationUrl: 'https://provider.com/oauth/authorize',
|
|
17
|
+
scopes: [{ name: 'scope1' }, { name: 'scope2' }],
|
|
18
|
+
tokenUrl: 'https://provider.com/oauth/token',
|
|
19
|
+
grantType: configurationTypes_1.GrantType.AUTHORIZATION_CODE,
|
|
20
|
+
requestContentType: configurationTypes_1.RequestContentType.URL_ENCODED,
|
|
21
|
+
responseContentType: configurationTypes_1.RequestContentType.JSON,
|
|
22
|
+
};
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
sinon_1.default.stub(oauth2Helper_1.default.prototype, 'startServer').resolves('http://localhost:5050');
|
|
25
|
+
sinon_1.default.stub(oauth2Helper_1.default.prototype, 'stopServer');
|
|
26
|
+
sinon_1.default.stub(oauth2Helper_1.default.prototype, 'authorize');
|
|
27
|
+
sinon_1.default.stub(inquirer_1.default, 'prompt');
|
|
28
|
+
});
|
|
29
|
+
afterEach(() => {
|
|
30
|
+
sinon_1.default.restore();
|
|
31
|
+
});
|
|
32
|
+
describe('performOAuth2Flow', () => {
|
|
33
|
+
it('should perform the oauth flow', async () => {
|
|
34
|
+
fetchStub = sinon_1.default.stub().onFirstCall().resolves({ status: 200 }).onSecondCall().resolves({ status: 200 });
|
|
35
|
+
sinon_1.default.replace(global, 'fetch', fetchStub);
|
|
36
|
+
sinon_1.default.stub(oauth2Helper_1.default.prototype, 'callbackIsDone').resolves({ accessToken: 'token' });
|
|
37
|
+
await oauth2HelperResource.performOAuth2Flow(authorizationInfo);
|
|
38
|
+
strict_1.default.equal(fetchStub.getCall(0).args.at(0), 'http://localhost:5050/health');
|
|
39
|
+
});
|
|
40
|
+
it('raises a FailedToRetrieveAccessTokenError', async () => {
|
|
41
|
+
fetchStub = sinon_1.default.stub().onFirstCall().resolves({ status: 200 }).onSecondCall().resolves({ status: 200 });
|
|
42
|
+
sinon_1.default.replace(global, 'fetch', fetchStub);
|
|
43
|
+
sinon_1.default.stub(oauth2Helper_1.default.prototype, 'callbackIsDone').resolves({});
|
|
44
|
+
const response = oauth2HelperResource.performOAuth2Flow(authorizationInfo);
|
|
45
|
+
await strict_1.default.rejects(response, errors_1.FailedToRetrieveAccessTokenError);
|
|
46
|
+
});
|
|
47
|
+
it('raises a FailedToRetrieveAccessTokenError when the accessToken is not returned', async () => {
|
|
48
|
+
fetchStub = sinon_1.default.stub().onFirstCall().resolves({ status: 200 }).onSecondCall().resolves({ status: 200 });
|
|
49
|
+
sinon_1.default.replace(global, 'fetch', fetchStub);
|
|
50
|
+
sinon_1.default.stub(oauth2Helper_1.default.prototype, 'callbackIsDone').resolves({});
|
|
51
|
+
const response = oauth2HelperResource.performOAuth2Flow(authorizationInfo);
|
|
52
|
+
await strict_1.default.rejects(response, errors_1.FailedToRetrieveAccessTokenError);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
});
|