debian-mirror-gitlab/spec/frontend/diffs/utils/discussions_spec.js
2021-12-11 22:18:48 +05:30

133 lines
4.3 KiB
JavaScript

import { discussionIntersectionObserverHandlerFactory } from '~/diffs/utils/discussions';
describe('Diff Discussions Utils', () => {
describe('discussionIntersectionObserverHandlerFactory', () => {
it('creates a handler function', () => {
expect(discussionIntersectionObserverHandlerFactory()).toBeInstanceOf(Function);
});
describe('intersection observer handler', () => {
const functions = {
setCurrentDiscussionId: jest.fn(),
getPreviousUnresolvedDiscussionId: jest.fn().mockImplementation((id) => {
return Number(id) - 1;
}),
};
const defaultProcessableWrapper = {
entry: {
time: 0,
isIntersecting: true,
rootBounds: {
bottom: 0,
},
boundingClientRect: {
top: 0,
},
},
currentDiscussion: {
id: 1,
},
isFirstUnresolved: false,
isDiffsPage: true,
};
let handler;
let getMock;
let setMock;
beforeEach(() => {
functions.setCurrentDiscussionId.mockClear();
functions.getPreviousUnresolvedDiscussionId.mockClear();
defaultProcessableWrapper.functions = functions;
setMock = functions.setCurrentDiscussionId.mock;
getMock = functions.getPreviousUnresolvedDiscussionId.mock;
handler = discussionIntersectionObserverHandlerFactory();
});
it('debounces multiple simultaneous requests into one queue', () => {
handler(defaultProcessableWrapper);
handler(defaultProcessableWrapper);
handler(defaultProcessableWrapper);
handler(defaultProcessableWrapper);
expect(setTimeout).toHaveBeenCalledTimes(4);
expect(clearTimeout).toHaveBeenCalledTimes(3);
// By only advancing to one timer, we ensure it's all being batched into one queue
jest.advanceTimersToNextTimer();
expect(functions.setCurrentDiscussionId).toHaveBeenCalledTimes(4);
});
it('properly processes, sorts and executes the correct actions for a set of observed intersections', () => {
handler(defaultProcessableWrapper);
handler({
// This observation is here to be filtered out because it's a scrollDown
...defaultProcessableWrapper,
entry: {
...defaultProcessableWrapper.entry,
isIntersecting: false,
boundingClientRect: { top: 10 },
rootBounds: { bottom: 100 },
},
});
handler({
...defaultProcessableWrapper,
entry: {
...defaultProcessableWrapper.entry,
time: 101,
isIntersecting: false,
rootBounds: { bottom: -100 },
},
currentDiscussion: { id: 20 },
});
handler({
...defaultProcessableWrapper,
entry: {
...defaultProcessableWrapper.entry,
time: 100,
isIntersecting: false,
boundingClientRect: { top: 100 },
},
currentDiscussion: { id: 30 },
isDiffsPage: false,
});
handler({
...defaultProcessableWrapper,
isFirstUnresolved: true,
entry: {
...defaultProcessableWrapper.entry,
time: 100,
isIntersecting: false,
boundingClientRect: { top: 200 },
},
});
jest.advanceTimersToNextTimer();
expect(setMock.calls.length).toBe(4);
expect(setMock.calls[0]).toEqual([1]);
expect(setMock.calls[1]).toEqual([29]);
expect(setMock.calls[2]).toEqual([null]);
expect(setMock.calls[3]).toEqual([19]);
expect(getMock.calls.length).toBe(2);
expect(getMock.calls[0]).toEqual([30, false]);
expect(getMock.calls[1]).toEqual([20, true]);
[
setMock.invocationCallOrder[0],
getMock.invocationCallOrder[0],
setMock.invocationCallOrder[1],
setMock.invocationCallOrder[2],
getMock.invocationCallOrder[1],
setMock.invocationCallOrder[3],
].forEach((order, idx, list) => {
// Compare each invocation sequence to the one before it (except the first one)
expect(list[idx - 1] || -1).toBeLessThan(order);
});
});
});
});
});