/* 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'); preloadFixtures('issues/issue-with-task-list.html'); preloadFixtures('issues/open-issue.html'); 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'); } else { loadFixtures('issues/closed-issue.html'); } mock = new MockAdapter(axios); mock.onGet(/(.*)\/related_branches$/).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(); }); }); }); }); });