Unverified Commit 394039b0 authored by Eric Rosenbaum's avatar Eric Rosenbaum Committed by GitHub

Merge pull request #4974 from LLK/develop

merge from develop to release branch
parents c42334a4 a9412af9
This diff is collapsed.
......@@ -37,7 +37,7 @@ class MuteModal extends React.Component {
this.numSteps = this.props.showWarning ? steps.BAN_WARNING : steps.MUTE_INFO;
this.state = {
step: steps.COMMENT_ISSUE
step: this.props.startStep ? this.props.startStep : steps.COMMENT_ISSUE
};
}
handleNext () {
......@@ -240,7 +240,8 @@ MuteModal.propTypes = {
}),
onRequestClose: PropTypes.func,
showWarning: PropTypes.bool,
startStep: PropTypes.oneOf(Object.keys(steps)),
timeMuted: PropTypes.string
};
MuteModal.steps = steps;
module.exports = injectIntl(MuteModal);
......@@ -231,6 +231,7 @@ class Comment extends React.Component {
{this.state.replying ? (
<FlexRow className="comment-reply-row">
<ComposeComment
isReply
commenteeId={author.id}
parentId={parentId || id}
projectId={projectId}
......
......@@ -50,7 +50,7 @@ class ComposeComment extends React.Component {
status: ComposeStatus.EDITING,
error: null,
appealId: null,
muteOpen: false,
muteOpen: muteExpiresAtMs > Date.now() && this.props.isReply,
muteExpiresAtMs: muteExpiresAtMs,
muteType: this.props.muteStatus.currentMessageType,
showWarning: this.props.muteStatus.showWarning ? this.props.muteStatus.showWarning : false
......@@ -147,6 +147,13 @@ class ComposeComment extends React.Component {
this.setState({
muteOpen: false
});
// Cancel (i.e. complete) the reply action if the user clicked on the reply button while
// alreay muted. This "closes" the reply. If they just got muted, we want to leave it open
// so the blue CommentingStatus box shows.
if (this.props.isReply && this.state.status !== ComposeStatus.REJECTED_MUTE) {
this.handleCancel();
}
}
handleMuteOpen () {
......@@ -187,6 +194,14 @@ class ComposeComment extends React.Component {
return creationTimeMinutesAgo < 2 && numOffenses === 1;
}
getMuteModalStartStep () {
// Decides which step of the mute modal to start on. If this was a reply button click,
// we show them the step that tells them how much time is left on their mute, otherwise
// they start at the beginning of the progression.
return this.props.isReply && this.state.status !== ComposeStatus.REJECTED_MUTE ?
MuteModal.steps.MUTE_INFO : MuteModal.steps.COMMENT_ISSUE;
}
getMuteMessageInfo () {
// return the ids for the messages that are shown for this mute type
// If mute modals have more than one unique "step" we could pass an array of steps
......@@ -232,7 +247,7 @@ class ComposeComment extends React.Component {
render () {
return (
<React.Fragment>
{this.isMuted() ? (
{(this.isMuted() && !(this.props.isReply && this.state.status !== ComposeStatus.REJECTED_MUTE)) ? (
<FlexRow className="comment">
<CommentingStatus>
<p><FormattedMessage id={this.getMuteMessageInfo().commentType} /></p>
......@@ -344,6 +359,7 @@ class ComposeComment extends React.Component {
muteModalMessages={this.getMuteMessageInfo()}
shouldCloseOnOverlayClick={false}
showWarning={this.state.showWarning}
startStep={this.getMuteModalStartStep()}
timeMuted={formatTime.formatRelativeTime(this.state.muteExpiresAtMs, window._locale)}
onRequestClose={this.handleMuteClose}
/>
......@@ -355,6 +371,7 @@ class ComposeComment extends React.Component {
ComposeComment.propTypes = {
commenteeId: PropTypes.number,
isReply: PropTypes.bool,
muteStatus: PropTypes.shape({
offenses: PropTypes.array,
muteExpiresAt: PropTypes.number,
......
......@@ -101,6 +101,46 @@ describe('Compose Comment test', () => {
global.Date.now = realDateNow;
});
test('Comment Status and compose box do not show on replies when muted, but mute modal does', () => {
const realDateNow = Date.now.bind(global.Date);
global.Date.now = () => 0;
const store = mockStore({
session: {
session: {
user: {},
permissions: {
mute_status: {
muteExpiresAt: 5,
offenses: [],
showWarning: true
}
}
}
}
});
const component = mountWithIntl(
<ComposeComment
{...defaultProps()}
isReply
/>
, {context: {store}}
);
expect(component.find('FlexRow.compose-comment').exists()).toEqual(false);
expect(component.find('MuteModal').exists()).toBe(true);
expect(component.find('MuteModal').props().startStep).toBe(1);
expect(component.find('CommentingStatus').exists()).toEqual(false);
global.Date.now = realDateNow;
});
test('Comment Status and compose box show on replies when not muted', () => {
const realDateNow = Date.now.bind(global.Date);
global.Date.now = () => 0;
const component = getComposeCommentWrapper({isReply: true});
expect(component.find('FlexRow.compose-comment').exists()).toEqual(true);
expect(component.find('CommentingStatus').exists()).toEqual(false);
global.Date.now = realDateNow;
});
test('Comment Status initialized properly when muted', () => {
jest.useFakeTimers();
const realDateNow = Date.now.bind(global.Date);
......@@ -133,6 +173,27 @@ describe('Compose Comment test', () => {
global.Date.now = realDateNow;
});
test('Comment Status shows when user just submitted a reply comment that got them muted', () => {
const realDateNow = Date.now.bind(global.Date);
global.Date.now = () => 0;
const component = getComposeCommentWrapper({isReply: true});
const commentInstance = component.instance();
commentInstance.setState({
status: 'REJECTED_MUTE',
muteExpiresAtMs: 100
});
component.update();
expect(component.find('FlexRow.compose-comment').exists()).toEqual(true);
expect(component.find('MuteModal').exists()).toEqual(false);
expect(component.find('CommentingStatus').exists()).toEqual(true);
// Compose box exists but is disabled
expect(component.find('InplaceInput.compose-input').exists()).toEqual(true);
expect(component.find('InplaceInput.compose-input').props().disabled).toBe(true);
expect(component.find('Button.compose-post').props().disabled).toBe(true);
expect(component.find('Button.compose-cancel').props().disabled).toBe(true);
global.Date.now = realDateNow;
});
test('Comment Status shows when user just submitted a comment that got them muted', () => {
const realDateNow = Date.now.bind(global.Date);
global.Date.now = () => 0;
......@@ -207,6 +268,7 @@ describe('Compose Comment test', () => {
commentInstance.setState({muteOpen: true});
component.update();
expect(component.find('MuteModal').exists()).toEqual(true);
expect(component.find('MuteModal').props().startStep).toEqual(0);
expect(component.find('MuteModal').props().showWarning).toBe(false);
global.Date.now = realDateNow;
});
......@@ -321,6 +383,27 @@ describe('Compose Comment test', () => {
global.Date.now = realDateNow;
});
test('getMuteModalStartStep: not a reply ', () => {
const commentInstance = getComposeCommentWrapper({}).instance();
expect(commentInstance.getMuteModalStartStep()).toBe(0);
});
test('getMuteModalStartStep: A reply that got them muted ', () => {
const commentInstance = getComposeCommentWrapper({isReply: true}).instance();
commentInstance.setState({
status: 'REJECTED_MUTE'
});
expect(commentInstance.getMuteModalStartStep()).toBe(0);
});
test('getMuteModalStartStep: A reply click when already muted ', () => {
const commentInstance = getComposeCommentWrapper({isReply: true}).instance();
commentInstance.setState({
status: 'EDITING'
});
expect(commentInstance.getMuteModalStartStep()).toBe(1);
});
test('isMuted: expiration is in the future ', () => {
const realDateNow = Date.now.bind(global.Date);
global.Date.now = () => 0; // Set "now" to 0 for easier testing.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment