import { describe, expect, it } from 'vitest';
import { validateAndNormalizeSubmission } from '../../forms/validation.js';
function field(overrides) {
    return {
        id: 'f',
        label: 'Label',
        key: 'key',
        type: 'text',
        required: false,
        sortOrder: 0,
        ...overrides,
    };
}
describe('validateAndNormalizeSubmission', () => {
    it('accepts a valid payload and coerces types', () => {
        const result = validateAndNormalizeSubmission([
            field({ key: 'name', type: 'text' }),
            field({ key: 'age', type: 'number' }),
            field({ key: 'subscribe', type: 'checkbox' }),
            field({
                key: 'topics',
                type: 'multiselect',
                options: [
                    { label: 'A', value: 'a' },
                    { label: 'B', value: 'b' },
                ],
            }),
        ], { name: 'Ada', age: '42', subscribe: 'on', topics: ['a', 'b'] });
        expect(result.ok).toBe(true);
        expect(result.normalized.age).toBe(42);
        expect(result.normalized.subscribe).toBe(true);
        expect(result.normalized.topics).toEqual(['a', 'b']);
        expect(result.data.name).toBe('Ada');
    });
    it('flags required fields that are missing or blank', () => {
        const result = validateAndNormalizeSubmission([field({ key: 'name', required: true }), field({ key: 'note', required: false })], { name: '   ' });
        expect(result.ok).toBe(false);
        expect(result.errors.some((e) => e.key === 'name')).toBe(true);
    });
    it('validates email format for email-typed fields', () => {
        const ok = validateAndNormalizeSubmission([field({ key: 'email', type: 'email' })], {
            email: 'a@b.co',
        });
        expect(ok.ok).toBe(true);
        const bad = validateAndNormalizeSubmission([field({ key: 'email', type: 'email' })], {
            email: 'not-an-email',
        });
        expect(bad.ok).toBe(false);
        expect(bad.errors[0]?.key).toBe('email');
    });
    it('strips HTML from string values to prevent stored XSS', () => {
        const result = validateAndNormalizeSubmission([field({ key: 'msg', type: 'textarea' })], {
            msg: '<script>alert(1)</script>Hello <b>there</b>',
        });
        expect(result.ok).toBe(true);
        const stored = String(result.data.msg);
        expect(stored).not.toContain('<script');
        expect(stored).not.toContain('alert(1)');
        expect(stored).toContain('Hello');
    });
    it('drops keys that are not part of the schema', () => {
        const result = validateAndNormalizeSubmission([field({ key: 'name' })], {
            name: 'Ada',
            injected: 'evil',
        });
        expect(result.data).toHaveProperty('name');
        expect(result.data).not.toHaveProperty('injected');
    });
    it('rejects select values outside the option set', () => {
        const result = validateAndNormalizeSubmission([field({ key: 'plan', type: 'select', options: [{ label: 'Pro', value: 'pro' }] })], { plan: 'enterprise' });
        expect(result.ok).toBe(false);
        expect(result.errors[0]?.key).toBe('plan');
    });
    it('enforces number min/max', () => {
        const result = validateAndNormalizeSubmission([field({ key: 'qty', type: 'number', validationRules: { min: 1, max: 10 } })], { qty: '20' });
        expect(result.ok).toBe(false);
    });
    it('requires consent fields to be accepted', () => {
        const result = validateAndNormalizeSubmission([field({ key: 'terms', type: 'consent', required: true })], { terms: 'false' });
        expect(result.ok).toBe(false);
    });
    it('skips fields hidden by conditional logic (not required, not stored)', () => {
        const fields = [
            field({ key: 'hasCompany', type: 'select', options: [{ label: 'Yes', value: 'yes' }] }),
            field({
                key: 'companyName',
                required: true,
                conditionalLogic: { show: [{ fieldKey: 'hasCompany', operator: 'equals', value: 'yes' }] },
            }),
        ];
        const hidden = validateAndNormalizeSubmission(fields, {
            hasCompany: 'yes' /* companyName not visible */,
        });
        // hasCompany=yes makes companyName visible -> required error
        expect(hidden.ok).toBe(false);
        const notShown = validateAndNormalizeSubmission(fields, { hasCompany: '' });
        expect(notShown.ok).toBe(true);
        expect(notShown.data).not.toHaveProperty('companyName');
    });
    it('requires a file field only when no file is attached', () => {
        const fields = [field({ key: 'resume', type: 'file', required: true })];
        const missing = validateAndNormalizeSubmission(fields, {});
        expect(missing.ok).toBe(false);
        const present = validateAndNormalizeSubmission(fields, {}, { fileKeys: new Set(['resume']) });
        expect(present.ok).toBe(true);
    });
});
//# sourceMappingURL=submission-validation.test.js.map