Files
overleaf-cep/services/web/test/unit/src/Settings/Settings.test.mjs
T
Tim Down c3d962c075 Add the SheerID student verification module (#36704)
GitOrigin-RevId: a3673c09e185c8f857d5da3e706fa9a310fba6d4
2026-09-17 12:07:32 +00:00

221 lines
6.9 KiB
JavaScript

import { afterEach, describe, expect, it } from 'vitest'
import { createRequire } from 'node:module'
const require = createRequire(import.meta.url)
function clearSettingsCache() {
const monorepoPath = require
.resolve('../../../../config/settings.defaults.js')
.replace(/\/services\/web\/config\/settings\.defaults\.js$/, '')
const settingsDeps = Object.keys(require.cache).filter(
x =>
x.includes('/@overleaf/settings') ||
x.includes('/@overleaf-settings-virtual') ||
x.includes(`${monorepoPath}/libraries/settings`) ||
x.includes('/libraries/settings/') ||
x.includes(`${monorepoPath}/services/web/config`)
)
settingsDeps.forEach(dep => delete require.cache[dep])
}
/**
* @param {any} value
* @returns {string} A string representation of the structure of the value
*/
function serializeTypes(value) {
if (typeof value === 'object') {
const keys = Object.keys(value).sort()
const types = keys.reduce((acc, key) => {
acc[key] = serializeTypes(value[key])
return acc
}, {})
return JSON.stringify(types)
}
if (Array.isArray(value)) {
return JSON.stringify(value.map(serializeTypes))
}
return typeof value
}
/**
* @param {any[]} objects
* @returns {boolean} Whether all objects have the same structure
*/
function haveSameStructure(objects) {
if (!objects.length) return true
const referenceStructure = serializeTypes(objects[0])
return objects.every(obj => serializeTypes(obj) === referenceStructure)
}
describe('settings.defaults', function () {
it('additional text extensions can be added via config', function () {
clearSettingsCache()
process.env.ADDITIONAL_TEXT_EXTENSIONS = 'abc, xyz'
const settings = require('@overleaf/settings')
expect(settings.textExtensions).to.include('tex') // from the default list
expect(settings.textExtensions).to.include('abc')
expect(settings.textExtensions).to.include('xyz')
})
it('generates pricings with same structures', function () {
const settingsOverridesSaas = require('../../../../config/settings.overrides.saas.js')
const { localizedPlanPricing } = settingsOverridesSaas
const pricingCurrencies = Object.keys(localizedPlanPricing)
expect(pricingCurrencies.sort()).to.eql([
'AUD',
'BRL',
'CAD',
'CHF',
'CLP',
'COP',
'DKK',
'EUR',
'GBP',
'INR',
'MXN',
'NOK',
'NZD',
'PEN',
'SEK',
'SGD',
'USD',
])
const pricings = pricingCurrencies.map(
currency => localizedPlanPricing[currency]
)
expect(haveSameStructure(pricings)).to.be.true
})
})
describe('settings.overrides.saas', function () {
const originalEnv = {
SHEERID_ENABLED: process.env.SHEERID_ENABLED,
SHEERID_MOCK: process.env.SHEERID_MOCK,
SHEERID_CLIENT_ID: process.env.SHEERID_CLIENT_ID,
SHEERID_CLIENT_SECRET: process.env.SHEERID_CLIENT_SECRET,
SHEERID_PROGRAM_ID: process.env.SHEERID_PROGRAM_ID,
SHEERID_API_BASE_URL: process.env.SHEERID_API_BASE_URL,
SHEERID_ENABLED_COUNTRIES: process.env.SHEERID_ENABLED_COUNTRIES,
SHEERID_FALLBACK_COUNTRY: process.env.SHEERID_FALLBACK_COUNTRY,
NODE_ENV: process.env.NODE_ENV,
}
function setCredentials() {
process.env.SHEERID_CLIENT_ID = 'client-id'
process.env.SHEERID_CLIENT_SECRET = 'client-secret'
process.env.SHEERID_PROGRAM_ID = 'program-id'
}
afterEach(function () {
for (const [key, value] of Object.entries(originalEnv)) {
if (value === undefined) {
delete process.env[key]
} else {
process.env[key] = value
}
}
clearSettingsCache()
})
it('sets the verification page CSP frame-src from the configured SheerID host', function () {
process.env.SHEERID_API_BASE_URL = 'https://sandbox.sheerid.com'
clearSettingsCache()
const settings = require('../../../../config/settings.overrides.saas.js')
expect(
settings.csp.viewDirectives[
'modules/student-verification/app/views/student-verification'
]
).to.deep.equal(["frame-src 'self' https://sandbox.sheerid.com"])
})
it('upper-cases the SheerID country settings', function () {
process.env.SHEERID_ENABLED_COUNTRIES = 'gb, us ,De'
process.env.SHEERID_FALLBACK_COUNTRY = 'gb'
clearSettingsCache()
const settings = require('../../../../config/settings.overrides.saas.js')
expect(settings.sheerId.enabledCountries).to.deep.equal(['GB', 'US', 'DE'])
expect(settings.sheerId.fallbackCountry).to.equal('GB')
})
it('refuses to boot with SHEERID_ENABLED and the default mock client in production', function () {
process.env.SHEERID_ENABLED = 'true'
delete process.env.SHEERID_MOCK // defaults to mock: true
process.env.NODE_ENV = 'production'
clearSettingsCache()
expect(() =>
require('../../../../config/settings.overrides.saas.js')
).to.throw(/SHEERID_ENABLED/)
})
it('boots with SHEERID_ENABLED, SHEERID_MOCK=false and credentials in production', function () {
process.env.SHEERID_ENABLED = 'true'
process.env.SHEERID_MOCK = 'false'
process.env.NODE_ENV = 'production'
setCredentials()
clearSettingsCache()
expect(() =>
require('../../../../config/settings.overrides.saas.js')
).not.to.throw()
})
it('refuses to boot with the real client and no credentials in production', function () {
process.env.SHEERID_ENABLED = 'true'
process.env.SHEERID_MOCK = 'false'
process.env.NODE_ENV = 'production'
delete process.env.SHEERID_CLIENT_ID
delete process.env.SHEERID_CLIENT_SECRET
delete process.env.SHEERID_PROGRAM_ID
clearSettingsCache()
expect(() =>
require('../../../../config/settings.overrides.saas.js')
).to.throw(/SHEERID_CLIENT_ID, SHEERID_CLIENT_SECRET, SHEERID_PROGRAM_ID/)
})
it('names only the credentials that are missing', function () {
process.env.SHEERID_ENABLED = 'true'
process.env.SHEERID_MOCK = 'false'
process.env.NODE_ENV = 'production'
setCredentials()
delete process.env.SHEERID_PROGRAM_ID
clearSettingsCache()
expect(() =>
require('../../../../config/settings.overrides.saas.js')
).to.throw(/requires SHEERID_PROGRAM_ID/)
})
it('boots with the real client and no credentials outside production', function () {
process.env.SHEERID_ENABLED = 'true'
process.env.SHEERID_MOCK = 'false'
process.env.NODE_ENV = 'test'
delete process.env.SHEERID_CLIENT_ID
delete process.env.SHEERID_CLIENT_SECRET
delete process.env.SHEERID_PROGRAM_ID
clearSettingsCache()
expect(() =>
require('../../../../config/settings.overrides.saas.js')
).not.to.throw()
})
it('boots with SHEERID_ENABLED and the default mock client outside production', function () {
process.env.SHEERID_ENABLED = 'true'
delete process.env.SHEERID_MOCK
process.env.NODE_ENV = 'test'
clearSettingsCache()
expect(() =>
require('../../../../config/settings.overrides.saas.js')
).not.to.throw()
})
})