-
Notifications
You must be signed in to change notification settings - Fork 85
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Show total number of votes and maximum number of votes for all users #488
base: main
Are you sure you want to change the base?
Changes from all commits
017d544
e305dc5
4a5c24d
660432c
d10fadd
b74e7a4
838dcd2
0ecc80f
ddf9eea
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,6 @@ | ||
|
||
import { mocked } from 'jest-mock'; | ||
import { WorkflowPhase } from '../../../interfaces/workItem'; | ||
import { TooltipOverflowMode } from 'office-ui-fabric-react'; | ||
|
||
export const testTeamId = "mocked-team-uuid"; | ||
export const testBoardId = "mocked-board-uuid"; | ||
|
@@ -90,7 +89,7 @@ testColumnsObj[testColumnUuidOne] = { | |
testColumnsObj[testColumnUuidTwo] = { | ||
columnProperties: | ||
{ | ||
id: TooltipOverflowMode, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know why this was using this random import, but it seemed like a bug. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Appreciate the diligence! Always appreciated :D |
||
id: testColumnUuidTwo, | ||
title: testColumnTwoTitle, | ||
iconClass: 'far fa-smile', | ||
accentColor: '#008100', | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,3 +1,115 @@ | ||||||
import React from 'react'; | ||||||
import { IFeedbackBoardDocument } from '../../interfaces/feedback'; | ||||||
import { shallow } from 'enzyme'; | ||||||
import { mocked } from 'jest-mock'; | ||||||
import FeedbackBoard, { FeedbackBoardProps } from '../../components/feedbackBoard'; | ||||||
import { testColumnProps } from '../__mocks__/mocked_components/mockedFeedbackColumn'; | ||||||
import { IdentityRef } from 'azure-devops-extension-api/WebApi'; | ||||||
|
||||||
jest.mock('../feedbackBoardMetadataForm', () => mocked({})); | ||||||
jest.mock('azure-devops-extension-api/Work/WorkClient', () => { | ||||||
const getTeamIterationsMock = () => { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These mocks are copied from There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If this chunk is a copy of the other, I think that's a valid thing to move to |
||||||
return [ | ||||||
mocked({ | ||||||
attributes: mocked({ | ||||||
finishDate: new Date(), | ||||||
startDate: new Date(), | ||||||
timeFrame: 1, | ||||||
}), | ||||||
id: 'iterationId', | ||||||
name: 'iteration name', | ||||||
path: 'default path', | ||||||
_links: [], | ||||||
url: 'https://teamfieldvaluesurl' | ||||||
}) | ||||||
]; | ||||||
}; | ||||||
|
||||||
const getTeamFieldValuesMock = () => { | ||||||
return [ | ||||||
mocked({ | ||||||
defaultValue: 'default field value', | ||||||
field: mocked({ | ||||||
referenceName: 'default reference name', | ||||||
url: 'https://fieldurl' | ||||||
}), | ||||||
values: [ | ||||||
mocked({ | ||||||
includeChildren: false, | ||||||
value: 'default team field value', | ||||||
}) | ||||||
], | ||||||
links: [], | ||||||
url: 'https://teamfieldvaluesurl' | ||||||
})] | ||||||
}; | ||||||
|
||||||
const workRestClientMock = jest.fn().mockImplementation(() => ({ | ||||||
getTeamIterations: getTeamIterationsMock, | ||||||
getTeamFieldValues: getTeamFieldValuesMock, | ||||||
})); | ||||||
|
||||||
return { WorkRestClient: workRestClientMock }; | ||||||
}); | ||||||
|
||||||
jest.mock('azure-devops-extension-api/Common', () => ({ | ||||||
getClient: (clientClass: typeof Object) => new clientClass(), | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this could be moved into There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll make a more overarching issue to maybe get the tests and components tidied eventually - may be a bit of an undertaking. For now, you should be good to go! |
||||||
})); | ||||||
|
||||||
const mockedIdentity: IdentityRef = { | ||||||
directoryAlias: '', | ||||||
id: '', | ||||||
imageUrl: '', | ||||||
inactive: false, | ||||||
isAadIdentity: false, | ||||||
isContainer: false, | ||||||
isDeletedInOrigin: false, | ||||||
profileUrl: '', | ||||||
uniqueName: '', | ||||||
_links: undefined, | ||||||
descriptor: '', | ||||||
displayName: '', | ||||||
url: '' | ||||||
}; | ||||||
|
||||||
const mockedBoard: IFeedbackBoardDocument = { | ||||||
id: testColumnProps.boardId, | ||||||
title: testColumnProps.boardTitle, | ||||||
teamId: testColumnProps.team.id, | ||||||
createdBy: mockedIdentity, | ||||||
createdDate: new Date(), | ||||||
columns: testColumnProps.columnIds.map((columnId) => testColumnProps.columns[columnId].columnProperties), | ||||||
activePhase: 'Vote', | ||||||
maxVotesPerUser: 5, | ||||||
boardVoteCollection: {}, | ||||||
teamEffectivenessMeasurementVoteCollection: [] | ||||||
}; | ||||||
|
||||||
const mockedProps: FeedbackBoardProps = { | ||||||
displayBoard: true, | ||||||
board: mockedBoard, | ||||||
team: testColumnProps.team, | ||||||
workflowPhase: 'Vote', | ||||||
nonHiddenWorkItemTypes: testColumnProps.nonHiddenWorkItemTypes, | ||||||
allWorkItemTypes: testColumnProps.allWorkItemTypes, | ||||||
isAnonymous: testColumnProps.isBoardAnonymous, | ||||||
hideFeedbackItems: testColumnProps.hideFeedbackItems, | ||||||
isCarouselDialogHidden: false, | ||||||
hideCarouselDialog: jest.fn(() => { }), | ||||||
userId: '' | ||||||
}; | ||||||
|
||||||
describe(`The Feedback Board Component`, () => { | ||||||
it(`Should not regress`, () => {}); | ||||||
}); | ||||||
it(`can be rendered`, () => { | ||||||
const wrapper = shallow(<FeedbackBoard {...mockedProps} />); | ||||||
const component = wrapper.children().dive(); | ||||||
expect(component.prop('className')).toBe('feedback-board'); | ||||||
}); | ||||||
|
||||||
it(`shows correct vote counts`, () => { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
optional: a test for when one or two different people have cast their votes? If not, this can have a |
||||||
const wrapper = shallow(<FeedbackBoard {...mockedProps} />); | ||||||
const component = wrapper.children().dive(); | ||||||
expect(component.findWhere((child) => child.prop("className") === "feedback-maxvotes-per-user").text()) | ||||||
.toBe('Votes Used: 0 / 5 (me), 0 / 0 (team)'); | ||||||
}); | ||||||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -69,7 +69,7 @@ class FeedbackBoard extends React.Component<FeedbackBoardProps, FeedbackBoardSta | |
defaultActionItemIteration: '', | ||
hasItems: false, | ||
isDataLoaded: false, | ||
currentVoteCount: (props.board.boardVoteCollection === undefined || props.board.boardVoteCollection === null) ? "0" : (props.board.boardVoteCollection[this.props.userId] === undefined || props.board.boardVoteCollection[this.props.userId] === null) ? "0" : props.board.boardVoteCollection[this.props.userId]?.toString() | ||
currentVoteCount: props.board.boardVoteCollection?.[this.props.userId]?.toString() ?? "0", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you for trimming this down! |
||
}; | ||
} | ||
|
||
|
@@ -421,19 +421,28 @@ class FeedbackBoard extends React.Component<FeedbackBoardProps, FeedbackBoardSta | |
onVoteCasted: () => { | ||
itemDataService.getBoardItem(this.props.team.id, this.props.board.id).then((boardItem: IFeedbackBoardDocument) => { | ||
const voteCollection = boardItem.boardVoteCollection; | ||
|
||
this.setState({ currentVoteCount: voteCollection === undefined ? "0" : voteCollection[this.props.userId] === undefined ? "0" : voteCollection[this.props.userId].toString() }); | ||
this.setState({ currentVoteCount: voteCollection?.[this.props.userId]?.toString() ?? "0"}); | ||
}); | ||
}, | ||
groupTitles: [] | ||
}; | ||
}); | ||
|
||
const columnItems = this.state.columnIds | ||
.flatMap((columnId) => this.state.columns[columnId].columnItems); | ||
const participants = new Set(columnItems.flatMap((columnItem) => Object.keys(columnItem.feedbackItem.voteCollection))).size; | ||
|
||
const teamVotes = columnItems | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I love this solution! Great job! |
||
.flatMap((columnItem) => Object.values(columnItem.feedbackItem.voteCollection)) | ||
.reduce((a, b) => a + b, 0) | ||
.toString(); | ||
const maxTeamVotes = (participants * this.props.board?.maxVotesPerUser).toString(); | ||
|
||
return ( | ||
<div className="feedback-board"> | ||
{this.props.workflowPhase === WorkflowPhase.Vote && | ||
<div className="feedback-maxvotes-per-user"> | ||
<label>Votes Used: {this.state.currentVoteCount} / {this.props.board?.maxVotesPerUser?.toString()}</label> | ||
<label>Votes Used: {this.state.currentVoteCount} / {this.props.board?.maxVotesPerUser?.toString()} (me), {teamVotes} / {maxTeamVotes} (team)</label> | ||
</div> | ||
} | ||
<div className="feedback-columns-container"> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍