import './multi-check.js';
import crudModel from 'core/mocks/crud-model';

describe('Component vnMultiCheck', () => {
    let controller;
    let $element;
    let $httpBackend;
    let $httpParamSerializer;

    beforeEach(ngModule('vnCore'));

    beforeEach(inject(($componentController, _$httpBackend_, _$httpParamSerializer_) => {
        $httpBackend = _$httpBackend_;
        $httpParamSerializer = _$httpParamSerializer_;
        $element = angular.element(`<div class="shown"></div>`);
        controller = $componentController('vnMultiCheck', {$element: $element});
        controller._model = crudModel;
        controller._model.data = [
            {id: 1, name: 'My item 1'},
            {id: 2, name: 'My item 2'},
            {id: 3, name: 'My item 3'}
        ];
    }));

    describe('checked() setter', () => {
        it(`should set controller _checked property with the argument received then call toggle()`, () => {
            jest.spyOn(controller, 'toggle');
            controller.checked = crudModel;

            expect(controller._checked).toEqual(crudModel);
            expect(controller.toggle).toHaveBeenCalledWith();
        });

        it(`should set checkedDummyCount to null`, () => {
            jest.spyOn(controller, 'toggle');
            controller.checkedDummyCount = 12;
            controller.checked = null;

            expect(controller.checkedDummyCount).toBeNull();
        });
    });

    describe('toggle()', () => {
        it(`should set checked property inside each existing element`, () => {
            const data = controller.model.data;

            expect(data[0].checked).not.toBeDefined();
            expect(data[1].checked).not.toBeDefined();
            expect(data[2].checked).not.toBeDefined();

            controller._checked = true;
            controller.checkAll = true;
            controller.toggle();

            expect(data[0].checked).toBeTruthy();
            expect(data[1].checked).toBeTruthy();
            expect(data[2].checked).toBeTruthy();
        });

        it(`should unset checked property inside each existing element`, () => {
            const data = controller.model.data;
            data[0].checked = true;
            data[1].checked = true;
            data[2].checked = true;

            controller._checked = false;
            controller.checkAll = false;
            controller.toggle();

            expect(data[0].checked).toBeFalsy();
            expect(data[1].checked).toBeFalsy();
            expect(data[2].checked).toBeFalsy();
        });
    });

    describe('areAllChecked()', () => {
        it(`should return true if all elements are checked`, () => {
            const data = controller.model.data;
            data[0].checked = true;
            data[1].checked = true;
            data[2].checked = true;

            expect(controller.areAllChecked()).toBeTruthy();
        });

        it(`should return false if not all elements are checked`, () => {
            const data = controller.model.data;
            data[0].checked = true;
            data[1].checked = false;
            data[2].checked = true;

            expect(controller.areAllChecked()).toBeFalsy();
        });
    });

    describe('areAllUnchecked()', () => {
        it(`should return true if all elements are unchecked`, () => {
            const data = controller.model.data;
            data[0].checked = false;
            data[1].checked = false;
            data[2].checked = false;

            expect(controller.areAllUnchecked()).toBeTruthy();
        });

        it(`should return false if not all elements are unchecked`, () => {
            const data = controller.model.data;
            data[0].checked = false;
            data[1].checked = true;
            data[2].checked = false;

            expect(controller.areAllUnchecked()).toBeFalsy();
        });
    });

    describe('setSelection()', () => {
        it(`should check all elements between the index range`, () => {
            controller.setSelection(true, 0, 2);

            const data = controller.model.data;
            const firstRow = data[0];
            const secondRow = data[1];
            const thirdRow = data[2];

            expect(firstRow.checked).toBeTruthy();
            expect(secondRow.checked).toBeTruthy();
            expect(thirdRow.checked).toBeTruthy();
        });

        it(`should uncheck all elements between the index range`, () => {
            const data = controller.model.data;
            const firstRow = data[0];
            const secondRow = data[1];
            const thirdRow = data[2];

            firstRow.checked = true;
            secondRow.checked = true;
            thirdRow.checked = true;

            controller.setSelection(false, 0, 1);

            expect(firstRow.checked).toBeFalsy();
            expect(secondRow.checked).toBeFalsy();
            expect(thirdRow.checked).toBeTruthy();
        });
    });

    describe('countRows()', () => {
        it(`should count visible rows and all rows of model`, () => {
            controller.model.url = 'modelUrl/filter';
            const data = controller.model.data;
            const filter = {
                limit: null
            };
            const serializedParams = $httpParamSerializer({filter});

            const response = [
                {id: 1, name: 'My item 1'},
                {id: 2, name: 'My item 2'},
                {id: 3, name: 'My item 3'},
                {id: 4, name: 'My item 4'},
                {id: 5, name: 'My item 5'},
                {id: 6, name: 'My item 6'}
            ];

            controller.countRows();
            $httpBackend.expectGET(`modelUrl/filter?${serializedParams}`).respond(response);
            $httpBackend.flush();

            expect(controller.rows).toEqual(data.length);
            expect(controller.allRowsCount).toEqual(response.length);
            expect(controller.allRowsCount).toBeGreaterThan(controller.rows);
        });
    });

    describe('checkDummy()', () => {
        const allRows = 1234;
        it(`should set the checked dummy count to all rows count if there was no count yet`, () => {
            controller.checkedDummyCount = null;
            controller.allRowsCount = allRows;
            controller.checkDummy();

            expect(controller.checkedDummyCount).toEqual(controller.allRowsCount);
        });

        it(`should remove the dummy count if there was an existing one`, () => {
            controller.checkedDummyCount = allRows;
            controller.checkDummy();

            expect(controller.checkedDummyCount).toBeNull();
        });
    });

    describe('isCheckedDummy()', () => {
        it(`should return true only if is checked and checked dummy is enabled`, () => {
            controller.checked = true;
            controller.checkDummyEnabled = true;
            const isCheckedDummy = controller.isCheckedDummy();

            expect(isCheckedDummy).toEqual(true);
        });

        it(`should return false if not checked`, () => {
            controller.checked = false;
            controller.checkDummyEnabled = true;
            const isCheckedDummy = controller.isCheckedDummy();

            expect(isCheckedDummy).toEqual(false);
        });

        it(`should return false if checked dummy is disabled`, () => {
            controller.checked = true;
            controller.checkDummyEnabled = false;
            const isCheckedDummy = controller.isCheckedDummy();

            expect(isCheckedDummy).toEqual(false);
        });
    });
});