diff --git a/app/javascript/profileDropdown/flagButton.js b/app/javascript/profileDropdown/flagButton.js index 1cd76ecd4..f27be6eed 100644 --- a/app/javascript/profileDropdown/flagButton.js +++ b/app/javascript/profileDropdown/flagButton.js @@ -1,32 +1,12 @@ /* global userData */ -/* eslint-disable no-alert */ -/** - * Adds a flag button visible only to trusted users on profile pages. - * @function initFlag - * @returns {(void|undefined)} This function has no useable return value. - */ -export function initFlag() { - const flagButton = document.getElementById( - 'user-profile-dropdownmenu-flag-button', - ); - - if (!flagButton) { - // button not always present when this is called - return; - } - - const user = userData(); - if (!user) { - return; - } +/* eslint-disable no-alert, import/order */ +import { request } from '@utilities/http'; +import { getUserDataAndCsrfToken } from '../chat/util'; +function addFlagUserBehavior(flagButton) { const { profileUserId, profileUserName } = flagButton.dataset; - let isUserFlagged = flagButton.dataset.isUserFlagged === 'true'; - const trustedOrAdmin = user.trusted || user.admin; - if (!trustedOrAdmin || user.id === parseInt(profileUserId, 10)) { - flagButton.remove(); - } + let isUserFlagged = flagButton.dataset.isUserFlagged === 'true'; function flag() { const confirmFlag = window.confirm( @@ -36,17 +16,13 @@ export function initFlag() { ); if (confirmFlag) { - fetch('/reactions', { + request('/reactions', { method: 'POST', - headers: { - 'X-CSRF-Token': window.csrfToken, - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ + body: { reactable_type: 'User', category: 'vomit', reactable_id: profileUserId, - }), + }, }) .then((response) => response.json()) .then((response) => { @@ -58,10 +34,49 @@ export function initFlag() { flagButton.innerHTML = `Flag ${profileUserName}`; } }) - .catch((e) => window.alert(`Something went wrong: ${e}`)); + .catch((e) => { + Honeybadger.notify( + isUserFlagged ? 'Unable to unflag user' : 'Unable to flag user', + profileUserId, + ); + window.alert(`Something went wrong: ${e}`); + }); } } flagButton.addEventListener('click', flag); } + +/** + * Adds a flag button visible only to trusted users on profile pages. + * @function initFlag + * @returns {(void|undefined)} This function has no useable return value. + */ + +export function initFlag() { + const flagButton = document.getElementById( + 'user-profile-dropdownmenu-flag-button', + ); + + if (!flagButton) { + // button not always present when this is called + return; + } + + getUserDataAndCsrfToken().then(() => { + const user = userData(); + if (!user) { + flagButton.remove(); + return; + } + + const trustedOrAdmin = user.trusted || user.admin; + const { profileUserId } = flagButton.dataset; + + if (!trustedOrAdmin || user.id === parseInt(profileUserId, 10)) { + flagButton.remove(); + } + addFlagUserBehavior(flagButton); + }); +} /* eslint-enable no-alert */ diff --git a/spec/system/user/trusted_user_flags_user_spec.rb b/spec/system/user/trusted_user_flags_user_spec.rb index c5add9590..5db7fe577 100644 --- a/spec/system/user/trusted_user_flags_user_spec.rb +++ b/spec/system/user/trusted_user_flags_user_spec.rb @@ -2,6 +2,7 @@ require "rails_helper" RSpec.describe "Flagging users from profile pages", type: :system, js: true do let(:user) { create :user } + let(:unflag_text) { "Unflag @#{user.username}" } let(:flag_text) { "Flag @#{user.username}" } context "when not logged in" do @@ -16,12 +17,7 @@ RSpec.describe "Flagging users from profile pages", type: :system, js: true do it "does not show the flag button" do sign_in create(:user) - # TODO: Fix me! Loading the page twice here ensures that the dropdown menu - # does not include the "Flag @username" option. This is a band-aid solution - # in order to get this spec to consistently pass and unblock builds. - 2.times do - visit user_profile_path(user.username) - end + visit user_profile_path(user.username) click_button(id: "user-profile-dropdown") expect(page).not_to have_link(flag_text) @@ -43,7 +39,11 @@ RSpec.describe "Flagging users from profile pages", type: :system, js: true do visit user_profile_path(user.username) click_button(id: "user-profile-dropdown") - expect(page).to have_link(flag_text) + + accept_confirm do + click_link(id: "user-profile-dropdownmenu-flag-button") + end + expect(page).to have_link(unflag_text) end end end