219 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
			
		
		
	
	
			219 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
/* eslint-disable one-var, no-use-before-define */
 | 
						|
 | 
						|
import $ from 'jquery';
 | 
						|
import MockAdapter from 'axios-mock-adapter';
 | 
						|
import axios from '~/lib/utils/axios_utils';
 | 
						|
import Issue from '~/issue';
 | 
						|
import '~/lib/utils/text_utility';
 | 
						|
 | 
						|
describe('Issue', function() {
 | 
						|
  let $boxClosed, $boxOpen, $btn;
 | 
						|
 | 
						|
  preloadFixtures('issues/closed-issue.html.raw');
 | 
						|
  preloadFixtures('issues/issue-with-task-list.html.raw');
 | 
						|
  preloadFixtures('issues/open-issue.html.raw');
 | 
						|
 | 
						|
  function expectErrorMessage() {
 | 
						|
    const $flashMessage = $('div.flash-alert');
 | 
						|
 | 
						|
    expect($flashMessage).toExist();
 | 
						|
    expect($flashMessage).toBeVisible();
 | 
						|
    expect($flashMessage).toHaveText('Unable to update this issue at this time.');
 | 
						|
  }
 | 
						|
 | 
						|
  function expectIssueState(isIssueOpen) {
 | 
						|
    expectVisibility($boxClosed, !isIssueOpen);
 | 
						|
    expectVisibility($boxOpen, isIssueOpen);
 | 
						|
 | 
						|
    expect($btn).toHaveText(isIssueOpen ? 'Close issue' : 'Reopen issue');
 | 
						|
  }
 | 
						|
 | 
						|
  function expectNewBranchButtonState(isPending, canCreate) {
 | 
						|
    if (Issue.$btnNewBranch.length === 0) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    const $available = Issue.$btnNewBranch.find('.available');
 | 
						|
 | 
						|
    expect($available).toHaveText('New branch');
 | 
						|
 | 
						|
    if (!isPending && canCreate) {
 | 
						|
      expect($available).toBeVisible();
 | 
						|
    } else {
 | 
						|
      expect($available).toBeHidden();
 | 
						|
    }
 | 
						|
 | 
						|
    const $unavailable = Issue.$btnNewBranch.find('.unavailable');
 | 
						|
 | 
						|
    expect($unavailable).toHaveText('New branch unavailable');
 | 
						|
 | 
						|
    if (!isPending && !canCreate) {
 | 
						|
      expect($unavailable).toBeVisible();
 | 
						|
    } else {
 | 
						|
      expect($unavailable).toBeHidden();
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  function expectVisibility($element, shouldBeVisible) {
 | 
						|
    if (shouldBeVisible) {
 | 
						|
      expect($element).not.toHaveClass('hidden');
 | 
						|
    } else {
 | 
						|
      expect($element).toHaveClass('hidden');
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  function findElements(isIssueInitiallyOpen) {
 | 
						|
    $boxClosed = $('div.status-box-issue-closed');
 | 
						|
 | 
						|
    expect($boxClosed).toExist();
 | 
						|
    expect($boxClosed).toHaveText('Closed');
 | 
						|
 | 
						|
    $boxOpen = $('div.status-box-open');
 | 
						|
 | 
						|
    expect($boxOpen).toExist();
 | 
						|
    expect($boxOpen).toHaveText('Open');
 | 
						|
 | 
						|
    $btn = $('.js-issuable-close-button');
 | 
						|
 | 
						|
    expect($btn).toExist();
 | 
						|
    expect($btn).toHaveText(isIssueInitiallyOpen ? 'Close issue' : 'Reopen issue');
 | 
						|
  }
 | 
						|
 | 
						|
  [true, false].forEach(isIssueInitiallyOpen => {
 | 
						|
    describe(`with ${isIssueInitiallyOpen ? 'open' : 'closed'} issue`, function() {
 | 
						|
      const action = isIssueInitiallyOpen ? 'close' : 'reopen';
 | 
						|
      let mock;
 | 
						|
 | 
						|
      function mockCloseButtonResponseSuccess(url, response) {
 | 
						|
        mock.onPut(url).reply(() => {
 | 
						|
          expectNewBranchButtonState(true, false);
 | 
						|
 | 
						|
          return [200, response];
 | 
						|
        });
 | 
						|
      }
 | 
						|
 | 
						|
      function mockCloseButtonResponseError(url) {
 | 
						|
        mock.onPut(url).networkError();
 | 
						|
      }
 | 
						|
 | 
						|
      function mockCanCreateBranch(canCreateBranch) {
 | 
						|
        mock.onGet(/(.*)\/can_create_branch$/).reply(200, {
 | 
						|
          can_create_branch: canCreateBranch,
 | 
						|
          suggested_branch_name: 'foo-99',
 | 
						|
        });
 | 
						|
      }
 | 
						|
 | 
						|
      beforeEach(function() {
 | 
						|
        if (isIssueInitiallyOpen) {
 | 
						|
          loadFixtures('issues/open-issue.html.raw');
 | 
						|
        } else {
 | 
						|
          loadFixtures('issues/closed-issue.html.raw');
 | 
						|
        }
 | 
						|
 | 
						|
        mock = new MockAdapter(axios);
 | 
						|
 | 
						|
        mock.onGet(/(.*)\/related_branches$/).reply(200, {});
 | 
						|
        mock.onGet(/(.*)\/referenced_merge_requests$/).reply(200, {});
 | 
						|
 | 
						|
        findElements(isIssueInitiallyOpen);
 | 
						|
        this.issue = new Issue();
 | 
						|
        expectIssueState(isIssueInitiallyOpen);
 | 
						|
 | 
						|
        this.$triggeredButton = $btn;
 | 
						|
 | 
						|
        this.$projectIssuesCounter = $('.issue_counter').first();
 | 
						|
        this.$projectIssuesCounter.text('1,001');
 | 
						|
 | 
						|
        spyOn(axios, 'get').and.callThrough();
 | 
						|
      });
 | 
						|
 | 
						|
      afterEach(() => {
 | 
						|
        mock.restore();
 | 
						|
        $('div.flash-alert').remove();
 | 
						|
      });
 | 
						|
 | 
						|
      it(`${action}s the issue`, function(done) {
 | 
						|
        mockCloseButtonResponseSuccess(this.$triggeredButton.attr('href'), {
 | 
						|
          id: 34,
 | 
						|
        });
 | 
						|
        mockCanCreateBranch(!isIssueInitiallyOpen);
 | 
						|
 | 
						|
        this.$triggeredButton.trigger('click');
 | 
						|
 | 
						|
        setTimeout(() => {
 | 
						|
          expectIssueState(!isIssueInitiallyOpen);
 | 
						|
 | 
						|
          expect(this.$triggeredButton.get(0).getAttribute('disabled')).toBeNull();
 | 
						|
          expect(this.$projectIssuesCounter.text()).toBe(isIssueInitiallyOpen ? '1,000' : '1,002');
 | 
						|
          expectNewBranchButtonState(false, !isIssueInitiallyOpen);
 | 
						|
 | 
						|
          done();
 | 
						|
        });
 | 
						|
      });
 | 
						|
 | 
						|
      it(`fails to ${action} the issue if saved:false`, function(done) {
 | 
						|
        mockCloseButtonResponseSuccess(this.$triggeredButton.attr('href'), {
 | 
						|
          saved: false,
 | 
						|
        });
 | 
						|
        mockCanCreateBranch(isIssueInitiallyOpen);
 | 
						|
 | 
						|
        this.$triggeredButton.trigger('click');
 | 
						|
 | 
						|
        setTimeout(() => {
 | 
						|
          expectIssueState(isIssueInitiallyOpen);
 | 
						|
 | 
						|
          expect(this.$triggeredButton.get(0).getAttribute('disabled')).toBeNull();
 | 
						|
          expectErrorMessage();
 | 
						|
 | 
						|
          expect(this.$projectIssuesCounter.text()).toBe('1,001');
 | 
						|
          expectNewBranchButtonState(false, isIssueInitiallyOpen);
 | 
						|
 | 
						|
          done();
 | 
						|
        });
 | 
						|
      });
 | 
						|
 | 
						|
      it(`fails to ${action} the issue if HTTP error occurs`, function(done) {
 | 
						|
        mockCloseButtonResponseError(this.$triggeredButton.attr('href'));
 | 
						|
        mockCanCreateBranch(isIssueInitiallyOpen);
 | 
						|
 | 
						|
        this.$triggeredButton.trigger('click');
 | 
						|
 | 
						|
        setTimeout(() => {
 | 
						|
          expectIssueState(isIssueInitiallyOpen);
 | 
						|
 | 
						|
          expect(this.$triggeredButton.get(0).getAttribute('disabled')).toBeNull();
 | 
						|
          expectErrorMessage();
 | 
						|
 | 
						|
          expect(this.$projectIssuesCounter.text()).toBe('1,001');
 | 
						|
          expectNewBranchButtonState(false, isIssueInitiallyOpen);
 | 
						|
 | 
						|
          done();
 | 
						|
        });
 | 
						|
      });
 | 
						|
 | 
						|
      it('disables the new branch button if Ajax call fails', function() {
 | 
						|
        mockCloseButtonResponseError(this.$triggeredButton.attr('href'));
 | 
						|
        mock.onGet(/(.*)\/can_create_branch$/).networkError();
 | 
						|
 | 
						|
        this.$triggeredButton.trigger('click');
 | 
						|
 | 
						|
        expectNewBranchButtonState(false, false);
 | 
						|
      });
 | 
						|
 | 
						|
      it('does not trigger Ajax call if new branch button is missing', function(done) {
 | 
						|
        mockCloseButtonResponseError(this.$triggeredButton.attr('href'));
 | 
						|
        Issue.$btnNewBranch = $();
 | 
						|
        this.canCreateBranchDeferred = null;
 | 
						|
 | 
						|
        this.$triggeredButton.trigger('click');
 | 
						|
 | 
						|
        setTimeout(() => {
 | 
						|
          expect(axios.get).not.toHaveBeenCalled();
 | 
						|
 | 
						|
          done();
 | 
						|
        });
 | 
						|
      });
 | 
						|
    });
 | 
						|
  });
 | 
						|
});
 |