bulltrackers-module 1.0.892 → 1.0.893
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.
|
@@ -16,6 +16,11 @@ process.env.COMPUTATION_VERIFICATION_URL = '';
|
|
|
16
16
|
// Mock Redis so sync route uses Firestore rate-limit path (path relative to Core where Jest runs)
|
|
17
17
|
jest.mock('bulltrackers-module/functions/shared/upstashRedis', () => ({ getRedis: () => null }));
|
|
18
18
|
|
|
19
|
+
// Force in-process verification in tests (no sandbox HTTP). Use same path as route require() so Jest applies the mock.
|
|
20
|
+
jest.mock('../services/verificationSandboxClient', () => ({
|
|
21
|
+
callVerificationSandbox: () => Promise.resolve(null),
|
|
22
|
+
}));
|
|
23
|
+
|
|
19
24
|
const request = require('supertest');
|
|
20
25
|
const { createTestApp } = require('./test-app-factory');
|
|
21
26
|
|
|
@@ -983,9 +988,10 @@ describe('Cross-Cutting', () => {
|
|
|
983
988
|
});
|
|
984
989
|
|
|
985
990
|
it('returns 200 and writes to GCS when code passes verification', async () => {
|
|
991
|
+
// Use process: (ctx) => ... so extracted process source re-parses when wrapped in parens (method shorthand process(ctx){ } is invalid as a standalone expression).
|
|
986
992
|
const validCode = `module.exports = {
|
|
987
993
|
config: { name: 'SafeComp', skills: ['lib'], requires: {} },
|
|
988
|
-
process(ctx)
|
|
994
|
+
process: (ctx) => ({ ok: true, date: ctx.date })
|
|
989
995
|
};`;
|
|
990
996
|
const res = await request(app)
|
|
991
997
|
.post('/computations/upload')
|
|
@@ -169,6 +169,13 @@ function createMockFirestore() {
|
|
|
169
169
|
commit: async () => { for (const op of ops) await op(); },
|
|
170
170
|
};
|
|
171
171
|
},
|
|
172
|
+
runTransaction(callback) {
|
|
173
|
+
const t = {
|
|
174
|
+
get: async (ref) => ref.get(),
|
|
175
|
+
set: async (ref, data, opts) => ref.set(data, opts),
|
|
176
|
+
};
|
|
177
|
+
return callback(t);
|
|
178
|
+
},
|
|
172
179
|
// ─── Test helper ─────────────────────────────────────────
|
|
173
180
|
// Seed a document at a Firestore-like path
|
|
174
181
|
seed(path, data) {
|
|
@@ -116,6 +116,8 @@ async function runVerification(code, name, userId, options = {}) {
|
|
|
116
116
|
addStage(STAGE_GCS_RULES, 'passed', 'GCS rules (no select-all) satisfied');
|
|
117
117
|
|
|
118
118
|
// Stage 3: Dry run with mock BQ and short timeout
|
|
119
|
+
// In test env, use in-process run (no WASM) so integration tests don't require quickjs-emscripten
|
|
120
|
+
const isTestEnv = process.env.NODE_ENV === 'test';
|
|
119
121
|
const sandboxExecutionConfig = {
|
|
120
122
|
...config.execution,
|
|
121
123
|
timeoutMs: SANDBOX_TIMEOUT_MS,
|
|
@@ -124,8 +126,8 @@ async function runVerification(code, name, userId, options = {}) {
|
|
|
124
126
|
memoryLimitBytes: config.execution?.memoryLimitBytes ?? 64 * 1024 * 1024,
|
|
125
127
|
maxStackSizeBytes: config.execution?.maxStackSizeBytes ?? 327680,
|
|
126
128
|
runtime: config.execution?.runtime ?? 'default',
|
|
127
|
-
sandbox:
|
|
128
|
-
useQuickJS: config.execution?.useQuickJS !== false
|
|
129
|
+
sandbox: !isTestEnv,
|
|
130
|
+
useQuickJS: isTestEnv ? false : (config.execution?.useQuickJS !== false)
|
|
129
131
|
};
|
|
130
132
|
|
|
131
133
|
const mockBq = new MockBQAdapter(options.fixtureData || {}, config);
|
|
@@ -154,6 +156,15 @@ async function runVerification(code, name, userId, options = {}) {
|
|
|
154
156
|
usageCollector: null
|
|
155
157
|
});
|
|
156
158
|
|
|
159
|
+
// In test, dynamic recipe only has processSource; provide a callable process so in-process run works without WASM
|
|
160
|
+
if (isTestEnv && entry.recipe.processSource && entry.recipe.process === null) {
|
|
161
|
+
const processSource = entry.recipe.processSource;
|
|
162
|
+
entry.recipe.process = function (context) {
|
|
163
|
+
const fn = new Function('ctx', `return (${processSource})(ctx);`);
|
|
164
|
+
return Promise.resolve(fn(context));
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
157
168
|
try {
|
|
158
169
|
const result = await runner.run(entry.recipe, ctx);
|
|
159
170
|
if (result && result.status === 'completed') {
|