From cf01917f00df76b52a03e87b37b58935e5b605ac Mon Sep 17 00:00:00 2001 From: sunilk429 <160393886+sunilk429@users.noreply.github.com> Date: Thu, 5 Dec 2024 00:34:35 +0500 Subject: [PATCH] Fix/remove outdated fields (#914) * featureUrl removed * removed feature/group * change class inputBox instead radioButton * task level section removed * unncessary object destruction under featureflag removed * status=available typo fixed * tests added for updated changes * Tests fixed * Added data-testid for testing,also added new tests * Test api updated to staging * refactored for readability * created a constants file * API_BASE_URL changed to stating for testing --- __tests__/tasks/task-dependency.test.js | 210 ++++++++++++++++-------- task/constants.js | 4 + task/index.html | 61 +++---- task/script.js | 109 ++++++++---- 4 files changed, 259 insertions(+), 125 deletions(-) create mode 100644 task/constants.js diff --git a/__tests__/tasks/task-dependency.test.js b/__tests__/tasks/task-dependency.test.js index 26e2035e..3043e26d 100644 --- a/__tests__/tasks/task-dependency.test.js +++ b/__tests__/tasks/task-dependency.test.js @@ -16,49 +16,37 @@ describe('Input box', () => { args: ['--incognito', '--disable-web-security'], devtools: false, }); - page = await browser.newPage(); - await page.setRequestInterception(true); - - page.on('request', (interceptedRequest) => { - const url = interceptedRequest.url(); - if (url === `${STAGING_API_URL}/levels`) { - interceptedRequest.respond({ - status: 200, - contentType: 'application/json', - headers: { - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization', - }, - body: JSON.stringify(levels), - }); - } else if (url === `${STAGING_API_URL}/users`) { - interceptedRequest.respond({ - status: 200, - contentType: 'application/json', - headers: { - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization', - }, - body: JSON.stringify(users), - }); - } else if (url === `${STAGING_API_URL}/tags`) { - interceptedRequest.respond({ - status: 200, - contentType: 'application/json', - headers: { - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization', - }, - body: JSON.stringify(tags), - }); - } else { - interceptedRequest.continue(); - } - }); + // Mock API response setup + const interceptAPI = async (page) => { + await page.setRequestInterception(true); + page.on('request', (interceptedRequest) => { + const url = interceptedRequest.url(); + + const mockResponses = { + [`${STAGING_API_URL}/levels`]: levels, + [`${STAGING_API_URL}/users`]: users, + [`${STAGING_API_URL}/tags`]: tags, + }; + + if (mockResponses[url]) { + interceptedRequest.respond({ + status: 200, + contentType: 'application/json', + headers: { + 'Access-Control-Allow-Origin': '*', + }, + body: JSON.stringify(mockResponses[url]), + }); + } else { + interceptedRequest.continue(); + } + }); + }; + + // Open a shared page instance and intercept API for all tests + page = await browser.newPage(); + await interceptAPI(page); await page.goto('http://localhost:8000/task'); await page.waitForNetworkIdle(); }); @@ -66,29 +54,123 @@ describe('Input box', () => { afterAll(async () => { await browser.close(); }); - it('DependsOn input box should exist', async () => { - const inputBox = await page.evaluate(() => - document.querySelector('.inputBox'), - ); - const linksDisplay = await page.evaluate(() => - document.querySelector('#linksDisplay'), - ); + + // Form Presence Tests + describe('Form Field Presence', () => { + it('should display the title field', async () => { + const titleField = await page.$('[data-testid="title"]'); + expect(titleField).toBeTruthy(); + }); + + it('should display the status field', async () => { + const statusField = await page.$('[data-testid="status"]'); + expect(statusField).toBeTruthy(); + }); + + it('should display the priority field', async () => { + const priorityField = await page.$('[data-testid="priority"]'); + expect(priorityField).toBeTruthy(); + }); + + it('should display the isNoteworthy checkbox', async () => { + const noteworthyField = await page.$('[data-testid="isNoteworthy"]'); + expect(noteworthyField).toBeTruthy(); + }); + + it('should display the purpose field', async () => { + const purposeField = await page.$('[data-testid="purpose"]'); + expect(purposeField).toBeTruthy(); + }); + + it('should display the dependsOn field', async () => { + const dependsOnField = await page.$('[data-testid="dependsOn"]'); + expect(dependsOnField).toBeTruthy(); + }); }); - it('DependsOn input should have correct attributes', async () => { - const input = await page.$('#dependsOn'); - const type = await input.evaluate((el) => el.getAttribute('type')); - const name = await input.evaluate((el) => el.getAttribute('name')); - const id = await input.evaluate((el) => el.getAttribute('id')); - const placeholder = await input.evaluate((el) => - el.getAttribute('placeholder'), - ); - const classList = await input.evaluate((el) => Array.from(el.classList)); - - expect(type).toBe('text'); - expect(name).toBe('dependsOn'); - expect(id).toBe('dependsOn'); - expect(placeholder).toBe('Task ID separated with comma '); - expect(classList.includes('notEditing')).toBeTruthy(); + // Status Field Behavior Tests + describe('Status Field Behavior', () => { + beforeEach(async () => { + await page.goto('http://localhost:8000/task'); + await page.waitForNetworkIdle(); + }); + + it('should have default status as "available"', async () => { + const defaultStatus = await page.$eval( + '[data-testid="status"] select', + (el) => el.value, + ); + expect(defaultStatus).toBe('AVAILABLE'); + }); + + it('should show/hide fields based on "status" selection', async () => { + // Change status to "assigned" + await page.select('[data-testid="status"] select', 'ASSIGNED'); + + const assigneeVisible = await page.$eval( + '[data-testid="assignee"]', + (el) => window.getComputedStyle(el).display !== 'none', + ); + const endsOnVisible = await page.$eval( + '[data-testid="endsOn"]', + (el) => window.getComputedStyle(el).display !== 'none', + ); + expect(assigneeVisible).toBeTruthy(); + expect(endsOnVisible).toBeTruthy(); + + // Change status back to "available" + await page.select('[data-testid="status"] select', 'available'); + + const assigneeHidden = await page.$eval( + '[data-testid="assignee"]', + (el) => window.getComputedStyle(el).display === 'none', + ); + const endsOnHidden = await page.$eval( + '[data-testid="endsOn"]', + (el) => window.getComputedStyle(el).display === 'none', + ); + expect(assigneeHidden).toBeTruthy(); + expect(endsOnHidden).toBeTruthy(); + }); + }); + + // Dev Mode Tests + describe('Dev Mode Behavior', () => { + beforeAll(async () => { + await page.goto('http://localhost:8000/task?dev=true'); + await page.waitForNetworkIdle(); + }); + + it('should hide feature URL field in dev mode', async () => { + const featureUrlField = await page.$('[data-testid="featureUrl"]'); + const display = await page.$eval( + '[data-testid="featureUrl"]', + (el) => window.getComputedStyle(el).display, + ); + expect(display).toBe('none'); + }); + + it('should hide task level field in dev mode', async () => { + const taskLevelField = await page.$('[data-testid="taskLevel"]'); + const display = await page.$eval( + '[data-testid="taskLevel"]', + (el) => window.getComputedStyle(el).display, + ); + expect(display).toBe('none'); + }); + + it('should hide feature/group radio buttons in dev mode', async () => { + const radioButtons = await page.$('[data-testid="radioButtons"]'); + const display = await page.$eval( + '[data-testid="radioButtons"]', + (el) => window.getComputedStyle(el).display, + ); + expect(display).toBe('none'); + }); + + it('should display the dependsOn field in dev mode', async () => { + const dependsOnField = await page.$('[data-testid="dependsOn"]'); + expect(dependsOnField).toBeTruthy(); + }); }); }); diff --git a/task/constants.js b/task/constants.js new file mode 100644 index 00000000..b27eb797 --- /dev/null +++ b/task/constants.js @@ -0,0 +1,4 @@ +const StatusType = { + AVAILABLE: 'AVAILABLE', + ASSIGNED: 'ASSIGNED', +}; diff --git a/task/index.html b/task/index.html index d086ac56..b0dc59df 100644 --- a/task/index.html +++ b/task/index.html @@ -16,7 +16,7 @@
-
+
-
+
-
+
-
+
-
+
@@ -86,7 +90,7 @@ *
-
+
-
+
@@ -112,11 +116,11 @@
-
+

-
-
- - - -
-
+
+ + + +
+
@@ -167,7 +171,7 @@

Suggested users

-
+
Suggested users class="notEditing" />
-
+
-
+
@@ -207,7 +211,7 @@

Suggested users

-
+
@@ -221,7 +225,7 @@

Suggested users

class="notEditing" />
-
+

@@ -249,7 +253,7 @@

Suggested users

/>
-
+

@@ -278,7 +282,7 @@

Suggested users

-
+
Suggested users
+
diff --git a/task/script.js b/task/script.js index 7101fca9..a231a7f5 100644 --- a/task/script.js +++ b/task/script.js @@ -1,9 +1,35 @@ const API_BASE_URL = window.API_BASE_URL; const suggestedUsers = []; const allUser = []; + +const params = new URLSearchParams(window.location.search); +const isDev = params.get('dev') === 'true'; + +// hide fields under isDev feature flag +const containers = [ + 'featureUrlContainer', + 'featureGroupContainer', + 'taskLevelContainer', +]; + +function hideElements(isDev, elementIds) { + if (isDev) { + elementIds.forEach((id) => { + const element = document.getElementById(id); + if (element) { + element.style.display = 'none'; + } + }); + } +} +// hide fields if dev=true +hideElements(isDev, containers); + const category = document.getElementById('category'); category.addEventListener('change', async () => { + if (isDev) return; + try { showSubmitLoader(); const categoryValue = category.value; @@ -54,7 +80,7 @@ const getDaysInEpoch = (remainingDays) => { }; const setDefaultDates = () => { - if (document.getElementById('status').value === 'ASSIGNED') { + if (document.getElementById('status').value === StatusType.ASSIGNED) { const endsOn = document.getElementById('endsOn'); endsOn.value = getFutureDateString(14); endsOn.min = getFutureDateString(1); @@ -71,7 +97,7 @@ function getObjectOfFormData(formId) { const object = {}; const data = new FormData(formId); const isStatusAssigned = - document.getElementById('status').value === 'ASSIGNED'; + document.getElementById('status').value === StatusType.ASSIGNED; data.forEach((value, key) => { if (!Reflect.has(object, key)) { @@ -155,7 +181,7 @@ taskForm.onsubmit = async (e) => { isNoteworthy, } = getObjectOfFormData(taskForm); - if (status === 'ASSIGNED' && !assignee.trim()) { + if (status === StatusType.ASSIGNED && !assignee.trim()) { alert('Assignee can not be empty'); showSubmitLoader(false); document.getElementById('assignee').focus(); @@ -184,7 +210,7 @@ taskForm.onsubmit = async (e) => { isNoteworthy: isNoteworthy == 'on', }; - if (status === 'ASSIGNED') { + if (status === StatusType.ASSIGNED) { dataToBeSent.startedOn = new Date() / 1000; } @@ -192,28 +218,34 @@ taskForm.onsubmit = async (e) => { delete dataToBeSent.endsOn; } - if (status === 'AVIALABLE') { + if (status === StatusType.AVAILABLE) { delete dataToBeSent.endsOn; } - if (dataToBeSent.type == 'feature') { - dataToBeSent.assignee = assignee.trim() ? assignee : ' '; - } + if (isDev) { + delete dataToBeSent.featureUrl; + delete dataToBeSent.type; + delete dataToBeSent.participants; - if (dataToBeSent.type == 'group') { - dataToBeSent.participants = participants.trim() - ? participants.split(',') - : []; + dataToBeSent.assignee = assignee.trim() ? assignee : ' '; + } else { + if (dataToBeSent.featureUrl.trim() === '') { + delete dataToBeSent.featureUrl; + } + if (dataToBeSent.type == 'feature') { + dataToBeSent.assignee = assignee.trim() ? assignee : ' '; + } + if (dataToBeSent.type == 'group') { + dataToBeSent.participants = participants.trim() + ? participants.split(',') + : []; + } } if (dataToBeSent.purpose.trim() === '') { delete dataToBeSent.purpose; } - if (dataToBeSent.featureUrl.trim() === '') { - delete dataToBeSent.featureUrl; - } - dataToBeSent.links = dataToBeSent.links.filter((link) => link); if (dataToBeSent.links.length !== 0) { @@ -248,19 +280,22 @@ taskForm.onsubmit = async (e) => { const result = await response.json(); if (response.ok) { - const body = { - itemId: result.id, - itemType: 'task', - tagPayload: [{ tagId: category, levelId: level }], - }; - await fetch(`${API_BASE_URL}/items`, { - method: 'POST', - credentials: 'include', - body: JSON.stringify(body), - headers: { - 'Content-type': 'application/json', - }, - }); + if (!isDev) { + const body = { + itemId: result.id, + itemType: 'task', + tagPayload: [{ tagId: category, levelId: level }], + }; + + await fetch(`${API_BASE_URL}/items`, { + method: 'POST', + credentials: 'include', + body: JSON.stringify(body), + headers: { + 'Content-type': 'application/json', + }, + }); + } alert(result.message); window.location.reload(true); } @@ -289,7 +324,7 @@ let stateHandle = () => { ) { return true; } else if ( - item.value === 'ASSIGNED' && + item.value === StatusType.ASSIGNED && (wasAssigneeSet === false || assigneeEl.value === '') ) { return true; @@ -308,6 +343,8 @@ let stateHandle = () => { }; let hideUnusedField = (radio) => { + if (isDev) return; + const assigneeInput = document.getElementById('assigneeInput'); const participantsInput = document.getElementById('participantsInput'); if ( @@ -364,12 +401,14 @@ const handleDateChange = (event) => { previewDate.innerHTML = !!input.value ? getRemainingDays(input.value) : 14; }; -function handleStatusChange(event = { target: { value: 'AVAILABLE' } }) { +function handleStatusChange( + event = { target: { value: StatusType.AVAILABLE } }, +) { const assignee = document.getElementById('assigneeInput'); const assigneeEl = document.getElementById('assignee'); const endsOnWrapper = document.getElementById('endsOnWrapper'); const featureRadio = document.getElementById('feature'); - if (event.target.value === 'ASSIGNED') { + if (event.target.value === StatusType.ASSIGNED) { setDefaultDates(); assignee.classList.add('show-assignee-field'); assignee.style.display = 'none'; @@ -381,7 +420,7 @@ function handleStatusChange(event = { target: { value: 'AVAILABLE' } }) { document.getElementById('endsOn').value = ''; assigneeEl.value = ''; } - if (event.target.value === 'ASSIGNED' && featureRadio.checked) { + if (event.target.value === StatusType.ASSIGNED && featureRadio.checked) { assignee.style.display = 'flex'; } } @@ -404,6 +443,8 @@ function debounce(func, delay) { } async function fetchTags() { + if (isDev) return; + const response = await fetch(`${API_BASE_URL}/tags`); const data = await response.json(); const { tags } = data; @@ -419,6 +460,8 @@ async function fetchTags() { } async function fetchLevel() { + if (isDev) return; + const response = await fetch(`${API_BASE_URL}/levels`); const data = await response.json(); const { levels } = data;