import { FIELD_TYPES, QuestionFieldType } from "@boldpenguin/sdk-types";
import { newSpecPage } from "@stencil/core/testing";
import debounce from "lodash/debounce";
import { MockAnswer } from "./../../mocks/answer";
import { BpSdkDynamicInput } from "./../bp-sdk-dynamic-input/bp-sdk-dynamic-input";
import { BpSdkDynamicInputEventContainer } from "./bp-sdk-dynamic-input-event-container";
const fakeStore = {
    config: {
        options: {
            debounceTime: 250,
        },
    },
};
let page;
let instance;
const setupPage = async () => {
    page = await newSpecPage({
        html: '<bp-sdk-dynamic-input-event-container></bp-sdk-dynamic-input-event-container>',
        components: [BpSdkDynamicInputEventContainer, BpSdkDynamicInput],
    });
    instance = page.rootInstance;
    instance.updateErrors = jest.fn();
    await page.waitForChanges();
};
describe('bp-sdk-dynamic-input-event-container', () => {
    beforeEach(() => {
        debounce = jest.fn(() => ({ cancel: jest.fn() }));
    });
    describe('renders', () => {
        it('vanilla', async () => {
            await setupPage();
            instance.answer = undefined;
            instance.componentWillLoad();
            await page.waitForChanges();
            expect(page.root.querySelector('bp-sdk-dynamic-input')).toBeTruthy();
            expect(page.root.querySelector('bp-sdk-external-dynamic-input-event-container')).toBeFalsy();
        });
        it('renders external component if defined', async () => {
            const whenDefinedMock = jest.spyOn(customElements, 'whenDefined').mockResolvedValueOnce({});
            await setupPage();
            instance.answer = undefined;
            await page.waitForChanges();
            expect(page.root.querySelector('bp-sdk-external-dynamic-input-event-container')).toBeTruthy();
            whenDefinedMock.mockRestore();
        });
    });
    it('with answer', async () => {
        await setupPage();
        instance.answer = new MockAnswer();
        instance.answer.is_readonly = true;
        instance.errors = ['required'];
        instance.pristine = false;
        instance.touched = true;
        instance.componentWillLoad();
        await page.waitForChanges();
        const input = page.root.querySelector('bp-sdk-dynamic-input');
        expect(instance.labelId).toEqual(`a11y-${instance.answer.question.code}-${instance.answer.id}`);
        expect(input.answerId).toEqual(instance.answer.id);
        expect(input.answerPoolId).toEqual(instance.answer.answer_pool_id);
        expect(input.applicationFormId).toEqual(instance.answer.application_form_id);
        expect(input.choiceId).toEqual(instance.answer.choice_id);
        expect(input.choiceIds).toEqual(instance.answer.choice_ids);
        expect(input.choices).toEqual(instance.answer.question.choices);
        expect(input.code).toEqual(instance.answer.question.code);
        expect(input.displayType).toEqual(instance.answer.display_type);
        expect(input.code).toEqual(instance.answer.question.code);
        expect(input.errors).toEqual(instance.errors);
        expect(input.errorText).toEqual(instance.answer.question.error_text);
        expect(input.fieldType).toEqual(instance.answer.question.field_type);
        expect(input.helpText).toEqual(instance.answer.question.help_text);
        expect(input.isAutocomplete).toBeTruthy();
        expect(input.isCompleted).toBeTruthy();
        expect(input.isHidden).toBeTruthy();
        expect(input.isLabelledField).toBeTruthy();
        expect(input.isMultiple).toBeTruthy();
        expect(input.isReadOnly).toBeTruthy();
        expect(input.isSensitive).toBeTruthy();
        expect(input.isTrackable).toBeTruthy();
        expect(input.labelId).toEqual(instance.labelId);
        expect(input.maxDate).toEqual(instance.answer.question.max_date);
        expect(input.maxValue).toEqual(instance.answer.question.max_value);
        expect(input.minDate).toEqual(instance.answer.question.min_date);
        expect(input.minValue).toEqual(instance.answer.question.min_value);
        expect(input.order).toEqual(instance.answer.question.order);
        expect(input.pattern).toEqual(instance.answer.question.pattern);
        expect(input.pristine).toEqual(instance.pristine);
        expect(input.questionId).toEqual(instance.answer.question.id);
        expect(input.questionGroupId).toEqual(instance.answer.question.question_group_id);
        expect(input.questionSetId).toEqual(instance.answer.question.question_set_id);
        expect(input.referenceType).toEqual(instance.answer.question.reference_type);
        expect(input.showBusinessClassificationSelector).toBeFalsy();
        expect(input.shouldShowInput).toBeTruthy();
        expect(input.text).toEqual(instance.answer.question.text);
        expect(input.touched).toEqual(instance.touched);
        expect(input.useSelectAlias).toEqual(instance.useSelectAlias);
        expect(input.value).toEqual(instance.answer.value);
        expect(page.root.querySelector('bp-sdk-external-dynamic-input-event-container')).toBeFalsy();
    });
    describe('mapStateToProps', () => {
        it('returns an object container all the expected keys', async () => {
            const page = await setupPage();
            const result = instance.mapStateToProps(fakeStore);
            expect(result).toHaveProperty('configOptions');
            expect(result.configOptions.debounceTime).toEqual(250);
        });
    });
    it('sets the debounce time', async () => {
        await setupPage();
        instance.answer = new MockAnswer();
        instance.errors = ['required'];
        instance.pristine = false;
        instance.touched = true;
        instance.componentWillLoad();
        await page.waitForChanges();
        expect(instance.SAVE_ANSWER_DEBOUNCE_MS).toEqual(500);
        instance.configOptions = {
            debounceTime: 250,
        };
        await page.waitForChanges();
        expect(instance.configOptions.debounceTime).toEqual(250);
        expect(instance.SAVE_ANSWER_DEBOUNCE_MS).toEqual(250);
        instance.answer = Object.assign(Object.assign({}, instance.answer), { question: Object.assign(Object.assign({}, instance.answer.question), { field_type: QuestionFieldType.DropDown }) });
        await page.waitForChanges();
        expect(instance.SAVE_ANSWER_DEBOUNCE_MS).toEqual(50);
    });
    it('label', async () => {
        await setupPage();
        instance.label = 'true';
        instance.componentWillLoad();
        await page.waitForChanges();
        expect(page.root.querySelector('bp-sdk-dynamic-input')).toBeTruthy();
        expect(page.root.querySelector('bp-sdk-dynamic-input').label).toEqual('true');
        expect(page.root.querySelector('bp-sdk-external-dynamic-input-event-container')).toBeFalsy();
    });
    it('hide label', async () => {
        await setupPage();
        instance.label = 'true';
        instance.shouldHideLabel = true;
        instance.componentWillLoad();
        await page.waitForChanges();
        expect(page.root.querySelector('bp-sdk-dynamic-input')).toBeTruthy();
        expect(page.root.querySelector('bp-sdk-dynamic-input').label).toEqual('');
        expect(page.root.querySelector('bp-sdk-external-dynamic-input-event-container')).toBeFalsy();
    });
    describe('methods', () => {
        beforeEach(async () => {
            await setupPage();
            instance.debouncedEmit = () => ({ cancel: jest.fn() });
        });
        describe('disconnectedCallback', () => {
            it('makes expected calls', async () => {
                jest.spyOn(instance, 'unloadFocusEvents');
                instance.disconnectedCallback();
                expect(instance.unloadFocusEvents).toHaveBeenCalledTimes(1);
            });
            it('works with no element', async () => {
                instance['_el'] = undefined;
                jest.spyOn(instance, 'unloadFocusEvents');
                instance.disconnectedCallback();
                expect(instance.unloadFocusEvents).toHaveBeenCalledTimes(1);
            });
        });
        describe('componentDidLoad', () => {
            it('makes expected calls', async () => {
                jest.spyOn(instance, 'loadFocusEvents');
                instance.componentDidLoad();
                expect(instance.loadFocusEvents).toHaveBeenCalledTimes(1);
            });
        });
        describe('updateLabel', () => {
            it('should set _label to label', async () => {
                instance.updateLabel({
                    text: 'text',
                }, 'label', false);
                expect(instance._label).toEqual('label');
            });
            it('should set _label to question.text as fallback', async () => {
                instance.updateLabel({
                    text: 'text',
                }, '', false);
                expect(instance._label).toEqual('text');
            });
            it('should set _label to undefined if no question as fallback', async () => {
                instance.updateLabel(undefined, '', false);
                expect(instance._label).toEqual('');
            });
            it('should set to empty string if no text', async () => {
                instance.updateLabel({
                    text: 'text',
                }, 'label', true);
                expect(instance._label).toEqual('');
            });
        });
        describe('onErrorsChange', () => {
            it('should ignore unchanged errors', async () => {
                jest.spyOn(instance, 'determineErrors').mockImplementation(() => { });
                instance.onErrorsChange([], []);
                expect(instance.determineErrors).toHaveBeenCalledTimes(0);
            });
            it('should determine errors if changed', async () => {
                jest.spyOn(instance, 'determineErrors').mockImplementation(() => { });
                instance.onErrorsChange(['required'], []);
                expect(instance.determineErrors).toHaveBeenCalledTimes(1);
                expect(instance.determineErrors).toHaveBeenCalledWith(['required'], instance.touched, instance.pristine);
            });
        });
        describe('onTouchedChange', () => {
            it('should ignore unchanged touched state', async () => {
                jest.spyOn(instance, 'determineErrors').mockImplementation(() => { });
                instance.onTouchedChange(true, true);
                expect(instance.determineErrors).toHaveBeenCalledTimes(0);
            });
            it('should determine errors if changed', async () => {
                jest.spyOn(instance, 'determineErrors').mockImplementation(() => { });
                instance.onTouchedChange(true, false);
                expect(instance.determineErrors).toHaveBeenCalledTimes(1);
                expect(instance.determineErrors).toHaveBeenCalledWith(instance.errors, true, instance.pristine);
            });
        });
        describe('onMakeDirty', () => {
            it('should ignore unchanged touched state', async () => {
                instance.touched = false;
                instance.pristine = true;
                instance.onMakeDirty();
                expect(instance.touched).toBeTruthy();
                expect(instance.pristine).toBeFalsy();
            });
        });
        describe('onPristineChange', () => {
            it('should ignore unchanged touched state', async () => {
                jest.spyOn(instance, 'determineErrors').mockImplementation(() => { });
                instance.onPristineChange(true, true);
                expect(instance.determineErrors).toHaveBeenCalledTimes(0);
            });
            it('should determine errors if changed', async () => {
                jest.spyOn(instance, 'determineErrors').mockImplementation(() => { });
                instance.onPristineChange(true, false);
                expect(instance.determineErrors).toHaveBeenCalledTimes(1);
                expect(instance.determineErrors).toHaveBeenCalledWith(instance.errors, instance.touched, true);
            });
        });
        describe('determineErrors', () => {
            it('should return errors if touched and not pristine', () => {
                const errors = ['required'];
                instance.touched = true;
                instance.pristine = false;
                instance.determineErrors(errors, instance.touched, instance.pristine);
                expect(instance._errors).toEqual(errors);
            });
            it('should return empty array if not touched', () => {
                const errors = ['required'];
                instance.touched = false;
                instance.pristine = false;
                instance.determineErrors(errors, instance.touched, instance.pristine);
                expect(instance._errors).toEqual([]);
            });
            it('should return empty array if pristine', () => {
                const errors = ['required'];
                instance.touched = true;
                instance.pristine = true;
                instance.determineErrors(errors, instance.touched, instance.pristine);
                expect(instance._errors).toEqual([]);
            });
        });
        describe('updateErrorState', () => {
            it('should make expected calls', () => {
                jest.spyOn(instance, 'determineErrors').mockImplementation(() => { });
                jest.spyOn(instance, 'updateErrors').mockImplementation(jest.fn());
                instance.errors = [];
                const mockAnswer = { required: true, value: null, question: { field_type: 'text', required: true } };
                instance.updateErrorState(mockAnswer);
                expect(instance.determineErrors).toHaveBeenLastCalledWith(instance.errors, instance.touched, instance.pristine);
                expect(instance.updateErrors).toHaveBeenLastCalledWith({ answer: mockAnswer, errors: instance.errors });
            });
            it("skips updating store if array's values are same", () => {
                jest.spyOn(instance, 'determineErrors').mockImplementation(() => { });
                jest.spyOn(instance, 'updateErrors').mockImplementation(jest.fn());
                instance.errors = ['required'];
                const mockAnswer = { required: true, value: null, question: { field_type: 'text', required: true } };
                instance.updateErrorState(mockAnswer);
                expect(instance.determineErrors).toHaveBeenLastCalledWith(instance.errors, instance.touched, instance.pristine);
                expect(instance.updateErrors).not.toHaveBeenCalled();
            });
            it('handles undefined errors', () => {
                jest.spyOn(instance, 'determineErrors').mockImplementation(() => { });
                jest.spyOn(instance, 'updateErrors').mockImplementation(jest.fn());
                instance.errors = undefined;
                const mockAnswer = { required: true, value: null, question: { field_type: 'text', required: true } };
                instance.updateErrorState(mockAnswer);
                expect(instance.determineErrors).toHaveBeenLastCalledWith(instance.errors, instance.touched, instance.pristine);
                expect(instance.updateErrors).toHaveBeenLastCalledWith({ answer: mockAnswer, errors: instance.errors });
            });
        });
        describe('onValueUpdate', () => {
            beforeEach(() => {
                instance.answer = {
                    value: 'some old value',
                    question: {
                        field_type: 'text',
                    },
                };
            });
            it('does nothing if external', async () => {
                instance.useExternal = true;
                jest.spyOn(instance, 'updateErrorState').mockImplementation(() => { });
                jest.spyOn(instance, 'updateValue').mockImplementation(() => { });
                const event = { detail: 'answer' };
                instance.onValueUpdate(event);
                expect(instance.updateErrorState).toBeCalledTimes(0);
                expect(instance.updateValue).toBeCalledTimes(0);
            });
            it('does nothing if last value equals new one', async () => {
                jest.spyOn(instance, 'updateErrorState').mockImplementation(() => { });
                jest.spyOn(instance, 'updateValue').mockImplementation(() => { });
                const event = { detail: 'answer' };
                instance.lastAnswer = event.detail;
                instance.onValueUpdate(event);
                expect(instance.updateErrorState).toBeCalledTimes(0);
                expect(instance.updateValue).toBeCalledTimes(0);
            });
            it('updates errors if value has changed', async () => {
                jest.spyOn(instance, 'updateErrorState').mockImplementation(() => { });
                jest.spyOn(instance, 'updateValue').mockImplementation(() => { });
                const event = { detail: 'answer' };
                instance.onValueUpdate(event);
                expect(instance.updateErrorState).toBeCalledTimes(1);
                expect(instance.updateErrorState).toHaveBeenCalledWith(Object.assign(Object.assign({}, instance.answer), { is_completed: false, question: Object.assign(Object.assign({}, instance.answer.question), { error_text: undefined }), value: event.detail }));
                expect(instance.updateValue).toBeCalledTimes(1);
                expect(instance.updateValue).toHaveBeenCalledWith(event.detail);
            });
            describe('if value has not changed', () => {
                beforeEach(() => {
                    jest.spyOn(instance, 'updateErrorState').mockImplementation(() => { });
                    jest.spyOn(instance, 'updateValue').mockImplementation(() => { });
                    const event = { detail: instance.answer.value };
                    instance.onValueUpdate(event);
                });
                it('should not update errors', () => {
                    expect(instance.updateErrorState).not.toHaveBeenCalled();
                });
                it('should update value', () => {
                    expect(instance.updateValue).toHaveBeenCalledWith(instance.answer.value);
                });
            });
            it('does not call removeActiveAnswer if not dropdown', async () => {
                jest.spyOn(instance.removeActiveAnswer, 'emit').mockImplementation(jest.fn());
                instance.isDropdown = false;
                const event = { detail: instance.answer.value };
                instance.onValueUpdate(event);
                expect(instance.removeActiveAnswer.emit).toBeCalledTimes(0);
            });
            it('calls removeActiveAnswer if dropdown', async () => {
                jest.spyOn(instance, 'updateErrorState').mockImplementation(() => { });
                jest.spyOn(instance, 'updateValue').mockImplementation(() => { });
                jest.spyOn(instance.removeActiveAnswer, 'emit').mockImplementation(jest.fn());
                instance.isDropdown = true;
                const event = { detail: 'new answer' };
                instance.onValueUpdate(event);
                expect(instance.removeActiveAnswer.emit).toBeCalledTimes(1);
            });
        });
        describe('cleanValue', () => {
            it('handles undefined', async () => {
                expect(instance.cleanValue(undefined)).toBeUndefined();
            });
            it('handles null', async () => {
                expect(instance.cleanValue(null)).toBeNull();
            });
            it('should return vanilla strings', async () => {
                const value = 'some string';
                expect(instance.cleanValue(value)).toEqual(value);
            });
            it('strip non-digits out if numeric', async () => {
                instance.isNumeric = true;
                const value = '123abc';
                expect(instance.cleanValue(value)).toEqual('123');
            });
            it('strips non-digits from negative numbers', async () => {
                instance.isNumeric = true;
                const value = '-123abc';
                expect(instance.cleanValue(value)).toEqual('-123');
            });
            it('strips non-digits from floating point numbers', () => {
                instance.isNumeric = true;
                const value = '12.34abc';
                expect(instance.cleanValue(value)).toEqual('12.34');
            });
            it('strip ensures arrays are unique', async () => {
                instance.isNumeric = true;
                const value = ['1', '2', '3', '3'];
                expect(instance.cleanValue(value)).toEqual(['1', '2', '3']);
            });
            it("doesn't strip * characters from FEIN", async () => {
                instance.isNumeric = true;
                instance.fieldType = QuestionFieldType.FederalEmployeeIdentification;
                const value = ['*****6789'];
                expect(instance.cleanValue(value)).toEqual(['*****6789']);
            });
            it("doesn't strip * characters from SSN", async () => {
                instance.isNumeric = true;
                instance.fieldType = QuestionFieldType.SocialSecurityNumber;
                const value = ['*****6789'];
                expect(instance.cleanValue(value)).toEqual(['*****6789']);
            });
            it('replaces curly quotes with straight quotes', async () => {
                instance.isNumeric = false;
                const value = 'The test‘s business’ “name”';
                expect(instance.cleanValue(value)).toEqual('The test\'s business\' "name"');
            });
            it('passes through boolean values', async () => {
                expect(instance.cleanValue(true)).toEqual(true);
            });
        });
        describe('updateValue', () => {
            it('makes expected calls', async () => {
                const value = 'new value';
                jest.spyOn(instance, 'save').mockImplementation(() => { });
                jest.spyOn(instance, 'cleanValue').mockReturnValue(`a ${value}`);
                instance.updateValue(value);
                expect(instance.cleanValue).toHaveBeenCalledWith(value);
                expect(instance.cleanValue).toBeCalledTimes(1);
                expect(instance.save).toHaveBeenCalledWith(`a ${value}`);
                expect(instance.save).toBeCalledTimes(1);
            });
        });
        describe('onFocusIn', () => {
            it('makes expected calls', async () => {
                instance.answer = { id: 'id' };
                instance.updateActiveAnswerId = jest.fn();
                instance.onFocusIn();
                expect(instance.updateActiveAnswerId).toBeCalledTimes(1);
                expect(instance.updateActiveAnswerId).toBeCalledWith('id');
            });
            it('makes expected calls if no answer', async () => {
                instance.updateActiveAnswerId = jest.fn();
                instance.onFocusIn();
                expect(instance.updateActiveAnswerId).toBeCalledTimes(1);
                expect(instance.updateActiveAnswerId).toBeCalledWith(undefined);
            });
            describe('dropdown', () => {
                beforeEach(() => {
                    instance.inputComponentType = 'dropdown';
                });
                it('makes expected calls if multiple', async () => {
                    instance.answer = {
                        id: 'id',
                        question: {
                            field_type: 'dropdown',
                            multiple: true,
                        },
                    };
                    jest.spyOn(instance.el, 'querySelector').mockReturnValue({});
                    instance.updateActiveAnswerId = jest.fn();
                    jest.spyOn(instance.removeActiveAnswer, 'emit').mockImplementation(() => ({}));
                    instance.onFocusIn();
                    expect(instance.updateActiveAnswerId).toBeCalledTimes(1);
                    expect(instance.updateActiveAnswerId).toBeCalledWith('id');
                    expect(instance.removeActiveAnswer.emit).toBeCalledTimes(0);
                });
                it('makes expected calls if not multiple', async () => {
                    instance.answer = {
                        id: 'id',
                        question: {
                            field_type: 'dropdown',
                            multiple: false,
                        },
                    };
                    instance.updateActiveAnswerId = jest.fn();
                    jest.spyOn(instance.removeActiveAnswer, 'emit').mockImplementation(() => ({}));
                    instance.onFocusIn();
                    expect(instance.removeActiveAnswer.emit).toBeCalledTimes(1);
                });
                it('makes expected calls if no question', async () => {
                    instance.answer = {
                        id: 'id',
                    };
                    instance.inputComponentType = 'dropdown';
                    instance.updateActiveAnswerId = jest.fn();
                    jest.spyOn(instance.removeActiveAnswer, 'emit').mockImplementation(() => ({}));
                    jest.spyOn(instance.el, 'querySelector').mockReturnValue({});
                    instance.onFocusIn();
                    expect(instance.updateActiveAnswerId).toBeCalledTimes(0);
                    expect(instance.removeActiveAnswer.emit).toBeCalledTimes(1);
                });
                it('makes expected calls if no answer', async () => {
                    instance.updateActiveAnswerId = jest.fn();
                    jest.spyOn(instance.removeActiveAnswer, 'emit').mockImplementation(() => ({}));
                    jest.spyOn(instance.el, 'querySelector').mockReturnValue({});
                    instance.onFocusIn();
                    expect(instance.updateActiveAnswerId).toBeCalledTimes(0);
                    expect(instance.removeActiveAnswer.emit).toBeCalledTimes(1);
                });
            });
        });
        describe('onFocusOut', () => {
            it('makes expected calls', async () => {
                instance.touched = false;
                jest.spyOn(instance, 'determineErrors').mockImplementation(() => { });
                instance.onFocusOut();
                expect(instance.determineErrors).toHaveBeenLastCalledWith(instance.errors, instance.touched, instance.pristine);
            });
            it('handles pending updates', async () => {
                instance.hasPendingUpdate = true;
                jest.spyOn(instance, 'emitSaveAnswer').mockImplementation(() => { });
                instance.onFocusOut();
                expect(instance.emitSaveAnswer).toBeCalledTimes(1);
                expect(instance.emitSaveAnswer).toBeCalledWith(instance.lastAnswer);
            });
        });
        describe('emitSaveAnswer', () => {
            it('does nothing if no pending answers', async () => {
                instance.hasPendingUpdate = false;
                jest.spyOn(instance.saveAnswer, 'emit');
                instance.emitSaveAnswer('some answer');
                expect(instance.saveAnswer.emit).toBeCalledTimes(0);
            });
            it('handles pending updates', async () => {
                instance.hasPendingUpdate = true;
                const new_value = 'some new value';
                jest.spyOn(instance.saveAnswer, 'emit');
                instance.emitSaveAnswer(new_value);
                expect(instance.saveAnswer.emit).toBeCalledTimes(1);
                expect(instance.saveAnswer.emit).toBeCalledWith({
                    answer: Object.assign({}, instance.answer),
                    new_value,
                });
                expect(instance.hasPendingUpdate).toBeFalsy();
            });
        });
        describe('getComponentType', () => {
            it('sets text for default text inputs', () => {
                FIELD_TYPES.textFields.forEach((v) => {
                    expect(instance.getComponentType(v)).toEqual('text');
                });
            });
            it('sets text for default masked inputs', () => {
                FIELD_TYPES.maskedFields.forEach((v) => {
                    expect(instance.getComponentType(v)).toEqual('masked');
                });
            });
            it('returns coverage_type if flagged', () => {
                instance.isCoverageType = true;
                expect(instance.getComponentType('text')).toEqual('coverage_type');
            });
            it('returns field type otherwise', () => {
                const fieldType = 'some other field type';
                expect(instance.getComponentType(fieldType)).toEqual(fieldType);
            });
        });
        describe('loadFocusEvents', () => {
            it('makes expected calls', async () => {
                jest.spyOn(instance.el, 'addEventListener').mockImplementation(() => { });
                instance.loadFocusEvents();
                expect(instance.el.addEventListener).toBeCalledTimes(2);
            });
            it('does nothing if external', async () => {
                jest.spyOn(instance.el, 'addEventListener').mockImplementation(() => { });
                instance.useExternal = true;
                instance.loadFocusEvents();
                expect(instance.el.addEventListener).toBeCalledTimes(0);
            });
        });
        describe('onLabelChange', () => {
            it('makes expected calls if no answer', () => {
                jest.spyOn(instance, 'updateLabel').mockImplementation(() => { });
                instance.onLabelChange('some label');
                expect(instance.updateLabel).toBeCalledTimes(1);
            });
            it('makes expected calls if no question', () => {
                instance.answer = {};
                jest.spyOn(instance, 'updateLabel').mockImplementation(() => { });
                instance.onLabelChange('some label');
                expect(instance.updateLabel).toBeCalledTimes(1);
            });
            it('otherwise works', () => {
                instance.answer = {
                    question: {},
                };
                jest.spyOn(instance, 'updateLabel').mockImplementation(() => { });
                instance.onLabelChange('some label');
                expect(instance.updateLabel).toBeCalledTimes(1);
            });
        });
        describe('onHideLabelChange', () => {
            it('makes expected calls if no answer', () => {
                jest.spyOn(instance, 'updateLabel').mockImplementation(() => { });
                instance.onHideLabelChange(true);
                expect(instance.updateLabel).toBeCalledTimes(1);
            });
            it('makes expected calls if no question', () => {
                instance.answer = {};
                jest.spyOn(instance, 'updateLabel').mockImplementation(() => { });
                instance.onHideLabelChange(true);
                expect(instance.updateLabel).toBeCalledTimes(1);
            });
            it('otherwise works', () => {
                instance.answer = {
                    question: {},
                };
                jest.spyOn(instance, 'updateLabel').mockImplementation(() => { });
                instance.onHideLabelChange(true);
                expect(instance.updateLabel).toBeCalledTimes(1);
            });
        });
        describe('onAnswerChange()', () => {
            describe('when an answer changes and has a different id', () => {
                const newAnswer = {
                    id: '567',
                };
                beforeEach(() => {
                    instance.answer = {
                        id: '123',
                    };
                    instance.answer = newAnswer;
                });
                it('should update the local answer id', () => {
                    expect(instance.answerId).toEqual(newAnswer.id);
                });
                it('should reset the touched state', () => {
                    expect(instance.touched).toEqual(false);
                });
                it('should reset the pristine state', () => {
                    expect(instance.pristine).toEqual(true);
                });
                it('should reset the last answer', () => {
                    expect(instance.lastAnswer).toEqual(undefined);
                });
            });
            describe('when an answer changes, but the id is the same', () => {
                const newAnswer = {
                    id: '123',
                };
                const isTouched = true;
                const isPristine = false;
                const lastAnswer = 'something;';
                beforeEach(() => {
                    instance.answer = {
                        id: '123',
                    };
                    instance.touched = isTouched;
                    instance.pristine = isPristine;
                    instance.lastAnswer = lastAnswer;
                    instance.answer = newAnswer;
                });
                it('should not change the answer id', () => {
                    expect(instance.answerId).toEqual(newAnswer.id);
                });
                it('should not reset the touched state', () => {
                    expect(instance.touched).toEqual(isTouched);
                });
                it('should reset the pristine state', () => {
                    expect(instance.pristine).toEqual(isPristine);
                });
                it('should reset the last answer', () => {
                    expect(instance.lastAnswer).toEqual(lastAnswer);
                });
            });
        });
    });
    //tests previously in dynamic-input-answer-container
    describe('shouldHideLabel', () => {
        it('renders active answer', async () => {
            const page = await newSpecPage({
                html: '<bp-sdk-dynamic-input-event-container></bp-sdk-dynamic-input-event-container>',
                components: [BpSdkDynamicInputEventContainer, BpSdkDynamicInput],
            });
            const instance = page.rootInstance;
            instance.answer = {
                active: true,
                display_type: 'public',
                question: {},
            };
            await page.waitForChanges();
            expect(page.root.querySelector('bp-sdk-dynamic-input').shouldShowInput).toBeTruthy();
        });
        it('hides non-public', async () => {
            const page = await newSpecPage({
                html: '<bp-sdk-dynamic-input-event-container></bp-sdk-dynamic-input-event-container>',
                components: [BpSdkDynamicInputEventContainer, BpSdkDynamicInput],
            });
            const instance = page.rootInstance;
            instance.answer = {
                active: true,
                display_type: 'private',
                question: {
                    field_type: 'text',
                },
            };
            await page.waitForChanges();
            expect(page.root.querySelector('bp-sdk-dynamic-input').shouldShowInput).toBeFalsy();
            expect(page.root.querySelector('bp-sdk-dynamic-input').fieldType).toEqual('text');
        });
        it('hides non-active', async () => {
            const page = await newSpecPage({
                html: '<bp-sdk-dynamic-input-event-container></bp-sdk-dynamic-input-event-container>',
                components: [BpSdkDynamicInputEventContainer, BpSdkDynamicInput],
            });
            const instance = page.rootInstance;
            instance.answer = {
                active: false,
                display_type: 'public',
                question: {
                    field_type: 'text',
                },
            };
            await page.waitForChanges();
            expect(page.root.querySelector('bp-sdk-dynamic-input').shouldShowInput).toBeFalsy();
            expect(page.root.querySelector('bp-sdk-dynamic-input').fieldType).toEqual('text');
        });
    });
    describe('isReadOnly', () => {
        it('is true when answer is readonly', async () => {
            const page = await newSpecPage({
                html: '<bp-sdk-dynamic-input-event-container></bp-sdk-dynamic-input-event-container>',
                components: [BpSdkDynamicInputEventContainer, BpSdkDynamicInput],
            });
            const instance = page.rootInstance;
            instance.answer = {
                active: true,
                display_type: 'public',
                answered_by_consumer: true,
                is_readonly: true,
            };
            await page.waitForChanges();
            expect(page.root.querySelector('bp-sdk-dynamic-input').isReadOnly).toBe(true);
        });
        it('is false when an answer is false', async () => {
            const page = await newSpecPage({
                html: '<bp-sdk-dynamic-input-event-container></bp-sdk-dynamic-input-event-container>',
                components: [BpSdkDynamicInputEventContainer, BpSdkDynamicInput],
            });
            const instance = page.rootInstance;
            instance.answer = {
                active: true,
                display_type: 'public',
                answered_by_consumer: true,
                is_readonly: false,
            };
            await page.waitForChanges();
            expect(page.root.querySelector('bp-sdk-dynamic-input').isReadOnly).toBe(false);
        });
    });
    describe('answeredBySource', () => {
        it('returns Consumer when answered by consumer', async () => {
            const page = await newSpecPage({
                html: '<bp-sdk-dynamic-input-event-container></bp-sdk-dynamic-input-event-container>',
                components: [BpSdkDynamicInputEventContainer, BpSdkDynamicInput],
            });
            const instance = page.rootInstance;
            instance.answer = {
                active: true,
                display_type: 'public',
                answered_by_consumer: true,
            };
            await page.waitForChanges();
            expect(page.root.querySelector('bp-sdk-dynamic-input').answeredBySource).toBe('Consumer');
        });
        it('returns source when answered source is defined', async () => {
            const page = await newSpecPage({
                html: '<bp-sdk-dynamic-input-event-container></bp-sdk-dynamic-input-event-container>',
                components: [BpSdkDynamicInputEventContainer, BpSdkDynamicInput],
            });
            const instance = page.rootInstance;
            instance.answer = {
                active: true,
                display_type: 'public',
                answered_by_source: 'ACORD 125',
            };
            await page.waitForChanges();
            expect(page.root.querySelector('bp-sdk-dynamic-input').answeredBySource).toBe('ACORD 125');
        });
        it('returns a falsy value when answered source is not defined', async () => {
            const page = await newSpecPage({
                html: '<bp-sdk-dynamic-input-event-container></bp-sdk-dynamic-input-event-container>',
                components: [BpSdkDynamicInputEventContainer, BpSdkDynamicInput],
            });
            const instance = page.rootInstance;
            instance.answer = {
                active: true,
                display_type: 'public',
            };
            await page.waitForChanges();
            expect(page.root.querySelector('bp-sdk-dynamic-input').answeredBySource).toBeFalsy();
        });
    });
});
