From 20426816740a6ecc2c37e1e1154bb1b33d02c399 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Feb 2024 14:44:11 -0800 Subject: [PATCH 01/58] AO3-6680 Bump reviewdog/action-rubocop from 2.7.0 to 2.8.0 (#4735) Bump reviewdog/action-rubocop from 2.7.0 to 2.8.0 Bumps [reviewdog/action-rubocop](https://github.com/reviewdog/action-rubocop) from 2.7.0 to 2.8.0. - [Release notes](https://github.com/reviewdog/action-rubocop/releases) - [Commits](https://github.com/reviewdog/action-rubocop/compare/32686543011497c256009cce0c94b73a8179cbdb...2f726ae5dd8df72b4faa9d93669cdab96aeb2153) --- updated-dependencies: - dependency-name: reviewdog/action-rubocop dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/reviewdog.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/reviewdog.yml b/.github/workflows/reviewdog.yml index c4014453bb1..58d50002cce 100644 --- a/.github/workflows/reviewdog.yml +++ b/.github/workflows/reviewdog.yml @@ -21,7 +21,7 @@ jobs: bundler-cache: true - name: rubocop - uses: reviewdog/action-rubocop@32686543011497c256009cce0c94b73a8179cbdb + uses: reviewdog/action-rubocop@2f726ae5dd8df72b4faa9d93669cdab96aeb2153 with: use_bundler: true reporter: github-pr-check From aa385b844749c4eae90256c485355ffff47a406c Mon Sep 17 00:00:00 2001 From: Saphron <109723086+denerose@users.noreply.github.com> Date: Wed, 14 Feb 2024 14:37:29 +1100 Subject: [PATCH 02/58] AO3-6613 Clarify GPL version (#4644) * AO3-6613 Clarify GPL version * ERBLint auto to resolve CI style guide fail * Correct additional linter errors * Remove antiquated extra stop/typo * Fix indentation * Revert "Correct additional linter errors" This reverts commit 7b68d12eb70e3cd3e3cd807fadfd31e16182b951. --- README.md | 2 +- app/views/layouts/_footer.html.erb | 30 ++++++------- public/403.html | 2 +- public/445.html | 2 +- public/500.html | 2 +- public/502.html | 2 +- public/503.html | 2 +- public/507.html | 2 +- public/nomaintenance.html | 2 +- public/status/index.html | 68 +++++++++++++++++------------- 10 files changed, 62 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index 419af3c5881..b91d3e67c3f 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ There is currently no API for the OTW-Archive software. While it is something we License and Acknowledgments ---------- -The Archive code is licensed under [GPL](https://www.gnu.org/licenses/gpl-2.0.html) by the [Organization for Transformative Works](https://www.transformativeworks.org/). +The Archive code is licensed under [GPL-2.0-or-later](https://www.gnu.org/licenses/gpl-2.0.html) by the [Organization for Transformative Works](https://www.transformativeworks.org/). We benefit from software and services that are free to use for Open Source projects, including: diff --git a/app/views/layouts/_footer.html.erb b/app/views/layouts/_footer.html.erb index 3653544b3ac..3f6e73ca1ce 100644 --- a/app/views/layouts/_footer.html.erb +++ b/app/views/layouts/_footer.html.erb @@ -1,14 +1,14 @@ -<% unless pseud.description.blank? %> +<% if pseud.description.present? %>
- <%=raw sanitize_field(pseud, :description) %> + <%= raw sanitize_field(pseud, :description, strip_images: true) %>
<% end %> diff --git a/app/views/share/_embed_meta_bookmark.erb b/app/views/share/_embed_meta_bookmark.erb index 757688ab8dc..b5f79af897c 100644 --- a/app/views/share/_embed_meta_bookmark.erb +++ b/app/views/share/_embed_meta_bookmark.erb @@ -5,6 +5,6 @@ <% end %> <% if bookmark.bookmarker_notes.present? %> <%= ts("Bookmarker's Notes: ").html_safe %> -<%= raw(sanitize_field(bookmark, :bookmarker_notes)) %> +<%= raw sanitize_field(bookmark, :bookmarker_notes, strip_images: true) %> <% end %> <% end %> diff --git a/features/bookmarks/bookmark_create.feature b/features/bookmarks/bookmark_create.feature index 72d1d8efe72..e56da0f057c 100644 --- a/features/bookmarks/bookmark_create.feature +++ b/features/bookmarks/bookmark_create.feature @@ -108,6 +108,18 @@ Scenario: extra commas in bookmark form (Issue 2284) And I press "Create" Then I should see "created" +Scenario: Bookmark notes do not display images + Given I am logged in as "bookmarkuser" + And I post the work "Some Work" + When I follow "Bookmark" + And I fill in "Notes" with "Fantastic!" + And I press "Create" + And all indexing jobs have been run + Then I should see "Bookmark was successfully created" + When I go to the bookmarks page + Then I should not see the image "src" text "http://example.com/icon.svg" + And I should see "Fantastic!" + Scenario: bookmark added to moderated collection has flash notice only when not approved Given the following activated users exist | login | password | diff --git a/features/comments_and_kudos/add_comment.feature b/features/comments_and_kudos/add_comment.feature index 782700c82f0..c4613c550a8 100644 --- a/features/comments_and_kudos/add_comment.feature +++ b/features/comments_and_kudos/add_comment.feature @@ -133,7 +133,7 @@ Scenario: Comment threading, comment editing And I fill in "Comment" with "B's improved comment (edited)" And I press "Update" Then 0 emails should be delivered to "User_A" - + Scenario: Try to post an invalid comment When I am logged in as "author" @@ -180,6 +180,17 @@ Scenario: Set preference and receive comment notifications of your own comments And "commenter" should be emailed And 1 email should be delivered to "commenter" +Scenario: Work comment displays images + + Given the work "Generic Work" + And I am logged in as "commenter" + And I visit the new comment page for the work "Generic Work" + When I fill in "Comment" with "Fantastic!" + And I press "Comment" + Then I should see "Comment created!" + And I should see "Fantastic!" + And I should see the image "src" text "http://example.com/icon.svg" + Scenario: Try to post a comment with a < angle bracket before a linebreak, without a space before the bracket Given the work "Generic Work" @@ -194,7 +205,7 @@ Scenario: Try to post a comment with a < angle bracket before a linebreak, witho And I press "Comment" Then I should see "Comment created!" -Scenario: Try to post a comment with a < angle bracket before a linebreak, with a space before the bracket +Scenario: Try to post a comment with a < angle bracket before a linebreak, with a space before the bracket Given the work "Generic Work" And I am logged in as "commenter" diff --git a/features/comments_and_kudos/comments_adminposts.feature b/features/comments_and_kudos/comments_adminposts.feature index da130cc1d0e..a5060948daa 100644 --- a/features/comments_and_kudos/comments_adminposts.feature +++ b/features/comments_and_kudos/comments_adminposts.feature @@ -135,3 +135,14 @@ Feature: Commenting on admin posts When I follow "Edit Post" Then I should see "No one can comment" # TODO: Test that the other options aren't available/selected in a non-brittle way + + Scenario: Admin post comment does not display images + Given I have posted an admin post + And I am logged in as "regular" + And I go to the admin-posts page + And I follow "Default Admin Post" + When I fill in "Comment" with "Hi!" + And I press "Comment" + Then I should see "Comment created!" + And I should not see the image "src" text "http://example.com/icon.svg" + And I should see "Hi!" diff --git a/features/other_a/pseuds.feature b/features/other_a/pseuds.feature index 50379fcfc78..077c1407e00 100644 --- a/features/other_a/pseuds.feature +++ b/features/other_a/pseuds.feature @@ -118,6 +118,18 @@ Scenario: Manage pseuds - add, edit And I should see "I wanted to add another fancy name" And I should not see "My new name (editpseuds)" +Scenario: Pseud descriptions do not display images + + Given I am logged in as "myself" + And I go to my pseuds page + When I follow "Edit" + And I fill in "Description" with "Fantastic!" + And I press "Update" + Then I should see "Pseud was successfully updated." + When I follow "Back To Pseuds" + Then I should not see the image "src" text "http://example.com/icon.svg" + And I should see "Fantastic!" + Scenario: Comments reflect pseud changes immediately Given the work "Interesting" diff --git a/lib/html_cleaner.rb b/lib/html_cleaner.rb index f2636d00a16..a70e19517ec 100644 --- a/lib/html_cleaner.rb +++ b/lib/html_cleaner.rb @@ -2,17 +2,21 @@ module HtmlCleaner # If we aren't sure that this field hasn't been sanitized since the last sanitizer version, # we sanitize it before we allow it to pass through (and save it if possible). - def sanitize_field(object, fieldname) + def sanitize_field(object, fieldname, strip_images: false) return "" if object.send(fieldname).nil? sanitizer_version = object.try("#{fieldname}_sanitizer_version") - if sanitizer_version && sanitizer_version >= ArchiveConfig.SANITIZER_VERSION - # return the field without sanitizing - object.send(fieldname) - else - # no sanitizer version information, so re-sanitize - sanitize_value(fieldname, object.send(fieldname)) - end + sanitized_field = + if sanitizer_version && sanitizer_version >= ArchiveConfig.SANITIZER_VERSION + # return the field without sanitizing + object.send(fieldname) + else + # no sanitizer version information, so re-sanitize + sanitize_value(fieldname, object.send(fieldname)) + end + + sanitized_field = strip_images(sanitized_field) if strip_images + sanitized_field end # yank out bad end-of-line characters and evil msword curly quotes diff --git a/spec/mailers/admin_mailer_spec.rb b/spec/mailers/admin_mailer_spec.rb index 9074b1b51d2..2ab35574f50 100644 --- a/spec/mailers/admin_mailer_spec.rb +++ b/spec/mailers/admin_mailer_spec.rb @@ -3,6 +3,48 @@ require "spec_helper" describe AdminMailer do + describe "#comment_notification" do + let(:email) { described_class.comment_notification(comment.id) } + + context "when the comment is on an admin post" do + let(:comment) { create(:comment, :on_admin_post) } + + context "and the comment's contents contain an image" do + let(:image_tag) { "" } + + before do + comment.comment_content += image_tag + comment.save! + end + + it "strips the image from the email message" do + expect(email).not_to have_html_part_content(image_tag) + end + end + end + end + + describe "#edited_comment_notification" do + let(:email) { described_class.edited_comment_notification(comment.id) } + + context "when the comment is on an admin post" do + let(:comment) { create(:comment, :on_admin_post) } + + context "and the comment's contents contain an image" do + let(:image_tag) { "" } + + before do + comment.comment_content += image_tag + comment.save! + end + + it "strips the image from the email message" do + expect(email).not_to have_html_part_content(image_tag) + end + end + end + end + describe "send_spam_alert" do let(:spam_user) { create(:user) } diff --git a/spec/mailers/comment_mailer_spec.rb b/spec/mailers/comment_mailer_spec.rb index 1946bcdd561..c60f4647e8d 100644 --- a/spec/mailers/comment_mailer_spec.rb +++ b/spec/mailers/comment_mailer_spec.rb @@ -71,7 +71,21 @@ end end - describe "comment_notification" do + shared_examples "strips image tags" do + let(:image_tag) { "" } + + before do + comment.comment_content += image_tag + comment.save! + end + + it "strips the image from the email message" do + expect(email).not_to have_html_part_content(image_tag) + expect(email).not_to have_text_part_content(image_tag) + end + end + + describe "#comment_notification" do subject(:email) { CommentMailer.comment_notification(user, comment) } it_behaves_like "an email with a valid sender" @@ -79,6 +93,12 @@ it_behaves_like "a notification email with a link to the comment" it_behaves_like "a notification email with a link to reply to the comment" + context "when the comment is on an admin post" do + let(:comment) { create(:comment, :on_admin_post) } + + it_behaves_like "strips image tags" + end + context "when the comment is a reply to another comment" do let(:comment) { create(:comment, commentable: create(:comment)) } @@ -111,6 +131,12 @@ it_behaves_like "a notification email with a link to the comment" it_behaves_like "a notification email with a link to reply to the comment" + context "when the comment is on an admin post" do + let(:comment) { create(:comment, :on_admin_post) } + + it_behaves_like "strips image tags" + end + context "when the comment is a reply to another comment" do let(:comment) { create(:comment, commentable: create(:comment)) } @@ -147,6 +173,12 @@ it_behaves_like "a notification email with a link to reply to the comment" it_behaves_like "a notification email with a link to the comment's thread" + context "when the comment is on an admin post" do + let(:comment) { create(:comment, :on_admin_post) } + + it_behaves_like "strips image tags" + end + context "when the comment is on a tag" do let(:parent_comment) { create(:comment, :on_tag) } @@ -183,6 +215,12 @@ it_behaves_like "a notification email with a link to reply to the comment" it_behaves_like "a notification email with a link to the comment's thread" + context "when the comment is on an admin post" do + let(:comment) { create(:comment, :on_admin_post) } + + it_behaves_like "strips image tags" + end + context "when the comment is on a tag" do let(:parent_comment) { create(:comment, :on_tag) } diff --git a/spec/models/feedback_reporters/abuse_reporter_spec.rb b/spec/models/feedback_reporters/abuse_reporter_spec.rb index 9bafc6a8aea..0cbd4c06f44 100644 --- a/spec/models/feedback_reporters/abuse_reporter_spec.rb +++ b/spec/models/feedback_reporters/abuse_reporter_spec.rb @@ -79,5 +79,13 @@ expect(subject.report_attributes.fetch("cf").fetch("cf_url")).to eq("Unknown URL") end end + + context "if the report has an image in description" do + it "strips all img tags" do + allow(subject).to receive(:description).and_return("Hi!Bye!") + + expect(subject.report_attributes.fetch("description")).to eq("Hi!Bye!") + end + end end end diff --git a/spec/models/feedback_reporters/support_reporter_spec.rb b/spec/models/feedback_reporters/support_reporter_spec.rb index c14fce8555e..33065485836 100644 --- a/spec/models/feedback_reporters/support_reporter_spec.rb +++ b/spec/models/feedback_reporters/support_reporter_spec.rb @@ -89,5 +89,13 @@ expect(subject.report_attributes.fetch("cf").fetch("cf_user_agent")).to eq("Unknown user agent") end end + + context "if the report has an image in description" do + it "strips all img tags" do + allow(subject).to receive(:description).and_return("Hi!Bye!") + + expect(subject.report_attributes.fetch("description")).to eq("Hi!Bye!") + end + end end end From 323abe1e4155d8c0fa5d9729f97f8d782cad0e02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20B?= Date: Sun, 24 Mar 2024 20:53:50 +0100 Subject: [PATCH 39/58] AO3-6502 Blocked users should not be able to give gift works to blocker (#4721) * AO3-6502 Blocked users gifting works to blocker https://otwarchive.atlassian.net/browse/AO3-6502 * Extend to co-authors * Possibly overkill error message improvement * Cop * Remove ??? break * Actually read/follow the spec * Add challenge exception Based on https://github.com/otwcode/otwarchive/pull/4721#issuecomment-1902728815 * Additional tests * Fix (unrelated) intermittent test * What if the test actually tested the right thing? * Cop * Add translation keys * i18n normalize * Proper RoR syntax * Explicit new restriction on blocked users * Revert "Fix (unrelated) intermittent test" This reverts commit d3839c9985caf0b5ce1e08a1895b93afb71d5b4b. Unable to reproduce on master anymore? --- app/models/work.rb | 40 ++++++++++++-- .../blocked/users/confirm_block.html.erb | 1 + .../blocked/users/confirm_unblock.html.erb | 1 + app/views/blocked/users/index.html.erb | 1 + config/locales/models/en.yml | 2 + config/locales/views/en.yml | 3 ++ .../challenge_giftexchange.feature | 34 ++++++++++++ features/other_a/gift.feature | 54 +++++++++++++++++++ ...challenge_promptmeme_posting_fills.feature | 17 ++++++ features/users/blocking.feature | 14 +++++ 10 files changed, 164 insertions(+), 3 deletions(-) diff --git a/app/models/work.rb b/app/models/work.rb index 292d6957c55..da0501e4f98 100755 --- a/app/models/work.rb +++ b/app/models/work.rb @@ -183,10 +183,34 @@ def new_recipients_allow_gifts self.new_gifts.each do |gift| next if gift.pseud.blank? next if gift.pseud&.user&.preference&.allow_gifts? - next if self.challenge_assignments.map(&:requesting_pseud).include?(gift.pseud) - next if self.challenge_claims.reject { |c| c.request_prompt.anonymous? }.map(&:requesting_pseud).include?(gift.pseud) + next if challenge_bypass(gift) - self.errors.add(:base, ts("%{byline} does not accept gifts.", byline: gift.pseud.byline)) + self.errors.add(:base, :blocked_gifts, byline: gift.pseud.byline) + end + end + + validate :new_recipients_have_not_blocked_gift_giver + def new_recipients_have_not_blocked_gift_giver + return if self.new_gifts.blank? + + self.new_gifts.each do |gift| + # Already dealt with in #new_recipients_allow_gifts + next if gift.pseud&.user&.preference && !gift.pseud.user.preference.allow_gifts? + + next if challenge_bypass(gift) + + blocked_users = gift.pseud&.user&.blocked_users || [] + next if blocked_users.empty? + + pseuds_after_saving.each do |pseud| + next unless blocked_users.include?(pseud.user) + + if User.current_user == pseud.user + self.errors.add(:base, :blocked_your_gifts, byline: gift.pseud.byline) + else + self.errors.add(:base, :blocked_gifts, byline: gift.pseud.byline) + end + end end end @@ -1258,4 +1282,14 @@ def nonfiction def allow_collection_invitation? users.any? { |user| user.preference.allow_collection_invitation } end + + private + + def challenge_bypass(gift) + self.challenge_assignments.map(&:requesting_pseud).include?(gift.pseud) || + self.challenge_claims + .reject { |c| c.request_prompt.anonymous? } + .map(&:requesting_pseud) + .include?(gift.pseud) + end end diff --git a/app/views/blocked/users/confirm_block.html.erb b/app/views/blocked/users/confirm_block.html.erb index 01ebec6d766..03b6045ec80 100644 --- a/app/views/blocked/users/confirm_block.html.erb +++ b/app/views/blocked/users/confirm_block.html.erb @@ -10,6 +10,7 @@

<%= t(".will_not.intro") %>

diff --git a/app/views/blocked/users/confirm_unblock.html.erb b/app/views/blocked/users/confirm_unblock.html.erb index af702be64b2..7e8b2fc2a82 100644 --- a/app/views/blocked/users/confirm_unblock.html.erb +++ b/app/views/blocked/users/confirm_unblock.html.erb @@ -10,6 +10,7 @@ diff --git a/app/views/blocked/users/index.html.erb b/app/views/blocked/users/index.html.erb index 045c8409c1a..4d00f2877b4 100644 --- a/app/views/blocked/users/index.html.erb +++ b/app/views/blocked/users/index.html.erb @@ -13,6 +13,7 @@

<%= t(".will_not.intro") %>

diff --git a/config/locales/models/en.yml b/config/locales/models/en.yml index 8c16681d48c..9730233f056 100644 --- a/config/locales/models/en.yml +++ b/config/locales/models/en.yml @@ -175,6 +175,8 @@ en: attributes: user_defined_tags_count: at_most: must not add up to more than %{count}. Your work has %{value} of these tags, so you must remove %{diff} of them. + blocked_gifts: "%{byline} does not accept gifts." + blocked_your_gifts: "%{byline} does not accept gifts from you." work/parent_work_relationships: format: "%{message}" models: diff --git a/config/locales/views/en.yml b/config/locales/views/en.yml index 12015c85d30..b8951dffe92 100644 --- a/config/locales/views/en.yml +++ b/config/locales/views/en.yml @@ -325,6 +325,7 @@ en: title: Block %{name} will: commenting: commenting or leaving kudos on your works + gifting: giving you gift works outside of challenge assignments and claimed prompts intro: 'Blocking a user prevents them from:' replying: replying to your comments anywhere on the site will_not: @@ -337,6 +338,7 @@ en: cancel: Cancel resume: commenting: commenting or leaving kudos on your works + gifting: giving you gift works outside of challenge assignments and claimed prompts intro: 'Unblocking a user allows them to resume:' replying: replying to your comments anywhere on the site sure_html: Are you sure you want to %{unblock} %{username}? @@ -356,6 +358,7 @@ en: title: Blocked Users will: commenting: commenting or leaving kudos on your works + gifting: giving you gift works outside of challenge assignments and claimed prompts intro: one: 'You can block up to %{block_limit} user. Blocking a user prevents them from:' other: 'You can block up to %{block_limit} users. Blocking a user prevents them from:' diff --git a/features/gift_exchanges/challenge_giftexchange.feature b/features/gift_exchanges/challenge_giftexchange.feature index 424f0c209ac..13c95d5d5bd 100644 --- a/features/gift_exchanges/challenge_giftexchange.feature +++ b/features/gift_exchanges/challenge_giftexchange.feature @@ -641,3 +641,37 @@ Feature: Gift Exchange Challenge And I uncheck "exchange_collection (recip)" And I press "Post" Then I should see "For recip." + + Scenario: If a work is connected to an assignment for a user who blocked the gifter, + user is still automatically added as a gift recipient. The recipient + remains attached even if the work is later disconnected from the assignment. + Given basic tags + And the user "recip" exists and is activated + And the user "recip" allows gifts + And the user "recip" has blocked the user "gifter" + And I am logged in as "gifter" + And I have an assignment for the user "recip" in the collection "exchange_collection" + When I fulfill my assignment + Then I should see "For recip." + When I follow "Edit" + And I uncheck "exchange_collection (recip)" + And I press "Post" + Then I should see "For recip." + + Scenario: A user can explicitly give a gift to a user who blocked the gifter if + the work is connected to an assignment. The recipient remains attached even if + the work is later disconnected from the assignment. + Given basic tags + And the user "recip" exists and is activated + And the user "recip" allows gifts + And the user "recip" has blocked the user "gifter" + And I am logged in as "gifter" + And I have an assignment for the user "recip" in the collection "exchange_collection" + When I start to fulfill my assignment + And I fill in "Gift this work to" with "recip" + And I press "Post" + Then I should see "For recip." + When I follow "Edit" + And I uncheck "exchange_collection (recip)" + And I press "Post" + Then I should see "For recip." diff --git a/features/other_a/gift.feature b/features/other_a/gift.feature index ec39358f45f..8d77e3b5171 100644 --- a/features/other_a/gift.feature +++ b/features/other_a/gift.feature @@ -337,3 +337,57 @@ Feature: Create Gifts And I should not see "by gifter for giftee1" When I view the work "Rude Gift" Then I should not see "For giftee1." + + Scenario: Can't give a gift to a user who has blocked you + Given the user "giftee1" has blocked the user "gifter" + When I am logged in as "gifter" + And I post the work "Rude Gift" as a gift for "giftee1" + Then I should see "Sorry! We couldn't save this work because: giftee1 does not accept gifts from you." + And 0 emails should be delivered to "giftee1@example.com" + + Scenario: Can't gift an existing work to a user who has blocked you + Given the user "giftee1" has blocked the user "gifter" + And I press "Post" + And I follow "Edit" + And I give the work to "giftee1" + When I press "Post" + Then I should see "Sorry! We couldn't save this work because: giftee1 does not accept gifts from you." + + Scenario: Can't gift a work whose co-creator is blocked by recipient + Given I coauthored the work "Collateral" as "gifter" with "gifter2" + And the user "giftee1" has blocked the user "gifter2" + And I edit the work "Collateral" + And I give the work to "giftee1" + When I press "Post" + Then I should see "Sorry! We couldn't save this work because: giftee1 does not accept gifts." + + Scenario: Only see one error message is shown if gifts are disabled and user is blocked* + Given the user "giftee1" disallows gifts + And the user "giftee1" has blocked the user "gifter" + When I am logged in as "gifter" + And I post the work "Rude Gift" as a gift for "giftee1" + Then I should see "Sorry! We couldn't save this work because:" + And I should see "giftee1 does not accept gifts." + And I should not see "giftee1 does not accept gifts from you." + + Scenario: A user can refuse previous gifts from user after blocking them + Given I am logged in as "gifter" + And I post the work "Rude Gift" as a gift for "giftee1" + When I am logged in as "giftee1" + And I go to my gifts page + Then I should see "Rude Gift" + When I go to my blocked users page + And I fill in "blocked_id" with "gifter" + And I press "Block" + And I press "Yes, Block User" + Then I should see "You have blocked the user gifter." + When I go to my gifts page + And it is currently 1 second from now + And I follow "Refuse Gift" + Then I should see "This work will no longer be listed among your gifts." + And I should not see "Rude Gift" + When I follow "Refused Gifts" + Then I should see "Rude Gift" + And I should not see "by gifter for giftee1" + When I view the work "Rude Gift" + Then I should not see "For giftee1." diff --git a/features/prompt_memes_b/challenge_promptmeme_posting_fills.feature b/features/prompt_memes_b/challenge_promptmeme_posting_fills.feature index 38691a84848..e15e8e7c5fb 100755 --- a/features/prompt_memes_b/challenge_promptmeme_posting_fills.feature +++ b/features/prompt_memes_b/challenge_promptmeme_posting_fills.feature @@ -542,3 +542,20 @@ Feature: Prompt Meme Challenge And I fill in "Gift this work to" with "prompter, bystander" And I press "Post" Then I should see "bystander does not accept gifts." + + Scenario: A creator can give a gift to a user who has blocked them if the work is connected to a claim of a non-anonymous prompt belonging to the recipient + + Given I have Battle 12 prompt meme fully set up + And the user "prompter" exists and is activated + And the user "prompter" has blocked the user "gifter" + And "prompter" has signed up for Battle 12 with combination A + When I am logged in as "gifter" + And I claim a prompt from "Battle 12" + And I start to fulfill my claim + And I fill in "Gift this work to" with "prompter" + And I press "Post" + Then I should see "For prompter." + When I follow "Edit" + And I uncheck "Battle 12 (prompter)" + And I press "Post" + Then I should see "For prompter." diff --git a/features/users/blocking.feature b/features/users/blocking.feature index d136e427c9a..d305915dd3f 100644 --- a/features/users/blocking.feature +++ b/features/users/blocking.feature @@ -121,3 +121,17 @@ Feature: Blocking | superadmin | | policy_and_abuse | | support | + + Scenario: Users are told about blocking effects on gift-giving + Given the user "pest" exists and is activated + And I am logged in as "blocker" + When I go to my blocked users page + Then I should see "giving you gift works" + Given the user "unblocker" has blocked the user "improving" + And I am logged in as "unblocker" + When I go to my blocked users page + Then I should see "improving" + And I should see "giving you gift works" + When I follow "Unblock" + Then I should see a "Yes, Unblock User" button + And I should see "giving you gift works" From 03193e15109c9b5e375705f1b76851b6caab1181 Mon Sep 17 00:00:00 2001 From: EchoEkhi Date: Sun, 24 Mar 2024 19:54:02 +0000 Subject: [PATCH 40/58] AO3-6320 Fix Incomplete error message when including invalid tag with ^ symbol (#4206) * AO3-6320 Fix regex error * AO3-6320 Pleasing the hound * AO3-6320 Add unit test * Fixes for merge --- app/helpers/validation_helper.rb | 8 +++++--- features/other_b/errors.feature | 12 ++++++++++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/app/helpers/validation_helper.rb b/app/helpers/validation_helper.rb index a73e12f55c2..7e7e72fb60d 100644 --- a/app/helpers/validation_helper.rb +++ b/app/helpers/validation_helper.rb @@ -42,9 +42,11 @@ def error_messages_for(object) end def error_messages_formatted(errors, intro = "") - return unless errors && !errors.empty? - error_messages = errors.map { |msg| content_tag(:li, msg.gsub(/^(.*)\^/, '').html_safe) }.join("\n").html_safe - content_tag(:div, intro.html_safe + content_tag(:ul, error_messages), id:"error", class:"error") + return unless errors.present? + + error_messages = errors.map { |msg| content_tag(:li, msg.gsub(/^(.*?)\^/, "").html_safe) } + .join("\n").html_safe + content_tag(:div, intro.html_safe + content_tag(:ul, error_messages), id: "error", class: "error") end # use to make sure we have consistent name throughout diff --git a/features/other_b/errors.feature b/features/other_b/errors.feature index a7dff1b681b..7bc6c78696d 100644 --- a/features/other_b/errors.feature +++ b/features/other_b/errors.feature @@ -1,6 +1,5 @@ @errors -Feature: We need to do something when someone asks for something we don't have -Some pages with non existent things raise errors +Feature: Error messages should work Scenario: Some pages with non existent things raise errors Given the user "KnownUser" exists and is activated @@ -24,3 +23,12 @@ Some pages with non existent things raise errors And visiting "/tags/UnknownTag/works" should fail with a not found error When I am logged in as "wranglerette" And visiting "/tags/NonexistentTag/edit" should fail with a not found error + + Scenario: Error messages should be able to display '^' + Given I am logged in as a random user + And I post the work "Work 1" + And I view the work "Work 1" + And I follow "Edit Tags" + When I fill in "Fandoms" with "^" + And I press "Post" + Then I should see "Sorry! We couldn't save this work because: Tag name '^' cannot include the following restricted characters: , ^ * < > { } = ` , 、 \ %" From fab9b24ca0be32223611d62ec18cb9e7601ab4b7 Mon Sep 17 00:00:00 2001 From: Bilka Date: Sun, 24 Mar 2024 20:54:09 +0100 Subject: [PATCH 41/58] AO3-4696 Link the fandom page on tag pages (#4350) * Link the fandom page on tag pages * AO3-4696 Add _link suffix to link variable and update test * AO3-4696 Move text to locale file * AO3-4696 Readd locale --- app/views/tags/show.html.erb | 3 +++ config/locales/views/en.yml | 3 +++ features/other_b/fandoms.feature | 3 ++- features/support/paths.rb | 2 -- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/app/views/tags/show.html.erb b/app/views/tags/show.html.erb index 6b2702138d6..1b8b2ccb229 100644 --- a/app/views/tags/show.html.erb +++ b/app/views/tags/show.html.erb @@ -24,6 +24,9 @@

<%= ts("This tag belongs to the %{tag_class} Category.", :tag_class => @tag.class::NAME) %> <% if @tag.canonical %> + <% if @tag.is_a?(Fandom) %> + <%= t(".list_fandom_tags_html", fandom_relationship_tags_link: link_to(t(".fandom_relationship_tags"), fandom_path(@tag.name))) %> + <% end %> <%= ts("It's a common tag. You can use it to ") %> <%= link_to ts('filter works'), {:controller => :works, :action => :index, :tag_id => @tag} %> <%= ts('and to') %> <%= link_to ts('filter bookmarks'), {:controller => :bookmarks, :action => :index, :tag_id => @tag} %>. diff --git a/config/locales/views/en.yml b/config/locales/views/en.yml index b8951dffe92..f74ce3491ab 100644 --- a/config/locales/views/en.yml +++ b/config/locales/views/en.yml @@ -733,6 +733,9 @@ en: random: These are some random tags used on the Archive. To find more tags, %{search_tags_link}. random_in_collection: These are some random tags used in the collection. search_tags: try our tag search + show: + fandom_relationship_tags: Relationship tags in this fandom + list_fandom_tags_html: A list of all the %{fandom_relationship_tags_link} is available. time: formats: date_short_html: %a %d %b %Y diff --git a/features/other_b/fandoms.feature b/features/other_b/fandoms.feature index 8fba205aae1..06dcf699f66 100644 --- a/features/other_b/fandoms.feature +++ b/features/other_b/fandoms.feature @@ -34,6 +34,7 @@ Feature: There is a list of unassigned Fandoms And I add the fandom "Steven Universe" to the character "Sapphire (Steven Universe)" And I am logged in as "author" And I post the work "Stronger than you" with fandom "Steven Universe" with character "Ruby (Steven Universe)" with second character "Sapphire (Steven Universe)" with relationship "Ruby/Sapphire (Steven Universe)" - When I go to the "Steven Universe" fandom relationship page + When I go to the "Steven Universe" tag page + And I follow "Relationship tags in this fandom" Then I should see "Ruby (Steven Universe)" And I should see "Sapphire (Steven Universe)" diff --git a/features/support/paths.rb b/features/support/paths.rb index 95df95966e3..01a4bdc2fd7 100644 --- a/features/support/paths.rb +++ b/features/support/paths.rb @@ -285,8 +285,6 @@ def path_to(page_name) edit_tag_path(Tag.find_by(name: Regexp.last_match(1))) when /^the wrangling tools page$/ tag_wranglings_path - when /^the "(.*)" fandom relationship page$/i - fandom_path($1) when /^the new external work page$/i new_external_work_path when /^the external works page$/i From 7c368fffd7ce1f5e48e50ebc6292c18f14b4918b Mon Sep 17 00:00:00 2001 From: sarken Date: Tue, 26 Mar 2024 16:28:25 -0400 Subject: [PATCH 42/58] AO3-6689 Fix JavaScript for dropdowns on status index (#4769) --- public/status/index.html | 1 + 1 file changed, 1 insertion(+) diff --git a/public/status/index.html b/public/status/index.html index 9bfea205714..0888bd84206 100644 --- a/public/status/index.html +++ b/public/status/index.html @@ -160,6 +160,7 @@

Development

} +