@zohodesk/testinglibrary 0.0.66-n20-experimental → 0.0.68-n20-experimental
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/build/common/data-generator/steps/DataGenerator.spec.js +4 -8
- package/build/common/data-generator/steps/DataGeneratorStepsHelper.js +2 -2
- package/build/core/dataGenerator/DataGenerator.js +4 -9
- package/build/core/playwright/builtInFixtures/caseTimeout.js +20 -0
- package/build/core/playwright/builtInFixtures/index.js +3 -1
- package/build/core/playwright/helpers/browserTimeoutFactor.js +16 -0
- package/build/core/playwright/helpers/caseTimeoutResolver.js +37 -0
- package/build/core/playwright/readConfigFile.js +1 -1
- package/build/core/playwright/setup/config-utils.js +7 -4
- package/build/core/playwright/types.js +1 -1
- package/build/setup-folder-structure/samples/uat-config-sample.js +1 -1
- package/build/test/core/playwright/buildInFixtures/__tests__/caseTimeout.test.js +96 -0
- package/jest.config.js +1 -1
- package/npm-shrinkwrap.json +1726 -2785
- package/package.json +1 -1
- package/unit_reports/unit-report.html +1 -1
- package/build/core/dataGenerator/authenticator/Authenticator.js +0 -35
- package/build/core/dataGenerator/authenticator/CookieAuthenticator.js +0 -41
- package/build/core/dataGenerator/authenticator/JWTauthenticator.js +0 -71
- package/build/core/dataGenerator/authenticator/OAuthAuthenticator.js +0 -31
- package/build/core/dataGenerator/authenticator/OrgOAuthAuthenticator.js +0 -29
- package/build/test/core/dataGenerator/authenticator/__test__/Authenticator.test.js +0 -89
- package/build/test/core/dataGenerator/authenticator/__test__/JWTauthenticator.test.js +0 -134
- package/build/test/core/dataGenerator/authenticator/__test__/OAuthAuthenticator.test.js +0 -46
- package/build/test/core/dataGenerator/authenticator/__test__/OrgOAuthAuthenticator.test.js +0 -46
- package/build/test/core/dataGenerator/authenticator/__tests__/JWTauthenticator.test.js +0 -165
package/package.json
CHANGED
|
@@ -274,4 +274,4 @@ header {
|
|
|
274
274
|
font-size: 1rem;
|
|
275
275
|
padding: 0 0.5rem;
|
|
276
276
|
}
|
|
277
|
-
</style></head><body><main class="jesthtml-content"><header><h1 id="title">Unit Report</h1></header><section id="metadata-container"><div id="timestamp">Started: 2026-06-
|
|
277
|
+
</style></head><body><main class="jesthtml-content"><header><h1 id="title">Unit Report</h1></header><section id="metadata-container"><div id="timestamp">Started: 2026-06-03 18:32:48</div><div id="summary"><div id="suite-summary"><div class="summary-total">Suites (1)</div><div class="summary-passed ">1 passed</div><div class="summary-failed summary-empty">0 failed</div><div class="summary-pending summary-empty">0 pending</div></div><div id="test-summary"><div class="summary-total">Tests (12)</div><div class="summary-passed ">12 passed</div><div class="summary-failed summary-empty">0 failed</div><div class="summary-pending summary-empty">0 pending</div></div></div></section><details id="suite-1" class="suite-container" open=""><summary class="suite-info"><div class="suite-path">/Users/muthu-19817/git/testing-framework/src/test/core/playwright/buildInFixtures/__tests__/caseTimeout.test.js</div><div class="suite-time">0.367s</div></summary><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">resolveCaseTimeoutMs</div><div class="test-title">returns null when no timeout tag is present</div><div class="test-status">passed</div><div class="test-duration">0.001s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">resolveCaseTimeoutMs</div><div class="test-title">returns null when tags is not an array</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">resolveCaseTimeoutMs</div><div class="test-title">parses @timeout_<n> as seconds for Chrome (factor 1)</div><div class="test-status">passed</div><div class="test-duration">0.001s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">resolveCaseTimeoutMs</div><div class="test-title">applies Firefox 2x multiplier</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">resolveCaseTimeoutMs</div><div class="test-title">returns 0 (no timeout) when tag is @timeout_0, regardless of browser</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">resolveCaseTimeoutMs</div><div class="test-title">uses the first matching tag and logs a warning when multiple are present</div><div class="test-status">passed</div><div class="test-duration">0.001s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">resolveCaseTimeoutMs</div><div class="test-title">ignores malformed timeout-like tags</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">resolveCaseTimeoutMs</div><div class="test-title">ignores non-string entries in tags</div><div class="test-status">passed</div><div class="test-duration">0.001s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">caseTimeout fixture</div><div class="test-title">is registered as an auto fixture</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">caseTimeout fixture</div><div class="test-title">calls testInfo.setTimeout with scaled value when tag matches</div><div class="test-status">passed</div><div class="test-duration">0.001s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">caseTimeout fixture</div><div class="test-title">does not call testInfo.setTimeout when no tag is present</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">caseTimeout fixture</div><div class="test-title">passes 0 through to testInfo.setTimeout for @timeout_0</div><div class="test-status">passed</div><div class="test-duration">0.001s</div></div></div></div></details></main></body></html>
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = void 0;
|
|
7
|
-
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
8
|
-
class Authenticator {
|
|
9
|
-
// Only route authentication augmentations; do not modify environment or base payload here.
|
|
10
|
-
async constructPayload(apiPayload, actorInfo, page = null) {
|
|
11
|
-
var _actorInfo$dataGener;
|
|
12
|
-
const authenticationLoaders = {
|
|
13
|
-
'jwt-auth': () => Promise.resolve().then(() => _interopRequireWildcard(require('./JWTauthenticator.js'))),
|
|
14
|
-
oauth2: () => Promise.resolve().then(() => _interopRequireWildcard(require('./OAuthAuthenticator.js'))),
|
|
15
|
-
'org-oauth': () => Promise.resolve().then(() => _interopRequireWildcard(require('./OrgOAuthAuthenticator.js'))),
|
|
16
|
-
'cookie-auth': () => Promise.resolve().then(() => _interopRequireWildcard(require('./CookieAuthenticator.js')))
|
|
17
|
-
};
|
|
18
|
-
const authentications = (actorInfo === null || actorInfo === void 0 || (_actorInfo$dataGener = actorInfo['data-generator']) === null || _actorInfo$dataGener === void 0 || (_actorInfo$dataGener = _actorInfo$dataGener.account) === null || _actorInfo$dataGener === void 0 ? void 0 : _actorInfo$dataGener.authentications) || [];
|
|
19
|
-
const authenticationTypes = [...new Set(authentications.map(auth => String(auth).toLowerCase()).filter(Boolean))];
|
|
20
|
-
for (const authenticationType of authenticationTypes) {
|
|
21
|
-
const authenticatorLoader = authenticationLoaders[authenticationType];
|
|
22
|
-
if (!authenticatorLoader) {
|
|
23
|
-
continue;
|
|
24
|
-
}
|
|
25
|
-
const {
|
|
26
|
-
default: AuthenticatorClass
|
|
27
|
-
} = await authenticatorLoader();
|
|
28
|
-
const authenticatorInstance = new AuthenticatorClass();
|
|
29
|
-
apiPayload = await authenticatorInstance.constructPayload(apiPayload, actorInfo, page);
|
|
30
|
-
break;
|
|
31
|
-
}
|
|
32
|
-
return apiPayload;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
exports.default = Authenticator;
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
-
Object.defineProperty(exports, "__esModule", {
|
|
5
|
-
value: true
|
|
6
|
-
});
|
|
7
|
-
exports.default = void 0;
|
|
8
|
-
var _Authenticator = _interopRequireDefault(require("./Authenticator.js"));
|
|
9
|
-
/**
|
|
10
|
-
* CookieAuthenticator prepares the payload for cookie-based authentication.
|
|
11
|
-
* It extracts cookies from the browser page context and attaches them
|
|
12
|
-
* as cookieAuthHeaders in the account block for the data generator service.
|
|
13
|
-
*/
|
|
14
|
-
class CookieAuthenticator extends _Authenticator.default {
|
|
15
|
-
async constructPayload(apiPayload, actorInfo, page = null) {
|
|
16
|
-
apiPayload.account = apiPayload.account || {};
|
|
17
|
-
if (page) {
|
|
18
|
-
const {
|
|
19
|
-
crmcsrToken,
|
|
20
|
-
cookieString
|
|
21
|
-
} = await _getCookies.call(CookieAuthenticator, page);
|
|
22
|
-
apiPayload.account.authHeaders = {
|
|
23
|
-
Cookie: cookieString,
|
|
24
|
-
'X-ZCSRF-TOKEN': crmcsrToken
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
return apiPayload;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
async function _getCookies(page) {
|
|
31
|
-
const context = page.context();
|
|
32
|
-
const pageUrl = new URL(page.url());
|
|
33
|
-
const currentDomain = pageUrl.hostname;
|
|
34
|
-
const cookies = await context.cookies([page.url()]);
|
|
35
|
-
const crmcsrCookie = cookies.filter(cookie => cookie.domain.includes(currentDomain) && cookie.name === 'crmcsr');
|
|
36
|
-
return {
|
|
37
|
-
crmcsrToken: crmcsrCookie.map(c => `crmcsrfparam=${c.value}`).join('; '),
|
|
38
|
-
cookieString: cookies.map(c => `${c.name}=${c.value}`).join('; ')
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
var _default = exports.default = CookieAuthenticator;
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
-
Object.defineProperty(exports, "__esModule", {
|
|
5
|
-
value: true
|
|
6
|
-
});
|
|
7
|
-
exports.default = void 0;
|
|
8
|
-
var _Authenticator = _interopRequireDefault(require("./Authenticator.js"));
|
|
9
|
-
/**
|
|
10
|
-
* JWTauthenticator constructs payload by fetching a JWT access token
|
|
11
|
-
* from the authenticator app and attaching it to the account.jwt config.
|
|
12
|
-
*/
|
|
13
|
-
class JWTauthenticator extends _Authenticator.default {
|
|
14
|
-
async constructPayload(apiPayload, actorInfo) {
|
|
15
|
-
const dg = (actorInfo === null || actorInfo === void 0 ? void 0 : actorInfo['data-generator']) || {};
|
|
16
|
-
const account = (dg === null || dg === void 0 ? void 0 : dg.account) || (apiPayload === null || apiPayload === void 0 ? void 0 : apiPayload.account) || {};
|
|
17
|
-
const jwtConf = account === null || account === void 0 ? void 0 : account['jwt-oauth'];
|
|
18
|
-
|
|
19
|
-
// If jwt config is not present, nothing to do
|
|
20
|
-
if (!jwtConf) {
|
|
21
|
-
return apiPayload;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// Build payload for authenticator service
|
|
25
|
-
const userToken = encodeURIComponent((actorInfo === null || actorInfo === void 0 ? void 0 : actorInfo.email) || '');
|
|
26
|
-
const jwtAuthUrl = process.env.DG_JWT_AUTH_URL;
|
|
27
|
-
const responseType = jwtConf.response_type;
|
|
28
|
-
const clientId = jwtConf.client_id;
|
|
29
|
-
|
|
30
|
-
// Resolve token_url from config or settings template
|
|
31
|
-
let tokenUrl = jwtConf.token_url;
|
|
32
|
-
if (!tokenUrl && process.env.DG_JWT_TOKEN_URL && clientId && clientId.includes('.')) {
|
|
33
|
-
const zsoid = clientId.split('.')[0];
|
|
34
|
-
tokenUrl = process.env.DG_JWT_TOKEN_URL.replace('{ZSOID}', zsoid);
|
|
35
|
-
}
|
|
36
|
-
const domainUrl = jwtConf.domain_url || process.env.DG_DOMAIN_URL;
|
|
37
|
-
const authPayload = {
|
|
38
|
-
user_token: userToken,
|
|
39
|
-
jwt_secret: jwtConf.jwt_secret,
|
|
40
|
-
jwt_auth_url: jwtAuthUrl,
|
|
41
|
-
response_type: responseType,
|
|
42
|
-
client_id: clientId,
|
|
43
|
-
token_url: tokenUrl,
|
|
44
|
-
domain_url: domainUrl
|
|
45
|
-
};
|
|
46
|
-
const authenticatorApi = process.env.DG_JWT_AUTHENTICATOR_API;
|
|
47
|
-
const resp = await fetch(authenticatorApi, {
|
|
48
|
-
method: 'POST',
|
|
49
|
-
headers: {
|
|
50
|
-
'Content-Type': 'application/json'
|
|
51
|
-
},
|
|
52
|
-
body: JSON.stringify(authPayload)
|
|
53
|
-
});
|
|
54
|
-
if (!resp.ok) {
|
|
55
|
-
const errorBody = await resp.text();
|
|
56
|
-
throw new Error(`JWT authenticator error! status: ${resp.status}, body: ${errorBody}`);
|
|
57
|
-
}
|
|
58
|
-
const json = await resp.json();
|
|
59
|
-
const accessToken = json === null || json === void 0 ? void 0 : json.access_token;
|
|
60
|
-
if (!accessToken) {
|
|
61
|
-
throw new Error('JWT authenticator did not return access_token');
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// Attach access token to authHeaders so downstream API calls can use it directly
|
|
65
|
-
apiPayload.account = apiPayload.account || {};
|
|
66
|
-
apiPayload.account.authHeaders = apiPayload.account.authHeaders || {};
|
|
67
|
-
apiPayload.account.authHeaders.Authorization = `Zoho-oauthtoken ${accessToken}`;
|
|
68
|
-
return apiPayload;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
var _default = exports.default = JWTauthenticator;
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
-
Object.defineProperty(exports, "__esModule", {
|
|
5
|
-
value: true
|
|
6
|
-
});
|
|
7
|
-
exports.default = void 0;
|
|
8
|
-
var _Authenticator = _interopRequireDefault(require("./Authenticator.js"));
|
|
9
|
-
/**
|
|
10
|
-
* OAuthAuthenticator prepares the payload for OAuth2-based authentication.
|
|
11
|
-
* It ensures oauth2 config is present in the account block so the
|
|
12
|
-
* data generator service can use it.
|
|
13
|
-
*/
|
|
14
|
-
class OAuthAuthenticator extends _Authenticator.default {
|
|
15
|
-
async constructPayload(apiPayload, actorInfo) {
|
|
16
|
-
const dg = (actorInfo === null || actorInfo === void 0 ? void 0 : actorInfo['data-generator']) || {};
|
|
17
|
-
const account = (dg === null || dg === void 0 ? void 0 : dg.account) || (apiPayload === null || apiPayload === void 0 ? void 0 : apiPayload.account) || {};
|
|
18
|
-
|
|
19
|
-
// If oauth2 details exist in actor info, merge them into payload
|
|
20
|
-
const oauth2 = account === null || account === void 0 ? void 0 : account.oauth2;
|
|
21
|
-
apiPayload.account = apiPayload.account || {};
|
|
22
|
-
if (oauth2) {
|
|
23
|
-
apiPayload.account.oauth2 = {
|
|
24
|
-
...(apiPayload.account.oauth2 || {}),
|
|
25
|
-
...oauth2
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
return apiPayload;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
var _default = exports.default = OAuthAuthenticator;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
-
Object.defineProperty(exports, "__esModule", {
|
|
5
|
-
value: true
|
|
6
|
-
});
|
|
7
|
-
exports.default = void 0;
|
|
8
|
-
var _Authenticator = _interopRequireDefault(require("./Authenticator.js"));
|
|
9
|
-
/**
|
|
10
|
-
* OrgOAuthAuthenticator prepares the payload for org_oauth authentication.
|
|
11
|
-
* It ensures org_oauth config is present in the account block so the
|
|
12
|
-
* data generator service can use it.
|
|
13
|
-
*/
|
|
14
|
-
class OrgOAuthAuthenticator extends _Authenticator.default {
|
|
15
|
-
async constructPayload(apiPayload, actorInfo) {
|
|
16
|
-
const dg = (actorInfo === null || actorInfo === void 0 ? void 0 : actorInfo['data-generator']) || {};
|
|
17
|
-
const account = (dg === null || dg === void 0 ? void 0 : dg.account) || (apiPayload === null || apiPayload === void 0 ? void 0 : apiPayload.account) || {};
|
|
18
|
-
const orgOauth = account === null || account === void 0 ? void 0 : account.org_oauth;
|
|
19
|
-
apiPayload.account = apiPayload.account || {};
|
|
20
|
-
if (orgOauth) {
|
|
21
|
-
apiPayload.account.org_oauth = {
|
|
22
|
-
...(apiPayload.account.org_oauth || {}),
|
|
23
|
-
...orgOauth
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
return apiPayload;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
var _default = exports.default = OrgOAuthAuthenticator;
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
-
var _Authenticator = _interopRequireDefault(require("../../../../../../src/core/dataGenerator/authenticator/Authenticator"));
|
|
5
|
-
describe('Authenticator', () => {
|
|
6
|
-
it('should return unchanged payload when no supported authentication type exists', async () => {
|
|
7
|
-
const authenticator = new _Authenticator.default();
|
|
8
|
-
const apiPayload = {
|
|
9
|
-
account: {
|
|
10
|
-
name: 'sample'
|
|
11
|
-
}
|
|
12
|
-
};
|
|
13
|
-
const actorInfo = {
|
|
14
|
-
'data-generator': {
|
|
15
|
-
account: {
|
|
16
|
-
authentications: ['apikey', 'basic']
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
};
|
|
20
|
-
const result = await authenticator.constructPayload(apiPayload, actorInfo);
|
|
21
|
-
expect(result).toEqual(apiPayload);
|
|
22
|
-
});
|
|
23
|
-
it('should route oauth2 authentication and merge oauth2 config into payload', async () => {
|
|
24
|
-
const authenticator = new _Authenticator.default();
|
|
25
|
-
const apiPayload = {
|
|
26
|
-
account: {}
|
|
27
|
-
};
|
|
28
|
-
const actorInfo = {
|
|
29
|
-
'data-generator': {
|
|
30
|
-
account: {
|
|
31
|
-
authentications: ['oauth2'],
|
|
32
|
-
oauth2: {
|
|
33
|
-
client_id: 'client_1',
|
|
34
|
-
client_secret: 'secret_1'
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
const result = await authenticator.constructPayload(apiPayload, actorInfo);
|
|
40
|
-
expect(result.account.oauth2).toEqual({
|
|
41
|
-
client_id: 'client_1',
|
|
42
|
-
client_secret: 'secret_1'
|
|
43
|
-
});
|
|
44
|
-
});
|
|
45
|
-
it('should treat authentication values case-insensitively and deduplicate them', async () => {
|
|
46
|
-
const authenticator = new _Authenticator.default();
|
|
47
|
-
const apiPayload = {
|
|
48
|
-
account: {}
|
|
49
|
-
};
|
|
50
|
-
const actorInfo = {
|
|
51
|
-
'data-generator': {
|
|
52
|
-
account: {
|
|
53
|
-
authentications: ['OAUTH2', 'oauth2', 'OAuth2'],
|
|
54
|
-
oauth2: {
|
|
55
|
-
scope: 'read'
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
const result = await authenticator.constructPayload(apiPayload, actorInfo);
|
|
61
|
-
expect(result.account.oauth2).toEqual({
|
|
62
|
-
scope: 'read'
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
it('should apply only the first supported authentication type', async () => {
|
|
66
|
-
const authenticator = new _Authenticator.default();
|
|
67
|
-
const apiPayload = {
|
|
68
|
-
account: {}
|
|
69
|
-
};
|
|
70
|
-
const actorInfo = {
|
|
71
|
-
'data-generator': {
|
|
72
|
-
account: {
|
|
73
|
-
authentications: ['oauth2', 'org-oauth'],
|
|
74
|
-
oauth2: {
|
|
75
|
-
client_id: 'oauth-client'
|
|
76
|
-
},
|
|
77
|
-
org_oauth: {
|
|
78
|
-
org_id: 'org-101'
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
const result = await authenticator.constructPayload(apiPayload, actorInfo);
|
|
84
|
-
expect(result.account.oauth2).toEqual({
|
|
85
|
-
client_id: 'oauth-client'
|
|
86
|
-
});
|
|
87
|
-
expect(result.account.org_oauth).toBeUndefined();
|
|
88
|
-
});
|
|
89
|
-
});
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
-
var _JWTauthenticator = _interopRequireDefault(require("../../../../../../src/core/dataGenerator/authenticator/JWTauthenticator"));
|
|
5
|
-
describe('JWTauthenticator', () => {
|
|
6
|
-
let fetchMock;
|
|
7
|
-
beforeEach(() => {
|
|
8
|
-
fetchMock = jest.fn();
|
|
9
|
-
global.fetch = fetchMock;
|
|
10
|
-
process.env.DG_JWT_AUTH_URL = 'https://jwt-auth.example.com';
|
|
11
|
-
process.env.DG_JWT_TOKEN_URL = 'https://token.example.com/{ZSOID}/oauth';
|
|
12
|
-
process.env.DG_DOMAIN_URL = 'https://domain.example.com';
|
|
13
|
-
process.env.DG_JWT_AUTHENTICATOR_API = 'https://authenticator.example.com/jwtToken';
|
|
14
|
-
});
|
|
15
|
-
afterEach(() => {
|
|
16
|
-
delete global.fetch;
|
|
17
|
-
delete process.env.DG_JWT_AUTH_URL;
|
|
18
|
-
delete process.env.DG_JWT_TOKEN_URL;
|
|
19
|
-
delete process.env.DG_DOMAIN_URL;
|
|
20
|
-
delete process.env.DG_JWT_AUTHENTICATOR_API;
|
|
21
|
-
});
|
|
22
|
-
it('should return unchanged payload when jwt config is missing', async () => {
|
|
23
|
-
const jwtAuthenticator = new _JWTauthenticator.default();
|
|
24
|
-
const apiPayload = {
|
|
25
|
-
account: {}
|
|
26
|
-
};
|
|
27
|
-
const actorInfo = {
|
|
28
|
-
email: 'user@example.com',
|
|
29
|
-
'data-generator': {
|
|
30
|
-
account: {}
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
const result = await jwtAuthenticator.constructPayload(apiPayload, actorInfo);
|
|
34
|
-
expect(result).toEqual(apiPayload);
|
|
35
|
-
expect(fetchMock).not.toHaveBeenCalled();
|
|
36
|
-
});
|
|
37
|
-
it('should fetch jwt access token and attach it to payload', async () => {
|
|
38
|
-
fetchMock.mockResolvedValue({
|
|
39
|
-
ok: true,
|
|
40
|
-
json: async () => ({
|
|
41
|
-
access_token: 'access-token-123'
|
|
42
|
-
})
|
|
43
|
-
});
|
|
44
|
-
const jwtAuthenticator = new _JWTauthenticator.default();
|
|
45
|
-
const apiPayload = {
|
|
46
|
-
account: {}
|
|
47
|
-
};
|
|
48
|
-
const actorInfo = {
|
|
49
|
-
email: 'user.one@example.com',
|
|
50
|
-
'data-generator': {
|
|
51
|
-
account: {
|
|
52
|
-
jwt: {
|
|
53
|
-
jwt_secret: 'jwt-secret',
|
|
54
|
-
response_type: 'token',
|
|
55
|
-
client_id: '12345.client-id'
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
const result = await jwtAuthenticator.constructPayload(apiPayload, actorInfo);
|
|
61
|
-
expect(fetchMock).toHaveBeenCalledTimes(1);
|
|
62
|
-
expect(fetchMock).toHaveBeenCalledWith('https://authenticator.example.com/jwtToken', expect.objectContaining({
|
|
63
|
-
method: 'POST',
|
|
64
|
-
headers: {
|
|
65
|
-
'Content-Type': 'application/json'
|
|
66
|
-
}
|
|
67
|
-
}));
|
|
68
|
-
const requestBody = JSON.parse(fetchMock.mock.calls[0][1].body);
|
|
69
|
-
expect(requestBody).toEqual(expect.objectContaining({
|
|
70
|
-
user_token: encodeURIComponent('user.one@example.com'),
|
|
71
|
-
jwt_secret: 'jwt-secret',
|
|
72
|
-
jwt_auth_url: 'https://jwt-auth.example.com',
|
|
73
|
-
response_type: 'token',
|
|
74
|
-
client_id: '12345.client-id',
|
|
75
|
-
token_url: 'https://token.example.com/12345/oauth',
|
|
76
|
-
domain_url: 'https://domain.example.com'
|
|
77
|
-
}));
|
|
78
|
-
expect(result.account.jwt).toEqual(expect.objectContaining({
|
|
79
|
-
jwt_secret: 'jwt-secret',
|
|
80
|
-
response_type: 'token',
|
|
81
|
-
client_id: '12345.client-id',
|
|
82
|
-
access_token: 'access-token-123'
|
|
83
|
-
}));
|
|
84
|
-
});
|
|
85
|
-
it('should throw a descriptive error when authenticator API returns non-ok response', async () => {
|
|
86
|
-
fetchMock.mockResolvedValue({
|
|
87
|
-
ok: false,
|
|
88
|
-
status: 500,
|
|
89
|
-
text: async () => 'internal error'
|
|
90
|
-
});
|
|
91
|
-
const jwtAuthenticator = new _JWTauthenticator.default();
|
|
92
|
-
const apiPayload = {
|
|
93
|
-
account: {}
|
|
94
|
-
};
|
|
95
|
-
const actorInfo = {
|
|
96
|
-
email: 'user@example.com',
|
|
97
|
-
'data-generator': {
|
|
98
|
-
account: {
|
|
99
|
-
jwt: {
|
|
100
|
-
jwt_secret: 'jwt-secret',
|
|
101
|
-
response_type: 'token',
|
|
102
|
-
client_id: '12345.client-id'
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
await expect(jwtAuthenticator.constructPayload(apiPayload, actorInfo)).rejects.toThrow('JWT authenticator error! status: 500, body: internal error');
|
|
108
|
-
});
|
|
109
|
-
it('should throw when authenticator response has no access_token', async () => {
|
|
110
|
-
fetchMock.mockResolvedValue({
|
|
111
|
-
ok: true,
|
|
112
|
-
json: async () => ({
|
|
113
|
-
token_type: 'Bearer'
|
|
114
|
-
})
|
|
115
|
-
});
|
|
116
|
-
const jwtAuthenticator = new _JWTauthenticator.default();
|
|
117
|
-
const apiPayload = {
|
|
118
|
-
account: {}
|
|
119
|
-
};
|
|
120
|
-
const actorInfo = {
|
|
121
|
-
email: 'user@example.com',
|
|
122
|
-
'data-generator': {
|
|
123
|
-
account: {
|
|
124
|
-
jwt: {
|
|
125
|
-
jwt_secret: 'jwt-secret',
|
|
126
|
-
response_type: 'token',
|
|
127
|
-
client_id: '12345.client-id'
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
};
|
|
132
|
-
await expect(jwtAuthenticator.constructPayload(apiPayload, actorInfo)).rejects.toThrow('JWT authenticator did not return access_token');
|
|
133
|
-
});
|
|
134
|
-
});
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
-
var _OAuthAuthenticator = _interopRequireDefault(require("../../../../../../src/core/dataGenerator/authenticator/OAuthAuthenticator"));
|
|
5
|
-
describe('OAuthAuthenticator', () => {
|
|
6
|
-
it('should merge oauth2 from actor info into payload account', async () => {
|
|
7
|
-
const oauthAuthenticator = new _OAuthAuthenticator.default();
|
|
8
|
-
const apiPayload = {
|
|
9
|
-
account: {
|
|
10
|
-
oauth2: {
|
|
11
|
-
existing_key: 'existing-value'
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
};
|
|
15
|
-
const actorInfo = {
|
|
16
|
-
'data-generator': {
|
|
17
|
-
account: {
|
|
18
|
-
oauth2: {
|
|
19
|
-
client_id: 'new-client',
|
|
20
|
-
scope: 'tickets.read'
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
const result = await oauthAuthenticator.constructPayload(apiPayload, actorInfo);
|
|
26
|
-
expect(result.account.oauth2).toEqual({
|
|
27
|
-
existing_key: 'existing-value',
|
|
28
|
-
client_id: 'new-client',
|
|
29
|
-
scope: 'tickets.read'
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
it('should initialize account when missing and keep payload unchanged if oauth2 is absent', async () => {
|
|
33
|
-
const oauthAuthenticator = new _OAuthAuthenticator.default();
|
|
34
|
-
const apiPayload = {};
|
|
35
|
-
const actorInfo = {
|
|
36
|
-
'data-generator': {
|
|
37
|
-
account: {}
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
const result = await oauthAuthenticator.constructPayload(apiPayload, actorInfo);
|
|
41
|
-
expect(result).toEqual({
|
|
42
|
-
account: {}
|
|
43
|
-
});
|
|
44
|
-
expect(result.account.oauth2).toBeUndefined();
|
|
45
|
-
});
|
|
46
|
-
});
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
-
var _OrgOAuthAuthenticator = _interopRequireDefault(require("../../../../../../src/core/dataGenerator/authenticator/OrgOAuthAuthenticator"));
|
|
5
|
-
describe('OrgOAuthAuthenticator', () => {
|
|
6
|
-
it('should merge org_oauth from actor info into payload account', async () => {
|
|
7
|
-
const orgOAuthAuthenticator = new _OrgOAuthAuthenticator.default();
|
|
8
|
-
const apiPayload = {
|
|
9
|
-
account: {
|
|
10
|
-
org_oauth: {
|
|
11
|
-
existing_key: 'existing-value'
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
};
|
|
15
|
-
const actorInfo = {
|
|
16
|
-
'data-generator': {
|
|
17
|
-
account: {
|
|
18
|
-
org_oauth: {
|
|
19
|
-
org_id: 'org-1001',
|
|
20
|
-
region: 'us'
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
const result = await orgOAuthAuthenticator.constructPayload(apiPayload, actorInfo);
|
|
26
|
-
expect(result.account.org_oauth).toEqual({
|
|
27
|
-
existing_key: 'existing-value',
|
|
28
|
-
org_id: 'org-1001',
|
|
29
|
-
region: 'us'
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
it('should initialize account when missing and keep payload unchanged if org_oauth is absent', async () => {
|
|
33
|
-
const orgOAuthAuthenticator = new _OrgOAuthAuthenticator.default();
|
|
34
|
-
const apiPayload = {};
|
|
35
|
-
const actorInfo = {
|
|
36
|
-
'data-generator': {
|
|
37
|
-
account: {}
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
const result = await orgOAuthAuthenticator.constructPayload(apiPayload, actorInfo);
|
|
41
|
-
expect(result).toEqual({
|
|
42
|
-
account: {}
|
|
43
|
-
});
|
|
44
|
-
expect(result.account.org_oauth).toBeUndefined();
|
|
45
|
-
});
|
|
46
|
-
});
|