debian-mirror-gitlab/spec/frontend/code_review/signals_spec.js
2023-07-09 08:55:56 +05:30

145 lines
4.5 KiB
JavaScript

import { start } from '~/code_review/signals';
import diffsEventHub from '~/diffs/event_hub';
import { EVT_MR_PREPARED } from '~/diffs/constants';
import { getDerivedMergeRequestInformation } from '~/diffs/utils/merge_request';
jest.mock('~/diffs/utils/merge_request');
describe('~/code_review', () => {
const io = diffsEventHub;
beforeAll(() => {
getDerivedMergeRequestInformation.mockImplementation(() => ({
namespace: 'x',
project: 'y',
id: '1',
}));
});
describe('start', () => {
it.each`
description | argument
${'no event hub is provided'} | ${{}}
${'no parameters are provided'} | ${undefined}
`('throws an error if $description', async ({ argument }) => {
await expect(() => start(argument)).rejects.toThrow('signalBus is a required argument');
});
describe('observeMergeRequestFinishingPreparation', () => {
const callArgs = {};
const apollo = {};
let querySpy;
let apolloSubscribeSpy;
let subscribeSpy;
let nextSpy;
let unsubscribeSpy;
let observable;
beforeEach(() => {
querySpy = jest.fn();
apolloSubscribeSpy = jest.fn();
subscribeSpy = jest.fn();
unsubscribeSpy = jest.fn();
nextSpy = jest.fn();
observable = {
next: nextSpy,
subscribe: subscribeSpy.mockReturnValue({
unsubscribe: unsubscribeSpy,
}),
};
querySpy.mockResolvedValue({
data: { project: { mergeRequest: { id: 'gql:id:1', preparedAt: 'x' } } },
});
apolloSubscribeSpy.mockReturnValue(observable);
apollo.query = querySpy;
apollo.subscribe = apolloSubscribeSpy;
callArgs.signalBus = io;
callArgs.apolloClient = apollo;
});
it('does not query at all if the page does not seem like a merge request', async () => {
getDerivedMergeRequestInformation.mockImplementationOnce(() => ({}));
await start(callArgs);
expect(querySpy).not.toHaveBeenCalled();
expect(apolloSubscribeSpy).not.toHaveBeenCalled();
});
describe('on a merge request page', () => {
it('requests the preparedAt (and id) for the current merge request', async () => {
await start(callArgs);
expect(querySpy).toHaveBeenCalledWith(
expect.objectContaining({
variables: {
projectPath: 'x/y',
iid: '1',
},
}),
);
});
it('does not subscribe to any updates if the preparedAt value is already populated', async () => {
await start(callArgs);
expect(apolloSubscribeSpy).not.toHaveBeenCalled();
});
describe('if the merge request is still asynchronously preparing', () => {
beforeEach(() => {
querySpy.mockResolvedValue({
data: { project: { mergeRequest: { id: 'gql:id:1', preparedAt: null } } },
});
});
it('subscribes to updates', async () => {
await start(callArgs);
expect(apolloSubscribeSpy).toHaveBeenCalledWith(
expect.objectContaining({ variables: { issuableId: 'gql:id:1' } }),
);
expect(observable.subscribe).toHaveBeenCalled();
});
describe('when the MR has been updated', () => {
let emitSpy;
let behavior;
beforeEach(() => {
emitSpy = jest.spyOn(diffsEventHub, '$emit');
nextSpy.mockImplementation((data) => behavior?.(data));
subscribeSpy.mockImplementation((handler) => {
behavior = handler;
return { unsubscribe: unsubscribeSpy };
});
});
it('does nothing if the MR has not yet finished preparing', async () => {
await start(callArgs);
observable.next({ data: { mergeRequestMergeStatusUpdated: { preparedAt: null } } });
expect(unsubscribeSpy).not.toHaveBeenCalled();
expect(emitSpy).not.toHaveBeenCalled();
});
it('emits an event and unsubscribes when the MR is prepared', async () => {
await start(callArgs);
observable.next({ data: { mergeRequestMergeStatusUpdated: { preparedAt: 'x' } } });
expect(unsubscribeSpy).toHaveBeenCalled();
expect(emitSpy).toHaveBeenCalledWith(EVT_MR_PREPARED);
});
});
});
});
});
});
});