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

166 lines
4.6 KiB
JavaScript

import waitForPromises from 'helpers/wait_for_promises';
import * as UserApi from '~/api/user_api';
import {
createUserCountsManager,
userCounts,
destroyUserCountsManager,
} from '~/super_sidebar/user_counts_manager';
jest.mock('~/api');
const USER_ID = 123;
const userCountDefaults = {
todos: 1,
assigned_issues: 2,
assigned_merge_requests: 3,
review_requested_merge_requests: 4,
};
const userCountUpdate = {
todos: 123,
assigned_issues: 456,
assigned_merge_requests: 789,
review_requested_merge_requests: 101112,
};
describe('User Merge Requests', () => {
let channelMock;
let newBroadcastChannelMock;
beforeEach(() => {
jest.spyOn(document, 'removeEventListener');
jest.spyOn(document, 'addEventListener');
global.gon.current_user_id = USER_ID;
channelMock = {
postMessage: jest.fn(),
close: jest.fn(),
};
newBroadcastChannelMock = jest.fn().mockImplementation(() => channelMock);
Object.assign(userCounts, userCountDefaults, { last_update: 0 });
global.BroadcastChannel = newBroadcastChannelMock;
});
describe('createUserCountsManager', () => {
beforeEach(() => {
createUserCountsManager();
});
it('creates BroadcastChannel which updates counts on message received', () => {
expect(newBroadcastChannelMock).toHaveBeenCalledWith(`user_counts_${USER_ID}`);
});
it('closes BroadCastchannel if called while already open', () => {
expect(channelMock.close).not.toHaveBeenCalled();
createUserCountsManager();
expect(channelMock.close).toHaveBeenCalled();
});
describe('BroadcastChannel onmessage handler', () => {
it('updates counts on message received', () => {
expect(userCounts).toMatchObject(userCountDefaults);
channelMock.onmessage({ data: { ...userCountUpdate, last_update: Date.now() } });
expect(userCounts).toMatchObject(userCountUpdate);
});
it('ignores updates with older data', () => {
expect(userCounts).toMatchObject(userCountDefaults);
userCounts.last_update = Date.now();
channelMock.onmessage({
data: { ...userCountUpdate, last_update: userCounts.last_update - 1000 },
});
expect(userCounts).toMatchObject(userCountDefaults);
});
it('ignores unknown fields', () => {
expect(userCounts).toMatchObject(userCountDefaults);
channelMock.onmessage({ data: { ...userCountUpdate, i_am_unknown: 5 } });
expect(userCounts).toMatchObject(userCountUpdate);
expect(userCounts.i_am_unknown).toBeUndefined();
});
});
it('broadcasts user counts during initialization', () => {
expect(channelMock.postMessage).toHaveBeenCalledWith(
expect.objectContaining(userCountDefaults),
);
});
it('setups event listener without leaking them', () => {
expect(document.removeEventListener).toHaveBeenCalledWith(
'userCounts:fetch',
expect.any(Function),
);
expect(document.addEventListener).toHaveBeenCalledWith(
'userCounts:fetch',
expect.any(Function),
);
});
});
describe('Event listener userCounts:fetch', () => {
beforeEach(() => {
jest.spyOn(UserApi, 'getUserCounts').mockResolvedValue({
data: { ...userCountUpdate, merge_requests: 'FOO' },
});
createUserCountsManager();
});
it('fetches counts from API, stores and rebroadcasts them', async () => {
expect(userCounts).toMatchObject(userCountDefaults);
document.dispatchEvent(new CustomEvent('userCounts:fetch'));
await waitForPromises();
expect(UserApi.getUserCounts).toHaveBeenCalled();
expect(userCounts).toMatchObject(userCountUpdate);
expect(channelMock.postMessage).toHaveBeenLastCalledWith(userCounts);
});
});
describe('destroyUserCountsManager', () => {
it('unregisters event handler', () => {
expect(document.removeEventListener).not.toHaveBeenCalledWith();
destroyUserCountsManager();
expect(document.removeEventListener).toHaveBeenCalledWith(
'userCounts:fetch',
expect.any(Function),
);
});
describe('when BroadcastChannel is not opened', () => {
it('does nothing', () => {
destroyUserCountsManager();
expect(channelMock.close).not.toHaveBeenCalled();
});
});
describe('when BroadcastChannel is opened', () => {
beforeEach(() => {
createUserCountsManager();
});
it('closes BroadcastChannel', () => {
expect(channelMock.close).not.toHaveBeenCalled();
destroyUserCountsManager();
expect(channelMock.close).toHaveBeenCalled();
});
});
});
});