diff --git a/src/amo/components/FlagReview/index.js b/src/amo/components/FlagReview/index.js index ba834ddc4b..b825fcbd7c 100644 --- a/src/amo/components/FlagReview/index.js +++ b/src/amo/components/FlagReview/index.js @@ -14,11 +14,14 @@ import type { ElementEvent, HTMLElementEventHandler } from 'amo/types/dom'; import type { ErrorHandlerType } from 'amo/types/errorHandler'; import type { DispatchFunc } from 'amo/types/redux'; +import './styles.scss'; + type Props = {| buttonText: string, reason: FlagReviewReasonType, review: UserReviewType, wasFlaggedText: string, + disabled?: boolean, |}; type PropsFromState = {| @@ -47,7 +50,8 @@ export class FlagReviewBase extends React.Component { }; renderControls(): React.Node { - const { errorHandler, flagState, buttonText, wasFlaggedText } = this.props; + const { disabled, errorHandler, flagState, buttonText, wasFlaggedText } = + this.props; if (flagState) { if (flagState.inProgress && !errorHandler.hasError()) { @@ -63,6 +67,7 @@ export class FlagReviewBase extends React.Component { className="FlagReview-button" onClick={this.onClick} type="button" + disabled={!!disabled} > {buttonText} diff --git a/src/amo/components/FlagReview/styles.scss b/src/amo/components/FlagReview/styles.scss new file mode 100644 index 0000000000..4bc2d66213 --- /dev/null +++ b/src/amo/components/FlagReview/styles.scss @@ -0,0 +1,11 @@ +@import '~amo/css/styles'; + +.FlagReview-button[disabled] { + @include disabled; + + &:hover, + &:focus, + &:active { + color: initial !important; + } +} diff --git a/src/amo/components/FlagReviewMenu/index.js b/src/amo/components/FlagReviewMenu/index.js index 1af0c0285a..cee56d560d 100644 --- a/src/amo/components/FlagReviewMenu/index.js +++ b/src/amo/components/FlagReviewMenu/index.js @@ -65,8 +65,16 @@ export class FlagReviewMenuBase extends React.Component { 'A user cannot flag their own review.', ); + const enableFeatureFeedbackFormLinks = config.get( + 'enableFeatureFeedbackFormLinks', + ); + + const disableItemsForUnauthenticatedUsers = enableFeatureFeedbackFormLinks + ? !siteUser + : false; + let items; - if (!siteUser) { + if (!enableFeatureFeedbackFormLinks && !siteUser) { items = [ { review={review} buttonText={i18n.gettext('This is spam')} wasFlaggedText={i18n.gettext('Flagged as spam')} + disabled={disableItemsForUnauthenticatedUsers} /> , - {config.get('enableFeatureFeedbackFormLinks') ? ( + {enableFeatureFeedbackFormLinks ? ( {i18n.gettext('This contains inappropriate language')} @@ -124,6 +133,7 @@ export class FlagReviewMenuBase extends React.Component { wasFlaggedText={i18n.gettext( 'Flagged as a bug report or support request', )} + disabled={disableItemsForUnauthenticatedUsers} /> ), diff --git a/src/amo/components/TooltipMenu/styles.scss b/src/amo/components/TooltipMenu/styles.scss index 32c7ec222c..c8730105df 100644 --- a/src/amo/components/TooltipMenu/styles.scss +++ b/src/amo/components/TooltipMenu/styles.scss @@ -90,7 +90,7 @@ a, a:link, button { - &:not(.Button) { + &:not(.Button):not([disabled]) { @include font-medium; cursor: pointer; diff --git a/tests/unit/amo/components/TestAddonReviewCard.js b/tests/unit/amo/components/TestAddonReviewCard.js index 66e602dd8e..2a1c0c0949 100644 --- a/tests/unit/amo/components/TestAddonReviewCard.js +++ b/tests/unit/amo/components/TestAddonReviewCard.js @@ -1485,6 +1485,11 @@ describe(__filename, () => { await openFlagMenu(); + expect( + screen.getByRole('button', { + name: 'This is spam', + }), + ).not.toBeDisabled(); expect( // It would have to be a 'button' if `enableFeatureFeedbackFormLinks` // was set to `false`. @@ -1492,6 +1497,11 @@ describe(__filename, () => { name: 'This contains inappropriate language', }), ).toBeInTheDocument(); + expect( + screen.getByRole('button', { + name: 'This is a bug report or support request', + }), + ).not.toBeDisabled(); }); it('can be configured with an openerClass', () => { @@ -1525,6 +1535,60 @@ describe(__filename, () => { ).toBeInTheDocument(); }); + describe('when enableFeatureFeedbackFormLinks is enabled', () => { + beforeEach(() => { + const fakeConfig = getMockConfig({ + enableFeatureFeedbackFormLinks: true, + }); + config.get.mockImplementation((key) => { + return fakeConfig[key]; + }); + }); + + it('shows the menu for signed-out users', async () => { + render({ review: _setReview() }); + + await openFlagMenu(); + + expect( + screen.queryByRole('link', { name: 'Log in to flag this review' }), + ).not.toBeInTheDocument(); + expect( + screen.getByRole('button', { + name: 'This is spam', + }), + ).toBeDisabled(); + expect( + screen.getByRole('link', { + name: 'This contains inappropriate language', + }), + ).toBeInTheDocument(); + expect( + screen.getByRole('button', { + name: 'This is a bug report or support request', + }), + ).toBeDisabled(); + }); + + it('shows the menu for signed-in users', async () => { + dispatchSignInActionsWithStore({ store, userId: 999 }); + render({ review: _setReview() }); + + await openFlagMenu(); + + expect( + screen.getByRole('button', { + name: 'This is spam', + }), + ).not.toBeDisabled(); + expect( + screen.getByRole('button', { + name: 'This is a bug report or support request', + }), + ).not.toBeDisabled(); + }); + }); + it('prompts you to flag a developer response after login', async () => { renderNestedReply();