mirror of
https://github.com/The-Low-Code-Foundation/OpenNoodl.git
synced 2026-01-12 07:12:54 +01:00
198 lines
6.8 KiB
TypeScript
198 lines
6.8 KiB
TypeScript
/**
|
|
* Tests for Config Validation
|
|
*/
|
|
|
|
import { describe, it, expect } from '@jest/globals';
|
|
|
|
import { DEFAULT_APP_CONFIG } from './types';
|
|
import { validateConfigKey, validateConfigValue, validateAppConfig } from './validation';
|
|
|
|
describe('validateConfigKey', () => {
|
|
it('should accept valid JavaScript identifiers', () => {
|
|
expect(validateConfigKey('apiKey').valid).toBe(true);
|
|
expect(validateConfigKey('API_KEY').valid).toBe(true);
|
|
expect(validateConfigKey('_privateKey').valid).toBe(true);
|
|
expect(validateConfigKey('$special').valid).toBe(true);
|
|
expect(validateConfigKey('key123').valid).toBe(true);
|
|
});
|
|
|
|
it('should reject empty keys', () => {
|
|
const result = validateConfigKey('');
|
|
expect(result.valid).toBe(false);
|
|
expect(result.errors[0]).toContain('cannot be empty');
|
|
});
|
|
|
|
it('should reject invalid identifiers', () => {
|
|
expect(validateConfigKey('123key').valid).toBe(false);
|
|
expect(validateConfigKey('my-key').valid).toBe(false);
|
|
expect(validateConfigKey('my key').valid).toBe(false);
|
|
expect(validateConfigKey('my.key').valid).toBe(false);
|
|
});
|
|
|
|
it('should reject reserved keys', () => {
|
|
const result = validateConfigKey('appName');
|
|
expect(result.valid).toBe(false);
|
|
expect(result.errors[0]).toContain('reserved');
|
|
});
|
|
});
|
|
|
|
describe('validateConfigValue', () => {
|
|
describe('number type', () => {
|
|
it('should accept valid numbers', () => {
|
|
expect(validateConfigValue(42, 'number').valid).toBe(true);
|
|
expect(validateConfigValue(0, 'number').valid).toBe(true);
|
|
expect(validateConfigValue(-10.5, 'number').valid).toBe(true);
|
|
});
|
|
|
|
it('should reject non-numbers', () => {
|
|
expect(validateConfigValue('42', 'number').valid).toBe(false);
|
|
expect(validateConfigValue(NaN, 'number').valid).toBe(false);
|
|
});
|
|
|
|
it('should enforce min/max validation', () => {
|
|
expect(validateConfigValue(5, 'number', { min: 0, max: 10 }).valid).toBe(true);
|
|
expect(validateConfigValue(-1, 'number', { min: 0 }).valid).toBe(false);
|
|
expect(validateConfigValue(11, 'number', { max: 10 }).valid).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('string type', () => {
|
|
it('should accept valid strings', () => {
|
|
expect(validateConfigValue('hello', 'string').valid).toBe(true);
|
|
expect(validateConfigValue('', 'string').valid).toBe(true);
|
|
});
|
|
|
|
it('should reject non-strings', () => {
|
|
expect(validateConfigValue(42, 'string').valid).toBe(false);
|
|
});
|
|
|
|
it('should enforce pattern validation', () => {
|
|
const result = validateConfigValue('abc', 'string', { pattern: '^[0-9]+$' });
|
|
expect(result.valid).toBe(false);
|
|
|
|
const validResult = validateConfigValue('123', 'string', { pattern: '^[0-9]+$' });
|
|
expect(validResult.valid).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe('boolean type', () => {
|
|
it('should accept booleans', () => {
|
|
expect(validateConfigValue(true, 'boolean').valid).toBe(true);
|
|
expect(validateConfigValue(false, 'boolean').valid).toBe(true);
|
|
});
|
|
|
|
it('should reject non-booleans', () => {
|
|
expect(validateConfigValue('true', 'boolean').valid).toBe(false);
|
|
expect(validateConfigValue(1, 'boolean').valid).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('color type', () => {
|
|
it('should accept valid hex colors', () => {
|
|
expect(validateConfigValue('#ff0000', 'color').valid).toBe(true);
|
|
expect(validateConfigValue('#FF0000', 'color').valid).toBe(true);
|
|
expect(validateConfigValue('#ff0000ff', 'color').valid).toBe(true);
|
|
});
|
|
|
|
it('should reject invalid colors', () => {
|
|
expect(validateConfigValue('red', 'color').valid).toBe(false);
|
|
expect(validateConfigValue('#ff00', 'color').valid).toBe(false);
|
|
expect(validateConfigValue('ff0000', 'color').valid).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('array type', () => {
|
|
it('should accept arrays', () => {
|
|
expect(validateConfigValue([], 'array').valid).toBe(true);
|
|
expect(validateConfigValue([1, 2, 3], 'array').valid).toBe(true);
|
|
});
|
|
|
|
it('should reject non-arrays', () => {
|
|
expect(validateConfigValue('[]', 'array').valid).toBe(false);
|
|
expect(validateConfigValue({}, 'array').valid).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('object type', () => {
|
|
it('should accept objects', () => {
|
|
expect(validateConfigValue({}, 'object').valid).toBe(true);
|
|
expect(validateConfigValue({ key: 'value' }, 'object').valid).toBe(true);
|
|
});
|
|
|
|
it('should reject non-objects', () => {
|
|
expect(validateConfigValue([], 'object').valid).toBe(false);
|
|
expect(validateConfigValue(null, 'object').valid).toBe(false);
|
|
expect(validateConfigValue('{}', 'object').valid).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('required validation', () => {
|
|
it('should require non-empty values', () => {
|
|
expect(validateConfigValue('', 'string', { required: true }).valid).toBe(false);
|
|
expect(validateConfigValue(null, 'string', { required: true }).valid).toBe(false);
|
|
expect(validateConfigValue(undefined, 'string', { required: true }).valid).toBe(false);
|
|
});
|
|
|
|
it('should allow empty values when not required', () => {
|
|
expect(validateConfigValue('', 'string').valid).toBe(true);
|
|
expect(validateConfigValue(null, 'string').valid).toBe(true);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('validateAppConfig', () => {
|
|
it('should accept valid config', () => {
|
|
const config = {
|
|
...DEFAULT_APP_CONFIG,
|
|
identity: {
|
|
appName: 'Test App',
|
|
description: 'Test Description'
|
|
}
|
|
};
|
|
expect(validateAppConfig(config).valid).toBe(true);
|
|
});
|
|
|
|
it('should require app name', () => {
|
|
const config = {
|
|
...DEFAULT_APP_CONFIG,
|
|
identity: {
|
|
appName: '',
|
|
description: ''
|
|
}
|
|
};
|
|
const result = validateAppConfig(config);
|
|
expect(result.valid).toBe(false);
|
|
expect(result.errors[0]).toContain('App name');
|
|
});
|
|
|
|
it('should detect duplicate variable keys', () => {
|
|
const config = {
|
|
...DEFAULT_APP_CONFIG,
|
|
identity: { appName: 'Test', description: '' },
|
|
variables: [
|
|
{ key: 'apiKey', type: 'string' as const, value: 'key1' },
|
|
{ key: 'apiKey', type: 'string' as const, value: 'key2' }
|
|
]
|
|
};
|
|
const result = validateAppConfig(config);
|
|
expect(result.valid).toBe(false);
|
|
expect(result.errors.some((e) => e.includes('Duplicate'))).toBe(true);
|
|
});
|
|
|
|
it('should validate individual variables', () => {
|
|
const config = {
|
|
...DEFAULT_APP_CONFIG,
|
|
identity: { appName: 'Test', description: '' },
|
|
variables: [{ key: 'my-invalid-key', type: 'string' as const, value: 'test' }]
|
|
};
|
|
const result = validateAppConfig(config);
|
|
expect(result.valid).toBe(false);
|
|
});
|
|
|
|
it('should reject non-object configs', () => {
|
|
const result = validateAppConfig(null);
|
|
expect(result.valid).toBe(false);
|
|
expect(result.errors[0]).toContain('must be an object');
|
|
});
|
|
});
|