Fix comment toggling and add permissions test

This commit is contained in:
Paul Kaplan 2021-04-26 15:11:06 -04:00
parent aab4c9aca6
commit f9419ac8fc
7 changed files with 64 additions and 22 deletions

View file

@ -191,7 +191,7 @@ const mutateStudioCommentsAllowed = shouldAllow => ((dispatch, getState) => {
api({
host: '',
uri: `/site-api/comments/gallery/${studioId}/toggle-comments/`,
method: 'PUT',
method: 'POST',
useCsrf: true
}, (err, body, res) => {
const error = normalizeError(err, body, res);

View file

@ -25,6 +25,10 @@ const selectCanDeleteCommentWithoutConfirm = state => selectIsAdmin(state);
const selectCanFollowStudio = state => selectIsLoggedIn(state);
// Matching existing behavior, only the creator is allowed to toggle comments.
const selectCanEditCommentsAllowed = state => selectIsAdmin(state) || isCreator(state);
const selectCanEditOpenToAll = state => selectIsAdmin(state) || isManager(state);
export {
selectCanEditInfo,
selectCanAddProjects,
@ -33,5 +37,7 @@ export {
selectCanDeleteComment,
selectCanDeleteCommentWithoutConfirm,
selectCanReportComment,
selectCanRestoreComment
selectCanRestoreComment,
selectCanEditCommentsAllowed,
selectCanEditOpenToAll
};

View file

@ -4,13 +4,12 @@ import PropTypes from 'prop-types';
import {connect} from 'react-redux';
import {selectStudioCommentsAllowed, selectIsLoadingInfo} from '../../redux/studio';
import {selectCanEditInfo} from '../../redux/studio-permissions';
import {
mutateStudioCommentsAllowed, selectIsMutatingCommentsAllowed, selectCommentsAllowedMutationError
} from '../../redux/studio-mutations';
const StudioCommentsAllowed = ({
commentsAllowedError, isLoading, isMutating, commentsAllowed, canEditInfo, handleUpdate
commentsAllowedError, isLoading, isMutating, commentsAllowed, handleUpdate
}) => (
<div>
{isLoading ? (
@ -19,12 +18,12 @@ const StudioCommentsAllowed = ({
<div>
<label>
<input
disabled={isMutating || !canEditInfo}
disabled={isMutating}
type="checkbox"
checked={commentsAllowed}
onChange={e => handleUpdate(e.target.checked)}
/>
<h4>{commentsAllowed ? 'Comments allowed' : 'Comments not allowed'}</h4>
<span>{commentsAllowed ? 'Comments allowed' : 'Comments not allowed'}</span>
{commentsAllowedError && <div>Error mutating commentsAllowed: {commentsAllowedError}</div>}
</label>
</div>
@ -34,7 +33,6 @@ const StudioCommentsAllowed = ({
StudioCommentsAllowed.propTypes = {
commentsAllowedError: PropTypes.string,
canEditInfo: PropTypes.bool,
isLoading: PropTypes.bool,
isMutating: PropTypes.bool,
commentsAllowed: PropTypes.bool,
@ -44,7 +42,6 @@ StudioCommentsAllowed.propTypes = {
export default connect(
state => ({
commentsAllowed: selectStudioCommentsAllowed(state),
canEditInfo: selectCanEditInfo(state),
isLoading: selectIsLoadingInfo(state),
isMutating: selectIsMutatingCommentsAllowed(state),
commentsAllowedError: selectCommentsAllowedMutationError(state)

View file

@ -14,11 +14,14 @@ import {
selectCanDeleteComment,
selectCanDeleteCommentWithoutConfirm,
selectCanReportComment,
selectCanRestoreComment
selectCanRestoreComment,
selectCanEditCommentsAllowed
} from '../../redux/studio-permissions';
import {selectStudioCommentsAllowed} from '../../redux/studio.js';
const StudioComments = ({
comments,
commentsAllowed,
handleLoadMoreComments,
handleNewComment,
moreCommentsToLoad,
@ -27,6 +30,7 @@ const StudioComments = ({
shouldShowCommentComposer,
canDeleteComment,
canDeleteCommentWithoutConfirm,
canEditCommentsAllowed,
canReportComment,
canRestoreComment,
handleDeleteComment,
@ -41,9 +45,9 @@ const StudioComments = ({
return (
<div>
<h2>Comments</h2>
<StudioCommentsAllowed />
{canEditCommentsAllowed && <StudioCommentsAllowed />}
<div>
{shouldShowCommentComposer &&
{shouldShowCommentComposer && commentsAllowed &&
<ComposeComment
postURI={postURI}
onAddComment={handleNewComment}
@ -88,6 +92,7 @@ const StudioComments = ({
StudioComments.propTypes = {
comments: PropTypes.arrayOf(PropTypes.shape({})),
commentsAllowed: PropTypes.bool,
handleLoadMoreComments: PropTypes.func,
handleNewComment: PropTypes.func,
moreCommentsToLoad: PropTypes.bool,
@ -95,6 +100,7 @@ StudioComments.propTypes = {
shouldShowCommentComposer: PropTypes.bool,
canDeleteComment: PropTypes.bool,
canDeleteCommentWithoutConfirm: PropTypes.bool,
canEditCommentsAllowed: PropTypes.bool,
canReportComment: PropTypes.bool,
canRestoreComment: PropTypes.bool,
handleDeleteComment: PropTypes.func,
@ -109,9 +115,11 @@ export default connect(
comments: state.comments.comments,
moreCommentsToLoad: state.comments.moreCommentsToLoad,
replies: state.comments.replies,
commentsAllowed: selectStudioCommentsAllowed(state),
shouldShowCommentComposer: selectShowCommentComposer(state),
canDeleteComment: selectCanDeleteComment(state),
canDeleteCommentWithoutConfirm: selectCanDeleteCommentWithoutConfirm(state),
canEditCommentsAllowed: selectCanEditCommentsAllowed(state),
canReportComment: selectCanReportComment(state),
canRestoreComment: selectCanRestoreComment(state),
postURI: `/proxy/comments/studio/${state.studio.id}`

View file

@ -4,13 +4,12 @@ import PropTypes from 'prop-types';
import {connect} from 'react-redux';
import {selectStudioOpenToAll, selectIsLoadingInfo} from '../../redux/studio';
import {selectCanEditInfo} from '../../redux/studio-permissions';
import {
mutateStudioOpenToAll, selectIsMutatingOpenToAll, selectOpenToAllMutationError
} from '../../redux/studio-mutations';
const StudioOpenToAll = ({
openToAllError, isLoading, isMutating, openToAll, canEditInfo, handleUpdate
openToAllError, isLoading, isMutating, openToAll, handleUpdate
}) => (
<div>
{isLoading ? (
@ -19,12 +18,12 @@ const StudioOpenToAll = ({
<div>
<label>
<input
disabled={isMutating || !canEditInfo}
disabled={isMutating}
type="checkbox"
checked={openToAll}
onChange={e => handleUpdate(e.target.checked)}
/>
<h4>{openToAll ? 'Open to all' : 'Not open to all'}</h4>
<span>{openToAll ? 'Open to all' : 'Not open to all'}</span>
{openToAllError && <div>Error mutating openToAll: {openToAllError}</div>}
</label>
</div>
@ -34,7 +33,6 @@ const StudioOpenToAll = ({
StudioOpenToAll.propTypes = {
openToAllError: PropTypes.string,
canEditInfo: PropTypes.bool,
isLoading: PropTypes.bool,
isMutating: PropTypes.bool,
openToAll: PropTypes.bool,
@ -44,7 +42,6 @@ StudioOpenToAll.propTypes = {
export default connect(
state => ({
openToAll: selectStudioOpenToAll(state),
canEditInfo: selectCanEditInfo(state),
isLoading: selectIsLoadingInfo(state),
isMutating: selectIsMutatingOpenToAll(state),
openToAllError: selectOpenToAllMutationError(state)

View file

@ -6,13 +6,13 @@ import StudioOpenToAll from './studio-open-to-all.jsx';
import {projectFetcher} from './lib/fetchers';
import {projects} from './lib/redux-modules';
import {selectCanAddProjects} from '../../redux/studio-permissions';
import {selectCanAddProjects, selectCanEditOpenToAll} from '../../redux/studio-permissions';
import Debug from './debug.jsx';
const {actions, selector: projectsSelector} = projects;
const StudioProjects = ({
canAddProjects, items, error, loading, moreToLoad, onLoadMore
canAddProjects, canEditOpenToAll, items, error, loading, moreToLoad, onLoadMore
}) => {
const {studioId} = useParams();
@ -25,7 +25,7 @@ const StudioProjects = ({
return (
<div>
<h2>Projects</h2>
<StudioOpenToAll />
{canEditOpenToAll && <StudioOpenToAll />}
{error && <Debug
label="Error"
data={error}
@ -56,6 +56,7 @@ const StudioProjects = ({
StudioProjects.propTypes = {
canAddProjects: PropTypes.bool,
canEditOpenToAll: PropTypes.bool,
items: PropTypes.array, // eslint-disable-line react/forbid-prop-types
loading: PropTypes.bool,
error: PropTypes.object, // eslint-disable-line react/forbid-prop-types
@ -65,7 +66,8 @@ StudioProjects.propTypes = {
const mapStateToProps = state => ({
...projectsSelector(state),
canAddProjects: selectCanAddProjects(state)
canAddProjects: selectCanAddProjects(state),
canEditOpenToAll: selectCanEditOpenToAll(state)
});
const mapDispatchToProps = dispatch => ({

View file

@ -6,7 +6,9 @@ import {
selectCanDeleteCommentWithoutConfirm,
selectCanReportComment,
selectCanRestoreComment,
selectCanFollowStudio
selectCanFollowStudio,
selectCanEditCommentsAllowed,
selectCanEditOpenToAll
} from '../../../src/redux/studio-permissions';
import {getInitialState as getInitialStudioState} from '../../../src/redux/studio';
@ -176,4 +178,34 @@ describe('studio comments', () => {
expect(selectCanFollowStudio(state)).toBe(expected);
});
});
describe('can set "comments allowed" on a studio', () => {
test.each([
['admin', true],
['curator', false],
['manager', false],
['creator', true],
['logged in', false],
['unconfirmed', false],
['logged out', false]
])('%s: %s', (role, expected) => {
setStateByRole(role);
expect(selectCanEditCommentsAllowed(state)).toBe(expected);
});
});
describe('can set "open to all" on a studio', () => {
test.each([
['admin', true],
['curator', false],
['manager', true],
['creator', true],
['logged in', false],
['unconfirmed', false],
['logged out', false]
])('%s: %s', (role, expected) => {
setStateByRole(role);
expect(selectCanEditOpenToAll(state)).toBe(expected);
});
});
});