Commit 6df996a1 authored by Paul Slaughter's avatar Paul Slaughter

Merge branch 'improve-issue-specs' into 'master'

Improve issue specs

See merge request gitlab-org/gitlab!52135
parents b1990f13 12cb1a98
...@@ -6,6 +6,9 @@ import axios from './lib/utils/axios_utils'; ...@@ -6,6 +6,9 @@ import axios from './lib/utils/axios_utils';
import { addDelimiter } from './lib/utils/text_utility'; import { addDelimiter } from './lib/utils/text_utility';
import { __ } from './locale'; import { __ } from './locale';
// TODO: Update all references of "issuable_vue_app:change" https://gitlab.com/gitlab-org/gitlab/-/issues/322760
export const EVENT_ISSUABLE_VUE_APP_CHANGE = 'issuable_vue_app:change';
export default class Issue { export default class Issue {
constructor() { constructor() {
if ($('.js-alert-moved-from-service-desk-warning').length) { if ($('.js-alert-moved-from-service-desk-warning').length) {
...@@ -23,9 +26,13 @@ export default class Issue { ...@@ -23,9 +26,13 @@ export default class Issue {
} }
// Listen to state changes in the Vue app // Listen to state changes in the Vue app
document.addEventListener('issuable_vue_app:change', (event) => { this.issuableVueAppChangeHandler = (event) =>
this.updateTopState(event.detail.isClosed, event.detail.data); this.updateTopState(event.detail.isClosed, event.detail.data);
}); document.addEventListener(EVENT_ISSUABLE_VUE_APP_CHANGE, this.issuableVueAppChangeHandler);
}
dispose() {
document.removeEventListener(EVENT_ISSUABLE_VUE_APP_CHANGE, this.issuableVueAppChangeHandler);
} }
/** /**
......
import { getByText } from '@testing-library/dom';
import MockAdapter from 'axios-mock-adapter'; import MockAdapter from 'axios-mock-adapter';
import $ from 'jquery'; import Issue, { EVENT_ISSUABLE_VUE_APP_CHANGE } from '~/issue';
import Issue from '~/issue';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import '~/lib/utils/text_utility';
describe('Issue', () => { describe('Issue', () => {
let $boxClosed;
let $boxOpen;
let testContext; let testContext;
let mock;
beforeEach(() => { beforeAll(() => {
testContext = {}; preloadFixtures('issues/closed-issue.html');
preloadFixtures('issues/open-issue.html');
}); });
preloadFixtures('issues/closed-issue.html'); beforeEach(() => {
preloadFixtures('issues/open-issue.html'); mock = new MockAdapter(axios);
mock.onGet(/(.*)\/related_branches$/).reply(200, {});
function expectVisibility($element, shouldBeVisible) {
if (shouldBeVisible) {
expect($element).not.toHaveClass('hidden');
} else {
expect($element).toHaveClass('hidden');
}
}
function expectIssueState(isIssueOpen) {
expectVisibility($boxClosed, !isIssueOpen);
expectVisibility($boxOpen, isIssueOpen);
}
function findElements() { testContext = {};
$boxClosed = $('div.status-box-issue-closed'); testContext.issue = new Issue();
});
expect($boxClosed).toExist(); afterEach(() => {
expect($boxClosed).toHaveText('Closed'); mock.restore();
testContext.issue.dispose();
});
$boxOpen = $('div.status-box-open'); const getIssueCounter = () => document.querySelector('.issue_counter');
const getOpenStatusBox = () =>
getByText(document, (_, el) => el.textContent.match(/Open/), {
selector: '.status-box-open',
});
const getClosedStatusBox = () =>
getByText(document, (_, el) => el.textContent.match(/Closed/), {
selector: '.status-box-issue-closed',
});
expect($boxOpen).toExist(); describe.each`
expect($boxOpen).toHaveText('Open'); desc | isIssueInitiallyOpen | expectedCounterText
} ${'with an initially open issue'} | ${true} | ${'1,000'}
${'with an initially closed issue'} | ${false} | ${'1,002'}
`('$desc', ({ isIssueInitiallyOpen, expectedCounterText }) => {
beforeEach(() => {
if (isIssueInitiallyOpen) {
loadFixtures('issues/open-issue.html');
} else {
loadFixtures('issues/closed-issue.html');
}
[true, false].forEach((isIssueInitiallyOpen) => { testContext.issueCounter = getIssueCounter();
describe(`with ${isIssueInitiallyOpen ? 'open' : 'closed'} issue`, () => { testContext.statusBoxClosed = getClosedStatusBox();
const action = isIssueInitiallyOpen ? 'close' : 'reopen'; testContext.statusBoxOpen = getOpenStatusBox();
let mock;
function setup() { testContext.issueCounter.textContent = '1,001';
testContext.issue = new Issue(); });
expectIssueState(isIssueInitiallyOpen);
testContext.$projectIssuesCounter = $('.issue_counter').first(); it(`has the proper visible status box when ${isIssueInitiallyOpen ? 'open' : 'closed'}`, () => {
testContext.$projectIssuesCounter.text('1,001'); if (isIssueInitiallyOpen) {
expect(testContext.statusBoxClosed).toHaveClass('hidden');
expect(testContext.statusBoxOpen).not.toHaveClass('hidden');
} else {
expect(testContext.statusBoxClosed).not.toHaveClass('hidden');
expect(testContext.statusBoxOpen).toHaveClass('hidden');
} }
});
describe('when vue app triggers change', () => {
beforeEach(() => { beforeEach(() => {
if (isIssueInitiallyOpen) {
loadFixtures('issues/open-issue.html');
} else {
loadFixtures('issues/closed-issue.html');
}
mock = new MockAdapter(axios);
mock.onGet(/(.*)\/related_branches$/).reply(200, {});
jest.spyOn(axios, 'get');
findElements(isIssueInitiallyOpen);
});
afterEach(() => {
mock.restore();
$('div.flash-alert').remove();
});
it(`${action}s the issue on dispatch of issuable_vue_app:change event`, () => {
setup();
document.dispatchEvent( document.dispatchEvent(
new CustomEvent('issuable_vue_app:change', { new CustomEvent(EVENT_ISSUABLE_VUE_APP_CHANGE, {
detail: { detail: {
data: { id: 1 }, data: { id: 1 },
isClosed: isIssueInitiallyOpen, isClosed: isIssueInitiallyOpen,
}, },
}), }),
); );
});
it('displays correct status box', () => {
if (isIssueInitiallyOpen) {
expect(testContext.statusBoxClosed).not.toHaveClass('hidden');
expect(testContext.statusBoxOpen).toHaveClass('hidden');
} else {
expect(testContext.statusBoxClosed).toHaveClass('hidden');
expect(testContext.statusBoxOpen).not.toHaveClass('hidden');
}
});
expectIssueState(!isIssueInitiallyOpen); it('updates issueCounter text', () => {
expect(testContext.issueCounter).toBeVisible();
expect(testContext.issueCounter).toHaveText(expectedCounterText);
}); });
}); });
}); });
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment