import './index.js';

describe('Order', () => {
    describe('Component vnOrderPricesPopover', () => {
        let controller;
        let $httpBackend;
        let orderId = 16;

        beforeEach(ngModule('order'));

        beforeEach(inject(($componentController, $rootScope, _$httpBackend_) => {
            $httpBackend = _$httpBackend_;
            const $scope = $rootScope.$new();
            const $element = angular.element('<vn-order-prices-popover></vn-order-prices-popover>');
            const $transclude = {
                $$boundTransclude: {
                    $$slots: []
                }
            };
            controller = $componentController('vnOrderPricesPopover', {$element, $scope, $transclude});
            controller._prices = [
                {warehouseFk: 1, grouping: 10, quantity: 0},
                {warehouseFk: 1, grouping: 100, quantity: 100}
            ];
            controller.item = {available: 1000};
            controller.maxQuantity = 1000;
            controller.order = {id: orderId};
        }));

        describe('prices() setter', () => {
            it('should call to the getTotalQuantity() method', () => {
                controller.getTotalQuantity = jest.fn();

                controller.prices = [
                    {grouping: 10, quantity: 0},
                    {grouping: 100, quantity: 0},
                    {grouping: 1000, quantity: 0},
                ];

                expect(controller.getTotalQuantity).toHaveBeenCalledWith();
            });
        });

        describe('getTotalQuantity()', () => {
            it('should set the totalQuantity property', () => {
                controller.getTotalQuantity();

                expect(controller.totalQuantity).toEqual(100);
            });
        });

        describe('addQuantity()', () => {
            it('should call to the getTotalQuantity() method and NOT set the quantity property', () => {
                jest.spyOn(controller, 'getTotalQuantity');

                controller.prices = [
                    {grouping: 10, quantity: 0},
                    {grouping: 100, quantity: 0},
                    {grouping: 1000, quantity: 1000},
                ];

                const oneThousandGrouping = controller.prices[2];

                expect(oneThousandGrouping.quantity).toEqual(1000);

                controller.addQuantity(oneThousandGrouping);

                expect(controller.getTotalQuantity).toHaveBeenCalledWith();
                expect(oneThousandGrouping.quantity).toEqual(1000);
            });

            it('should call to the getTotalQuantity() method and then set the quantity property', () => {
                jest.spyOn(controller, 'getTotalQuantity');

                const oneHandredGrouping = controller.prices[1];
                controller.addQuantity(oneHandredGrouping);

                expect(controller.getTotalQuantity).toHaveBeenCalledWith();
                expect(oneHandredGrouping.quantity).toEqual(200);
            });
        });

        describe('getGroupings()', () => {
            it('should return a row with the total filled quantity', () => {
                jest.spyOn(controller, 'getTotalQuantity');

                controller.prices = [
                    {warehouseFk: 1, grouping: 10, quantity: 10},
                    {warehouseFk: 1, grouping: 100, quantity: 100},
                    {warehouseFk: 1, grouping: 1000, quantity: 1000},
                ];

                const rows = controller.getGroupings();
                const firstRow = rows[0];

                expect(rows.length).toEqual(1);
                expect(firstRow.quantity).toEqual(1110);
            });

            it('should return two filled rows with a quantity', () => {
                jest.spyOn(controller, 'getTotalQuantity');

                controller.prices = [
                    {warehouseFk: 1, grouping: 10, quantity: 10},
                    {warehouseFk: 2, grouping: 10, quantity: 10},
                    {warehouseFk: 1, grouping: 100, quantity: 0},
                    {warehouseFk: 1, grouping: 1000, quantity: 1000},
                ];

                const rows = controller.getGroupings();
                const firstRow = rows[0];
                const secondRow = rows[1];

                expect(rows.length).toEqual(2);
                expect(firstRow.quantity).toEqual(1010);
                expect(secondRow.quantity).toEqual(10);
            });
        });

        describe('submit()', () => {
            it('should throw an error if none of the rows contains a quantity', () => {
                jest.spyOn(controller, 'getTotalQuantity');
                jest.spyOn(controller.vnApp, 'showError');

                controller.prices = [
                    {warehouseFk: 1, grouping: 10, quantity: 0},
                    {warehouseFk: 1, grouping: 100, quantity: 0}
                ];

                controller.submit();

                expect(controller.vnApp.showError).toHaveBeenCalledWith(`First you must add some quantity`);
            });

            it(`should throw an error if the quantity doesn't match the grouping value`, () => {
                jest.spyOn(controller, 'getTotalQuantity');
                jest.spyOn(controller.vnApp, 'showError');

                controller.prices = [
                    {warehouseFk: 1, grouping: 10, quantity: 0},
                    {warehouseFk: 1, grouping: 100, quantity: 1101}
                ];

                controller.submit();

                expect(controller.vnApp.showError).toHaveBeenCalledWith(`The amounts doesn't match with the grouping`);
            });

            it('should should make an http query and then show a success message', () => {
                jest.spyOn(controller, 'getTotalQuantity');
                jest.spyOn(controller.vnApp, 'showSuccess');

                controller.prices = [
                    {warehouseFk: 1, grouping: 10, quantity: 0},
                    {warehouseFk: 1, grouping: 100, quantity: 100}
                ];

                const params = {
                    orderFk: orderId,
                    items: [{warehouseFk: 1, grouping: 100, quantity: 100}]
                };

                $httpBackend.expectPOST('OrderRows/addToOrder', params).respond(200);
                controller.submit();
                $httpBackend.flush();

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