/
test-destination-mocker.ts
135 lines (126 loc) · 4.79 KB
/
test-destination-mocker.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/* Copyright (c) 2020 SAP SE or an SAP affiliate company. All rights reserved. */
import { Destination } from '@sap-cloud-sdk/core';
import {
getTestDestinationByAlias,
GetTestDestinationOptions,
getTestDestinations
} from './test-destination-provider';
/**
* Add a destination with the given name from the `systems.json` and `credentials.json` files to the `destinations` environment variable.
*
* Throws an error if a destination with the same name as the given test destination already exists.
*
* @param name - Name of the test destination to add to the `destinations` environment variable
* @param options - References to the `systems.json` and `credentials.json` files
*/
export function mockTestDestination(
name: string,
options?: GetTestDestinationOptions
): void {
const mockedDestination = getTestDestinationByAlias(name, options);
setTestDestination(mockedDestination);
}
/**
* Set a given destination in the `destinations` environment variable.
*
* Throws an error if a destination with the same name as the given test destination already exists.
*
* @param destination - Test destination to add to the `destinations` environment variable
* @param options - References to the `systems.json` and `credentials.json` files
*/
export function setTestDestination(destination: Destination): void {
const currentDestinations = getDestinationsFromEnv();
const existingNames = new Set<string>(
currentDestinations.map(dest => {
if (!dest.name) {
throw Error('The destination name is undefined.');
}
return dest.name;
})
);
if (!destination.name) {
throw Error('The destination name is undefined.');
}
validateNameAvailable(destination.name, existingNames);
destination.isTestDestination = true;
setDestinationsInEnv([...currentDestinations, destination]);
}
/**
* Removes a destination with the given name from the destinations environment variable. If the given destination name is not found calling this function has no effect.
* This function should be called to invert the behavior of [[mockTestDestination]]() and [[setTestDestination]]().
*
* @param name - Name of the mocked destination to remove
*/
export function unmockTestDestination(name: string): void {
const currentDestinations = getDestinationsFromEnv();
const cleanedDestinations = currentDestinations.filter(
destination => !(destination.isTestDestination && destination.name === name)
);
setDestinationsInEnv(cleanedDestinations);
}
/**
* Add all destinations from the `systems.json` and `credentials.json` files to the `destinations` environment variable.
*
* Throws an error if a destination with the same name as the given test destinations already exists.
*
* @param options - References to the `systems.json` and `credentials.json` files
*/
export function mockAllTestDestinations(
options?: GetTestDestinationOptions
): void {
const testDestinations = getTestDestinations(options);
const currentDestinations = getDestinationsFromEnv();
const existingNames = new Set<string>(
currentDestinations.map(dest => {
if (!dest.name) {
throw Error('The destination name is undefined.');
}
return dest.name;
})
);
testDestinations.forEach(dest => {
if (!dest.name) {
throw Error(
"At least one of the provided destinations is missing a the 'name' property!"
);
}
validateNameAvailable(dest.name, existingNames);
currentDestinations.push(dest);
});
setDestinationsInEnv(currentDestinations);
}
/**
* Removes all test destinations stored in `systems.json` and `credentials.json` files or added through [[setTestDestination]]() from the `destinations` environment variable.
*
* This function should be called to invert the behavior of [[mockAllTestDestinations]]() and other add single mocked destination functions.
*/
export function unmockAllTestDestinations(): void {
const currentDestinations = getDestinationsFromEnv();
const cleanedDestinations = currentDestinations.filter(
destination => !destination.isTestDestination
);
setDestinationsInEnv(cleanedDestinations);
}
function validateNameAvailable(
destinationName: string,
existingNames: Set<string>
): void {
if (existingNames.has(destinationName)) {
throw new Error(
`Parsing mocked destinations failed, destination with name "${destinationName}" already exists in the "destinations" environment variables.`
);
}
}
function setDestinationsInEnv(destinations: Destination[]): void {
process.env['destinations'] = JSON.stringify(destinations);
}
function getDestinationsFromEnv(): Destination[] {
try {
const envDestinations = process.env['destinations'] || '[]';
return JSON.parse(envDestinations);
} catch (error) {
throw new Error(
`Destinations environment variable cannot be read: ${error.message}`
);
}
}