Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
b2bfb82
refactor private options handler
ivinayakg Jan 14, 2023
d4691d0
basic setup
ivinayakg Jan 14, 2023
2047c82
draft feature
ivinayakg Jan 16, 2023
896ccda
added feature
ivinayakg Jan 31, 2023
3bb1d85
.
ivinayakg Jan 31, 2023
6b3f295
Merge branch 'develop' into extension-requests
ivinayakg Jan 31, 2023
ca2ca3c
made suggested changes
ivinayakg Feb 21, 2023
2a8ae93
Merge branch 'extension-requests' of https://github.com/ivinayakg/web…
ivinayakg Feb 21, 2023
3cf44ef
Merge branch 'develop' into extension-requests
ivinayakg Feb 27, 2023
b116156
#326 Add cursor pointer in clickable elements (#329)
khushi818 Mar 12, 2023
304dfb9
requested changes done
ivinayakg Mar 12, 2023
e1a48c5
Merge branch 'extension-requests' of https://github.com/ivinayakg/web…
ivinayakg Mar 12, 2023
51d7a2e
[Issue 333] Refactored / replaces redundant API URLs using global con…
musukeshu Mar 19, 2023
0bca131
Add footer and footer test for all page (#330)
khushi818 Mar 22, 2023
cc8fd03
Run prettier check package-lock.json
musukeshu Mar 28, 2023
ed9ed89
Merge branch 'develop' into refactor/constants
musukeshu Mar 28, 2023
fdc0183
Fixed constants in the online-members contants file
musukeshu Mar 30, 2023
cd6349b
Merge branch 'refactor/constants' of https://github.com/musukeshu/web…
musukeshu Mar 30, 2023
09ae769
Merge pull request #334 from musukeshu/refactor/constants
ankushdharkar Apr 1, 2023
a8e0938
adds filter modal
heyrandhir Apr 6, 2023
ad9ac65
Merge branch 'develop' into extension-requests
ivinayakg Apr 6, 2023
a06768a
tests for user filter
heyrandhir Apr 7, 2023
0a88fea
fix formatting
ivinayakg Apr 11, 2023
ced4f15
Jest/setup (#344)
vinit717 Apr 14, 2023
dac98d4
Move puppeteer to dev-dependencies (#348)
vinit717 Apr 14, 2023
9ff77ea
Remove package-lock.json (#350)
vinit717 Apr 14, 2023
272766b
Merge branch 'develop' into feat/add-tests-for-usermanagement-filter
heyrandhir Apr 21, 2023
e3fda9d
added config files for jest
heyrandhir Apr 22, 2023
7fa67e9
intercepting the request for mocking api calls
heyrandhir Apr 22, 2023
d28760b
add yaml for running the test suite on ci cd pipeline
heyrandhir Apr 22, 2023
58c05e8
sanitize and validate the user input before using it in the path expr…
heyrandhir Apr 22, 2023
dafad92
check path is absolute and not a relative path also check the existence
heyrandhir Apr 22, 2023
641ec4f
Adding annotations to help CodeQL better understand the code
heyrandhir Apr 22, 2023
c705fb5
prevent the codeql warning
heyrandhir Apr 22, 2023
0d66609
fix the false positive warning
heyrandhir Apr 22, 2023
6b449b0
remove the warning
heyrandhir Apr 22, 2023
e072b61
remove comments
heyrandhir Apr 23, 2023
ff196ee
Merge branch 'develop' into extension-requests
ivinayakg Apr 23, 2023
30f5d8d
resolve comments by Ritik
heyrandhir Apr 25, 2023
5966bce
changed the babel config file
heyrandhir Apr 25, 2023
5bc1492
resolve comments on the PR
heyrandhir Apr 25, 2023
ded297a
resolve comments by Ritik
heyrandhir Apr 25, 2023
9146468
reduce timeout
heyrandhir Apr 25, 2023
2bcac1e
resolve comments by yash raj
heyrandhir Apr 25, 2023
8ec0bf1
change css padding in multiples of 4px
heyrandhir Apr 25, 2023
8b5173b
added responsiveness
ivinayakg Apr 25, 2023
d012203
Merge branch 'extension-requests' of https://github.com/ivinayakg/web…
ivinayakg Apr 25, 2023
c9cfecf
Merge pull request #284 from ivinayakg/extension-requests
ankushdharkar Apr 27, 2023
1b28bc0
Merge branch 'main' into develop
ankushdharkar Apr 27, 2023
71379ea
Merge pull request #351 from Real-Dev-Squad/feat/add-tests-for-userma…
ankushdharkar Apr 27, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: Tests
on:
pull_request:
branches: [main, develop]
push:
branches: [main, develop]
jobs:
Lint-Check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: yarn
- run: yarn test
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
node_modules/
node_modules/
coverage/
192 changes: 192 additions & 0 deletions __tests__/users/user-management-home-screen.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
const puppeteer = require('puppeteer');
const { allUsersData, filteredUsersData } = require('../../mock-data/users');
const { tags } = require('../../mock-data/tags');

describe('Tests the User Management User Listing Screen', () => {
let browser;
let page;
let userListElement;
let tileViewBtn;
let tableViewBtn;
let userSearchElement;
let paginationElement;
let prevBtn;
let nextBtn;
jest.setTimeout(60000);

beforeAll(async () => {
browser = await puppeteer.launch({
headless: true,
ignoreHTTPSErrors: true,
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 === 'https://api.realdevsquad.com/users?size=100&page=0') {
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(allUsersData),
});
} else if (url === 'https://api.realdevsquad.com/users?search=randhir') {
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(filteredUsersData),
});
} else if (url === 'https://api.realdevsquad.com/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();
}
});
await page.goto('http://localhost:8000/users');
await page.waitForNetworkIdle();

userListElement = await page.$('#user-list');
tileViewBtn = await page.$('#tile-view-btn');
tableViewBtn = await page.$('#table-view-btn');
userSearchElement = await page.$('#user-search');
paginationElement = await page.$('#pagination');
prevBtn = await page.$('#prevButton');
nextBtn = await page.$('#nextButton');
});

afterAll(async () => {
await browser.close();
});

it('Checks the UI elements on user listing page.', async () => {
expect(userListElement).toBeTruthy();
expect(tileViewBtn).toBeTruthy();
expect(tableViewBtn).toBeTruthy();
expect(userSearchElement).toBeTruthy();
expect(paginationElement).toBeTruthy();
expect(prevBtn).toBeTruthy();
expect(nextBtn).toBeTruthy();
});

it('Check the UI interactions of tile view and table view button.', async () => {
await tileViewBtn.click();
const activeTileView = await page.$('.btn-active');
expect(activeTileView).toBeTruthy();
expect(activeTileView).toEqual(tileViewBtn);

await tableViewBtn.click();
const activeTableView = await page.$('.btn-active');
expect(activeTableView).toBeTruthy();
expect(activeTableView).toEqual(tableViewBtn);
});

it('Check the home screen contain user-cards', async () => {
const userList = await page.$('#user-list');
const liList = await userList.$$('li');
expect(liList.length).toBeGreaterThan(0);
});

it('checks the search functionality to display queried user', async () => {
await page.type('input[id="user-search"]', 'randhir');
await page.waitForNetworkIdle();
const userList = await page.$('#user-list');
const userCard = await userList.$$('li');
expect(userCard.length).toBeGreaterThan(0);
});

it('checks the next and previous button functionality', async () => {
await page.goto('http://localhost:8000/users');
await page.waitForNetworkIdle();

// Get the "next" button and check if it is enabled
const nextBtn = await page.$('#nextButton');
const isNextButtonDisabled = await page.evaluate(
(button) => button.disabled,
nextBtn,
);
expect(isNextButtonDisabled).toBe(false);

// Click the "next" button and wait for the page to load
await nextBtn.click();
await page.waitForNetworkIdle();

// Check that the "next" button is still present and the "previous" button is not disabled
const updatedNextButton = await page.$('#nextButton');
expect(updatedNextButton).toBeTruthy();

const prevBtn = await page.$('#prevButton');
const isPrevButtonDisabled = await page.evaluate(
(button) => button.disabled,
prevBtn,
);
expect(isPrevButtonDisabled).toBe(false);
});

it('Clicking on filter button should display filter modal', async () => {
const modal = await page.$('.filter-modal');
expect(await modal.evaluate((el) => el.classList.contains('hidden'))).toBe(
true,
);
await page.click('#filter-button');
expect(modal).not.toBeNull();
expect(await modal.evaluate((el) => el.classList.contains('hidden'))).toBe(
false,
);
await page.click('#filter-button');
expect(await modal.evaluate((el) => el.classList.contains('hidden'))).toBe(
true,
);
});

it('Selecting filters and clicking on apply should filter user list', async () => {
await page.click('#filter-button');
await page.click('input[value="ACTIVE"]');
await page.click('#apply-filter-button');
await page.waitForNetworkIdle();
const userList = await page.$('#user-list');
expect(userList).not.toBeNull();
const userCard = await userList.$$('li');
expect(userCard.length).toBeGreaterThanOrEqual(0);
});

it('clears the filter when the Clear button is clicked', async () => {
const filterButton = await page.$('#filter-button');
await filterButton.click();

await page.waitForSelector('.filter-modal');

const activeFilter = await page.$('input[value="ACTIVE"]');
await activeFilter.click();

const clearButton = await page.$('.filter-modal #clear-button');
await clearButton.click();

await page.waitForSelector('.filter-modal', { hidden: true });

const currentState = await activeFilter.getProperty('checked');
const isChecked = await currentState.jsonValue();
expect(isChecked).toBe(false);
});
});
1 change: 1 addition & 0 deletions admin-panel/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" href="/images/index.ico" type="image/x-icon" />
<title>Admin Panel | Real Dev Squad</title>
<script src="/constants.js"></script>
<script src="/admin-panel/index.js" type="module" defer></script>
<link rel="stylesheet" href="/admin-panel/index.css" />
</head>
Expand Down
7 changes: 3 additions & 4 deletions admin-panel/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ const mainContainer = document.getElementById('main-container');
const main = document.getElementById('main');
const loading = document.getElementById('loading');
const selectElement = document.getElementById('select-tags');
const BASE_URL = 'https://api.realdevsquad.com';
(async function setAuth() {
try {
const res = await fetch(`${BASE_URL}/users/self`, {
const res = await fetch(`${API_BASE_URL}/users/self`, {
method: 'GET',
credentials: 'include',
headers: {
Expand Down Expand Up @@ -70,7 +69,7 @@ async function createLevel() {
setLoadingState();
button.textContent = 'Creating Level...';

const response = await fetch(`${BASE_URL}/levels`, {
const response = await fetch(`${API_BASE_URL}/levels`, {
method: 'POST',
credentials: 'include',
body: JSON.stringify(body),
Expand Down Expand Up @@ -103,7 +102,7 @@ async function createSkill() {
setLoadingState();
button.textContent = 'creating skill...';

const response = await fetch(`${BASE_URL}/tags`, {
const response = await fetch(`${API_BASE_URL}/tags`, {
method: 'POST',
credentials: 'include',
body: JSON.stringify(body),
Expand Down
5 changes: 5 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const plugins = ['istanbul'];

module.exports = {
plugins: plugins,
};
1 change: 1 addition & 0 deletions constants.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
const API_BASE_URL = 'https://api.realdevsquad.com';
const USER_MANAGEMENT_LINK = 'user-management-link';
const EXTENSION_REQUESTS_LINK = 'extension-requests-link';
19 changes: 19 additions & 0 deletions extension-requests/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const taskInfoModelHeadings = [
{ title: 'Title' },
{ title: 'Ends On', key: 'endsOn', time: true },
{ title: 'Purpose' },
{ title: 'Assignee' },
{ title: 'Created By', key: 'createdBy' },
{ title: 'Is Noteworthy', key: 'isNoteworthy' },
];

const extensionRequestCardHeadings = [
{ title: 'Title' },
{ title: 'Reason' },
{ title: 'Old Ends On', key: 'oldEndsOn', time: true },
{ title: 'New Ends On', key: 'newEndsOn', time: true },
{ title: 'Status', bold: true },
{ title: 'Assignee' },
{ title: 'Created At', key: 'timestamp', time: true },
{ title: 'Task', key: 'taskId' },
];
110 changes: 110 additions & 0 deletions extension-requests/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="style.css" />
<title>Extension Requests</title>
</head>

<body>
<div class="extension-requests-modal-parent">
<div class="extension-requests-info"></div>
<form class="extension-requests-form">
<h3>Update Extension Request</h3>
<label for="title">Title</label>
<input
required
type="text"
id="title"
name="title"
class="extensionTitle"
/>
<label for="reason">Reason</label>
<input
required
type="text"
id="reason"
name="reason"
class="extensionReason"
/>
<label for="newEndsOn">New Ends On</label>
<input
required
type="datetime-local"
id="newEndsOn"
name="newEndsOn"
class="extensionNewEndsOn"
/>
<label for="oldEndsOn">Old Ends On</label>
<input
required
type="datetime-local"
id="oldEndsOn"
class="extensionOldEndsOn"
readonly
/>
<label for="status">Status</label>
<input
required
type="text"
id="status"
class="extensionStatus"
readonly
/>
<label for="Task Id">Task Id</label>
<input required type="text" id="Task Id" class="extensionId" readonly />
<label for="assignee">Assignee</label>
<input
required
type="text"
id="assignee"
class="extensionAssignee"
readonly
/>
<button type="submit">Submit</button>
<button id="close-modal" type="button">Cancel</button>
</form>
<form class="extension-requests-status-form">
<h3>Update Extension Request Status</h3>
<label for="status">Status</label>
<select name="status" id="status">
<option value="APPROVED">APPROVED</option>
<option value="DENIED">DENIED</option>
</select>
<label for="title">Title</label>
<input
required
type="text"
id="title"
class="extensionTitle"
readonly
/>
<label for="Task Id">Task Id</label>
<input required type="text" id="Task Id" class="extensionId" readonly />
<label for="assignee">Assignee</label>
<input
required
type="text"
id="assignee"
class="extensionAssignee"
readonly
/>
<button type="submit">Submit</button>
<button id="close-modal" type="button">Cancel</button>
</form>
</div>
<header class="header">
<h1>Extension Requests</h1>
</header>
<div class="container">
<div class="extension-requests"></div>
</div>
<h2 id="error"></h2>
<script src="/constants.js"></script>
<script src="constants.js"></script>
<script src="/utils.js"></script>
<script src="local-utils.js"></script>
<script src="script.js"></script>
</body>
</html>
Loading