UNPKG

17.6 kBTypeScriptView Raw
1/// <reference types="node" />
2import { EventEmitter } from 'events';
3import { SinonSandbox, SinonStatic, SinonStub } 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: SinonSandbox;
19 CRYPTO: SinonSandbox;
20 CONFIG: SinonSandbox;
21 PROJECT: SinonSandbox;
22 CONNECTION: SinonSandbox;
23 FS: SinonSandbox;
24 ORGS: 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 * Instantiate a @salesforce/core test context.
59 */
60export declare class TestContext {
61 /**
62 * The default sandbox is cleared out before each test run.
63 *
64 * **See** [sinon sandbox]{@link https://sinonjs.org/releases/v14/sandbox/}.
65 */
66 SANDBOX: 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 * An object used in tests that interact with config files.
82 */
83 configStubs: {
84 [configName: string]: Optional<ConfigStub>;
85 AliasesConfig?: ConfigStub;
86 AuthInfoConfig?: ConfigStub;
87 Config?: ConfigStub;
88 SfProjectJson?: ConfigStub;
89 TokensConfig?: ConfigStub;
90 OrgUsersConfig?: ConfigStub;
91 };
92 /**
93 * A record of stubs created during instantiation.
94 */
95 stubs: Record<string, SinonStub>;
96 constructor(options?: {
97 sinon?: SinonStatic;
98 sandbox?: SinonSandbox;
99 setup?: boolean;
100 });
101 /**
102 * Generate unique string.
103 */
104 uniqid(): string;
105 /**
106 * A function used when resolving the local path. Calls localPathResolverSync by default.
107 *
108 * @param uid Unique id.
109 */
110 localPathRetriever(uid: string): Promise<string>;
111 /**
112 * A function used when resolving the local path.
113 *
114 * @param uid Unique id.
115 */
116 localPathRetrieverSync(uid: string): string;
117 /**
118 * A function used when resolving the global path. Calls globalPathResolverSync by default.
119 *
120 * @param uid Unique id.
121 */
122 globalPathRetriever(uid: string): Promise<string>;
123 /**
124 * A function used when resolving the global path.
125 *
126 * @param uid Unique id.
127 */
128 globalPathRetrieverSync(uid: string): string;
129 /**
130 * A function used for resolving paths. Calls localPathRetriever and globalPathRetriever.
131 *
132 * @param isGlobal `true` if the config is global.
133 * @param uid user id.
134 */
135 rootPathRetriever(isGlobal: boolean, uid?: string): Promise<string>;
136 /**
137 * A function used for resolving paths. Calls localPathRetrieverSync and globalPathRetrieverSync.
138 *
139 * @param isGlobal `true` if the config is global.
140 * @param uid user id.
141 */
142 rootPathRetrieverSync(isGlobal: boolean, uid?: string): string;
143 /**
144 * Used to mock http request to Salesforce.
145 *
146 * @param request An HttpRequest.
147 * @param options Additional options.
148 *
149 * **See** {@link Connection.request}
150 */
151 fakeConnectionRequest(request: AnyJson, options?: AnyJson): Promise<AnyJson>;
152 /**
153 * Gets a config stub contents by name.
154 *
155 * @param name The name of the config.
156 * @param group If the config supports groups.
157 */
158 getConfigStubContents(name: string, group?: string): ConfigContents;
159 /**
160 * Sets a config stub contents by name
161 *
162 * @param name The name of the config stub.
163 * @param value The actual stub contents. The Mock data.
164 */
165 setConfigStubContents(name: string, value: ConfigContents): void;
166 /**
167 * Set stubs for working in the context of a SfProject
168 */
169 inProject(inProject?: boolean): void;
170 /**
171 * Stub salesforce org authorizations.
172 */
173 stubAuths(...orgs: MockTestOrgData[]): Promise<void>;
174 /**
175 * Stub salesforce user authorizations.
176 *
177 * @param users The users to stub.
178 * 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.
179 * The admin user is excluded from the users array.
180 *
181 */
182 stubUsers(users: Record<string, MockTestOrgData[]>): void;
183 /**
184 * Stub salesforce sandbox authorizations.
185 */
186 stubSandboxes(...sandboxes: MockTestSandboxData[]): Promise<void>;
187 /**
188 * Stub the aliases in the global aliases config file.
189 */
190 stubAliases(aliases: Record<string, string>, group?: AliasGroup): void;
191 /**
192 * Stub contents in the config file.
193 */
194 stubConfig(config: Record<string, string>): Promise<void>;
195 /**
196 * Stub the tokens in the global token config file.
197 */
198 stubTokens(tokens: Record<string, string>): void;
199 restore(): void;
200 init(): void;
201 /**
202 * Add beforeEach and afterEach hooks to init the stubs and restore them.
203 * This is called automatically when the class is instantiated unless the setup option is set to false.
204 */
205 setup(): void;
206 private requireSinon;
207}
208/**
209 * A function to generate a unique id and return it in the context of a template, if supplied.
210 *
211 * A template is a string that can contain `${%s}` to be replaced with a unique id.
212 * If the template contains the "%s" placeholder, it will be replaced with the unique id otherwise the id will be appended to the template.
213 *
214 * @param options an object with the following properties:
215 * - template: a template string.
216 * - length: the length of the unique id as presented in hexadecimal.
217 */
218export declare function uniqid(options?: {
219 template?: string;
220 length?: number;
221}): string;
222/**
223 * Instantiate a @salesforce/core test context. This is automatically created by `const $$ = testSetup()`
224 * but is useful if you don't want to have a global stub of @salesforce/core and you want to isolate it to
225 * a single describe.
226 *
227 * **Note:** Call `stubContext` in your beforeEach to have clean stubs of @salesforce/core every test run.
228 *
229 * @example
230 * ```
231 * const $$ = instantiateContext();
232 *
233 * beforeEach(() => {
234 * $$.init()
235 * });
236 *
237 * afterEach(() => {
238 * $$.restore();
239 * });
240 * ```
241 * @param sinon
242 */
243export declare const instantiateContext: (sinon?: SinonStatic) => TestContext;
244/**
245 * Stub a @salesforce/core test context. This will mock out logging to a file, config file reading and writing,
246 * local and global path resolution, and http request using connection (soon)*.
247 *
248 * This is automatically stubbed in the global beforeEach created by
249 * `const $$ = testSetup()` but is useful if you don't want to have a global stub of @salesforce/core and you
250 * want to isolate it to a single describe.
251 *
252 * **Note:** Always call `restoreContext` in your afterEach.
253 *
254 * @example
255 * ```
256 * const $$ = instantiateContext();
257 *
258 * beforeEach(() => {
259 * $$.init()
260 * });
261 *
262 * afterEach(() => {
263 * $$.restore();
264 * });
265 * ```
266 * @param testContext
267 */
268export declare const stubContext: (testContext: TestContext) => Record<string, SinonStub>;
269/**
270 * Restore a @salesforce/core test context. This is automatically stubbed in the global beforeEach created by
271 * `const $$ = testSetup()` but is useful if you don't want to have a global stub of @salesforce/core and you
272 * want to isolate it to a single describe.
273 *
274 * @example
275 * ```
276 * const $$ = instantiateContext();
277 *
278 * beforeEach(() => {
279 * $$.init()
280 * });
281 *
282 * afterEach(() => {
283 * $$.restore();
284 * });
285 * ```
286 * @param testContext
287 */
288export declare const restoreContext: (testContext: TestContext) => void;
289/**
290 * @deprecated Use TestContext instead.
291 * Using testSetup will create globals stubs that could lead to erratic test behavior.
292 *
293 * This example shows you how to use TestContext:
294 * @example
295 * ```
296 * const $$ = new TestContext();
297 *
298 * beforeEach(() => {
299 * $$.init();
300 * });
301 *
302 * afterEach(() => {
303 * $$.restore();
304 * });
305 * ```
306 *
307 * Use to mock out different pieces of sfdx-core to make testing easier. This will mock out
308 * logging to a file, config file reading and writing, local and global path resolution, and
309 * *http request using connection (soon)*.
310 *
311 * **Note:** The testSetup should be outside of the describe. If you need to stub per test, use
312 * `TestContext`.
313 * ```
314 * // In a mocha tests
315 * import testSetup from '@salesforce/core/lib/testSetup';
316 *
317 * const $$ = testSetup();
318 *
319 * describe(() => {
320 * it('test', () => {
321 * // Stub out your own method
322 * $$.SANDBOX.stub(MyClass.prototype, 'myMethod').returnsFake(() => {});
323 *
324 * // Set the contents that is used when aliases are read. Same for all config files.
325 * $$.stubAliases({ 'myTestAlias': 'user@company.com' });
326 *
327 * // Will use the contents set above.
328 * const username = (await StateAggregator.getInstance()).aliases.resolveUsername("myTestAlias");
329 * expect(username).to.equal("user@company.com");
330 * });
331 * });
332 * ```
333 */
334export declare const testSetup: (sinon?: SinonStatic) => TestContext;
335/**
336 * A pre-canned error for try/catch testing.
337 *
338 * **See** {@link shouldThrow}
339 */
340export declare const unexpectedResult: SfError;
341/**
342 * Use for this testing pattern:
343 * ```
344 * try {
345 * await call()
346 * assert.fail("this should never happen");
347 * } catch (e) {
348 * ...
349 * }
350 *
351 * Just do this
352 *
353 * try {
354 * await shouldThrow(call()); // If this succeeds unexpectedResultError is thrown.
355 * } catch(e) {
356 * ...
357 * }
358 * ```
359 *
360 * @param f The async function that is expected to throw.
361 */
362export declare function shouldThrow(f: Promise<unknown>, message?: string): Promise<never>;
363/**
364 * Use for this testing pattern:
365 * ```
366 * try {
367 * call()
368 * assert.fail("this should never happen");
369 * } catch (e) {
370 * ...
371 * }
372 *
373 * Just do this
374 *
375 * try {
376 * shouldThrowSync(call); // If this succeeds unexpectedResultError is thrown.
377 * } catch(e) {
378 * ...
379 * }
380 * ```
381 *
382 * @param f The function that is expected to throw.
383 */
384export declare function shouldThrowSync(f: () => unknown, message?: string): never;
385/**
386 * A helper to determine if a subscription will use callback or errorback.
387 * Enable errback to simulate a subscription failure.
388 */
389export declare enum StreamingMockSubscriptionCall {
390 CALLBACK = 0,
391 ERRORBACK = 1
392}
393/**
394 * Additional subscription options for the StreamingMock.
395 */
396export interface StreamingMockCometSubscriptionOptions {
397 /**
398 * Target URL.
399 */
400 url: string;
401 /**
402 * Simple id to associate with this instance.
403 */
404 id: string;
405 /**
406 * What is the subscription outcome a successful callback or an error?.
407 */
408 subscriptionCall: StreamingMockSubscriptionCall;
409 /**
410 * If it's an error that states what that error should be.
411 */
412 subscriptionErrbackError?: SfError;
413 /**
414 * A list of messages to playback for the client. One message per process tick.
415 */
416 messagePlaylist?: Message[];
417}
418/**
419 * Simulates a comet subscription to a streaming channel.
420 */
421export declare class StreamingMockCometSubscription extends EventEmitter implements CometSubscription {
422 static SUBSCRIPTION_COMPLETE: string;
423 static SUBSCRIPTION_FAILED: string;
424 private options;
425 constructor(options: StreamingMockCometSubscriptionOptions);
426 /**
427 * Sets up a streaming subscription callback to occur after the setTimeout event loop phase.
428 *
429 * @param callback The function to invoke.
430 */
431 callback(callback: () => void): void;
432 /**
433 * Sets up a streaming subscription errback to occur after the setTimeout event loop phase.
434 *
435 * @param callback The function to invoke.
436 */
437 errback(callback: (error: Error) => void): void;
438}
439/**
440 * Simulates a comet client. To the core streaming client this mocks the internal comet impl.
441 * The uses setTimeout(0ms) event loop phase just so the client can simulate actual streaming without the response
442 * latency.
443 */
444export declare class StreamingMockCometClient extends CometClient {
445 private readonly options;
446 /**
447 * Constructor
448 *
449 * @param {StreamingMockCometSubscriptionOptions} options Extends the StreamingClient options.
450 */
451 constructor(options: StreamingMockCometSubscriptionOptions);
452 /**
453 * Fake addExtension. Does nothing.
454 */
455 addExtension(extension: StreamingExtension): void;
456 /**
457 * Fake disable. Does nothing.
458 */
459 disable(label: string): void;
460 /**
461 * Fake handshake that invoke callback after the setTimeout event phase.
462 *
463 * @param callback The function to invoke.
464 */
465 handshake(callback: () => void): void;
466 /**
467 * Fake setHeader. Does nothing,
468 */
469 setHeader(name: string, value: string): void;
470 /**
471 * Fake subscription that completed after the setTimout event phase.
472 *
473 * @param channel The streaming channel.
474 * @param callback The function to invoke after the subscription completes.
475 */
476 subscribe(channel: string, callback: (message: Message) => void): CometSubscription;
477 /**
478 * Fake disconnect. Does Nothing.
479 */
480 disconnect(): Promise<void>;
481}
482type MockUserInfo = {
483 Id: string;
484 Username: string;
485 LastName: string;
486 Alias: string;
487 Configs: string[] | undefined;
488 TimeZoneSidKey: string;
489 LocaleSidKey: string;
490 EmailEncodingKey: string;
491 ProfileId: string;
492 LanguageLocaleKey: string;
493 Email: string;
494};
495/**
496 * Mock class for Salesforce Orgs.
497 *
498 * @example
499 * ```
500 * const testOrg = new MockTestOrgData();
501 * await $$.stubAuths(testOrg)
502 * ```
503 */
504export declare class MockTestOrgData {
505 testId: string;
506 aliases?: string[];
507 configs?: string[];
508 username: string;
509 devHubUsername?: string;
510 orgId: string;
511 loginUrl: string;
512 instanceUrl: string;
513 clientId: string;
514 clientSecret: string;
515 authcode: string;
516 accessToken: string;
517 refreshToken: string | undefined;
518 tracksSource: boolean | undefined;
519 userId: string;
520 redirectUri: string;
521 isDevHub?: boolean;
522 isScratchOrg?: boolean;
523 isExpired?: boolean | 'unknown';
524 password?: string;
525 constructor(id?: string, options?: {
526 username: string;
527 });
528 /**
529 * Add devhub username to properties.
530 */
531 createDevHubUsername(username: string): void;
532 /**
533 * Mark this org as a devhub.
534 */
535 makeDevHub(): void;
536 /**
537 * Returns a MockTestOrgData that represents a user created in the org.
538 */
539 createUser(user: string): MockTestOrgData;
540 /**
541 * Return mock user information based on this org.
542 */
543 getMockUserInfo(): MockUserInfo;
544 /**
545 * Return the auth config file contents.
546 */
547 getConfig(): Promise<AuthFields>;
548 /**
549 * Return the Connection for the org.
550 */
551 getConnection(): Promise<Connection>;
552}
553/**
554 * Mock class for Salesforce Sandboxes.
555 *
556 * @example
557 * ```
558 * const testOrg = new MockTestSandboxData();
559 * await $$.stubSandboxes(testOrg)
560 * ```
561 */
562export declare class MockTestSandboxData {
563 id: string;
564 sandboxOrgId: string;
565 prodOrgUsername: string;
566 sandboxName?: string;
567 username?: string;
568 constructor(id?: string, options?: Partial<{
569 prodOrgUsername: string;
570 name: string;
571 username: string;
572 }>);
573 /**
574 * Return the auth config file contents.
575 */
576 getConfig(): Promise<SandboxFields>;
577}
578export {};