diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-05-23 03:07:55 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-05-23 03:07:55 +0300 |
commit | 82f96a9ae2529898de0e91ccfad1d6457f3c1975 (patch) | |
tree | 7e189a0d2cef7df67aaa4f709e3f5bc312878cbd /spec/frontend/profile | |
parent | c50e042a392687730db9b8c2607883485b258ae4 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend/profile')
-rw-r--r-- | spec/frontend/profile/components/follow_spec.js | 99 | ||||
-rw-r--r-- | spec/frontend/profile/components/followers_tab_spec.js | 119 | ||||
-rw-r--r-- | spec/frontend/profile/components/following_tab_spec.js | 2 |
3 files changed, 207 insertions, 13 deletions
diff --git a/spec/frontend/profile/components/follow_spec.js b/spec/frontend/profile/components/follow_spec.js new file mode 100644 index 00000000000..2555e41257f --- /dev/null +++ b/spec/frontend/profile/components/follow_spec.js @@ -0,0 +1,99 @@ +import { GlAvatarLabeled, GlAvatarLink, GlLoadingIcon, GlPagination } from '@gitlab/ui'; +import { shallowMount } from '@vue/test-utils'; + +import users from 'test_fixtures/api/users/followers/get.json'; +import Follow from '~/profile/components/follow.vue'; +import { DEFAULT_PER_PAGE } from '~/api'; + +jest.mock('~/rest_api'); + +describe('FollowersTab', () => { + let wrapper; + + const defaultPropsData = { + users, + loading: false, + page: 1, + totalItems: 50, + }; + + const createComponent = ({ propsData = {} } = {}) => { + wrapper = shallowMount(Follow, { + propsData: { + ...defaultPropsData, + ...propsData, + }, + }); + }; + + const findPagination = () => wrapper.findComponent(GlPagination); + const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon); + + describe('when `loading` prop is `true`', () => { + it('renders loading icon', () => { + createComponent({ propsData: { loading: true } }); + + expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(true); + }); + }); + + describe('when `loading` prop is `false`', () => { + beforeEach(() => { + createComponent(); + }); + + it('does not render loading icon', () => { + expect(findLoadingIcon().exists()).toBe(false); + }); + + it('renders users', () => { + const avatarLinksHref = wrapper + .findAllComponents(GlAvatarLink) + .wrappers.map((avatarLinkWrapper) => avatarLinkWrapper.attributes('href')); + const expectedAvatarLinksHref = users.map((user) => user.web_url); + + const avatarLabeledProps = wrapper + .findAllComponents(GlAvatarLabeled) + .wrappers.map((avatarLabeledWrapper) => ({ + label: avatarLabeledWrapper.props('label'), + subLabel: avatarLabeledWrapper.props('subLabel'), + size: avatarLabeledWrapper.attributes('size'), + entityName: avatarLabeledWrapper.attributes('entity-name'), + entityId: avatarLabeledWrapper.attributes('entity-id'), + src: avatarLabeledWrapper.attributes('src'), + })); + const expectedAvatarLabeledProps = users.map((user) => ({ + src: user.avatar_url, + size: '48', + entityId: user.id.toString(), + entityName: user.name, + label: user.name, + subLabel: user.username, + })); + + expect(avatarLinksHref).toEqual(expectedAvatarLinksHref); + expect(avatarLabeledProps).toEqual(expectedAvatarLabeledProps); + }); + + it('renders `GlPagination` and passes correct props', () => { + expect(wrapper.findComponent(GlPagination).props()).toMatchObject({ + align: 'center', + value: defaultPropsData.page, + totalItems: defaultPropsData.totalItems, + perPage: DEFAULT_PER_PAGE, + prevText: Follow.i18n.prev, + nextText: Follow.i18n.next, + }); + }); + + describe('when `GlPagination` emits `input` event', () => { + it('emits `pagination-input` event', () => { + const nextPage = defaultPropsData.page + 1; + + findPagination().vm.$emit('input', nextPage); + + expect(wrapper.emitted('pagination-input')).toEqual([[nextPage]]); + }); + }); + }); +}); diff --git a/spec/frontend/profile/components/followers_tab_spec.js b/spec/frontend/profile/components/followers_tab_spec.js index 9cc5bdea9be..0370005d0a4 100644 --- a/spec/frontend/profile/components/followers_tab_spec.js +++ b/spec/frontend/profile/components/followers_tab_spec.js @@ -1,32 +1,127 @@ import { GlBadge, GlTab } from '@gitlab/ui'; +import { shallowMount } from '@vue/test-utils'; +import followers from 'test_fixtures/api/users/followers/get.json'; import { s__ } from '~/locale'; import FollowersTab from '~/profile/components/followers_tab.vue'; -import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; +import Follow from '~/profile/components/follow.vue'; +import { getUserFollowers } from '~/rest_api'; +import { createAlert } from '~/alert'; +import waitForPromises from 'helpers/wait_for_promises'; +import { stubComponent } from 'helpers/stub_component'; + +jest.mock('~/rest_api'); +jest.mock('~/alert'); describe('FollowersTab', () => { let wrapper; const createComponent = () => { - wrapper = shallowMountExtended(FollowersTab, { + wrapper = shallowMount(FollowersTab, { provide: { - followers: 2, + followersCount: 2, + userId: 1, + }, + stubs: { + GlTab: stubComponent(GlTab, { + template: ` + <li> + <slot name="title"></slot> + <slot></slot> + </li> + `, + }), }, }); }; - it('renders `GlTab` and sets title', () => { - createComponent(); + const findGlBadge = () => wrapper.findComponent(GlBadge); + const findFollow = () => wrapper.findComponent(Follow); + + describe('when API request is loading', () => { + beforeEach(() => { + getUserFollowers.mockReturnValueOnce(new Promise(() => {})); + createComponent(); + }); + + it('renders `Follow` component and sets `loading` prop to `true`', () => { + expect(findFollow().props('loading')).toBe(true); + }); + }); + + describe('when API request is successful', () => { + beforeEach(async () => { + getUserFollowers.mockResolvedValueOnce({ + data: followers, + headers: { 'X-TOTAL': '6' }, + }); + createComponent(); + + await waitForPromises(); + }); + + it('renders `GlTab` and sets title', () => { + expect(wrapper.findComponent(GlTab).text()).toContain(s__('UserProfile|Followers')); + }); + + it('renders `GlBadge`, sets size and content', () => { + expect(findGlBadge().props('size')).toBe('sm'); + expect(findGlBadge().text()).toBe('2'); + }); + + it('renders `Follow` component and passes correct props', () => { + expect(findFollow().props()).toMatchObject({ + users: followers, + loading: false, + page: 1, + totalItems: 6, + }); + }); + + describe('when `Follow` component emits `pagination-input` event', () => { + it('calls API and updates `users` and `page` props', async () => { + const lastFollower = followers.at(-1); + const paginationFollowers = [ + { + ...lastFollower, + id: lastFollower.id + 1, + name: 'page 2 follower', + }, + ]; + + getUserFollowers.mockResolvedValueOnce({ + data: paginationFollowers, + headers: { 'X-TOTAL': '6' }, + }); - expect(wrapper.findComponent(GlTab).element.textContent).toContain( - s__('UserProfile|Followers'), - ); + findFollow().vm.$emit('pagination-input', 2); + + await waitForPromises(); + + expect(findFollow().props()).toMatchObject({ + users: paginationFollowers, + loading: false, + page: 2, + totalItems: 6, + }); + }); + }); }); - it('renders `GlBadge`, sets size and content', () => { - createComponent(); + describe('when API request is not successful', () => { + beforeEach(async () => { + getUserFollowers.mockRejectedValueOnce(new Error()); + createComponent(); - expect(wrapper.findComponent(GlBadge).attributes('size')).toBe('sm'); - expect(wrapper.findComponent(GlBadge).element.textContent).toBe('2'); + await waitForPromises(); + }); + + it('shows error alert', () => { + expect(createAlert).toHaveBeenCalledWith({ + message: FollowersTab.i18n.errorMessage, + error: new Error(), + captureError: true, + }); + }); }); }); diff --git a/spec/frontend/profile/components/following_tab_spec.js b/spec/frontend/profile/components/following_tab_spec.js index c9d56360c3e..c0583cf4877 100644 --- a/spec/frontend/profile/components/following_tab_spec.js +++ b/spec/frontend/profile/components/following_tab_spec.js @@ -10,7 +10,7 @@ describe('FollowingTab', () => { const createComponent = () => { wrapper = shallowMountExtended(FollowingTab, { provide: { - followees: 3, + followeesCount: 3, }, }); }; |