summaryrefslogtreecommitdiff
path: root/spec/frontend/sidebar/components/reviewers
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/sidebar/components/reviewers')
-rw-r--r--spec/frontend/sidebar/components/reviewers/reviewer_title_spec.js5
-rw-r--r--spec/frontend/sidebar/components/reviewers/reviewers_spec.js4
-rw-r--r--spec/frontend/sidebar/components/reviewers/sidebar_reviewers_spec.js3
-rw-r--r--spec/frontend/sidebar/components/reviewers/uncollapsed_reviewer_list_spec.js153
4 files changed, 111 insertions, 54 deletions
diff --git a/spec/frontend/sidebar/components/reviewers/reviewer_title_spec.js b/spec/frontend/sidebar/components/reviewers/reviewer_title_spec.js
index 68ecd62e4c6..0f595ab21a5 100644
--- a/spec/frontend/sidebar/components/reviewers/reviewer_title_spec.js
+++ b/spec/frontend/sidebar/components/reviewers/reviewer_title_spec.js
@@ -16,11 +16,6 @@ describe('ReviewerTitle component', () => {
});
};
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- });
-
describe('reviewer title', () => {
it('renders reviewer', () => {
wrapper = createComponent({
diff --git a/spec/frontend/sidebar/components/reviewers/reviewers_spec.js b/spec/frontend/sidebar/components/reviewers/reviewers_spec.js
index 229f7ffbe04..016ec9225da 100644
--- a/spec/frontend/sidebar/components/reviewers/reviewers_spec.js
+++ b/spec/frontend/sidebar/components/reviewers/reviewers_spec.js
@@ -35,10 +35,6 @@ describe('Reviewer component', () => {
const findCollapsedChildren = () => wrapper.findAll('.sidebar-collapsed-icon > *');
- afterEach(() => {
- wrapper.destroy();
- });
-
describe('No reviewers/users', () => {
it('displays no reviewer icon when collapsed', () => {
createWrapper();
diff --git a/spec/frontend/sidebar/components/reviewers/sidebar_reviewers_spec.js b/spec/frontend/sidebar/components/reviewers/sidebar_reviewers_spec.js
index 57ae146a27a..a221d28704b 100644
--- a/spec/frontend/sidebar/components/reviewers/sidebar_reviewers_spec.js
+++ b/spec/frontend/sidebar/components/reviewers/sidebar_reviewers_spec.js
@@ -44,9 +44,6 @@ describe('sidebar reviewers', () => {
});
afterEach(() => {
- wrapper.destroy();
- wrapper = null;
-
SidebarService.singleton = null;
SidebarStore.singleton = null;
SidebarMediator.singleton = null;
diff --git a/spec/frontend/sidebar/components/reviewers/uncollapsed_reviewer_list_spec.js b/spec/frontend/sidebar/components/reviewers/uncollapsed_reviewer_list_spec.js
index d00c8dcb653..66bc1f393ae 100644
--- a/spec/frontend/sidebar/components/reviewers/uncollapsed_reviewer_list_spec.js
+++ b/spec/frontend/sidebar/components/reviewers/uncollapsed_reviewer_list_spec.js
@@ -1,9 +1,10 @@
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import { TEST_HOST } from 'helpers/test_constants';
import ReviewerAvatarLink from '~/sidebar/components/reviewers/reviewer_avatar_link.vue';
import UncollapsedReviewerList from '~/sidebar/components/reviewers/uncollapsed_reviewer_list.vue';
-const userDataMock = () => ({
+const userDataMock = ({ approved = false } = {}) => ({
id: 1,
name: 'Root',
state: 'active',
@@ -14,14 +15,21 @@ const userDataMock = () => ({
canMerge: true,
canUpdate: true,
reviewed: true,
- approved: false,
+ approved,
},
});
describe('UncollapsedReviewerList component', () => {
let wrapper;
- const reviewerApprovalIcons = () => wrapper.findAll('[data-testid="re-approved"]');
+ const findAllRerequestButtons = () => wrapper.findAll('[data-testid="re-request-button"]');
+ const findAllReviewerApprovalIcons = () => wrapper.findAll('[data-testid="approved"]');
+ const findAllReviewedNotApprovedIcons = () =>
+ wrapper.findAll('[data-testid="reviewed-not-approved"]');
+ const findAllReviewerAvatarLinks = () => wrapper.findAllComponents(ReviewerAvatarLink);
+
+ const hasApprovalIconAnimation = () =>
+ findAllReviewerApprovalIcons().at(0).classes('merge-request-approved-icon');
function createComponent(props = {}, glFeatures = {}) {
const propsData = {
@@ -38,10 +46,6 @@ describe('UncollapsedReviewerList component', () => {
});
}
- afterEach(() => {
- wrapper.destroy();
- });
-
describe('single reviewer', () => {
const user = userDataMock();
@@ -52,27 +56,17 @@ describe('UncollapsedReviewerList component', () => {
});
it('only has one user', () => {
- expect(wrapper.findAllComponents(ReviewerAvatarLink).length).toBe(1);
+ expect(findAllReviewerAvatarLinks()).toHaveLength(1);
});
it('shows one user with avatar, and author name', () => {
- expect(wrapper.text()).toContain(user.name);
+ expect(wrapper.text()).toBe(user.name);
});
it('renders re-request loading icon', async () => {
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- await wrapper.setData({ loadingStates: { 1: 'loading' } });
+ await findAllRerequestButtons().at(0).vm.$emit('click');
- expect(wrapper.find('[data-testid="re-request-button"]').props('loading')).toBe(true);
- });
-
- it('renders re-request success icon', async () => {
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- await wrapper.setData({ loadingStates: { 1: 'success' } });
-
- expect(wrapper.find('[data-testid="re-request-success"]').exists()).toBe(true);
+ expect(findAllRerequestButtons().at(0).props('loading')).toBe(true);
});
});
@@ -88,51 +82,126 @@ describe('UncollapsedReviewerList component', () => {
approved: true,
},
};
+ const user3 = {
+ ...user,
+ id: 3,
+ name: 'lizabeth-wilderman',
+ username: 'lizabeth-wilderman',
+ mergeRequestInteraction: {
+ ...user.mergeRequestInteraction,
+ approved: false,
+ reviewed: true,
+ },
+ };
beforeEach(() => {
createComponent({
- users: [user, user2],
+ users: [user, user2, user3],
});
});
- it('has both users', () => {
- expect(wrapper.findAllComponents(ReviewerAvatarLink).length).toBe(2);
+ it('has three users', () => {
+ expect(findAllReviewerAvatarLinks()).toHaveLength(3);
});
- it('shows both users with avatar, and author name', () => {
+ it('shows all users with avatar, and author name', () => {
expect(wrapper.text()).toContain(user.name);
expect(wrapper.text()).toContain(user2.name);
+ expect(wrapper.text()).toContain(user3.name);
});
it('renders approval icon', () => {
- expect(reviewerApprovalIcons().length).toBe(1);
+ expect(findAllReviewerApprovalIcons()).toHaveLength(1);
});
it('shows that hello-world approved', () => {
- const icon = reviewerApprovalIcons().at(0);
+ const icon = findAllReviewerApprovalIcons().at(0);
- expect(icon.attributes('title')).toEqual('Approved by @hello-world');
+ expect(icon.attributes('title')).toBe('Approved by @hello-world');
+ });
+
+ it('shows that lizabeth-wilderman reviewed but did not approve', () => {
+ const icon = findAllReviewedNotApprovedIcons().at(1);
+
+ expect(icon.attributes('title')).toBe('Reviewed by @lizabeth-wilderman but not yet approved');
});
it('renders re-request loading icon', async () => {
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- await wrapper.setData({ loadingStates: { 2: 'loading' } });
+ await findAllRerequestButtons().at(1).vm.$emit('click');
- expect(wrapper.findAll('[data-testid="re-request-button"]').length).toBe(2);
- expect(wrapper.findAll('[data-testid="re-request-button"]').at(1).props('loading')).toBe(
- true,
- );
+ const allRerequestButtons = findAllRerequestButtons();
+
+ expect(allRerequestButtons).toHaveLength(3);
+ expect(allRerequestButtons.at(1).props('loading')).toBe(true);
+ });
+ });
+
+ describe('when updating reviewers list', () => {
+ it('does not animate icon on initial page load', () => {
+ const user = userDataMock({ approved: true });
+ createComponent({ users: [user] });
+
+ expect(hasApprovalIconAnimation()).toBe(false);
});
- it('renders re-request success icon', async () => {
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- await wrapper.setData({ loadingStates: { 2: 'success' } });
+ it('does not animate icon when adding a new reviewer', async () => {
+ const user = userDataMock({ approved: true });
+ const anotherUser = { ...user, id: 2 };
+ createComponent({ users: [user] });
+
+ await wrapper.setProps({ users: [user, anotherUser] });
+
+ expect(
+ findAllReviewerApprovalIcons().wrappers.every((w) =>
+ w.classes('merge-request-approved-icon'),
+ ),
+ ).toBe(false);
+ });
+
+ it('removes animation CSS class after 1500ms', async () => {
+ const previousUserState = userDataMock({ approved: false });
+ const currentUserState = userDataMock({ approved: true });
+
+ createComponent({
+ users: [previousUserState],
+ });
+
+ await wrapper.setProps({
+ users: [currentUserState],
+ });
+
+ expect(hasApprovalIconAnimation()).toBe(true);
+
+ jest.advanceTimersByTime(1500);
+ await nextTick();
- expect(wrapper.findAll('[data-testid="re-request-button"]').length).toBe(1);
- expect(wrapper.findAll('[data-testid="re-request-success"]').length).toBe(1);
- expect(wrapper.find('[data-testid="re-request-success"]').exists()).toBe(true);
+ expect(findAllReviewerApprovalIcons().at(0).classes('merge-request-approved-icon')).toBe(
+ false,
+ );
+ });
+
+ describe('when reviewer was present in the list', () => {
+ it.each`
+ previousApprovalState | currentApprovalState | shouldAnimate
+ ${false} | ${true} | ${true}
+ ${true} | ${true} | ${false}
+ `(
+ 'when approval state changes from $previousApprovalState to $currentApprovalState',
+ async ({ previousApprovalState, currentApprovalState, shouldAnimate }) => {
+ const previousUserState = userDataMock({ approved: previousApprovalState });
+ const currentUserState = userDataMock({ approved: currentApprovalState });
+
+ createComponent({
+ users: [previousUserState],
+ });
+
+ await wrapper.setProps({
+ users: [currentUserState],
+ });
+
+ expect(hasApprovalIconAnimation()).toBe(shouldAnimate);
+ },
+ );
});
});
});