UNPKG

16.5 kBTypeScriptView Raw
1/// <reference types="node" />
2import { EventEmitter } from 'events';
3import * as sinonType from 'sinon';
4import { AnyJson, JsonMap, Optional } from '@salesforce/ts-types';
5import { ConfigContents } from './config/configStore';
6import { Connection } from './org/connection';
7import { Logger } from './logger';
8import { SfError } from './sfError';
9import { CometClient, CometSubscription, Message, StreamingExtension } from './status/streamingClient';
10import { AuthFields, SandboxFields } from './org';
11import { AliasGroup } from './config/aliasesConfig';
12/**
13 * Different parts of the system that are mocked out. They can be restored for
14 * individual tests. Test's stubs should always go on the DEFAULT which is exposed
15 * on the TestContext.
16 */
17export interface SandboxTypes {
18 DEFAULT: sinon.SinonSandbox;
19 CRYPTO: sinon.SinonSandbox;
20 CONFIG: sinon.SinonSandbox;
21 PROJECT: sinon.SinonSandbox;
22 CONNECTION: sinon.SinonSandbox;
23 FS: sinonType.SinonSandbox;
24 ORGS: sinonType.SinonSandbox;
25}
26/**
27 * Different hooks into {@link ConfigFile} used for testing instead of doing file IO.
28 */
29export interface ConfigStub {
30 /**
31 * readFn A function that controls all aspect of {@link ConfigFile.read}. For example, it won't set the contents
32 * unless explicitly done. Only use this if you know what you are doing. Use retrieveContents
33 * instead.
34 */
35 readFn?: () => Promise<ConfigContents>;
36 /**
37 * A function that controls all aspects of {@link ConfigFile.write}. For example, it won't read the contents unless
38 * explicitly done. Only use this if you know what you are doing. Use updateContents instead.
39 */
40 writeFn?: (contents?: AnyJson) => Promise<void>;
41 /**
42 * The contents that are used with @{link ConfigFile.readSync} and @{link ConfigFile.read}. If retrieveContents is set,
43 * it will use that instead of @{link ConfigFile.read} but NOT @{link ConfigFile.readSync}. This will also contain the
44 * new config when @{link ConfigFile.write} or @{link ConfigFile.writeSync} is called. This will persist through config instances,
45 * such as {@link Alias.update} and {@link Alias.fetch}.
46 */
47 contents?: ConfigContents;
48 /**
49 * A function to conditionally read based on the config instance. The `this` value will be the config instance.
50 */
51 retrieveContents?: () => Promise<JsonMap>;
52 /**
53 * A function to conditionally set based on the config instance. The `this` value will be the config instance.
54 */
55 updateContents?: () => Promise<JsonMap>;
56}
57/**
58 * Different configuration options when running before each
59 */
60export interface TestContext {
61 /**
62 * The default sandbox is cleared out before each test run.
63 *
64 * **See** [sinon sandbox]{@link http://sinonjs.org/releases/v1.17.7/sandbox/}.
65 */
66 SANDBOX: sinonType.SinonSandbox;
67 /**
68 * An object of different sandboxes. Used when
69 * needing to restore parts of the system for customized testing.
70 */
71 SANDBOXES: SandboxTypes;
72 /**
73 * The test logger that is used when {@link Logger.child} is used anywhere. It uses memory logging.
74 */
75 TEST_LOGGER: Logger;
76 /**
77 * id A unique id for the test run.
78 */
79 id: string;
80 /**
81 * A function that returns unique strings.
82 */
83 uniqid: () => string;
84 /**
85 * An object used in tests that interact with config files.
86 */
87 configStubs: {
88 [configName: string]: Optional<ConfigStub>;
89 AliasesConfig?: ConfigStub;
90 AuthInfoConfig?: ConfigStub;
91 Config?: ConfigStub;
92 SfProjectJson?: ConfigStub;
93 TokensConfig?: ConfigStub;
94 };
95 /**
96 * An record of stubs created during instantaion.
97 */
98 stubs: {
99 configRead?: sinonType.SinonStub;
100 configReadSync?: sinonType.SinonStub;
101 configWriteSync?: sinonType.SinonStub;
102 configWrite?: sinonType.SinonStub;
103 configExists?: sinonType.SinonStub;
104 configRemove?: sinonType.SinonStub;
105 };
106 /**
107 * A function used when resolving the local path. Calls localPathResolverSync by default.
108 *
109 * @param uid Unique id.
110 */
111 localPathRetriever: (uid: string) => Promise<string>;
112 /**
113 * A function used when resolving the local path.
114 *
115 * @param uid Unique id.
116 */
117 localPathRetrieverSync: (uid: string) => string;
118 /**
119 * A function used when resolving the global path. Calls globalPathResolverSync by default.
120 *
121 * @param uid Unique id.
122 */
123 globalPathRetriever: (uid: string) => Promise<string>;
124 /**
125 * A function used when resolving the global path.
126 *
127 * @param uid Unique id.
128 */
129 globalPathRetrieverSync: (uid: string) => string;
130 /**
131 * A function used for resolving paths. Calls localPathRetriever and globalPathRetriever.
132 *
133 * @param isGlobal `true` if the config is global.
134 * @param uid user id.
135 */
136 rootPathRetriever: (isGlobal: boolean, uid?: string) => Promise<string>;
137 /**
138 * A function used for resolving paths. Calls localPathRetrieverSync and globalPathRetrieverSync.
139 *
140 * @param isGlobal `true` if the config is global.
141 * @param uid user id.
142 */
143 rootPathRetrieverSync: (isGlobal: boolean, uid?: string) => string;
144 /**
145 * Used to mock http request to Salesforce.
146 *
147 * @param request An HttpRequest.
148 * @param options Additional options.
149 *
150 * **See** {@link Connection.request}
151 */
152 fakeConnectionRequest: (request: AnyJson, options?: AnyJson) => Promise<AnyJson>;
153 /**
154 * Gets a config stub contents by name.
155 *
156 * @param name The name of the config.
157 * @param group If the config supports groups.
158 */
159 getConfigStubContents(name: string, group?: string): ConfigContents;
160 /**
161 * Sets a config stub contents by name
162 *
163 * @param name The name of the config stub.
164 * @param value The actual stub contents. The Mock data.
165 */
166 setConfigStubContents(name: string, value: ConfigContents): void;
167 /**
168 * Set stubs for working in the context of a SfProject
169 */
170 inProject(inProject: boolean): void;
171 /**
172 * Stub salesforce org authorizations.
173 */
174 stubAuths(...orgs: MockTestOrgData[]): Promise<void>;
175 /**
176 * Stub salesforce sandbox authorizations.
177 */
178 stubSandboxes(...orgs: MockTestSandboxData[]): Promise<void>;
179 /**
180 * Stub the aliases in the global aliases config file.
181 */
182 stubAliases(aliases: Record<string, string>, group?: AliasGroup): void;
183 /**
184 * Stub contents in the config file.
185 */
186 stubConfig(config: Record<string, string>): void;
187 /**
188 * Stub the tokens in the global token config file.
189 */
190 stubTokens(tokens: Record<string, string>): void;
191}
192/**
193 * A function to generate a unique id and return it in the context of a template, if supplied.
194 *
195 * A template is a string that can contain `${%s}` to be replaced with a unique id.
196 * If the template contains the "%s" placeholder, it will be replaced with the unique id otherwise the id will be appended to the template.
197 *
198 * @param options an object with the following properties:
199 * - template: a template string.
200 * - length: the length of the unique id as presented in hexadecimal.
201 */
202export declare function uniqid(options?: {
203 template?: string;
204 length?: number;
205}): string;
206/**
207 * Instantiate a @salesforce/core test context. This is automatically created by `const $$ = testSetup()`
208 * but is useful if you don't want to have a global stub of @salesforce/core and you want to isolate it to
209 * a single describe.
210 *
211 * **Note:** Call `stubContext` in your beforeEach to have clean stubs of @salesforce/core every test run.
212 *
213 * @example
214 * ```
215 * const $$ = instantiateContext();
216 *
217 * beforeEach(() => {
218 * stubContext($$);
219 * });
220 *
221 * afterEach(() => {
222 * restoreContext($$);
223 * });
224 * ```
225 * @param sinon
226 */
227export declare const instantiateContext: (sinon?: any) => TestContext;
228/**
229 * Stub a @salesforce/core test context. This will mock out logging to a file, config file reading and writing,
230 * local and global path resolution, and http request using connection (soon)*.
231 *
232 * This is automatically stubbed in the global beforeEach created by
233 * `const $$ = testSetup()` but is useful if you don't want to have a global stub of @salesforce/core and you
234 * want to isolate it to a single describe.
235 *
236 * **Note:** Always call `restoreContext` in your afterEach.
237 *
238 * @example
239 * ```
240 * const $$ = instantiateContext();
241 *
242 * beforeEach(() => {
243 * stubContext($$);
244 * });
245 *
246 * afterEach(() => {
247 * restoreContext($$);
248 * });
249 * ```
250 * @param testContext
251 */
252export declare const stubContext: (testContext: TestContext) => Record<string, sinonType.SinonStub>;
253/**
254 * Restore a @salesforce/core test context. This is automatically stubbed in the global beforeEach created by
255 * `const $$ = testSetup()` but is useful if you don't want to have a global stub of @salesforce/core and you
256 * want to isolate it to a single describe.
257 *
258 * @example
259 * ```
260 * const $$ = instantiateContext();
261 *
262 * beforeEach(() => {
263 * stubContext($$);
264 * });
265 *
266 * afterEach(() => {
267 * restoreContext($$);
268 * });
269 * ```
270 * @param testContext
271 */
272export declare const restoreContext: (testContext: TestContext) => void;
273/**
274 * Use to mock out different pieces of sfdx-core to make testing easier. This will mock out
275 * logging to a file, config file reading and writing, local and global path resolution, and
276 * *http request using connection (soon)*.
277 *
278 * **Note:** The testSetup should be outside of the describe. If you need to stub per test, use
279 * `instantiateContext`, `stubContext`, and `restoreContext`.
280 * ```
281 * // In a mocha tests
282 * import testSetup from '@salesforce/core/lib/testSetup';
283 *
284 * const $$ = testSetup();
285 *
286 * describe(() => {
287 * it('test', () => {
288 * // Stub out your own method
289 * $$.SANDBOX.stub(MyClass.prototype, 'myMethod').returnsFake(() => {});
290 *
291 * // Set the contents that is used when aliases are read. Same for all config files.
292 * $$.stubAliases({ 'myTestAlias': 'user@company.com' });
293 *
294 * // Will use the contents set above.
295 * const username = (await StateAggregator.getInstance()).aliases.resolveUseranme('myTestAlias');
296 * expect(username).to.equal('user@company.com');
297 * });
298 * });
299 * ```
300 */
301export declare const testSetup: (sinon?: any) => TestContext;
302/**
303 * A pre-canned error for try/catch testing.
304 *
305 * **See** {@link shouldThrow}
306 */
307export declare const unexpectedResult: SfError;
308/**
309 * Use for this testing pattern:
310 * ```
311 * try {
312 * await call()
313 * assert.fail('this should never happen');
314 * } catch (e) {
315 * ...
316 * }
317 *
318 * Just do this
319 *
320 * try {
321 * await shouldThrow(call()); // If this succeeds unexpectedResultError is thrown.
322 * } catch(e) {
323 * ...
324 * }
325 * ```
326 *
327 * @param f The async function that is expected to throw.
328 */
329export declare function shouldThrow(f: Promise<unknown>, message?: string): Promise<never>;
330/**
331 * Use for this testing pattern:
332 * ```
333 * try {
334 * call()
335 * assert.fail('this should never happen');
336 * } catch (e) {
337 * ...
338 * }
339 *
340 * Just do this
341 *
342 * try {
343 * shouldThrowSync(call); // If this succeeds unexpectedResultError is thrown.
344 * } catch(e) {
345 * ...
346 * }
347 * ```
348 *
349 * @param f The function that is expected to throw.
350 */
351export declare function shouldThrowSync(f: () => unknown, message?: string): never;
352/**
353 * A helper to determine if a subscription will use callback or errorback.
354 * Enable errback to simulate a subscription failure.
355 */
356export declare enum StreamingMockSubscriptionCall {
357 CALLBACK = 0,
358 ERRORBACK = 1
359}
360/**
361 * Additional subscription options for the StreamingMock.
362 */
363export interface StreamingMockCometSubscriptionOptions {
364 /**
365 * Target URL.
366 */
367 url: string;
368 /**
369 * Simple id to associate with this instance.
370 */
371 id: string;
372 /**
373 * What is the subscription outcome a successful callback or an error?.
374 */
375 subscriptionCall: StreamingMockSubscriptionCall;
376 /**
377 * If it's an error that states what that error should be.
378 */
379 subscriptionErrbackError?: SfError;
380 /**
381 * A list of messages to playback for the client. One message per process tick.
382 */
383 messagePlaylist?: Message[];
384}
385/**
386 * Simulates a comet subscription to a streaming channel.
387 */
388export declare class StreamingMockCometSubscription extends EventEmitter implements CometSubscription {
389 static SUBSCRIPTION_COMPLETE: string;
390 static SUBSCRIPTION_FAILED: string;
391 private options;
392 constructor(options: StreamingMockCometSubscriptionOptions);
393 /**
394 * Sets up a streaming subscription callback to occur after the setTimeout event loop phase.
395 *
396 * @param callback The function to invoke.
397 */
398 callback(callback: () => void): void;
399 /**
400 * Sets up a streaming subscription errback to occur after the setTimeout event loop phase.
401 *
402 * @param callback The function to invoke.
403 */
404 errback(callback: (error: Error) => void): void;
405}
406/**
407 * Simulates a comet client. To the core streaming client this mocks the internal comet impl.
408 * The uses setTimeout(0ms) event loop phase just so the client can simulate actual streaming without the response
409 * latency.
410 */
411export declare class StreamingMockCometClient extends CometClient {
412 private readonly options;
413 /**
414 * Constructor
415 *
416 * @param {StreamingMockCometSubscriptionOptions} options Extends the StreamingClient options.
417 */
418 constructor(options: StreamingMockCometSubscriptionOptions);
419 /**
420 * Fake addExtension. Does nothing.
421 */
422 addExtension(extension: StreamingExtension): void;
423 /**
424 * Fake disable. Does nothing.
425 */
426 disable(label: string): void;
427 /**
428 * Fake handshake that invoke callback after the setTimeout event phase.
429 *
430 * @param callback The function to invoke.
431 */
432 handshake(callback: () => void): void;
433 /**
434 * Fake setHeader. Does nothing,
435 */
436 setHeader(name: string, value: string): void;
437 /**
438 * Fake subscription that completed after the setTimout event phase.
439 *
440 * @param channel The streaming channel.
441 * @param callback The function to invoke after the subscription completes.
442 */
443 subscribe(channel: string, callback: (message: Message) => void): CometSubscription;
444 /**
445 * Fake disconnect. Does Nothing.
446 */
447 disconnect(): Promise<void>;
448}
449/**
450 * Mock class for Salesforce Orgs.
451 *
452 * @example
453 * const testOrg = new MockTestOrgData();
454 * await $$.stubAuths(testOrg)
455 */
456export declare class MockTestOrgData {
457 testId: string;
458 aliases?: string[];
459 configs?: string[];
460 username: string;
461 devHubUsername?: string;
462 orgId: string;
463 loginUrl: string;
464 instanceUrl: string;
465 clientId: string;
466 clientSecret: string;
467 authcode: string;
468 accessToken: string;
469 refreshToken: string;
470 tracksSource: boolean | undefined;
471 userId: string;
472 redirectUri: string;
473 isDevHub?: boolean;
474 isScratchOrg?: boolean;
475 isExpired?: boolean | 'unknown';
476 constructor(id?: string, options?: {
477 username: string;
478 });
479 /**
480 * Add devhub username to properties.
481 */
482 createDevHubUsername(username: string): void;
483 /**
484 * Mark this org as a devhub.
485 */
486 makeDevHub(): void;
487 /**
488 * Returns a MockTestOrgData that represents a user created in the org.
489 */
490 createUser(user: string): MockTestOrgData;
491 /**
492 * Return mock user information based on this org.
493 */
494 getMockUserInfo(): JsonMap;
495 /**
496 * Return the auth config file contents.
497 */
498 getConfig(): Promise<AuthFields>;
499 /**
500 * Return the Connection for the org.
501 */
502 getConnection(): Promise<Connection>;
503}
504/**
505 * Mock class for Salesforce Sandboxes.
506 *
507 * @example
508 * const testOrg = new MockTestSandboxData();
509 * await $$.stubSandboxes(testOrg)
510 */
511export declare class MockTestSandboxData {
512 id: string;
513 sandboxOrgId: string;
514 prodOrgUsername: string;
515 sandboxName?: string;
516 username?: string;
517 constructor(id?: string, options?: Partial<{
518 prodOrgUsername: string;
519 name: string;
520 username: string;
521 }>);
522 /**
523 * Return the auth config file contents.
524 */
525 getConfig(): Promise<SandboxFields>;
526}