Files
bface/test/env.test.js
Amer Agovic 859db6ccb2 Release 1.0.8 with platform, security, and UI hardening.
Adds API filter registry, style theme registry, SW bitmask cache clear, KV namespacing, session expiry checks, accessibility improvements, and expanded test coverage.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-10 21:08:21 -05:00

212 lines
7.0 KiB
JavaScript

/**
* Tests for platform/env.js
* Uses Node.js built-in test runner (node --test)
*/
import { test, describe, beforeEach } from 'node:test';
import assert from 'node:assert';
import {
initEnv,
getConfig,
getConfigSync,
setConfig,
getConfigDict,
isDevelopment,
isProduction,
isServiceWorkerEnabledSync,
resolveServiceWorkerEnabled,
CONFIG_KEYS
} from '../src/platform/env.js';
import { getProvider } from '../src/platform/storage.js';
describe('env.js', () => {
beforeEach(() => {
// Reset config before each test
initEnv({});
});
describe('initEnv', () => {
test('should initialize config with provided values', () => {
const appConfig = {
name: 'TestApp',
displayName: 'Test Application',
brandLogo: '/logo.png',
ui_shell: 'DashboardShell',
storage: { backend: 'indexedDB' },
api: { baseURL: '/api/v1' },
modules: ['core', 'dummy']
};
initEnv(appConfig);
const config = getConfigDict();
assert.strictEqual(config.APP_NAME, 'TestApp');
assert.strictEqual(config.APP_DISPLAY_NAME, 'Test Application');
assert.strictEqual(config.BRAND_LOGO, '/logo.png');
assert.strictEqual(config.UI_SHELL, 'DashboardShell');
assert.strictEqual(config.STORAGE_BACKEND, 'indexedDB');
assert.strictEqual(config.API_BASE_URL, '/api/v1');
assert.deepStrictEqual(config.MODULES, ['core', 'dummy']);
});
test('should use defaults when values are missing', () => {
const appConfig = {
name: 'TestApp'
};
initEnv(appConfig);
const config = getConfigDict();
assert.strictEqual(config.APP_NAME, 'TestApp');
assert.strictEqual(config.APP_DISPLAY_NAME, 'TestApp'); // Falls back to name
assert.strictEqual(config.BRAND_LOGO, '/favicon.svg'); // Default
assert.strictEqual(config.UI_SHELL, 'EmptyShell'); // Default
assert.strictEqual(config.STORAGE_BACKEND, 'localStorage'); // Default
assert.strictEqual(config.API_BASE_URL, '/api'); // Default
assert.deepStrictEqual(config.MODULES, []); // Default
});
});
describe('getConfig', () => {
beforeEach(() => {
initEnv({
name: 'TestApp',
displayName: 'Test Display Name'
});
});
test('should return config value from dictionary', async () => {
const value = await getConfig(CONFIG_KEYS.APP_NAME);
assert.strictEqual(value, 'TestApp');
});
test('should return altValue when key not found', async () => {
// Note: getConfig checks import.meta.env which may not be available in Node
// This test verifies the fallback behavior
const value = await getConfig('NON_EXISTENT_KEY', 'default');
assert.strictEqual(value, 'default');
});
test('should return null when key not found and no altValue', async () => {
// Note: getConfig checks import.meta.env which may not be available in Node
// This test verifies the fallback behavior
const value = await getConfig('NON_EXISTENT_KEY');
// May return null or undefined depending on import.meta.env availability
assert.ok(value === null || value === undefined);
});
test('locked keys ignore persisted storage overrides', async () => {
initEnv({
name: 'TestApp',
api: { base_url: '/api/profile' },
modules: ['rt', 'game']
});
const configStorage = getProvider('kv', 'config');
await configStorage.set(CONFIG_KEYS.API_BASE_URL, '/api/stale');
await configStorage.set(CONFIG_KEYS.MODULES, ['stale']);
assert.strictEqual(await getConfig(CONFIG_KEYS.API_BASE_URL), '/api/profile');
assert.deepStrictEqual(await getConfig(CONFIG_KEYS.MODULES), ['rt', 'game']);
});
});
describe('getConfigSync', () => {
test('should return in-memory config without storage reads', () => {
initEnv({
name: 'SyncApp',
api: { base_url: '/api/sync' }
});
assert.strictEqual(getConfigSync(CONFIG_KEYS.APP_NAME), 'SyncApp');
assert.strictEqual(getConfigSync(CONFIG_KEYS.API_BASE_URL), '/api/sync');
assert.strictEqual(getConfigSync('MISSING', 'fallback'), 'fallback');
});
});
describe('setConfig', () => {
beforeEach(() => {
initEnv({
name: 'TestApp'
});
});
test('should update existing config key in dictionary', async () => {
await setConfig(CONFIG_KEYS.APP_NAME, 'UpdatedApp');
const value = await getConfig(CONFIG_KEYS.APP_NAME);
assert.strictEqual(value, 'UpdatedApp');
});
test('should handle new keys (may attempt storage)', async () => {
// Since it's a new key, it should attempt to store in storage
// We just verify it doesn't throw
await assert.doesNotReject(async () => {
await setConfig('custom.key', 'customValue');
});
});
});
describe('getConfigDict', () => {
test('should return a copy of config dictionary', () => {
initEnv({
name: 'TestApp',
displayName: 'Test Display'
});
const config1 = getConfigDict();
const config2 = getConfigDict();
// Should be equal but not the same object (copy)
assert.deepStrictEqual(config1, config2);
assert.notStrictEqual(config1, config2);
});
test('should return config with defaults when initialized with empty object', () => {
initEnv({});
const config = getConfigDict();
// initEnv sets defaults even with empty object
assert.ok('APP_NAME' in config);
assert.ok('BRAND_LOGO' in config);
assert.strictEqual(config.BRAND_LOGO, '/favicon.svg');
});
});
describe('CONFIG_KEYS', () => {
test('should export all expected config keys', () => {
assert.ok('APP_NAME' in CONFIG_KEYS);
assert.ok('APP_DISPLAY_NAME' in CONFIG_KEYS);
assert.ok('BRAND_LOGO' in CONFIG_KEYS);
assert.ok('UI_SHELL' in CONFIG_KEYS);
assert.ok('STORAGE_BACKEND' in CONFIG_KEYS);
assert.ok('API_BASE_URL' in CONFIG_KEYS);
assert.ok('MODULES' in CONFIG_KEYS);
assert.ok('SERVICE_WORKER_ENABLED' in CONFIG_KEYS);
});
});
describe('service worker profile flag', () => {
test('resolveServiceWorkerEnabled defaults to true', () => {
assert.strictEqual(resolveServiceWorkerEnabled({}), true);
});
test('resolveServiceWorkerEnabled reads service_worker.enabled', () => {
assert.strictEqual(resolveServiceWorkerEnabled({ service_worker: { enabled: false } }), false);
assert.strictEqual(resolveServiceWorkerEnabled({ pwa: { service_worker: { enabled: false } } }), false);
});
test('initEnv seeds SERVICE_WORKER_ENABLED into config', () => {
initEnv({ service_worker: { enabled: false } });
assert.strictEqual(isServiceWorkerEnabledSync(), false);
assert.strictEqual(getConfigDict()[CONFIG_KEYS.SERVICE_WORKER_ENABLED], false);
});
});
describe('isDevelopment and isProduction', () => {
test('should be functions', () => {
assert.strictEqual(typeof isDevelopment, 'function');
assert.strictEqual(typeof isProduction, 'function');
});
});
});