/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

/*jscs:disable jsDoc*/
require.config({
    map: {
        '*': {
            'Magento_Checkout/js/model/shipping-service': 'Magento_Checkout/js/model/shipping-service'
        }
    }
});

define([
    'squire',
    'ko'
], function (Squire, ko) {
    'use strict';

    var injector = new Squire(),
        rates = 'flatrate',
        totals = {
            tax: 0.1,
            totals: 10
        },
        mocks = {
            'Magento_Checkout/js/model/quote': {
                shippingAddress: ko.observable(),
                isVirtual: function () {},
                billingAddress: ko.observable(),
                shippingMethod: ko.observable(),
                setTotals: function () {},
                getTotals: function () {}
            },
            'Magento_Checkout/js/model/shipping-rate-processor/new-address': {
                getRates: jasmine.createSpy()
            },
            'Magento_Checkout/js/model/cart/totals-processor/default': {
                estimateTotals: jasmine.createSpy()
            },
            'Magento_Checkout/js/model/shipping-service': {
                setShippingRates: function () {},
                isLoading: ko.observable(),
                getShippingRates: function () {
                    return ko.observable(rates);
                }
            },
            'Magento_Checkout/js/model/cart/cache': {
                isChanged: function () {},
                get: jasmine.createSpy().and.returnValues(rates, rates, totals),
                set: jasmine.createSpy()
            },
            'Magento_Customer/js/customer-data': {
                get: jasmine.createSpy().and.returnValue(
                    ko.observable({
                        'data_id': 1
                    })
                )
            }
        };

    beforeEach(function (done) {
        window.checkoutConfig = {
            quoteData: {},
            storeCode: 'US'
        };
        injector.mock(mocks);
        injector.require(['Magento_Checkout/js/model/cart/estimate-service'], function () {
            done();
        });
    });

    afterEach(function () {
        try {
            injector.clean();
            injector.remove();
        } catch (e) {}
    });

    describe('Magento_Checkout/js/model/cart/estimate-service', function () {

        it('test subscribe when billingAddress was changed for  virtual quote', function () {
            spyOn(mocks['Magento_Checkout/js/model/quote'], 'isVirtual').and.returnValue(false);
            mocks['Magento_Checkout/js/model/quote'].billingAddress({
                id: 5,
                getType: function () {
                    return 'address_type_test';
                }
            });
            expect(mocks['Magento_Checkout/js/model/cart/totals-processor/default'].estimateTotals)
                .not.toHaveBeenCalled();
        });

        it('test subscribe when shipping address wasn\'t changed for not virtual quote', function () {
            spyOn(mocks['Magento_Checkout/js/model/quote'], 'isVirtual').and.returnValue(false);
            spyOn(mocks['Magento_Checkout/js/model/quote'], 'getTotals').and.returnValue(false);
            spyOn(mocks['Magento_Checkout/js/model/cart/cache'], 'isChanged').and.returnValues(false, false);
            spyOn(mocks['Magento_Checkout/js/model/shipping-service'], 'setShippingRates');
            spyOn(mocks['Magento_Checkout/js/model/quote'], 'setTotals');
            mocks['Magento_Checkout/js/model/quote'].shippingAddress({
                id: 2,
                getType: function () {
                    return 'address_type_test';
                }
            });
            expect(mocks['Magento_Checkout/js/model/shipping-service'].setShippingRates).toHaveBeenCalledWith(rates);
            expect(mocks['Magento_Checkout/js/model/quote'].setTotals).toHaveBeenCalledWith(totals);
            expect(mocks['Magento_Checkout/js/model/cart/totals-processor/default'].estimateTotals)
                .not.toHaveBeenCalled();
            expect(mocks['Magento_Checkout/js/model/shipping-rate-processor/new-address'].getRates)
                .toHaveBeenCalled();
        });

        it('test subscribe when shipping address was changed for virtual quote', function () {
            spyOn(mocks['Magento_Checkout/js/model/quote'], 'isVirtual').and.returnValue(true);
            mocks['Magento_Checkout/js/model/quote'].shippingAddress({
                id: 1,
                getType: function () {
                    return 'address_type_test';
                }
            });
            expect(mocks['Magento_Checkout/js/model/cart/totals-processor/default'].estimateTotals)
                .toHaveBeenCalled();
            expect(mocks['Magento_Checkout/js/model/shipping-rate-processor/new-address'].getRates)
                .toHaveBeenCalled();
        });

        it('test subscribe when shipping address was changed for not virtual quote', function () {
            spyOn(mocks['Magento_Checkout/js/model/quote'], 'isVirtual').and.returnValue(false);
            spyOn(mocks['Magento_Checkout/js/model/cart/cache'], 'isChanged').and.returnValue(
                true
            );
            spyOn(mocks['Magento_Checkout/js/model/shipping-service'], 'setShippingRates');
            mocks['Magento_Checkout/js/model/quote'].shippingAddress({
                id: 4,
                getType: function () {
                    return 'address_type_test';
                }
            });
            expect(mocks['Magento_Checkout/js/model/shipping-service'].setShippingRates)
                .not.toHaveBeenCalledWith(rates);
            expect(mocks['Magento_Checkout/js/model/cart/cache'].set).not.toHaveBeenCalled();
            expect(mocks['Magento_Checkout/js/model/shipping-rate-processor/new-address'].getRates).toHaveBeenCalled();
            expect(mocks['Magento_Checkout/js/model/cart/totals-processor/default'].estimateTotals)
                .toHaveBeenCalled();
        });

        it('test subscribe when shipping method was changed', function () {
            mocks['Magento_Checkout/js/model/quote'].shippingMethod('flatrate');
            expect(mocks['Magento_Checkout/js/model/cart/totals-processor/default'].estimateTotals).toHaveBeenCalled();
        });

        it('test subscribe when billingAddress was changed for not virtual quote', function () {
            spyOn(mocks['Magento_Checkout/js/model/quote'], 'isVirtual').and.returnValue(true);
            mocks['Magento_Checkout/js/model/quote'].billingAddress({
                id: 6,
                getType: function () {
                    return 'address_type_test';
                }
            });
            expect(mocks['Magento_Checkout/js/model/cart/totals-processor/default'].estimateTotals).toHaveBeenCalled();
        });
    });
});
