'use strict';
describe('ngInclude', function() {
  var element;
  afterEach(function(){
    dealoc(element);
  });
  function putIntoCache(url, content) {
    return function($templateCache) {
      $templateCache.put(url, [200, content, {}]);
    };
  }
  it('should trust and use literal urls', inject(function(
      $rootScope, $httpBackend, $compile) {
    element = $compile('
')($rootScope);
    $httpBackend.expect('GET', 'url').respond('template text');
    $rootScope.$digest();
    $httpBackend.flush();
    expect(element.text()).toEqual('template text');
    dealoc($rootScope);
  }));
  it('should trust and use trusted urls', inject(function($rootScope, $httpBackend, $compile, $sce) {
    element = $compile('')($rootScope);
    $httpBackend.expect('GET', 'http://foo.bar/url').respond('template text');
    $rootScope.fooUrl = $sce.trustAsResourceUrl('http://foo.bar/url');
    $rootScope.$digest();
    $httpBackend.flush();
    expect(element.text()).toEqual('template text');
    dealoc($rootScope);
  }));
  it('should include an external file', inject(putIntoCache('myUrl', '{{name}}'),
      function($rootScope, $compile) {
    element = jqLite('');
    jqLite(document.body).append(element);
    element = $compile(element)($rootScope);
    $rootScope.name = 'misko';
    $rootScope.url = 'myUrl';
    $rootScope.$digest();
    expect(element.text()).toEqual('misko');
    jqLite(document.body).html('');
  }));
  it('should support ng-include="src" syntax', inject(putIntoCache('myUrl', '{{name}}'),
      function($rootScope, $compile) {
    element = jqLite('');
    jqLite(document.body).append(element);
    element = $compile(element)($rootScope);
    $rootScope.name = 'Alibaba';
    $rootScope.url = 'myUrl';
    $rootScope.$digest();
    expect(element.text()).toEqual('Alibaba');
    jqLite(document.body).html('');
  }));
  it('should NOT use untrusted expressions ', inject(putIntoCache('myUrl', '{{name}} text'),
      function($rootScope, $compile, $sce) {
    element = jqLite('');
    jqLite(document.body).append(element);
    element = $compile(element)($rootScope);
    $rootScope.name = 'chirayu';
    $rootScope.url = 'myUrl';
    expect($rootScope.$digest).toThrow();
    jqLite(document.body).html('');
  }));
  it('should NOT use mistyped expressions ', inject(putIntoCache('myUrl', '{{name}} text'),
      function($rootScope, $compile, $sce) {
    element = jqLite('');
    jqLite(document.body).append(element);
    element = $compile(element)($rootScope);
    $rootScope.name = 'chirayu';
    $rootScope.url = $sce.trustAsUrl('myUrl');
    expect($rootScope.$digest).toThrow();
    jqLite(document.body).html('');
  }));
  it('should remove previously included text if a falsy value is bound to src', inject(
        putIntoCache('myUrl', '{{name}}'),
        function($rootScope, $compile) {
    element = jqLite('');
    element = $compile(element)($rootScope);
    $rootScope.name = 'igor';
    $rootScope.url = 'myUrl';
    $rootScope.$digest();
    expect(element.text()).toEqual('igor');
    $rootScope.url = undefined;
    $rootScope.$digest();
    expect(element.text()).toEqual('');
  }));
  it('should fire $includeContentRequested event on scope after making the xhr call', inject(
      function ($rootScope, $compile, $httpBackend) {
    var contentRequestedSpy = jasmine.createSpy('content requested').andCallFake(function (event) {
        expect(event.targetScope).toBe($rootScope);
    });
    $httpBackend.whenGET('url').respond('my partial');
    $rootScope.$on('$includeContentRequested', contentRequestedSpy);
    element = $compile('')($rootScope);
    $rootScope.$digest();
    expect(contentRequestedSpy).toHaveBeenCalledOnce();
    $httpBackend.flush();
  }));
  it('should fire $includeContentLoaded event on child scope after linking the content', inject(
      function($rootScope, $compile, $templateCache) {
    var contentLoadedSpy = jasmine.createSpy('content loaded').andCallFake(function(event) {
      expect(event.targetScope.$parent).toBe($rootScope);
      expect(element.text()).toBe('partial content');
    });
    $templateCache.put('url', [200, 'partial content', {}]);
    $rootScope.$on('$includeContentLoaded', contentLoadedSpy);
    element = $compile('')($rootScope);
    $rootScope.$digest();
    expect(contentLoadedSpy).toHaveBeenCalledOnce();
  }));
  it('should evaluate onload expression when a partial is loaded', inject(
      putIntoCache('myUrl', 'my partial'),
      function($rootScope, $compile) {
    element = jqLite('');
    element = $compile(element)($rootScope);
    expect($rootScope.loaded).not.toBeDefined();
    $rootScope.url = 'myUrl';
    $rootScope.$digest();
    expect(element.text()).toEqual('my partial');
    expect($rootScope.loaded).toBe(true);
  }));
  it('should create child scope and destroy old one', inject(
        function($rootScope, $compile, $httpBackend) {
    $httpBackend.whenGET('url1').respond('partial {{$parent.url}}');
    $httpBackend.whenGET('url2').respond(404);
    element = $compile('')($rootScope);
    expect(element.children().scope()).toBeFalsy();
    $rootScope.url = 'url1';
    $rootScope.$digest();
    $httpBackend.flush();
    expect(element.children().scope().$parent).toBe($rootScope);
    expect(element.text()).toBe('partial url1');
    $rootScope.url = 'url2';
    $rootScope.$digest();
    $httpBackend.flush();
    expect($rootScope.$$childHead).toBeFalsy();
    expect(element.text()).toBe('');
    $rootScope.url = 'url1';
    $rootScope.$digest();
    expect(element.children().scope().$parent).toBe($rootScope);
    $rootScope.url = null;
    $rootScope.$digest();
    expect($rootScope.$$childHead).toBeFalsy();
  }));
  it('should do xhr request and cache it',
      inject(function($rootScope, $httpBackend, $compile) {
    element = $compile('')($rootScope);
    $httpBackend.expect('GET', 'myUrl').respond('my partial');
    $rootScope.url = 'myUrl';
    $rootScope.$digest();
    $httpBackend.flush();
    expect(element.text()).toEqual('my partial');
    $rootScope.url = null;
    $rootScope.$digest();
    expect(element.text()).toEqual('');
    $rootScope.url = 'myUrl';
    $rootScope.$digest();
    expect(element.text()).toEqual('my partial');
    dealoc($rootScope);
  }));
  it('should clear content when error during xhr request',
      inject(function($httpBackend, $compile, $rootScope) {
    element = $compile('content')($rootScope);
    $httpBackend.expect('GET', 'myUrl').respond(404, '');
    $rootScope.url = 'myUrl';
    $rootScope.$digest();
    $httpBackend.flush();
    expect(element.text()).toBe('');
  }));
  it('should be async even if served from cache', inject(
        putIntoCache('myUrl', 'my partial'),
        function($rootScope, $compile) {
    element = $compile('')($rootScope);
    $rootScope.url = 'myUrl';
    var called = 0;
    // we want to assert only during first watch
    $rootScope.$watch(function() {
      if (!called++) expect(element.text()).toBe('');
    });
    $rootScope.$digest();
    expect(element.text()).toBe('my partial');
  }));
  it('should discard pending xhr callbacks if a new template is requested before the current ' +
      'finished loading', inject(function($rootScope, $compile, $httpBackend) {
    element = jqLite("");
    var log = {};
    $rootScope.templateUrl = 'myUrl1';
    $rootScope.logger = function(msg) {
      log[msg] = true;
    }
    $compile(element)($rootScope);
    expect(log).toEqual({});
    $httpBackend.expect('GET', 'myUrl1').respond('{{logger("url1")}}
');
    $rootScope.$digest();
    expect(log).toEqual({});
    $rootScope.templateUrl = 'myUrl2';
    $httpBackend.expect('GET', 'myUrl2').respond('{{logger("url2")}}
');
    $httpBackend.flush(); // now that we have two requests pending, flush!
    expect(log).toEqual({ url2 : true });
  }));
  it('should compile only the content', inject(function($compile, $rootScope, $templateCache) {
    // regression
    var onload = jasmine.createSpy('$includeContentLoaded');
    $rootScope.$on('$includeContentLoaded', onload);
    $templateCache.put('tpl.html', [200, 'partial {{tpl}}', {}]);
    element = $compile('')($rootScope);
    expect(onload).not.toHaveBeenCalled();
    $rootScope.$apply(function() {
      $rootScope.tpl = 'tpl.html';
    });
    expect(onload).toHaveBeenCalledOnce();
  }));
  describe('autoscoll', function() {
    var autoScrollSpy;
    function spyOnAnchorScroll() {
      return function($provide) {
        autoScrollSpy = jasmine.createSpy('$anchorScroll');
        $provide.value('$anchorScroll', autoScrollSpy);
      };
    }
    function compileAndLink(tpl) {
      return function($compile, $rootScope) {
        element = $compile(tpl)($rootScope);
      };
    }
    function changeTplAndValueTo(template, value) {
      return function($rootScope, $browser) {
        $rootScope.$apply(function() {
          $rootScope.tpl = template;
          $rootScope.value = value;
        });
      };
    }
    beforeEach(module(spyOnAnchorScroll()));
    beforeEach(inject(
        putIntoCache('template.html', 'CONTENT'),
        putIntoCache('another.html', 'CONTENT')));
    it('should call $anchorScroll if autoscroll attribute is present', inject(
        compileAndLink(''),
        changeTplAndValueTo('template.html'), function() {
      expect(autoScrollSpy).toHaveBeenCalledOnce();
    }));
    it('should call $anchorScroll if autoscroll evaluates to true', inject(
        compileAndLink(''),
        changeTplAndValueTo('template.html', true),
        changeTplAndValueTo('another.html', 'some-string'),
        changeTplAndValueTo('template.html', 100), function() {
      expect(autoScrollSpy).toHaveBeenCalled();
      expect(autoScrollSpy.callCount).toBe(3);
    }));
    it('should not call $anchorScroll if autoscroll attribute is not present', inject(
        compileAndLink(''),
        changeTplAndValueTo('template.html'), function() {
      expect(autoScrollSpy).not.toHaveBeenCalled();
    }));
    it('should not call $anchorScroll if autoscroll evaluates to false', inject(
        compileAndLink(''),
        changeTplAndValueTo('template.html', false),
        changeTplAndValueTo('template.html', undefined),
        changeTplAndValueTo('template.html', null), function() {
      expect(autoScrollSpy).not.toHaveBeenCalled();
    }));
  });
});
describe('ngInclude ngAnimate', function() {
  var vendorPrefix, window;
  var body, element, $rootElement;
  function html(html) {
    $rootElement.html(html);
    element = $rootElement.children().eq(0);
    return element;
  }
  function applyCSS(element, cssProp, cssValue) {
    element.css(cssProp, cssValue);
    element.css(vendorPrefix + cssProp, cssValue);
  }
  beforeEach(module(function() {
    // we need to run animation on attached elements;
    return function(_$rootElement_) {
      $rootElement = _$rootElement_;
      body = jqLite(document.body);
      body.append($rootElement);
    };
  }));
  afterEach(function(){
    dealoc(body);
    dealoc(element);
  });
  beforeEach(module(function($animationProvider, $provide) {
    $provide.value('$window', window = angular.mock.createMockWindow());
    return function($sniffer, $animator) {
      vendorPrefix = '-' + $sniffer.vendorPrefix + '-';
      $animator.enabled(true);
    };
  }));
  afterEach(function(){
    dealoc(element);
  });
  it('should fire off the enter animation + add and remove the css classes',
    inject(function($compile, $rootScope, $templateCache, $sniffer) {
      $templateCache.put('enter', [200, 'data
', {}]);
      $rootScope.tpl = 'enter';
      element = $compile(html(
        '' +
        '
'
      ))($rootScope);
      $rootScope.$digest();
      //if we add the custom css stuff here then it will get picked up before the animation takes place
      var child = jqLite(element.children()[0]);
      applyCSS(child, 'transition', '1s linear all');
      if ($sniffer.transitions) {
        expect(child.attr('class')).toContain('custom-enter');
        window.setTimeout.expect(1).process();
        expect(child.attr('class')).toContain('custom-enter-active');
        window.setTimeout.expect(1000).process();
      } else {
       expect(window.setTimeout.queue).toEqual([]);
      }
      expect(child.attr('class')).not.toContain('custom-enter');
      expect(child.attr('class')).not.toContain('custom-enter-active');
  }));
  it('should fire off the leave animation + add and remove the css classes',
    inject(function($compile, $rootScope, $templateCache, $sniffer) {
      $templateCache.put('enter', [200, 'data
', {}]);
      $rootScope.tpl = 'enter';
      element = $compile(html(
        '' +
        '
'
      ))($rootScope);
      $rootScope.$digest();
      //if we add the custom css stuff here then it will get picked up before the animation takes place
      var child = jqLite(element.children()[0]);
      applyCSS(child, 'transition', '1s linear all');
      $rootScope.tpl = '';
      $rootScope.$digest();
      if ($sniffer.transitions) {
        expect(child.attr('class')).toContain('custom-leave');
        window.setTimeout.expect(1).process();
        expect(child.attr('class')).toContain('custom-leave-active');
        window.setTimeout.expect(1000).process();
      } else {
       expect(window.setTimeout.queue).toEqual([]);
      }
      expect(child.attr('class')).not.toContain('custom-leave');
      expect(child.attr('class')).not.toContain('custom-leave-active');
  }));
  it('should catch and use the correct duration for animation',
    inject(function($compile, $rootScope, $templateCache, $sniffer) {
      $templateCache.put('enter', [200, 'data
', {}]);
      $rootScope.tpl = 'enter';
      element = $compile(html(
        '' +
        '
'
      ))($rootScope);
      $rootScope.$digest();
      //if we add the custom css stuff here then it will get picked up before the animation takes place
      var child = jqLite(element.children()[0]);
      applyCSS(child, 'transition', '0.5s linear all');
      $rootScope.tpl = 'enter';
      $rootScope.$digest();
      if ($sniffer.transitions) {
        window.setTimeout.expect(1).process();
        window.setTimeout.expect(500).process();
      } else {
        expect(window.setTimeout.queue).toEqual([]);
      }
  }));
});