@naturalcycles/dev-lib 20.60.0 → 20.61.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/dist/testing/testOffline.js +39 -1
- package/package.json +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
1
2
|
import { AppError } from '@naturalcycles/js-lib/error/error.util.js';
|
|
2
3
|
import { red } from '@naturalcycles/nodejs-lib/colors';
|
|
3
4
|
import { createMitm } from '../vendor/mitm.js';
|
|
@@ -18,7 +19,8 @@ export function testOffline(opt) {
|
|
|
18
19
|
mitm.on('connect', (socket, socketOptions) => {
|
|
19
20
|
const { host } = socketOptions;
|
|
20
21
|
if (!LOCAL_HOSTS.has(host)) {
|
|
21
|
-
|
|
22
|
+
const testInfo = getCurrentTestInfo(host);
|
|
23
|
+
process.stderr.write(red(`Network request forbidden by testOffline: ${testInfo}\n`));
|
|
22
24
|
opt?.onForbiddenRequest?.(host);
|
|
23
25
|
throw new AppError(`Network request forbidden by testOffline: ${host}`, {
|
|
24
26
|
backendResponseStatusCode: 410,
|
|
@@ -34,3 +36,39 @@ export function testOnline() {
|
|
|
34
36
|
mitm?.disable();
|
|
35
37
|
mitm = undefined;
|
|
36
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Returns the test name and test file that triggered the request (as tracked by vitest),
|
|
41
|
+
* formatted as `test: <name>, file: <path>` to append to the alert, so the culprit is easy to find.
|
|
42
|
+
* Returns an empty string when nothing is known (e.g. vitest is not installed or not running,
|
|
43
|
+
* or the request was made outside of any test).
|
|
44
|
+
*
|
|
45
|
+
* Reads vitest's worker state from the global vitest stores it in (the same source that
|
|
46
|
+
* `expect.getState()` uses for `testPath` and `currentTestName`), instead of importing `vitest`:
|
|
47
|
+
* - it has to be synchronous (see the `connect` listener), and `vitest` can only be imported asynchronously
|
|
48
|
+
* - `vitest` may not be installed in the consuming project
|
|
49
|
+
*/
|
|
50
|
+
function getCurrentTestInfo(host) {
|
|
51
|
+
const tokens = [host];
|
|
52
|
+
const state = globalThis['__vitest_worker__'];
|
|
53
|
+
if (state) {
|
|
54
|
+
if (state.filepath) {
|
|
55
|
+
tokens.push(`file: ${path.relative(process.cwd(), state.filepath)}`);
|
|
56
|
+
}
|
|
57
|
+
if (state.current?.type === 'test') {
|
|
58
|
+
tokens.push(`test: ${getFullTestName(state.current)}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return tokens.filter(Boolean).join('\n');
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Test name prefixed with the names of its parent suites (same as `expect.getState().currentTestName`),
|
|
65
|
+
* e.g. `describe name > nested describe name > test name`.
|
|
66
|
+
*/
|
|
67
|
+
function getFullTestName(test) {
|
|
68
|
+
const names = [];
|
|
69
|
+
// Walk up the chain of parent suites; it ends with `undefined` (or with the file itself, which is excluded)
|
|
70
|
+
for (let task = test; task && task !== test.file; task = task.suite) {
|
|
71
|
+
names.push(task.name);
|
|
72
|
+
}
|
|
73
|
+
return names.reverse().join(' > ');
|
|
74
|
+
}
|