Disable comment box functionality when you've just been muted.

Also, keep showing the blue comment status box based on when the mute 
expires rather than basing it on the status of the commet box itself.

TODO: css for disabled state.  The grey is there as a placeholder/proof 
of concept.
This commit is contained in:
picklesrus 2020-11-17 17:04:54 -05:00
parent 0470e0e56b
commit aed0f024c0
3 changed files with 92 additions and 6 deletions

View file

@ -32,6 +32,9 @@
&:not(:focus) {
border: 2px solid $active-dark-gray;
}
&:disabled {
background-color: $box-shadow-light-gray;
}
}
}

View file

@ -38,8 +38,8 @@ class ComposeComment extends React.Component {
'handleCancel',
'handleInput',
'handleMuteClose',
'handleMuteOpen'
'handleMuteOpen',
'isMuted'
]);
this.state = {
message: '',
@ -115,6 +115,10 @@ class ComposeComment extends React.Component {
return Math.ceil(((timeStampInSec * 1000) - Date.now()) / (60 * 1000));
}
isMuted () {
return this.state.muteExpiresAt * 1000 > Date.now();
}
handleMuteClose () {
this.setState({
muteOpen: false
@ -163,7 +167,7 @@ class ComposeComment extends React.Component {
render () {
return (
<React.Fragment>
{this.state.status === ComposeStatus.REJECTED_MUTE ? (
{this.isMuted() ? (
<FlexRow className="comment">
<CommentingStatus>
<p>Scratch thinks your comment was disrespectful.</p>
@ -205,6 +209,7 @@ class ComposeComment extends React.Component {
className={classNames('compose-input',
MAX_COMMENT_LENGTH - this.state.message.length >= 0 ?
'compose-valid' : 'compose-invalid')}
disabled={this.state.status === ComposeStatus.REJECTED_MUTE}
handleUpdate={onUpdate}
name="compose-comment"
type="textarea"

View file

@ -66,23 +66,73 @@ describe('Compose Comment test', () => {
expect(component.find('FlexRow.compose-error-row').exists()).toEqual(false);
});
test('Comment Status shows when state is REJECTED_MUTE ', () => {
test('Comment Status shows when mute expiration in the future ', () => {
const realDateNow = Date.now.bind(global.Date);
global.Date.now = () => 0;
const component = getComposeCommentWrapper({});
const commentInstance = component.instance();
commentInstance.setState({status: 'REJECTED_MUTE'});
commentInstance.setState({muteExpiresAt: 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);
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;
const component = getComposeCommentWrapper({});
const commentInstance = component.instance();
commentInstance.setState({
status: 'REJECTED_MUTE',
muteExpiresAt: 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 is disabled
expect(component.find('InplaceInput.compose-input').exists()).toEqual(true);
expect(component.find('InplaceInput.compose-input').props().disabled).toBe(true);
global.Date.now = realDateNow;
});
test('Comment Error does not show for mutes', () => {
const realDateNow = Date.now.bind(global.Date);
global.Date.now = () => 0;
const component = getComposeCommentWrapper({});
const commentInstance = component.instance();
commentInstance.setState({
status: 'REJECTED_MUTE',
error: 'a mute error'
});
component.update();
expect(component.find('FlexRow.compose-error-row').exists()).toEqual(false);
expect(component.find('FlexRow.compose-comment').exists()).toEqual(true);
global.Date.now = realDateNow;
});
test('Comment Error does show for non-mute errors', () => {
const component = getComposeCommentWrapper({});
const commentInstance = component.instance();
commentInstance.setState({
error: 'some error',
status: 'FLOOD'
});
component.update();
expect(component.find('FlexRow.compose-error-row').exists()).toEqual(true);
expect(component.find('FlexRow.compose-comment').exists()).toEqual(true);
expect(component.find('InplaceInput.compose-input').exists()).toEqual(true);
expect(component.find('InplaceInput.compose-input').props().disabled).toBe(false);
});
test('Mute Modal shows when muteOpen is true ', () => {
const realDateNow = Date.now.bind(global.Date);
global.Date.now = () => 0;
const component = getComposeCommentWrapper({});
const commentInstance = component.instance();
commentInstance.setState({muteOpen: true});
component.update();
expect(component.find('FlexRow.compose-comment').exists()).toEqual(true);
expect(component.find('MuteModal').exists()).toEqual(true);
global.Date.now = realDateNow;
});
test('shouldShowMuteModal is false when list is undefined ', () => {
@ -130,4 +180,32 @@ describe('Compose Comment test', () => {
global.Date.now = realDateNow;
});
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.
const commentInstance = getComposeCommentWrapper({}).instance();
commentInstance.setState({muteExpiresAt: 100});
expect(commentInstance.isMuted()).toBe(true);
global.Date.now = realDateNow;
});
test('isMuted: expiration is in the past ', () => {
const realDateNow = Date.now.bind(global.Date);
global.Date.now = () => 0;
const commentInstance = getComposeCommentWrapper({}).instance();
commentInstance.setState({muteExpiresAt: -100});
expect(commentInstance.isMuted()).toBe(false);
global.Date.now = realDateNow;
});
test('isMuted: expiration is not set ', () => {
const realDateNow = Date.now.bind(global.Date);
global.Date.now = () => 0;
const commentInstance = getComposeCommentWrapper({}).instance();
expect(commentInstance.isMuted()).toBe(false);
global.Date.now = realDateNow;
});
});