1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
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 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 = shallowMount(FollowersTab, {
provide: {
followersCount: 2,
userId: 1,
},
stubs: {
GlTab: stubComponent(GlTab, {
template: `
<li>
<slot name="title"></slot>
<slot></slot>
</li>
`,
}),
},
});
};
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,
currentUserEmptyStateTitle: FollowersTab.i18n.currentUserEmptyStateTitle,
visitorEmptyStateTitle: FollowersTab.i18n.visitorEmptyStateTitle,
});
});
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' },
});
findFollow().vm.$emit('pagination-input', 2);
await waitForPromises();
expect(findFollow().props()).toMatchObject({
users: paginationFollowers,
loading: false,
page: 2,
totalItems: 6,
});
});
});
});
describe('when API request is not successful', () => {
beforeEach(async () => {
getUserFollowers.mockRejectedValueOnce(new Error());
createComponent();
await waitForPromises();
});
it('shows error alert', () => {
expect(createAlert).toHaveBeenCalledWith({
message: FollowersTab.i18n.errorMessage,
error: new Error(),
captureError: true,
});
});
});
});
|