import { newSpecPage } from "@stencil/core/testing";
import { BpSdkAddQuestionPoolItemContainer } from "./bp-sdk-add-question-pool-item-container";
const setupPage = async () => {
    return await newSpecPage({
        html: '<bp-sdk-add-question-pool-item-container></bp-sdk-add-question-pool-item-container>',
        components: [BpSdkAddQuestionPoolItemContainer],
    });
};
const mockQuestionSetState = {
    activeAnswerId: '',
    list: [],
    parentQuestionSets: [],
    active: '',
    completedQuestionSetAnswerHasChanged: false,
    idOfNextActiveQuestionSetNotInState: '',
};
const setupInstance = (page) => {
    return page.rootInstance;
};
describe('bp-sdk-add-question-pool-item-container', () => {
    it('renders', async () => {
        const page = await setupPage();
        const instance = setupInstance(page);
        instance.questionSetState = mockQuestionSetState;
        instance.questionId = 'some id';
        instance.questionSetId = 'some other id';
        await page.waitForChanges();
        expect(page.root.querySelector('div')).toBeTruthy();
        const element = page.root.querySelector('bp-sdk-question-pool-container');
        expect(element).toBeFalsy();
        expect(page.root.querySelector('bp-sdk-external-add-question-pool-item-container')).toBeFalsy();
    });
    it('renders pool', async () => {
        const page = await setupPage();
        const instance = setupInstance(page);
        instance.questionSetState = mockQuestionSetState;
        instance.questionPool = {};
        await page.waitForChanges();
        const element = page.root.querySelector('bp-sdk-question-pool-container');
        expect(element).toBeTruthy();
        expect(page.root.querySelector('bp-sdk-external-add-question-pool-item-container')).toBeFalsy();
    });
    it('renders external component if defined', async () => {
        const whenDefinedMock = jest.spyOn(customElements, 'whenDefined').mockResolvedValueOnce({});
        const page = await setupPage();
        await page.waitForChanges();
        expect(page.root.querySelector('bp-sdk-external-add-question-pool-item-container')).toBeTruthy();
        whenDefinedMock.mockRestore();
    });
    describe('mapStateToProps', () => {
        it('returns expected result', async () => {
            const page = await setupPage();
            const instance = setupInstance(page);
            expect(instance.mapStateToProps({
                application: {
                    form: {
                        id: 'bob',
                    },
                    questionSets: mockQuestionSetState,
                },
                auth: {},
                config: { env: '', uri: '' },
            })).toEqual({
                applicationId: 'bob',
                config: { env: '', token: undefined, uri: '' },
                questionSetState: mockQuestionSetState,
            });
        });
    });
    describe('disconnectedCallback', () => {
        it('makes expected calls', async () => {
            const page = await setupPage();
            const instance = setupInstance(page);
            instance.storeUnsubscribe = jest.fn();
            instance.disconnectedCallback();
            expect(instance.storeUnsubscribe).toBeCalledTimes(1);
        });
    });
    describe('updateQuestionPool', () => {
        it('finds pool', async () => {
            const page = await setupPage();
            const instance = setupInstance(page);
            const pool = {
                parent_question_id: '1',
            };
            instance.updateQuestionPool('1', '1', Object.assign(Object.assign({}, mockQuestionSetState), { list: [
                    {
                        question_set_id: '1',
                        question_set: {
                            question_pools: [pool],
                        },
                    },
                ] }));
            expect(instance.questionPool).toEqual(pool);
        });
        it('finds pool on parent question set', async () => {
            const page = await setupPage();
            const instance = setupInstance(page);
            const pool = {
                parent_question_id: '1',
            };
            const testQuestionStateSet = Object.assign(Object.assign({}, mockQuestionSetState), { list: [
                    {
                        question_set_id: '123',
                    },
                ], parentQuestionSets: [
                    {
                        question_set_id: '1',
                        question_set: {
                            question_pools: [pool],
                        },
                    },
                ] });
            instance.updateQuestionPool('12', '1', testQuestionStateSet);
            expect(instance.questionPool).toBeUndefined();
            instance.updateQuestionPool('1', '1', testQuestionStateSet);
            expect(instance.questionPool).toEqual(pool);
        });
        it('skips pool mismatch', async () => {
            const page = await setupPage();
            const instance = setupInstance(page);
            const pool = {
                parent_question_id: '2',
            };
            instance.updateQuestionPool('1', '1', Object.assign(Object.assign({}, mockQuestionSetState), { list: [
                    {
                        question_set_id: '1',
                        question_set: {
                            question_pools: [pool],
                        },
                    },
                ] }));
            expect(instance.questionPool).toBeUndefined();
        });
        it('skips question set mismatch', async () => {
            const page = await setupPage();
            const instance = setupInstance(page);
            const pool = {
                parent_question_id: '1',
            };
            instance.updateQuestionPool('1', '1', Object.assign(Object.assign({}, mockQuestionSetState), { list: [
                    {
                        question_set_id: '2',
                        question_set: {
                            question_pools: [pool],
                        },
                    },
                ] }));
            expect(instance.questionPool).toBeUndefined();
        });
        it('handles no sets', async () => {
            const page = await setupPage();
            const instance = setupInstance(page);
            instance.updateQuestionPool('1', '1', undefined);
            expect(instance.questionPool).toBeUndefined();
        });
    });
    describe('handleSubscriptions', () => {
        it('calls unsubscribe if subscribed', async () => {
            const page = await setupPage();
            const instance = setupInstance(page);
            const unsubscribe = jest.fn();
            instance.storeUnsubscribe = unsubscribe;
            instance.handleSubscriptions();
            expect(unsubscribe).toHaveBeenCalled();
        });
        it('overwrites an existing subscribe function', async () => {
            const page = await setupPage();
            const instance = setupInstance(page);
            const unsubscribe = jest.fn();
            instance.storeUnsubscribe = unsubscribe;
            instance.handleSubscriptions();
            expect(instance.storeUnsubscribe).not.toEqual(unsubscribe);
            expect(instance.storeUnsubscribe).toBeDefined();
        });
        it('subscribes if not subscribed', async () => {
            const page = await setupPage();
            const instance = setupInstance(page);
            instance.storeUnsubscribe = null;
            instance.handleSubscriptions();
            expect(instance.storeUnsubscribe).not.toBeNull();
        });
        it('subscribes updates mapStateToProps if already has storeUnsubscribe', async () => {
            const page = await setupPage();
            const instance = setupInstance(page);
            const unsubscribe = jest.fn();
            instance.storeUnsubscribe = unsubscribe;
            instance.handleSubscriptions();
            expect(instance.storeUnsubscribe).not.toEqual(unsubscribe);
        });
    });
    describe('connectedCallback', () => {
        it('makes expected call if root available', async () => {
            const page = await setupPage();
            const instance = setupInstance(page);
            instance.handleSubscriptions = jest.fn();
            jest.spyOn(instance.el, 'querySelector').mockImplementationOnce(() => ({
                componentOnReady: () => Promise.resolve(true),
            }));
            instance.connectedCallback();
            await page.waitForChanges();
            expect(instance.handleSubscriptions).toBeCalledTimes(1);
        });
    });
});
