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

describe('Component vnRouteIndex', () => {
    let controller;
    let $httpBackend;

    beforeEach(ngModule('route'));

    beforeEach(inject(($componentController, _$httpBackend_) => {
        $httpBackend = _$httpBackend_;
        const $element = angular.element('<vn-route-index></vn-route-index>');
        controller = $componentController('vnRouteIndex', {$element});
        controller.$.model = crudModel;
        controller.$.model.data = [{id: 1, checked: true}, {id: 2}, {id: 3}];
    }));

    describe('checked() getter', () => {
        it('should return the checked lines', () => {
            const data = controller.$.model.data;
            data[0].checked = true;
            data[2].checked = true;

            const checkedRows = controller.checked;

            const firstCheckedRow = checkedRows[0];
            const secondCheckedRow = checkedRows[1];

            expect(firstCheckedRow.id).toEqual(1);
            expect(secondCheckedRow.id).toEqual(3);
        });
    });

    describe('totalCheked() getter', () => {
        it('should return the total checked lines', () => {
            const data = controller.$.model.data;
            data[0].checked = true;

            const checkedRows = controller.totalChecked;

            expect(checkedRows).toEqual(1);
        });
    });

    describe('showRouteReport()', () => {
        it('should call to the vnReport show method', () => {
            jest.spyOn(window, 'open').mockReturnThis();

            const data = controller.$.model.data;
            data[0].checked = true;
            data[2].checked = true;

            controller.showRouteReport();

            expect(window.open).toHaveBeenCalled();
        });
    });

    describe('cloneSelectedRoutes()', () => {
        it('should perform an http request to Routes/clone', () => {
            controller.createdDate = Date.vnNew();

            $httpBackend.expect('POST', 'Routes/clone').respond();
            controller.cloneSelectedRoutes();
            $httpBackend.flush();
        });
    });

    describe('onDrop()', () => {
        it('should call the insert method when dragging a ticket number', () => {
            jest.spyOn(controller, 'insert');

            const routeId = '1';
            const expectedTicketId = '16';
            const draggedElement = '16';
            const droppable = document.createElement('a');
            droppable.setAttribute('id', 1);
            droppable.classList.add('vn-tr');

            const $event = {
                dataTransfer: {
                    getData: () => draggedElement
                },
                target: droppable
            };
            controller.onDrop($event);

            expect(controller.insert).toHaveBeenCalledWith(routeId, expectedTicketId);
        });

        it('should call the insert method when dragging a ticket link', () => {
            jest.spyOn(controller, 'insert');

            const routeId = '1';
            const expectedTicketId = '11';
            const draggedElement = 'http://arkamcity.com/#!/ticket/11/summary';
            const droppable = document.createElement('a');
            droppable.setAttribute('id', 1);
            droppable.classList.add('vn-tr');

            const $event = {
                dataTransfer: {
                    getData: () => draggedElement
                },
                target: droppable
            };
            controller.onDrop($event);

            expect(controller.insert).toHaveBeenCalledWith(routeId, expectedTicketId);
        });

        it('should throw an error when dragging an invalid ticket link', () => {
            jest.spyOn(controller.vnApp, 'showError');

            const draggedElement = 'http://arkamcity.com/#!/item/11/summary';
            const droppable = document.createElement('a');
            droppable.setAttribute('id', 1);
            droppable.classList.add('vn-tr');
            const $event = {
                dataTransfer: {
                    getData: () => draggedElement
                },
                target: droppable
            };
            controller.onDrop($event);

            expect(controller.vnApp.showError).toHaveBeenCalledWith('Ticket not found');
        });
    });

    describe('insert()', () => {
        it('should perform a HTTP patch query and then call both refresh and showSuccess methods', () => {
            jest.spyOn(controller.$.model, 'refresh').mockReturnThis();
            jest.spyOn(controller.vnApp, 'showSuccess');

            const routeId = 1;
            const ticketId = 11;
            const data = {ticketId};
            $httpBackend.expect('PATCH', `Routes/1/insertTicket`, data).respond();
            controller.insert(routeId, ticketId);
            $httpBackend.flush();

            expect(controller.vnApp.showSuccess).toHaveBeenCalled();
            expect(controller.$.model.refresh).toHaveBeenCalledWith();
        });
    });

    describe('markAsServed()', () => {
        it('should perform a HTTP patch query', () => {
            const data = {isOk: true};
            $httpBackend.expect('PATCH', `Routes/1`, data).respond();
            controller.markAsServed();
            $httpBackend.flush();
        });
    });
});