Skip to content

Commit

Permalink
Feature: edit extension request before approval or rejection (#910)
Browse files Browse the repository at this point in the history
* Added input validation and toast based on api response - behind dev flag.

* Added tests for input validation and edit button under dev flag.

* Added dev flag in ER update api request.

* Resolved failing test cases.

* Updated failing tests based on new changes.

* Added missing tests.

* Changed the confusing dev feature flag name.

* Added Error Handling for Unavailable user details.

* Changes style values to 8/4 metric and made toast timing a constant.

* Changed the getSelfUser endpoint to new one.

* Updated the getSelfUser() url for tests.

* Fix: Prevent Code Format Overflow in Task Request Page (#927)

added code css property

* Added input validation and toast based on api response - behind dev flag.

* Took latest pull from develop and merged it.

* Added missing tests.

* Changes style values to 8/4 metric and made toast timing a constant.

* Made shouldDisplayEditButton() a pure function.

* Added tests for input validation and edit button under dev flag.

* Updated failing tests based on new changes.

* Added missing tests.

* Made shouldDisplayEditButton() a pure function.

* Rebased and removed duplicate tests.

---------

Co-authored-by: Rishi <[email protected]>
Co-authored-by: Anuj Chhikara <[email protected]>
  • Loading branch information
3 people authored Dec 18, 2024
1 parent 8ce0841 commit 1ecffc5
Show file tree
Hide file tree
Showing 5 changed files with 376 additions and 15 deletions.
161 changes: 160 additions & 1 deletion __tests__/extension-requests/extension-requests.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ describe('Tests the Extension Requests Screen', () => {
},
body: JSON.stringify(extensionRequestListForAuditLogs),
});
} else if (url === `${STAGING_API_URL}/users/self`) {
} else if (url === `${STAGING_API_URL}/users?profile=true`) {
interceptedRequest.respond({
status: 200,
contentType: 'application/json',
Expand Down Expand Up @@ -654,6 +654,165 @@ describe('Tests the Extension Requests Screen', () => {
expect(hasSkeletonClassAfter).toBe(false);
});

it('shows error messages for empty title and reason inputs on update under dev feature flag', async () => {
await page.goto(`${LOCAL_TEST_PAGE_URL}/extension-requests/?dev=true`);
const editButtonSelector = '[data-testid="edit-button"]';
const editButton = await page.$(editButtonSelector);
if (!editButton) {
return;
}
await page.click(editButtonSelector);
const updateButtonSelector = '[data-testid="update-button"]';
const titleInputSelector = '[data-testid="title-text-input"]';
const reasonInputSelector = '[data-testid="reason-input-text-area"]';
const titleErrorSelector = '[data-testid="title-input-error"]';
const reasonErrorSelector = '[data-testid="reason-input-error"]';

await page.evaluate((selector) => {
const element = document.querySelector(selector);
if (element) element.value = '';
}, titleInputSelector);

await page.evaluate((selector) => {
const element = document.querySelector(selector);
if (element) element.value = '';
}, reasonInputSelector);

await page.click(updateButtonSelector);

const isTitleErrorVisible = await page
.$eval(titleErrorSelector, (el) => el && !el.classList.contains('hidden'))
.catch(() => false);

const isReasonErrorVisible = await page
.$eval(
reasonErrorSelector,
(el) => el && !el.classList.contains('hidden'),
)
.catch(() => false);
expect(isTitleErrorVisible).toBe(true);
expect(isReasonErrorVisible).toBe(true);
});

it('shows error message if deadline is set to past date under dev feature flag', async () => {
await page.goto(`${LOCAL_TEST_PAGE_URL}/extension-requests/?dev=true`);
const editButtonSelector = '[data-testid="edit-button"]';
const editButton = await page.$(editButtonSelector);
if (!editButton) {
return;
}

await page.click(editButtonSelector);

const extensionInputSelector = '[data-testid="extension-input"]';
const extensionErrorSelector = '[data-testid="extension-input-error"]';
await page.$eval(extensionInputSelector, (input) => {
input.value = '2020-01-01';
});
await page.click('[data-testid="update-button"]');
const isExtensionErrorVisible = await page.$eval(
extensionErrorSelector,
(el) =>
!el.classList.contains('hidden') &&
el.innerText.includes("Past date can't be the new deadline"),
);
expect(isExtensionErrorVisible).toBe(true);
});

it('hides edit button and displays update wrapper on successful update under dev feature flag', async () => {
await page.goto(`${LOCAL_TEST_PAGE_URL}/extension-requests/?dev=true`);
const editButtonSelector = '[data-testid="edit-button"]';
const editButton = await page.$(editButtonSelector);
if (!editButton) {
return;
}

await page.click(editButtonSelector);

const updateButtonSelector = '[data-testid="update-button"]';
const updateWrapperSelector = '[data-testid="update-wrapper"]';

await page.type('[data-testid="title-text-input"]', 'Valid Title');
await page.type('[data-testid="reason-input-text-area"]', 'Valid Reason');
await page.type('[data-testid="extension-input"]', '2050-01-01');

await page.click(updateButtonSelector);

const isEditButtonHidden = await page.$eval(editButtonSelector, (el) =>
el.classList.contains('hidden'),
);
const isUpdateWrapperVisible = await page.$eval(
updateWrapperSelector,
(el) => !el.classList.contains('hidden'),
);
expect(isEditButtonHidden).toBe(true);
expect(isUpdateWrapperVisible).toBe(true);
});

it('handles long title and long reason properly under dev feature flag', async () => {
await page.goto(`${LOCAL_TEST_PAGE_URL}/extension-requests/?dev=true`);

const editButtonSelector = '[data-testid="edit-button"]';
const titleInputSelector = '[data-testid="title-text-input"]';
const reasonInputSelector = '[data-testid="reason-input-text-area"]';
const titleDisplaySelector = '.title-text';
const reasonDisplaySelector = '.reason-text';

const longTitle = 'A'.repeat(300);
const longReason = 'This is a very long reason '.repeat(50);

const editButton = await page.$(editButtonSelector);
if (!editButton) {
return;
}
await page.click(editButtonSelector);

await page.type(titleInputSelector, longTitle);
await page.type(reasonInputSelector, longReason);

const isTitleTruncated = await page.$eval(
titleDisplaySelector,
(el) => window.getComputedStyle(el).textOverflow === 'ellipsis',
);

const isReasonWrapped = await page.$eval(
reasonDisplaySelector,
(el) => window.getComputedStyle(el).whiteSpace === 'normal',
);

expect(isTitleTruncated).toBe(true);
expect(isReasonWrapped).toBe(true);
});

it('displays an error message for invalid date format under dev feature flag', async () => {
await page.goto(`${LOCAL_TEST_PAGE_URL}/extension-requests/?dev=true`);

const editButtonSelector = '[data-testid="edit-button"]';
const editButton = await page.$(editButtonSelector);
if (!editButton) {
return;
}

await page.click(editButtonSelector);

const extensionInputSelector = '[data-testid="extension-input"]';
const extensionErrorSelector = '[data-testid="extension-input-error"]';

await page.$eval(extensionInputSelector, (input) => {
input.value = 'invalid-date';
});
await page.click('[data-testid="update-button"]');

const isExtensionErrorVisible = await page.$eval(
extensionErrorSelector,
(el) =>
!el.classList.contains('hidden') &&
el.innerText.includes('Invalid date format.'),
);

expect(isExtensionErrorVisible).toBe(true);
});

it('Checks whether the card is not removed from display when api call is unsuccessful', async () => {
const extensionCards = await page.$$('.extension-card');

Expand Down
2 changes: 2 additions & 0 deletions extension-requests/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,5 @@ const SORT_ASC_ICON = 'asc-sort-icon';
const SORT_DESC_ICON = 'desc-sort-icon';
const OLDEST_FIRST = 'Oldest first';
const NEWEST_FIRST = 'Newest first';

const UPDATE_TOAST_TIMING = 3000;
8 changes: 5 additions & 3 deletions extension-requests/local-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const Order = {
};
async function getSelfUser() {
try {
const res = await fetch(`${API_BASE_URL}/users/self`, {
const res = await fetch(`${API_BASE_URL}/users?profile=true`, {
method: 'GET',
credentials: 'include',
headers: {
Expand Down Expand Up @@ -103,8 +103,10 @@ const parseExtensionRequestParams = (uri, nextPageParamsObject) => {
return nextPageParamsObject;
};

async function updateExtensionRequest({ id, body }) {
const url = `${API_BASE_URL}/extension-requests/${id}`;
async function updateExtensionRequest({ id, body, underDevFeatureFlag }) {
const url = underDevFeatureFlag
? `${API_BASE_URL}/extension-requests/${id}?dev=true`
: `${API_BASE_URL}/extension-requests/${id}`;
const res = await fetch(url, {
credentials: 'include',
method: 'PATCH',
Expand Down
Loading

0 comments on commit 1ecffc5

Please sign in to comment.