import { newSpecPage } from "@stencil/core/testing";
import { BpSdkGoogleAddressValidation } from "./bp-sdk-google-address-validation";
import { AddressValidationVerdict, LoadingStates } from "@boldpenguin/sdk-types";
const setupPage = async () => {
    return await newSpecPage({
        html: '<bp-sdk-google-address-validation></bp-sdk-google-address-validation>',
        components: [BpSdkGoogleAddressValidation],
    });
};
describe('bp-sdk-google-address-validation', () => {
    let page;
    let instance;
    beforeEach(async () => {
        page = await setupPage();
        await page.waitForChanges();
        instance = page.rootInstance;
        instance.address = {
            addressComponents: [],
            formattedAddress: '100 E Main Street Columbus, OH 43215',
        };
        instance.answerMap = {
            street_1: { question: { choices: [] }, value: null, choice_id: null, choice_ids: [] },
            street_2: { question: { choices: [] }, value: null, choice_id: null, choice_ids: [] },
            city: { question: { choices: [] }, value: null, choice_id: null, choice_ids: [] },
            state: { question: { choices: [] }, value: null, choice_id: null, choice_ids: [] },
            zipcode: { question: { choices: [] }, value: null, choice_id: null, choice_ids: [] },
        };
        instance.config = { uri: '' };
        instance.googleApiToken = '123456';
    });
    it('renders', async () => {
        const element = page.root.querySelector('.bp-sdk-google-address-validation__container');
        expect(element).toBeTruthy();
    });
    describe('onstageAddressValidationAnswerForUpdate', () => {
        it('should stage answer to save', () => {
            jest.spyOn(instance, 'stageAddressValidationAnswer').mockImplementation(jest.fn());
            instance.onStageAddressValidationAnswerForUpdate({
                detail: { id: '1', value: 'test' },
            });
            expect(instance.stageAddressValidationAnswer).toHaveBeenCalled();
        });
    });
    describe('onIsReadyToProceedNext', () => {
        it('should set status to proceed next and reset the state when loading is complete and its ready to proceed', () => {
            jest.spyOn(instance, 'setAddressValidationStatus').mockImplementation(jest.fn());
            jest.spyOn(instance, 'resetAddressValidation').mockImplementation(jest.fn());
            instance.hasValidationError = false;
            instance.shouldProceedNext = true;
            instance.answersResourceState = LoadingStates.Loaded;
            expect(instance.setAddressValidationStatus).toHaveBeenCalled();
            expect(instance.resetAddressValidation).toHaveBeenCalled();
        });
        it('should not set the status when it should not yet proceed next', () => {
            jest.spyOn(instance, 'setAddressValidationStatus').mockImplementation(jest.fn());
            jest.spyOn(instance, 'resetAddressValidation').mockImplementation(jest.fn());
            instance.hasValidationError = false;
            instance.shouldProceedNext = false;
            instance.answersResourceState = LoadingStates.Loaded;
            expect(instance.setAddressValidationStatus).not.toHaveBeenCalled();
        });
        it('should not set the status when there has been a validation error', () => {
            jest.spyOn(instance, 'setAddressValidationStatus').mockImplementation(jest.fn());
            jest.spyOn(instance, 'resetAddressValidation').mockImplementation(jest.fn());
            instance.hasValidationError = true;
            instance.shouldProceedNext = true;
            instance.answersResourceState = LoadingStates.Loaded;
            expect(instance.setAddressValidationStatus).not.toHaveBeenCalled();
        });
    });
    describe('onValidationError', () => {
        it('should emit analytic event', () => {
            jest.spyOn(instance.bpAnalyticsTrack, 'emit');
            instance.hasValidationError = true;
            expect(instance.bpAnalyticsTrack.emit).toHaveBeenCalled();
        });
    });
    describe('onTriggerValidation', () => {
        it('should trigger address validation', () => {
            jest.spyOn(instance, 'validateAddress').mockImplementation(jest.fn());
            instance.latestAddress = Object.assign({}, instance.answerMap);
            instance.validationAttempt = 0;
            instance.triggerValidation = true;
            instance.onTriggerValidation();
            expect(instance.validateAddress).toHaveBeenCalled();
        });
        it('should not trigger address validation', () => {
            jest.spyOn(instance, 'validateAddress').mockImplementation(jest.fn());
            instance.latestAddress = Object.assign({}, instance.answerMap);
            instance.validationAttempt = 0;
            instance.triggerValidation = false;
            instance.onTriggerValidation();
            expect(instance.validateAddress).not.toHaveBeenCalled();
        });
        it('should trigger validation when there has only been 1 attempt', () => {
            jest.spyOn(instance, 'validateAddress').mockImplementation(jest.fn());
            instance.latestAddress = Object.assign({}, instance.answerMap);
            instance.validationAttempt = 1;
            instance.triggerValidation = true;
            instance.onTriggerValidation();
            expect(instance.validateAddress).toHaveBeenCalled();
        });
        it('should proceed next if attempts has been exceeded', () => {
            jest.spyOn(instance, 'validateAddress').mockImplementation(jest.fn());
            instance.latestAddress = Object.assign({}, instance.answerMap);
            instance.validationAttempt = 2;
            instance.triggerValidation = true;
            instance.onTriggerValidation();
            expect(instance.validateAddress).not.toHaveBeenCalled();
        });
    });
    describe('continueWithConfirm - Confirm flow, Confirm google suggested address', () => {
        it('should save answers and reset validation', () => {
            jest.spyOn(instance, 'saveValidatedAddressAnswers').mockImplementation(jest.fn());
            jest.spyOn(instance, 'onIsReadyToProceedNext').mockImplementation(jest.fn());
            jest.spyOn(instance, 'removeActiveAnswerId').mockImplementation(jest.fn());
            instance.shouldProceedNext = false;
            instance.continueWithConfirm();
            expect(instance.removeActiveAnswerId).toHaveBeenCalled();
            expect(instance.saveValidatedAddressAnswers).toHaveBeenCalled();
            expect(instance.shouldProceedNext).toEqual(true);
        });
    });
    describe('continueWithMissingInputFix - Fix flow, save missing information', () => {
        it('should save answers, unstage answers and set validation status to retrigger validation', () => {
            jest.spyOn(instance, 'saveAddressValidationMissingAnswers').mockImplementation(jest.fn());
            jest.spyOn(instance, 'resetAddressValidation').mockImplementation(jest.fn());
            jest.spyOn(instance, 'removeActiveAnswerId').mockImplementation(jest.fn());
            instance.verdict = AddressValidationVerdict.FIX;
            instance.stagedAnswers = [{ answer: { value: null }, new_value: '100' }];
            instance.addressValidationId = '123';
            instance.continueWithMissingInputFix();
            expect(instance.removeActiveAnswerId).toHaveBeenCalled();
            expect(instance.saveAddressValidationMissingAnswers).toHaveBeenCalledTimes(1);
        });
    });
    describe('editAddress - Fix flow, edit address group fields', () => {
        it('should reset validation', () => {
            jest.spyOn(instance, 'resetAddressValidation').mockImplementation(jest.fn());
            instance.editAddress();
            expect(instance.resetAddressValidation).toHaveBeenCalled();
        });
    });
    describe('continueAsEntered - All flows, proceed with unvalidated address', () => {
        it('should reset validation', () => {
            jest.spyOn(instance, 'resetAddressValidation').mockImplementation(jest.fn());
            jest.spyOn(instance, 'onIsReadyToProceedNext').mockImplementation(jest.fn());
            instance.continueAsEntered();
            expect(instance.shouldProceedNext).toEqual(true);
        });
    });
});
