"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const react_1 = __importDefault(require("react"));
const faker_1 = __importDefault(require("faker"));
const test_utilities_1 = require("../../test-utilities");
const InlineError_1 = require("../InlineError");
const TextField_1 = require("../TextField");
const Stepper_1 = require("./Stepper");
const defaultProps = {
    label: 'Quantity',
};
describe('<Stepper />', () => {
    beforeAll(() => {
        jest.useFakeTimers();
    });
    afterAll(() => {
        jest.clearAllTimers();
    });
    it('renders a number input field with basic props', () => {
        const id = faker_1.default.random.alphaNumeric();
        const name = faker_1.default.random.word();
        const label = faker_1.default.random.word();
        const stepper = test_utilities_1.mountWithContext(<Stepper_1.Stepper {...defaultProps} id={id} name={name} label={label}/>);
        expect(stepper).toContainReactComponent(TextField_1.Field, { id, name, label });
    });
    it('renders an error message when the error prop is provided', () => {
        const error = 'Limit reached';
        const id = faker_1.default.random.alphaNumeric();
        const stepper = test_utilities_1.mountWithContext(<Stepper_1.Stepper {...defaultProps} id={id} error={error}/>);
        expect(stepper).toContainReactComponent(InlineError_1.InlineError, {
            controlID: id,
            children: error,
        });
    });
    it('increases until it reaches the maximum', () => {
        const step = 2;
        const max = 1;
        const stepper = test_utilities_1.mountWithContext(<Stepper_1.Stepper {...defaultProps} step={step} max={max}/>);
        const [, increaseButton] = stepper.findAll('button');
        increaseButton.trigger('onMouseDown', { button: 0 });
        jest.advanceTimersByTime(200);
        stepper.act(() => {
            const event = new MouseEvent('mouseup');
            document.dispatchEvent(event);
        });
        expect(stepper).toContainReactComponent(TextField_1.Field, {
            value: `${max}`,
        });
    });
    it('decreases until it reaches the minimum', () => {
        const step = 2;
        const min = 0;
        const stepper = test_utilities_1.mountWithContext(<Stepper_1.Stepper {...defaultProps} step={step} min={min}/>);
        const [decreaseButton] = stepper.findAll('button');
        decreaseButton.trigger('onMouseDown', { button: 0 });
        jest.advanceTimersByTime(0);
        stepper.act(() => {
            const event = new MouseEvent('mouseup');
            document.dispatchEvent(event);
        });
        expect(stepper).toContainReactComponent(TextField_1.Field, {
            value: `${min}`,
        });
    });
    describe('onChange', () => {
        it('does not call onChange when the value changes but is not committed, but updates the value in the input', () => {
            const onChange = jest.fn();
            const value = faker_1.default.random.number();
            const stepper = test_utilities_1.mountWithContext(<Stepper_1.Stepper {...defaultProps} value={value} onChange={onChange}/>);
            stepper
                .find('input')
                .trigger('oninput', { currentTarget: { value: `${value + 1}` } });
            const input = stepper.find('input');
            expect(onChange).not.toHaveBeenCalled();
            expect(input).toHaveReactProps({ value: `${value + 1}` });
        });
        it('does not call onChange when the value changes and is committed, but matches the current prop value', () => {
            const onChange = jest.fn();
            const value = faker_1.default.random.number();
            const stepper = test_utilities_1.mountWithContext(<Stepper_1.Stepper {...defaultProps} value={value} onChange={onChange}/>);
            stepper
                .find('input')
                .trigger('oninput', { currentTarget: { value: `${value}` } });
            stepper
                .find('input')
                .trigger('onBlur', { currentTarget: { value: `${value}` } });
            expect(onChange).not.toHaveBeenCalled();
        });
        it('calls onChange when the value changes and is committed, and does not match the current prop value', () => {
            const onChange = jest.fn();
            const stepper = test_utilities_1.mountWithContext(<Stepper_1.Stepper {...defaultProps} value={0} onChange={onChange}/>);
            const value = faker_1.default.random.number();
            stepper
                .find('input')
                .trigger('oninput', { currentTarget: { value: `${value}` } });
            stepper
                .find('input')
                .trigger('onBlur', { currentTarget: { value: `${value}` } });
            expect(onChange).toHaveBeenCalledWith(`${value}`);
        });
    });
    describe('max', () => {
        it('does not increase when value is at the maximum', () => {
            const value = 10;
            const stepper = test_utilities_1.mountWithContext(<Stepper_1.Stepper {...defaultProps} value={value} max={10}/>);
            const [, increaseButton] = stepper.findAll('button');
            increaseButton.trigger('onMouseDown', { button: 0 });
            jest.advanceTimersByTime(500);
            stepper.act(() => {
                const event = new MouseEvent('mouseup');
                document.dispatchEvent(event);
            });
            expect(stepper).toContainReactComponent(TextField_1.Field, { value: `${value}` });
        });
        describe('going to default maximum value when input is greater than maximum', () => {
            it('increase button is clicked', () => {
                const value = 200;
                const max = 10;
                const stepper = test_utilities_1.mountWithContext(<Stepper_1.Stepper {...defaultProps} value={value} max={max}/>);
                const [, increaseButton] = stepper.findAll('button');
                increaseButton.trigger('onMouseDown', { button: 0 });
                jest.advanceTimersByTime(200);
                stepper.act(() => {
                    const event = new MouseEvent('mouseup');
                    document.dispatchEvent(event);
                });
                expect(stepper).toContainReactComponent(TextField_1.Field, { value: `${max}` });
            });
            it('decrease button is clicked', () => {
                const value = 200;
                const max = 10;
                const stepper = test_utilities_1.mountWithContext(<Stepper_1.Stepper {...defaultProps} value={value} max={max}/>);
                const [decreaseButton] = stepper.findAll('button');
                decreaseButton.trigger('onMouseDown', { button: 0 });
                jest.advanceTimersByTime(0);
                stepper.act(() => {
                    const event = new MouseEvent('mouseup');
                    document.dispatchEvent(event);
                });
                expect(stepper).toContainReactComponent(TextField_1.Field, { value: `${max}` });
            });
        });
    });
    describe('min', () => {
        it('does not decrease when value is at the minimum', () => {
            const min = 0;
            const stepper = test_utilities_1.mountWithContext(<Stepper_1.Stepper {...defaultProps} min={min}/>);
            const [decreaseButton] = stepper.findAll('button');
            decreaseButton.trigger('onMouseDown', { button: 0 });
            jest.advanceTimersByTime(200);
            stepper.act(() => {
                const event = new MouseEvent('mouseup');
                document.dispatchEvent(event);
            });
            expect(stepper).toContainReactComponent(TextField_1.Field, { value: `${min}` });
        });
        describe('going to default minimum value when input is less than minimum', () => {
            it('increase button is clicked', () => {
                const value = -100;
                const min = 1;
                const stepper = test_utilities_1.mountWithContext(<Stepper_1.Stepper {...defaultProps} value={value} min={min}/>);
                const [, increaseButton] = stepper.findAll('button');
                increaseButton.trigger('onMouseDown', { button: 0 });
                jest.advanceTimersByTime(0);
                stepper.act(() => {
                    const event = new MouseEvent('mouseup');
                    document.dispatchEvent(event);
                });
                expect(stepper).toContainReactComponent(TextField_1.Field, { value: `${min}` });
            });
            it('decrease button is clicked', () => {
                const value = -100;
                const min = 1;
                const stepper = test_utilities_1.mountWithContext(<Stepper_1.Stepper {...defaultProps} value={value} min={min}/>);
                const [decreaseButton] = stepper.findAll('button');
                decreaseButton.trigger('onMouseDown', { button: 0 });
                jest.advanceTimersByTime(0);
                stepper.act(() => {
                    const event = new MouseEvent('mouseup');
                    document.dispatchEvent(event);
                });
                expect(stepper).toContainReactComponent(TextField_1.Field, { value: `${min}` });
            });
        });
    });
    describe('<Button/>', () => {
        it('increases when the increase button is clicked on', () => {
            const stepper = test_utilities_1.mountWithContext(<Stepper_1.Stepper {...defaultProps}/>);
            const [, increaseButton] = stepper.findAll('button');
            increaseButton.trigger('onMouseDown', { button: 0 });
            jest.advanceTimersByTime(0);
            stepper.act(() => {
                const event = new MouseEvent('mouseup');
                document.dispatchEvent(event);
            });
            expect(stepper).toContainReactComponent(TextField_1.Field, { value: `${1}` });
        });
        it('decreases when the decrease button is clicked on', () => {
            const value = 2;
            const stepper = test_utilities_1.mountWithContext(<Stepper_1.Stepper {...defaultProps} value={value}/>);
            const [decreaseButton] = stepper.findAll('button');
            decreaseButton.trigger('onMouseDown', { button: 0 });
            jest.advanceTimersByTime(0);
            stepper.act(() => {
                const event = new MouseEvent('mouseup');
                document.dispatchEvent(event);
            });
            expect(stepper).toContainReactComponent(TextField_1.Field, {
                value: `${value - 1}`,
            });
        });
    });
    describe('value', () => {
        it('decreases from the initial value', () => {
            const value = 1;
            const stepper = test_utilities_1.mountWithContext(<Stepper_1.Stepper {...defaultProps} value={value}/>);
            const [decreaseButton] = stepper.findAll('button');
            decreaseButton.trigger('onMouseDown', { button: 0 });
            jest.advanceTimersByTime(0);
            stepper.act(() => {
                const event = new MouseEvent('mouseup');
                document.dispatchEvent(event);
            });
            expect(stepper).toContainReactComponent(TextField_1.Field, {
                value: `${value - 1}`,
            });
        });
        it('increases from the initial value', () => {
            const value = 1;
            const stepper = test_utilities_1.mountWithContext(<Stepper_1.Stepper {...defaultProps} value={value}/>);
            const [, increaseButton] = stepper.findAll('button');
            increaseButton.trigger('onMouseDown', { button: 0 });
            jest.advanceTimersByTime(0);
            stepper.act(() => {
                const event = new MouseEvent('mouseup');
                document.dispatchEvent(event);
            });
            expect(stepper).toContainReactComponent(TextField_1.Field, {
                value: `${value + 1}`,
            });
        });
    });
    describe('step', () => {
        it('decrease based on the step value', () => {
            const value = 2;
            const step = 2;
            const stepper = test_utilities_1.mountWithContext(<Stepper_1.Stepper {...defaultProps} step={step} value={value}/>);
            const [decreaseButton] = stepper.findAll('button');
            decreaseButton.trigger('onMouseDown', { button: 0 });
            jest.advanceTimersByTime(0);
            stepper.act(() => {
                const event = new MouseEvent('mouseup');
                document.dispatchEvent(event);
            });
            expect(stepper).toContainReactComponent(TextField_1.Field, {
                value: `${value - step}`,
            });
        });
        it('increases based on the step value', () => {
            const step = 2;
            const stepper = test_utilities_1.mountWithContext(<Stepper_1.Stepper {...defaultProps} step={step}/>);
            const [, increaseButton] = stepper.findAll('button');
            increaseButton.trigger('onMouseDown', { button: 0 });
            jest.advanceTimersByTime(0);
            stepper.act(() => {
                const event = new MouseEvent('mouseup');
                document.dispatchEvent(event);
            });
            expect(stepper).toContainReactComponent(TextField_1.Field, { value: `${step}` });
        });
    });
    describe('press and hold', () => {
        it('continues to decrease with long press', () => {
            const value = 5;
            const stepper = test_utilities_1.mountWithContext(<Stepper_1.Stepper {...defaultProps} value={value}/>);
            const [decreaseButton] = stepper.findAll('button');
            decreaseButton.trigger('onMouseDown', { button: 0 });
            jest.advanceTimersByTime(300);
            stepper.act(() => {
                const event = new MouseEvent('mouseup');
                document.dispatchEvent(event);
            });
            expect(stepper).toContainReactComponent(TextField_1.Field, {
                value: `${value - 2}`,
            });
        });
        it('continues to increase with long press', () => {
            const value = 1;
            const stepper = test_utilities_1.mountWithContext(<Stepper_1.Stepper {...defaultProps} value={value}/>);
            const [, increaseButton] = stepper.findAll('button');
            increaseButton.trigger('onMouseDown', { button: 0 });
            jest.advanceTimersByTime(300);
            stepper.act(() => {
                const event = new MouseEvent('mouseup');
                document.dispatchEvent(event);
            });
            expect(stepper).toContainReactComponent(TextField_1.Field, {
                value: `${value + 2}`,
            });
        });
        it('does not call onChange for decrease until mouseup', () => {
            const value = 10;
            const onChange = jest.fn();
            const stepper = test_utilities_1.mountWithContext(<Stepper_1.Stepper {...defaultProps} value={value} onChange={onChange}/>);
            const [decreaseButton] = stepper.findAll('button');
            decreaseButton.trigger('onMouseDown', { button: 0 });
            jest.advanceTimersByTime(390);
            expect(onChange).not.toHaveBeenCalled();
            stepper.act(() => {
                const event = new MouseEvent('mouseup');
                document.dispatchEvent(event);
            });
            expect(onChange).toHaveBeenCalledWith(`${value - 3}`);
        });
        it('does not call onChange for increase until mouseup', () => {
            const value = 1;
            const onChange = jest.fn();
            const stepper = test_utilities_1.mountWithContext(<Stepper_1.Stepper {...defaultProps} value={value} onChange={onChange}/>);
            const [, increaseButton] = stepper.findAll('button');
            increaseButton.trigger('onMouseDown', { button: 0 });
            jest.advanceTimersByTime(390);
            expect(onChange).not.toHaveBeenCalled();
            stepper.act(() => {
                const event = new MouseEvent('mouseup');
                document.dispatchEvent(event);
            });
            expect(onChange).toHaveBeenCalledWith(`${value + 3}`);
        });
    });
    describe('tap on mobile', () => {
        it('decreases by 1 with onTouchStart', () => {
            const value = 5;
            const stepper = test_utilities_1.mountWithContext(<Stepper_1.Stepper {...defaultProps} value={value}/>);
            const [decreaseButton] = stepper.findAll('button');
            decreaseButton.trigger('ontouchstart');
            jest.advanceTimersByTime(300);
            stepper.act(() => {
                const event = new TouchEvent('touchend');
                document.dispatchEvent(event);
            });
            expect(stepper).toContainReactComponent(TextField_1.Field, {
                value: `${value - 1}`,
            });
        });
        it('increases by 1 with onTouchStart', () => {
            const value = 10;
            const stepper = test_utilities_1.mountWithContext(<Stepper_1.Stepper {...defaultProps} value={value}/>);
            const [, increaseButton] = stepper.findAll('button');
            increaseButton.trigger('ontouchstart');
            jest.advanceTimersByTime(300);
            stepper.act(() => {
                const event = new TouchEvent('touchend');
                document.dispatchEvent(event);
            });
            expect(stepper).toContainReactComponent(TextField_1.Field, {
                value: `${value + 1}`,
            });
        });
    });
    describe('disables buttons when min or max reached', () => {
        it('disables decrease button if value is equal to min', () => {
            const value = 1;
            const min = 1;
            const stepper = test_utilities_1.mountWithContext(<Stepper_1.Stepper {...defaultProps} min={min} value={value}/>);
            const [decreaseButton, increaseButton] = stepper.findAll('button');
            expect(decreaseButton).toHaveReactProps({ disabled: true });
            expect(increaseButton).toHaveReactProps({ disabled: false });
        });
        it('disables decrease button if value is less than min', () => {
            const value = 0;
            const min = 1;
            const stepper = test_utilities_1.mountWithContext(<Stepper_1.Stepper {...defaultProps} min={min} value={value}/>);
            const [decreaseButton, increaseButton] = stepper.findAll('button');
            expect(decreaseButton).toHaveReactProps({ disabled: true });
            expect(increaseButton).toHaveReactProps({ disabled: false });
        });
        it('disables increase button if value is equal to max', () => {
            const value = 10;
            const max = 10;
            const stepper = test_utilities_1.mountWithContext(<Stepper_1.Stepper {...defaultProps} max={max} value={value}/>);
            const [decreaseButton, increaseButton] = stepper.findAll('button');
            expect(decreaseButton).toHaveReactProps({ disabled: false });
            expect(increaseButton).toHaveReactProps({ disabled: true });
        });
        it('disables increase button if value is greater than max', () => {
            const value = 20;
            const max = 10;
            const stepper = test_utilities_1.mountWithContext(<Stepper_1.Stepper {...defaultProps} max={max} value={value}/>);
            const [decreaseButton, increaseButton] = stepper.findAll('button');
            expect(decreaseButton).toHaveReactProps({ disabled: false });
            expect(increaseButton).toHaveReactProps({ disabled: true });
        });
        it('disables decrease button if input value is less than or equal to min', () => {
            const value = 11;
            const min = 10;
            const stepper = test_utilities_1.mountWithContext(<Stepper_1.Stepper {...defaultProps} min={min} value={value}/>);
            stepper
                .find('input')
                .trigger('oninput', { currentTarget: { value: '0' } });
            const [decreaseButton, increaseButton] = stepper.findAll('button');
            expect(decreaseButton).toHaveReactProps({ disabled: true });
            expect(increaseButton).toHaveReactProps({ disabled: false });
        });
        it('disables increase button if input value is greater than or equal to max', () => {
            const value = 0;
            const max = 10;
            const stepper = test_utilities_1.mountWithContext(<Stepper_1.Stepper {...defaultProps} max={max} value={value}/>);
            stepper
                .find('input')
                .trigger('oninput', { currentTarget: { value: '10.1' } });
            const [decreaseButton, increaseButton] = stepper.findAll('button');
            expect(decreaseButton).toHaveReactProps({ disabled: false });
            expect(increaseButton).toHaveReactProps({ disabled: true });
        });
    });
});
