Skip to content

Commit

Permalink
Merge pull request #4510 from appirio-tech/dev
Browse files Browse the repository at this point in the history
[PROD] Bug Fixes for Milestone Management Project
  • Loading branch information
RishiRajSahu committed Sep 29, 2021
2 parents 045f7e1 + 55712aa commit fd19f8d
Show file tree
Hide file tree
Showing 18 changed files with 179 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ export class ProjectsPageObject {
await CommonHelper.fillInputField(searchInput, inputText);
await this.searchButton.click();

await BrowserHelper.sleep(2000);
await BrowserHelper.sleep(4000);

}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -347,9 +347,11 @@ export class ProjectMilestonePageHelper {
await this.projectMilestonePageObject.yesButton.click();
logger.info('Clicked Yes button');

const milestoneDeletionMessage = await CommonHelper.getAlertMessageAndClosePopup();
expect(milestoneDeletionMessage).toEqual(projectMilestones.milestoneDeletionMessage);
logger.info(`Verified Delete Milestone Message ${milestoneDeletionMessage}`);

const milestoneBulkDeletionMessage = await CommonHelper.getAlertMessageAndClosePopup();
expect(milestoneBulkDeletionMessage).toEqual(projectMilestones.milestoneBulkDeletionMessage);
logger.info(`Verified Delete Milestone Message ${milestoneBulkDeletionMessage}`);

}

/**
Expand Down Expand Up @@ -438,9 +440,11 @@ export class ProjectMilestonePageHelper {
await this.projectMilestonePageObject.yesButton.click();
logger.info('Clicked Yes button');

const milestoneDeletionMessage = await CommonHelper.getAlertMessageAndClosePopup();
expect(milestoneDeletionMessage).toEqual(projectMilestones.milestoneDeletionMessage);
logger.info(`Verified Delete Milestone Message ${milestoneDeletionMessage}`);

const milestoneBulkDeletionMessage = await CommonHelper.getAlertMessageAndClosePopup();
expect(milestoneBulkDeletionMessage).toEqual(projectMilestones.milestoneBulkDeletionMessage);
logger.info(`Verified Delete Milestone Message ${milestoneBulkDeletionMessage}`);


await BrowserHelper.waitUntilClickableOf(
this.projectMilestonePageObject.getAddButton(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ export interface IProjectMilestone {
deleteConfirmation: string;
deletePopupMessage: string;
milestoneDeletionMessage: string;

milestoneBulkDeletionMessage: string;
copilot: string;
copilotName: string;
moveMilestoneDatesTitle: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ export class ProjectSettingsPageHelper {
public static async specifyUploadFilePathAndClickUploadButton() {
// Specify the File Upload Path
const fileToUploadElement = this.projectSettingsPageObject.selectFileToUploadButton;
const fileToUpload = '../../sample.pdf';
const fileToUpload = '../../../sample.pdf';
let absolutePath = path.resolve(__dirname, fileToUpload);
absolutePath = absolutePath.replace('/temp/', '/');
await fileToUploadElement.sendKeys(absolutePath);
Expand Down
6 changes: 5 additions & 1 deletion connect-automation/test-data/test-data.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@
"deleteConfirmation": "Deletion Confirmation",
"deletePopupMessage": "Are you sure you want to delete the selected Milestone (s)?",
"milestoneDeletionMessage": "PROJECT MILESTONE DELETED.",

"milestoneBulkDeletionMessage": "PROJECT MILESTONES DELETED.",
"copilot": "Copilot",
"copilotName": "TCConnCopilot",
"moveMilestoneDatesTitle": "Move Milestone Dates",
Expand All @@ -94,6 +96,8 @@
"inReview": "In Review",
"actionOnMilestoneApprove": "approve",
"milestoneApprovedMessageStr": "APPROVED MILESTONES SUCCESSFULLY.",
"allMilestoneApprovedNotificationStr": "All the milestone(s) has been approved by the customer"

"allMilestoneApprovedNotificationStr": "The following milestone(s) has been approved"

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ describe('Connect App - Create New Milestone Tests:', () => {

it('[TC_003] Should verify user can bulk update the milestone.', async () => {
await ProjectMilestonePageHelper.deleteAllMilestones(testData.projectMilestone);

await CommonHelper.waitForAddNewMilestones();
const milestoneNames = await ProjectMilestonePageHelper.addMilestones(testData.projectMilestone, 2, testData.projectMilestone.active);
await ProjectMilestonePageHelper.verifyUserCanBulkUpdateTheMilestone(testData.projectMilestone);
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { BrowserHelper } from 'topcoder-testing-lib';
import { CommonHelper } from '../../page-objects/common-page/common.helper';
import { ProjectSettingsPageHelper } from '../../page-objects/project-settings/project-settings.helper'
import * as testData from '../../test-data/test-data.json';
Expand Down Expand Up @@ -42,18 +43,21 @@ describe('Connect App - Project Settings Tests:', () => {

it('[TC_003] Should verify user can Add/Edit/Delete/Download Files', async () => {
await CommonHelper.goToRecentlyCreatedProject();
await BrowserHelper.sleep(5000);
await CommonHelper.waitForAddNewMilestones();
await ProjectSettingsPageHelper.verifyUserCanAddEditDeleteDownloadFiles(testData.projectSettings);
});

it('[TC_004] Should verify user can Add/Edit/Delete/Download Links', async () => {
await CommonHelper.goToRecentlyCreatedProject();
await BrowserHelper.sleep(5000);
await CommonHelper.waitForAddNewMilestones();
await ProjectSettingsPageHelper.verifyUserCanAddEditDeleteDownloadLinks(testData.projectSettings);
});

it('[TC_005] Should verify user can Add Message with Files Attachment', async () => {
await CommonHelper.goToRecentlyCreatedProject();
await BrowserHelper.sleep(5000);
await CommonHelper.waitForAddNewMilestones();
await ProjectSettingsPageHelper.verifyUserCanAddMessageWithFileAttachment(testData.projectSettings);
});
Expand Down
5 changes: 5 additions & 0 deletions src/api/projects.js
Original file line number Diff line number Diff line change
Expand Up @@ -223,3 +223,8 @@ export function deleteProjectPhase(projectId, phaseId) {
return axios.delete(`${PROJECTS_API_URL}/v5/projects/${projectId}/phases/${phaseId}`)
.then(() => ({ projectId, phaseId }))
}

export function deleteBulkProjectPhase(projectId, phaseIds) {
return axios.delete(`${PROJECTS_API_URL}/v5/projects/${projectId}/phases`, { data: { phaseIds } })
.then(() => ({ phaseIds }))
}
5 changes: 5 additions & 0 deletions src/config/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,11 @@ export const DELETE_PROJECT_PHASE_PENDING = 'DELETE_PROJECT_PHASE_PENDING'
export const DELETE_PROJECT_PHASE_FAILURE = 'DELETE_PROJECT_PHASE_FAILURE'
export const DELETE_PROJECT_PHASE_SUCCESS = 'DELETE_PROJECT_PHASE_SUCCESS'

export const DELETE_BULK_PROJECT_PHASE = 'DELETE_BULK_PROJECT_PHASE'
export const DELETE_BULK_PROJECT_PHASE_PENDING = 'DELETE_BULK_PROJECT_PHASE_PENDING'
export const DELETE_BULK_PROJECT_PHASE_FAILURE = 'DELETE_BULK_PROJECT_PHASE_FAILURE'
export const DELETE_BULK_PROJECT_PHASE_SUCCESS = 'DELETE_BULK_PROJECT_PHASE_SUCCESS'

export const UPDATE_PRODUCT = 'UPDATE_PRODUCT'
export const UPDATE_PRODUCT_PENDING = 'UPDATE_PRODUCT_PENDING'
export const UPDATE_PRODUCT_SUCCESS = 'UPDATE_PRODUCT_SUCCESS'
Expand Down
2 changes: 1 addition & 1 deletion src/config/permissions.js
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ export const PERMISSIONS = {
description: 'Remove copilots form the project.',
},
projectRoles: [
..._.difference(PROJECT_ALL, [PROJECT_ROLE_COPILOT, PROJECT_ROLE_CUSTOMER])
..._.difference(PROJECT_ALL, [PROJECT_ROLE_CUSTOMER])
],
topcoderRoles: [
...TOPCODER_ADMINS,
Expand Down
18 changes: 17 additions & 1 deletion src/projects/actions/project.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { getProjectById,
updateProject as updateProjectAPI,
deleteProject as deleteProjectAPI,
deleteProjectPhase as deleteProjectPhaseAPI,
deleteBulkProjectPhase as deleteBulkProjectPhaseAPI,
getProjectPhases,
updateProduct as updateProductAPI,
updatePhase as updatePhaseAPI,
Expand Down Expand Up @@ -79,7 +80,8 @@ import {
CUSTOMER_APPROVE_MILESTONE_APPROVE_SUCCESS,
CUSTOMER_APPROVE_MILESTONE_REJECT_FAILURE,
CUSTOMER_APPROVE_MILESTONE_APPROVE_FAILURE,
CUSTOMER_APPROVE_MILESTONE_REJECT_SUCCESS
CUSTOMER_APPROVE_MILESTONE_REJECT_SUCCESS,
DELETE_BULK_PROJECT_PHASE
} from '../../config/constants'
import {
updateProductMilestone,
Expand Down Expand Up @@ -334,6 +336,11 @@ export function createProjectPhaseAndProduct(project, productTemplate, status =
description: productTemplate.description,
productTemplateId: productTemplate.id,
}

if(productTemplate.members) {
param.members = productTemplate.members
}

if (startDate) {
param['startDate'] = startDate.format('YYYY-MM-DD')
}
Expand Down Expand Up @@ -441,6 +448,15 @@ export function deleteProjectPhase(projectId, phaseId) {
}
}

export function deleteBulkProjectPhase(projectId, phaseIds) {
return (dispatch) => {
return dispatch({
type: DELETE_BULK_PROJECT_PHASE,
payload: deleteBulkProjectPhaseAPI(projectId, phaseIds)
})
}
}

export function updateProject(projectId, updatedProps, updateExisting = false) {
return (dispatch) => {
return dispatch({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import * as milestoneHelper from '../components/helpers/milestone'

import styles from './CreateSimplePlan.scss'
import MilestonesApprovalNotification from '../components/MilestonesApprovalNotification'
import { PHASE_STATUS_IN_REVIEW } from '../../../../../config/constants'

const createTabs = ({ onClick } ) => ([
{
Expand Down Expand Up @@ -39,13 +40,18 @@ class CreateSimplePlan extends React.Component {
onChangeMilestones,
onSaveMilestone,
onRemoveMilestone,
onRemoveAllMilestones,
onGetChallenges,
onApproveMilestones,
isProjectLive,
isCustomer,
} = this.props
const onClickMilestonesTab = () => {}

const isInReview =
isCustomer ? (milestones.filter( x => x.status === PHASE_STATUS_IN_REVIEW).length > 0 && isProjectLive)
: isProjectLive

if (milestones.length === 0) {
return isCustomer ? null : (
<div styleName="add-new-milestone">
Expand Down Expand Up @@ -78,10 +84,12 @@ class CreateSimplePlan extends React.Component {
onChangeMilestones={onChangeMilestones}
onSaveMilestone={onSaveMilestone}
onRemoveMilestone={onRemoveMilestone}
onRemoveAllMilestones={onRemoveAllMilestones}
onApproveMilestones={onApproveMilestones}
projectMembers={project.members}
project={project}
isUpdatable={isProjectLive && !isCustomer}
isInReview={isInReview}
isCustomer={isCustomer}
/>
</div>
Expand All @@ -97,6 +105,7 @@ CreateSimplePlan.propTypes = {
onChangeMilestones: PT.func,
onSaveMilestone: PT.func,
onRemoveMilestone: PT.func,
onRemoveAllMilestones: PT.func,
onGetChallenges: PT.func,
onApproveMilestones: PT.func,
isCustomer: PT.bool,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import MilestoneMoveDateButton from '../components/MilestoneMoveDateButton'
import * as milestoneHelper from '../components/helpers/milestone'
import IconUnselect from '../../../../../assets/icons/icon-disselect.svg'
import IconCopilot from '../../../../../assets/icons/icon-copilot.svg'
import { CHALLENGE_ID_MAPPING, PHASE_STATUS_IN_REVIEW } from '../../../../../config/constants'
import { CHALLENGE_ID_MAPPING, PHASE_STATUS_IN_REVIEW, PROJECT_STATUS_CANCELLED, PROJECT_STATUS_COMPLETED } from '../../../../../config/constants'

import './ManageMilestones.scss'
import MilestoneApprovalButton from '../components/MilestoneApprovalButton'
Expand Down Expand Up @@ -84,11 +84,14 @@ class ManageMilestones extends React.Component {
}

onDeleteAll() {
const { milestones, onRemoveMilestone } = this.props
const seletedMilestones = _.filter(milestones, m => m.selected)
_.forEach(seletedMilestones, m => {
onRemoveMilestone(m.id)
})
const { milestones, onRemoveAllMilestones } = this.props
const selectedPhases = _.filter(milestones, m => m.selected)

if (selectedPhases.length) {
const { projectId } = selectedPhases[0]
const phaseIds = selectedPhases.map(m => m.id)
onRemoveAllMilestones(projectId, phaseIds)
}
}

onUnselectAll() {
Expand Down Expand Up @@ -256,8 +259,12 @@ class ManageMilestones extends React.Component {
onChangeMilestones,
isUpdatable,
isCustomer,
isInReview,
project,
} = this.props

const hideCheckbox = project.status === PROJECT_STATUS_CANCELLED || project.status === PROJECT_STATUS_COMPLETED

// const isNeedApproval = project.status === PROJECT_STATUS_IN_REVIEW
const isNeedApproval = !milestones.filter(ms => ms.selected === true).find(ms => !(ms.status === PHASE_STATUS_IN_REVIEW))
const canShowApproval = isCustomer && isNeedApproval
Expand Down Expand Up @@ -325,20 +332,21 @@ class ManageMilestones extends React.Component {
<table styleName="milestones-table">
<colgroup>
<col style={{ width: '20px' }} />
<col style={{ width: '20px' }} />{/* CHECKBOX */}
{hideCheckbox ? null : <col style={{ width: '20px' }} />}{/* CHECKBOX */}
<col style={{ width: '8%' }} />{/* MILESTONE */}
<col />{/* DESCRIPTION */}
<col style={{ width: '12%' }} />{/* START DATE */}
<col style={{ width: '11%' }} />{/* END DATE */}
<col style={{ width: '10%' }} />{/* STATUS */}
<col style={{ width: '13%' }} />{/* COPILOTS */}
{(isUpdatable || isCustomer) && (<col style={{ width: '64px' }} />)}{/* ACTION */}
{(isUpdatable || isInReview) && (<col style={{ width: '64px' }} />)}{/* ACTION */}
</colgroup>
<thead>
<MilestoneHeaderRow
milestones={milestones}
onChangeMilestones={onChangeMilestones}
isUpdatable={isUpdatable || isCustomer}
isUpdatable={isUpdatable || isInReview}
hideCheckbox={hideCheckbox}
/>
</thead>
<tbody>
Expand All @@ -365,6 +373,8 @@ class ManageMilestones extends React.Component {
onApprove={this.onApprove}
phaseMembers={milestone.members}
isApproving={milestonesInApproval.indexOf(milestone.id) !== -1}
hideCheckbox={hideCheckbox}
isInReview={isInReview}
/>,
...this.renderChallengeTable(milestone)
]
Expand All @@ -383,11 +393,13 @@ ManageMilestones.propTypes = {
onChangeMilestones: PT.func,
onSaveMilestone: PT.func,
onRemoveMilestone: PT.func,
onRemoveAllMilestones: PT.func,
onGetChallenges: PT.func,
onApproveMilestones: PT.func,
projectMembers: PT.arrayOf(PT.shape()),
isUpdatable: PT.bool,
isCustomer: PT.bool,
isInReview: PT.bool,
project: PT.shape()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import './MilestoneHeaderRow.scss'

const TCFormFields = FormsyForm.Fields

function MilestoneHeaderRow ({ milestones, onChangeMilestones, isUpdatable }) {
function MilestoneHeaderRow ({ milestones, onChangeMilestones, isUpdatable, hideCheckbox }) {
const checked = milestones.reduce(
(selected, milestone) => selected = selected && milestone.selected,
milestones.length > 0
Expand All @@ -31,16 +31,18 @@ function MilestoneHeaderRow ({ milestones, onChangeMilestones, isUpdatable }) {

return (
<tr styleName="milestone-row">
{isUpdatable ? <th />: null}
<th>
<TCFormFields.Checkbox
name="select-all"
value={checked}
onChange={(_, value) => {
value ? selectAll() : unselectAll()
}}
/>
</th>
<th />
{
hideCheckbox ? null : <th>
<TCFormFields.Checkbox
name="select-all"
value={checked}
onChange={(_, value) => {
value ? selectAll() : unselectAll()
}}
/>
</th>
}
<th>MILESTONE</th>
<th>DESCRIPTION</th>
<th>START DATE</th>
Expand All @@ -54,6 +56,7 @@ function MilestoneHeaderRow ({ milestones, onChangeMilestones, isUpdatable }) {

MilestoneHeaderRow.propTypes = {
onChangeMilestones: PT.func,
hideCheckbox: PT.bool,
}

export default MilestoneHeaderRow
Loading

0 comments on commit fd19f8d

Please sign in to comment.