Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AO3-6875 Add additional wrangling status filtering options to tag search #5029

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion app/controllers/tags_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ def tag_search_params
:name,
:fandoms,
:type,
:canonical,
:wrangling_status,
:created_at,
:uses,
:sort_column,
Expand Down
3 changes: 2 additions & 1 deletion app/models/search/tag_indexer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ def document(object)
has_posted_works: object.has_posted_works?,
tag_type: object.type,
uses: object.taggings_count_cache,
unwrangled: object.unwrangled?
unwrangled: object.unwrangled?,
filterable: object.synonymous? || object.canonical
).merge(parent_data(object))
end

Expand Down
5 changes: 5 additions & 0 deletions app/models/search/tag_query.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ def filters
[
type_filter,
canonical_filter,
filterable_filter,
unwrangleable_filter,
posted_works_filter,
media_filter,
Expand Down Expand Up @@ -81,6 +82,10 @@ def canonical_filter
term_filter(:canonical, bool_value(options[:canonical])) if options[:canonical].present?
end

def filterable_filter
term_filter(:filterable, bool_value(options[:filterable])) if options[:filterable].present?
end

def unwrangleable_filter
term_filter(:unwrangleable, bool_value(options[:unwrangleable])) unless options[:unwrangleable].nil?
end
Expand Down
22 changes: 20 additions & 2 deletions app/models/search/tag_search_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ class TagSearchForm
ATTRIBUTES = [
:query,
:name,
:canonical,
:wrangling_status,
:fandoms,
:type,
:created_at,
:uses,
:sort_column,
:sort_direction
]
].freeze

attr_accessor :options

Expand All @@ -25,6 +25,8 @@ class TagSearchForm
def initialize(options={})
@options = options
set_fandoms
set_canonical
set_filterable
@searcher = TagQuery.new(@options.delete_if { |_, v| v.blank? })
end

Expand All @@ -36,6 +38,22 @@ def search_results
@searcher.search_results
end

def set_canonical
if @options[:wrangling_status] == "canonical"
@options[:canonical] = "T"
elsif %w[noncanonical synonymous].include?(@options[:wrangling_status])
@options[:canonical] = "F"
end
end

def set_filterable
if %w[synonymous canonical_synonymous].include?(@options[:wrangling_status])
@options[:filterable] = "T"
elsif @options[:wrangling_status] == "noncanonical_nonsynonymous"
@options[:filterable] = "F"
end
end

def set_fandoms
return if @options[:fandoms].blank?

Expand Down
5 changes: 5 additions & 0 deletions app/models/tag.rb
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,11 @@ def has_posted_works?
self.works.posted.any?
end

# Returns true if a tag is a synonym of a canonical tag
def synonymous?
!self.canonical? && self.merger_id.present?
end

# sort tags by name
def <=>(another_tag)
name.downcase <=> another_tag.name.downcase
Expand Down
41 changes: 27 additions & 14 deletions app/views/tags/_search_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@
<fieldset>
<dl>
<dt>
<%= f.label :name, ts("Tag name") %>
<%= f.label :name, t(".tag_name") %>
<%= link_to_help "tag-search-text-help" %>
</dt>
<dd>
<%= f.text_field :name %>
</dd>
<dt>
<%= f.label :fandoms, ts("Fandoms") %>
<%= f.label :fandoms, t(".fandoms") %>
</dt>
<dd>
<%= f.text_field :fandoms, autocomplete_options("fandom", "aria-describedby" => "fandom-field-description") %>
<p class="footnote" id="fandom-field-description">
<%= ts("Find tags wrangled to specific canonical fandoms.") %>
<%= t(".fandoms_footnote") %>
</p>
</dd>
<dt><%= ts("Type") %></dt>
<dt><%= t(".type") %></dt>
<dd>
<fieldset>
<ul>
Expand All @@ -35,38 +35,51 @@
</ul>
</fieldset>
</dd>
<dt><%= ts("Wrangling status") %></dt>
<dt><%= t(".wrangling_status") %></dt>
<dd>
<fieldset>
<ul>
<li>
<%= f.radio_button :canonical, "T" %>
<%= f.label :canonical, ts("Canonical"), value: "T" %>
<%= f.radio_button :wrangling_status, "canonical" %>
<%= f.label :wrangling_status, t(".status_option.canonical"), value: "canonical" %>
</li>
<li>
<%= f.radio_button :canonical, "F" %>
<%= f.label :canonical, ts("Non-canonical"), value: "F" %>
<%= f.radio_button :wrangling_status, "noncanonical" %>
<%= f.label :wrangling_status, t(".status_option.noncanonical"), value: "noncanonical" %>
</li>
<li>
<%= f.radio_button :canonical, "" %>
<%= f.label :canonical, ts("Any status"), value: "" %>
<%= f.radio_button :wrangling_status, "synonymous" %>
<%= f.label :wrangling_status, t(".status_option.synonymous"), value: "synonymous" %>
</li>
<li>
<%= f.radio_button :wrangling_status, "canonical_synonymous" %>
<%= f.label :wrangling_status, t(".status_option.canonical_or_synonymous"), value: "canonical_synonymous" %>
</li>
<li>
<%= f.radio_button :wrangling_status, "noncanonical_nonsynonymous" %>
<%= f.label :wrangling_status, t(".status_option.noncanonical_and_nonsynonymous"), value: "noncanonical_nonsynonymous" %>
</li>
<li>
<%= f.radio_button :wrangling_status, "" %>
<%= f.label :wrangling_status, t(".status_option.any_status"), value: "" %>
</li>
</ul>
</fieldset>
</dd>
<dt>
<%= f.label :sort_column, ts("Sort by") %>
<%= f.label :sort_column, t(".sort_by") %>
</dt>
<dd>
<%= f.select :sort_column, options_for_select(@search.sort_options, @search.sort_column) %>
</dd>
<dt>
<%= f.label :sort_direction, ts("Sort direction") %>
<%= f.label :sort_direction, t(".sort_direction") %>
</dt>
<dd>
<%= f.select :sort_direction,
options_for_select([["Ascending", "asc"], ["Descending", "desc"]], @search.sort_direction) %>
</dd>
</dl>
<p class="submit actions"><%= f.submit ts("Search Tags") %></p>
<p class="submit actions"><%= f.submit t(".search_tags") %></p>
</fieldset>
<% end %>
16 changes: 16 additions & 0 deletions config/locales/views/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1661,6 +1661,22 @@ 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
search_form:
fandoms: Fandoms
fandoms_footnote: Find tags wrangled to specific canonical fandoms.
search_tags: Search Tags
sort_by: Sort by
sort_direction: Sort direction
status_option:
any_status: Any status
canonical: Canonical
canonical_or_synonymous: Canonical or synonymous
noncanonical: Non-canonical
noncanonical_and_nonsynonymous: Non-canonical and non-synonymous
synonymous: Synonymous
tag_name: Tag name
type: Type
wrangling_status: Wrangling status
show:
canonical_html: It's a %{canonical_tag_link}. You can use it to %{filter_works_link} and to %{filter_bookmarks_link}.
canonical_tag: canonical tag
Expand Down
32 changes: 30 additions & 2 deletions features/tags_and_wrangling/tag_search.feature
Original file line number Diff line number Diff line change
Expand Up @@ -150,28 +150,56 @@ Feature: Search Tags
Scenario: Search by wrangling status
Given a fandom exists with name: "Not Canon Fandom", canonical: false
And a character exists with name: "Canon Character", canonical: true
And a synonym "Same Canon Character" of the tag "Canon Character"
And all indexing jobs have been run
When I am on the search tags page
And I fill in "Tag name" with "Canon"
And I choose "Canonical"
And I press "Search Tags"
Then I should see "1 Found"
And I should see the tag search result "Character: Canon Character (0)"
And I should not see the tag search result "Fandom: Not Canon Fandom (0)"
And I should see the tag search result "Character: Canon Character (0)"
And I should not see the tag search result "Character: Same Canon Character (0)"
When I am on the search tags page
And I fill in "Tag name" with "Canon"
And I choose "Non-canonical"
And I press "Search Tags"
Then I should see "2 Found"
And I should see the tag search result "Fandom: Not Canon Fandom (0)"
And I should not see the tag search result "Character: Canon Character (0)"
And I should see the tag search result "Character: Same Canon Character (0)"
When I am on the search tags page
And I fill in "Tag name" with "Canon"
And I choose "Synonymous"
And I press "Search Tags"
Then I should see "1 Found"
And I should not see the tag search result "Fandom: Not Canon Fandom (0)"
And I should not see the tag search result "Character: Canon Character (0)"
And I should see the tag search result "Character: Same Canon Character (0)"
When I am on the search tags page
And I fill in "Tag name" with "Canon"
And I choose "Canonical or synonymous"
And I press "Search Tags"
Then I should see "2 Found"
And I should not see the tag search result "Fandom: Not Canon Fandom (0)"
And I should see the tag search result "Character: Canon Character (0)"
And I should see the tag search result "Character: Same Canon Character (0)"
When I am on the search tags page
And I fill in "Tag name" with "Canon"
And I choose "Non-canonical and non-synonymous"
And I press "Search Tags"
Then I should see "1 Found"
And I should see the tag search result "Fandom: Not Canon Fandom (0)"
And I should not see the tag search result "Character: Canon Character (0)"
And I should not see the tag search result "Character: Same Canon Character (0)"
When I am on the search tags page
And I fill in "Tag name" with "Canon"
And I choose "Any status"
And I press "Search Tags"
Then I should see "2 Found"
Then I should see "3 Found"
And I should see the tag search result "Fandom: Not Canon Fandom (0)"
And I should see the tag search result "Character: Canon Character (0)"
And I should see the tag search result "Character: Same Canon Character (0)"

Scenario: Search and sort by Date Created in descending and ascending order
Given a freeform exists with name: "created first", created_at: "2008-01-01 20:00:00 Z"
Expand Down
18 changes: 18 additions & 0 deletions spec/models/tag_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,24 @@ def expect_tag_update_flag_in_redis_to_be(flag)
end
end

describe "synonymous?" do
it "is false for a canonical tag" do
tag = create(:freeform, canonical: true)
expect(tag.synonymous?).to be_falsey
end

it "is false for a non-canonical, non-synonymous tag" do
tag = create(:freeform, canonical: false)
expect(tag.synonymous?).to be_falsey
end

it "is true for a synonymous tag" do
canonical_tag = create(:freeform, canonical: true)
synonym_tag = create(:freeform, canonical: false, merger: canonical_tag)
expect(synonym_tag.synonymous?).to be_truthy
end
end

describe "has_posted_works?" do
before do
create(:work, fandom_string: "love live,jjba")
Expand Down
Loading