Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/user_popovers_spec.js')
-rw-r--r--spec/frontend/user_popovers_spec.js137
1 files changed, 83 insertions, 54 deletions
diff --git a/spec/frontend/user_popovers_spec.js b/spec/frontend/user_popovers_spec.js
index fa598716645..1544fed5240 100644
--- a/spec/frontend/user_popovers_spec.js
+++ b/spec/frontend/user_popovers_spec.js
@@ -22,16 +22,17 @@ describe('User Popovers', () => {
const link = document.createElement('a');
link.classList.add('js-user-link');
- link.setAttribute('data-user', '1');
+ link.dataset.user = '1';
return link;
};
+ const findPopovers = () => {
+ return Array.from(document.querySelectorAll('[data-testid="user-popover"]'));
+ };
const dummyUser = { name: 'root', username: 'root', is_followed: false };
const dummyUserStatus = { message: 'active' };
- let popovers;
-
const triggerEvent = (eventName, el) => {
const event = new MouseEvent(eventName, {
bubbles: true,
@@ -54,56 +55,73 @@ describe('User Popovers', () => {
.mockImplementation((userId) => userStatusCacheSpy(userId));
jest.spyOn(UsersCache, 'updateById');
- popovers = initUserPopovers(document.querySelectorAll(selector));
+ initUserPopovers((popoverInstance) => {
+ const mountingRoot = document.createElement('div');
+ document.body.appendChild(mountingRoot);
+ popoverInstance.$mount(mountingRoot);
+ });
});
afterEach(() => {
resetHTMLFixture();
});
- it('initializes a popover for each user link with a user id', () => {
- const linksWithUsers = findFixtureLinks();
+ describe('shows a placeholder popover on hover', () => {
+ let linksWithUsers;
+ beforeEach(() => {
+ linksWithUsers = findFixtureLinks();
+ linksWithUsers.forEach((el) => {
+ triggerEvent('mouseover', el);
+ });
+ });
- expect(linksWithUsers.length).toBe(popovers.length);
- });
+ it('for initial links', () => {
+ expect(findPopovers().length).toBe(linksWithUsers.length);
+ });
- it('adds popovers to user links added to the DOM tree after the initial call', async () => {
- document.body.appendChild(createUserLink());
- document.body.appendChild(createUserLink());
+ it('for elements added after initial load', async () => {
+ const addedLinks = [createUserLink(), createUserLink()];
+ addedLinks.forEach((link) => {
+ document.body.appendChild(link);
+ });
- const linksWithUsers = findFixtureLinks();
+ jest.runOnlyPendingTimers();
- expect(linksWithUsers.length).toBe(popovers.length + 2);
+ addedLinks.forEach((link) => {
+ triggerEvent('mouseover', link);
+ });
+
+ expect(findPopovers().length).toBe(linksWithUsers.length + addedLinks.length);
+ });
});
- it('does not initialize the user popovers twice for the same element', () => {
- const newPopovers = initUserPopovers(document.querySelectorAll(selector));
- const samePopovers = popovers.every((popover, index) => newPopovers[index] === popover);
+ it('does not initialize the user popovers twice for the same element', async () => {
+ const [firstUserLink] = findFixtureLinks();
+ triggerEvent('mouseover', firstUserLink);
+ jest.runOnlyPendingTimers();
+ triggerEvent('mouseleave', firstUserLink);
+ jest.runOnlyPendingTimers();
+ triggerEvent('mouseover', firstUserLink);
+ jest.runOnlyPendingTimers();
- expect(samePopovers).toBe(true);
+ expect(findPopovers().length).toBe(1);
});
- describe('when user link emits mouseenter event', () => {
+ describe('when user link emits mouseenter event with empty user cache', () => {
let userLink;
beforeEach(() => {
UsersCache.retrieveById.mockReset();
- userLink = document.querySelector(selector);
-
- triggerEvent('mouseenter', userLink);
- });
+ [userLink] = findFixtureLinks();
- it('removes title attribute from user links', () => {
- expect(userLink.getAttribute('title')).toBeFalsy();
- expect(userLink.dataset.originalTitle).toBeFalsy();
+ triggerEvent('mouseover', userLink);
});
- it('populates popovers with preloaded user data', () => {
+ it('populates popover with preloaded user data', () => {
const { name, userId, username } = userLink.dataset;
- const [firstPopover] = popovers;
- expect(firstPopover.$props.user).toEqual(
+ expect(userLink.user).toEqual(
expect.objectContaining({
name,
userId,
@@ -111,6 +129,21 @@ describe('User Popovers', () => {
}),
);
});
+ });
+
+ describe('when user link emits mouseenter event', () => {
+ let userLink;
+
+ beforeEach(() => {
+ [userLink] = findFixtureLinks();
+
+ triggerEvent('mouseover', userLink);
+ });
+
+ it('removes title attribute from user links', () => {
+ expect(userLink.getAttribute('title')).toBeFalsy();
+ expect(userLink.dataset.originalTitle).toBeFalsy();
+ });
it('fetches user info and status from the user cache', () => {
const { userId } = userLink.dataset;
@@ -118,42 +151,38 @@ describe('User Popovers', () => {
expect(UsersCache.retrieveById).toHaveBeenCalledWith(userId);
expect(UsersCache.retrieveStatusById).toHaveBeenCalledWith(userId);
});
- });
-
- it('removes aria-describedby attribute from the user link on mouseleave', () => {
- const userLink = document.querySelector(selector);
- userLink.setAttribute('aria-describedby', 'popover');
- triggerEvent('mouseleave', userLink);
+ it('removes aria-describedby attribute from the user link on mouseleave', () => {
+ userLink.setAttribute('aria-describedby', 'popover');
+ triggerEvent('mouseleave', userLink);
- expect(userLink.getAttribute('aria-describedby')).toBe(null);
- });
-
- it('updates toggle follow button and `UsersCache` when toggle follow button is clicked', async () => {
- const [firstPopover] = popovers;
- const withinFirstPopover = within(firstPopover.$el);
- const findFollowButton = () => withinFirstPopover.queryByRole('button', { name: 'Follow' });
- const findUnfollowButton = () => withinFirstPopover.queryByRole('button', { name: 'Unfollow' });
+ expect(userLink.getAttribute('aria-describedby')).toBe(null);
+ });
- const userLink = document.querySelector(selector);
- triggerEvent('mouseenter', userLink);
+ it('updates toggle follow button and `UsersCache` when toggle follow button is clicked', async () => {
+ const [firstPopover] = findPopovers();
+ const withinFirstPopover = within(firstPopover);
+ const findFollowButton = () => withinFirstPopover.queryByRole('button', { name: 'Follow' });
+ const findUnfollowButton = () =>
+ withinFirstPopover.queryByRole('button', { name: 'Unfollow' });
- await waitForPromises();
+ jest.runOnlyPendingTimers();
- const { userId } = document.querySelector(selector).dataset;
+ const { userId } = document.querySelector(selector).dataset;
- triggerEvent('click', findFollowButton());
+ triggerEvent('click', findFollowButton());
- await waitForPromises();
+ await waitForPromises();
- expect(findUnfollowButton()).not.toBe(null);
- expect(UsersCache.updateById).toHaveBeenCalledWith(userId, { is_followed: true });
+ expect(findUnfollowButton()).not.toBe(null);
+ expect(UsersCache.updateById).toHaveBeenCalledWith(userId, { is_followed: true });
- triggerEvent('click', findUnfollowButton());
+ triggerEvent('click', findUnfollowButton());
- await waitForPromises();
+ await waitForPromises();
- expect(findFollowButton()).not.toBe(null);
- expect(UsersCache.updateById).toHaveBeenCalledWith(userId, { is_followed: false });
+ expect(findFollowButton()).not.toBe(null);
+ expect(UsersCache.updateById).toHaveBeenCalledWith(userId, { is_followed: false });
+ });
});
});