mirror of
https://gh.wpcy.net/https://github.com/discourse/discourse.git
synced 2026-05-02 19:28:42 +08:00
Fixes a couple issues reported here: https://meta.discourse.org/t/ip-info-is-not-updated-when-you-switch-to-a-different-reviewable/391230 1. When you navigated from one review item directly to another, from notifications for example, we weren't resetting the state so if you had opened the insights tab it would remain open with stale IP data. Now didUpdateAttrs will reset the state so the data will be fetched for the new reviewable. 2. Every switch to the insights tab fetches data all over again — this will check if it's been opened and shows/hides it with `hidden` to avoid fetching the data every time
429 lines
14 KiB
Ruby
429 lines
14 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "discourse_ip_info"
|
|
|
|
describe "Viewing reviewable item" do
|
|
fab!(:admin)
|
|
fab!(:moderator)
|
|
fab!(:group)
|
|
fab!(:reviewable_flagged_post) do
|
|
Fabricate(
|
|
:reviewable_flagged_post,
|
|
target_created_by: Fabricate(:user, email: "flagged@example.com"),
|
|
)
|
|
end
|
|
|
|
let(:review_page) { PageObjects::Pages::Review.new }
|
|
let(:review_note_form) { PageObjects::Components::ReviewNoteForm.new }
|
|
|
|
before do
|
|
group.add(admin)
|
|
sign_in(admin)
|
|
end
|
|
|
|
describe "when the reviewable item is a flagged post" do
|
|
it "shows the new reviewable UI" do
|
|
review_page.visit_reviewable(reviewable_flagged_post)
|
|
|
|
expect(page).to have_selector(".review-container")
|
|
end
|
|
|
|
it "shows the reviewable item with badges stating the flag reason and count" do
|
|
_spam_reviewable_score =
|
|
Fabricate(
|
|
:reviewable_score,
|
|
reviewable: reviewable_flagged_post,
|
|
reviewable_score_type: ReviewableScore.types[:spam],
|
|
)
|
|
|
|
_off_topic_reviewable_score =
|
|
Fabricate(
|
|
:reviewable_score,
|
|
reviewable: reviewable_flagged_post,
|
|
reviewable_score_type: ReviewableScore.types[:off_topic],
|
|
)
|
|
|
|
_illegal_reviewable_score =
|
|
Fabricate(
|
|
:reviewable_score,
|
|
reviewable: reviewable_flagged_post,
|
|
reviewable_score_type: ReviewableScore.types[:illegal],
|
|
)
|
|
|
|
_inappropriate_reviewable_score =
|
|
Fabricate(
|
|
:reviewable_score,
|
|
reviewable: reviewable_flagged_post,
|
|
reviewable_score_type: ReviewableScore.types[:inappropriate],
|
|
)
|
|
|
|
_needs_approval_reviewable_score =
|
|
Fabricate(
|
|
:reviewable_score,
|
|
reviewable: reviewable_flagged_post,
|
|
reviewable_score_type: ReviewableScore.types[:needs_approval],
|
|
)
|
|
|
|
flag_reason_component =
|
|
review_page.visit_reviewable(reviewable_flagged_post).flag_reason_component
|
|
|
|
expect(flag_reason_component).to have_spam_flag_reason(reviewable_flagged_post, count: 1)
|
|
expect(flag_reason_component).to have_off_topic_flag_reason(reviewable_flagged_post, count: 1)
|
|
expect(flag_reason_component).to have_illegal_flag_reason(reviewable_flagged_post, count: 1)
|
|
|
|
expect(flag_reason_component).to have_inappropriate_flag_reason(
|
|
reviewable_flagged_post,
|
|
count: 2,
|
|
)
|
|
|
|
expect(flag_reason_component).to have_needs_approval_flag_reason(
|
|
reviewable_flagged_post,
|
|
count: 1,
|
|
)
|
|
end
|
|
|
|
it "shows the topic status, title link, category badge and tags of the topic associated with the reviewable item correctly" do
|
|
post = reviewable_flagged_post.post
|
|
topic = reviewable_flagged_post.topic
|
|
category = Fabricate(:category)
|
|
topic.change_category_to_id(category.id)
|
|
tag_1 = Fabricate(:tag)
|
|
tag_2 = Fabricate(:tag)
|
|
topic.tags = [tag_1, tag_2]
|
|
topic.closed = true
|
|
topic.save!
|
|
|
|
topic_link_component =
|
|
review_page.visit_reviewable(reviewable_flagged_post).topic_link_component
|
|
|
|
expect(topic_link_component).to have_closed_topic_status
|
|
|
|
expect(topic_link_component).to have_topic_link(
|
|
topic_title: topic.title,
|
|
post_url: post.full_url,
|
|
)
|
|
|
|
expect(topic_link_component).to have_category_badge(category.name)
|
|
expect(topic_link_component).to have_tag_link(tag_name: tag_1.name, tag_url: tag_1.url)
|
|
expect(topic_link_component).to have_tag_link(tag_name: tag_2.name, tag_url: tag_2.url)
|
|
|
|
# TODO: Add test for watched words highlighting
|
|
end
|
|
|
|
it "allows to add notes and persists them when toggle tabs" do
|
|
review_page.visit_reviewable(reviewable_flagged_post)
|
|
review_page.click_timeline_tab
|
|
review_note_form.add_note("This is a review note.")
|
|
review_page.click_insights_tab
|
|
review_page.click_timeline_tab
|
|
expect(page).to have_text("This is a review note.")
|
|
end
|
|
|
|
it "shows confirmation dialog when navigating away with unsaved note, but not after clearing the note" do
|
|
dialog = PageObjects::Components::Dialog.new
|
|
|
|
review_page.visit_reviewable(reviewable_flagged_post)
|
|
review_page.click_timeline_tab
|
|
|
|
review_note_form.form.fill_in("content", with: "This is a draft note")
|
|
|
|
click_logo
|
|
|
|
expect(dialog).to be_open
|
|
expect(dialog).to have_content(I18n.t("js.form_kit.dirty_form"))
|
|
|
|
dialog.click_no
|
|
|
|
expect(page).to have_current_path("/review/#{reviewable_flagged_post.id}")
|
|
|
|
review_note_form.form.fill_in("content", with: "")
|
|
|
|
click_logo
|
|
|
|
expect(dialog).to be_closed
|
|
expect(page).to have_current_path("/")
|
|
end
|
|
|
|
it "displays the flagged user's email address in user activity" do
|
|
review_page.visit_reviewable(reviewable_flagged_post)
|
|
review_page.click_insights_tab
|
|
|
|
expect(page).to have_text("flagged@example.com")
|
|
end
|
|
|
|
describe "Moderation history" do
|
|
fab!(:flagged_user) { reviewable_flagged_post.target_created_by }
|
|
|
|
it "displays the number of times the user has been silenced, suspended and number of rejected posts" do
|
|
UserHistory.create!(
|
|
action: UserHistory.actions[:silence_user],
|
|
target_user_id: flagged_user.id,
|
|
acting_user_id: admin.id,
|
|
)
|
|
UserHistory.create!(
|
|
action: UserHistory.actions[:silence_user],
|
|
target_user_id: flagged_user.id,
|
|
acting_user_id: admin.id,
|
|
)
|
|
UserHistory.create!(
|
|
action: UserHistory.actions[:suspend_user],
|
|
target_user_id: flagged_user.id,
|
|
acting_user_id: admin.id,
|
|
)
|
|
ReviewableQueuedPost.create!(
|
|
created_by: admin,
|
|
target_created_by: flagged_user,
|
|
status: Reviewable.statuses[:rejected],
|
|
payload: {
|
|
raw: "test post 1",
|
|
},
|
|
)
|
|
ReviewableQueuedPost.create!(
|
|
created_by: admin,
|
|
target_created_by: flagged_user,
|
|
status: Reviewable.statuses[:rejected],
|
|
payload: {
|
|
raw: "test post 2",
|
|
},
|
|
)
|
|
|
|
review_page.visit_reviewable(reviewable_flagged_post)
|
|
review_page.click_insights_tab
|
|
|
|
expect(page).to have_text(
|
|
I18n.t("js.review.insights.moderation_history.silenced", count: 2),
|
|
)
|
|
expect(page).to have_text(
|
|
I18n.t("js.review.insights.moderation_history.suspended", count: 1),
|
|
)
|
|
expect(page).to have_text(
|
|
I18n.t("js.review.insights.moderation_history.rejected_posts", count: 2),
|
|
)
|
|
end
|
|
end
|
|
|
|
describe "IP lookup" do
|
|
fab!(:reviewable_flagged_post)
|
|
|
|
before do
|
|
reviewable_flagged_post.target_created_by.update!(ip_address: "81.2.69.142")
|
|
|
|
DiscourseIpInfo.open_db(File.join(Rails.root, "spec", "fixtures", "mmdb"))
|
|
Resolv::DNS
|
|
.any_instance
|
|
.stubs(:getname)
|
|
.with("81.2.69.142")
|
|
.returns("ip-81-2-69-142.example.com")
|
|
end
|
|
|
|
it "shows IP lookup information when insights tab is viewed" do
|
|
review_page.visit_reviewable(reviewable_flagged_post)
|
|
review_page.click_insights_tab
|
|
|
|
expect(review_page).to have_ip_lookup_info
|
|
end
|
|
|
|
it "displays IP location, hostname, and organization when available" do
|
|
review_page.visit_reviewable(reviewable_flagged_post)
|
|
review_page.click_insights_tab
|
|
|
|
expect(review_page).to have_ip_location("London, England, United Kingdom")
|
|
expect(review_page).to have_ip_hostname("ip-81-2-69-142.example.com")
|
|
end
|
|
|
|
it "shows other accounts link when there are multiple accounts with same IP" do
|
|
other_user_1 = Fabricate(:user, ip_address: "81.2.69.142")
|
|
other_user_2 = Fabricate(:user, ip_address: "81.2.69.142")
|
|
|
|
review_page.visit_reviewable(reviewable_flagged_post)
|
|
review_page.click_insights_tab
|
|
|
|
expect(review_page).to have_other_accounts_link(count: 2)
|
|
end
|
|
|
|
it "opens modal with account list when clicking other accounts link" do
|
|
other_user = Fabricate(:user, username: "suspicious_user", ip_address: "81.2.69.142")
|
|
|
|
review_page.visit_reviewable(reviewable_flagged_post)
|
|
review_page.click_insights_tab
|
|
review_page.click_other_accounts_link
|
|
|
|
expect(review_page).to have_ip_lookup_modal
|
|
expect(review_page).to have_account_in_modal(other_user.username)
|
|
end
|
|
|
|
it "shows correct IP when navigating between reviewables" do
|
|
other_reviewable =
|
|
Fabricate(
|
|
:reviewable_flagged_post,
|
|
target_created_by: Fabricate(:user, ip_address: "2.125.160.216"),
|
|
)
|
|
|
|
Resolv::DNS
|
|
.any_instance
|
|
.stubs(:getname)
|
|
.with("2.125.160.216")
|
|
.returns("ip-2-125-160-216.example.com")
|
|
|
|
review_page.visit_reviewable(reviewable_flagged_post)
|
|
review_page.click_insights_tab
|
|
|
|
expect(review_page).to have_ip_hostname("ip-81-2-69-142.example.com")
|
|
|
|
review_page.visit_reviewable(other_reviewable)
|
|
review_page.click_insights_tab
|
|
|
|
expect(review_page).to have_ip_hostname("ip-2-125-160-216.example.com")
|
|
end
|
|
|
|
context "when category moderator" do
|
|
fab!(:category)
|
|
fab!(:trust_level_1_user, :trust_level_1)
|
|
fab!(:category_moderation_group) do
|
|
Fabricate(
|
|
:category_moderation_group,
|
|
category: category,
|
|
group: trust_level_1_user.groups.last,
|
|
)
|
|
end
|
|
|
|
before do
|
|
SiteSetting.enable_category_group_moderation = true
|
|
reviewable_flagged_post.topic.change_category_to_id(category.id)
|
|
sign_in trust_level_1_user
|
|
end
|
|
|
|
it "does not show IP information" do
|
|
review_page.visit_reviewable(reviewable_flagged_post)
|
|
review_page.click_insights_tab
|
|
|
|
expect(review_page).to have_no_ip_lookup_info
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "when the reviewable item is a queued post" do
|
|
fab!(:reviewable_queued_post)
|
|
|
|
it "allows to edit post when old moderator actions are enabled" do
|
|
review_page.visit_reviewable(reviewable_queued_post)
|
|
|
|
expect(page).to have_text("hello world post contents.")
|
|
review_page.click_edit_post_button
|
|
review_page.fill_post_content("Hello world from system spec!")
|
|
review_page.save_post_edit
|
|
|
|
expect(page).to have_text("Hello world from system spec!")
|
|
expect(page).not_to have_text("hello world post contents.")
|
|
end
|
|
|
|
it "shows context question for rejected queued post" do
|
|
review_page.visit_reviewable(reviewable_queued_post)
|
|
|
|
expect(review_page).to have_context_question(
|
|
reviewable_queued_post,
|
|
I18n.t("js.review.context_question.approve_post"),
|
|
)
|
|
end
|
|
end
|
|
|
|
describe "when the reviewable item is a user" do
|
|
fab!(:user)
|
|
let(:rejection_reason_modal) { PageObjects::Modals::RejectReasonReviewable.new }
|
|
let(:scrub_user_modal) { PageObjects::Modals::ScrubRejectedUser.new }
|
|
|
|
before do
|
|
SiteSetting.must_approve_users = true
|
|
Jobs.run_immediately!
|
|
user.update!(approved: false)
|
|
user.activate
|
|
end
|
|
|
|
it "Allow to delete and scrub user" do
|
|
reviewable = ReviewableUser.find_by_target_id(user.id)
|
|
|
|
review_page.visit_reviewable(reviewable)
|
|
|
|
expect(page).to have_text(user.name)
|
|
expect(page).to have_link(user.username, href: "/admin/users/#{user.id}/#{user.username}")
|
|
|
|
review_page.select_bundled_action(reviewable, "user-delete_user")
|
|
rejection_reason_modal.fill_in_rejection_reason("Spamming the site")
|
|
rejection_reason_modal.delete_user
|
|
|
|
expect(review_page).to have_reviewable_with_rejected_status(reviewable)
|
|
|
|
expect(page).to have_text(user.name)
|
|
|
|
review_page.click_scrub_user_button
|
|
|
|
scrubbing_reason = "a spammer who knows how to make GDPR requests"
|
|
scrub_user_modal.fill_in_scrub_reason(scrubbing_reason)
|
|
expect(scrub_user_modal.scrub_button).not_to be_disabled
|
|
scrub_user_modal.scrub_button.click
|
|
|
|
expect(review_page).to have_reviewable_with_scrubbed_by(reviewable, admin.username)
|
|
expect(review_page).to have_reviewable_with_scrubbed_reason(reviewable, scrubbing_reason)
|
|
expect(review_page).to have_reviewable_with_scrubbed_at(
|
|
reviewable,
|
|
reviewable.payload["scrubbed_at"],
|
|
)
|
|
expect(page).not_to have_text(user.name)
|
|
end
|
|
|
|
it "Allows to delete and block user" do
|
|
reviewable = ReviewableUser.find_by_target_id(user.id)
|
|
|
|
review_page.visit_reviewable(reviewable)
|
|
review_page.select_bundled_action(reviewable, "user-delete_user_block")
|
|
rejection_reason_modal.fill_in_rejection_reason("Spamming the site")
|
|
rejection_reason_modal.delete_user
|
|
expect(review_page).to have_reviewable_with_rejected_status(reviewable)
|
|
expect(review_page).to have_rejected_item_in_timeline(reviewable)
|
|
end
|
|
|
|
it "Allows to approve user" do
|
|
reviewable = ReviewableUser.find_by_target_id(user.id)
|
|
|
|
review_page.visit_reviewable(reviewable)
|
|
review_page.click_approve_user_button
|
|
|
|
expect(review_page).to have_reviewable_with_approved_status(reviewable)
|
|
expect(review_page).to have_approved_item_in_timeline(reviewable)
|
|
end
|
|
end
|
|
|
|
describe "moderator" do
|
|
before do
|
|
group.add(admin)
|
|
group.add(moderator)
|
|
sign_in(moderator)
|
|
end
|
|
|
|
it "shows claimed and unclaimed events in the timeline" do
|
|
SiteSetting.reviewable_claiming = "required"
|
|
|
|
review_page.visit_reviewable(reviewable_flagged_post)
|
|
expect(review_page).to have_history_items(count: 2)
|
|
expect(review_page).to have_created_at_history_item
|
|
|
|
review_page.click_claim_reviewable
|
|
page.refresh
|
|
expect(review_page).to have_history_items(count: 3)
|
|
expect(review_page).to have_claimed_history_item(moderator)
|
|
|
|
review_page.click_unclaim_reviewable
|
|
page.refresh
|
|
expect(review_page).to have_history_items(count: 4)
|
|
expect(review_page).to have_unclaimed_history_item(moderator)
|
|
|
|
# remove history items created by deleted users
|
|
UserDestroyer.new(admin).destroy(moderator)
|
|
sign_in(admin)
|
|
review_page.visit_reviewable(reviewable_flagged_post)
|
|
|
|
expect(review_page).to have_history_items(count: 2)
|
|
end
|
|
end
|
|
end
|