Skip to content

Commit 766d3ed

Browse files
authored
AO3-6875 Add additional wrangling status filtering options to tag search (#5029)
* AO3-6875 Add additional wrangling status filtering options to tag search * Freeze mutable objects assigned to constants * Prefer Rails built-in `t` helper over `ts` * Filter wrangling status via `canonical_or_synonymous` field * Filter for synonym tags by presence of `merger_id` * Add shared `exists_filter` function * Map existing `canonical` tag search param to `wrangling_status` * Match existing behavior for canonical 'T' and 'F'
1 parent f362050 commit 766d3ed

File tree

7 files changed

+107
-21
lines changed

7 files changed

+107
-21
lines changed

app/controllers/tags_controller.rb

+1
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,7 @@ def tag_search_params
413413
:fandoms,
414414
:type,
415415
:canonical,
416+
:wrangling_status,
416417
:created_at,
417418
:uses,
418419
:sort_column,

app/models/search/query.rb

+4
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,10 @@ def terms_filter(field, value, options={})
143143
{ terms: options.merge(field => value) }
144144
end
145145

146+
def exists_filter(field)
147+
{ exists: { field: field } }
148+
end
149+
146150
# A filter used to match all words in a particular field, most frequently
147151
# used for matching non-existent tags. The match query doesn't allow
148152
# negation/or/and/wildcards, so it should only be used on fields where the

app/models/search/tag_query.rb

+15-4
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def document_type
1515
def filters
1616
[
1717
type_filter,
18-
canonical_filter,
18+
wrangling_status_filter,
1919
unwrangleable_filter,
2020
posted_works_filter,
2121
media_filter,
@@ -77,8 +77,19 @@ def type_filter
7777
{ term: { tag_type: options[:type] } } if options[:type]
7878
end
7979

80-
def canonical_filter
81-
term_filter(:canonical, bool_value(options[:canonical])) if options[:canonical].present?
80+
def wrangling_status_filter
81+
case options[:wrangling_status]
82+
when "canonical"
83+
term_filter(:canonical, true)
84+
when "noncanonical"
85+
term_filter(:canonical, false)
86+
when "synonymous"
87+
[exists_filter("merger_id"), term_filter(:canonical, false)]
88+
when "canonical_synonymous"
89+
{ bool: { should: [exists_filter("merger_id"), term_filter(:canonical, true)] } }
90+
when "noncanonical_nonsynonymous"
91+
[{ bool: { must_not: exists_filter("merger_id") } }, term_filter(:canonical, false)]
92+
end
8293
end
8394

8495
def unwrangleable_filter
@@ -130,7 +141,7 @@ def unwrangled_filter
130141
# the fandom exists, because this particular filter is included in the
131142
# exclusion_filters section.
132143
def wrangled_filter
133-
{ exists: { field: "fandom_ids" } } unless options[:wrangled].nil?
144+
exists_filter("fandom_ids") unless options[:wrangled].nil?
134145
end
135146

136147
################

app/models/search/tag_search_form.rb

+14-1
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@ class TagSearchForm
88
:query,
99
:name,
1010
:canonical,
11+
:wrangling_status,
1112
:fandoms,
1213
:type,
1314
:created_at,
1415
:uses,
1516
:sort_column,
1617
:sort_direction
17-
]
18+
].freeze
1819

1920
attr_accessor :options
2021

@@ -25,6 +26,7 @@ class TagSearchForm
2526
def initialize(options={})
2627
@options = options
2728
set_fandoms
29+
set_wrangling_status
2830
@searcher = TagQuery.new(@options.delete_if { |_, v| v.blank? })
2931
end
3032

@@ -43,6 +45,17 @@ def set_fandoms
4345
@options[:fandom_ids] = Tag.where(name: names).pluck(:id)
4446
end
4547

48+
def bool_value(str)
49+
%w[true 1 T].include?(str.to_s)
50+
end
51+
52+
def set_wrangling_status
53+
return if @options[:canonical].blank?
54+
55+
# Match old behavior for canonical param
56+
@options[:wrangling_status] = bool_value(@options[:canonical]) ? "canonical" : "noncanonical"
57+
end
58+
4659
def sort_columns
4760
options[:sort_column] || "name"
4861
end

app/views/tags/_search_form.html.erb

+27-14
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,22 @@
22
<fieldset>
33
<dl>
44
<dt>
5-
<%= f.label :name, ts("Tag name") %>
5+
<%= f.label :name, t(".tag_name") %>
66
<%= link_to_help "tag-search-text-help" %>
77
</dt>
88
<dd>
99
<%= f.text_field :name %>
1010
</dd>
1111
<dt>
12-
<%= f.label :fandoms, ts("Fandoms") %>
12+
<%= f.label :fandoms, t(".fandoms") %>
1313
</dt>
1414
<dd>
1515
<%= f.text_field :fandoms, autocomplete_options("fandom", "aria-describedby" => "fandom-field-description") %>
1616
<p class="footnote" id="fandom-field-description">
17-
<%= ts("Find tags wrangled to specific canonical fandoms.") %>
17+
<%= t(".fandoms_footnote") %>
1818
</p>
1919
</dd>
20-
<dt><%= ts("Type") %></dt>
20+
<dt><%= t(".type") %></dt>
2121
<dd>
2222
<fieldset>
2323
<ul>
@@ -35,38 +35,51 @@
3535
</ul>
3636
</fieldset>
3737
</dd>
38-
<dt><%= ts("Wrangling status") %></dt>
38+
<dt><%= t(".wrangling_status") %></dt>
3939
<dd>
4040
<fieldset>
4141
<ul>
4242
<li>
43-
<%= f.radio_button :canonical, "T" %>
44-
<%= f.label :canonical, ts("Canonical"), value: "T" %>
43+
<%= f.radio_button :wrangling_status, "canonical" %>
44+
<%= f.label :wrangling_status, t(".status_option.canonical"), value: "canonical" %>
4545
</li>
4646
<li>
47-
<%= f.radio_button :canonical, "F" %>
48-
<%= f.label :canonical, ts("Non-canonical"), value: "F" %>
47+
<%= f.radio_button :wrangling_status, "noncanonical" %>
48+
<%= f.label :wrangling_status, t(".status_option.noncanonical"), value: "noncanonical" %>
4949
</li>
5050
<li>
51-
<%= f.radio_button :canonical, "" %>
52-
<%= f.label :canonical, ts("Any status"), value: "" %>
51+
<%= f.radio_button :wrangling_status, "synonymous" %>
52+
<%= f.label :wrangling_status, t(".status_option.synonymous"), value: "synonymous" %>
53+
</li>
54+
<li>
55+
<%= f.radio_button :wrangling_status, "canonical_synonymous" %>
56+
<%= f.label :wrangling_status, t(".status_option.canonical_or_synonymous"), value: "canonical_synonymous" %>
57+
</li>
58+
<li>
59+
<%= f.radio_button :wrangling_status, "noncanonical_nonsynonymous" %>
60+
<%= f.label :wrangling_status, t(".status_option.noncanonical_and_nonsynonymous"), value: "noncanonical_nonsynonymous" %>
61+
</li>
62+
<li>
63+
<%= f.radio_button :wrangling_status, "" %>
64+
<%= f.label :wrangling_status, t(".status_option.any_status"), value: "" %>
5365
</li>
5466
</ul>
5567
</fieldset>
68+
</dd>
5669
<dt>
57-
<%= f.label :sort_column, ts("Sort by") %>
70+
<%= f.label :sort_column, t(".sort_by") %>
5871
</dt>
5972
<dd>
6073
<%= f.select :sort_column, options_for_select(@search.sort_options, @search.sort_column) %>
6174
</dd>
6275
<dt>
63-
<%= f.label :sort_direction, ts("Sort direction") %>
76+
<%= f.label :sort_direction, t(".sort_direction") %>
6477
</dt>
6578
<dd>
6679
<%= f.select :sort_direction,
6780
options_for_select([["Ascending", "asc"], ["Descending", "desc"]], @search.sort_direction) %>
6881
</dd>
6982
</dl>
70-
<p class="submit actions"><%= f.submit ts("Search Tags") %></p>
83+
<p class="submit actions"><%= f.submit t(".search_tags") %></p>
7184
</fieldset>
7285
<% end %>

config/locales/views/en.yml

+16
Original file line numberDiff line numberDiff line change
@@ -1735,6 +1735,22 @@ en:
17351735
random: These are some random tags used on the Archive. To find more tags, %{search_tags_link}.
17361736
random_in_collection: These are some random tags used in the collection.
17371737
search_tags: try our tag search
1738+
search_form:
1739+
fandoms: Fandoms
1740+
fandoms_footnote: Find tags wrangled to specific canonical fandoms.
1741+
search_tags: Search Tags
1742+
sort_by: Sort by
1743+
sort_direction: Sort direction
1744+
status_option:
1745+
any_status: Any status
1746+
canonical: Canonical
1747+
canonical_or_synonymous: Canonical or synonymous
1748+
noncanonical: Non-canonical
1749+
noncanonical_and_nonsynonymous: Non-canonical and non-synonymous
1750+
synonymous: Synonymous
1751+
tag_name: Tag name
1752+
type: Type
1753+
wrangling_status: Wrangling status
17381754
show:
17391755
canonical_html: It's a %{canonical_tag_link}. You can use it to %{filter_works_link} and to %{filter_bookmarks_link}.
17401756
canonical_tag: canonical tag

features/tags_and_wrangling/tag_search.feature

+30-2
Original file line numberDiff line numberDiff line change
@@ -150,28 +150,56 @@ Feature: Search Tags
150150
Scenario: Search by wrangling status
151151
Given a fandom exists with name: "Not Canon Fandom", canonical: false
152152
And a character exists with name: "Canon Character", canonical: true
153+
And a synonym "Same Canon Character" of the tag "Canon Character"
153154
And all indexing jobs have been run
154155
When I am on the search tags page
155156
And I fill in "Tag name" with "Canon"
156157
And I choose "Canonical"
157158
And I press "Search Tags"
158159
Then I should see "1 Found"
159-
And I should see the tag search result "Character: Canon Character (0)"
160160
And I should not see the tag search result "Fandom: Not Canon Fandom (0)"
161+
And I should see the tag search result "Character: Canon Character (0)"
162+
And I should not see the tag search result "Character: Same Canon Character (0)"
161163
When I am on the search tags page
162164
And I fill in "Tag name" with "Canon"
163165
And I choose "Non-canonical"
164166
And I press "Search Tags"
167+
Then I should see "2 Found"
168+
And I should see the tag search result "Fandom: Not Canon Fandom (0)"
169+
And I should not see the tag search result "Character: Canon Character (0)"
170+
And I should see the tag search result "Character: Same Canon Character (0)"
171+
When I am on the search tags page
172+
And I fill in "Tag name" with "Canon"
173+
And I choose "Synonymous"
174+
And I press "Search Tags"
175+
Then I should see "1 Found"
176+
And I should not see the tag search result "Fandom: Not Canon Fandom (0)"
177+
And I should not see the tag search result "Character: Canon Character (0)"
178+
And I should see the tag search result "Character: Same Canon Character (0)"
179+
When I am on the search tags page
180+
And I fill in "Tag name" with "Canon"
181+
And I choose "Canonical or synonymous"
182+
And I press "Search Tags"
183+
Then I should see "2 Found"
184+
And I should not see the tag search result "Fandom: Not Canon Fandom (0)"
185+
And I should see the tag search result "Character: Canon Character (0)"
186+
And I should see the tag search result "Character: Same Canon Character (0)"
187+
When I am on the search tags page
188+
And I fill in "Tag name" with "Canon"
189+
And I choose "Non-canonical and non-synonymous"
190+
And I press "Search Tags"
165191
Then I should see "1 Found"
166192
And I should see the tag search result "Fandom: Not Canon Fandom (0)"
167193
And I should not see the tag search result "Character: Canon Character (0)"
194+
And I should not see the tag search result "Character: Same Canon Character (0)"
168195
When I am on the search tags page
169196
And I fill in "Tag name" with "Canon"
170197
And I choose "Any status"
171198
And I press "Search Tags"
172-
Then I should see "2 Found"
199+
Then I should see "3 Found"
173200
And I should see the tag search result "Fandom: Not Canon Fandom (0)"
174201
And I should see the tag search result "Character: Canon Character (0)"
202+
And I should see the tag search result "Character: Same Canon Character (0)"
175203

176204
Scenario: Search and sort by Date Created in descending and ascending order
177205
Given a freeform exists with name: "created first", created_at: "2008-01-01 20:00:00 Z"

0 commit comments

Comments
 (0)