@salesforce/core 4.0.0 → 4.0.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.txt +1 -1
- package/README.md +93 -44
- package/lib/config/aliasesConfig.d.ts +12 -0
- package/lib/config/aliasesConfig.js +28 -0
- package/lib/config/authInfoConfig.d.ts +19 -0
- package/lib/config/authInfoConfig.js +35 -0
- package/lib/config/config.d.ts +87 -22
- package/lib/config/config.js +117 -65
- package/lib/config/configAggregator.d.ts +41 -35
- package/lib/config/configAggregator.js +102 -73
- package/lib/config/configFile.d.ts +2 -2
- package/lib/config/configFile.js +38 -29
- package/lib/config/configGroup.d.ts +141 -0
- package/lib/config/configGroup.js +225 -0
- package/lib/config/configStore.d.ts +9 -9
- package/lib/config/configStore.js +17 -15
- package/lib/config/envVars.d.ts +15 -9
- package/lib/config/envVars.js +71 -47
- package/lib/config/orgUsersConfig.js +2 -0
- package/lib/config/sandboxOrgConfig.js +2 -0
- package/lib/config/sandboxProcessCache.d.ts +16 -0
- package/lib/config/sandboxProcessCache.js +38 -0
- package/lib/config/tokensConfig.d.ts +10 -0
- package/lib/config/tokensConfig.js +29 -0
- package/lib/config/ttlConfig.d.ts +34 -0
- package/lib/config/ttlConfig.js +50 -0
- package/lib/crypto/crypto.js +15 -22
- package/lib/crypto/keyChain.js +2 -3
- package/lib/crypto/keyChainImpl.d.ts +5 -3
- package/lib/crypto/keyChainImpl.js +58 -61
- package/lib/crypto/secureBuffer.d.ts +1 -1
- package/lib/deviceOauthService.d.ts +3 -3
- package/lib/deviceOauthService.js +27 -25
- package/lib/exported.d.ts +15 -12
- package/lib/exported.js +28 -16
- package/lib/global.d.ts +11 -3
- package/lib/global.js +39 -12
- package/lib/lifecycleEvents.d.ts +1 -1
- package/lib/lifecycleEvents.js +3 -0
- package/lib/logger.d.ts +19 -9
- package/lib/logger.js +112 -86
- package/lib/messages.d.ts +53 -36
- package/lib/messages.js +81 -91
- package/lib/org/authInfo.d.ts +56 -20
- package/lib/org/authInfo.js +232 -131
- package/lib/org/authRemover.d.ts +8 -7
- package/lib/org/authRemover.js +32 -28
- package/lib/org/connection.d.ts +13 -37
- package/lib/org/connection.js +78 -124
- package/lib/org/index.js +5 -1
- package/lib/org/org.d.ts +151 -48
- package/lib/org/org.js +466 -220
- package/lib/org/orgConfigProperties.d.ts +64 -3
- package/lib/org/orgConfigProperties.js +96 -4
- package/lib/org/permissionSetAssignment.js +4 -13
- package/lib/org/scratchOrgCache.d.ts +20 -0
- package/lib/org/scratchOrgCache.js +33 -0
- package/lib/org/scratchOrgCreate.d.ts +28 -17
- package/lib/org/scratchOrgCreate.js +125 -53
- package/lib/org/scratchOrgErrorCodes.d.ts +9 -3
- package/lib/org/scratchOrgErrorCodes.js +34 -17
- package/lib/org/scratchOrgFeatureDeprecation.js +1 -6
- package/lib/org/scratchOrgInfoApi.d.ts +21 -47
- package/lib/org/scratchOrgInfoApi.js +129 -63
- package/lib/org/scratchOrgInfoGenerator.d.ts +6 -5
- package/lib/org/scratchOrgInfoGenerator.js +76 -62
- package/lib/org/scratchOrgLifecycleEvents.d.ts +10 -0
- package/lib/org/scratchOrgLifecycleEvents.js +41 -0
- package/lib/org/scratchOrgSettingsGenerator.d.ts +44 -21
- package/lib/org/scratchOrgSettingsGenerator.js +165 -98
- package/lib/org/scratchOrgTypes.d.ts +43 -0
- package/lib/org/scratchOrgTypes.js +9 -0
- package/lib/org/user.d.ts +1 -1
- package/lib/org/user.js +25 -34
- package/lib/schema/printer.d.ts +6 -0
- package/lib/schema/printer.js +34 -31
- package/lib/schema/validator.d.ts +12 -10
- package/lib/schema/validator.js +56 -76
- package/lib/{sfdxError.d.ts → sfError.d.ts} +12 -20
- package/lib/{sfdxError.js → sfError.js} +40 -30
- package/lib/{sfdxProject.d.ts → sfProject.d.ts} +75 -35
- package/lib/sfProject.js +651 -0
- package/lib/{globalInfo → stateAggregator}/accessors/aliasAccessor.d.ts +27 -12
- package/lib/{globalInfo → stateAggregator}/accessors/aliasAccessor.js +47 -31
- package/lib/stateAggregator/accessors/orgAccessor.d.ts +101 -0
- package/lib/stateAggregator/accessors/orgAccessor.js +240 -0
- package/lib/stateAggregator/accessors/sandboxAccessor.d.ts +8 -0
- package/lib/stateAggregator/accessors/sandboxAccessor.js +28 -0
- package/lib/stateAggregator/accessors/tokenAccessor.d.ts +63 -0
- package/lib/stateAggregator/accessors/tokenAccessor.js +80 -0
- package/lib/stateAggregator/index.d.ts +4 -0
- package/lib/stateAggregator/index.js +27 -0
- package/lib/stateAggregator/stateAggregator.d.ts +25 -0
- package/lib/stateAggregator/stateAggregator.js +46 -0
- package/lib/status/myDomainResolver.d.ts +1 -1
- package/lib/status/myDomainResolver.js +4 -4
- package/lib/status/pollingClient.js +4 -4
- package/lib/status/streamingClient.d.ts +2 -2
- package/lib/status/streamingClient.js +58 -63
- package/lib/status/types.d.ts +2 -2
- package/lib/testSetup.d.ts +206 -75
- package/lib/testSetup.js +463 -165
- package/lib/util/cache.d.ts +2 -2
- package/lib/util/cache.js +6 -6
- package/lib/util/checkLightningDomain.js +3 -4
- package/lib/util/directoryWriter.d.ts +12 -0
- package/lib/util/directoryWriter.js +54 -0
- package/lib/util/getJwtAudienceUrl.js +1 -1
- package/lib/util/internal.d.ts +28 -2
- package/lib/util/internal.js +65 -8
- package/lib/util/jsonXmlTools.js +2 -4
- package/lib/util/mapKeys.d.ts +9 -9
- package/lib/util/mapKeys.js +13 -9
- package/lib/util/sfdc.d.ts +51 -51
- package/lib/util/sfdc.js +74 -79
- package/lib/util/sfdcUrl.d.ts +5 -19
- package/lib/util/sfdcUrl.js +40 -49
- package/lib/util/structuredWriter.d.ts +9 -0
- package/lib/util/structuredWriter.js +3 -0
- package/lib/util/zipWriter.d.ts +8 -6
- package/lib/util/zipWriter.js +13 -13
- package/lib/webOAuthServer.d.ts +20 -6
- package/lib/webOAuthServer.js +102 -56
- package/messageTransformer/messageTransformer.ts +93 -0
- package/messages/auth.md +9 -1
- package/messages/config.md +42 -6
- package/messages/connection.md +8 -0
- package/messages/core.md +10 -0
- package/messages/envVars.md +37 -3
- package/messages/org.md +21 -1
- package/messages/scratchOrgCreate.md +2 -6
- package/messages/scratchOrgErrorCodes.md +17 -1
- package/messages/scratchOrgInfoApi.md +9 -0
- package/messages/scratchOrgInfoGenerator.md +9 -1
- package/package.json +121 -46
- package/CHANGELOG.md +0 -1244
- package/lib/config/keychainConfig.d.ts +0 -19
- package/lib/config/keychainConfig.js +0 -43
- package/lib/globalInfo/accessors/orgAccessor.d.ts +0 -13
- package/lib/globalInfo/accessors/orgAccessor.js +0 -45
- package/lib/globalInfo/accessors/tokenAccessor.d.ts +0 -13
- package/lib/globalInfo/accessors/tokenAccessor.js +0 -35
- package/lib/globalInfo/globalInfoConfig.d.ts +0 -36
- package/lib/globalInfo/globalInfoConfig.js +0 -105
- package/lib/globalInfo/index.d.ts +0 -6
- package/lib/globalInfo/index.js +0 -29
- package/lib/globalInfo/sfdxDataHandler.d.ts +0 -43
- package/lib/globalInfo/sfdxDataHandler.js +0 -217
- package/lib/globalInfo/types.d.ts +0 -39
- package/lib/globalInfo/types.js +0 -10
- package/lib/sfdxProject.js +0 -557
- package/lib/util/fs.d.ts +0 -201
- package/lib/util/fs.js +0 -378
package/lib/testSetup.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MockTestOrgData = exports.StreamingMockCometClient = exports.StreamingMockCometSubscription = exports.StreamingMockSubscriptionCall = exports.shouldThrow = exports.unexpectedResult = exports.testSetup = exports.restoreContext = exports.stubContext = exports.instantiateContext = void 0;
|
|
4
2
|
/*
|
|
5
3
|
* Copyright (c) 2020, salesforce.com, inc.
|
|
6
4
|
* All rights reserved.
|
|
@@ -8,11 +6,17 @@ exports.MockTestOrgData = exports.StreamingMockCometClient = exports.StreamingMo
|
|
|
8
6
|
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
9
7
|
*/
|
|
10
8
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
9
|
+
/* eslint-disable class-methods-use-this */
|
|
10
|
+
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
11
|
+
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
12
|
+
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.MockTestSandboxData = exports.MockTestOrgData = exports.StreamingMockCometClient = exports.StreamingMockCometSubscription = exports.StreamingMockSubscriptionCall = exports.shouldThrowSync = exports.shouldThrow = exports.unexpectedResult = exports.restoreContext = exports.stubContext = exports.instantiateContext = exports.uniqid = exports.TestContext = void 0;
|
|
11
15
|
const crypto_1 = require("crypto");
|
|
12
16
|
const events_1 = require("events");
|
|
13
17
|
const os_1 = require("os");
|
|
14
18
|
const path_1 = require("path");
|
|
15
|
-
const
|
|
19
|
+
const util = require("util");
|
|
16
20
|
const ts_sinon_1 = require("@salesforce/ts-sinon");
|
|
17
21
|
const ts_types_1 = require("@salesforce/ts-types");
|
|
18
22
|
const configAggregator_1 = require("./config/configAggregator");
|
|
@@ -21,14 +25,299 @@ const connection_1 = require("./org/connection");
|
|
|
21
25
|
const crypto_2 = require("./crypto/crypto");
|
|
22
26
|
const logger_1 = require("./logger");
|
|
23
27
|
const messages_1 = require("./messages");
|
|
24
|
-
const
|
|
25
|
-
const
|
|
28
|
+
const sfError_1 = require("./sfError");
|
|
29
|
+
const sfProject_1 = require("./sfProject");
|
|
26
30
|
const streamingClient_1 = require("./status/streamingClient");
|
|
27
|
-
const
|
|
31
|
+
const stateAggregator_1 = require("./stateAggregator");
|
|
32
|
+
const org_1 = require("./org");
|
|
33
|
+
const sandboxAccessor_1 = require("./stateAggregator/accessors/sandboxAccessor");
|
|
34
|
+
const aliasesConfig_1 = require("./config/aliasesConfig");
|
|
28
35
|
const global_1 = require("./global");
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
36
|
+
/**
|
|
37
|
+
* Instantiate a @salesforce/core test context.
|
|
38
|
+
*/
|
|
39
|
+
class TestContext {
|
|
40
|
+
constructor(options = {}) {
|
|
41
|
+
/**
|
|
42
|
+
* id A unique id for the test run.
|
|
43
|
+
*/
|
|
44
|
+
this.id = uniqid();
|
|
45
|
+
/**
|
|
46
|
+
* An object used in tests that interact with config files.
|
|
47
|
+
*/
|
|
48
|
+
this.configStubs = {};
|
|
49
|
+
/**
|
|
50
|
+
* A record of stubs created during instantiation.
|
|
51
|
+
*/
|
|
52
|
+
this.stubs = {};
|
|
53
|
+
const opts = { setup: true, ...options };
|
|
54
|
+
const sinon = this.requireSinon(opts.sinon);
|
|
55
|
+
// Create a global sinon sandbox and a test logger instance for use within tests.
|
|
56
|
+
this.SANDBOX = opts.sandbox ?? sinon.createSandbox();
|
|
57
|
+
this.SANDBOXES = {
|
|
58
|
+
DEFAULT: this.SANDBOX,
|
|
59
|
+
CONFIG: sinon.createSandbox(),
|
|
60
|
+
PROJECT: sinon.createSandbox(),
|
|
61
|
+
CRYPTO: sinon.createSandbox(),
|
|
62
|
+
CONNECTION: sinon.createSandbox(),
|
|
63
|
+
FS: sinon.createSandbox(),
|
|
64
|
+
ORGS: sinon.createSandbox(),
|
|
65
|
+
};
|
|
66
|
+
this.TEST_LOGGER = new logger_1.Logger({ name: 'SFDX_Core_Test_Logger' }).useMemoryLogging();
|
|
67
|
+
if (opts.setup) {
|
|
68
|
+
this.setup();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Generate unique string.
|
|
73
|
+
*/
|
|
74
|
+
uniqid() {
|
|
75
|
+
return uniqid();
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* A function used when resolving the local path. Calls localPathResolverSync by default.
|
|
79
|
+
*
|
|
80
|
+
* @param uid Unique id.
|
|
81
|
+
*/
|
|
82
|
+
async localPathRetriever(uid) {
|
|
83
|
+
return Promise.resolve(getTestLocalPath(uid));
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* A function used when resolving the local path.
|
|
87
|
+
*
|
|
88
|
+
* @param uid Unique id.
|
|
89
|
+
*/
|
|
90
|
+
localPathRetrieverSync(uid) {
|
|
91
|
+
return getTestLocalPath(uid);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* A function used when resolving the global path. Calls globalPathResolverSync by default.
|
|
95
|
+
*
|
|
96
|
+
* @param uid Unique id.
|
|
97
|
+
*/
|
|
98
|
+
async globalPathRetriever(uid) {
|
|
99
|
+
return Promise.resolve(getTestGlobalPath(uid));
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* A function used when resolving the global path.
|
|
103
|
+
*
|
|
104
|
+
* @param uid Unique id.
|
|
105
|
+
*/
|
|
106
|
+
globalPathRetrieverSync(uid) {
|
|
107
|
+
return getTestGlobalPath(uid);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* A function used for resolving paths. Calls localPathRetriever and globalPathRetriever.
|
|
111
|
+
*
|
|
112
|
+
* @param isGlobal `true` if the config is global.
|
|
113
|
+
* @param uid user id.
|
|
114
|
+
*/
|
|
115
|
+
async rootPathRetriever(isGlobal, uid) {
|
|
116
|
+
return retrieveRootPath(isGlobal, uid);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* A function used for resolving paths. Calls localPathRetrieverSync and globalPathRetrieverSync.
|
|
120
|
+
*
|
|
121
|
+
* @param isGlobal `true` if the config is global.
|
|
122
|
+
* @param uid user id.
|
|
123
|
+
*/
|
|
124
|
+
rootPathRetrieverSync(isGlobal, uid) {
|
|
125
|
+
return retrieveRootPathSync(isGlobal, uid);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Used to mock http request to Salesforce.
|
|
129
|
+
*
|
|
130
|
+
* @param request An HttpRequest.
|
|
131
|
+
* @param options Additional options.
|
|
132
|
+
*
|
|
133
|
+
* **See** {@link Connection.request}
|
|
134
|
+
*/
|
|
135
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
136
|
+
async fakeConnectionRequest(request, options) {
|
|
137
|
+
return defaultFakeConnectionRequest();
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Gets a config stub contents by name.
|
|
141
|
+
*
|
|
142
|
+
* @param name The name of the config.
|
|
143
|
+
* @param group If the config supports groups.
|
|
144
|
+
*/
|
|
145
|
+
getConfigStubContents(name, group) {
|
|
146
|
+
const stub = this.configStubs[name];
|
|
147
|
+
if (stub?.contents) {
|
|
148
|
+
if (group && stub.contents[group]) {
|
|
149
|
+
return (0, ts_types_1.ensureJsonMap)(stub.contents[group]);
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
return stub.contents;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return {};
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Sets a config stub contents by name
|
|
159
|
+
*
|
|
160
|
+
* @param name The name of the config stub.
|
|
161
|
+
* @param value The actual stub contents. The Mock data.
|
|
162
|
+
*/
|
|
163
|
+
setConfigStubContents(name, value) {
|
|
164
|
+
if ((0, ts_types_1.ensureString)(name) && (0, ts_types_1.isJsonMap)(value)) {
|
|
165
|
+
this.configStubs[name] = value;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Set stubs for working in the context of a SfProject
|
|
170
|
+
*/
|
|
171
|
+
inProject(inProject = true) {
|
|
172
|
+
this.SANDBOXES.PROJECT.restore();
|
|
173
|
+
if (inProject) {
|
|
174
|
+
this.SANDBOXES.PROJECT.stub(sfProject_1.SfProject, 'resolveProjectPath').callsFake(() => this.localPathRetriever(this.id));
|
|
175
|
+
this.SANDBOXES.PROJECT.stub(sfProject_1.SfProject, 'resolveProjectPathSync').callsFake(() => this.localPathRetrieverSync(this.id));
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
this.SANDBOXES.PROJECT.stub(sfProject_1.SfProject, 'resolveProjectPath').rejects(new sfError_1.SfError('', 'InvalidProjectWorkspaceError'));
|
|
179
|
+
this.SANDBOXES.PROJECT.stub(sfProject_1.SfProject, 'resolveProjectPathSync').throws(new sfError_1.SfError('', 'InvalidProjectWorkspaceError'));
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Stub salesforce org authorizations.
|
|
184
|
+
*/
|
|
185
|
+
async stubAuths(...orgs) {
|
|
186
|
+
const entries = await Promise.all(orgs.map(async (org) => [org.username, await org.getConfig()]));
|
|
187
|
+
const orgMap = new Map(entries);
|
|
188
|
+
(0, ts_sinon_1.stubMethod)(this.SANDBOX, stateAggregator_1.OrgAccessor.prototype, 'getAllFiles').resolves([...orgMap.keys()].map((o) => `${o}.json`));
|
|
189
|
+
(0, ts_sinon_1.stubMethod)(this.SANDBOX, stateAggregator_1.OrgAccessor.prototype, 'hasFile').callsFake((username) => orgMap.has(username));
|
|
190
|
+
const retrieveContents = async function () {
|
|
191
|
+
const username = (0, path_1.basename)(this.path.replace('.json', ''));
|
|
192
|
+
return Promise.resolve(orgMap.get(username) ?? {});
|
|
193
|
+
};
|
|
194
|
+
this.configStubs.AuthInfoConfig = { retrieveContents };
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Stub salesforce user authorizations.
|
|
198
|
+
*
|
|
199
|
+
* @param users The users to stub.
|
|
200
|
+
* The key is the username of the admin user and it must be included in the users array in order to obtain the orgId key for the remaining users.
|
|
201
|
+
* The admin user is excluded from the users array.
|
|
202
|
+
*
|
|
203
|
+
*/
|
|
204
|
+
stubUsers(users) {
|
|
205
|
+
const mockUsers = Object.values(users).flatMap((orgUsers) => orgUsers.map((user) => {
|
|
206
|
+
const userInfo = user.getMockUserInfo();
|
|
207
|
+
return {
|
|
208
|
+
alias: userInfo.Alias ?? '',
|
|
209
|
+
email: userInfo.Email ?? '',
|
|
210
|
+
emailEncodingKey: userInfo.EmailEncodingKey ?? '',
|
|
211
|
+
id: userInfo.Id ?? '',
|
|
212
|
+
languageLocaleKey: userInfo.LanguageLocaleKey ?? '',
|
|
213
|
+
lastName: userInfo.LastName ?? '',
|
|
214
|
+
localeSidKey: userInfo.LocaleSidKey ?? '',
|
|
215
|
+
profileId: userInfo.ProfileId ?? '',
|
|
216
|
+
timeZoneSidKey: userInfo.TimeZoneSidKey ?? '',
|
|
217
|
+
username: userInfo.Username ?? '',
|
|
218
|
+
};
|
|
219
|
+
}));
|
|
220
|
+
const userOrgsMap = new Map(Object.entries(users).map(([adminUsername, orgs]) => {
|
|
221
|
+
const adminOrg = orgs.find((org) => org.username === adminUsername);
|
|
222
|
+
return adminOrg
|
|
223
|
+
? [adminOrg.orgId, { usernames: orgs.filter((org) => org.username !== adminUsername) }]
|
|
224
|
+
: [undefined, undefined];
|
|
225
|
+
}));
|
|
226
|
+
(0, ts_sinon_1.stubMethod)(this.SANDBOX, org_1.User.prototype, 'retrieve').callsFake((username) => Promise.resolve(mockUsers.find((org) => org.username === username)));
|
|
227
|
+
const retrieveContents = async function () {
|
|
228
|
+
const orgId = (0, path_1.basename)(this.path.replace('.json', ''));
|
|
229
|
+
return Promise.resolve(userOrgsMap.get(orgId) ?? {});
|
|
230
|
+
};
|
|
231
|
+
this.configStubs.OrgUsersConfig = { retrieveContents };
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Stub salesforce sandbox authorizations.
|
|
235
|
+
*/
|
|
236
|
+
async stubSandboxes(...sandboxes) {
|
|
237
|
+
const entries = (await Promise.all(sandboxes.map(async (sandbox) => [sandbox.username, await sandbox.getConfig()])));
|
|
238
|
+
const sandboxMap = new Map(entries);
|
|
239
|
+
(0, ts_sinon_1.stubMethod)(this.SANDBOX, sandboxAccessor_1.SandboxAccessor.prototype, 'getAllFiles').resolves([...sandboxMap.keys()].map((o) => `${o}.sandbox.json`));
|
|
240
|
+
const retrieveContents = async function () {
|
|
241
|
+
const username = (0, path_1.basename)(this.path.replace('.sandbox.json', ''));
|
|
242
|
+
return Promise.resolve(sandboxMap.get(username) ?? {});
|
|
243
|
+
};
|
|
244
|
+
this.configStubs.SandboxOrgConfig = { retrieveContents };
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Stub the aliases in the global aliases config file.
|
|
248
|
+
*/
|
|
249
|
+
stubAliases(aliases, group = aliasesConfig_1.AliasGroup.ORGS) {
|
|
250
|
+
this.configStubs.AliasesConfig = { contents: { [group]: aliases } };
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Stub contents in the config file.
|
|
254
|
+
*/
|
|
255
|
+
async stubConfig(config) {
|
|
256
|
+
this.configStubs.Config = { contents: config };
|
|
257
|
+
// configAggregator may have already loaded an instance. We're not sure why this happens.
|
|
258
|
+
// This seems to solve the problem by forcing a load of the new stubbed config.
|
|
259
|
+
await configAggregator_1.ConfigAggregator.create();
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Stub the tokens in the global token config file.
|
|
263
|
+
*/
|
|
264
|
+
stubTokens(tokens) {
|
|
265
|
+
this.configStubs.TokensConfig = { contents: tokens };
|
|
266
|
+
}
|
|
267
|
+
restore() {
|
|
268
|
+
(0, exports.restoreContext)(this);
|
|
269
|
+
}
|
|
270
|
+
init() {
|
|
271
|
+
this.stubs = (0, exports.stubContext)(this);
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Add beforeEach and afterEach hooks to init the stubs and restore them.
|
|
275
|
+
* This is called automatically when the class is instantiated unless the setup option is set to false.
|
|
276
|
+
*/
|
|
277
|
+
setup() {
|
|
278
|
+
beforeEach(() => {
|
|
279
|
+
this.init();
|
|
280
|
+
});
|
|
281
|
+
afterEach(() => {
|
|
282
|
+
this.restore();
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
requireSinon(sinon) {
|
|
286
|
+
if (sinon)
|
|
287
|
+
return sinon;
|
|
288
|
+
try {
|
|
289
|
+
sinon = require('sinon');
|
|
290
|
+
}
|
|
291
|
+
catch (e) {
|
|
292
|
+
throw new Error('The package sinon was not found. Add it to your package.json and pass it in to new TestContext({sinon})');
|
|
293
|
+
}
|
|
294
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
295
|
+
return sinon;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
exports.TestContext = TestContext;
|
|
299
|
+
/**
|
|
300
|
+
* A function to generate a unique id and return it in the context of a template, if supplied.
|
|
301
|
+
*
|
|
302
|
+
* A template is a string that can contain `${%s}` to be replaced with a unique id.
|
|
303
|
+
* If the template contains the "%s" placeholder, it will be replaced with the unique id otherwise the id will be appended to the template.
|
|
304
|
+
*
|
|
305
|
+
* @param options an object with the following properties:
|
|
306
|
+
* - template: a template string.
|
|
307
|
+
* - length: the length of the unique id as presented in hexadecimal.
|
|
308
|
+
*/
|
|
309
|
+
function uniqid(options) {
|
|
310
|
+
const uniqueString = (0, crypto_1.randomBytes)(Math.ceil((options?.length ?? 32) / 2.0))
|
|
311
|
+
.toString('hex')
|
|
312
|
+
.slice(0, options?.length ?? 32);
|
|
313
|
+
if (!options?.template) {
|
|
314
|
+
return uniqueString;
|
|
315
|
+
}
|
|
316
|
+
return options.template.includes('%s')
|
|
317
|
+
? util.format(options.template, uniqueString)
|
|
318
|
+
: `${options.template}${uniqueString}`;
|
|
319
|
+
}
|
|
320
|
+
exports.uniqid = uniqid;
|
|
32
321
|
function getTestLocalPath(uid) {
|
|
33
322
|
return (0, path_1.join)((0, os_1.tmpdir)(), uid, 'sfdx_core', 'local');
|
|
34
323
|
}
|
|
@@ -57,86 +346,16 @@ function defaultFakeConnectionRequest() {
|
|
|
57
346
|
* const $$ = instantiateContext();
|
|
58
347
|
*
|
|
59
348
|
* beforeEach(() => {
|
|
60
|
-
*
|
|
349
|
+
* $$.init()
|
|
61
350
|
* });
|
|
62
351
|
*
|
|
63
352
|
* afterEach(() => {
|
|
64
|
-
*
|
|
353
|
+
* $$.restore();
|
|
65
354
|
* });
|
|
66
355
|
* ```
|
|
67
356
|
* @param sinon
|
|
68
357
|
*/
|
|
69
|
-
|
|
70
|
-
const instantiateContext = (sinon) => {
|
|
71
|
-
if (!sinon) {
|
|
72
|
-
try {
|
|
73
|
-
sinon = require('sinon');
|
|
74
|
-
}
|
|
75
|
-
catch (e) {
|
|
76
|
-
throw new Error('The package sinon was not found. Add it to your package.json and pass it in to testSetup(sinon.sandbox)');
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
// Import all the messages files in the sfdx-core messages dir.
|
|
80
|
-
// Messages.importMessagesDirectory(pathJoin(__dirname, '..', '..'));
|
|
81
|
-
messages_1.Messages.importMessagesDirectory((0, path_1.join)(__dirname));
|
|
82
|
-
// Create a global sinon sandbox and a test logger instance for use within tests.
|
|
83
|
-
const defaultSandbox = sinon.createSandbox();
|
|
84
|
-
const testContext = {
|
|
85
|
-
SANDBOX: defaultSandbox,
|
|
86
|
-
SANDBOXES: {
|
|
87
|
-
DEFAULT: defaultSandbox,
|
|
88
|
-
CONFIG: sinon.createSandbox(),
|
|
89
|
-
PROJECT: sinon.createSandbox(),
|
|
90
|
-
CRYPTO: sinon.createSandbox(),
|
|
91
|
-
CONNECTION: sinon.createSandbox(),
|
|
92
|
-
FS: sinon.createSandbox(),
|
|
93
|
-
},
|
|
94
|
-
TEST_LOGGER: new logger_1.Logger({
|
|
95
|
-
name: 'SFDX_Core_Test_Logger',
|
|
96
|
-
}).useMemoryLogging(),
|
|
97
|
-
id: uniqid(),
|
|
98
|
-
uniqid,
|
|
99
|
-
configStubs: {},
|
|
100
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
101
|
-
localPathRetriever: async (uid) => getTestLocalPath(uid),
|
|
102
|
-
localPathRetrieverSync: getTestLocalPath,
|
|
103
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
104
|
-
globalPathRetriever: async (uid) => getTestGlobalPath(uid),
|
|
105
|
-
globalPathRetrieverSync: getTestGlobalPath,
|
|
106
|
-
rootPathRetriever: retrieveRootPath,
|
|
107
|
-
rootPathRetrieverSync: retrieveRootPathSync,
|
|
108
|
-
fakeConnectionRequest: defaultFakeConnectionRequest,
|
|
109
|
-
getConfigStubContents(name, group) {
|
|
110
|
-
const stub = this.configStubs[name];
|
|
111
|
-
if (stub && stub.contents) {
|
|
112
|
-
if (group && stub.contents[group]) {
|
|
113
|
-
return (0, ts_types_1.ensureJsonMap)(stub.contents[group]);
|
|
114
|
-
}
|
|
115
|
-
else {
|
|
116
|
-
return stub.contents;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
return {};
|
|
120
|
-
},
|
|
121
|
-
setConfigStubContents(name, value) {
|
|
122
|
-
if ((0, ts_types_1.ensureString)(name) && (0, ts_types_1.isJsonMap)(value)) {
|
|
123
|
-
this.configStubs[name] = value;
|
|
124
|
-
}
|
|
125
|
-
},
|
|
126
|
-
inProject(inProject = true) {
|
|
127
|
-
testContext.SANDBOXES.PROJECT.restore();
|
|
128
|
-
if (inProject) {
|
|
129
|
-
testContext.SANDBOXES.PROJECT.stub(sfdxProject_1.SfdxProject, 'resolveProjectPath').callsFake(() => testContext.localPathRetriever(testContext.id));
|
|
130
|
-
testContext.SANDBOXES.PROJECT.stub(sfdxProject_1.SfdxProject, 'resolveProjectPathSync').callsFake(() => testContext.localPathRetrieverSync(testContext.id));
|
|
131
|
-
}
|
|
132
|
-
else {
|
|
133
|
-
testContext.SANDBOXES.PROJECT.stub(sfdxProject_1.SfdxProject, 'resolveProjectPath').rejects(new sfdxError_1.SfdxError('', 'InvalidProjectWorkspaceError'));
|
|
134
|
-
testContext.SANDBOXES.PROJECT.stub(sfdxProject_1.SfdxProject, 'resolveProjectPathSync').throws(new sfdxError_1.SfdxError('', 'InvalidProjectWorkspaceError'));
|
|
135
|
-
}
|
|
136
|
-
},
|
|
137
|
-
};
|
|
138
|
-
return testContext;
|
|
139
|
-
};
|
|
358
|
+
const instantiateContext = (sinon) => new TestContext({ sinon, setup: false });
|
|
140
359
|
exports.instantiateContext = instantiateContext;
|
|
141
360
|
/**
|
|
142
361
|
* Stub a @salesforce/core test context. This will mock out logging to a file, config file reading and writing,
|
|
@@ -153,11 +372,11 @@ exports.instantiateContext = instantiateContext;
|
|
|
153
372
|
* const $$ = instantiateContext();
|
|
154
373
|
*
|
|
155
374
|
* beforeEach(() => {
|
|
156
|
-
*
|
|
375
|
+
* $$.init()
|
|
157
376
|
* });
|
|
158
377
|
*
|
|
159
378
|
* afterEach(() => {
|
|
160
|
-
*
|
|
379
|
+
* $$.restore();
|
|
161
380
|
* });
|
|
162
381
|
* ```
|
|
163
382
|
* @param testContext
|
|
@@ -165,34 +384,33 @@ exports.instantiateContext = instantiateContext;
|
|
|
165
384
|
const stubContext = (testContext) => {
|
|
166
385
|
// Turn off the interoperability feature so that we don't have to mock
|
|
167
386
|
// the old .sfdx config files
|
|
168
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
169
|
-
// @ts-ignore
|
|
170
387
|
global_1.Global.SFDX_INTEROPERABILITY = false;
|
|
388
|
+
const stubs = {};
|
|
171
389
|
// Most core files create a child logger so stub this to return our test logger.
|
|
172
|
-
(0, ts_sinon_1.stubMethod)(testContext.SANDBOX, logger_1.Logger, 'child').
|
|
390
|
+
(0, ts_sinon_1.stubMethod)(testContext.SANDBOX, logger_1.Logger, 'child').resolves(testContext.TEST_LOGGER);
|
|
173
391
|
(0, ts_sinon_1.stubMethod)(testContext.SANDBOX, logger_1.Logger, 'childFromRoot').returns(testContext.TEST_LOGGER);
|
|
174
392
|
testContext.inProject(true);
|
|
175
393
|
testContext.SANDBOXES.CONFIG.stub(configFile_1.ConfigFile, 'resolveRootFolder').callsFake((isGlobal) => testContext.rootPathRetriever(isGlobal, testContext.id));
|
|
176
394
|
testContext.SANDBOXES.CONFIG.stub(configFile_1.ConfigFile, 'resolveRootFolderSync').callsFake((isGlobal) => testContext.rootPathRetrieverSync(isGlobal, testContext.id));
|
|
177
|
-
(0, ts_sinon_1.stubMethod)(testContext.SANDBOXES.PROJECT,
|
|
395
|
+
(0, ts_sinon_1.stubMethod)(testContext.SANDBOXES.PROJECT, sfProject_1.SfProjectJson.prototype, 'doesPackageExist').callsFake(() => true);
|
|
178
396
|
const initStubForRead = (configFile) => {
|
|
179
|
-
const stub = testContext.configStubs[configFile.constructor.name]
|
|
397
|
+
const stub = testContext.configStubs[configFile.constructor.name] ?? {};
|
|
180
398
|
// init calls read calls getPath which sets the path on the config file the first time.
|
|
181
399
|
// Since read is now stubbed, make sure to call getPath to initialize it.
|
|
182
400
|
configFile.getPath();
|
|
183
|
-
// @ts-
|
|
401
|
+
// @ts-expect-error: set this to true to avoid an infinite loop in tests when reading config files.
|
|
184
402
|
configFile.hasRead = true;
|
|
185
403
|
return stub;
|
|
186
404
|
};
|
|
187
405
|
const readSync = function (newContents) {
|
|
188
406
|
const stub = initStubForRead(this);
|
|
189
|
-
this.setContentsFromObject(newContents
|
|
407
|
+
this.setContentsFromObject(newContents ?? stub.contents ?? {});
|
|
190
408
|
return this.getContents();
|
|
191
409
|
};
|
|
192
410
|
const read = async function () {
|
|
193
411
|
const stub = initStubForRead(this);
|
|
194
412
|
if (stub.readFn) {
|
|
195
|
-
return
|
|
413
|
+
return stub.readFn.call(this);
|
|
196
414
|
}
|
|
197
415
|
if (stub.retrieveContents) {
|
|
198
416
|
return readSync.call(this, await stub.retrieveContents.call(this));
|
|
@@ -202,9 +420,9 @@ const stubContext = (testContext) => {
|
|
|
202
420
|
}
|
|
203
421
|
};
|
|
204
422
|
// Mock out all config file IO for all tests. They can restore individually if they need original functionality.
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
testContext.SANDBOXES.CONFIG.stub(configFile_1.ConfigFile.prototype, '
|
|
423
|
+
stubs.configRead = testContext.SANDBOXES.CONFIG.stub(configFile_1.ConfigFile.prototype, 'read').callsFake(read);
|
|
424
|
+
// @ts-expect-error: muting exact type match for stub readSync
|
|
425
|
+
stubs.configReadSync = testContext.SANDBOXES.CONFIG.stub(configFile_1.ConfigFile.prototype, 'readSync').callsFake(readSync);
|
|
208
426
|
const writeSync = function (newContents) {
|
|
209
427
|
if (!testContext.configStubs[this.constructor.name]) {
|
|
210
428
|
testContext.configStubs[this.constructor.name] = {};
|
|
@@ -212,7 +430,7 @@ const stubContext = (testContext) => {
|
|
|
212
430
|
const stub = testContext.configStubs[this.constructor.name];
|
|
213
431
|
if (!stub)
|
|
214
432
|
return;
|
|
215
|
-
this.setContents(newContents
|
|
433
|
+
this.setContents(newContents ?? this.getContents());
|
|
216
434
|
stub.contents = this.toObject();
|
|
217
435
|
};
|
|
218
436
|
const write = async function (newContents) {
|
|
@@ -223,7 +441,7 @@ const stubContext = (testContext) => {
|
|
|
223
441
|
if (!stub)
|
|
224
442
|
return;
|
|
225
443
|
if (stub.writeFn) {
|
|
226
|
-
return
|
|
444
|
+
return stub.writeFn.call(this, newContents);
|
|
227
445
|
}
|
|
228
446
|
if (stub.updateContents) {
|
|
229
447
|
writeSync.call(this, await stub.updateContents.call(this));
|
|
@@ -232,8 +450,8 @@ const stubContext = (testContext) => {
|
|
|
232
450
|
writeSync.call(this);
|
|
233
451
|
}
|
|
234
452
|
};
|
|
235
|
-
(0, ts_sinon_1.stubMethod)(testContext.SANDBOXES.CONFIG, configFile_1.ConfigFile.prototype, 'writeSync').callsFake(writeSync);
|
|
236
|
-
(0, ts_sinon_1.stubMethod)(testContext.SANDBOXES.CONFIG, configFile_1.ConfigFile.prototype, 'write').callsFake(write);
|
|
453
|
+
stubs.configWriteSync = (0, ts_sinon_1.stubMethod)(testContext.SANDBOXES.CONFIG, configFile_1.ConfigFile.prototype, 'writeSync').callsFake(writeSync);
|
|
454
|
+
stubs.configWrite = (0, ts_sinon_1.stubMethod)(testContext.SANDBOXES.CONFIG, configFile_1.ConfigFile.prototype, 'write').callsFake(write);
|
|
237
455
|
(0, ts_sinon_1.stubMethod)(testContext.SANDBOXES.CRYPTO, crypto_2.Crypto.prototype, 'getKeyChain').callsFake(() => Promise.resolve({
|
|
238
456
|
setPassword: () => Promise.resolve(),
|
|
239
457
|
getPassword: (data, cb) => cb(undefined, '12345678901234567890123456789012'),
|
|
@@ -245,8 +463,24 @@ const stubContext = (testContext) => {
|
|
|
245
463
|
}
|
|
246
464
|
return testContext.fakeConnectionRequest.call(this, request, options);
|
|
247
465
|
});
|
|
466
|
+
stubs.configExists = (0, ts_sinon_1.stubMethod)(testContext.SANDBOXES.ORGS, stateAggregator_1.OrgAccessor.prototype, 'exists').callsFake(async function (username) {
|
|
467
|
+
// @ts-expect-error because private member
|
|
468
|
+
if ([...this.contents.keys()].includes(username))
|
|
469
|
+
return Promise.resolve(true);
|
|
470
|
+
else
|
|
471
|
+
return Promise.resolve(false);
|
|
472
|
+
});
|
|
473
|
+
stubs.configRemove = (0, ts_sinon_1.stubMethod)(testContext.SANDBOXES.ORGS, stateAggregator_1.OrgAccessor.prototype, 'remove').callsFake(async function (username) {
|
|
474
|
+
// @ts-expect-error because private member
|
|
475
|
+
if ([...this.contents.keys()].includes(username))
|
|
476
|
+
return Promise.resolve(true);
|
|
477
|
+
else
|
|
478
|
+
return Promise.resolve(false);
|
|
479
|
+
});
|
|
248
480
|
// Always start with the default and tests beforeEach or it methods can override it.
|
|
249
481
|
testContext.fakeConnectionRequest = defaultFakeConnectionRequest;
|
|
482
|
+
testContext.stubs = stubs;
|
|
483
|
+
return stubs;
|
|
250
484
|
};
|
|
251
485
|
exports.stubContext = stubContext;
|
|
252
486
|
/**
|
|
@@ -259,78 +493,41 @@ exports.stubContext = stubContext;
|
|
|
259
493
|
* const $$ = instantiateContext();
|
|
260
494
|
*
|
|
261
495
|
* beforeEach(() => {
|
|
262
|
-
*
|
|
496
|
+
* $$.init()
|
|
263
497
|
* });
|
|
264
498
|
*
|
|
265
499
|
* afterEach(() => {
|
|
266
|
-
*
|
|
500
|
+
* $$.restore();
|
|
267
501
|
* });
|
|
268
502
|
* ```
|
|
269
503
|
* @param testContext
|
|
270
504
|
*/
|
|
271
505
|
const restoreContext = (testContext) => {
|
|
506
|
+
// Restore the default value for this setting on restore.
|
|
507
|
+
global_1.Global.SFDX_INTEROPERABILITY = true;
|
|
272
508
|
testContext.SANDBOX.restore();
|
|
509
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
273
510
|
Object.values(testContext.SANDBOXES).forEach((theSandbox) => theSandbox.restore());
|
|
274
511
|
testContext.configStubs = {};
|
|
275
|
-
// Give each test run a clean
|
|
276
|
-
|
|
512
|
+
// Give each test run a clean StateAggregator
|
|
513
|
+
stateAggregator_1.StateAggregator.clearInstance();
|
|
514
|
+
// Allow each test to have their own config aggregator
|
|
515
|
+
// @ts-ignore clear for testing.
|
|
516
|
+
delete configAggregator_1.ConfigAggregator.instance;
|
|
277
517
|
};
|
|
278
518
|
exports.restoreContext = restoreContext;
|
|
279
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
280
|
-
const _testSetup = (sinon) => {
|
|
281
|
-
const testContext = (0, exports.instantiateContext)(sinon);
|
|
282
|
-
beforeEach(() => {
|
|
283
|
-
// Allow each test to have their own config aggregator
|
|
284
|
-
// @ts-ignore clear for testing.
|
|
285
|
-
delete configAggregator_1.ConfigAggregator.instance;
|
|
286
|
-
(0, exports.stubContext)(testContext);
|
|
287
|
-
});
|
|
288
|
-
afterEach(() => {
|
|
289
|
-
(0, exports.restoreContext)(testContext);
|
|
290
|
-
});
|
|
291
|
-
return testContext;
|
|
292
|
-
};
|
|
293
|
-
/**
|
|
294
|
-
* Use to mock out different pieces of sfdx-core to make testing easier. This will mock out
|
|
295
|
-
* logging to a file, config file reading and writing, local and global path resolution, and
|
|
296
|
-
* *http request using connection (soon)*.
|
|
297
|
-
*
|
|
298
|
-
* **Note:** The testSetup should be outside of the describe. If you need to stub per test, use
|
|
299
|
-
* `instantiateContext`, `stubContext`, and `restoreContext`.
|
|
300
|
-
* ```
|
|
301
|
-
* // In a mocha tests
|
|
302
|
-
* import testSetup from '@salesforce/core/lib/testSetup';
|
|
303
|
-
*
|
|
304
|
-
* const $$ = testSetup();
|
|
305
|
-
*
|
|
306
|
-
* describe(() => {
|
|
307
|
-
* it('test', () => {
|
|
308
|
-
* // Stub out your own method
|
|
309
|
-
* $$.SANDBOX.stub(MyClass.prototype, 'myMethod').returnsFake(() => {});
|
|
310
|
-
*
|
|
311
|
-
* // Set the contents that is used when aliases are read. Same for all config files.
|
|
312
|
-
* $$.configStubs.Aliases = { contents: { 'myTestAlias': 'user@company.com' } };
|
|
313
|
-
*
|
|
314
|
-
* // Will use the contents set above.
|
|
315
|
-
* const username = Aliases.fetch('myTestAlias');
|
|
316
|
-
* expect(username).to.equal('user@company.com');
|
|
317
|
-
* });
|
|
318
|
-
* });
|
|
319
|
-
* ```
|
|
320
|
-
*/
|
|
321
|
-
exports.testSetup = (0, kit_1.once)(_testSetup);
|
|
322
519
|
/**
|
|
323
520
|
* A pre-canned error for try/catch testing.
|
|
324
521
|
*
|
|
325
522
|
* **See** {@link shouldThrow}
|
|
326
523
|
*/
|
|
327
|
-
exports.unexpectedResult = new
|
|
524
|
+
exports.unexpectedResult = new sfError_1.SfError('This code was expected to fail', 'UnexpectedResult');
|
|
328
525
|
/**
|
|
329
526
|
* Use for this testing pattern:
|
|
330
527
|
* ```
|
|
331
528
|
* try {
|
|
332
529
|
* await call()
|
|
333
|
-
* assert.fail(
|
|
530
|
+
* assert.fail("this should never happen");
|
|
334
531
|
* } catch (e) {
|
|
335
532
|
* ...
|
|
336
533
|
* }
|
|
@@ -346,11 +543,47 @@ exports.unexpectedResult = new sfdxError_1.SfdxError('This code was expected to
|
|
|
346
543
|
*
|
|
347
544
|
* @param f The async function that is expected to throw.
|
|
348
545
|
*/
|
|
349
|
-
async function shouldThrow(f) {
|
|
546
|
+
async function shouldThrow(f, message) {
|
|
350
547
|
await f;
|
|
351
|
-
|
|
548
|
+
if (message) {
|
|
549
|
+
throw new sfError_1.SfError(message, 'UnexpectedResult');
|
|
550
|
+
}
|
|
551
|
+
else {
|
|
552
|
+
throw exports.unexpectedResult;
|
|
553
|
+
}
|
|
352
554
|
}
|
|
353
555
|
exports.shouldThrow = shouldThrow;
|
|
556
|
+
/**
|
|
557
|
+
* Use for this testing pattern:
|
|
558
|
+
* ```
|
|
559
|
+
* try {
|
|
560
|
+
* call()
|
|
561
|
+
* assert.fail("this should never happen");
|
|
562
|
+
* } catch (e) {
|
|
563
|
+
* ...
|
|
564
|
+
* }
|
|
565
|
+
*
|
|
566
|
+
* Just do this
|
|
567
|
+
*
|
|
568
|
+
* try {
|
|
569
|
+
* shouldThrowSync(call); // If this succeeds unexpectedResultError is thrown.
|
|
570
|
+
* } catch(e) {
|
|
571
|
+
* ...
|
|
572
|
+
* }
|
|
573
|
+
* ```
|
|
574
|
+
*
|
|
575
|
+
* @param f The function that is expected to throw.
|
|
576
|
+
*/
|
|
577
|
+
function shouldThrowSync(f, message) {
|
|
578
|
+
f();
|
|
579
|
+
if (message) {
|
|
580
|
+
throw new sfError_1.SfError(message, 'UnexpectedResult');
|
|
581
|
+
}
|
|
582
|
+
else {
|
|
583
|
+
throw exports.unexpectedResult;
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
exports.shouldThrowSync = shouldThrowSync;
|
|
354
587
|
/**
|
|
355
588
|
* A helper to determine if a subscription will use callback or errorback.
|
|
356
589
|
* Enable errback to simulate a subscription failure.
|
|
@@ -472,33 +705,49 @@ class StreamingMockCometClient extends streamingClient_1.CometClient {
|
|
|
472
705
|
}
|
|
473
706
|
exports.StreamingMockCometClient = StreamingMockCometClient;
|
|
474
707
|
/**
|
|
475
|
-
* Mock class for
|
|
708
|
+
* Mock class for Salesforce Orgs.
|
|
709
|
+
*
|
|
710
|
+
* @example
|
|
711
|
+
* ```
|
|
712
|
+
* const testOrg = new MockTestOrgData();
|
|
713
|
+
* await $$.stubAuths(testOrg)
|
|
714
|
+
* ```
|
|
476
715
|
*/
|
|
477
716
|
class MockTestOrgData {
|
|
478
717
|
constructor(id = uniqid(), options) {
|
|
479
718
|
this.testId = id;
|
|
480
719
|
this.userId = `user_id_${this.testId}`;
|
|
481
720
|
this.orgId = `${this.testId}`;
|
|
482
|
-
this.username =
|
|
483
|
-
this.loginUrl = `
|
|
484
|
-
this.instanceUrl = `
|
|
721
|
+
this.username = options?.username ?? `admin_${this.testId}@gb.org`;
|
|
722
|
+
this.loginUrl = `https://login.${this.testId}.salesforce.com`;
|
|
723
|
+
this.instanceUrl = `https://instance.${this.testId}.salesforce.com`;
|
|
485
724
|
this.clientId = `${this.testId}/client_id`;
|
|
486
725
|
this.clientSecret = `${this.testId}/client_secret`;
|
|
487
726
|
this.authcode = `${this.testId}/authcode`;
|
|
488
727
|
this.accessToken = `${this.testId}/accessToken`;
|
|
489
728
|
this.refreshToken = `${this.testId}/refreshToken`;
|
|
490
|
-
this.redirectUri =
|
|
729
|
+
this.redirectUri = 'http://localhost:1717/OauthRedirect';
|
|
491
730
|
}
|
|
731
|
+
/**
|
|
732
|
+
* Add devhub username to properties.
|
|
733
|
+
*/
|
|
492
734
|
createDevHubUsername(username) {
|
|
493
735
|
this.devHubUsername = username;
|
|
494
736
|
}
|
|
737
|
+
/**
|
|
738
|
+
* Mark this org as a devhub.
|
|
739
|
+
*/
|
|
495
740
|
makeDevHub() {
|
|
496
|
-
|
|
741
|
+
this.isDevHub = true;
|
|
497
742
|
}
|
|
743
|
+
/**
|
|
744
|
+
* Returns a MockTestOrgData that represents a user created in the org.
|
|
745
|
+
*/
|
|
498
746
|
createUser(user) {
|
|
499
747
|
const userMock = new MockTestOrgData();
|
|
500
748
|
userMock.username = user;
|
|
501
|
-
userMock.
|
|
749
|
+
userMock.aliases = this.aliases;
|
|
750
|
+
userMock.configs = this.configs;
|
|
502
751
|
userMock.devHubUsername = this.devHubUsername;
|
|
503
752
|
userMock.orgId = this.orgId;
|
|
504
753
|
userMock.loginUrl = this.loginUrl;
|
|
@@ -506,14 +755,23 @@ class MockTestOrgData {
|
|
|
506
755
|
userMock.clientId = this.clientId;
|
|
507
756
|
userMock.clientSecret = this.clientSecret;
|
|
508
757
|
userMock.redirectUri = this.redirectUri;
|
|
758
|
+
userMock.isDevHub = this.isDevHub;
|
|
759
|
+
userMock.isScratchOrg = this.isScratchOrg;
|
|
760
|
+
userMock.isExpired = this.isExpired;
|
|
761
|
+
userMock.password = this.password;
|
|
762
|
+
userMock.accessToken = this.accessToken;
|
|
509
763
|
return userMock;
|
|
510
764
|
}
|
|
765
|
+
/**
|
|
766
|
+
* Return mock user information based on this org.
|
|
767
|
+
*/
|
|
511
768
|
getMockUserInfo() {
|
|
512
769
|
return {
|
|
513
770
|
Id: this.userId,
|
|
514
771
|
Username: this.username,
|
|
515
772
|
LastName: `user_lastname_${this.testId}`,
|
|
516
|
-
Alias: this.
|
|
773
|
+
Alias: this.aliases ? this.aliases[0] : 'user_alias_blah',
|
|
774
|
+
Configs: this.configs,
|
|
517
775
|
TimeZoneSidKey: `user_timezonesidkey_${this.testId}`,
|
|
518
776
|
LocaleSidKey: `user_localesidkey_${this.testId}`,
|
|
519
777
|
EmailEncodingKey: `user_emailencodingkey_${this.testId}`,
|
|
@@ -522,17 +780,20 @@ class MockTestOrgData {
|
|
|
522
780
|
Email: `user_email@${this.testId}.com`,
|
|
523
781
|
};
|
|
524
782
|
}
|
|
783
|
+
/**
|
|
784
|
+
* Return the auth config file contents.
|
|
785
|
+
*/
|
|
525
786
|
async getConfig() {
|
|
526
787
|
const crypto = await crypto_2.Crypto.create();
|
|
527
788
|
const config = {};
|
|
528
789
|
config.orgId = this.orgId;
|
|
790
|
+
config.clientId = this.clientId;
|
|
529
791
|
const accessToken = crypto.encrypt(this.accessToken);
|
|
530
792
|
if (accessToken) {
|
|
531
793
|
config.accessToken = accessToken;
|
|
532
794
|
}
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
config.refreshToken = refreshToken;
|
|
795
|
+
if (this.refreshToken) {
|
|
796
|
+
config.refreshToken = crypto.encrypt(this.refreshToken);
|
|
536
797
|
}
|
|
537
798
|
config.instanceUrl = this.instanceUrl;
|
|
538
799
|
config.loginUrl = this.loginUrl;
|
|
@@ -540,16 +801,53 @@ class MockTestOrgData {
|
|
|
540
801
|
config.createdOrgInstance = 'CS1';
|
|
541
802
|
config.created = '1519163543003';
|
|
542
803
|
config.userId = this.userId;
|
|
543
|
-
|
|
804
|
+
config.tracksSource = this.tracksSource;
|
|
544
805
|
if (this.devHubUsername) {
|
|
545
806
|
config.devHubUsername = this.devHubUsername;
|
|
546
807
|
}
|
|
547
|
-
|
|
548
|
-
if (
|
|
549
|
-
config.
|
|
808
|
+
config.isDevHub = this.isDevHub;
|
|
809
|
+
if (this.password) {
|
|
810
|
+
config.password = crypto.encrypt(this.password);
|
|
550
811
|
}
|
|
551
812
|
return config;
|
|
552
813
|
}
|
|
814
|
+
/**
|
|
815
|
+
* Return the Connection for the org.
|
|
816
|
+
*/
|
|
817
|
+
async getConnection() {
|
|
818
|
+
return (await org_1.Org.create({ aliasOrUsername: this.username })).getConnection();
|
|
819
|
+
}
|
|
553
820
|
}
|
|
554
821
|
exports.MockTestOrgData = MockTestOrgData;
|
|
822
|
+
/**
|
|
823
|
+
* Mock class for Salesforce Sandboxes.
|
|
824
|
+
*
|
|
825
|
+
* @example
|
|
826
|
+
* ```
|
|
827
|
+
* const testOrg = new MockTestSandboxData();
|
|
828
|
+
* await $$.stubSandboxes(testOrg)
|
|
829
|
+
* ```
|
|
830
|
+
*/
|
|
831
|
+
class MockTestSandboxData {
|
|
832
|
+
constructor(id = uniqid(), options) {
|
|
833
|
+
this.id = id;
|
|
834
|
+
this.sandboxOrgId = id;
|
|
835
|
+
this.prodOrgUsername = options?.prodOrgUsername ?? `admin_${id}@gb.org`;
|
|
836
|
+
this.sandboxName = options?.name ?? `sandbox_${id}`;
|
|
837
|
+
this.username = options?.username ?? `${this.prodOrgUsername}.sandbox`;
|
|
838
|
+
}
|
|
839
|
+
/**
|
|
840
|
+
* Return the auth config file contents.
|
|
841
|
+
*/
|
|
842
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
843
|
+
async getConfig() {
|
|
844
|
+
return {
|
|
845
|
+
sandboxOrgId: this.sandboxOrgId,
|
|
846
|
+
prodOrgUsername: this.prodOrgUsername,
|
|
847
|
+
sandboxName: this.sandboxName,
|
|
848
|
+
sandboxUsername: this.username,
|
|
849
|
+
};
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
exports.MockTestSandboxData = MockTestSandboxData;
|
|
555
853
|
//# sourceMappingURL=testSetup.js.map
|