import InputMask from "inputmask";
import { MaskedInputService } from "./masked-input.service";
describe('MaskedInputService', () => {
    const service = new MaskedInputService();
    describe('buildPlaceholderFromMaskConfig()', () => {
        let maskedPlaceholder;
        describe('when the mask options includes a prefix', () => {
            const placeholder = 'placeholder';
            const mask = '';
            const options = {
                prefix: '$',
            };
            beforeEach(() => {
                maskedPlaceholder = service.buildPlaceholderFromMaskConfig(placeholder, mask, options);
            });
            it('should prepend it to the masked placeholder', () => {
                expect(maskedPlaceholder).toEqual(`${options.prefix}${placeholder}`);
            });
        });
        describe('when the mask options does not include a prefix', () => {
            const placeholder = 'placeholder';
            const mask = '';
            const options = {};
            beforeEach(() => {
                maskedPlaceholder = service.buildPlaceholderFromMaskConfig(placeholder, mask, options);
            });
            it('should not affect the masked placeholder', () => {
                expect(maskedPlaceholder).toEqual(placeholder);
            });
        });
        describe('when the mask is a datetime alias', () => {
            const placeholder = 'placeholder';
            const mask = 'datetime';
            const options = {
                placeholder: '#',
            };
            beforeEach(() => {
                maskedPlaceholder = service.buildPlaceholderFromMaskConfig(placeholder, mask, options);
            });
            it('should use the datetime placeholder override', () => {
                expect(maskedPlaceholder).toEqual('##/##/####');
            });
        });
        describe('when a mask and placeholder character are provided', () => {
            const placeholder = 'placeholder';
            const mask = '9a*-A[]';
            const options = {
                placeholder: '#',
            };
            beforeEach(() => {
                maskedPlaceholder = service.buildPlaceholderFromMaskConfig(placeholder, mask, options);
            });
            it('should replace valid mask characters with the placeholder', () => {
                expect(maskedPlaceholder).toEqual('###-A[]');
            });
        });
        describe('when a mask or placeholder character are not provided', () => {
            const placeholder = 'placeholder';
            const mask = '';
            const options = {};
            beforeEach(() => {
                maskedPlaceholder = service.buildPlaceholderFromMaskConfig(placeholder, mask, options);
            });
            it('should return the original placeholder', () => {
                expect(maskedPlaceholder).toEqual(placeholder);
            });
        });
        describe('when the mask, options, and placeholder are not provided', () => {
            const placeholder = '';
            const mask = '';
            const options = undefined;
            beforeEach(() => {
                maskedPlaceholder = service.buildPlaceholderFromMaskConfig(placeholder, mask, options);
            });
            it('should return an empty string', () => {
                expect(maskedPlaceholder).toEqual('');
            });
        });
    });
    describe('applyMaskToElement()', () => {
        let element;
        let maskInstance;
        beforeEach(() => {
            element = document.createElement('input');
            maskInstance = new InputMask('datetime');
        });
        describe('when the element and mask instance exist', () => {
            beforeEach(() => {
                service.applyMaskToElement(element, maskInstance);
            });
            it('should apply the mask to the element', () => {
                expect(element.inputmask).toBeDefined();
            });
        });
        describe('when the element is not defined', () => {
            let spy;
            beforeEach(() => {
                spy = jest.spyOn(maskInstance, 'mask');
                service.applyMaskToElement(undefined, maskInstance);
            });
            it('should not attempt to apply a mask to the element', () => {
                expect(spy).not.toHaveBeenCalled();
            });
        });
        describe('when the mask instance does not exist', () => {
            beforeEach(() => {
                service.applyMaskToElement(element, undefined);
            });
            it('should not apply a mask to the element', () => {
                expect(element.inputmask).not.toBeDefined();
            });
        });
    });
    describe('removeMaskFromElement()', () => {
        let element;
        let maskInstance;
        beforeEach(() => {
            element = document.createElement('input');
            maskInstance = new InputMask('datetime');
        });
        describe('when the element and mask instance exist', () => {
            beforeEach(() => {
                service.applyMaskToElement(element, maskInstance);
            });
            it('should remove the mask from the element', () => {
                expect(element.inputmask).toBeDefined();
                service.removeMaskFromElement(element);
                expect(element.inputmask).toBeUndefined();
            });
            it('should remove inline styles', () => {
                element.setAttribute('style', 'text-align: right');
                service.removeMaskFromElement(element);
                expect(element.getAttribute('style')).toBeNull();
            });
        });
        describe('when the element is not defined', () => {
            it('should not attempt to remove the mask', () => {
                expect(() => service.removeMaskFromElement(undefined)).not.toThrow();
                expect(element.inputmask).toBeUndefined();
            });
        });
    });
    describe('create mask instances', () => {
        const mask = '99';
        const maskConfig = {
            prefix: '$',
            placeholder: '%',
        };
        // These tests are to satisfy coverage. The InputMask instances don't seem
        // to load correctly in Jest.
        it('createDefaultMaskInstance() should return a mask instance', () => {
            const maskInstance = service.createDefaultMaskInstance();
            expect(maskInstance).toBeDefined();
        });
        it('createPasswordMaskInstance() should return a mask instance', () => {
            const maskInstance = service.createPasswordMaskInstance(mask, maskConfig);
            expect(maskInstance).toBeDefined();
        });
        it('createTextMaskInstance() should return a mask instance', () => {
            const maskInstance = service.createTextMaskInstance(mask, maskConfig);
            expect(maskInstance).toBeDefined();
        });
    });
    describe('isElementMaskSame()', () => {
        let element;
        let maskInstance;
        describe('when element is not defined', () => {
            it('should be false', () => {
                expect(service.isElementMaskSame(element, 'koala')).toBe(false);
            });
        });
        describe('when element does not have inputmask applied', () => {
            beforeEach(() => {
                element = document.createElement('input');
            });
            it('should be false', () => {
                expect(service.isElementMaskSame(element, 'koala')).toBe(false);
            });
        });
        describe('when element has inputmask applied', () => {
            beforeEach(() => {
                element = document.createElement('input');
                maskInstance = new InputMask('datetime');
                service.applyMaskToElement(element, maskInstance);
            });
            it.each([
                ['empty string', ''],
                ['null', null],
                ['undefined', undefined],
            ])('should be false when alias is invalid: %s', (_description, invalidAlias) => {
                expect(service.isElementMaskSame(element, invalidAlias)).toBe(false);
            });
            it('should be false when alias does not match', () => {
                expect(service.isElementMaskSame(element, 'koala')).toBe(false);
            });
            it('should be true when alias does match', () => {
                expect(service.isElementMaskSame(element, 'datetime')).toBe(true);
            });
        });
    });
});
