From 7a3b71503f4f6944849b29b5e7b812633d6da3ca Mon Sep 17 00:00:00 2001 From: Andrew Rumble Date: Mon, 20 Oct 2025 10:55:35 +0100 Subject: [PATCH] Allow sandboxed-module for model mockery GitOrigin-RevId: 79dfe75088b760968fdc1b6e5dce4278f44a0dae --- .../src/helpers/indirectlyImportModels.js | 19 ++++++++++++ services/web/test/unit/vitest_bootstrap.mjs | 29 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 services/web/test/unit/src/helpers/indirectlyImportModels.js diff --git a/services/web/test/unit/src/helpers/indirectlyImportModels.js b/services/web/test/unit/src/helpers/indirectlyImportModels.js new file mode 100644 index 0000000000..cfa4706b49 --- /dev/null +++ b/services/web/test/unit/src/helpers/indirectlyImportModels.js @@ -0,0 +1,19 @@ +// When importing models in vitest unit tests we need to import them from a CJS file +// instead of directly from the test file so that we can mock the model when it is imported via CJS +// and make sure that is in the require cache for other imports. +// +// TODO: This helper can be removed when all models are converted to ESM and vitest can handle them correctly. + +/** + * + * @param {string[]} models + */ +module.exports = function (models) { + return models.reduce((exports, model) => { + const module = require(`./models/${model}`) + return { + ...exports, + ...module, + } + }, {}) +} diff --git a/services/web/test/unit/vitest_bootstrap.mjs b/services/web/test/unit/vitest_bootstrap.mjs index e00720c5d6..50ff559bc9 100644 --- a/services/web/test/unit/vitest_bootstrap.mjs +++ b/services/web/test/unit/vitest_bootstrap.mjs @@ -4,6 +4,35 @@ import sinon from 'sinon' import logger from '@overleaf/logger' import sinonChai from 'sinon-chai' import chaiAsPromised from 'chai-as-promised' +import SandboxedModule from 'sandboxed-module' +import { createRequire } from 'module' + +const require = createRequire(import.meta.url) + +SandboxedModule.configure({ + ignoreMissing: true, + requires: { + // This is already imported the same way in the mocha bootstrap + // eslint-disable-next-line import/no-extraneous-dependencies + sshpk: require('sshpk'), + }, + globals: { + AbortController, + AbortSignal, + Buffer, + Promise, + console, + process, + URL, + TextEncoder, + TextDecoder, + }, + sourceTransformers: { + removeNodePrefix: function (source) { + return source.replace(/require\(['"]node:/g, "require('") + }, + }, +}) /* * Chai configuration