Skip to content

Commit e23fc5c

Browse files
Adds pagination, filters and sorting on task requests listing page (#617)
* feat : adds pagination and integrates pagination api * fix: failing tests * refactor: improves accessibility and tests for task requests details
1 parent f9bd3a9 commit e23fc5c

File tree

8 files changed

+464
-177
lines changed

8 files changed

+464
-177
lines changed

__tests__/taskRequests/taskRequest.test.js

Lines changed: 87 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,18 @@ describe('Task Requests', () => {
1919
args: ['--incognito', '--disable-web-security'],
2020
devtools: false,
2121
});
22-
22+
});
23+
beforeEach(async () => {
2324
page = await browser.newPage();
2425

2526
await page.setRequestInterception(true);
2627

2728
page.on('request', (request) => {
2829
if (
2930
request.url() === `${API_BASE_URL}/taskRequests` ||
30-
request.url() === `${API_BASE_URL}/taskRequests?dev=true`
31+
request.url() === `${API_BASE_URL}/taskRequests?dev=true` ||
32+
request.url() ===
33+
`${API_BASE_URL}/taskRequests?size=20&q=status%3Apending+sort%3Acreated-asc&dev=true`
3134
) {
3235
request.respond({
3336
status: 200,
@@ -39,19 +42,37 @@ describe('Task Requests', () => {
3942
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
4043
},
4144
});
45+
} else if (
46+
request.url() ===
47+
`${API_BASE_URL}/taskRequests?size=20&q=status%3Aapproved++sort%3Acreated-asc&dev=true`
48+
) {
49+
const list = [];
50+
for (let i = 0; i < 20; i++) {
51+
list.push(fetchedTaskRequests[0]);
52+
}
53+
request.respond({
54+
status: 200,
55+
contentType: 'application/json',
56+
body: JSON.stringify({
57+
data: list,
58+
next: '/taskRequests?size=20&q=status%3Aapproved++sort%3Acreated-asc&dev=true',
59+
}),
60+
});
4261
} else {
4362
request.continue();
4463
}
4564
});
46-
4765
await page.goto(`${SITE_URL}/taskRequests`);
4866
await page.waitForNetworkIdle();
4967
});
5068

69+
afterEach(async () => {
70+
await page.close();
71+
});
72+
5173
afterAll(async () => {
5274
await browser.close();
5375
});
54-
5576
describe('When the user is super user', () => {
5677
it('should display the task requests card', async () => {
5778
const url = await page.evaluate(() => API_BASE_URL);
@@ -68,11 +89,6 @@ describe('Task Requests', () => {
6889
expect(purpose).toMatch(/test purpose/i);
6990
});
7091
describe('Filter Modal', () => {
71-
beforeAll(async () => {
72-
await page.goto(`${SITE_URL}/taskRequests/?dev=true`);
73-
await page.waitForNetworkIdle();
74-
});
75-
7692
it('should be hidden initially', async () => {
7793
const modal = await page.$('.filter-modal');
7894
expect(
@@ -84,28 +100,63 @@ describe('Task Requests', () => {
84100
const modal = await page.$('.filter-modal');
85101
const filterHead = await page.$('.filter-head');
86102
const filterContainer = await page.$('.filters-container');
87-
88103
expect(filterHead).toBeTruthy();
89104
expect(filterContainer).toBeTruthy();
90-
91105
await page.click('#filter-button');
92106
expect(modal).not.toBeNull();
93107
expect(
94108
await modal.evaluate((el) => el.classList.contains('hidden')),
95109
).toBe(false);
96-
97110
await page.mouse.click(20, 20);
98111
expect(
99112
await modal.evaluate((el) => el.classList.contains('hidden')),
100113
).toBe(true);
101114
});
115+
116+
it('checks if PENDING is checked by default', async () => {
117+
const filterButton = await page.$('#filter-button');
118+
await filterButton.click();
119+
await page.waitForSelector('.filter-modal');
120+
const activeFilter = await page.$('input[value="PENDING"]');
121+
const currentState = await activeFilter.getProperty('checked');
122+
const isChecked = await currentState.jsonValue();
123+
expect(isChecked).toBe(true);
124+
});
125+
126+
it('Selecting filters and clicking on apply should filter task request list', async () => {
127+
let cardsList = await page.$$('.taskRequest__card');
128+
expect(cardsList).not.toBeNull();
129+
const initialLength = cardsList.length;
130+
await page.click('#filter-button');
131+
await page.click('input[value="PENDING"]');
132+
await page.click('input[value="APPROVED"]');
133+
await page.click('#apply-filter-button');
134+
await page.waitForNetworkIdle();
135+
cardsList = await page.$$('.taskRequest__card');
136+
expect(cardsList).not.toBeNull();
137+
expect(cardsList.length).toBeGreaterThanOrEqual(0);
138+
expect(cardsList.length).not.toBe(initialLength);
139+
});
140+
141+
it('clears the filter when the Clear button is clicked', async () => {
142+
const filterButton = await page.$('#filter-button');
143+
await filterButton.click();
144+
await page.waitForSelector('.filter-modal');
145+
const activeFilter = await page.$('input[value="APPROVED"]');
146+
await activeFilter.click();
147+
const clearButton = await page.$('.filter-modal #clear-button');
148+
await clearButton.click();
149+
await page.waitForSelector('.filter-modal', { hidden: true });
150+
const currentState = await activeFilter.getProperty('checked');
151+
const isChecked = await currentState.jsonValue();
152+
expect(isChecked).toBe(false);
153+
});
102154
});
103155

104156
describe('Sort Modal', () => {
105157
it('should be hidden initially', async () => {
106158
const sortModal = await page.$('.sort-modal');
107-
const assigneButton = await page.$('#ASSIGNEE_COUNT');
108-
159+
const assigneButton = await page.$('#REQUESTORS_COUNT_ASC');
109160
expect(
110161
await sortModal.evaluate((el) => el.classList.contains('hidden')),
111162
).toBe(true);
@@ -114,15 +165,15 @@ describe('Task Requests', () => {
114165

115166
it('should toggle visibility sort modal by clicking the sort button and selecting an option', async () => {
116167
const sortModal = await page.$('.sort-modal');
117-
const assigneButton = await page.$('#ASSIGNEE_COUNT');
168+
const assigneButton = await page.$('#REQUESTORS_COUNT_ASC');
118169
const sortHead = await page.$('.sort-head');
119170
const sortContainer = await page.$('.sorts-container');
120171

121172
expect(sortHead).toBeTruthy();
122173
expect(sortContainer).toBeTruthy();
123174

124175
await page.click('.sort-button');
125-
await page.click('#ASSIGNEE_COUNT');
176+
await page.click('#REQUESTORS_COUNT_ASC');
126177
expect(
127178
await assigneButton.evaluate((el) =>
128179
el.classList.contains('selected'),
@@ -131,9 +182,8 @@ describe('Task Requests', () => {
131182
expect(
132183
await sortModal.evaluate((el) => el.classList.contains('hidden')),
133184
).toBe(true);
134-
135185
await page.click('.sort-button');
136-
await page.click('#ASSIGNEE_COUNT');
186+
await page.click('#REQUESTORS_COUNT_ASC');
137187
expect(
138188
await assigneButton.evaluate((el) =>
139189
el.classList.contains('selected'),
@@ -144,6 +194,25 @@ describe('Task Requests', () => {
144194
).toBe(true);
145195
});
146196
});
197+
198+
it('Checks that new items are loaded when scrolled to the bottom', async () => {
199+
await page.click('#filter-button');
200+
await page.click('input[value="PENDING"]');
201+
await page.click('input[value="APPROVED"]');
202+
await page.click('#apply-filter-button');
203+
await page.waitForNetworkIdle();
204+
let taskRequestList = await page.$$('.taskRequest__card');
205+
expect(taskRequestList.length).toBe(20);
206+
await page.evaluate(() => {
207+
const element = document.querySelector('.virtual');
208+
if (element) {
209+
element.scrollIntoView({ behavior: 'auto' });
210+
}
211+
});
212+
await page.waitForNetworkIdle();
213+
taskRequestList = await page.$$('.taskRequest__card');
214+
expect(taskRequestList.length).toBe(40);
215+
});
147216
});
148217
});
149218

mock-data/taskRequests/index.js

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@ const fetchedTaskRequests = [
1414
priority: 'HIGH',
1515
status: 'ASSIGNED',
1616
},
17+
users: [
18+
{
19+
proposedStartDate: 1700304616479,
20+
proposedDeadline: 1700909416479,
21+
userId: 'eChYAP0kUwLo4wQ1gqMV',
22+
status: 'PENDING',
23+
username: 'ajeyak',
24+
first_name: 'Test first_name',
25+
},
26+
],
1727
requestors: [
1828
{
1929
userExists: true,
@@ -60,10 +70,10 @@ const individualTaskReqDetail = {
6070
proposedDeadline: 1699142400000,
6171
description: 'code change 3 days , testing - 2 days. total - 5 days',
6272
userId: 'SooJK37gzjIZfFNH0tlL',
63-
status: 'APPROVED',
73+
status: 'PENDING',
6474
},
6575
],
66-
status: 'APPROVED',
76+
status: 'PENDING',
6777
id: 'dM5wwD9QsiTzi7eG7Oq5',
6878
url: 'http://localhost:3000/taskRequests/dM5wwD9QsiTzi7eG7Oq5',
6979
},
@@ -142,6 +152,14 @@ const urlMappings = {
142152
userInformation,
143153
'https://staging-api.realdevsquad.com/users/userId/SooJK37gzjIZfFNH0tlL':
144154
userInformation,
155+
'https://staging-api.realdevsquad.com/taskRequests?action=approve':
156+
fetchedTaskRequests,
157+
'https://api.realdevsquad.com/taskRequests?action=approve':
158+
fetchedTaskRequests,
159+
'https://staging-api.realdevsquad.com/taskRequests?action=reject':
160+
fetchedTaskRequests,
161+
'https://api.realdevsquad.com/taskRequests?action=reject':
162+
fetchedTaskRequests,
145163
};
146164

147165
module.exports = {

taskRequests/constants.js

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,44 @@ const taskRequestStatus = {
33
APPROVED: 'APPROVED',
44
};
55
const DEV_FEATURE_FLAG = 'dev';
6+
const DEFAULT_PAGE_SIZE = 20;
7+
const Status = {
8+
APPROVED: 'approved',
9+
PENDING: 'pending',
10+
DENIED: 'denied',
11+
};
12+
13+
const Order = {
14+
REQUESTORS_COUNT_ASC: { requestors: 'asc' },
15+
REQUESTORS_COUNT_DESC: { requestors: 'desc' },
16+
CREATED_TIME_DESC: { created: 'desc' },
17+
CREATED_TIME_ASC: { created: 'asc' },
18+
};
619

720
const FILTER_MODAL = 'filter-modal';
821
const FILTER_BUTTON = 'filter-button';
922
const APPLY_FILTER_BUTTON = 'apply-filter-button';
1023
const SEARCH_ELEMENT = 'assignee-search';
1124
const SORT_BUTTON = '.sort-button';
12-
const OLD_FILTER = '.container__filters';
25+
const CLEAR_BUTTON = 'clear-button';
1326
const FILTER_CONTAINER = '.sort-filters';
1427
const SORT_MODAL = 'sort-modal';
15-
const ASSIGNEE_COUNT = 'ASSIGNEE_COUNT';
16-
const ASSIGNEE_DESC = 'ASSIGNEE_COUNT-desc';
17-
const CREATED_TIME = 'CREATED_TIME';
18-
const CREATED_TIME_DESC = 'CREATED_TIME-desc';
28+
const ASSIGNEE_COUNT = 'REQUESTORS_COUNT_ASC';
29+
const ASSIGNEE_DESC = 'REQUESTORS_COUNT_DESC';
30+
const CREATED_TIME = 'CREATED_TIME_ASC';
31+
const CREATED_TIME_DESC = 'CREATED_TIME_DESC';
1932
const BACKDROP = '.backdrop';
33+
const LAST_ELEMENT_CONTAINER = '.virtual';
2034

2135
const MessageStatus = {
2236
SUCCESS: 'SUCCESS',
2337
ERROR: 'ERROR',
2438
};
2539

40+
const TaskRequestAction = {
41+
APPROVE: 'approve',
42+
REJECT: 'reject',
43+
};
2644
const ErrorMessages = {
2745
UNAUTHENTICATED:
2846
'You are unauthenticated to view this section, please login!',

0 commit comments

Comments
 (0)