NoctisHsu
9/26/2016 - 3:00 AM

StickyHeaderDirective.spec.js

describe('StickyHeaderDirective', ()=> {
    var $rootScope,
        $compile,
        $window,
        elem,
        scope;

    beforeEach(angular.mock.module('NineYi.Mall.Directives'));

    beforeEach(inject(function (_$rootScope_,
                                _$compile_,
                                _$window_) {
        $window = _$window_;
        $compile = _$compile_;
        $rootScope = _$rootScope_;
        Modernizr = {csspositionsticky: false};
        elem = angular.element("<div data-ns-sticky-header></div>");
    }));

    it('Directive Scope測試', ()=> {
        scope = $rootScope.$new();
        elem = $compile(elem)(scope);
        scope.$digest();
        var elemScope = elem.scope();
        elemScope.should.not.undefined;
        elemScope.FixHeader.should.isFunction;
        elemScope.IsOnTop.should.isFunction;
    });

    it('Directive 基本屬性設定', ()=> {
        var StickyHeaderDirective = new NineYi.Mall.Directives.StickyHeaderDirective($window);
        StickyHeaderDirective.restrict.should.equal('A');
    });

    describe('當瀏覽器支援CSS3 sticky屬性時', ()=> {
        it('父元素會被加上sticky的class', ()=> {
            scope = $rootScope.$new();
            //noinspection JSValidateTypes
            elem = angular.element('<div id="header-container"><div id="header" data-ns-sticky-header></div></div>');
            Modernizr = {csspositionsticky: true};
            $compile(elem)(scope);
            scope.$digest();
            elem.hasClass('sticky').should.be.true;
        });
    });

    describe('當瀏覽器不支援CSS3 sticky屬性時', ()=> {
        let scope, clock, stubIsOnTop, spyFixHeader;
        beforeEach(()=> {
            scope = $rootScope.$new();
            clock = sinon.useFakeTimers();
            $compile(elem)(scope);
        });

        it("套用sticky header的元素上方存在其他元素時,增加scroll event切換position設定", ()=> {
            stubIsOnTop = sinon.stub(scope, "IsOnTop").returns(false);
            spyFixHeader = sinon.spy(scope, "FixHeader");
            scope.$digest();
            clock.tick(2000);
            angular.element($window).triggerHandler('scroll');
            spyFixHeader.called.should.is.true;
        });

        it("套用sticky header的元素上方不存在其他元素時", ()=> {
            stubIsOnTop = sinon.stub(scope, "IsOnTop").returns(true);
            spyFixHeader = sinon.spy(scope, "FixHeader");
            scope.$digest();
            clock.tick(2000);
            angular.element($window).triggerHandler('scroll');
            spyFixHeader.called.should.is.false;
        });

        afterEach(()=> {
            stubIsOnTop.restore();
            spyFixHeader.restore();
            clock.restore();
        })
    });

    describe('FixHeader Function Test', ()=> {
        let clock,stubIsOnTop,fixedClassName;
        beforeEach(()=> {
            scope = $rootScope.$new();
            clock = sinon.useFakeTimers();
            $compile(elem)(scope);
            stubIsOnTop = sinon.stub(scope, "IsOnTop").returns(false);
            clock.tick(2000);
            fixedClassName = elem.scope().fixedClassName;
        });
        it('scoll時,當pageYOffset值小於sticky header 元素的offset top時,移除控制posotion fixed的class', ()=> {
            elem.addClass(fixedClassName);
            elem.scope().$windowElem[0].pageYOffset = 50;
            elem.scope().fixedOffset = 100;
            angular.element($window).triggerHandler('scroll');
            scope.$digest();
            elem.hasClass(fixedClassName).should.be.false;
        });

        it('scoll時,當pageYOffset值大於sticky header 元素的offset top時,加上控制posotion fixed的class', ()=> {
            elem.scope().$windowElem[0].pageYOffset = 200;
            elem.scope().fixedOffset = 100;
            angular.element($window).triggerHandler('scroll');
            scope.$digest();
            elem.hasClass(fixedClassName).should.be.true;
        });

        afterEach(()=> {
            stubIsOnTop.restore();
            clock.restore();
        })
    });
    describe('FixHeader Function Test', ()=> {
        let clock,stubIsOnTop,fixedClassName;
        beforeEach(()=> {
            scope = $rootScope.$new();
            clock = sinon.useFakeTimers();
            $compile(elem)(scope);
            stubIsOnTop = sinon.stub(scope, "IsOnTop").returns(false);
            clock.tick(2000);
            fixedClassName = elem.scope().fixedClassName;
        });
        it('scoll時,當pageYOffset值小於sticky header 元素的offset top時,移除控制posotion fixed的class', ()=> {
            elem.addClass(fixedClassName);
            elem.scope().$windowElem[0].pageYOffset = 50;
            elem.scope().fixedOffset = 100;
            angular.element($window).triggerHandler('scroll');
            scope.$digest();
            elem.hasClass(fixedClassName).should.be.false;
        });

        it('scoll時,當pageYOffset值大於sticky header 元素的offset top時,加上控制posotion fixed的class', ()=> {
            elem.scope().$windowElem[0].pageYOffset = 200;
            elem.scope().fixedOffset = 100;
            angular.element($window).triggerHandler('scroll');
            scope.$digest();
            elem.hasClass(fixedClassName).should.be.true;
        });

        afterEach(()=> {
            stubIsOnTop.restore();
            clock.restore();
        })
    });
    describe('IsOnTop Function Test', ()=> {
        beforeEach(()=> {
            scope = $rootScope.$new();
            $compile(elem)(scope);
        });
        it('當元素的offset top為0,返回true', ()=> {
            elem.offsetTop = 0;
            scope.$digest();
            var result = elem.scope().IsOnTop();
            result.should.be.true;
        });
    });
});