@deenruv/testing 1.0.0
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 +23 -0
- package/README.md +5 -0
- package/lib/config/test-config.d.ts +26 -0
- package/lib/config/test-config.js +70 -0
- package/lib/config/test-config.js.map +1 -0
- package/lib/config/testing-asset-preview-strategy.d.ts +13 -0
- package/lib/config/testing-asset-preview-strategy.js +21 -0
- package/lib/config/testing-asset-preview-strategy.js.map +1 -0
- package/lib/config/testing-asset-storage-strategy.d.ts +18 -0
- package/lib/config/testing-asset-storage-strategy.js +47 -0
- package/lib/config/testing-asset-storage-strategy.js.map +1 -0
- package/lib/config/testing-entity-id-strategy.d.ts +11 -0
- package/lib/config/testing-entity-id-strategy.js +22 -0
- package/lib/config/testing-entity-id-strategy.js.map +1 -0
- package/lib/create-test-environment.d.ts +57 -0
- package/lib/create-test-environment.js +47 -0
- package/lib/create-test-environment.js.map +1 -0
- package/lib/data-population/clear-all-tables.d.ts +5 -0
- package/lib/data-population/clear-all-tables.js +32 -0
- package/lib/data-population/clear-all-tables.js.map +1 -0
- package/lib/data-population/mock-data.service.d.ts +21 -0
- package/lib/data-population/mock-data.service.js +108 -0
- package/lib/data-population/mock-data.service.js.map +1 -0
- package/lib/data-population/populate-customers.d.ts +5 -0
- package/lib/data-population/populate-customers.js +30 -0
- package/lib/data-population/populate-customers.js.map +1 -0
- package/lib/data-population/populate-for-testing.d.ts +7 -0
- package/lib/data-population/populate-for-testing.js +42 -0
- package/lib/data-population/populate-for-testing.js.map +1 -0
- package/lib/error-result-guard.d.ts +65 -0
- package/lib/error-result-guard.js +85 -0
- package/lib/error-result-guard.js.map +1 -0
- package/lib/index.d.ts +14 -0
- package/lib/index.js +31 -0
- package/lib/index.js.map +1 -0
- package/lib/initializers/initializers.d.ts +14 -0
- package/lib/initializers/initializers.js +24 -0
- package/lib/initializers/initializers.js.map +1 -0
- package/lib/initializers/mysql-initializer.d.ts +10 -0
- package/lib/initializers/mysql-initializer.js +43 -0
- package/lib/initializers/mysql-initializer.js.map +1 -0
- package/lib/initializers/postgres-initializer.d.ts +10 -0
- package/lib/initializers/postgres-initializer.js +41 -0
- package/lib/initializers/postgres-initializer.js.map +1 -0
- package/lib/initializers/sqljs-initializer.d.ts +19 -0
- package/lib/initializers/sqljs-initializer.js +55 -0
- package/lib/initializers/sqljs-initializer.js.map +1 -0
- package/lib/initializers/test-db-initializer.d.ts +42 -0
- package/lib/initializers/test-db-initializer.js +3 -0
- package/lib/initializers/test-db-initializer.js.map +1 -0
- package/lib/simple-graphql-client.d.ts +86 -0
- package/lib/simple-graphql-client.js +229 -0
- package/lib/simple-graphql-client.js.map +1 -0
- package/lib/test-server.d.ts +45 -0
- package/lib/test-server.js +123 -0
- package/lib/test-server.js.map +1 -0
- package/lib/testing-logger.d.ts +67 -0
- package/lib/testing-logger.js +82 -0
- package/lib/testing-logger.js.map +1 -0
- package/lib/types.d.ts +42 -0
- package/lib/types.js +3 -0
- package/lib/types.js.map +1 -0
- package/lib/utils/create-upload-post-data.d.ts +23 -0
- package/lib/utils/create-upload-post-data.js +55 -0
- package/lib/utils/create-upload-post-data.js.map +1 -0
- package/lib/utils/get-superadmin-context.d.ts +10 -0
- package/lib/utils/get-superadmin-context.js +40 -0
- package/lib/utils/get-superadmin-context.js.map +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ClientError = exports.SimpleGraphQLClient = void 0;
|
|
7
|
+
const shared_constants_1 = require("@deenruv/common/lib/shared-constants");
|
|
8
|
+
const form_data_1 = __importDefault(require("form-data"));
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const printer_1 = require("graphql/language/printer");
|
|
11
|
+
const graphql_tag_1 = __importDefault(require("graphql-tag"));
|
|
12
|
+
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
13
|
+
const querystring_1 = require("querystring");
|
|
14
|
+
const create_upload_post_data_1 = require("./utils/create-upload-post-data");
|
|
15
|
+
const LOGIN = (0, graphql_tag_1.default) `
|
|
16
|
+
mutation ($username: String!, $password: String!) {
|
|
17
|
+
login(username: $username, password: $password) {
|
|
18
|
+
... on CurrentUser {
|
|
19
|
+
id
|
|
20
|
+
identifier
|
|
21
|
+
channels {
|
|
22
|
+
token
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
... on ErrorResult {
|
|
26
|
+
errorCode
|
|
27
|
+
message
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
`;
|
|
32
|
+
/**
|
|
33
|
+
* @description
|
|
34
|
+
* A minimalistic GraphQL client for populating and querying test data.
|
|
35
|
+
*
|
|
36
|
+
* @docsCategory testing
|
|
37
|
+
*/
|
|
38
|
+
class SimpleGraphQLClient {
|
|
39
|
+
constructor(deenruvConfig, apiUrl = "") {
|
|
40
|
+
this.deenruvConfig = deenruvConfig;
|
|
41
|
+
this.apiUrl = apiUrl;
|
|
42
|
+
this.channelToken = null;
|
|
43
|
+
this.headers = {
|
|
44
|
+
"Apollo-Require-Preflight": "true",
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* @description
|
|
49
|
+
* Sets the authToken to be used in each GraphQL request.
|
|
50
|
+
*/
|
|
51
|
+
setAuthToken(token) {
|
|
52
|
+
this.authToken = token;
|
|
53
|
+
this.headers.Authorization = `Bearer ${this.authToken}`;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* @description
|
|
57
|
+
* Sets the authToken to be used in each GraphQL request.
|
|
58
|
+
*/
|
|
59
|
+
setChannelToken(token) {
|
|
60
|
+
this.channelToken = token;
|
|
61
|
+
if (this.deenruvConfig.apiOptions.channelTokenKey) {
|
|
62
|
+
this.headers[this.deenruvConfig.apiOptions.channelTokenKey] =
|
|
63
|
+
this.channelToken;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* @description
|
|
68
|
+
* Returns the authToken currently being used.
|
|
69
|
+
*/
|
|
70
|
+
getAuthToken() {
|
|
71
|
+
return this.authToken;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* @description
|
|
75
|
+
* Performs both query and mutation operations.
|
|
76
|
+
*/
|
|
77
|
+
async query(query, variables, queryParams) {
|
|
78
|
+
const response = await this.makeGraphQlRequest(query, variables, queryParams);
|
|
79
|
+
const result = await this.getResult(response);
|
|
80
|
+
if (response.ok && !result.errors && result.data) {
|
|
81
|
+
return result.data;
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
const errorResult = typeof result === "string" ? { error: result } : result;
|
|
85
|
+
throw new ClientError(Object.assign(Object.assign({}, errorResult), { status: response.status }), { query: (0, printer_1.print)(query), variables });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* @description
|
|
90
|
+
* Performs a raw HTTP request to the given URL, but also includes the authToken & channelToken
|
|
91
|
+
* headers if they have been set. Useful for testing non-GraphQL endpoints, e.g. for plugins
|
|
92
|
+
* which make use of REST controllers.
|
|
93
|
+
*/
|
|
94
|
+
async fetch(url, options = {}) {
|
|
95
|
+
const headers = Object.assign(Object.assign({ "Content-Type": "application/json" }, this.headers), options.headers);
|
|
96
|
+
const response = await (0, node_fetch_1.default)(url, Object.assign(Object.assign({}, options), { headers }));
|
|
97
|
+
const authToken = response.headers.get(this.deenruvConfig.authOptions.authTokenHeaderKey || "");
|
|
98
|
+
if (authToken != null) {
|
|
99
|
+
this.setAuthToken(authToken);
|
|
100
|
+
}
|
|
101
|
+
return response;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* @description
|
|
105
|
+
* Performs a query or mutation and returns the resulting status code.
|
|
106
|
+
*/
|
|
107
|
+
async queryStatus(query, variables) {
|
|
108
|
+
const response = await this.makeGraphQlRequest(query, variables);
|
|
109
|
+
return response.status;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* @description
|
|
113
|
+
* Attempts to log in with the specified credentials.
|
|
114
|
+
*/
|
|
115
|
+
async asUserWithCredentials(username, password) {
|
|
116
|
+
var _a;
|
|
117
|
+
// first log out as the current user
|
|
118
|
+
if (this.authToken) {
|
|
119
|
+
await this.query((0, graphql_tag_1.default) `
|
|
120
|
+
mutation {
|
|
121
|
+
logout {
|
|
122
|
+
success
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
`);
|
|
126
|
+
}
|
|
127
|
+
const result = await this.query(LOGIN, { username, password });
|
|
128
|
+
if (((_a = result.login.channels) === null || _a === void 0 ? void 0 : _a.length) === 1) {
|
|
129
|
+
this.setChannelToken(result.login.channels[0].token);
|
|
130
|
+
}
|
|
131
|
+
return result.login;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* @description
|
|
135
|
+
* Logs in as the SuperAdmin user.
|
|
136
|
+
*/
|
|
137
|
+
async asSuperAdmin() {
|
|
138
|
+
var _a, _b;
|
|
139
|
+
const { superadminCredentials } = this.deenruvConfig.authOptions;
|
|
140
|
+
await this.asUserWithCredentials((_a = superadminCredentials === null || superadminCredentials === void 0 ? void 0 : superadminCredentials.identifier) !== null && _a !== void 0 ? _a : shared_constants_1.SUPER_ADMIN_USER_IDENTIFIER, (_b = superadminCredentials === null || superadminCredentials === void 0 ? void 0 : superadminCredentials.password) !== null && _b !== void 0 ? _b : shared_constants_1.SUPER_ADMIN_USER_PASSWORD);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* @description
|
|
144
|
+
* Logs out so that the client is then treated as an anonymous user.
|
|
145
|
+
*/
|
|
146
|
+
async asAnonymousUser() {
|
|
147
|
+
await this.query((0, graphql_tag_1.default) `
|
|
148
|
+
mutation {
|
|
149
|
+
logout {
|
|
150
|
+
success
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
`);
|
|
154
|
+
}
|
|
155
|
+
async makeGraphQlRequest(query, variables, queryParams) {
|
|
156
|
+
const queryString = (0, printer_1.print)(query);
|
|
157
|
+
const body = JSON.stringify({
|
|
158
|
+
query: queryString,
|
|
159
|
+
variables: variables ? variables : undefined,
|
|
160
|
+
});
|
|
161
|
+
const url = queryParams
|
|
162
|
+
? this.apiUrl + `?${(0, querystring_1.stringify)(queryParams)}`
|
|
163
|
+
: this.apiUrl;
|
|
164
|
+
return this.fetch(url, {
|
|
165
|
+
method: "POST",
|
|
166
|
+
body,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
async getResult(response) {
|
|
170
|
+
const contentType = response.headers.get("Content-Type");
|
|
171
|
+
if (contentType && contentType.startsWith("application/json")) {
|
|
172
|
+
return response.json();
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
return response.text();
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* @description
|
|
180
|
+
* Perform a file upload mutation.
|
|
181
|
+
*
|
|
182
|
+
* Upload spec: https://github.com/jaydenseric/graphql-multipart-request-spec
|
|
183
|
+
* Discussion of issue: https://github.com/jaydenseric/apollo-upload-client/issues/32
|
|
184
|
+
*/
|
|
185
|
+
async fileUploadMutation(options) {
|
|
186
|
+
const { mutation, filePaths, mapVariables } = options;
|
|
187
|
+
const postData = (0, create_upload_post_data_1.createUploadPostData)(mutation, filePaths, mapVariables);
|
|
188
|
+
const body = new form_data_1.default();
|
|
189
|
+
body.append("operations", JSON.stringify(postData.operations));
|
|
190
|
+
body.append("map", "{" +
|
|
191
|
+
Object.entries(postData.map)
|
|
192
|
+
.map(([i, path]) => `"${i}":["${path}"]`)
|
|
193
|
+
.join(",") +
|
|
194
|
+
"}");
|
|
195
|
+
for (const filePath of postData.filePaths) {
|
|
196
|
+
const file = fs_1.default.readFileSync(filePath.file);
|
|
197
|
+
body.append(filePath.name, file, { filename: filePath.file });
|
|
198
|
+
}
|
|
199
|
+
const result = await (0, node_fetch_1.default)(this.apiUrl, {
|
|
200
|
+
method: "POST",
|
|
201
|
+
body,
|
|
202
|
+
headers: Object.assign({}, this.headers),
|
|
203
|
+
});
|
|
204
|
+
const response = await result.json();
|
|
205
|
+
if (response.errors && response.errors.length) {
|
|
206
|
+
const error = response.errors[0];
|
|
207
|
+
throw new Error(error.message);
|
|
208
|
+
}
|
|
209
|
+
return response.data;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
exports.SimpleGraphQLClient = SimpleGraphQLClient;
|
|
213
|
+
class ClientError extends Error {
|
|
214
|
+
constructor(response, request) {
|
|
215
|
+
super(ClientError.extractMessage(response));
|
|
216
|
+
this.response = response;
|
|
217
|
+
this.request = request;
|
|
218
|
+
}
|
|
219
|
+
static extractMessage(response) {
|
|
220
|
+
if (response.errors) {
|
|
221
|
+
return response.errors[0].message;
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
return `GraphQL Error (Code: ${response.status})`;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
exports.ClientError = ClientError;
|
|
229
|
+
//# sourceMappingURL=simple-graphql-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simple-graphql-client.js","sourceRoot":"","sources":["../src/simple-graphql-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { INestApplication } from "@nestjs/common";
|
|
2
|
+
import { DeenruvConfig } from "@deenruv/core";
|
|
3
|
+
import { TestServerOptions } from "./types";
|
|
4
|
+
/**
|
|
5
|
+
* @description
|
|
6
|
+
* A real Deenruv server against which the e2e tests should be run.
|
|
7
|
+
*
|
|
8
|
+
* @docsCategory testing
|
|
9
|
+
*/
|
|
10
|
+
export declare class TestServer {
|
|
11
|
+
private deenruvConfig;
|
|
12
|
+
app: INestApplication;
|
|
13
|
+
constructor(deenruvConfig: Required<DeenruvConfig>);
|
|
14
|
+
/**
|
|
15
|
+
* @description
|
|
16
|
+
* Bootstraps an instance of Deenruv server and populates the database according to the options
|
|
17
|
+
* passed in. Should be called in the `beforeAll` function.
|
|
18
|
+
*
|
|
19
|
+
* The populated data is saved into an .sqlite file for each test file. On subsequent runs, this file
|
|
20
|
+
* is loaded so that the populate step can be skipped, which speeds up the tests significantly.
|
|
21
|
+
*/
|
|
22
|
+
init(options: TestServerOptions): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* @description
|
|
25
|
+
* Bootstraps a Deenruv server instance. Generally the `.init()` method should be used, as that will also
|
|
26
|
+
* populate the test data. However, the `bootstrap()` method is sometimes useful in tests which need to
|
|
27
|
+
* start and stop a Deenruv instance multiple times without re-populating data.
|
|
28
|
+
*/
|
|
29
|
+
bootstrap(): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* @description
|
|
32
|
+
* Destroy the Deenruv server instance and clean up all resources.
|
|
33
|
+
* Should be called after all tests have run, e.g. in an `afterAll` function.
|
|
34
|
+
*/
|
|
35
|
+
destroy(): Promise<void>;
|
|
36
|
+
private getCallerFilename;
|
|
37
|
+
/**
|
|
38
|
+
* Populates an .sqlite database file based on the PopulateOptions.
|
|
39
|
+
*/
|
|
40
|
+
private populateInitialData;
|
|
41
|
+
/**
|
|
42
|
+
* Bootstraps an instance of the Deenruv server for testing against.
|
|
43
|
+
*/
|
|
44
|
+
private bootstrapForTesting;
|
|
45
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TestServer = void 0;
|
|
4
|
+
const core_1 = require("@nestjs/core");
|
|
5
|
+
const core_2 = require("@deenruv/core");
|
|
6
|
+
const bootstrap_1 = require("@deenruv/core/dist/bootstrap");
|
|
7
|
+
const populate_for_testing_1 = require("./data-population/populate-for-testing");
|
|
8
|
+
const initializers_1 = require("./initializers/initializers");
|
|
9
|
+
/**
|
|
10
|
+
* @description
|
|
11
|
+
* A real Deenruv server against which the e2e tests should be run.
|
|
12
|
+
*
|
|
13
|
+
* @docsCategory testing
|
|
14
|
+
*/
|
|
15
|
+
class TestServer {
|
|
16
|
+
constructor(deenruvConfig) {
|
|
17
|
+
this.deenruvConfig = deenruvConfig;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* @description
|
|
21
|
+
* Bootstraps an instance of Deenruv server and populates the database according to the options
|
|
22
|
+
* passed in. Should be called in the `beforeAll` function.
|
|
23
|
+
*
|
|
24
|
+
* The populated data is saved into an .sqlite file for each test file. On subsequent runs, this file
|
|
25
|
+
* is loaded so that the populate step can be skipped, which speeds up the tests significantly.
|
|
26
|
+
*/
|
|
27
|
+
async init(options) {
|
|
28
|
+
const { type } = this.deenruvConfig.dbConnectionOptions;
|
|
29
|
+
const { dbConnectionOptions } = this.deenruvConfig;
|
|
30
|
+
const testFilename = this.getCallerFilename(1);
|
|
31
|
+
const initializer = (0, initializers_1.getInitializerFor)(type);
|
|
32
|
+
try {
|
|
33
|
+
await initializer.init(testFilename, dbConnectionOptions);
|
|
34
|
+
const populateFn = () => this.populateInitialData(this.deenruvConfig, options);
|
|
35
|
+
await initializer.populate(populateFn);
|
|
36
|
+
await initializer.destroy();
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
throw e;
|
|
40
|
+
}
|
|
41
|
+
await this.bootstrap();
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* @description
|
|
45
|
+
* Bootstraps a Deenruv server instance. Generally the `.init()` method should be used, as that will also
|
|
46
|
+
* populate the test data. However, the `bootstrap()` method is sometimes useful in tests which need to
|
|
47
|
+
* start and stop a Deenruv instance multiple times without re-populating data.
|
|
48
|
+
*/
|
|
49
|
+
async bootstrap() {
|
|
50
|
+
this.app = await this.bootstrapForTesting(this.deenruvConfig);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* @description
|
|
54
|
+
* Destroy the Deenruv server instance and clean up all resources.
|
|
55
|
+
* Should be called after all tests have run, e.g. in an `afterAll` function.
|
|
56
|
+
*/
|
|
57
|
+
async destroy() {
|
|
58
|
+
var _a;
|
|
59
|
+
// allow a grace period of any outstanding async tasks to complete
|
|
60
|
+
await new Promise((resolve) => global.setTimeout(resolve, 500));
|
|
61
|
+
await ((_a = this.app) === null || _a === void 0 ? void 0 : _a.close());
|
|
62
|
+
}
|
|
63
|
+
getCallerFilename(depth) {
|
|
64
|
+
let stack;
|
|
65
|
+
let file;
|
|
66
|
+
let frame;
|
|
67
|
+
const pst = Error.prepareStackTrace;
|
|
68
|
+
Error.prepareStackTrace = (_, _stack) => {
|
|
69
|
+
Error.prepareStackTrace = pst;
|
|
70
|
+
return _stack;
|
|
71
|
+
};
|
|
72
|
+
stack = new Error().stack;
|
|
73
|
+
stack = stack.slice(depth + 1);
|
|
74
|
+
do {
|
|
75
|
+
frame = stack.shift();
|
|
76
|
+
file = frame && frame.getFileName();
|
|
77
|
+
} while (stack.length && file === "module.js");
|
|
78
|
+
return file;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Populates an .sqlite database file based on the PopulateOptions.
|
|
82
|
+
*/
|
|
83
|
+
async populateInitialData(testingConfig, options) {
|
|
84
|
+
const app = await (0, populate_for_testing_1.populateForTesting)(testingConfig, this.bootstrapForTesting, Object.assign({ logging: false }, options));
|
|
85
|
+
await app.close();
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Bootstraps an instance of the Deenruv server for testing against.
|
|
89
|
+
*/
|
|
90
|
+
async bootstrapForTesting(userConfig) {
|
|
91
|
+
const config = await (0, bootstrap_1.preBootstrapConfig)(userConfig);
|
|
92
|
+
core_2.Logger.useLogger(config.logger);
|
|
93
|
+
const appModule = await import("@deenruv/core/dist/app.module.js");
|
|
94
|
+
try {
|
|
95
|
+
core_2.DefaultLogger.hideNestBootstrapLogs();
|
|
96
|
+
const app = await core_1.NestFactory.create(appModule.AppModule, {
|
|
97
|
+
cors: config.apiOptions.cors,
|
|
98
|
+
logger: new core_2.Logger(),
|
|
99
|
+
abortOnError: false,
|
|
100
|
+
});
|
|
101
|
+
const { tokenMethod } = config.authOptions;
|
|
102
|
+
const usingCookie = tokenMethod === "cookie" ||
|
|
103
|
+
(Array.isArray(tokenMethod) && tokenMethod.includes("cookie"));
|
|
104
|
+
if (usingCookie) {
|
|
105
|
+
(0, bootstrap_1.configureSessionCookies)(app, config);
|
|
106
|
+
}
|
|
107
|
+
const earlyMiddlewares = config.apiOptions.middleware.filter((mid) => mid.beforeListen);
|
|
108
|
+
earlyMiddlewares.forEach((mid) => {
|
|
109
|
+
app.use(mid.route, mid.handler);
|
|
110
|
+
});
|
|
111
|
+
await app.listen(config.apiOptions.port);
|
|
112
|
+
await app.get(core_2.JobQueueService).start();
|
|
113
|
+
core_2.DefaultLogger.restoreOriginalLogLevel();
|
|
114
|
+
return app;
|
|
115
|
+
}
|
|
116
|
+
catch (e) {
|
|
117
|
+
console.log(e);
|
|
118
|
+
throw e;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
exports.TestServer = TestServer;
|
|
123
|
+
//# sourceMappingURL=test-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-server.js","sourceRoot":"","sources":["../src/test-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { DeenruvLogger } from "@deenruv/core";
|
|
2
|
+
/**
|
|
3
|
+
* @description
|
|
4
|
+
* The TestingLogger can be used in unit tests or e2e tests to make assertions on whether the various
|
|
5
|
+
* Logger methods have been called, and which arguments.
|
|
6
|
+
*
|
|
7
|
+
* Here's some examples of how to use it in e2e tests and unit tests. In both cases we are using
|
|
8
|
+
* the Jest testing framework, but the TestingLogger should work with other similar frameworks
|
|
9
|
+
* (e.g. replacing `jest.fn()` with `jasmine.createSpy()`).
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* // e2e test example
|
|
14
|
+
* import { createTestEnvironment, TestingLogger } from '\@deenruv/testing';
|
|
15
|
+
*
|
|
16
|
+
* const testingLogger = new TestingLogger(() => jest.fn());
|
|
17
|
+
*
|
|
18
|
+
* const { server, adminClient, shopClient } = createTestEnvironment({
|
|
19
|
+
* ...testConfig,
|
|
20
|
+
* logger: testingLogger,
|
|
21
|
+
* });
|
|
22
|
+
*
|
|
23
|
+
* // e2e testing setup omitted
|
|
24
|
+
*
|
|
25
|
+
* it('should log an error', async () => {
|
|
26
|
+
* // The `errorSpy` property exposes the Jest mock function
|
|
27
|
+
* testingLogger.errorSpy.mockClear();
|
|
28
|
+
*
|
|
29
|
+
* await doSomethingThatErrors();
|
|
30
|
+
*
|
|
31
|
+
* expect(testingLogger.errorSpy).toHaveBeenCalled();
|
|
32
|
+
* });
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* // unit test example
|
|
38
|
+
* import { Test } from '\@nestjs/testing';
|
|
39
|
+
* import { Logger } from '\@deenruv/core';
|
|
40
|
+
* import { TestingLogger } from '\@deenruv/testing';
|
|
41
|
+
*
|
|
42
|
+
* beforeEach(async () => {
|
|
43
|
+
* const moduleRef = await Test.createTestingModule({
|
|
44
|
+
* // Nest testing setup omitted
|
|
45
|
+
* }).compile();
|
|
46
|
+
*
|
|
47
|
+
* Logger.useLogger(testingLogger);
|
|
48
|
+
* moduleRef.useLogger(new Logger());
|
|
49
|
+
* }
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* @docsCategory testing
|
|
53
|
+
*/
|
|
54
|
+
export declare class TestingLogger<Spy extends (...args: any[]) => any> implements DeenruvLogger {
|
|
55
|
+
private createSpyFn;
|
|
56
|
+
constructor(createSpyFn: () => Spy);
|
|
57
|
+
debugSpy: Spy;
|
|
58
|
+
errorSpy: Spy;
|
|
59
|
+
infoSpy: Spy;
|
|
60
|
+
verboseSpy: Spy;
|
|
61
|
+
warnSpy: Spy;
|
|
62
|
+
debug(message: string, context?: string): void;
|
|
63
|
+
error(message: string, context?: string, trace?: string): void;
|
|
64
|
+
info(message: string, context?: string): void;
|
|
65
|
+
verbose(message: string, context?: string): void;
|
|
66
|
+
warn(message: string, context?: string): void;
|
|
67
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TestingLogger = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* @description
|
|
6
|
+
* The TestingLogger can be used in unit tests or e2e tests to make assertions on whether the various
|
|
7
|
+
* Logger methods have been called, and which arguments.
|
|
8
|
+
*
|
|
9
|
+
* Here's some examples of how to use it in e2e tests and unit tests. In both cases we are using
|
|
10
|
+
* the Jest testing framework, but the TestingLogger should work with other similar frameworks
|
|
11
|
+
* (e.g. replacing `jest.fn()` with `jasmine.createSpy()`).
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* // e2e test example
|
|
16
|
+
* import { createTestEnvironment, TestingLogger } from '\@deenruv/testing';
|
|
17
|
+
*
|
|
18
|
+
* const testingLogger = new TestingLogger(() => jest.fn());
|
|
19
|
+
*
|
|
20
|
+
* const { server, adminClient, shopClient } = createTestEnvironment({
|
|
21
|
+
* ...testConfig,
|
|
22
|
+
* logger: testingLogger,
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* // e2e testing setup omitted
|
|
26
|
+
*
|
|
27
|
+
* it('should log an error', async () => {
|
|
28
|
+
* // The `errorSpy` property exposes the Jest mock function
|
|
29
|
+
* testingLogger.errorSpy.mockClear();
|
|
30
|
+
*
|
|
31
|
+
* await doSomethingThatErrors();
|
|
32
|
+
*
|
|
33
|
+
* expect(testingLogger.errorSpy).toHaveBeenCalled();
|
|
34
|
+
* });
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* // unit test example
|
|
40
|
+
* import { Test } from '\@nestjs/testing';
|
|
41
|
+
* import { Logger } from '\@deenruv/core';
|
|
42
|
+
* import { TestingLogger } from '\@deenruv/testing';
|
|
43
|
+
*
|
|
44
|
+
* beforeEach(async () => {
|
|
45
|
+
* const moduleRef = await Test.createTestingModule({
|
|
46
|
+
* // Nest testing setup omitted
|
|
47
|
+
* }).compile();
|
|
48
|
+
*
|
|
49
|
+
* Logger.useLogger(testingLogger);
|
|
50
|
+
* moduleRef.useLogger(new Logger());
|
|
51
|
+
* }
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* @docsCategory testing
|
|
55
|
+
*/
|
|
56
|
+
class TestingLogger {
|
|
57
|
+
constructor(createSpyFn) {
|
|
58
|
+
this.createSpyFn = createSpyFn;
|
|
59
|
+
this.debugSpy = createSpyFn();
|
|
60
|
+
this.errorSpy = createSpyFn();
|
|
61
|
+
this.infoSpy = createSpyFn();
|
|
62
|
+
this.verboseSpy = createSpyFn();
|
|
63
|
+
this.warnSpy = createSpyFn();
|
|
64
|
+
}
|
|
65
|
+
debug(message, context) {
|
|
66
|
+
this.debugSpy(message, context);
|
|
67
|
+
}
|
|
68
|
+
error(message, context, trace) {
|
|
69
|
+
this.errorSpy(message, context, trace);
|
|
70
|
+
}
|
|
71
|
+
info(message, context) {
|
|
72
|
+
this.infoSpy(message, context);
|
|
73
|
+
}
|
|
74
|
+
verbose(message, context) {
|
|
75
|
+
this.verboseSpy(message, context);
|
|
76
|
+
}
|
|
77
|
+
warn(message, context) {
|
|
78
|
+
this.warnSpy(message, context);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.TestingLogger = TestingLogger;
|
|
82
|
+
//# sourceMappingURL=testing-logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testing-logger.js","sourceRoot":"","sources":["../src/testing-logger.ts"],"names":[],"mappings":";;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AACH,MAAa,aAAa;IAGxB,YAAoB,WAAsB;QAAtB,gBAAW,GAAX,WAAW,CAAW;QACxC,IAAI,CAAC,QAAQ,GAAG,WAAW,EAAE,CAAC;QAC9B,IAAI,CAAC,QAAQ,GAAG,WAAW,EAAE,CAAC;QAC9B,IAAI,CAAC,OAAO,GAAG,WAAW,EAAE,CAAC;QAC7B,IAAI,CAAC,UAAU,GAAG,WAAW,EAAE,CAAC;QAChC,IAAI,CAAC,OAAO,GAAG,WAAW,EAAE,CAAC;IAC/B,CAAC;IAQD,KAAK,CAAC,OAAe,EAAE,OAAgB;QACrC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,OAAgB,EAAE,KAAc;QACrD,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IACzC,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,OAAgB;QACpC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACjC,CAAC;IAED,OAAO,CAAC,OAAe,EAAE,OAAgB;QACvC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACpC,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,OAAgB;QACpC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACjC,CAAC;CACF;AApCD,sCAoCC"}
|
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { InitialData } from "@deenruv/core";
|
|
2
|
+
/**
|
|
3
|
+
* Creates a mutable version of a type with readonly properties.
|
|
4
|
+
*/
|
|
5
|
+
export type Mutable<T> = {
|
|
6
|
+
-readonly [K in keyof T]: T[K];
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* @description
|
|
10
|
+
* Configuration options used to initialize an instance of the {@link TestServer}.
|
|
11
|
+
*
|
|
12
|
+
* @docsCategory testing
|
|
13
|
+
*/
|
|
14
|
+
export interface TestServerOptions {
|
|
15
|
+
/**
|
|
16
|
+
* @description
|
|
17
|
+
* The path to an optional CSV file containing product data to import.
|
|
18
|
+
*/
|
|
19
|
+
productsCsvPath?: string;
|
|
20
|
+
/**
|
|
21
|
+
* @description
|
|
22
|
+
* An object containing non-product data which is used to populate the database.
|
|
23
|
+
*/
|
|
24
|
+
initialData: InitialData;
|
|
25
|
+
/**
|
|
26
|
+
* @description
|
|
27
|
+
* The number of fake Customers to populate into the database.
|
|
28
|
+
*
|
|
29
|
+
* @default 10
|
|
30
|
+
*/
|
|
31
|
+
customerCount?: number;
|
|
32
|
+
/**
|
|
33
|
+
* @description
|
|
34
|
+
* Set this to `true` to log some information about the database population process.
|
|
35
|
+
*
|
|
36
|
+
* @default false
|
|
37
|
+
*/
|
|
38
|
+
logging?: boolean;
|
|
39
|
+
}
|
|
40
|
+
export type QueryParams = {
|
|
41
|
+
[key: string]: string | number;
|
|
42
|
+
};
|
package/lib/types.js
ADDED
package/lib/types.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { DocumentNode } from "graphql";
|
|
2
|
+
export interface FilePlaceholder {
|
|
3
|
+
file: null;
|
|
4
|
+
}
|
|
5
|
+
export interface UploadPostData<V = any> {
|
|
6
|
+
operations: {
|
|
7
|
+
operationName: string;
|
|
8
|
+
variables: V;
|
|
9
|
+
query: string;
|
|
10
|
+
};
|
|
11
|
+
map: {
|
|
12
|
+
[index: number]: string;
|
|
13
|
+
};
|
|
14
|
+
filePaths: Array<{
|
|
15
|
+
name: string;
|
|
16
|
+
file: string;
|
|
17
|
+
}>;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Creates a data structure which can be used to mae a curl request to upload files to a mutation using
|
|
21
|
+
* the Upload type.
|
|
22
|
+
*/
|
|
23
|
+
export declare function createUploadPostData<P extends string[] | string, V>(mutation: DocumentNode, filePaths: P, mapVariables: (filePaths: P) => V): UploadPostData<V>;
|