Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
2afa5c1
AO3-6022 don't show hidden related works on related work pages
slavalamp Apr 22, 2026
981235f
AO3-6022 a hacky way to make it also work in tests
slavalamp Apr 22, 2026
e579e38
AO3-6022 refactored + sidebar counts should also be correct in tests
slavalamp Apr 23, 2026
e311a70
Merge branch 'master' into AO3-6022_hide_hidden_related_works
slavalamp May 6, 2026
c16f8cb
Merge branch 'master' into AO3-6022_hide_hidden_related_works
slavalamp May 12, 2026
fb05ddf
AO3-6022 hide hidden works from everyone
slavalamp May 12, 2026
28cddbb
AO3-6022 add comment + slightly rearrange the scopes
slavalamp May 13, 2026
047be41
AO3-5550 hide relations that include restricted works from guests
slavalamp May 13, 2026
60aa302
AO3-6022 rubocop
slavalamp May 15, 2026
b26e0be
AO3-6022 test improvements
slavalamp May 16, 2026
2020187
AO3-6022 ...undo the changes that i'm already doing in the other pr a…
slavalamp May 16, 2026
6786abc
Merge branch 'master' into AO3-6022_hide_hidden_related_works
slavalamp Jul 25, 2026
1c4b869
AO3-5550 AO3-6022 nicer scopes + another test
slavalamp Jul 29, 2026
9c9fbf4
better test name
slavalamp Jul 29, 2026
7f707dc
replace sql with activerecord queries & don't add a new helper method…
slavalamp Aug 2, 2026
41bccb3
rubocop
slavalamp Aug 2, 2026
dce79aa
added test for AO3-5743
slavalamp Aug 2, 2026
0f3370a
better test coverage + removed a redundant one
slavalamp Aug 9, 2026
bd82f31
AO3-5743 simplify the test
slavalamp Aug 9, 2026
df57c52
AO3-5743 simplify the test even more
slavalamp Aug 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 6 additions & 11 deletions app/controllers/related_works_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,14 @@ class RelatedWorksController < ApplicationController

def index
@page_subtitle = t(".page_title", login: @user.login)
@translations_of_user = @user.related_works.posted.where(translation: true)
@remixes_of_user = @user.related_works.posted.where(translation: false)
@translations_by_user = @user.parent_work_relationships.posted.where(translation: true)
@remixes_by_user = @user.parent_work_relationships.posted.where(translation: false)

return if @user == current_user
related_works = @user.related_works_for_user_page
parent_work_relationships = @user.parent_work_relationships_for_user_page

# Extra constraints on what we display if someone else is viewing @user's
# related works page:
@translations_of_user = @translations_of_user.merge(Work.revealed.non_anon).where(reciprocal: true)
@remixes_of_user = @remixes_of_user.merge(Work.revealed.non_anon).where(reciprocal: true)
@translations_by_user = @translations_by_user.merge(Work.revealed.non_anon).where(reciprocal: true)
@remixes_by_user = @remixes_by_user.merge(Work.revealed.non_anon).where(reciprocal: true)
@translations_of_user = related_works.translations
@remixes_of_user = related_works.remixes
@translations_by_user = parent_work_relationships.translations
@remixes_by_user = parent_work_relationships.remixes
end

# GET /related_works/1
Expand Down
43 changes: 39 additions & 4 deletions app/models/related_work.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class RelatedWork < ActiveRecord::Base
class RelatedWork < ApplicationRecord
belongs_to :work
belongs_to :parent, polymorphic: true, autosave: true

Expand All @@ -7,11 +7,46 @@ class RelatedWork < ActiveRecord::Base
attribute :author, :string
attribute :language_id, :integer

scope :posted, -> {
joins("INNER JOIN `works` `child_works` ON `child_works`.`id` = `related_works`.`work_id`").
where("child_works.posted = 1")
scope :translations, -> { where(translation: true) }
scope :remixes, -> { where(translation: false) }
scope :reciprocal, -> { where(reciprocal: true) }

scope :posted_children, -> { joins(:work).where(work: { posted: true }) }
scope :unhidden_children, -> { joins(:work).where(work: { hidden_by_admin: false }) }
scope :unrestricted_children, -> { joins(:work).where(work: { restricted: false }) }

# visible child works in User.related_works
scope :children_for_user_page, lambda {
if User.current_user.present?
posted_children.unhidden_children
else
posted_children.unhidden_children.unrestricted_children
end
}

# visible parent works in User.parent_work_relationships
scope :parents_for_user_page, lambda {
visible_work_ids = if User.current_user.present?
Work.visible_to_registered_user.select(:id)
else
Work.visible_to_all.select(:id)
end

where(parent_type: "Work").where(parent_id: visible_work_ids)
.or(where(parent_type: "ExternalWork").where(parent_id: ExternalWork.visible.select(:id)))
}

# visible user's own works in User.related_works and User.parent_work_relationships
def self.user_works_for_user_page(user)
if User.current_user == user
merge(Work.unhidden)
elsif User.current_user.present?
reciprocal.merge(Work.posted.unhidden.revealed.non_anon)
else
reciprocal.merge(Work.posted.unhidden.revealed.non_anon.unrestricted)
end
end

before_validation :set_parent, if: :new_record?
def set_parent
return if parent
Expand Down
13 changes: 13 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,19 @@ def historic_values(field)
end
end

def related_works_for_user_page
related_works.children_for_user_page.user_works_for_user_page(self)
end

def parent_work_relationships_for_user_page
parent_work_relationships.parents_for_user_page.user_works_for_user_page(self)
end

def visible_related_works_count
related_works_for_user_page.count +
parent_work_relationships_for_user_page.count
end

private

# Override the default Justifiable enabled check, because we only need to justify
Expand Down
2 changes: 1 addition & 1 deletion app/views/users/_sidebar.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
<li><%= span_if_current t(".switch.sign_ups", signup_number: @user.challenge_signups.count), user_signups_path(@user) %></li>
<li><%= span_if_current t(".switch.assignments", assignment_number: @user.assignments.unposted.undefaulted.count), user_assignments_path(@user) %></li>
<li><%= span_if_current t(".switch.claims", claim_number: @user.request_claims.unposted.count), user_claims_path(@user) %></li>
<li><%= span_if_current t(".switch.related_works", related_works_number: (@user.related_works.posted.count + @user.parent_work_relationships.count)), user_related_works_path(@user) %></li>
<li><%= span_if_current t(".switch.related_works", related_works_number: @user.visible_related_works_count), user_related_works_path(@user) %></li>
<% end %>
<li><%= gifts_link(@user) %></li>
</ul>
Expand Down
6 changes: 6 additions & 0 deletions features/step_definitions/admin_steps.rb
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,12 @@
step %{I follow "Make Work Visible"}
end

When "I hide the external work {string}" do |title|
external_work = ExternalWork.find_by(title: title)
visit external_work_path(external_work)
step %{I follow "Hide External Work"}
end

When "the search criteria contains the ID for {string}" do |login|
user_id = User.find_by(login: login).id
fill_in("user_id", with: user_id)
Expand Down
14 changes: 14 additions & 0 deletions features/step_definitions/work_related_steps.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,20 @@
step %{I approve a related work}
end

# given for external works

Given "a work inspired by an external work has been posted" do
step %{basic tags}
step %{mock websites with no content}
step %{I am logged in as "remixer"}
step %{I set up the draft "Followup"}
step %{I check "parent-options-show"}
step %{I fill in "URL" with "http://example.org/200"}
step %{I fill in "Title" with "Worldbuilding"}
step %{I fill in "Author" with "external_inspiration"}
step %{I press "Post"}
end

### WHEN

When "I post an inspiring parent work as testuser" do
Expand Down
113 changes: 112 additions & 1 deletion features/works/work_related.feature
Comment thread
slavalamp marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ Scenario: Translate your own work
And I approve a related work
Then approving the related work should succeed

Scenario: Draft works should not show up on related works
Scenario: Related draft works should not show up on the related works page

Given I have related works setup
And I am logged in as "translator"
Expand All @@ -250,6 +250,26 @@ Scenario: Draft works should not show up on related works
When I view my related works
Then I should not see "Worldbuilding Translated"

Scenario: A user's parent draft works should only be visible to them on their related works page

Given I have related works setup
And I am logged in as "inspiration"
And the draft "Worldbuilding Draft"
When I set up the draft "Followup"
And I list the work "Worldbuilding Draft" as inspiration
And I press "Post"
And I view my related works
And I follow "Approve"
And I press "Yes, link me!"
When I am logged in as "translator"
And I go to inspiration's related works page
Then I should not see "Related Works (1)"
Then I should not see "Followup"
When I log out
And I go to inspiration's related works page
Then I should not see "Related Works (1)"
Then I should not see "Followup"

Scenario: Listing external works as inspirations

Given basic tags
Expand Down Expand Up @@ -349,6 +369,32 @@ Scenario: Restricted works listed as Inspiration show up [Restricted] for guests
And I view the work "Followup"
Then I should see "Inspired by [Restricted Work] by inspiration"

Scenario: Restricted inspired and inspiring works should not be listed on related work pages for guests
Given I have related works setup
And a related work has been posted and approved
# Restricted inspired work
When I am logged in as "remixer"
And I lock the work "Followup"
When I log out
And I go to inspiration's related works page
Then I should not see "Followup"
And I should not see "Worldbuilding"
When I go to remixer's related works page
Then I should not see "Followup"
And I should not see "Worldbuilding"
# Restricted inspiration
When I am logged in as "remixer"
And I unlock the work "Followup"
When I am logged in as "inspiration"
And I lock the work "Worldbuilding"
When I log out
And I go to inspiration's related works page
Then I should not see "Followup"
And I should not see "Worldbuilding"
When I go to remixer's related works page
Then I should not see "Followup"
And I should not see "Worldbuilding"

Scenario: Anonymous works listed as inspiration should have links to the authors,
but only for the authors themselves and admins
Given I have related works setup
Expand All @@ -373,6 +419,61 @@ Scenario: Anonymous works listed as inspiration should have links to the authors
Then I should see "Works inspired by this one: Followup by Anonymous"
And I should not see "remixer" within ".afterword .children"

Scenario: Hidden inspired and inspiring works should not be listed on related work pages
Given I have related works setup
And a related work has been posted and approved
# Hidden inspired work
When I am logged in as a "policy_and_abuse" admin
And I hide the work "Followup"
When I am logged in as "remixer"
And I view my related works
Then I should see "Related Works (0)"
And I should not see "Followup"
When I go to inspiration's related works page
Then I should not see "Followup"
When I am logged in as "inspiration"
And I view my related works
Then I should see "Related Works (0)"
And I should not see "Followup"
When I log out
And I go to remixer's related works page
Then I should not see "Worldbuilding"
When I go to inspiration's related works page
Then I should not see "Worldbuilding"
# Hidden inspiration
When I am logged in as a "policy_and_abuse" admin
And I unhide the work "Followup"
And I hide the work "Worldbuilding"
When I am logged in as "inspiration"
And I view my related works
Then I should see "Related Works (0)"
And I should not see "Worldbuilding"
When I go to remixer's related works page
Then I should not see "Worldbuilding"
When I am logged in as "remixer"
And I view my related works
Then I should see "Related Works (0)"
And I should not see "Worldbuilding"
When I log out
And I go to remixer's related works page
Then I should not see "Worldbuilding"
When I go to inspiration's related works page
Then I should not see "Worldbuilding"

Scenario: Hidden external inspirations should not be listed on related work pages
Given a work inspired by an external work has been posted
When I am logged in as a "policy_and_abuse" admin
And I hide the external work "Worldbuilding"
When I go to remixer's related works page
Then I should not see "Worldbuilding"
When I am logged in as "remixer"
And I view my related works
Then I should see "Related Works (0)"
And I should not see "Worldbuilding"
When I log out
And I go to remixer's related works page
Then I should not see "Worldbuilding"

Scenario: When a user is notified that a co-authored work has been inspired by a work they posted,
the e-mail should link to each author's URL instead of showing escaped HTML
Given I have related works setup
Expand Down Expand Up @@ -840,3 +941,13 @@ Scenario: Deleted inspiration relationships can be deleted from the Edit Work pa
Then I should see "Deleted work"
When I follow "Remove" within "#parent-options"
Then I should not see "Deleted work"

Scenario: Deleted parent works don't create empty sections on the related works page and aren't counted in the sidebar
Given I have related works setup
And a related work has been posted and approved
When I am logged in as "inspiration"
And I delete the work "Worldbuilding"
When I am logged in as "remixer"
And I view my related works
Then I should see "Related Works (0)"
And I should not see "Works that inspired"
Loading