c56100b3ec
This only appears when in the collapsed sidebar. If the sidebar is expanded, then these items are hidden & no fly-out navigation is displayed. Closes #36294
225 lines
7.7 KiB
JavaScript
225 lines
7.7 KiB
JavaScript
/* eslint-disable space-before-function-paren, one-var, one-var-declaration-per-line, no-use-before-define, comma-dangle, max-len */
|
|
import Issue from '~/issue';
|
|
import CloseReopenReportToggle from '~/close_reopen_report_toggle';
|
|
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-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');
|
|
}
|
|
|
|
describe('task lists', function() {
|
|
beforeEach(function() {
|
|
loadFixtures('issues/issue-with-task-list.html.raw');
|
|
this.issue = new Issue();
|
|
});
|
|
|
|
it('submits an ajax request on tasklist:changed', function() {
|
|
spyOn(jQuery, 'ajax').and.callFake(function(req) {
|
|
expect(req.type).toBe('PATCH');
|
|
expect(req.url).toBe(gl.TEST_HOST + '/frontend-fixtures/issues-project/issues/1.json'); // eslint-disable-line prefer-template
|
|
expect(req.data.issue.description).not.toBe(null);
|
|
});
|
|
|
|
$('.js-task-list-field').trigger('tasklist:changed');
|
|
});
|
|
});
|
|
|
|
[true, false].forEach((isIssueInitiallyOpen) => {
|
|
describe(`with ${isIssueInitiallyOpen ? 'open' : 'closed'} issue`, function() {
|
|
const action = isIssueInitiallyOpen ? 'close' : 'reopen';
|
|
|
|
function ajaxSpy(req) {
|
|
if (req.url === this.$triggeredButton.attr('href')) {
|
|
expect(req.type).toBe('PUT');
|
|
expectNewBranchButtonState(true, false);
|
|
return this.issueStateDeferred;
|
|
} else if (req.url === Issue.createMrDropdownWrap.dataset.canCreatePath) {
|
|
expect(req.type).toBe('GET');
|
|
expectNewBranchButtonState(true, false);
|
|
return this.canCreateBranchDeferred;
|
|
}
|
|
|
|
expect(req.url).toBe('unexpected');
|
|
return null;
|
|
}
|
|
|
|
beforeEach(function() {
|
|
if (isIssueInitiallyOpen) {
|
|
loadFixtures('issues/open-issue.html.raw');
|
|
} else {
|
|
loadFixtures('issues/closed-issue.html.raw');
|
|
}
|
|
|
|
findElements(isIssueInitiallyOpen);
|
|
this.issue = new Issue();
|
|
expectIssueState(isIssueInitiallyOpen);
|
|
|
|
this.$triggeredButton = $btn;
|
|
|
|
this.$projectIssuesCounter = $('.issue_counter').first();
|
|
this.$projectIssuesCounter.text('1,001');
|
|
|
|
this.issueStateDeferred = new jQuery.Deferred();
|
|
this.canCreateBranchDeferred = new jQuery.Deferred();
|
|
|
|
spyOn(jQuery, 'ajax').and.callFake(ajaxSpy.bind(this));
|
|
});
|
|
|
|
it(`${action}s the issue`, function() {
|
|
this.$triggeredButton.trigger('click');
|
|
this.issueStateDeferred.resolve({
|
|
id: 34
|
|
});
|
|
this.canCreateBranchDeferred.resolve({
|
|
can_create_branch: !isIssueInitiallyOpen
|
|
});
|
|
|
|
expectIssueState(!isIssueInitiallyOpen);
|
|
expect(this.$triggeredButton.get(0).getAttribute('disabled')).toBeNull();
|
|
expect(this.$projectIssuesCounter.text()).toBe(isIssueInitiallyOpen ? '1,000' : '1,002');
|
|
expectNewBranchButtonState(false, !isIssueInitiallyOpen);
|
|
});
|
|
|
|
it(`fails to ${action} the issue if saved:false`, function() {
|
|
this.$triggeredButton.trigger('click');
|
|
this.issueStateDeferred.resolve({
|
|
saved: false
|
|
});
|
|
this.canCreateBranchDeferred.resolve({
|
|
can_create_branch: isIssueInitiallyOpen
|
|
});
|
|
|
|
expectIssueState(isIssueInitiallyOpen);
|
|
expect(this.$triggeredButton.get(0).getAttribute('disabled')).toBeNull();
|
|
expectErrorMessage();
|
|
expect(this.$projectIssuesCounter.text()).toBe('1,001');
|
|
expectNewBranchButtonState(false, isIssueInitiallyOpen);
|
|
});
|
|
|
|
it(`fails to ${action} the issue if HTTP error occurs`, function() {
|
|
this.$triggeredButton.trigger('click');
|
|
this.issueStateDeferred.reject();
|
|
this.canCreateBranchDeferred.resolve({
|
|
can_create_branch: isIssueInitiallyOpen
|
|
});
|
|
|
|
expectIssueState(isIssueInitiallyOpen);
|
|
expect(this.$triggeredButton.get(0).getAttribute('disabled')).toBeNull();
|
|
expectErrorMessage();
|
|
expect(this.$projectIssuesCounter.text()).toBe('1,001');
|
|
expectNewBranchButtonState(false, isIssueInitiallyOpen);
|
|
});
|
|
|
|
it('disables the new branch button if Ajax call fails', function() {
|
|
this.$triggeredButton.trigger('click');
|
|
this.issueStateDeferred.reject();
|
|
this.canCreateBranchDeferred.reject();
|
|
|
|
expectNewBranchButtonState(false, false);
|
|
});
|
|
|
|
it('does not trigger Ajax call if new branch button is missing', function() {
|
|
Issue.$btnNewBranch = $();
|
|
this.canCreateBranchDeferred = null;
|
|
|
|
this.$triggeredButton.trigger('click');
|
|
this.issueStateDeferred.reject();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('units', () => {
|
|
describe('class constructor', () => {
|
|
it('calls .initCloseReopenReport', () => {
|
|
spyOn(Issue.prototype, 'initCloseReopenReport');
|
|
|
|
new Issue(); // eslint-disable-line no-new
|
|
|
|
expect(Issue.prototype.initCloseReopenReport).toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe('initCloseReopenReport', () => {
|
|
it('calls .initDroplab', () => {
|
|
const container = jasmine.createSpyObj('container', ['querySelector']);
|
|
const dropdownTrigger = {};
|
|
const dropdownList = {};
|
|
const button = {};
|
|
|
|
spyOn(document, 'querySelector').and.returnValue(container);
|
|
spyOn(CloseReopenReportToggle.prototype, 'initDroplab');
|
|
container.querySelector.and.returnValues(dropdownTrigger, dropdownList, button);
|
|
|
|
Issue.prototype.initCloseReopenReport();
|
|
|
|
expect(document.querySelector).toHaveBeenCalledWith('.js-issuable-close-dropdown');
|
|
expect(container.querySelector).toHaveBeenCalledWith('.js-issuable-close-toggle');
|
|
expect(container.querySelector).toHaveBeenCalledWith('.js-issuable-close-menu');
|
|
expect(container.querySelector).toHaveBeenCalledWith('.js-issuable-close-button');
|
|
expect(CloseReopenReportToggle.prototype.initDroplab).toHaveBeenCalled();
|
|
});
|
|
});
|
|
});
|
|
});
|