146 lines
4.5 KiB
JavaScript
146 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);
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
});
|