"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const assert = require("assert");
const sinon = require("sinon");
const imageVerification_1 = require("./imageVerification");
class MockImage {
    onload = null;
    onerror = null;
    width = 800;
    height = 600;
    _src = '';
    get src() {
        return this._src;
    }
    set src(value) {
        this._src = value;
        // Simulate image loading
        Promise.resolve().then(() => this.onload?.());
    }
}
class MockFileReader {
    onload = null;
    onerror = null;
    result = null;
    readAsDataURL(file) {
        setTimeout(() => {
            this.result = 'data:image/png;base64,mock-data';
            this.onload?.({ target: { result: this.result } });
        }, 0);
    }
}
describe('imageVerification', () => {
    let imageStub;
    let urlStub;
    let fileReaderStub;
    beforeEach(() => {
        imageStub = sinon.stub(global, 'Image').callsFake(() => new MockImage());
        urlStub = sinon.stub(global, 'URL').value({
            createObjectURL: sinon.stub().returns('blob:mock-url'),
            revokeObjectURL: sinon.stub(),
        });
        fileReaderStub = sinon.stub(global, 'FileReader').callsFake(() => new MockFileReader());
    });
    afterEach(() => {
        sinon.restore();
    });
    describe('constants', () => {
        it('has correct MAX_IMAGE_CONTEXT value', () => {
            assert.equal(imageVerification_1.MAX_IMAGE_CONTEXT, 20);
        });
        it('has correct default options', () => {
            assert.equal(imageVerification_1.DEFAULT_IMAGE_VERIFICATION_OPTIONS.maxSizeBytes, 3.75 * 1024 * 1024);
            assert.equal(imageVerification_1.DEFAULT_IMAGE_VERIFICATION_OPTIONS.maxDimension, 8000);
            assert.deepEqual(imageVerification_1.DEFAULT_IMAGE_VERIFICATION_OPTIONS.supportedExtensions, [
                'jpeg',
                'jpg',
                'png',
                'gif',
                'webp',
            ]);
        });
    });
    describe('isSupportedImageExtension', () => {
        it('returns true for supported extensions', () => {
            assert.equal((0, imageVerification_1.isSupportedImageExtension)('jpg'), true);
            assert.equal((0, imageVerification_1.isSupportedImageExtension)('jpeg'), true);
            assert.equal((0, imageVerification_1.isSupportedImageExtension)('png'), true);
            assert.equal((0, imageVerification_1.isSupportedImageExtension)('gif'), true);
            assert.equal((0, imageVerification_1.isSupportedImageExtension)('webp'), true);
        });
        it('returns true for supported extensions with dots', () => {
            assert.equal((0, imageVerification_1.isSupportedImageExtension)('.jpg'), true);
            assert.equal((0, imageVerification_1.isSupportedImageExtension)('.png'), true);
        });
        it('returns true for uppercase extensions', () => {
            assert.equal((0, imageVerification_1.isSupportedImageExtension)('JPG'), true);
            assert.equal((0, imageVerification_1.isSupportedImageExtension)('PNG'), true);
        });
        it('returns false for unsupported extensions', () => {
            assert.equal((0, imageVerification_1.isSupportedImageExtension)('txt'), false);
            assert.equal((0, imageVerification_1.isSupportedImageExtension)('pdf'), false);
            assert.equal((0, imageVerification_1.isSupportedImageExtension)('doc'), false);
        });
    });
    describe('isFileSizeValid', () => {
        it('returns true for valid file sizes', () => {
            assert.equal((0, imageVerification_1.isFileSizeValid)(1024), true); // 1KB
            assert.equal((0, imageVerification_1.isFileSizeValid)(1024 * 1024), true); // 1MB
        });
        it('returns false for oversized files', () => {
            const maxSize = imageVerification_1.DEFAULT_IMAGE_VERIFICATION_OPTIONS.maxSizeBytes;
            assert.equal((0, imageVerification_1.isFileSizeValid)(maxSize + 1), false);
        });
        it('accepts custom max size', () => {
            assert.equal((0, imageVerification_1.isFileSizeValid)(2048, 1024), false);
            assert.equal((0, imageVerification_1.isFileSizeValid)(512, 1024), true);
        });
    });
    describe('areImageDimensionsValid', () => {
        it('returns true for valid dimensions', () => {
            assert.equal((0, imageVerification_1.areImageDimensionsValid)(800, 600), true);
            assert.equal((0, imageVerification_1.areImageDimensionsValid)(1920, 1080), true);
        });
        it('returns false for oversized dimensions', () => {
            const maxDim = imageVerification_1.DEFAULT_IMAGE_VERIFICATION_OPTIONS.maxDimension;
            assert.equal((0, imageVerification_1.areImageDimensionsValid)(maxDim + 1, 600), false);
            assert.equal((0, imageVerification_1.areImageDimensionsValid)(800, maxDim + 1), false);
        });
        it('accepts custom max dimension', () => {
            assert.equal((0, imageVerification_1.areImageDimensionsValid)(1200, 800, 1000), false);
            assert.equal((0, imageVerification_1.areImageDimensionsValid)(800, 600, 1000), true);
        });
    });
    describe('verifyClientImage', () => {
        let mockFile;
        beforeEach(() => {
            mockFile = {
                name: 'test.jpg',
                size: 1024 * 1024, // 1MB
                type: 'image/jpeg',
            };
        });
        it('validates a correct image file', async () => {
            const result = await (0, imageVerification_1.verifyClientImage)(mockFile, 'test.jpg');
            assert.equal(result.isValid, true);
            assert.equal(result.errors.length, 0);
        });
        it('rejects unsupported file extension', async () => {
            const result = await (0, imageVerification_1.verifyClientImage)(mockFile, 'test.txt');
            assert.equal(result.isValid, false);
            assert.equal(result.errors.length, 1);
            assert.ok(result.errors[0].includes('File must be an image'));
        });
        it('rejects oversized files', async () => {
            const largeFile = {
                ...mockFile,
                size: imageVerification_1.DEFAULT_IMAGE_VERIFICATION_OPTIONS.maxSizeBytes + 1,
            };
            const result = await (0, imageVerification_1.verifyClientImage)(largeFile, 'large.jpg');
            assert.equal(result.isValid, false);
            assert.equal(result.errors.length, 1);
            assert.ok(result.errors[0].includes('must be no more than'));
        });
        it('rejects images with oversized dimensions', async () => {
            // Stub Image to return oversized dimensions
            imageStub.callsFake(() => ({
                onload: null,
                onerror: null,
                width: imageVerification_1.DEFAULT_IMAGE_VERIFICATION_OPTIONS.maxDimension + 1,
                height: 600,
                _src: '',
                get src() {
                    return this._src;
                },
                set src(value) {
                    this._src = value;
                    Promise.resolve().then(() => this.onload?.());
                },
            }));
            const result = await (0, imageVerification_1.verifyClientImage)(mockFile, 'oversized.jpg');
            assert.equal(result.isValid, false);
            assert.equal(result.errors.length, 1);
            assert.ok(result.errors[0].includes('must be no more than'));
        });
        it('handles image loading errors', async () => {
            // Stub Image to fail loading
            imageStub.callsFake(() => ({
                onload: null,
                onerror: null,
                width: 0,
                height: 0,
                _src: '',
                get src() {
                    return this._src;
                },
                set src(value) {
                    this._src = value;
                    Promise.resolve().then(() => this.onerror?.());
                },
            }));
            // Stub FileReader to also fail
            fileReaderStub.callsFake(() => ({
                onload: null,
                onerror: null,
                result: null,
                readAsDataURL() {
                    setTimeout(() => this.onerror?.(), 0);
                },
            }));
            const result = await (0, imageVerification_1.verifyClientImage)(mockFile, 'failing.jpg');
            assert.equal(result.isValid, false);
            assert.equal(result.errors.length, 1);
            assert.ok(result.errors[0].includes('Unable to read image dimensions'));
        });
    });
    describe('verifyClientImages', () => {
        let mockFileList;
        beforeEach(() => {
            const validFile = {
                name: 'valid.jpg',
                size: 1024 * 1024,
                type: 'image/jpeg',
            };
            const invalidFile = {
                name: 'invalid.txt',
                size: 1024,
                type: 'text/plain',
            };
            mockFileList = {
                length: 2,
                0: validFile,
                1: invalidFile,
                item: (index) => (index === 0 ? validFile : invalidFile),
            };
        });
        it('separates valid and invalid files', async () => {
            const result = await (0, imageVerification_1.verifyClientImages)(mockFileList);
            assert.equal(result.validFiles.length, 1);
            assert.equal(result.errors.length, 1);
            assert.equal(result.validFiles[0].name, 'valid.jpg');
            assert.ok(result.errors[0].includes('invalid.txt'));
        });
        it('handles empty file list', async () => {
            const emptyFileList = {
                length: 0,
                item: () => null,
            };
            const result = await (0, imageVerification_1.verifyClientImages)(emptyFileList);
            assert.equal(result.validFiles.length, 0);
            assert.equal(result.errors.length, 0);
        });
        it('handles files without names', async () => {
            const fileWithoutName = {
                name: '',
                size: 1024,
                type: 'image/jpeg',
            };
            const fileListWithUnnamed = {
                length: 1,
                0: fileWithoutName,
                item: () => fileWithoutName,
            };
            const result = await (0, imageVerification_1.verifyClientImages)(fileListWithUnnamed);
            // File without extension should be rejected
            assert.equal(result.validFiles.length, 0);
            assert.equal(result.errors.length, 1);
            assert.ok(result.errors[0].includes('Unknown file'));
        });
    });
});
//# sourceMappingURL=imageVerification.test.js.map