diff --git a/__tests__/applications/applications.test.js b/__tests__/applications/applications.test.js
index b214a112..941ae8ab 100644
--- a/__tests__/applications/applications.test.js
+++ b/__tests__/applications/applications.test.js
@@ -4,6 +4,7 @@ const {
fetchedApplications,
acceptedApplications,
pendingApplications,
+ changesRequestedApplications,
} = require('../../mock-data/applications');
const { superUserForAudiLogs } = require('../../mock-data/users');
const {
@@ -73,13 +74,13 @@ describe('Applications page', () => {
body: JSON.stringify(superUserForAudiLogs),
});
} else if (
- url === `${STAGING_API_URL}/applications/lavEduxsb2C5Bl4s289P`
+ url === `${STAGING_API_URL}/applications/lavEduxsb2C5Bl4s289P/feedback`
) {
interceptedRequest.respond({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
- message: 'application updated successfully!',
+ message: 'Application feedback submitted successfully',
}),
headers: {
'Access-Control-Allow-Origin': '*',
@@ -120,6 +121,23 @@ describe('Applications page', () => {
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
},
});
+ } else if (
+ url ===
+ `${STAGING_API_URL}/applications?size=6&status=changes_requested&dev=true`
+ ) {
+ interceptedRequest.respond({
+ status: 200,
+ contentType: 'application/json',
+ body: JSON.stringify({
+ applications: changesRequestedApplications,
+ totalCount: changesRequestedApplications.length,
+ }),
+ headers: {
+ 'Access-Control-Allow-Origin': '*',
+ 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
+ 'Access-Control-Allow-Headers': 'Content-Type, Authorization',
+ },
+ });
} else {
interceptedRequest.continue();
}
@@ -285,7 +303,7 @@ describe('Applications page', () => {
it.skip('should show toast message with application updated successfully', async function () {
await page.click('.view-details-button');
- await page.click('.application-details-accept');
+ await page.click('[data-testid="application-details-accept"]');
const toast = await page.$('#toast');
expect(await toast.evaluate((el) => el.classList.contains('hidden'))).toBe(
false,
@@ -334,7 +352,7 @@ describe('Applications page', () => {
await page.waitForSelector('.application-card');
await page.click('.application-card');
- await page.click('.application-details-accept');
+ await page.click('[data-testid="application-details-accept"]');
await page.waitForSelector('[data-testid="toast-component"].show');
const toastComponent = await page.$('[data-testid="toast-component"]');
expect(
@@ -355,7 +373,7 @@ describe('Applications page', () => {
).toBe(false);
const toastMessage = await page.$('[data-testid="toast-message"]');
expect(await toastMessage.evaluate((el) => el.textContent)).toBe(
- 'application updated successfully!',
+ 'Application feedback submitted successfully',
);
});
@@ -371,4 +389,209 @@ describe('Applications page', () => {
const applicationCardElements = await page.$$('.application-card');
expect(applicationCardElements.length).toBe(acceptedApplications.length);
});
+
+ it('should show success toast after requesting changes for an application', async function () {
+ await page.goto(
+ `${LOCAL_TEST_PAGE_URL}/applications?dev=true&status=pending`,
+ );
+ await page.waitForSelector('.application-card');
+ await page.click('.application-card');
+
+ await page.type(
+ '.application-textarea',
+ 'Please update your introduction.',
+ );
+
+ await page.click('[data-testid="application-details-request-changes"]');
+ await page.waitForSelector('[data-testid="toast-component"].show');
+ const toastComponent = await page.$('[data-testid="toast-component"]');
+ expect(
+ await toastComponent.evaluate((el) => el.classList.contains('show')),
+ ).toBe(true);
+ expect(
+ await toastComponent.evaluate((el) => el.classList.contains('hide')),
+ ).toBe(false);
+ expect(
+ await toastComponent.evaluate((el) =>
+ el.classList.contains('success__toast'),
+ ),
+ ).toBe(true);
+ expect(
+ await toastComponent.evaluate((el) =>
+ el.classList.contains('error__toast'),
+ ),
+ ).toBe(false);
+ const toastMessage = await page.$('[data-testid="toast-message"]');
+ expect(await toastMessage.evaluate((el) => el.textContent)).toBe(
+ 'Application feedback submitted successfully',
+ );
+ });
+
+ it('should show error toast when requesting changes without providing feedback', async function () {
+ await page.goto(
+ `${LOCAL_TEST_PAGE_URL}/applications?dev=true&status=pending`,
+ );
+ await page.waitForSelector('.application-card');
+ await page.click('.application-card');
+
+ await page.$eval('.application-textarea', (el) => (el.value = ''));
+ await page.click('[data-testid="application-details-request-changes"]');
+ await page.waitForSelector('[data-testid="toast-component"].show');
+ const toastComponent = await page.$('[data-testid="toast-component"]');
+ expect(
+ await toastComponent.evaluate((el) => el.classList.contains('show')),
+ ).toBe(true);
+ expect(
+ await toastComponent.evaluate((el) =>
+ el.classList.contains('error__toast'),
+ ),
+ ).toBe(true);
+ const toastMessage = await page.$('[data-testid="toast-message"]');
+ expect(await toastMessage.evaluate((el) => el.textContent)).toBe(
+ 'Please provide feedback before requesting changes.',
+ );
+ });
+
+ it('should hide action buttons after successfully updating application status to changes_requested', async function () {
+ await page.goto(
+ `${LOCAL_TEST_PAGE_URL}/applications?dev=true&status=pending`,
+ );
+ await page.waitForSelector('.application-card');
+ await page.click('.application-card');
+
+ await page.type(
+ '.application-textarea',
+ 'Please update your introduction.',
+ );
+
+ await page.click('[data-testid="application-details-request-changes"]');
+ await page.waitForSelector('[data-testid="toast-component"].show');
+
+ const acceptBtn = await page.$(
+ '[data-testid="application-details-accept"]',
+ );
+ const rejectBtn = await page.$(
+ '[data-testid="application-details-reject"]',
+ );
+ const requestChangesBtn = await page.$(
+ '[data-testid="application-details-request-changes"]',
+ );
+
+ expect(
+ await acceptBtn.evaluate((el) => el.classList.contains('hidden')),
+ ).toBe(true);
+ expect(
+ await rejectBtn.evaluate((el) => el.classList.contains('hidden')),
+ ).toBe(true);
+ expect(
+ await requestChangesBtn.evaluate((el) => el.classList.contains('hidden')),
+ ).toBe(true);
+ });
+
+ it('should display "Changes were already requested" message after successfully requesting changes', async function () {
+ await page.goto(
+ `${LOCAL_TEST_PAGE_URL}/applications?dev=true&status=pending`,
+ );
+ await page.waitForSelector('.application-card');
+ await page.click('.application-card');
+
+ await page.type(
+ '.application-textarea',
+ 'Please update your introduction.',
+ );
+
+ await page.click('[data-testid="application-details-request-changes"]');
+ await page.waitForSelector('[data-testid="toast-component"].show');
+
+ const statusMsg = await page.$(
+ '.application-details-changes-requested-msg',
+ );
+ expect(statusMsg).toBeTruthy();
+ expect(await statusMsg.evaluate((el) => el.textContent)).toBe(
+ 'Changes were already requested',
+ );
+ });
+
+ it('should send correct PATCH request when requesting changes', async function () {
+ let feedbackRequestBody = null;
+ let feedbackRequestMethod = null;
+
+ await page.goto(
+ `${LOCAL_TEST_PAGE_URL}/applications?dev=true&status=pending`,
+ );
+ await page.waitForSelector('.application-card');
+
+ page.on('request', (request) => {
+ if (
+ request.url().includes('/applications/') &&
+ request.url().includes('/feedback')
+ ) {
+ feedbackRequestMethod = request.method();
+ feedbackRequestBody = JSON.parse(request.postData());
+ }
+ });
+
+ await page.click('.application-card');
+
+ await page.$eval('.application-textarea', (el) => (el.value = ''));
+ await page.type(
+ '.application-textarea',
+ 'Please update your introduction.',
+ );
+
+ await page.click('[data-testid="application-details-request-changes"]');
+ await page.waitForSelector('[data-testid="toast-component"].show');
+
+ expect(feedbackRequestBody).toEqual({
+ status: 'changes_requested',
+ feedback: 'Please update your introduction.',
+ });
+ });
+
+ it('should display existing feedback in a list', async function () {
+ await page.click('.view-details-button');
+ await page.waitForSelector('.feedback-list');
+ const feedbackItems = await page.$$('.feedback-item');
+ expect(feedbackItems.length).toBe(1);
+
+ const feedbackText = await feedbackItems[0].$eval(
+ '.feedback-text',
+ (el) => el.innerText,
+ );
+ expect(feedbackText).toBe('estee');
+
+ const feedbackMeta = await feedbackItems[0].$eval(
+ '.feedback-meta',
+ (el) => el.innerText,
+ );
+ expect(feedbackMeta).toContain('Reviewer');
+ });
+
+ it('should show action buttons when application status is changes_requested', async function () {
+ await page.goto(
+ `${LOCAL_TEST_PAGE_URL}/applications?dev=true&status=changes_requested`,
+ );
+ await page.waitForSelector('.application-card');
+ await page.click('.application-card');
+
+ const acceptBtn = await page.$(
+ '[data-testid="application-details-accept"]',
+ );
+ const rejectBtn = await page.$(
+ '[data-testid="application-details-reject"]',
+ );
+ const requestChangesBtn = await page.$(
+ '[data-testid="application-details-request-changes"]',
+ );
+
+ expect(
+ await acceptBtn.evaluate((el) => el.classList.contains('hidden')),
+ ).toBe(false);
+ expect(
+ await rejectBtn.evaluate((el) => el.classList.contains('hidden')),
+ ).toBe(false);
+ expect(
+ await requestChangesBtn.evaluate((el) => el.classList.contains('hidden')),
+ ).toBe(false);
+ });
});
diff --git a/applications/index.html b/applications/index.html
index af5e1c02..4d558f46 100644
--- a/applications/index.html
+++ b/applications/index.html
@@ -125,15 +125,30 @@
+
+