Commit 12cb1a98 authored by Greg Johnson's avatar Greg Johnson Committed by Paul Slaughter
parent 310c30ad
......@@ -6,6 +6,9 @@ import axios from './lib/utils/axios_utils';
import { addDelimiter } from './lib/utils/text_utility';
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 {
constructor() {
if ($('.js-alert-moved-from-service-desk-warning').length) {
......@@ -23,9 +26,13 @@ export default class Issue {
}
// 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);
});
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 $ from 'jquery';
import Issue from '~/issue';
import Issue, { EVENT_ISSUABLE_VUE_APP_CHANGE } from '~/issue';
import axios from '~/lib/utils/axios_utils';
import '~/lib/utils/text_utility';
describe('Issue', () => {
let $boxClosed;
let $boxOpen;
let testContext;
let mock;
beforeEach(() => {
testContext = {};
beforeAll(() => {
preloadFixtures('issues/closed-issue.html');
preloadFixtures('issues/open-issue.html');
});
preloadFixtures('issues/closed-issue.html');
preloadFixtures('issues/open-issue.html');
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);
}
beforeEach(() => {
mock = new MockAdapter(axios);
mock.onGet(/(.*)\/related_branches$/).reply(200, {});
function findElements() {
$boxClosed = $('div.status-box-issue-closed');
testContext = {};
testContext.issue = new Issue();
});
expect($boxClosed).toExist();
expect($boxClosed).toHaveText('Closed');
afterEach(() => {
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();
expect($boxOpen).toHaveText('Open');
}
describe.each`
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) => {
describe(`with ${isIssueInitiallyOpen ? 'open' : 'closed'} issue`, () => {
const action = isIssueInitiallyOpen ? 'close' : 'reopen';
let mock;
testContext.issueCounter = getIssueCounter();
testContext.statusBoxClosed = getClosedStatusBox();
testContext.statusBoxOpen = getOpenStatusBox();
function setup() {
testContext.issue = new Issue();
expectIssueState(isIssueInitiallyOpen);
testContext.issueCounter.textContent = '1,001';
});
testContext.$projectIssuesCounter = $('.issue_counter').first();
testContext.$projectIssuesCounter.text('1,001');
it(`has the proper visible status box when ${isIssueInitiallyOpen ? 'open' : 'closed'}`, () => {
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(() => {
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(
new CustomEvent('issuable_vue_app:change', {
new CustomEvent(EVENT_ISSUABLE_VUE_APP_CHANGE, {
detail: {
data: { id: 1 },
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