<commit_before>/*jshint browser: true, indent: 2 */
/*global describe: false, it: false, beforeEach: false, expect: false, resolvedValue: false, module: false, inject: false, angular: false */

describe('uiView', function () {
  'use strict';

  var scope, $compile, elem;

  beforeEach(function() {
    var depends = ['ui.router'];

    try {
      angular.module('ngAnimateMock');
      depends.push('ngAnimateMock');
    } catch(e) {
      angular.module('mock.animate', []).value('$animate', null);
      module('mock.animate');
    }

    angular.module('ui.router.test', depends);
    module('ui.router.test');
  });

  beforeEach(module(function ($provide) {
    $provide.decorator('$uiViewScroll', function () {
      return jasmine.createSpy('$uiViewScroll');
    });
  }));

  var aState = {
    template: 'aState template'
  },
  bState = {
    template: 'bState template'
  },
  cState = {
    views: {
      'cview': {
        template: 'cState cview template'
      }
    }
  },
  dState = {
    views: {
      'dview1': {
        template: 'dState dview1 template'
      },
      'dview2': {
        template: 'dState dview2 template'
      }
    }
  },
  eState = {
    template: '

'
  },
  fState = {
    views: {
      'eview': {
        template: 'fState eview template'
      }
    }
  },
  gState = {
    template: '
{{content}}
'
  },
  hState = {
    views: {
      'inner': {
        template: 'hState inner template'
      }
    }
  },
  iState = {
    template: '
'+
        '

{{item}}

'+
      '
'
  },
  jState = {
    template: 'jState'
  },
  kState = {
    controller: function() {
      this.someProperty = "value"
    },
    controllerAs: "vm"
  };

  beforeEach(module(function ($stateProvider) {
    $stateProvider
      .state('a', aState)
      .state('b', bState)
      .state('c', cState)
      .state('d', dState)
      .state('e', eState)
      .state('e.f', fState)
      .state('g', gState)
      .state('g.h', hState)
      .state('i', iState)
      .state('j', jState)
      .state('k', kState)
  }));

  beforeEach(inject(function ($rootScope, _$compile_) {
    scope = $rootScope.$new();
    $compile = _$compile_;
    elem = angular.element('
');
  }));

  describe('linking ui-directive', function () {

    it('anonymous ui-view should be replaced with the template of the current $state', inject(function ($state, $q) {
      elem.append($compile('
<ui-view></ui-view>
')(scope));

      expect(elem.find('ui-view').text()).toBe('');

      $state.transitionTo(aState);
      $q.flush();

      expect(elem.find('ui-view').text()).toBe(aState.template);
    }));

    it('named ui-view should be replaced with the template of the current $state', inject(function ($state, $q) {
      elem.append($compile('
<ui-view name="cview"></ui-view>
')(scope));

      $state.transitionTo(cState);
      $q.flush();

      expect(elem.find('ui-view').text()).toBe(cState.views.cview.template);
    }));

    it('ui-view should be updated after transition to another state', inject(function ($state, $q) {
      elem.append($compile('
<ui-view></ui-view>
')(scope));
      expect(elem.find('ui-view').text()).toBe('');

      $state.transitionTo(aState);
      $q.flush();

      expect(elem.find('ui-view').text()).toBe(aState.template);

      $state.transitionTo(bState);
      $q.flush();

      expect(elem.find('ui-view').text()).toBe(bState.template);
    }));

    it('should handle NOT nested ui-views', inject(function ($state, $q) {
      elem.append($compile('
<ui-view name="dview1" class="dview1"></ui-view><ui-view name="dview2" class="dview2"></ui-view>
')(scope));
      expect(elem.find('ui-view').eq(0).text()).toBe('');
      expect(elem.find('ui-view').eq(1).text()).toBe('');

      $state.transitionTo(dState);
      $q.flush();

      expect(elem.find('ui-view').eq(0).text()).toBe(dState.views.dview1.template);
      expect(elem.find('ui-view').eq(1).text()).toBe(dState.views.dview2.template);
    }));

    it('should handle nested ui-views (testing two levels deep)', inject(function ($state, $q) {
      $compile(elem.append('
<ui-view></ui-view>
'))(scope);
      expect(elem.find('ui-view').text()).toBe('');

      $state.transitionTo(fState);
      $q.flush();

      expect(elem.find('ui-view').text()).toBe(fState.views.eview.template);
    }));
  });

  describe('handling initial view', function () {
    it('initial view should be compiled if the view is empty', inject(function ($state, $q) {
      var content = 'inner content';
      scope.content = content;
      elem.append($compile('
<ui-view></ui-view>
')(scope));

      $state.transitionTo(gState);
      $q.flush();

      expect(elem.find('ui-view').text()).toBe(content);
    }));

    it('initial view should be put back after removal of the view', inject(function ($state, $q) {
      var content = 'inner content';
      scope.content = content;
      elem.append($compile('
<ui-view></ui-view>
')(scope));

      $state.go(hState);
      $q.flush();

      expect(elem.find('ui-view').text()).toBe(hState.views.inner.template);

      // going to the parent state which makes the inner view empty
      $state.go(gState);
      $q.flush();

      expect(elem.find('ui-view').text()).toBe(content);
    }));

    // related to issue #435
    it('initial view should be transcluded once to prevent breaking other directives', inject(function ($state, $q) {
      scope.items = ["I", "am", "a", "list", "of", "items"];

      elem.append($compile('
<ui-view></ui-view>
')(scope));

      // transition to state that has an initial view
      $state.transitionTo(iState);
      $q.flush();

      // verify if ng-repeat has been compiled
      expect(elem.find('li').length).toBe(scope.items.length);

      // transition to another state that replace the initial content
      $state.transitionTo(jState);
      $q.flush();

      expect(elem.find('ui-view').text()).toBe(jState.template);

      // transition back to the state with empty subview and the initial view
      $state.transitionTo(iState);
      $q.flush();

      // verify if the initial view is correct
      expect(elem.find('li').length).toBe(scope.items.length);

      // change scope properties
      scope.$apply(function () {
        scope.items.push(".", "Working?");
      });

      // verify if the initial view has been updated
      expect(elem.find('li').length).toBe(scope.items.length);
    }));

    // related to issue #857
    it('should handle ui-view inside ng-if', inject(function ($state, $q, $compile) {
      // ngIf does not exist in 1.0.8
      if (angular.version.full === '1.0.8') return;

      scope.someBoolean = false;
      elem.append($compile('
<ui-view></ui-view>
')(scope));

      $state.transitionTo(aState);
      $q.flush();

      // Verify there is no ui-view in the DOM
      expect(elem.find('ui-view').length).toBe(0);

      // Turn on the div that holds the ui-view
      scope.someBoolean = true;
      scope.$digest();

      // Verify that the ui-view is there and it has the correct content
      expect(elem.find('ui-view').text()).toBe(aState.template);

      // Turn off the ui-view
      scope.someBoolean = false;
      scope.$digest();

      // Verify there is no ui-view in the DOM
      expect(elem.find('ui-view').length).toBe(0);

      // Turn on the div that holds the ui-view once again
      scope.someBoolean = true;
      scope.$digest();

      // Verify that the ui-view is there and it has the correct content
      expect(elem.find('ui-view').text()).toBe(aState.template);
    }));
  });

  describe('autoscroll attribute', function () {
    it('should autoscroll when unspecified', inject(function ($state, $q, $uiViewScroll, $animate) {
      elem.append($compile('
<ui-view></ui-view>
')(scope));

      $state.transitionTo(aState);
      $q.flush();

      if ($animate) $animate.triggerCallbacks();

      expect($uiViewScroll).toHaveBeenCalledWith(elem.find('span').parent());
    }));

    it('should autoscroll when expression is missing', inject(function ($state, $q, $uiViewScroll, $animate) {
      elem.append($compile('
<ui-view autoscroll></ui-view>
')(scope));
      $state.transitionTo(aState);
      $q.flush();

      if ($animate) $animate.triggerCallbacks();

      expect($uiViewScroll).toHaveBeenCalledWith(elem.find('span').parent());
    }));

    it('should autoscroll based on expression', inject(function ($state, $q, $uiViewScroll, $animate) {
      scope.doScroll = false;

      elem.append($compile('
<ui-view autoscroll="doScroll"></ui-view>
')(scope));

      $state.transitionTo(aState);
      $q.flush();

      if ($animate) $animate.triggerCallbacks();

      expect($uiViewScroll).not.toHaveBeenCalled();

      scope.doScroll = true;
      $state.transitionTo(bState);
      $q.flush();

      if ($animate) $animate.triggerCallbacks();

      var target,
          index   = -1,
          uiViews = elem.find('ui-view');

      while (index++ < uiViews.length) {
        var uiView = angular.element(uiViews[index]);
        if (uiView.text() === bState.template) target = uiView;
      }

      expect($uiViewScroll).toHaveBeenCalledWith(target);
    }));
  });

  it('should instantiate a controller with controllerAs', inject(function($state, $q) {
    elem.append($compile('
<ui-view>{{vm.someProperty}}</ui-view>
')(scope));
    $state.transitionTo(kState);
    $q.flush();

    expect(elem.text()).toBe('value');
  }));
});
<commit_msg>test(uiView): Added in tests for ngClass, ngRepeat, and animations.<commit_after>/*jshint browser: true, indent: 2 */
/*global describe: false, it: false, beforeEach: false, expect: false, resolvedValue: false, module: false, inject: false, angular: false */

describe('uiView', function () {
  'use strict';

  var scope, $compile, elem;

  beforeEach(function() {
    var depends = ['ui.router'];

    try {
      angular.module('ngAnimate');
      depends.push('ngAnimate', 'ngAnimateMock');
    } catch(e) {
      angular.module('mock.animate', []).value('$animate', null);
      module('mock.animate');
    }

    angular.module('ui.router.test', depends);
    module('ui.router.test');
  });

  beforeEach(module(function ($provide) {
    $provide.decorator('$uiViewScroll', function () {
      return jasmine.createSpy('$uiViewScroll');
    });
  }));

  var aState = {
    template: 'aState template'
  },
  bState = {
    template: 'bState template'
  },
  cState = {
    views: {
      'cview': {
        template: 'cState cview template'
      }
    }
  },
  dState = {
    views: {
      'dview1': {
        template: 'dState dview1 template'
      },
      'dview2': {
        template: 'dState dview2 template'
      }
    }
  },
  eState = {
    template: '

'
  },
  fState = {
    views: {
      'eview': {
        template: 'fState eview template'
      }
    }
  },
  gState = {
    template: '
{{content}}
'
  },
  hState = {
    views: {
      'inner': {
        template: 'hState inner template'
      }
    }
  },
  iState = {
    template: '
'+
        '

{{item}}

'+
      '
'
  },
  jState = {
    template: 'jState'
  },
  kState = {
    controller: function() {
      this.someProperty = "value"
    },
    controllerAs: "vm"
  },
  lState = {
    views: {
      view1: {
        template: 'view1'
      },
      view2: {
        template: 'view2'
      },
      view3: {
        template: 'view3'
      }
    }
  };

  beforeEach(module(function ($stateProvider) {
    $stateProvider
      .state('a', aState)
      .state('b', bState)
      .state('c', cState)
      .state('d', dState)
      .state('e', eState)
      .state('e.f', fState)
      .state('g', gState)
      .state('g.h', hState)
      .state('i', iState)
      .state('j', jState)
      .state('k', kState)
      .state('l', lState)
  }));

  beforeEach(inject(function ($rootScope, _$compile_) {
    scope = $rootScope.$new();
    $compile = _$compile_;
    elem = angular.element('
');
  }));

  describe('linking ui-directive', function () {

    it('anonymous ui-view should be replaced with the template of the current $state', inject(function ($state, $q) {
      elem.append($compile('
<ui-view></ui-view>
')(scope));

      expect(elem.find('ui-view').text()).toBe('');

      $state.transitionTo(aState);
      $q.flush();

      expect(elem.find('ui-view').text()).toBe(aState.template);
    }));

    it('named ui-view should be replaced with the template of the current $state', inject(function ($state, $q) {
      elem.append($compile('
<ui-view name="cview"></ui-view>
')(scope));

      $state.transitionTo(cState);
      $q.flush();

      expect(elem.find('ui-view').text()).toBe(cState.views.cview.template);
    }));

    it('ui-view should be updated after transition to another state', inject(function ($state, $q) {
      elem.append($compile('
<ui-view></ui-view>
')(scope));
      expect(elem.find('ui-view').text()).toBe('');

      $state.transitionTo(aState);
      $q.flush();

      expect(elem.find('ui-view').text()).toBe(aState.template);

      $state.transitionTo(bState);
      $q.flush();

      expect(elem.find('ui-view').text()).toBe(bState.template);
    }));

    it('should handle NOT nested ui-views', inject(function ($state, $q) {
      elem.append($compile('
<ui-view name="dview1" class="dview1"></ui-view><ui-view name="dview2" class="dview2"></ui-view>
')(scope));
      expect(elem.find('ui-view').eq(0).text()).toBe('');
      expect(elem.find('ui-view').eq(1).text()).toBe('');

      $state.transitionTo(dState);
      $q.flush();

      expect(elem.find('ui-view').eq(0).text()).toBe(dState.views.dview1.template);
      expect(elem.find('ui-view').eq(1).text()).toBe(dState.views.dview2.template);
    }));

    it('should handle nested ui-views (testing two levels deep)', inject(function ($state, $q) {
      $compile(elem.append('
<ui-view></ui-view>
'))(scope);
      expect(elem.find('ui-view').text()).toBe('');

      $state.transitionTo(fState);
      $q.flush();

      expect(elem.find('ui-view').text()).toBe(fState.views.eview.template);
    }));
  });

  describe('handling initial view', function () {
    it('initial view should be compiled if the view is empty', inject(function ($state, $q) {
      var content = 'inner content';
      scope.content = content;
      elem.append($compile('
<ui-view></ui-view>
')(scope));

      $state.transitionTo(gState);
      $q.flush();

      expect(elem.find('ui-view').text()).toBe(content);
    }));

    it('initial view should be put back after removal of the view', inject(function ($state, $q) {
      var content = 'inner content';
      scope.content = content;
      elem.append($compile('
<ui-view></ui-view>
')(scope));

      $state.go(hState);
      $q.flush();

      expect(elem.find('ui-view').text()).toBe(hState.views.inner.template);

      // going to the parent state which makes the inner view empty
      $state.go(gState);
      $q.flush();

      expect(elem.find('ui-view').text()).toBe(content);
    }));

    // related to issue #435
    it('initial view should be transcluded once to prevent breaking other directives', inject(function ($state, $q) {
      scope.items = ["I", "am", "a", "list", "of", "items"];

      elem.append($compile('
<ui-view></ui-view>
')(scope));

      // transition to state that has an initial view
      $state.transitionTo(iState);
      $q.flush();

      // verify if ng-repeat has been compiled
      expect(elem.find('li').length).toBe(scope.items.length);

      // transition to another state that replace the initial content
      $state.transitionTo(jState);
      $q.flush();

      expect(elem.find('ui-view').text()).toBe(jState.template);

      // transition back to the state with empty subview and the initial view
      $state.transitionTo(iState);
      $q.flush();

      // verify if the initial view is correct
      expect(elem.find('li').length).toBe(scope.items.length);

      // change scope properties
      scope.$apply(function () {
        scope.items.push(".", "Working?");
      });

      // verify if the initial view has been updated
      expect(elem.find('li').length).toBe(scope.items.length);
    }));
  });

  describe('autoscroll attribute', function () {
    it('should autoscroll when unspecified', inject(function ($state, $q, $uiViewScroll, $animate) {
      elem.append($compile('
<ui-view></ui-view>
')(scope));

      $state.transitionTo(aState);
      $q.flush();

      if ($animate) $animate.triggerCallbacks();

      expect($uiViewScroll).toHaveBeenCalledWith(elem.find('span').parent());
    }));

    it('should autoscroll when expression is missing', inject(function ($state, $q, $uiViewScroll, $animate) {
      elem.append($compile('
<ui-view autoscroll></ui-view>
')(scope));
      $state.transitionTo(aState);
      $q.flush();

      if ($animate) $animate.triggerCallbacks();

      expect($uiViewScroll).toHaveBeenCalledWith(elem.find('span').parent());
    }));

    it('should autoscroll based on expression', inject(function ($state, $q, $uiViewScroll, $animate) {
      scope.doScroll = false;

      elem.append($compile('
<ui-view autoscroll="doScroll"></ui-view>
')(scope));

      $state.transitionTo(aState);
      $q.flush();

      if ($animate) $animate.triggerCallbacks();

      expect($uiViewScroll).not.toHaveBeenCalled();

      scope.doScroll = true;
      $state.transitionTo(bState);
      $q.flush();

      if ($animate) $animate.triggerCallbacks();

      var target,
          index   = -1,
          uiViews = elem.find('ui-view');

      while (index++ < uiViews.length) {
        var uiView = angular.element(uiViews[index]);
        if (uiView.text() === bState.template) target = uiView;
      }

      expect($uiViewScroll).toHaveBeenCalledWith(target);
    }));
  });

  it('should instantiate a controller with controllerAs', inject(function($state, $q) {
    elem.append($compile('
<ui-view>{{vm.someProperty}}</ui-view>
')(scope));
    $state.transitionTo(kState);
    $q.flush();

    expect(elem.text()).toBe('value');
  }));

  describe('play nicely with other directives', function() {
    // related to issue #857
    it('should work with ngIf', inject(function ($state, $q, $compile) {
      // ngIf does not exist in 1.0.8
      if (angular.version.full === '1.0.8') return;

      scope.someBoolean = false;
      elem.append($compile('
<ui-view></ui-view>
')(scope));

      $state.transitionTo(aState);
      $q.flush();

      // Verify there is no ui-view in the DOM
      expect(elem.find('ui-view').length).toBe(0);

      // Turn on the div that holds the ui-view
      scope.someBoolean = true;
      scope.$digest();

      // Verify that the ui-view is there and it has the correct content
      expect(elem.find('ui-view').text()).toBe(aState.template);

      // Turn off the ui-view
      scope.someBoolean = false;
      scope.$digest();

      // Verify there is no ui-view in the DOM
      expect(elem.find('ui-view').length).toBe(0);

      // Turn on the div that holds the ui-view once again
      scope.someBoolean = true;
      scope.$digest();

      // Verify that the ui-view is there and it has the correct content
      expect(elem.find('ui-view').text()).toBe(aState.template);
    }));

    it ('should work with ngClass', inject(function($state, $q, $compile) {
      scope.showClass = false;
      elem.append($compile('
<ui-view ng-class="{\'someClass\': showClass}"></ui-view>
')(scope));

      expect(elem.find('ui-view')).not.toHaveClass('someClass');

      scope.showClass = true;
      scope.$digest();

      expect(elem.find('ui-view')).toHaveClass('someClass');

      scope.showClass = false;
      scope.$digest();

      expect(elem.find('ui-view')).not.toHaveClass('someClass');
    }));

    describe ('working with ngRepeat', function() {
      // ngRepeat does not work properly with uiView in 1.0.8 & 1.1.5
      if (['1.0.8', '1.1.5'].indexOf(angular.version.full) !== -1) return;

      it ('should have correct number of uiViews', inject(function($state, $q, $compile) {
        elem.append($compile('
<ui-view ng-repeat="view in views" name="{{view}}"></ui-view>
')(scope));

        // Should be no ui-views in DOM
        expect(elem.find('ui-view').length).toBe(0);

        // Lets add 3
        scope.views = ['view1', 'view2', 'view3'];
        scope.$digest();

        // Should be 3 ui-views in the DOM
        expect(elem.find('ui-view').length).toBe(scope.views.length);

        // Lets add one more - yay two-way binding
        scope.views.push('view4');
        scope.$digest();

        // Should have 4 ui-views
        expect(elem.find('ui-view').length).toBe(scope.views.length);

        // Lets remove 2 ui-views from the DOM
        scope.views.pop();
        scope.views.pop();
        scope.$digest();

        // Should have 2 ui-views
        expect(elem.find('ui-view').length).toBe(scope.views.length);
      }));

      it ('should populate each view with content', inject(function($state, $q, $compile) {
        elem.append($compile('
<ui-view ng-repeat="view in views" name="{{view}}"></ui-view>
')(scope));

        $state.transitionTo(lState);
        $q.flush();

        expect(elem.find('ui-view').length).toBe(0);

        scope.views = ['view1', 'view2'];

        scope.$digest();

        var uiViews = elem.find('ui-view');

        expect(uiViews.eq(0).text()).toBe(lState.views.view1.template);
        expect(uiViews.eq(1).text()).toBe(lState.views.view2.template);
        expect(uiViews.eq(2).length).toBe(0);

        scope.views.push('view3');
        scope.$digest();

        uiViews = elem.find('ui-view');

        expect(uiViews.eq(0).text()).toBe(lState.views.view1.template);
        expect(uiViews.eq(1).text()).toBe(lState.views.view2.template);
        expect(uiViews.eq(2).text()).toBe(lState.views.view3.template);
      }));
    });
  });

  describe('AngularJS 1.2.* Animations', function() {
    // Only doing tests for AngularJS 1.2.*
    if (['1.0.8', '1.1.5'].indexOf(angular.version.full) !== -1) return;

    it ('should do transition animations', inject(function($state, $q, $compile, $animate) {
      var content = 'Initial Content',
          animation;
      elem.append($compile('
<ui-view>' + content + '</ui-view>
')(scope));

      // Enter Animation
      animation = $animate.queue.shift();
      expect(animation.event).toBe('enter');
      expect(animation.element.text()).toBe(content);

      $state.transitionTo(aState);
      $q.flush();

      // Enter Animation
      animation = $animate.queue.shift();
      expect(animation.event).toBe('enter');
      expect(animation.element.text()).toBe(aState.template);
      // Leave Animation
      animation = $animate.queue.shift();
      expect(animation.event).toBe('leave');
      expect(animation.element.text()).toBe(content);

      $state.transitionTo(bState);
      $q.flush();

      // Enter Animation
      animation = $animate.queue.shift();
      expect(animation.event).toBe('enter');
      expect(animation.element.text()).toBe(bState.template);
      // Leave Animation
      animation = $animate.queue.shift();
      expect(animation.event).toBe('leave');
      expect(animation.element.text()).toBe(aState.template);

      // No more animations
      expect($animate.queue.length).toBe(0);
    }));

    it ('should do ngClass animations', inject(function($state, $q, $compile, $animate) {
      scope.classOn = false;
      var content = 'Initial Content',
          className = 'yay',
          animation;
      elem.append($compile('
<ui-view ng-class="{\'' + className + '\': classOn}">' + content + '</ui-view>
')(scope));
      // Don't care about enter class
      $animate.queue.shift();

      scope.classOn = true;
      scope.$digest();

      animation = $animate.queue.shift();
      expect(animation.event).toBe('addClass');
      expect(animation.element.text()).toBe(content);

      scope.classOn = false;
      scope.$digest();

      animation = $animate.queue.shift();
      expect(animation.event).toBe('removeClass');
      expect(animation.element.text()).toBe(content);

      // No more animations
      expect($animate.queue.length).toBe(0);
    }));

    it ('should do ngIf animations', inject(function($state, $q, $compile, $animate) {
      scope.shouldShow = false;
      var content = 'Initial Content',
          animation;
      elem.append($compile('
<ui-view ng-if="shouldShow">' + content + '</ui-view>
')(scope));

      // No animations yet
      expect($animate.queue.length).toBe(0);

      scope.shouldShow = true;
      scope.$digest();

      // $ViewDirective enter animation - Basically it's just the  comment
      animation = $animate.queue.shift();
      expect(animation.event).toBe('enter');
      expect(animation.element.text()).toBe('');

      // $ViewDirectiveFill enter animation - The second uiView directive that files in the content
      animation = $animate.queue.shift();
      expect(animation.event).toBe('enter');
      expect(animation.element.text()).toBe(content);

      scope.shouldShow = false;
      scope.$digest();

      // uiView leave animation
      animation = $animate.queue.shift();
      expect(animation.event).toBe('leave');
      expect(animation.element.text()).toBe(content);

      // No more animations
      expect($animate.queue.length).toBe(0);
    }));
  });
});
<|endoftext|>


<commit_before>/* global jasmine,describe,it,expect,beforeEach,inject */
describe('angular autodisable', function() {
  'use strict';

  it('should pass', function() {
    expect(true).toBe(true);
    expect(false).toBe(!true);
  });

  describe('directive', function() {
    var $compile, $rootScope;

    beforeEach(module('ngAutodisable'));

    beforeEach(inject(function(_$compile_, _$rootScope_) {
      $compile   = _$compile_;
      $rootScope = _$rootScope_;
    }));

    function compile(html) {
      var el = $compile(html)($rootScope);
      $rootScope.$apply();
      return el;
    }

    it('should throw if no ng-submit is defined', function() {
      expect(function() {
        compile('<form ng-autodisable> <button type="submit"></button> </form>');
      }).toThrow('ngAutodisable requires ngClick or ngSubmit attribute in order to work');
    });

    it('should only call the handler once', function() {
      $rootScope.clickHandler = jasmine.createSpy();
      var el = compile('<form ng-submit="clickHandler()" ng-autodisable> <button type="submit"></button> </form>');
      el.find('button[type=submit]').click();
      expect($rootScope.clickHandler.callCount).toBe(1);
    });

    it('should trigger $scope.$apply when calling the handler', function() {
      $rootScope.clickHandler = function() {
        $rootScope.data = 'hello';
      };
      var el = compile('<form ng-submit="clickHandler()" ng-autodisable> {{ data }} <button type="submit"></button> </form>');
      el.find('button[type=submit]').click();
      expect(el.find('span').text()).toEqual('hello');
    });

    describe('multiple handlers', function() {
      it('should trigger both handlers', function() {
        $rootScope.firstHandler  = jasmine.createSpy();
        $rootScope.secondHandler = jasmine.createSpy();
        var el = compile('<form ng-submit="firstHandler();secondHandler()" ng-autodisable> <button type="submit"></button> </form>');
        el.find('button[type=submit]').click();
        expect($rootScope.firstHandler).toHaveBeenCalled();
        expect($rootScope.secondHandler).toHaveBeenCalled();
      });

      it('should trigger $scope.$apply when calling the handler', function() {
        $rootScope.firstHandler = function() {};
        $rootScope.secondHandler = function() {
          $rootScope.data = 'hello';
        };
        var el = compile('<form ng-submit="firstHandler();secondHandler()" ng-autodisable> {{ data }} <button type="submit"></button> </form>');
        el.find('button[type=submit]').click();
        expect(el.find('span').text()).toEqual('hello');
      });

      it('should disable the button if at least one ngSubmit handler returns $q promise', inject(function($q) {
        $rootScope.defaultHandler = function() {};
        $rootScope.promiseHandler = function() {
          var defer = $q.defer();
          return defer.promise;
        };
        var el = compile('<form ng-submit="defaultHandler();promiseHandler()" ng-autodisable> <button type="submit"></button> </form>');
        el.find('button[type=submit]').click();
        expect(el.find('button[type=submit]').attr('disabled')).toBeDefined();
      }));

      it('should not enable the button if the last promise resolves before others', inject(function($q) {
        var defer1 = $q.defer();
        var defer2 = $q.defer();
        $rootScope.firstHandler = function() {
          return defer1.promise;
        };
        $rootScope.secondHandler = function() {
          return defer2.promise;
        };
        var el = compile('<form ng-submit="firstHandler();secondHandler()" ng-autodisable> <button type="submit"></button> </form>');
        el.find('button[type=submit]').click();

        defer2.resolve();
        $rootScope.$apply();

        expect(el.find('button[type=submit]').attr('disabled')).toBeDefined();
      }));

      it('should not enable the button if the last promise resolves before others', inject(function($q) {
        var defer1 = $q.defer();
        var defer2 = $q.defer();
        $rootScope.firstHandler = function() {
          return defer1.promise;
        };
        $rootScope.secondHandler = function() {
          return defer2.promise;
        };
        var el = compile('<form ng-submit="firstHandler();secondHandler()" ng-autodisable> <button type="submit"></button> </form>');
        el.find('button[type=submit]').click();

        defer2.resolve();
        $rootScope.$apply();

        expect(el.find('button[type=submit]').attr('disabled')).toBeDefined();
      }));

      it('should enable the button if the all promises resolve', inject(function($q) {
        var defer1 = $q.defer();
        var defer2 = $q.defer();
        $rootScope.firstHandler = function() {
          return defer1.promise;
        };
        $rootScope.secondHandler = function() {
          return defer2.promise;
        };
        var el = compile('<form ng-submit="firstHandler();secondHandler()" ng-autodisable> <button type="submit"></button> </form>');
        el.find('button[type=submit]').click();

        defer2.resolve();
        $rootScope.$apply();

        defer1.resolve();
        $rootScope.$apply();
        expect(el.find('button[type=submit]').attr('disabled')).not.toBeDefined();
      }));
    });

    describe('loading class', function() {
      it('should add a class to the button if the promise is not resolved', inject(function($q) {
        $rootScope.clickHandler = function() {
          var defer = $q.defer();
          return defer.promise;
        };
        var el = compile('<form ng-submit="clickHandler()" ng-autodisable-class="loading" ng-autodisable> <button type="submit"></button> </form>');
        el.find('button[type=submit]').click();
        expect(el.find('button[type=submit]').hasClass('loading')).toBe(true);
      }));

      it('should add multiple class to the button if the promise is not resolved', inject(function($q) {
        $rootScope.clickHandler = function() {
          var defer = $q.defer();
          return defer.promise;
        };
        var el = compile('<form ng-submit="clickHandler()" ng-autodisable-class="firstClass secondClass" ng-autodisable> <button type="submit"></button> </form>');
        el.find('button[type=submit]').click();
        expect(el.find('button[type=submit]').hasClass('firstClass')).toBe(true);
        expect(el.find('button[type=submit]').hasClass('secondClass')).toBe(true);
      }));

      it('should remove the classes to the button if the promise is resolved', inject(function($q) {
        var defer = $q.defer();
        $rootScope.clickHandler = function() {
          return defer.promise;
        };
        var el = compile('<form ng-submit="clickHandler()" ng-autodisable-class="firstClass secondClass" ng-autodisable> <button type="submit"></button> </form>');
        el.find('button[type=submit]').click();
        defer.resolve('resolved');
        $rootScope.$apply();
        expect(el.find('button[type=submit]').hasClass('firstClass')).toBe(false);
        expect(el.find('button[type=submit]').hasClass('secondClass')).toBe(false);
      }));
    });

    describe('http promise', function() {
      it('should disable the button if ngClick returns HTTP promise', inject(function($http, $httpBackend) {
        $rootScope.clickHandler = function() {
          $httpBackend.expectGET('/').respond(200);
          return $http.get('/');
        };
        var el = compile('<form ng-submit="clickHandler()" ng-autodisable> <button type="submit"></button> </form>');
        el.find('button[type=submit]').click();
        expect(el.find('button[type=submit]').attr('disabled')).toBeDefined();
        $httpBackend.flush();
      }));

      it('should enable the button if ngClick returns HTTP promise resolves', inject(function($http, $httpBackend) {
        $rootScope.clickHandler = function() {
          $httpBackend.expectGET('/').respond(200);
          return $http.get('/');
        };
        var el = compile('<form ng-submit="clickHandler()" ng-autodisable> <button type="submit"></button> </form>');
        el.find('button[type=submit]').click();
        $httpBackend.flush();
        expect(el.find('button[type=submit]').attr('disabled')).not.toBeDefined();
      }));

      it('should enable the button if ngClick returns HTTP promise resolves with an error', inject(function($http, $httpBackend) {
        $rootScope.clickHandler = function() {
          $httpBackend.expectGET('/').respond(400);
          return $http.get('/');
        };
        var el = compile('<form ng-submit="clickHandler()" ng-autodisable> <button type="submit"></button> </form>');
        el.find('button[type=submit]').click();
        $httpBackend.flush();
        expect(el.find('button[type=submit]').attr('disabled')).not.toBeDefined();
      }));
    });

    describe('$q promise', function() {
      it('should disable the button if ngClick returns $q promise', inject(function($q) {
        $rootScope.clickHandler = function() {
          var defer = $q.defer();
          return defer.promise;
        };
        var el = compile('<form ng-submit="clickHandler()" ng-autodisable> <button type="submit"></button> </form>');
        el.find('button[type=submit]').click();
        expect(el.find('button[type=submit]').attr('disabled')).toBeDefined();
      }));

      it('should remove disabled after the promise is resolved with success', inject(function($q) {
        var defer = $q.defer();
        $rootScope.clickHandler = function() {
          return defer.promise;
        };
        var el = compile('<form ng-submit="clickHandler()" ng-autodisable> <button type="submit"></button> </form>');
        el.find('button[type=submit]').click();
        defer.resolve('resolved');
        $rootScope.$apply();
        expect(el.find('button[type=submit]').attr('disabled')).not.toBeDefined();
      }));

      it('should remove disabled after the promise is resolved with error', inject(function($q) {
        var defer = $q.defer();
        $rootScope.clickHandler = function() {
          return defer.promise;
        };
        var el = compile('<form ng-submit="clickHandler()" ng-autodisable> <button type="submit"></button> </form>');
        el.find('button[type=submit]').click();
        defer.reject('resolved');
        $rootScope.$apply();
        expect(el.find('button[type=submit]').attr('disabled')).not.toBeDefined();
      }));

      it('should not disable the button if it does not return button promise', function() {
        $rootScope.clickHandler = function() { return true; };
        var el = compile('<form ng-submit="clickHandler()" ng-autodisable> <button type="submit"></button> </form>');
        el.find('button[type=submit]').click();
        expect(el.find('button[type=submit]').attr('disabled')).not.toBeDefined();
      });
    });
  });

});
<commit_msg>Issue #8 : Add test exposing issue.<commit_after>/* global jasmine,describe,it,expect,beforeEach,inject */
describe('angular autodisable', function() {
  'use strict';

  it('should pass', function() {
    expect(true).toBe(true);
    expect(false).toBe(!true);
  });

  describe('directive', function() {
    var $compile, $rootScope;

    beforeEach(module('ngAutodisable'));

    beforeEach(inject(function(_$compile_, _$rootScope_) {
      $compile   = _$compile_;
      $rootScope = _$rootScope_;
    }));

    function compile(html) {
      var el = $compile(html)($rootScope);
      $rootScope.$apply();
      return el;
    }

    it('should throw if no ng-submit is defined', function() {
      expect(function() {
        compile('<form ng-autodisable> <button type="submit"></button> </form>');
      }).toThrow('ngAutodisable requires ngClick or ngSubmit attribute in order to work');
    });

    it('should only call the handler once', function() {
      $rootScope.clickHandler = jasmine.createSpy();
      var el = compile('<form ng-submit="clickHandler()" ng-autodisable> <button type="submit"></button> </form>');
      el.find('button[type=submit]').click();
      expect($rootScope.clickHandler.callCount).toBe(1);
    });

    it('should handle more than one directive type', inject(function($q) {
      var defer1 = $q.defer();

      $rootScope.firstHandler = function() {
        return defer1.promise;
      };
      $rootScope.secondHandler = jasmine.createSpy();
      var el = compile('<form ng-submit="firstHandler()" ng-autodisable> <button id="formButton" type="submit"></button> </form><button id="simpleButton" ng-click="secondHandler()" ng-autodisable></button');
      el.find('#formButton').click();

      expect(el.find('#formButton').attr('disabled')).toBeDefined();
      expect(el.find('#simpleButton').attr('disabled')).not.toBeDefined();
    }));

    it('should trigger $scope.$apply when calling the handler', function() {
      $rootScope.clickHandler = function() {
        $rootScope.data = 'hello';
      };
      var el = compile('<form ng-submit="clickHandler()" ng-autodisable> {{ data }} <button type="submit"></button> </form>');
      el.find('button[type=submit]').click();
      expect(el.find('span').text()).toEqual('hello');
    });

    describe('multiple handlers', function() {
      it('should trigger both handlers', function() {
        $rootScope.firstHandler  = jasmine.createSpy();
        $rootScope.secondHandler = jasmine.createSpy();
        var el = compile('<form ng-submit="firstHandler();secondHandler()" ng-autodisable> <button type="submit"></button> </form>');
        el.find('button[type=submit]').click();
        expect($rootScope.firstHandler).toHaveBeenCalled();
        expect($rootScope.secondHandler).toHaveBeenCalled();
      });

      it('should trigger $scope.$apply when calling the handler', function() {
        $rootScope.firstHandler = function() {};
        $rootScope.secondHandler = function() {
          $rootScope.data = 'hello';
        };
        var el = compile('<form ng-submit="firstHandler();secondHandler()" ng-autodisable> {{ data }} <button type="submit"></button> </form>');
        el.find('button[type=submit]').click();
        expect(el.find('span').text()).toEqual('hello');
      });

      it('should disable the button if at least one ngSubmit handler returns $q promise', inject(function($q) {
        $rootScope.defaultHandler = function() {};
        $rootScope.promiseHandler = function() {
          var defer = $q.defer();
          return defer.promise;
        };
        var el = compile('<form ng-submit="defaultHandler();promiseHandler()" ng-autodisable> <button type="submit"></button> </form>');
        el.find('button[type=submit]').click();
        expect(el.find('button[type=submit]').attr('disabled')).toBeDefined();
      }));

      it('should not enable the button if the last promise resolves before others', inject(function($q) {
        var defer1 = $q.defer();
        var defer2 = $q.defer();
        $rootScope.firstHandler = function() {
          return defer1.promise;
        };
        $rootScope.secondHandler = function() {
          return defer2.promise;
        };
        var el = compile('<form ng-submit="firstHandler();secondHandler()" ng-autodisable> <button type="submit"></button> </form>');
        el.find('button[type=submit]').click();

        defer2.resolve();
        $rootScope.$apply();

        expect(el.find('button[type=submit]').attr('disabled')).toBeDefined();
      }));

      it('should not enable the button if the last promise resolves before others', inject(function($q) {
        var defer1 = $q.defer();
        var defer2 = $q.defer();
        $rootScope.firstHandler = function() {
          return defer1.promise;
        };
        $rootScope.secondHandler = function() {
          return defer2.promise;
        };
        var el = compile('<form ng-submit="firstHandler();secondHandler()" ng-autodisable> <button type="submit"></button> </form>');
        el.find('button[type=submit]').click();

        defer2.resolve();
        $rootScope.$apply();

        expect(el.find('button[type=submit]').attr('disabled')).toBeDefined();
      }));

      it('should enable the button if the all promises resolve', inject(function($q) {
        var defer1 = $q.defer();
        var defer2 = $q.defer();
        $rootScope.firstHandler = function() {
          return defer1.promise;
        };
        $rootScope.secondHandler = function() {
          return defer2.promise;
        };
        var el = compile('<form ng-submit="firstHandler();secondHandler()" ng-autodisable> <button type="submit"></button> </form>');
        el.find('button[type=submit]').click();

        defer2.resolve();
        $rootScope.$apply();

        defer1.resolve();
        $rootScope.$apply();
        expect(el.find('button[type=submit]').attr('disabled')).not.toBeDefined();
      }));
    });

    describe('loading class', function() {
      it('should add a class to the button if the promise is not resolved', inject(function($q) {
        $rootScope.clickHandler = function() {
          var defer = $q.defer();
          return defer.promise;
        };
        var el = compile('<form ng-submit="clickHandler()" ng-autodisable-class="loading" ng-autodisable> <button type="submit"></button> </form>');
        el.find('button[type=submit]').click();
        expect(el.find('button[type=submit]').hasClass('loading')).toBe(true);
      }));

      it('should add multiple class to the button if the promise is not resolved', inject(function($q) {
        $rootScope.clickHandler = function() {
          var defer = $q.defer();
          return defer.promise;
        };
        var el = compile('<form ng-submit="clickHandler()" ng-autodisable-class="firstClass secondClass" ng-autodisable> <button type="submit"></button> </form>');
        el.find('button[type=submit]').click();
        expect(el.find('button[type=submit]').hasClass('firstClass')).toBe(true);
        expect(el.find('button[type=submit]').hasClass('secondClass')).toBe(true);
      }));

      it('should remove the classes to the button if the promise is resolved', inject(function($q) {
        var defer = $q.defer();
        $rootScope.clickHandler = function() {
          return defer.promise;
        };
        var el = compile('<form ng-submit="clickHandler()" ng-autodisable-class="firstClass secondClass" ng-autodisable> <button type="submit"></button> </form>');
        el.find('button[type=submit]').click();
        defer.resolve('resolved');
        $rootScope.$apply();
        expect(el.find('button[type=submit]').hasClass('firstClass')).toBe(false);
        expect(el.find('button[type=submit]').hasClass('secondClass')).toBe(false);
      }));
    });

    describe('http promise', function() {
      it('should disable the button if ngClick returns HTTP promise', inject(function($http, $httpBackend) {
        $rootScope.clickHandler = function() {
          $httpBackend.expectGET('/').respond(200);
          return $http.get('/');
        };
        var el = compile('<form ng-submit="clickHandler()" ng-autodisable> <button type="submit"></button> </form>');
        el.find('button[type=submit]').click();
        expect(el.find('button[type=submit]').attr('disabled')).toBeDefined();
        $httpBackend.flush();
      }));

      it('should enable the button if ngClick returns HTTP promise resolves', inject(function($http, $httpBackend) {
        $rootScope.clickHandler = function() {
          $httpBackend.expectGET('/').respond(200);
          return $http.get('/');
        };
        var el = compile('<form ng-submit="clickHandler()" ng-autodisable> <button type="submit"></button> </form>');
        el.find('button[type=submit]').click();
        $httpBackend.flush();
        expect(el.find('button[type=submit]').attr('disabled')).not.toBeDefined();
      }));

      it('should enable the button if ngClick returns HTTP promise resolves with an error', inject(function($http, $httpBackend) {
        $rootScope.clickHandler = function() {
          $httpBackend.expectGET('/').respond(400);
          return $http.get('/');
        };
        var el = compile('<form ng-submit="clickHandler()" ng-autodisable> <button type="submit"></button> </form>');
        el.find('button[type=submit]').click();
        $httpBackend.flush();
        expect(el.find('button[type=submit]').attr('disabled')).not.toBeDefined();
      }));
    });

    describe('$q promise', function() {
      it('should disable the button if ngClick returns $q promise', inject(function($q) {
        $rootScope.clickHandler = function() {
          var defer = $q.defer();
          return defer.promise;
        };
        var el = compile('<form ng-submit="clickHandler()" ng-autodisable> <button type="submit"></button> </form>');
        el.find('button[type=submit]').click();
        expect(el.find('button[type=submit]').attr('disabled')).toBeDefined();
      }));

      it('should remove disabled after the promise is resolved with success', inject(function($q) {
        var defer = $q.defer();
        $rootScope.clickHandler = function() {
          return defer.promise;
        };
        var el = compile('<form ng-submit="clickHandler()" ng-autodisable> <button type="submit"></button> </form>');
        el.find('button[type=submit]').click();
        defer.resolve('resolved');
        $rootScope.$apply();
        expect(el.find('button[type=submit]').attr('disabled')).not.toBeDefined();
      }));

      it('should remove disabled after the promise is resolved with error', inject(function($q) {
        var defer = $q.defer();
        $rootScope.clickHandler = function() {
          return defer.promise;
        };
        var el = compile('<form ng-submit="clickHandler()" ng-autodisable> <button type="submit"></button> </form>');
        el.find('button[type=submit]').click();
        defer.reject('resolved');
        $rootScope.$apply();
        expect(el.find('button[type=submit]').attr('disabled')).not.toBeDefined();
      }));

      it('should not disable the button if it does not return button promise', function() {
        $rootScope.clickHandler = function() { return true; };
        var el = compile('<form ng-submit="clickHandler()" ng-autodisable> <button type="submit"></button> </form>');
        el.find('button[type=submit]').click();
        expect(el.find('button[type=submit]').attr('disabled')).not.toBeDefined();
      });
    });
  });

});
<|endoftext|>


<commit_before>const request = require('supertest');

const {
    createLicenceServiceStub,
    createApp,
    formConfig,
    testFormPageGets
} = require('../supertestSetup');

describe('/hdc/proposedAddress', () => {
    describe('proposed address routes', () => {
        const licenceService = createLicenceServiceStub();
        licenceService.getLicence = sinon.stub().resolves({
            licence: {
                proposedAddress: {
                    curfewAddress: {
                        addresses: [
                            {
                                addressLine1: 'line1',
                                consent: 'No'
                            },
                            {
                                addressLine1: 'line2',
                                consent: 'Yes',
                                electricity: 'Yes',
                                deemedSafe: 'No'
                            },
                            {
                                addressLine1: 'line3'
                            }
                        ]
                    }
                }
            },
            stage: 'ELIGIBILITY'
        });

        const app = createApp({licenceService});

        const routes = [
            {url: '/hdc/proposedAddress/optOut/1', content: 'decided to opt out'},
            {url: '/hdc/proposedAddress/addressProposed/1', content: 'proposed a curfew address?'},
            {url: '/hdc/proposedAddress/bassReferral/1', content: 'BASS referral'},
            {url: '/hdc/proposedAddress/curfewAddress/1', content: 'Proposed curfew address'}
        ];

        testFormPageGets(app, routes, licenceService);
    });

    describe('POST /hdc/proposedAddress/:section/:bookingId', () => {
        const routes = [
            {
                url: '/hdc/proposedAddress/optOut/1',
                body: {bookingId: 1, decision: 'Yes'},
                section: 'optOut',
                nextPath: '/hdc/taskList/1',
                user: 'caUser'
            },
            {
                url: '/hdc/proposedAddress/optOut/1',
                body: {bookingId: 1, decision: 'No'},
                section: 'optOut',
                nextPath: '/hdc/proposedAddress/addressProposed/1',
                user: 'caUser'
            },
            {
                url: '/hdc/proposedAddress/addressProposed/1',
                body: {bookingId: 1, decision: 'Yes'},
                section: 'addressProposed',
                nextPath: '/hdc/proposedAddress/curfewAddress/1',
                user: 'caUser'
            },
            {
                url: '/hdc/proposedAddress/addressProposed/1',
                body: {bookingId: 1, decision: 'No'},
                section: 'addressProposed',
                nextPath: '/hdc/proposedAddress/bassReferral/1',
                user: 'caUser'
            },
            {
                url: '/hdc/proposedAddress/bassReferral/1',
                body: {bookingId: 1},
                section: 'bassReferral',
                nextPath: '/hdc/taskList/1',
                user: 'caUser'
            },
            {
                url: '/hdc/proposedAddress/curfewAddress/1',
                body: {bookingId: 1},
                section: 'curfewAddress',
                nextPath: '/hdc/taskList/1',
                user: 'caUser'
            }
        ];

        routes.forEach(route => {
            it(`renders the correct path '${route.nextPath}' page`, () => {
                const licenceService = createLicenceServiceStub();
                const app = createApp({licenceService});

                return request(app)
                    .post(route.url)
                    .send(route.body)
                    .expect(302)
                    .expect(res => {
                        expect(licenceService.update).to.be.calledOnce();
                        expect(licenceService.update).to.be.calledWith({
                            bookingId: '1',
                            config: formConfig[route.section],
                            userInput: route.body,
                            licenceSection: 'proposedAddress',
                            formName: route.section
                        });

                        expect(res.header.location).to.equal(route.nextPath);
                    });
            });

            it('throws an error if logged in as dm', () => {
                const licenceService = createLicenceServiceStub();
                const app = createApp({licenceService}, 'dmUser');

                return request(app)
                    .post(route.url)
                    .send(route.body)
                    .expect(403);

            });

            it('throws an error if logged in as ro except for curfew address', () => {
                const licenceService = createLicenceServiceStub();
                const app = createApp({licenceService}, 'roUser');

                if (route.url === '/hdc/proposedAddress/curfewAddress/1') {
                    return request(app)
                        .post(route.url)
                        .send(route.body)
                        .expect(302);
                }

                return request(app)
                    .post(route.url)
                    .send(route.body)
                    .expect(403);

            });
        });

        it('should redirect back to optOut page if there is an error in the submission', () => {
            const licenceService = createLicenceServiceStub();
            licenceService.getValidationErrorsForPage = sinon.stub().returns({
                proposedAddress: {
                    optOut: {
                        reason: 'error'
                    }
                }
            });
            const app = createApp({licenceService});

            return request(app)
                .post('/hdc/proposedAddress/optOut/1')
                .send({})
                .expect(302)
                .expect('Location', '/hdc/proposedAddress/optOut/1');

        });
    });

    describe('curfewAddress', () => {
        context('there is a rejected address and active', () => {
            it('should display the active and post to update', () => {
                const licenceService = createLicenceServiceStub();
                licenceService.getLicence.resolves({
                    licence: {
                        proposedAddress: {
                            curfewAddress: {
                                addresses: [
                                    {addressLine1: 'address1', consent: 'No', electricity: 'No', deemedSafe: 'No'},
                                    {addressLine1: 'address2'}
                                ]
                            }
                        }
                    }
                });
                const app = createApp({licenceService});

                return request(app)
                    .get('/hdc/proposedAddress/curfewAddress/1')
                    .expect(200)
                    .expect('Content-Type', /html/)
                    .expect(res => {
                        expect(res.text).to.include('/proposedAddress/curfewAddress/update/');
                        expect(res.text).to.include('name="[addresses][0][addressLine1]" value="address2"');
                    });

            });
        });

        context('there are no addresses saved', () => {
            it('should post to standard route', () => {
                const licenceService = createLicenceServiceStub();
                licenceService.getLicence = sinon.stub().resolves({
                    licence: { }
                });

                const app = createApp({licenceService});

                return request(app)
                    .get('/hdc/proposedAddress/curfewAddress/1')
                    .expect(200)
                    .expect('Content-Type', /html/)
                    .expect(res => {
                        expect(res.text).to.include('<form method="post">');
                        expect(res.text).to.include('name="[addresses][0][addressLine1]"/>');
                    });

            });
        });

        context('there are only rejected addresses', () => {
            it('should display no address and post to add', () => {
                const licenceService = createLicenceServiceStub();
                licenceService.getLicence = sinon.stub().resolves({
                    licence: {
                        proposedAddress: {
                            curfewAddress: {
                                addresses: [
                                    {addressLine1: 'address1', consent: 'No', electricity: 'No', deemedSafe: 'No'}
                                ]
                            }
                        }
                    }
                });
                const app = createApp({licenceService});

                return request(app)
                    .get('/hdc/proposedAddress/curfewAddress/1')
                    .expect(200)
                    .expect('Content-Type', /html/)
                    .expect(res => {
                        expect(res.text).to.include('/proposedAddress/curfewAddress/add');
                        expect(res.text).to.include('name="[addresses][0][addressLine1]"/>');
                    });

            });
        });

        context('there are only active addresses', () => {
            it('should display the active address', () => {
                const licenceService = createLicenceServiceStub();
                licenceService.getLicence = sinon.stub().resolves({
                    licence: {
                        proposedAddress: {
                            curfewAddress: {
                                addresses: [
                                    {addressLine1: 'address1'}
                                ]
                            }
                        }
                    }
                });
                const app = createApp({licenceService});

                return request(app)
                    .get('/hdc/proposedAddress/curfewAddress/1')
                    .expect(200)
                    .expect('Content-Type', /html/)
                    .expect(res => {
                        expect(res.text).to.include(
                            '<form method="post" action="/hdc/proposedAddress/curfewAddress/update/1">');
                        expect(res.text).to.include('name="[addresses][0][addressLine1]" value="address1"/>');
                    });

            });
        });
    });

    describe('rejected', () => {
        it('should display the rejected address', () => {
            const licenceService = createLicenceServiceStub();
            licenceService.getLicence = sinon.stub().resolves({
                licence: {
                    proposedAddress: {
                        curfewAddress: {
                            addresses: [
                                {addressLine1: 'address1', consent: 'No'}
                            ]
                        }
                    }
                }
            });
            const app = createApp({licenceService});

            return request(app)
                .get('/hdc/proposedAddress/rejected/1')
                .expect(200)
                .expect('Content-Type', /html/)
                .expect(res => {
                    expect(res.text).to.include('id="rejectedLine1">address1</p>');
                });

        });

        it('should show the form to enter new address', () => {
            const licenceService = createLicenceServiceStub();

            licenceService.getLicence.resolves({
                licence: {
                    proposedAddress: {
                        curfewAddress: {
                            addresses: [
                                {addressLine1: 'address1', consent: 'No'},
                                {addressLine1: 'alt1'}
                            ]
                        }
                    }
                }
            });
            const app = createApp({licenceService});

            return request(app)
                .get('/hdc/proposedAddress/rejected/1')
                .expect(200)
                .expect('Content-Type', /html/)
                .expect(res => {
                    expect(res.text).to.include('<form id="enterAlternativeForm" method="post">');
                });
        });

        it('should redirect to task list if not in ELIGIBILITY stage', () => {
            const licenceService = createLicenceServiceStub();
            licenceService.getLicence.resolves({
                licence: {
                    proposedAddress: {
                        curfewAddress: {
                            addresses: [
                                {addressLine1: 'address1', consent: 'No'}
                            ]
                        }
                    }
                },
                stage: 'PROCESSING_CA'
            });

            const app = createApp({licenceService});

            return request(app)
                .post('/hdc/proposedAddress/curfewAddress/add/1')
                .send({bookingId: '1', addresses: [{addressLine1: 'something'}]})
                .expect(302)
                .expect('Location', '/hdc/taskList/1');

        });

        it('should redirect to form if empty address is passed in', () => {
            const licenceService = createLicenceServiceStub();
            licenceService.getLicence.resolves({
                licence: {
                    proposedAddress: {
                        curfewAddress: {
                            addresses: [
                                {addressLine1: 'address1', consent: 'No'}
                            ]
                        }
                    }
                },
                stage: 'PROCESSING_CA'
            });

            const app = createApp({licenceService});

            return request(app)
                .post('/hdc/proposedAddress/curfewAddress/add/1')
                .send({bookingId: '1', addresses: [{addressLine1: '', postCode: '', addressLine2: ''}]})
                .expect(302)
                .expect('Location', '/hdc/proposedAddress/curfewAddress/1');

        });
    });
});
<commit_msg>Fix test<commit_after>const request = require('supertest');

const {
    createLicenceServiceStub,
    createApp,
    formConfig,
    testFormPageGets
} = require('../supertestSetup');

describe('/hdc/proposedAddress', () => {
    describe('proposed address routes', () => {
        const licenceService = createLicenceServiceStub();
        licenceService.getLicence = sinon.stub().resolves({
            licence: {
                proposedAddress: {
                    curfewAddress: {
                        addresses: [
                            {
                                addressLine1: 'line1',
                                consent: 'No'
                            },
                            {
                                addressLine1: 'line2',
                                consent: 'Yes',
                                electricity: 'Yes',
                                deemedSafe: 'No'
                            },
                            {
                                addressLine1: 'line3'
                            }
                        ]
                    }
                }
            },
            stage: 'ELIGIBILITY'
        });

        const app = createApp({licenceService});

        const routes = [
            {url: '/hdc/proposedAddress/optOut/1', content: 'decided to opt out'},
            {url: '/hdc/proposedAddress/addressProposed/1', content: 'proposed a curfew address?'},
            {url: '/hdc/proposedAddress/bassReferral/1', content: 'BASS referral'},
            {url: '/hdc/proposedAddress/curfewAddress/1', content: 'Proposed curfew address'}
        ];

        testFormPageGets(app, routes, licenceService);
    });

    describe('POST /hdc/proposedAddress/:section/:bookingId', () => {
        const routes = [
            {
                url: '/hdc/proposedAddress/optOut/1',
                body: {bookingId: 1, decision: 'Yes'},
                section: 'optOut',
                nextPath: '/hdc/taskList/1',
                user: 'caUser'
            },
            {
                url: '/hdc/proposedAddress/optOut/1',
                body: {bookingId: 1, decision: 'No'},
                section: 'optOut',
                nextPath: '/hdc/proposedAddress/addressProposed/1',
                user: 'caUser'
            },
            {
                url: '/hdc/proposedAddress/addressProposed/1',
                body: {bookingId: 1, decision: 'Yes'},
                section: 'addressProposed',
                nextPath: '/hdc/proposedAddress/curfewAddress/1',
                user: 'caUser'
            },
            {
                url: '/hdc/proposedAddress/addressProposed/1',
                body: {bookingId: 1, decision: 'No'},
                section: 'addressProposed',
                nextPath: '/hdc/proposedAddress/bassReferral/1',
                user: 'caUser'
            },
            {
                url: '/hdc/proposedAddress/bassReferral/1',
                body: {bookingId: 1},
                section: 'bassReferral',
                nextPath: '/hdc/taskList/1',
                user: 'caUser'
            },
            {
                url: '/hdc/proposedAddress/curfewAddress/1',
                body: {bookingId: 1},
                section: 'curfewAddress',
                nextPath: '/hdc/taskList/1',
                user: 'caUser'
            }
        ];

        routes.forEach(route => {
            it(`renders the correct path '${route.nextPath}' page`, () => {
                const licenceService = createLicenceServiceStub();
                const app = createApp({licenceService});

                return request(app)
                    .post(route.url)
                    .send(route.body)
                    .expect(302)
                    .expect(res => {
                        expect(licenceService.update).to.be.calledOnce();
                        expect(licenceService.update).to.be.calledWith({
                            bookingId: '1',
                            config: formConfig[route.section],
                            userInput: route.body,
                            licenceSection: 'proposedAddress',
                            formName: route.section
                        });

                        expect(res.header.location).to.equal(route.nextPath);
                    });
            });

            it('throws an error if logged in as dm', () => {
                const licenceService = createLicenceServiceStub();
                const app = createApp({licenceService}, 'dmUser');

                return request(app)
                    .post(route.url)
                    .send(route.body)
                    .expect(403);

            });

            it('throws an error if logged in as ro except for curfew address', () => {
                const licenceService = createLicenceServiceStub();
                const app = createApp({licenceService}, 'roUser');

                if (route.url === '/hdc/proposedAddress/curfewAddress/1') {
                    return request(app)
                        .post(route.url)
                        .send(route.body)
                        .expect(302);
                }

                return request(app)
                    .post(route.url)
                    .send(route.body)
                    .expect(403);

            });
        });

        it('should redirect back to optOut page if there is an error in the submission', () => {
            const licenceService = createLicenceServiceStub();
            licenceService.getValidationErrorsForPage = sinon.stub().returns({
                proposedAddress: {
                    optOut: {
                        reason: 'error'
                    }
                }
            });
            const app = createApp({licenceService});

            return request(app)
                .post('/hdc/proposedAddress/optOut/1')
                .send({})
                .expect(302)
                .expect('Location', '/hdc/proposedAddress/optOut/1');

        });
    });

    describe('curfewAddress', () => {
        context('there is a rejected address and active', () => {
            it('should display the active and post to update', () => {
                const licenceService = createLicenceServiceStub();
                licenceService.getLicence.resolves({
                    licence: {
                        proposedAddress: {
                            curfewAddress: {
                                addresses: [
                                    {addressLine1: 'address1', consent: 'No', electricity: 'No', deemedSafe: 'No'},
                                    {addressLine1: 'address2'}
                                ]
                            }
                        }
                    }
                });
                const app = createApp({licenceService});

                return request(app)
                    .get('/hdc/proposedAddress/curfewAddress/1')
                    .expect(200)
                    .expect('Content-Type', /html/)
                    .expect(res => {
                        expect(res.text).to.include('/proposedAddress/curfewAddress/update/');
                        expect(res.text).to.include('name="[addresses][0][addressLine1]" value="address2"');
                    });

            });
        });

        context('there are no addresses saved', () => {
            it('should post to standard route', () => {
                const licenceService = createLicenceServiceStub();
                licenceService.getLicence = sinon.stub().resolves({
                    licence: { }
                });

                const app = createApp({licenceService});

                return request(app)
                    .get('/hdc/proposedAddress/curfewAddress/1')
                    .expect(200)
                    .expect('Content-Type', /html/)
                    .expect(res => {
                        expect(res.text).to.include('<form method="post">');
                        expect(res.text).to.include('name="[addresses][0][addressLine1]"');
                    });

            });
        });

        context('there are only rejected addresses', () => {
            it('should display no address and post to add', () => {
                const licenceService = createLicenceServiceStub();
                licenceService.getLicence = sinon.stub().resolves({
                    licence: {
                        proposedAddress: {
                            curfewAddress: {
                                addresses: [
                                    {addressLine1: 'address1', consent: 'No', electricity: 'No', deemedSafe: 'No'}
                                ]
                            }
                        }
                    }
                });
                const app = createApp({licenceService});

                return request(app)
                    .get('/hdc/proposedAddress/curfewAddress/1')
                    .expect(200)
                    .expect('Content-Type', /html/)
                    .expect(res => {
                        expect(res.text).to.include('/proposedAddress/curfewAddress/add');
                        expect(res.text).to.include('name="[addresses][0][addressLine1]"');
                    });

            });
        });

        context('there are only active addresses', () => {
            it('should display the active address', () => {
                const licenceService = createLicenceServiceStub();
                licenceService.getLicence = sinon.stub().resolves({
                    licence: {
                        proposedAddress: {
                            curfewAddress: {
                                addresses: [
                                    {addressLine1: 'address1'}
                                ]
                            }
                        }
                    }
                });
                const app = createApp({licenceService});

                return request(app)
                    .get('/hdc/proposedAddress/curfewAddress/1')
                    .expect(200)
                    .expect('Content-Type', /html/)
                    .expect(res => {
                        expect(res.text).to.include(
                            '<form method="post" action="/hdc/proposedAddress/curfewAddress/update/1">');
                        expect(res.text).to.include('name="[addresses][0][addressLine1]" value="address1"');
                    });

            });
        });
    });

    describe('rejected', () => {
        it('should display the rejected address', () => {
            const licenceService = createLicenceServiceStub();
            licenceService.getLicence = sinon.stub().resolves({
                licence: {
                    proposedAddress: {
                        curfewAddress: {
                            addresses: [
                                {addressLine1: 'address1', consent: 'No'}
                            ]
                        }
                    }
                }
            });
            const app = createApp({licenceService});

            return request(app)
                .get('/hdc/proposedAddress/rejected/1')
                .expect(200)
                .expect('Content-Type', /html/)
                .expect(res => {
                    expect(res.text).to.include('id="rejectedLine1">address1</p>');
                });

        });

        it('should show the form to enter new address', () => {
            const licenceService = createLicenceServiceStub();

            licenceService.getLicence.resolves({
                licence: {
                    proposedAddress: {
                        curfewAddress: {
                            addresses: [
                                {addressLine1: 'address1', consent: 'No'},
                                {addressLine1: 'alt1'}
                            ]
                        }
                    }
                }
            });
            const app = createApp({licenceService});

            return request(app)
                .get('/hdc/proposedAddress/rejected/1')
                .expect(200)
                .expect('Content-Type', /html/)
                .expect(res => {
                    expect(res.text).to.include('<form id="enterAlternativeForm" method="post">');
                });
        });

        it('should redirect to task list if not in ELIGIBILITY stage', () => {
            const licenceService = createLicenceServiceStub();
            licenceService.getLicence.resolves({
                licence: {
                    proposedAddress: {
                        curfewAddress: {
                            addresses: [
                                {addressLine1: 'address1', consent: 'No'}
                            ]
                        }
                    }
                },
                stage: 'PROCESSING_CA'
            });

            const app = createApp({licenceService});

            return request(app)
                .post('/hdc/proposedAddress/curfewAddress/add/1')
                .send({bookingId: '1', addresses: [{addressLine1: 'something'}]})
                .expect(302)
                .expect('Location', '/hdc/taskList/1');

        });

        it('should redirect to form if empty address is passed in', () => {
            const licenceService = createLicenceServiceStub();
            licenceService.getLicence.resolves({
                licence: {
                    proposedAddress: {
                        curfewAddress: {
                            addresses: [
                                {addressLine1: 'address1', consent: 'No'}
                            ]
                        }
                    }
                },
                stage: 'PROCESSING_CA'
            });

            const app = createApp({licenceService});

            return request(app)
                .post('/hdc/proposedAddress/curfewAddress/add/1')
                .send({bookingId: '1', addresses: [{addressLine1: '', postCode: '', addressLine2: ''}]})
                .expect(302)
                .expect('Location', '/hdc/proposedAddress/curfewAddress/1');

        });
    });
});
<|endoftext|>


<commit_before>const assert = require('assert');
const chai = require('chai');
const chaiHttp = require('chai-http');
// const oauth2 = require('simple-oauth2');
// const request = require('request-promise-native');
// proxyserver
const oauth2Server = require('./oauth2MockServer');

const app = require('../../../src/app');
const logger = require('../../../src/logger/');

const baseUrlService = app.service('oauth2/baseUrl');
const clientsService = app.service('oauth2/clients');
const loginService = app.service('oauth2/loginRequest');
const introspectService = app.service('oauth2/introspect');
const consentService = app.service('oauth2/auth/sessions/consent');
const toolService = app.service('ltiTools');

const testObjects = require('../helpers/testObjects')(app);

chai.use(chaiHttp);

describe('oauth2 service', function oauthTest() {
	this.timeout(10000);

	const testUser2 = {
		_id: '0000d224816abba584714c9c',
	};

	const testClient = {
		client_id: 'unit_test',
		client_name: 'Unit Test Client',
		client_secret: 'xxxxxxxxxxxxx',
		redirect_uris: [
			'https://localhost:8888',
		],
		token_endpoint_auth_method: 'client_secret_basic',
		subject_type: 'pairwise',
	};

	const testClient2 = {
		client_id: 'unit_test_2',
		client_name: 'Unit Test Client',
		client_secret: 'xxxxxxxxxxxxx',
		redirect_uris: [
			'https://localhost:8888',
		],
		token_endpoint_auth_method: 'client_secret_basic',
		subject_type: 'pairwise',
	};

	const testTool1 = {
		_id: '5a79cb15c3874f9aea14daa5',
		name: 'test1',
		url: 'https://tool.com?pseudonym={PSEUDONYM}',
		isLocal: true,
		isTemplate: true,
		resource_link_id: 1,
		lti_version: '1p0',
		lti_message_type: 'basic-start-request',
		secret: '1',
		key: '1',
		oAuthClientId: testClient2.client_id,
	};

	const testTool2 = {
		_id: '5a79cb15c3874f9aea14daa6',
		originTool: '5a79cb15c3874f9aea14daa5',
		name: 'test2',
		url: 'https://tool.com?pseudonym={PSEUDONYM}',
		isLocal: true,
		resource_link_id: 1,
		lti_version: '1p0',
		lti_message_type: 'basic-start-request',
		secret: '1',
		key: '1',
	};

	const loginRequest1 = null;
	const loginRequest2 = null;
	// let redirectTo = null;
	const hydraUri = app.settings.services.hydra;
	before(async () => {
		this.timeout(10000);

		const o2mock = await oauth2Server({});
		app.settings.services.hydra = o2mock.url; // revert to old value do this in after hook

		const oauth2 = require('../../../src/services/oauth2/index.js');
		app.configure(oauth2);
	});

	after((done) => {
		// sets uri back to original uri
		app.settings.services.hydra = hydraUri;
		Promise.all([
			toolService.remove(testTool1._id),
			toolService.remove(testTool2._id),
			clientsService.remove(testClient2.client_id),
		]).then(() => {
			done();
		}).catch((err) => {
			logger.warning('Can not execute oauth2 after all hook.', err);
			done();
		});
	});

	it('is registered', () => {
		assert.ok(clientsService);
		assert.ok(loginService);
		assert.ok(introspectService);
		assert.ok(consentService);
	});

	it('GET BaseUrl', () => baseUrlService.find().then((response) => {
		assert.ok(response);
	}));

	it('CREATE Client', () => app.service('oauth2/clients').create(testClient).then((result) => {
		assert.strictEqual(result.client_id, testClient.client_id);
	}));

	it('FIND Clients', () => app.service('oauth2/clients/').find().then((result) => {
		const foundTestClient = JSON.parse(result)
			.find((client) => (client.client_id === testClient.client_id));
		assert(foundTestClient, foundTestClient.toString());
	}));

	it('DELETE Client', () => app.service('oauth2/clients/').remove(testClient.client_id).then((result) => {
		assert(true);
	}));

	it('GET Login Request', () => app.service('oauth2/loginRequest').get(loginRequest1).then((result) => {
		assert.strictEqual(result.challenge, loginRequest1);
	}));

	it('PATCH Login Request Accept', async () => {
		const user = await testObjects.createTestUser();
		const ltiTool = await app.service('ltiTools').create({
			oAuthClientId: 'thethingwearelookingfor',
			url: 'someUrl',
			key: 'someKey',
			secret: 'someSecret',
		});
		const pseudonym = await app.service('pseudonym').create({
			userId: user._id,
			tooldId: ltiTool._id,
			pseudonym: 'somePseudonym',
		});
		const results = await app.service('oauth2/loginRequest').patch(loginRequest1, {}, {
			query: { accept: 1 },
			account: { userId: testUser2._id },
		});
		// redirectTo = result.redirect_to;
		assert.ok(results.redirect_to.indexOf(testClient2.client_id) !== -1);
		app.service('pseudonym').remove(pseudonym._id);
		app.service('ltiTools').remove(ltiTool._id);
	});

	it('PATCH Login Request Reject', () => app.service('oauth2/loginRequest').patch(loginRequest2, {}, {
		query: { accept: 0 },
		account: { userId: '0000d224816abba584714c9c' },
	}).then(() => {
		assert.ok(true);
	}));

	// it('GET and PATCH Consent Request', (done) => {
	// 	return request({
	// 		uri: redirectTo,
	// 		method: 'GET',
	// 		followRedirect: false,
	// 	}).then(response => {
	// 		console.log(response);
	// 		assert.ok(true);
	// 		done();
	// 	}).catch(err => {
	// 		console.log(err);
	// 	});
	// });

	it('Introspect Inactive Token', () => app.service('oauth2/introspect').create({ token: 'xxx' }).then((res) => {
		assert((res.active === false));
	}));

	it('GET Consent', () => app.service('oauth2/auth/sessions/consent').get(testUser2._id, {
		account: { userId: testUser2._id },
	}).then((consents) => {
		assert.ok(consents);
	}));

	it('REMOVE Consent', () => app.service('oauth2/auth/sessions/consent').remove(testUser2._id, {
		account: { userId: testUser2._id },
		query: { client: testClient.client_id },
	}).then(() => {
		throw new Error('Was not supposed to succeed');
	}).catch((err) => {
		assert.strictEqual(404, err.statusCode);
	}));
});

// TODO reset values and fix last patch. issues in hooks?
<commit_msg>fix linting issue<commit_after>const assert = require('assert');
const chai = require('chai');
const chaiHttp = require('chai-http');
// const oauth2 = require('simple-oauth2');
// const request = require('request-promise-native');
// proxyserver
const oauth2Server = require('./oauth2MockServer');
const oauth2 = require('../../../src/services/oauth2/index.js');

const app = require('../../../src/app');
const logger = require('../../../src/logger/');

const baseUrlService = app.service('oauth2/baseUrl');
const clientsService = app.service('oauth2/clients');
const loginService = app.service('oauth2/loginRequest');
const introspectService = app.service('oauth2/introspect');
const consentService = app.service('oauth2/auth/sessions/consent');
const toolService = app.service('ltiTools');

const testObjects = require('../helpers/testObjects')(app);

chai.use(chaiHttp);

describe('oauth2 service', function oauthTest() {
	this.timeout(10000);

	const testUser2 = {
		_id: '0000d224816abba584714c9c',
	};

	const testClient = {
		client_id: 'unit_test',
		client_name: 'Unit Test Client',
		client_secret: 'xxxxxxxxxxxxx',
		redirect_uris: [
			'https://localhost:8888',
		],
		token_endpoint_auth_method: 'client_secret_basic',
		subject_type: 'pairwise',
	};

	const testClient2 = {
		client_id: 'unit_test_2',
		client_name: 'Unit Test Client',
		client_secret: 'xxxxxxxxxxxxx',
		redirect_uris: [
			'https://localhost:8888',
		],
		token_endpoint_auth_method: 'client_secret_basic',
		subject_type: 'pairwise',
	};

	const testTool1 = {
		_id: '5a79cb15c3874f9aea14daa5',
		name: 'test1',
		url: 'https://tool.com?pseudonym={PSEUDONYM}',
		isLocal: true,
		isTemplate: true,
		resource_link_id: 1,
		lti_version: '1p0',
		lti_message_type: 'basic-start-request',
		secret: '1',
		key: '1',
		oAuthClientId: testClient2.client_id,
	};

	const testTool2 = {
		_id: '5a79cb15c3874f9aea14daa6',
		originTool: '5a79cb15c3874f9aea14daa5',
		name: 'test2',
		url: 'https://tool.com?pseudonym={PSEUDONYM}',
		isLocal: true,
		resource_link_id: 1,
		lti_version: '1p0',
		lti_message_type: 'basic-start-request',
		secret: '1',
		key: '1',
	};

	const loginRequest1 = null;
	const loginRequest2 = null;
	// let redirectTo = null;
	const hydraUri = app.settings.services.hydra;
	before(async () => {
		this.timeout(10000);

		const o2mock = await oauth2Server({});
		app.settings.services.hydra = o2mock.url; // revert to old value do this in after hook

		app.configure(oauth2);
	});

	after((done) => {
		// sets uri back to original uri
		app.settings.services.hydra = hydraUri;
		Promise.all([
			toolService.remove(testTool1._id),
			toolService.remove(testTool2._id),
			clientsService.remove(testClient2.client_id),
		]).then(() => {
			done();
		}).catch((err) => {
			logger.warning('Can not execute oauth2 after all hook.', err);
			done();
		});
	});

	it('is registered', () => {
		assert.ok(clientsService);
		assert.ok(loginService);
		assert.ok(introspectService);
		assert.ok(consentService);
	});

	it('GET BaseUrl', () => baseUrlService.find().then((response) => {
		assert.ok(response);
	}));

	it('CREATE Client', () => app.service('oauth2/clients').create(testClient).then((result) => {
		assert.strictEqual(result.client_id, testClient.client_id);
	}));

	it('FIND Clients', () => app.service('oauth2/clients/').find().then((result) => {
		const foundTestClient = JSON.parse(result)
			.find((client) => (client.client_id === testClient.client_id));
		assert(foundTestClient, foundTestClient.toString());
	}));

	it('DELETE Client', () => app.service('oauth2/clients/').remove(testClient.client_id).then((result) => {
		assert(true);
	}));

	it('GET Login Request', () => app.service('oauth2/loginRequest').get(loginRequest1).then((result) => {
		assert.strictEqual(result.challenge, loginRequest1);
	}));

	it('PATCH Login Request Accept', async () => {
		const user = await testObjects.createTestUser();
		const ltiTool = await app.service('ltiTools').create({
			oAuthClientId: 'thethingwearelookingfor',
			url: 'someUrl',
			key: 'someKey',
			secret: 'someSecret',
		});
		const pseudonym = await app.service('pseudonym').create({
			userId: user._id,
			tooldId: ltiTool._id,
			pseudonym: 'somePseudonym',
		});
		const results = await app.service('oauth2/loginRequest').patch(loginRequest1, {}, {
			query: { accept: 1 },
			account: { userId: testUser2._id },
		});
		// redirectTo = result.redirect_to;
		assert.ok(results.redirect_to.indexOf(testClient2.client_id) !== -1);
		app.service('pseudonym').remove(pseudonym._id);
		app.service('ltiTools').remove(ltiTool._id);
	});

	it('PATCH Login Request Reject', () => app.service('oauth2/loginRequest').patch(loginRequest2, {}, {
		query: { accept: 0 },
		account: { userId: '0000d224816abba584714c9c' },
	}).then(() => {
		assert.ok(true);
	}));

	// it('GET and PATCH Consent Request', (done) => {
	// 	return request({
	// 		uri: redirectTo,
	// 		method: 'GET',
	// 		followRedirect: false,
	// 	}).then(response => {
	// 		console.log(response);
	// 		assert.ok(true);
	// 		done();
	// 	}).catch(err => {
	// 		console.log(err);
	// 	});
	// });

	it('Introspect Inactive Token', () => app.service('oauth2/introspect').create({ token: 'xxx' }).then((res) => {
		assert((res.active === false));
	}));

	it('GET Consent', () => app.service('oauth2/auth/sessions/consent').get(testUser2._id, {
		account: { userId: testUser2._id },
	}).then((consents) => {
		assert.ok(consents);
	}));

	it('REMOVE Consent', () => app.service('oauth2/auth/sessions/consent').remove(testUser2._id, {
		account: { userId: testUser2._id },
		query: { client: testClient.client_id },
	}).then(() => {
		throw new Error('Was not supposed to succeed');
	}).catch((err) => {
		assert.strictEqual(404, err.statusCode);
	}));
});

// TODO reset values and fix last patch. issues in hooks?
<|endoftext|>