import './index.js';

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

    beforeEach(ngModule('travel'));

    beforeEach(inject(($componentController, _$httpBackend_) => {
        $httpBackend = _$httpBackend_;
        const $element = angular.element('<vn-travel-extra-community><div class="travel-list"></div></vn-travel-extra-community>');
        controller = $componentController('vnTravelExtraCommunity', {$element});
        controller.$.model = {};
        controller.$.model.refresh = jest.fn();
    }));

    describe('findDraggable()', () => {
        it('should find the draggable element', () => {
            const draggable = document.createElement('tr');
            draggable.setAttribute('draggable', true);

            const $event = new Event('dragstart');
            const target = document.createElement('div');
            draggable.appendChild(target);
            target.dispatchEvent($event);

            const result = controller.findDraggable($event);

            expect(result).toEqual(draggable);
        });
    });

    describe('findDroppable()', () => {
        it('should find the droppable element', () => {
            const droppable = document.createElement('tbody');
            droppable.setAttribute('vn-droppable', true);

            const $event = new Event('drop');
            const target = document.createElement('div');
            droppable.appendChild(target);
            target.dispatchEvent($event);

            const result = controller.findDroppable($event);

            expect(result).toEqual(droppable);
        });
    });

    describe('dragStart()', () => {
        it(`should add the class "dragging" to the draggable element
            and then set the entryId controller property`, () => {
            const draggable = document.createElement('tr');
            draggable.setAttribute('draggable', true);
            draggable.setAttribute('id', 3);

            jest.spyOn(controller, 'findDraggable').mockReturnValue(draggable);

            const $event = new Event('dragStart');
            controller.dragStart($event);

            const firstClass = draggable.classList[0];

            expect(firstClass).toEqual('dragging');
            expect(controller.entryId).toEqual(3);
            expect(controller.entry).toEqual(draggable);
        });
    });

    describe('dragEnd()', () => {
        it(`should remove the class "dragging" from the draggable element
            and then set the entryId controller property to null`, () => {
            const draggable = document.createElement('tr');
            draggable.setAttribute('draggable', true);
            draggable.setAttribute('id', 3);
            draggable.classList.add('dragging');

            jest.spyOn(controller, 'findDraggable').mockReturnValue(draggable);

            const $event = new Event('dragStart');
            controller.dragEnd($event);

            const classList = draggable.classList;

            expect(classList.length).toEqual(0);
            expect(controller.entryId).toBeNull();
            expect(controller.entry).toBeNull();
        });
    });

    describe('onDrop()', () => {
        it('should make an HTTP patch query', () => {
            const droppable = document.createElement('tbody');
            droppable.setAttribute('vn-droppable', true);
            droppable.setAttribute('id', 1);

            jest.spyOn(controller, 'findDroppable').mockReturnValue(droppable);

            const oldDroppable = document.createElement('tbody');
            oldDroppable.setAttribute('vn-droppable', true);
            const entry = document.createElement('div');
            oldDroppable.appendChild(entry);

            controller.entryId = 3;
            controller.entry = entry;

            const $event = new Event('drop');
            const expectedData = {travelFk: 1};
            $httpBackend.expect('PATCH', `Entries/3`, expectedData).respond(200);
            controller.onDrop($event);
            $httpBackend.flush();
        });
    });

    describe('save()', () => {
        it('should make an HTTP query', () => {
            jest.spyOn(controller.vnApp, 'showSuccess');

            const travelId = 1;
            const data = {ref: 'New reference'};
            const expectedData = {ref: 'New reference'};
            $httpBackend.expect('PATCH', `Travels/${travelId}`, expectedData).respond(200);
            controller.save(travelId, data);
            $httpBackend.flush();

            expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
        });
    });
});