diff --git a/app/logical/concerns/searchable.rb b/app/logical/concerns/searchable.rb
index 37813e40f..1740cce95 100644
--- a/app/logical/concerns/searchable.rb
+++ b/app/logical/concerns/searchable.rb
@@ -1,6 +1,15 @@
module Searchable
extend ActiveSupport::Concern
+ def parameter_hash?(params)
+ params.present? && params.respond_to?(:each)
+ end
+
+ def parameter_depth(params)
+ return 0 if params.values.empty?
+ 1 + params.values.map { |v| parameter_hash?(v) ? parameter_depth(v) : 1 }.max
+ end
+
def negate(kind = :nand)
unscoped.where(all.where_clause.invert(kind).ast)
end
@@ -139,8 +148,13 @@ module Searchable
end
def search_attributes(params, *attributes)
+ raise ArgumentError, "max parameter depth of 10 exceeded" if parameter_depth(params) > 10
+
+ # This allows the hash keys to be either strings or symbols
+ indifferent_params = params.try(:with_indifferent_access) || params.try(:to_unsafe_h)
+ raise ArgumentError, "unable to process params" if indifferent_params.nil?
attributes.reduce(all) do |relation, attribute|
- relation.search_attribute(attribute, params)
+ relation.search_attribute(attribute, indifferent_params)
end
end
@@ -159,7 +173,9 @@ module Searchable
when "User"
search_user_attribute(name, params)
when "Post"
- search_post_id_attribute(params)
+ search_post_attribute(name, params)
+ when "Model"
+ search_polymorphic_attribute(name, params)
when :string, :text
search_text_attribute(name, params)
when :boolean
@@ -173,7 +189,8 @@ module Searchable
when :array
search_array_attribute(name, subtype, params)
else
- raise NotImplementedError, "unhandled attribute type: #{name}"
+ raise NotImplementedError, "unhandled attribute type: #{name}" if type.blank?
+ search_includes(name, params, type)
end
end
@@ -214,26 +231,56 @@ module Searchable
end
def search_user_attribute(attr, params)
- if params["#{attr}_id"]
- search_attribute("#{attr}_id", params)
- elsif params["#{attr}_name"]
+ if params["#{attr}_name"].present?
where(attr => User.search(name_matches: params["#{attr}_name"]).reorder(nil))
- elsif params[attr]
- where(attr => User.search(params[attr]).reorder(nil))
+ else
+ search_includes(attr, params, "User")
+ end
+ end
+
+ def search_post_attribute(attr, params)
+ if params["#{attr}_tags_match"]
+ where(attr => Post.user_tag_match(params["#{attr}_tags_match"]).reorder(nil))
+ else
+ search_includes(attr, params, "Post")
+ end
+ end
+
+ def search_includes(attr, params, type)
+ model = Kernel.const_get(type)
+ if params["#{attr}_id"].present?
+ search_attribute("#{attr}_id", params)
+ elsif params["has_#{attr}"].to_s.truthy? || params["has_#{attr}"].to_s.falsy?
+ search_has_include(attr, params["has_#{attr}"].to_s.truthy?, model)
+ elsif parameter_hash?(params[attr])
+ where(attr => model.search(params[attr]).reorder(nil))
else
all
end
end
- def search_post_id_attribute(params)
- relation = all
+ def search_polymorphic_attribute(attr, params)
+ model_keys = ((model_types || []) & params.keys)
+ # The user can only logically specify one model at a time, so more than that should return no results
+ return none if model_keys.length > 1
- if params[:post_id].present?
- relation = relation.search_attribute(:post_id, params)
+ relation = all
+ model_specified = false
+ model_key = model_keys[0]
+ if model_keys.length == 1 && parameter_hash?(params[model_key])
+ # Returning none here for the same reason specified above
+ return none if params["#{attr}_type"].present? && params["#{attr}_type"] != model_key
+ model_specified = true
+ model = Kernel.const_get(model_key)
+ relation = relation.where(attr => model.search(params[model_key]))
end
- if params[:post_tags_match].present?
- relation = relation.where(post_id: Post.user_tag_match(params[:post_tags_match]).reorder(nil))
+ if params["#{attr}_id"].present?
+ relation = relation.search_attribute("#{attr}_id", params)
+ end
+
+ if params["#{attr}_type"].present? && !model_specified
+ relation = relation.search_attribute("#{attr}_type", params)
end
relation
@@ -292,6 +339,28 @@ module Searchable
relation
end
+ def search_has_include(name, exists, model)
+ if column_names.include?("#{name}_id")
+ return exists ? where.not("#{name}_id" => nil) : where("#{name}_id" => nil)
+ end
+
+ association = reflect_on_association(name)
+ primary_key = association.active_record_primary_key
+ foreign_key = association.foreign_key
+ # The belongs_to macro has its primary and foreign keys reversed
+ primary_key, foreign_key = foreign_key, primary_key if association.macro == :belongs_to
+ return all if primary_key.nil? || foreign_key.nil?
+
+ self_table = arel_table
+ model_table = model.arel_table
+ model_exists = model.model_restriction(model_table).where(model_table[foreign_key].eq(self_table[primary_key])).exists
+ if exists
+ attribute_restriction(name).where(model_exists)
+ else
+ attribute_restriction(name).where.not(model_exists)
+ end
+ end
+
def apply_default_order(params)
if params[:order] == "custom"
parse_ids = PostQueryBuilder.new(nil).parse_range(params[:id], :integer)
@@ -319,7 +388,8 @@ module Searchable
params ||= {}
default_attributes = (attribute_names.map(&:to_sym) & %i[id created_at updated_at])
- search_attributes(params, *default_attributes)
+ all_attributes = default_attributes + searchable_includes
+ search_attributes(params, *all_attributes)
end
private
diff --git a/app/models/application_record.rb b/app/models/application_record.rb
index bd366d214..ec5af12fe 100644
--- a/app/models/application_record.rb
+++ b/app/models/application_record.rb
@@ -93,6 +93,22 @@ class ApplicationRecord < ActiveRecord::Base
end
end
+ concerning :SearchMethods do
+ class_methods do
+ def searchable_includes
+ []
+ end
+
+ def model_restriction(table)
+ table.project(1)
+ end
+
+ def attribute_restriction(*)
+ all
+ end
+ end
+ end
+
concerning :ActiveRecordExtensions do
class_methods do
def without_timeout
diff --git a/app/models/artist.rb b/app/models/artist.rb
index e40820fef..dccde5f68 100644
--- a/app/models/artist.rb
+++ b/app/models/artist.rb
@@ -266,12 +266,6 @@ class Artist < ApplicationRecord
q = q.url_matches(params[:url_matches])
end
- if params[:has_tag].to_s.truthy?
- q = q.where(name: Tag.nonempty.select(:name))
- elsif params[:has_tag].to_s.falsy?
- q = q.where.not(name: Tag.nonempty.select(:name))
- end
-
case params[:order]
when "name"
q = q.order("artists.name")
@@ -295,6 +289,14 @@ class Artist < ApplicationRecord
include BanMethods
extend SearchMethods
+ def self.model_restriction(table)
+ super.where(table[:is_deleted].eq(false))
+ end
+
+ def self.searchable_includes
+ [:urls, :wiki_page, :tag_alias, :tag]
+ end
+
def self.available_includes
[:members, :urls, :wiki_page, :tag_alias, :tag]
end
diff --git a/app/models/artist_commentary.rb b/app/models/artist_commentary.rb
index 64cf215a9..d94939d22 100644
--- a/app/models/artist_commentary.rb
+++ b/app/models/artist_commentary.rb
@@ -33,7 +33,7 @@ class ArtistCommentary < ApplicationRecord
def search(params)
q = super
- q = q.search_attributes(params, :post, :original_title, :original_description, :translated_title, :translated_description)
+ q = q.search_attributes(params, :original_title, :original_description, :translated_title, :translated_description)
if params[:text_matches].present?
q = q.text_matches(params[:text_matches])
@@ -146,6 +146,10 @@ class ArtistCommentary < ApplicationRecord
extend SearchMethods
include VersionMethods
+ def self.searchable_includes
+ [:post]
+ end
+
def self.available_includes
[:post]
end
diff --git a/app/models/artist_commentary_version.rb b/app/models/artist_commentary_version.rb
index d052810e8..1bf34aa02 100644
--- a/app/models/artist_commentary_version.rb
+++ b/app/models/artist_commentary_version.rb
@@ -2,9 +2,23 @@ class ArtistCommentaryVersion < ApplicationRecord
belongs_to :post
belongs_to_updater
+ def self.text_matches(query)
+ query = "*#{query}*" unless query =~ /\*/
+
+ where_ilike(:original_title, query)
+ .or(where_ilike(:original_description, query))
+ .or(where_ilike(:translated_title, query))
+ .or(where_ilike(:translated_description, query))
+ end
+
def self.search(params)
q = super
- q = q.search_attributes(params, :post, :updater, :original_title, :original_description, :translated_title, :translated_description)
+ q = q.search_attributes(params, :original_title, :original_description, :translated_title, :translated_description)
+
+ if params[:text_matches].present?
+ q = q.text_matches(params[:text_matches])
+ end
+
q.apply_default_order(params)
end
@@ -42,6 +56,10 @@ class ArtistCommentaryVersion < ApplicationRecord
self[field].strip.empty? && (previous.nil? || previous[field].strip.empty?)
end
+ def self.searchable_includes
+ [:post, :updater]
+ end
+
def self.available_includes
[:post, :updater]
end
diff --git a/app/models/artist_url.rb b/app/models/artist_url.rb
index b4e4d9af5..1119305a5 100644
--- a/app/models/artist_url.rb
+++ b/app/models/artist_url.rb
@@ -42,9 +42,8 @@ class ArtistUrl < ApplicationRecord
def self.search(params = {})
q = super
- q = q.search_attributes(params, :url, :normalized_url, :artist_id, :is_active)
+ q = q.search_attributes(params, :url, :normalized_url, :is_active)
- q = q.artist_matches(params[:artist])
q = q.url_matches(params[:url_matches])
q = q.normalized_url_matches(params[:normalized_url_matches])
@@ -59,11 +58,6 @@ class ArtistUrl < ApplicationRecord
q
end
- def self.artist_matches(params = {})
- return all if params.blank?
- where(artist_id: Artist.search(params).reorder(nil))
- end
-
def self.url_attribute_matches(attr, url)
if url.blank?
all
@@ -134,6 +128,10 @@ class ArtistUrl < ApplicationRecord
errors[:url] << "'#{uri}' is malformed: #{error}"
end
+ def self.searchable_includes
+ [:artist]
+ end
+
def self.available_includes
[:artist]
end
diff --git a/app/models/artist_version.rb b/app/models/artist_version.rb
index bcd08fa2b..19d608e6b 100644
--- a/app/models/artist_version.rb
+++ b/app/models/artist_version.rb
@@ -9,7 +9,9 @@ class ArtistVersion < ApplicationRecord
def search(params)
q = super
- q = q.search_attributes(params, :updater, :is_deleted, :is_banned, :artist_id, :name, :group_name)
+ q = q.search_attributes(params, :is_deleted, :is_banned, :name, :group_name, :urls, :other_names)
+ q = q.text_attribute_matches(:name, params[:name_matches])
+ q = q.text_attribute_matches(:group_name, params[:group_name_matches])
if params[:order] == "name"
q = q.order("artist_versions.name").default_order
@@ -103,6 +105,10 @@ class ArtistVersion < ApplicationRecord
end
end
+ def self.searchable_includes
+ [:updater, :artist]
+ end
+
def self.available_includes
[:updater, :artist]
end
diff --git a/app/models/ban.rb b/app/models/ban.rb
index 7b2ece40d..4af738b30 100644
--- a/app/models/ban.rb
+++ b/app/models/ban.rb
@@ -22,7 +22,7 @@ class Ban < ApplicationRecord
def self.search(params)
q = super
- q = q.search_attributes(params, :banner, :user, :expires_at, :reason)
+ q = q.search_attributes(params, :expires_at, :reason)
q = q.text_attribute_matches(:reason, params[:reason_matches])
q = q.expired if params[:expired].to_s.truthy?
@@ -97,6 +97,10 @@ class Ban < ApplicationRecord
ModAction.log(%{Unbanned <@#{user_name}>}, :user_unban)
end
+ def self.searchable_includes
+ [:user, :banner]
+ end
+
def self.available_includes
[:user, :banner]
end
diff --git a/app/models/bulk_update_request.rb b/app/models/bulk_update_request.rb
index 6909728a6..2070dc1db 100644
--- a/app/models/bulk_update_request.rb
+++ b/app/models/bulk_update_request.rb
@@ -35,7 +35,7 @@ class BulkUpdateRequest < ApplicationRecord
def search(params = {})
q = super
- q = q.search_attributes(params, :user, :approver, :forum_topic_id, :forum_post_id, :script, :tags)
+ q = q.search_attributes(params, :script, :tags)
q = q.text_attribute_matches(:script, params[:script_matches])
if params[:status].present?
@@ -152,6 +152,10 @@ class BulkUpdateRequest < ApplicationRecord
status == "rejected"
end
+ def self.searchable_includes
+ [:user, :forum_topic, :forum_post, :approver]
+ end
+
def self.available_includes
[:user, :forum_topic, :forum_post, :approver]
end
diff --git a/app/models/comment.rb b/app/models/comment.rb
index a402fcbc2..ade9a8073 100644
--- a/app/models/comment.rb
+++ b/app/models/comment.rb
@@ -28,7 +28,7 @@ class Comment < ApplicationRecord
def search(params)
q = super
- q = q.search_attributes(params, :post, :creator, :updater, :is_deleted, :is_sticky, :do_not_bump_post, :body, :score)
+ q = q.search_attributes(params, :is_deleted, :is_sticky, :do_not_bump_post, :body, :score)
q = q.text_attribute_matches(:body, params[:body_matches], index_column: :body_index)
case params[:order]
@@ -140,6 +140,10 @@ class Comment < ApplicationRecord
DText.quote(body, creator.name)
end
+ def self.searchable_includes
+ [:post, :creator, :updater]
+ end
+
def self.available_includes
[:post, :creator, :updater]
end
diff --git a/app/models/comment_vote.rb b/app/models/comment_vote.rb
index 0cfea7c16..ec1a5ce11 100644
--- a/app/models/comment_vote.rb
+++ b/app/models/comment_vote.rb
@@ -18,15 +18,9 @@ class CommentVote < ApplicationRecord
end
end
- def self.comment_matches(params)
- return all if params.blank?
- where(comment_id: Comment.search(params).reorder(nil).select(:id))
- end
-
def self.search(params)
q = super
- q = q.search_attributes(params, :comment_id, :user, :score)
- q = q.comment_matches(params[:comment])
+ q = q.search_attributes(params, :score)
q.apply_default_order(params)
end
@@ -44,6 +38,10 @@ class CommentVote < ApplicationRecord
score == -1
end
+ def self.searchable_includes
+ [:comment, :user]
+ end
+
def self.available_includes
[:comment, :user]
end
diff --git a/app/models/dmail.rb b/app/models/dmail.rb
index 25c053213..54b167242 100644
--- a/app/models/dmail.rb
+++ b/app/models/dmail.rb
@@ -98,7 +98,7 @@ class Dmail < ApplicationRecord
def search(params)
q = super
- q = q.search_attributes(params, :to, :from, :is_read, :is_deleted, :title, :body)
+ q = q.search_attributes(params, :is_read, :is_deleted, :title, :body)
q = q.text_attribute_matches(:title, params[:title_matches])
q = q.text_attribute_matches(:body, params[:message_matches], index_column: :message_index)
@@ -172,6 +172,10 @@ class Dmail < ApplicationRecord
key ? "dmail ##{id}/#{self.key}" : "dmail ##{id}"
end
+ def self.searchable_includes
+ [:to, :from]
+ end
+
def self.available_includes
[:owner, :to, :from]
end
diff --git a/app/models/dtext_link.rb b/app/models/dtext_link.rb
index 08df3bc23..ea4902d53 100644
--- a/app/models/dtext_link.rb
+++ b/app/models/dtext_link.rb
@@ -1,6 +1,7 @@
class DtextLink < ApplicationRecord
belongs_to :model, polymorphic: true
belongs_to :linked_wiki, primary_key: :title, foreign_key: :link_target, class_name: "WikiPage", optional: true
+ belongs_to :linked_tag, primary_key: :name, foreign_key: :link_target, class_name: "Tag", optional: true
enum link_type: [:wiki_link, :external_link]
@@ -28,43 +29,9 @@ class DtextLink < ApplicationRecord
links
end
- def self.model_matches(params)
- return all if params.blank?
- where(model_type: "WikiPage", model_id: WikiPage.search(params).reorder(nil))
- end
-
- def self.linked_wiki_exists(exists = true)
- dtext_links = DtextLink.arel_table
- wiki_pages = WikiPage.arel_table
- wiki_exists = wiki_pages.project(1).where(wiki_pages[:is_deleted].eq(false)).where(wiki_pages[:title].eq(dtext_links[:link_target])).exists
-
- if exists
- where(link_type: :wiki_link).where(wiki_exists)
- else
- where(link_type: :wiki_link).where.not(wiki_exists)
- end
- end
-
- def self.linked_tag_exists(exists = true)
- dtext_links = DtextLink.arel_table
- tags = Tag.arel_table
- tag_exists = tags.project(1).where(tags[:post_count].gt(0)).where(tags[:name].eq(dtext_links[:link_target])).exists
-
- if exists
- where(link_type: :wiki_link).where(tag_exists)
- else
- where(link_type: :wiki_link).where.not(tag_exists)
- end
- end
-
def self.search(params)
q = super
- q = q.search_attributes(params, :model_type, :model_id, :link_type, :link_target)
-
- q = q.model_matches(params[:model])
- q = q.linked_wiki_exists(params[:linked_wiki_exists].truthy?) if params[:linked_wiki_exists].present?
- q = q.linked_tag_exists(params[:linked_tag_exists].truthy?) if params[:linked_tag_exists].present?
-
+ q = q.search_attributes(params, :link_type, :link_target)
q.apply_default_order(params)
end
@@ -78,7 +45,15 @@ class DtextLink < ApplicationRecord
self.link_target = self.link_target.truncate(2048, omission: "")
end
+ def self.attribute_restriction(*)
+ where(link_type: :wiki_link)
+ end
+
+ def self.searchable_includes
+ [:model, :linked_wiki, :linked_tag]
+ end
+
def self.available_includes
- [:model]
+ [:model, :linked_wiki, :linked_tag]
end
end
diff --git a/app/models/favorite_group.rb b/app/models/favorite_group.rb
index d90e0e04a..edd4d0dfe 100644
--- a/app/models/favorite_group.rb
+++ b/app/models/favorite_group.rb
@@ -27,7 +27,7 @@ class FavoriteGroup < ApplicationRecord
def search(params)
q = super
- q = q.search_attributes(params, :name, :is_public, :post_ids, :creator)
+ q = q.search_attributes(params, :name, :is_public, :post_ids)
if params[:name_matches].present?
q = q.name_matches(params[:name_matches])
@@ -164,6 +164,10 @@ class FavoriteGroup < ApplicationRecord
post_ids.include?(post_id)
end
+ def self.searchable_includes
+ [:creator]
+ end
+
def self.available_includes
[:creator]
end
diff --git a/app/models/forum_post.rb b/app/models/forum_post.rb
index fde386242..d82c7b15f 100644
--- a/app/models/forum_post.rb
+++ b/app/models/forum_post.rb
@@ -32,31 +32,19 @@ class ForumPost < ApplicationRecord
)
module SearchMethods
- def topic_title_matches(title)
- where(topic_id: ForumTopic.search(title_matches: title).select(:id))
- end
-
def visible(user)
where(topic_id: ForumTopic.visible(user))
end
def search(params)
q = super
- q = q.search_attributes(params, :creator, :updater, :topic_id, :is_deleted, :body)
+ q = q.search_attributes(params, :is_deleted, :body)
q = q.text_attribute_matches(:body, params[:body_matches], index_column: :text_index)
if params[:linked_to].present?
q = q.where(id: DtextLink.forum_post.wiki_link.where(link_target: params[:linked_to]).select(:model_id))
end
- if params[:topic_title_matches].present?
- q = q.topic_title_matches(params[:topic_title_matches])
- end
-
- if params[:topic_category_id].present?
- q = q.where(topic_id: ForumTopic.where(category_id: params[:topic_category_id]))
- end
-
q.apply_default_order(params)
end
end
@@ -179,6 +167,10 @@ class ForumPost < ApplicationRecord
"forum ##{id}"
end
+ def self.searchable_includes
+ [:creator, :updater, :topic, :dtext_links, :votes, :tag_alias, :tag_implication, :bulk_update_request]
+ end
+
def self.available_includes
[:creator, :updater, :topic, :dtext_links, :votes, :tag_alias, :tag_implication, :bulk_update_request]
end
diff --git a/app/models/forum_post_vote.rb b/app/models/forum_post_vote.rb
index fe2bcd77c..3ea592389 100644
--- a/app/models/forum_post_vote.rb
+++ b/app/models/forum_post_vote.rb
@@ -20,7 +20,7 @@ class ForumPostVote < ApplicationRecord
def self.search(params)
q = super
- q = q.search_attributes(params, :creator, :forum_post_id, :score)
+ q = q.search_attributes(params, :score)
q = q.forum_post_matches(params[:forum_post])
q.apply_default_order(params)
end
@@ -59,7 +59,11 @@ class ForumPostVote < ApplicationRecord
end
end
+ def self.searchable_includes
+ [:creator, :forum_post]
+ end
+
def self.available_includes
- [:creator]
+ [:creator, :forum_post]
end
end
diff --git a/app/models/forum_topic.rb b/app/models/forum_topic.rb
index 22858c7f8..7daef04c4 100644
--- a/app/models/forum_topic.rb
+++ b/app/models/forum_topic.rb
@@ -19,6 +19,8 @@ class ForumTopic < ApplicationRecord
has_many :moderation_reports, through: :forum_posts
has_one :original_post, -> { order(id: :asc) }, class_name: "ForumPost", foreign_key: "topic_id", inverse_of: :topic
has_many :bulk_update_requests, :foreign_key => "forum_topic_id"
+ has_many :tag_aliases, :foreign_key => "forum_topic_id"
+ has_many :tag_implications, :foreign_key => "forum_topic_id"
validates_presence_of :title
validates_associated :original_post
@@ -85,7 +87,7 @@ class ForumTopic < ApplicationRecord
def search(params)
q = super
- q = q.search_attributes(params, :creator, :updater, :is_sticky, :is_locked, :is_deleted, :category_id, :title, :response_count)
+ q = q.search_attributes(params, :is_sticky, :is_locked, :is_deleted, :category_id, :title, :response_count)
q = q.text_attribute_matches(:title, params[:title_matches], index_column: :text_index)
if params[:is_private].to_s.truthy?
@@ -111,6 +113,8 @@ class ForumTopic < ApplicationRecord
case params[:order]
when "sticky"
q = q.sticky_first
+ when "id"
+ q = q.order(id: :desc)
else
q = q.apply_default_order(params)
end
@@ -190,6 +194,10 @@ class ForumTopic < ApplicationRecord
super + [:is_read?]
end
+ def self.searchable_includes
+ [:creator, :updater, :forum_posts, :bulk_update_requests, :tag_aliases, :tag_implications]
+ end
+
def self.available_includes
[:creator, :updater, :original_post]
end
diff --git a/app/models/ip_address.rb b/app/models/ip_address.rb
index 0fcf5a8fb..00920ced7 100644
--- a/app/models/ip_address.rb
+++ b/app/models/ip_address.rb
@@ -13,7 +13,7 @@ class IpAddress < ApplicationRecord
def self.search(params)
q = super
- q = q.search_attributes(params, :user, :model_type, :model_id, :ip_addr)
+ q = q.search_attributes(params, :ip_addr)
q.order(created_at: :desc)
end
@@ -54,6 +54,10 @@ class IpAddress < ApplicationRecord
super & attributes.keys.map(&:to_sym)
end
+ def self.searchable_includes
+ [:user, :model]
+ end
+
def self.available_includes
[:user, :model]
end
diff --git a/app/models/ip_ban.rb b/app/models/ip_ban.rb
index 7772250fa..266ff0ea0 100644
--- a/app/models/ip_ban.rb
+++ b/app/models/ip_ban.rb
@@ -26,7 +26,8 @@ class IpBan < ApplicationRecord
def self.search(params)
q = super
- q = q.search_attributes(params, :creator, :reason)
+ q = q.search_attributes(params, :reason)
+ q = q.text_attribute_matches(:reason, params[:reason_matches])
if params[:ip_addr].present?
q = q.where("ip_addr = ?", params[:ip_addr])
@@ -77,6 +78,10 @@ class IpBan < ApplicationRecord
super(ip_addr.strip)
end
+ def self.searchable_includes
+ [:creator]
+ end
+
def self.available_includes
[:creator]
end
diff --git a/app/models/mod_action.rb b/app/models/mod_action.rb
index 73b3f58f9..430948648 100644
--- a/app/models/mod_action.rb
+++ b/app/models/mod_action.rb
@@ -63,7 +63,7 @@ class ModAction < ApplicationRecord
def self.search(params)
q = super
- q = q.search_attributes(params, :creator, :category, :description)
+ q = q.search_attributes(params, :category, :description)
q = q.text_attribute_matches(:description, params[:description_matches])
q.apply_default_order(params)
@@ -77,6 +77,10 @@ class ModAction < ApplicationRecord
create(creator: user, description: desc, category: categories[cat])
end
+ def self.searchable_includes
+ [:creator]
+ end
+
def self.available_includes
[:creator]
end
diff --git a/app/models/moderation_report.rb b/app/models/moderation_report.rb
index b45a6d86c..4fa1f77de 100644
--- a/app/models/moderation_report.rb
+++ b/app/models/moderation_report.rb
@@ -83,11 +83,16 @@ class ModerationReport < ApplicationRecord
def self.search(params)
q = super
- q = q.search_attributes(params, :model_type, :model_id, :creator_id)
+ q = q.search_attributes(params, :reason)
+ q = q.text_attribute_matches(:reason, params[:reason_matches])
q.apply_default_order(params)
end
+ def self.searchable_includes
+ [:creator, :model]
+ end
+
def self.available_includes
[:creator, :model]
end
diff --git a/app/models/note.rb b/app/models/note.rb
index 9dd89362e..4facb2028 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -16,7 +16,7 @@ class Note < ApplicationRecord
def search(params)
q = super
- q = q.search_attributes(params, :post, :is_active, :x, :y, :width, :height, :body, :version)
+ q = q.search_attributes(params, :is_active, :x, :y, :width, :height, :body, :version)
q = q.text_attribute_matches(:body, params[:body_matches], index_column: :body_index)
q.apply_default_order(params)
@@ -129,6 +129,10 @@ class Note < ApplicationRecord
new_note.save
end
+ def self.searchable_includes
+ [:post]
+ end
+
def self.available_includes
[:post]
end
diff --git a/app/models/note_version.rb b/app/models/note_version.rb
index d8655f995..d8c3aed07 100644
--- a/app/models/note_version.rb
+++ b/app/models/note_version.rb
@@ -6,7 +6,7 @@ class NoteVersion < ApplicationRecord
def self.search(params)
q = super
- q = q.search_attributes(params, :updater, :is_active, :post, :note_id, :x, :y, :width, :height, :body, :version)
+ q = q.search_attributes(params, :is_active, :x, :y, :width, :height, :body, :version)
q = q.text_attribute_matches(:body, params[:body_matches])
q.apply_default_order(params)
@@ -71,6 +71,10 @@ class NoteVersion < ApplicationRecord
end
end
+ def self.searchable_includes
+ [:updater, :note, :post]
+ end
+
def self.available_includes
[:updater, :note, :post]
end
diff --git a/app/models/pixiv_ugoira_frame_data.rb b/app/models/pixiv_ugoira_frame_data.rb
index 2bfe5af3d..92c1eba2b 100644
--- a/app/models/pixiv_ugoira_frame_data.rb
+++ b/app/models/pixiv_ugoira_frame_data.rb
@@ -4,13 +4,17 @@ class PixivUgoiraFrameData < ApplicationRecord
serialize :data
before_validation :normalize_data, on: :create
+ def self.searchable_includes
+ [:post]
+ end
+
def self.available_includes
[:post]
end
def self.search(params)
q = super
- q = q.search_attributes(params, :post, :data, :content_type)
+ q = q.search_attributes(params, :data, :content_type)
q.apply_default_order(params)
end
diff --git a/app/models/post.rb b/app/models/post.rb
index 93cbfa75c..b01b4979a 100644
--- a/app/models/post.rb
+++ b/app/models/post.rb
@@ -1291,12 +1291,12 @@ class Post < ApplicationRecord
def search(params)
q = super
- q = q.search_attributes(params,
- :approver, :uploader, :rating, :source, :pixiv_id, :fav_count, :score, :up_score,
- :down_score, :md5, :file_ext, :file_size, :image_width, :image_height, :tag_count,
- :parent, :has_children, :has_active_children, :is_note_locked, :is_rating_locked,
- :is_status_locked, :is_pending, :is_flagged, :is_deleted, :is_banned,
- :last_comment_bumped_at, :last_commented_at, :last_noted_at
+ q = q.search_attributes(
+ params,
+ :rating, :source, :pixiv_id, :fav_count, :score, :up_score, :down_score, :md5, :file_ext,
+ :file_size, :image_width, :image_height, :tag_count, :has_children, :has_active_children,
+ :is_note_locked, :is_rating_locked, :is_status_locked, :is_pending, :is_flagged, :is_deleted,
+ :is_banned, :last_comment_bumped_at, :last_commented_at, :last_noted_at
)
if params[:tags].present?
@@ -1508,6 +1508,14 @@ class Post < ApplicationRecord
super + [:has_large?, :current_image_size]
end
+ def self.model_restriction(table)
+ super.where(table[:is_pending].eq(false)).where(table[:is_flagged].eq(false)).where(table[:is_deleted].eq(false))
+ end
+
+ def self.searchable_includes
+ [:uploader, :updater, :approver, :parent, :upload, :artist_commentary, :flags, :appeals, :notes, :comments, :children, :approvals, :replacements, :pixiv_ugoira_frame_data]
+ end
+
def self.available_includes
[:uploader, :updater, :approver, :parent, :upload, :artist_commentary, :flags, :appeals, :notes, :comments, :children, :approvals, :replacements, :pixiv_ugoira_frame_data]
end
diff --git a/app/models/post_appeal.rb b/app/models/post_appeal.rb
index 84fc143aa..8c8be655a 100644
--- a/app/models/post_appeal.rb
+++ b/app/models/post_appeal.rb
@@ -18,7 +18,7 @@ class PostAppeal < ApplicationRecord
module SearchMethods
def search(params)
q = super
- q = q.search_attributes(params, :creator, :post, :reason, :status)
+ q = q.search_attributes(params, :reason, :status)
q = q.text_attribute_matches(:reason, params[:reason_matches])
q.apply_default_order(params)
@@ -35,6 +35,10 @@ class PostAppeal < ApplicationRecord
errors[:post] << "cannot be appealed" if post.is_status_locked? || !post.is_appealable?
end
+ def self.searchable_includes
+ [:creator, :post]
+ end
+
def self.available_includes
[:creator, :post]
end
diff --git a/app/models/post_approval.rb b/app/models/post_approval.rb
index b2efa6437..599cd1ba9 100644
--- a/app/models/post_approval.rb
+++ b/app/models/post_approval.rb
@@ -39,10 +39,13 @@ class PostApproval < ApplicationRecord
def self.search(params)
q = super
- q = q.search_attributes(params, :user, :post)
q.apply_default_order(params)
end
+ def self.searchable_includes
+ [:user, :post]
+ end
+
def self.available_includes
[:user, :post]
end
diff --git a/app/models/post_disapproval.rb b/app/models/post_disapproval.rb
index fc1076d6b..0c6af91d8 100644
--- a/app/models/post_disapproval.rb
+++ b/app/models/post_disapproval.rb
@@ -23,7 +23,7 @@ class PostDisapproval < ApplicationRecord
def search(params)
q = super
- q = q.search_attributes(params, :post, :user, :message, :reason)
+ q = q.search_attributes(params, :message, :reason)
q = q.text_attribute_matches(:message, params[:message_matches])
q = q.with_message if params[:has_message].to_s.truthy?
@@ -41,6 +41,10 @@ class PostDisapproval < ApplicationRecord
end
end
+ def self.searchable_includes
+ [:user, :post]
+ end
+
def self.available_includes
[:user, :post]
end
diff --git a/app/models/post_flag.rb b/app/models/post_flag.rb
index 852de1809..80f5b07f1 100644
--- a/app/models/post_flag.rb
+++ b/app/models/post_flag.rb
@@ -58,7 +58,7 @@ class PostFlag < ApplicationRecord
def search(params)
q = super
- q = q.search_attributes(params, :post, :reason, :status)
+ q = q.search_attributes(params, :reason, :status)
q = q.text_attribute_matches(:reason, params[:reason_matches])
if params[:creator_id].present?
@@ -113,6 +113,10 @@ class PostFlag < ApplicationRecord
post.uploader_id
end
+ def self.searchable_includes
+ [:post]
+ end
+
def self.available_includes
[:post]
end
diff --git a/app/models/post_replacement.rb b/app/models/post_replacement.rb
index 40cbaed2d..35dd266a6 100644
--- a/app/models/post_replacement.rb
+++ b/app/models/post_replacement.rb
@@ -22,7 +22,7 @@ class PostReplacement < ApplicationRecord
class_methods do
def search(params = {})
q = super
- q = q.search_attributes(params, :post, :creator, :md5, :md5_was, :file_ext, :file_ext_was, :original_url, :replacement_url)
+ q = q.search_attributes(params, :md5, :md5_was, :file_ext, :file_ext_was, :original_url, :replacement_url)
q.apply_default_order(params)
end
end
@@ -39,6 +39,10 @@ class PostReplacement < ApplicationRecord
tags.join(" ")
end
+ def self.searchable_includes
+ [:creator, :post]
+ end
+
def self.available_includes
[:creator, :post]
end
diff --git a/app/models/post_vote.rb b/app/models/post_vote.rb
index bcbcc74a2..fdc9aa896 100644
--- a/app/models/post_vote.rb
+++ b/app/models/post_vote.rb
@@ -20,12 +20,12 @@ class PostVote < ApplicationRecord
def self.search(params)
q = super
- q = q.search_attributes(params, :post, :user, :score)
+ q = q.search_attributes(params, :score)
q.apply_default_order(params)
end
def initialize_attributes
- self.user_id ||= CurrentUser.user.id
+ self.user_id ||= CurrentUser.id
if vote == "up"
self.score = 1
@@ -50,6 +50,10 @@ class PostVote < ApplicationRecord
end
end
+ def self.searchable_includes
+ [:user, :post]
+ end
+
def self.available_includes
[:user, :post]
end
diff --git a/app/models/tag.rb b/app/models/tag.rb
index 731f2aee7..f018c2dbf 100644
--- a/app/models/tag.rb
+++ b/app/models/tag.rb
@@ -5,6 +5,7 @@ class Tag < ApplicationRecord
has_many :consequent_aliases, -> {active}, :class_name => "TagAlias", :foreign_key => "consequent_name", :primary_key => "name"
has_many :antecedent_implications, -> {active}, :class_name => "TagImplication", :foreign_key => "antecedent_name", :primary_key => "name"
has_many :consequent_implications, -> {active}, :class_name => "TagImplication", :foreign_key => "consequent_name", :primary_key => "name"
+ has_many :dtext_links, foreign_key: :link_target, primary_key: :name
validates :name, tag_name: true, uniqueness: true, on: :create
validates :name, tag_name: true, on: :name
@@ -284,18 +285,6 @@ class Tag < ApplicationRecord
q = q.nonempty
end
- if params[:has_wiki].to_s.truthy?
- q = q.joins(:wiki_page).merge(WikiPage.undeleted)
- elsif params[:has_wiki].to_s.falsy?
- q = q.left_outer_joins(:wiki_page).where("wiki_pages.title IS NULL OR wiki_pages.is_deleted = TRUE")
- end
-
- if params[:has_artist].to_s.truthy?
- q = q.joins(:artist).merge(Artist.undeleted)
- elsif params[:has_artist].to_s.falsy?
- q = q.left_outer_joins(:artist).where("artists.name IS NULL OR artists.is_deleted = TRUE")
- end
-
case params[:order]
when "name"
q = q.order("name")
@@ -355,8 +344,16 @@ class Tag < ApplicationRecord
Post.system_tag_match(name)
end
+ def self.model_restriction(table)
+ super.where(table[:post_count].gt(0))
+ end
+
+ def self.searchable_includes
+ [:wiki_page, :artist, :antecedent_alias, :consequent_aliases, :antecedent_implications, :consequent_implications, :dtext_links]
+ end
+
def self.available_includes
- [:wiki_page, :artist, :antecedent_alias, :consequent_aliases, :antecedent_implications, :consequent_implications]
+ [:wiki_page, :artist, :antecedent_alias, :consequent_aliases, :antecedent_implications, :consequent_implications, :dtext_links]
end
include ApiMethods
diff --git a/app/models/tag_relationship.rb b/app/models/tag_relationship.rb
index 1ed46ad98..75d37571a 100644
--- a/app/models/tag_relationship.rb
+++ b/app/models/tag_relationship.rb
@@ -12,8 +12,8 @@ class TagRelationship < ApplicationRecord
belongs_to :forum_topic, optional: true
belongs_to :antecedent_tag, class_name: "Tag", foreign_key: "antecedent_name", primary_key: "name", default: -> { Tag.find_or_create_by_name(antecedent_name) }
belongs_to :consequent_tag, class_name: "Tag", foreign_key: "consequent_name", primary_key: "name", default: -> { Tag.find_or_create_by_name(consequent_name) }
- has_one :antecedent_wiki, through: :antecedent_tag, source: :wiki_page
- has_one :consequent_wiki, through: :consequent_tag, source: :wiki_page
+ belongs_to :antecedent_wiki, class_name: "WikiPage", foreign_key: "antecedent_name", primary_key: "title", optional: true
+ belongs_to :consequent_wiki, class_name: "WikiPage", foreign_key: "antecedent_name", primary_key: "title", optional: true
scope :active, -> {approved}
scope :approved, -> {where(status: %w[active processing queued])}
@@ -94,7 +94,7 @@ class TagRelationship < ApplicationRecord
def search(params)
q = super
- q = q.search_attributes(params, :creator, :approver, :forum_topic_id, :forum_post_id, :antecedent_name, :consequent_name)
+ q = q.search_attributes(params, :antecedent_name, :consequent_name)
if params[:name_matches].present?
q = q.name_matches(params[:name_matches])
@@ -157,6 +157,14 @@ class TagRelationship < ApplicationRecord
end
end
+ def self.model_restriction(table)
+ super.where(table[:status].eq("active"))
+ end
+
+ def self.searchable_includes
+ [:creator, :approver, :forum_post, :forum_topic, :antecedent_tag, :consequent_tag, :antecedent_wiki, :consequent_wiki]
+ end
+
def self.available_includes
[:creator, :approver, :forum_post, :forum_topic, :antecedent_tag, :consequent_tag, :antecedent_wiki, :consequent_wiki]
end
diff --git a/app/models/upload.rb b/app/models/upload.rb
index 3d46380b7..e3e8cda1a 100644
--- a/app/models/upload.rb
+++ b/app/models/upload.rb
@@ -184,7 +184,7 @@ class Upload < ApplicationRecord
def self.search(params)
q = super
- q = q.search_attributes(params, :uploader, :post, :source, :rating, :parent_id, :server, :md5, :server, :file_ext, :file_size, :image_width, :image_height, :referer_url)
+ q = q.search_attributes(params, :source, :rating, :parent_id, :server, :md5, :server, :file_ext, :file_size, :image_width, :image_height, :referer_url)
if params[:source_matches].present?
q = q.where_like(:source, params[:source_matches])
@@ -225,6 +225,10 @@ class Upload < ApplicationRecord
artist_commentary_title.present? || artist_commentary_desc.present? || translated_commentary_title.present? || translated_commentary_desc.present?
end
+ def self.searchable_includes
+ [:uploader, :post]
+ end
+
def self.available_includes
[:uploader, :post]
end
diff --git a/app/models/user.rb b/app/models/user.rb
index afee4db2d..835e08894 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -80,7 +80,6 @@ class User < ApplicationRecord
validates_presence_of :comment_threshold
before_validation :normalize_blacklisted_tags
before_create :promote_to_admin_if_first_user
- has_many :artists, foreign_key: :creator_id
has_many :artist_versions, foreign_key: :updater_id
has_many :artist_commentary_versions, foreign_key: :updater_id
has_many :comments, foreign_key: :creator_id
@@ -91,7 +90,6 @@ class User < ApplicationRecord
has_many :forum_topic_visits, dependent: :destroy
has_many :visited_forum_topics, through: :forum_topic_visits, source: :forum_topic
has_many :moderation_reports, as: :model
- has_many :pools, foreign_key: :creator_id
has_many :posts, :foreign_key => "uploader_id"
has_many :post_appeals, foreign_key: :creator_id
has_many :post_approvals, :dependent => :destroy
@@ -105,10 +103,10 @@ class User < ApplicationRecord
has_one :api_key
has_one :token_bucket
has_one :email_address, dependent: :destroy
- has_many :notes, foreign_key: :creator_id
has_many :note_versions, :foreign_key => "updater_id"
has_many :dmails, -> {order("dmails.id desc")}, :foreign_key => "owner_id"
has_many :saved_searches
+ has_many :forum_topics, :foreign_key => "creator_id"
has_many :forum_posts, -> {order("forum_posts.created_at, forum_posts.id")}, :foreign_key => "creator_id"
has_many :user_name_change_requests, -> {order("user_name_change_requests.created_at desc")}
has_many :favorite_groups, -> {order(name: :asc)}, foreign_key: :creator_id
@@ -537,7 +535,7 @@ class User < ApplicationRecord
params = params.dup
params[:name_matches] = params.delete(:name) if params[:name].present?
- q = q.search_attributes(params, :name, :level, :inviter, :post_upload_count, :post_update_count, :note_update_count, :favorite_count)
+ q = q.search_attributes(params, :name, :level, :post_upload_count, :post_update_count, :note_update_count, :favorite_count)
if params[:name_matches].present?
q = q.where_ilike(:name, normalize_name(params[:name_matches]))
@@ -606,6 +604,10 @@ class User < ApplicationRecord
"<@#{name}>"
end
+ def self.searchable_includes
+ [:posts, :note_versions, :artist_commentary_versions, :post_appeals, :post_approvals, :artist_versions, :comments, :wiki_page_versions, :feedback, :forum_topics, :forum_posts, :forum_post_votes, :tag_aliases, :tag_implications, :bans, :inviter]
+ end
+
def self.available_includes
[:inviter]
end
diff --git a/app/models/user_feedback.rb b/app/models/user_feedback.rb
index 90690d56a..e7ffbcb45 100644
--- a/app/models/user_feedback.rb
+++ b/app/models/user_feedback.rb
@@ -32,7 +32,7 @@ class UserFeedback < ApplicationRecord
def search(params)
q = super
- q = q.search_attributes(params, :user, :creator, :category, :body, :is_deleted)
+ q = q.search_attributes(params, :category, :body, :is_deleted)
q = q.text_attribute_matches(:body, params[:body_matches])
q.apply_default_order(params)
@@ -65,6 +65,10 @@ class UserFeedback < ApplicationRecord
Dmail.create_automated(:to_id => user_id, :title => "Your user record has been updated", :body => body)
end
+ def self.searchable_includes
+ [:creator, :user]
+ end
+
def self.available_includes
[:creator, :user]
end
diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb
index 73f7f8ced..f2651be56 100644
--- a/app/models/wiki_page.rb
+++ b/app/models/wiki_page.rb
@@ -48,10 +48,6 @@ class WikiPage < ApplicationRecord
end
end
- def tag_matches(params)
- where(title: Tag.search(params).select(:name).reorder(nil))
- end
-
def linked_to(title)
where(dtext_links: DtextLink.wiki_page.wiki_link.where(link_target: normalize_title(title)))
end
@@ -78,10 +74,6 @@ class WikiPage < ApplicationRecord
q = q.other_names_match(params[:other_names_match])
end
- if params[:tag].present?
- q = q.tag_matches(params[:tag])
- end
-
if params[:linked_to].present?
q = q.linked_to(params[:linked_to])
end
@@ -197,12 +189,12 @@ class WikiPage < ApplicationRecord
def merge_version?
prev = versions.last
- prev && prev.updater_id == CurrentUser.user.id && prev.updated_at > 1.hour.ago
+ prev && prev.updater_id == CurrentUser.id && prev.updated_at > 1.hour.ago
end
def create_new_version
versions.create(
- :updater_id => CurrentUser.user.id,
+ :updater_id => CurrentUser.id,
:updater_ip_addr => CurrentUser.ip_addr,
:title => title,
:body => body,
@@ -245,6 +237,14 @@ class WikiPage < ApplicationRecord
end
end
+ def self.model_restriction(table)
+ super.where(table[:is_deleted].eq(false))
+ end
+
+ def self.searchable_includes
+ [:tag, :artist, :dtext_links]
+ end
+
def self.available_includes
[:tag, :artist, :dtext_links]
end
diff --git a/app/models/wiki_page_version.rb b/app/models/wiki_page_version.rb
index 4830b83fd..b0687b191 100644
--- a/app/models/wiki_page_version.rb
+++ b/app/models/wiki_page_version.rb
@@ -9,9 +9,9 @@ class WikiPageVersion < ApplicationRecord
def search(params)
q = super
- q = q.search_attributes(params, :updater, :is_locked, :is_deleted, :wiki_page_id)
- q = q.text_attribute_matches(:title, params[:title])
- q = q.text_attribute_matches(:body, params[:body])
+ q = q.search_attributes(params, :title, :body, :other_names, :is_locked, :is_deleted)
+ q = q.text_attribute_matches(:title, params[:title_matches])
+ q = q.text_attribute_matches(:body, params[:body_matches])
q.apply_default_order(params)
end
@@ -77,7 +77,11 @@ class WikiPageVersion < ApplicationRecord
end
end
+ def self.searchable_includes
+ [:updater, :wiki_page, :artist, :tag]
+ end
+
def self.available_includes
- [:updater, :wiki_page, :artist]
+ [:updater, :wiki_page, :artist, :tag]
end
end
diff --git a/app/views/dtext_links/index.html.erb b/app/views/dtext_links/index.html.erb
index 8cc2957fd..8ec40e974 100644
--- a/app/views/dtext_links/index.html.erb
+++ b/app/views/dtext_links/index.html.erb
@@ -4,8 +4,8 @@
<%= f.input :link_target_ilike, label: "Link", hint: "Use * for wildcard", input_html: { value: params[:search][:link_target_ilike], data: { autocomplete: "wiki-page" } } %>
<%= f.input :model_type, label: "Page Type", collection: [["Wiki Page", "WikiPage"], ["Forum Post", "ForumPost"]], include_blank: true, selected: params[:search][:model_type] %>
<%= f.input :link_type, label: "Link Type", collection: [["Wiki", "0"], ["External", "1"]], include_blank: true, selected: params[:search][:link_type] %>
- <%= f.input :linked_wiki_exists, label: "Wiki Exists?", collection: ["Yes", "No"], include_blank: true, selected: params[:search][:linked_wiki_exists] %>
- <%= f.input :linked_tag_exists, label: "Tag Exists?", collection: ["Yes", "No"], include_blank: true, selected: params[:search][:linked_tag_exists] %>
+ <%= f.input :has_linked_wiki, label: "Wiki Exists?", collection: ["Yes", "No"], include_blank: true, selected: params[:search][:has_linked_wiki] %>
+ <%= f.input :has_linked_tag, label: "Tag Exists?", collection: ["Yes", "No"], include_blank: true, selected: params[:search][:has_linked_tag] %>
<%= f.submit "Search" %>
<% end %>
diff --git a/app/views/forum_posts/search.html.erb b/app/views/forum_posts/search.html.erb
index decceebfe..f889cd3a3 100644
--- a/app/views/forum_posts/search.html.erb
+++ b/app/views/forum_posts/search.html.erb
@@ -3,11 +3,15 @@
Search Forum
<%= search_form_for(forum_posts_path) do |f| %>
- <%= f.input :topic_title_matches, label: "Title" %>
+ <%= f.simple_fields_for :topic do |pf| %>
+ <%= pf.input :title_matches, label: "Title" %>
+ <% end %>
<%= f.input :body_matches, label: "Body" %>
<%= f.input :creator_name, label: "Creator", input_html: { "data-autocomplete": "user" } %>
<%= f.input :linked_to, label: "Tag", hint: "Find posts mentioning a tag", input_html: { "data-autocomplete": "tag" } %>
- <%= f.input :topic_category_id, label: "Category", collection: ForumTopic::CATEGORIES.invert.to_a, include_blank: true %>
+ <%= f.simple_fields_for :topic do |pf| %>
+ <%= pf.input :category_id, label: "Category", collection: ForumTopic::CATEGORIES.invert.to_a, include_blank: true %>
+ <% end %>
<%= f.submit "Search" %>
<% end %>
diff --git a/app/views/tags/_search.html.erb b/app/views/tags/_search.html.erb
index a4fb623b6..a6a2bfbe1 100644
--- a/app/views/tags/_search.html.erb
+++ b/app/views/tags/_search.html.erb
@@ -3,7 +3,7 @@
<%= f.input :category, label: "Category", collection: TagCategory.canonical_mapping.to_a, include_blank: true,selected: params[:search][:category] %>
<%= f.input :order, collection: [%w[Newest date], %w[Count count], %w[Name name]], include_blank: false, selected: params[:search][:order] %>
<%= f.input :hide_empty, label: "Hide empty?", collection: %w[yes no], selected: params[:search][:hide_empty] %>
- <%= f.input :has_wiki, label: "Has wiki?", collection: %w[yes no], include_blank: true, selected: params[:search][:has_wiki] %>
+ <%= f.input :has_wiki_page, label: "Has wiki?", collection: %w[yes no], include_blank: true, selected: params[:search][:has_wiki_page] %>
<%= f.input :has_artist, label: "Has artist?", collection: %w[yes no], include_blank: true, selected: params[:search][:has_artist] %>
<%= f.submit "Search" %>
<% end %>
diff --git a/test/factories/forum_post.rb b/test/factories/forum_post.rb
index acc151a70..09e65918a 100644
--- a/test/factories/forum_post.rb
+++ b/test/factories/forum_post.rb
@@ -1,6 +1,7 @@
FactoryBot.define do
factory(:forum_post) do
creator
+ topic factory: :forum_topic
body {FFaker::Lorem.sentences.join(" ")}
end
end
diff --git a/test/factories/mod_action.rb b/test/factories/mod_action.rb
index 4be3425e2..18ae08903 100644
--- a/test/factories/mod_action.rb
+++ b/test/factories/mod_action.rb
@@ -2,5 +2,6 @@ FactoryBot.define do
factory(:mod_action) do
creator :factory => :user
description {"1234"}
+ category {"other"}
end
end
diff --git a/test/factories/post_disapproval.rb b/test/factories/post_disapproval.rb
index 55052a2b5..89f5717ef 100644
--- a/test/factories/post_disapproval.rb
+++ b/test/factories/post_disapproval.rb
@@ -1,7 +1,7 @@
FactoryBot.define do
factory(:post_disapproval) do
- user
- post
+ user factory: :moderator_user
+ post factory: :post, is_pending: true
reason { PostDisapproval::REASONS.sample }
message { FFaker::Lorem.sentence }
end
diff --git a/test/factories/post_replacement.rb b/test/factories/post_replacement.rb
index 119242c0a..43108423a 100644
--- a/test/factories/post_replacement.rb
+++ b/test/factories/post_replacement.rb
@@ -1,5 +1,6 @@
FactoryBot.define do
factory(:post_replacement) do
+ post factory: :post, source: FFaker::Internet.http_url
original_url { FFaker::Internet.http_url }
replacement_url { FFaker::Internet.http_url }
end
diff --git a/test/factories/post_vote.rb b/test/factories/post_vote.rb
index 8a360bd39..4d1e6b3b9 100644
--- a/test/factories/post_vote.rb
+++ b/test/factories/post_vote.rb
@@ -1,6 +1,6 @@
FactoryBot.define do
factory(:post_vote) do
- user
+ user factory: :gold_user
post
score { [-1, 1].sample }
end
diff --git a/test/factories/tag_alias.rb b/test/factories/tag_alias.rb
index 3ab1efb46..c280d7dab 100644
--- a/test/factories/tag_alias.rb
+++ b/test/factories/tag_alias.rb
@@ -1,8 +1,8 @@
FactoryBot.define do
factory :tag_alias do
creator
- antecedent_name {"aaa"}
- consequent_name {"bbb"}
+ antecedent_name {"#{FFaker::Name.first_name.downcase}#{rand(1000)}"}
+ consequent_name {"#{FFaker::Name.first_name.downcase}#{rand(1000)}"}
status {"active"}
skip_secondary_validations {true}
end
diff --git a/test/factories/tag_implication.rb b/test/factories/tag_implication.rb
index c1f0d7fd5..08677a9d2 100644
--- a/test/factories/tag_implication.rb
+++ b/test/factories/tag_implication.rb
@@ -1,8 +1,8 @@
FactoryBot.define do
factory :tag_implication do
creator
- antecedent_name {"aaa"}
- consequent_name {"bbb"}
+ antecedent_name {"#{FFaker::Name.first_name.downcase}#{rand(1000)}"}
+ consequent_name {"#{FFaker::Name.first_name.downcase}#{rand(1000)}"}
status {"active"}
skip_secondary_validations {true}
end
diff --git a/test/functional/artist_commentaries_controller_test.rb b/test/functional/artist_commentaries_controller_test.rb
index beea52479..9698a00bd 100644
--- a/test/functional/artist_commentaries_controller_test.rb
+++ b/test/functional/artist_commentaries_controller_test.rb
@@ -3,43 +3,43 @@ require 'test_helper'
class ArtistCommentariesControllerTest < ActionDispatch::IntegrationTest
context "The artist commentaries controller" do
setup do
- @user = create(:user)
-
+ @user = create(:user, id: 1000, name: "danbo", created_at: 2.weeks.ago)
as(@user) do
- @commentary1 = create(:artist_commentary)
- @commentary2 = create(:artist_commentary)
+ @commentary = create(:artist_commentary, post: build(:post, id: 999, tag_string: "hakurei_reimu", uploader: @user), original_title: "ot1", translated_title: "tt1")
+ @other_commentary = create(:artist_commentary, translated_title: "", translated_description: "")
end
end
context "index action" do
+ setup do
+ @deleted_commentary = create(:artist_commentary, original_title: "", original_description: "", translated_title: "", translated_description: "")
+ end
+
should "render" do
get artist_commentaries_path
assert_response :success
end
- should "render with search params" do
- params = {
- search: {
- text_matches: @commentary1.original_title,
- post_id: @commentary1.post_id,
- original_present: "yes",
- translated_present: "yes",
- post_tags_match: @commentary1.post.tag_array.first
- }
- }
+ should respond_to_search({}).with { [@deleted_commentary, @other_commentary, @commentary] }
+ should respond_to_search(text_matches: "ot1").with { @commentary }
+ should respond_to_search(original_present: "true").with { [@other_commentary, @commentary] }
+ should respond_to_search(translated_present: "true").with { @commentary }
+ should respond_to_search(is_deleted: "yes").with { @deleted_commentary }
- get artist_commentaries_path(params)
- assert_response :success
+ context "using includes" do
+ should respond_to_search(post_id: 999).with { @commentary }
+ should respond_to_search(post_tags_match: "hakurei_reimu").with { @commentary }
+ should respond_to_search(post: {uploader_name: "danbo"}).with { @commentary }
end
end
context "show action" do
should "render" do
- get artist_commentary_path(@commentary1.id)
- assert_redirected_to(@commentary1.post)
+ get artist_commentary_path(@commentary.id)
+ assert_redirected_to(@commentary.post)
- get artist_commentary_path(post_id: @commentary1.post_id)
- assert_redirected_to(@commentary1.post)
+ get artist_commentary_path(post_id: @commentary.post_id)
+ assert_redirected_to(@commentary.post)
end
end
@@ -62,27 +62,27 @@ class ArtistCommentariesControllerTest < ActionDispatch::IntegrationTest
should "render for update" do
params = {
artist_commentary: {
- post_id: @commentary1.post_id,
+ post_id: @commentary.post_id,
original_title: "foo"
},
format: "js"
}
put_auth create_or_update_artist_commentaries_path(params), @user
- @commentary1.reload
+ @commentary.reload
assert_response :success
- assert_equal("foo", @commentary1.reload.original_title)
+ assert_equal("foo", @commentary.reload.original_title)
end
end
context "revert action" do
should "work" do
- original_title = @commentary1.original_title
- @commentary1.update(original_title: "foo")
- @commentary1.reload
- put_auth revert_artist_commentary_path(@commentary1.post_id, version_id: @commentary1.versions.first.id, format: "js"), @user
+ original_title = @commentary.original_title
+ @commentary.update(original_title: "foo")
+ @commentary.reload
+ put_auth revert_artist_commentary_path(@commentary.post_id, version_id: @commentary.versions.first.id, format: "js"), @user
assert_response :success
- assert_equal(original_title, @commentary1.reload.original_title)
+ assert_equal(original_title, @commentary.reload.original_title)
end
should "return 404 when trying to revert a nonexistent commentary" do
@@ -91,9 +91,9 @@ class ArtistCommentariesControllerTest < ActionDispatch::IntegrationTest
end
should "not allow reverting to a previous version of another artist commentary" do
- put_auth revert_artist_commentary_path(@commentary1.post_id, version_id: @commentary2.versions.first.id, format: "js"), @user
- @commentary1.reload
- assert_not_equal(@commentary1.original_title, @commentary2.original_title)
+ put_auth revert_artist_commentary_path(@commentary.post_id, version_id: @other_commentary.versions.first.id, format: "js"), @user
+ @commentary.reload
+ assert_not_equal(@commentary.original_title, @other_commentary.original_title)
assert_response :missing
end
end
diff --git a/test/functional/artist_commentary_versions_controller_test.rb b/test/functional/artist_commentary_versions_controller_test.rb
index 246fda590..9c5f79f2d 100644
--- a/test/functional/artist_commentary_versions_controller_test.rb
+++ b/test/functional/artist_commentary_versions_controller_test.rb
@@ -3,24 +3,48 @@ require 'test_helper'
class ArtistCommentaryVersionsControllerTest < ActionDispatch::IntegrationTest
context "The artist commentary versions controller" do
setup do
- @user = create(:user)
- @commentary1 = as(@user) { create(:artist_commentary) }
- @commentary2 = as(@user) { create(:artist_commentary) }
+ @user = create(:member_user, id: 1000, created_at: 2.weeks.ago)
+ @builder = create(:builder_user, created_at: 2.weeks.ago)
+ as(@user) do
+ @commentary = create(:artist_commentary, post: build(:post, id: 999, tag_string: "hakurei_reimu", uploader: @user))
+ end
+ as (@builder) { @commentary.update(original_title: "traslated") }
+ as (@user) { @commentary.update(original_title: "translated") }
end
context "index action" do
+ setup do
+ @versions = @commentary.versions
+ as(@builder) do
+ @other_commentary = create(:artist_commentary, post: build(:post, uploader: @builder))
+ end
+ @other_versions = @other_commentary.versions
+ end
+
should "render" do
get artist_commentary_versions_path
assert_response :success
end
+
+ should respond_to_search({}).with { @other_versions + @versions.reverse }
+ should respond_to_search(original_title: "translated").with { @versions[2] }
+ should respond_to_search(text_matches: "traslated").with { @versions[1] }
+
+ context "using includes" do
+ should respond_to_search(post_id: 999).with { @versions.reverse }
+ should respond_to_search(post_tags_match: "hakurei_reimu").with { @versions.reverse }
+ should respond_to_search(post: {uploader: {level: User::Levels::BUILDER}}).with { @other_commentary.versions }
+ should respond_to_search(updater_id: 1000).with { [@versions[2], @versions[0]] }
+ should respond_to_search(updater: {level: User::Levels::BUILDER}).with { [@other_versions[0], @versions[1]] }
+ end
end
context "show action" do
should "work" do
- get artist_commentary_version_path(@commentary1.versions.first)
- assert_redirected_to artist_commentary_versions_path(search: { post_id: @commentary1.post_id })
+ get artist_commentary_version_path(@commentary.versions.first)
+ assert_redirected_to artist_commentary_versions_path(search: { post_id: @commentary.post_id })
- get artist_commentary_version_path(@commentary1.versions.first), as: :json
+ get artist_commentary_version_path(@commentary.versions.first), as: :json
assert_response :success
end
end
diff --git a/test/functional/artist_urls_controller_test.rb b/test/functional/artist_urls_controller_test.rb
index 8a0f15707..1cbe927db 100644
--- a/test/functional/artist_urls_controller_test.rb
+++ b/test/functional/artist_urls_controller_test.rb
@@ -2,28 +2,24 @@ require 'test_helper'
class ArtistUrlsControllerTest < ActionDispatch::IntegrationTest
context "The artist urls controller" do
+ setup do
+ @artist = create(:artist, name: "bkub", url_string: "-http://bkub.com")
+ @banned = create(:artist, name: "danbo", is_banned: true, url_string: "https://danbooru.donmai.us")
+ end
+
context "index page" do
should "render" do
get artist_urls_path
assert_response :success
end
- should "render for a json request" do
- get artist_urls_path, as: :json
- assert_response :success
- end
+ should respond_to_search({}).with { @banned.urls + @artist.urls }
+ should respond_to_search(url_matches: "*bkub*").with { @artist.urls }
+ should respond_to_search(is_active: "false").with { @artist.urls }
- should "render for a complex search" do
- @artist = FactoryBot.create(:artist, name: "bkub", url_string: "-http://bkub.com")
-
- get artist_urls_path(search: {
- artist: { name: "bkub" },
- url_matches: "*bkub*",
- is_active: "false",
- order: "created_at"
- })
-
- assert_response :success
+ context "using includes" do
+ should respond_to_search(artist: {name: "bkub"}).with { @artist.urls }
+ should respond_to_search(artist: {is_banned: "true"}).with { @banned.urls }
end
end
end
diff --git a/test/functional/artist_versions_controller_test.rb b/test/functional/artist_versions_controller_test.rb
index 143b8d196..d04ba86b8 100644
--- a/test/functional/artist_versions_controller_test.rb
+++ b/test/functional/artist_versions_controller_test.rb
@@ -3,18 +3,37 @@ require 'test_helper'
class ArtistVersionsControllerTest < ActionDispatch::IntegrationTest
context "An artist versions controller" do
setup do
- @user = create(:gold_user)
- @artist = as(@user) { create(:artist) }
+ @user = create(:gold_user, id: 100)
+ @builder = create(:builder_user, name: "danbo")
+ as(@builder) { @artist = create(:artist, name: "masao", url_string: "https://masao.deviantart.com") }
+ as(@user) { @artist.update(name: "masao_(deleted)", is_deleted: true) }
+ as(@builder) { @artist.update(name: "masao", is_deleted: false, group_name: "the_best", url_string: "https://www.deviantart.com/masao") }
end
- should "get the index page" do
- get_auth artist_versions_path, @user
- assert_response :success
- end
+ context "index action" do
+ setup do
+ @versions = @artist.versions
+ end
- should "get the index page when searching for something" do
- get_auth artist_versions_path(search: {name: @artist.name}), @user
- assert_response :success
+ should "render" do
+ get artist_versions_path
+ assert_response :success
+ end
+
+ should respond_to_search({}).with { @versions.reverse }
+ should respond_to_search(name: "masao").with { [@versions[2], @versions[0]] }
+ should respond_to_search(name_matches: "(deleted)").with { @versions[1] }
+ should respond_to_search(group_name_matches: "the_best").with { @versions[2] }
+ should respond_to_search(urls_include_any: "https://www.deviantart.com/masao").with { @versions[2] }
+ should respond_to_search(is_deleted: "true").with { @versions[1] }
+
+ context "using includes" do
+ should respond_to_search(updater_id: 100).with { @versions[1] }
+ should respond_to_search(updater_name: "danbo").with { [@versions[2], @versions[0]] }
+ should respond_to_search(updater: {level: User::Levels::BUILDER}).with { [@versions[2], @versions[0]] }
+ should respond_to_search(artist: {name: "masao"}).with { @versions.reverse }
+ should respond_to_search(artist: {name: "doesntexist"}).with { [] }
+ end
end
context "show action" do
diff --git a/test/functional/artists_controller_test.rb b/test/functional/artists_controller_test.rb
index 076d8fd41..11ebae670 100644
--- a/test/functional/artists_controller_test.rb
+++ b/test/functional/artists_controller_test.rb
@@ -28,6 +28,8 @@ class ArtistsControllerTest < ActionDispatch::IntegrationTest
@artist = create(:artist)
@masao = create(:artist, name: "masao", url_string: "http://www.pixiv.net/member.php?id=32777")
@artgerm = create(:artist, name: "artgerm", url_string: "http://artgerm.deviantart.com/")
+ @wiki = create(:wiki_page, title: "artgerm")
+ @post = create(:post, tag_string: "masao")
end
end
@@ -130,7 +132,7 @@ class ArtistsControllerTest < ActionDispatch::IntegrationTest
end
context "index action" do
- should "get the index page" do
+ should "render" do
get artists_path
assert_response :success
end
@@ -142,26 +144,36 @@ class ArtistsControllerTest < ActionDispatch::IntegrationTest
end
context "when searching the index page" do
+ setup do
+ @deleted = create(:artist, is_deleted: true)
+ @banned = create(:artist, is_banned: true)
+ end
+
should "find artists by name" do
get artists_path(name: "masao", format: "json")
assert_artist_found("masao")
end
- should "find artists by image URL" do
- get artists_path(search: { url_matches: "http://i2.pixiv.net/img04/img/syounen_no_uta/46170939_m.jpg" }, format: "json")
- assert_artist_found("masao")
+ should respond_to_search({}).with { [@banned, @deleted, @artgerm, @masao, @artist] }
+ should respond_to_search(name: "masao").with { @masao }
+ should respond_to_search(is_banned: "true").with { @banned }
+ should respond_to_search(is_deleted: "true").with { @deleted }
+ should respond_to_search(url_matches: "http://i2.pixiv.net/img04/img/syounen_no_uta/46170939_m.jpg").with { @masao }
+ should respond_to_search(url_matches: "http://www.pixiv.net/member_illust.php?mode=medium&illust_id=46170939").with { @masao }
+
+ context "ignoring whitespace" do
+ should respond_to_search(url_matches: " http://www.pixiv.net/member_illust.php?mode=medium&illust_id=46170939 ").with { @masao }
end
- should "find artists by page URL" do
- url = "http://www.pixiv.net/member_illust.php?mode=medium&illust_id=46170939"
- get artists_path(search: { url_matches: url }, format: "json")
- assert_artist_found("masao")
- end
-
- should "ignore whitespace when searching by URL" do
- url = " http://www.pixiv.net/member_illust.php?mode=medium&illust_id=46170939 "
- get artists_path(search: { url_matches: url }, format: "json")
- assert_artist_found("masao")
+ context "using includes" do
+ should respond_to_search(has_wiki_page: "true").with { @artgerm }
+ should respond_to_search(has_wiki_page: "false").with { [@banned, @deleted, @masao, @artist] }
+ should respond_to_search(has_tag: "true").with { @masao }
+ should respond_to_search(has_tag: "false").with { [@banned, @deleted, @artgerm, @artist] }
+ should respond_to_search(has_urls: "true").with { [@artgerm, @masao] }
+ should respond_to_search(has_urls: "false").with { [@banned, @deleted, @artist] }
+ should respond_to_search(urls: {url: "http://www.pixiv.net/member.php?id=32777"}).with { @masao }
+ should respond_to_search(urls: {normalized_url: "http://www.deviantart.com/artgerm/"}).with { @artgerm }
end
end
end
diff --git a/test/functional/bans_controller_test.rb b/test/functional/bans_controller_test.rb
index 629ae922a..f2168b420 100644
--- a/test/functional/bans_controller_test.rb
+++ b/test/functional/bans_controller_test.rb
@@ -3,8 +3,11 @@ require 'test_helper'
class BansControllerTest < ActionDispatch::IntegrationTest
context "A bans controller" do
setup do
- @mod = create(:moderator_user)
- @ban = create(:ban)
+ @mod = create(:moderator_user, name: "danbo")
+ @admin = create(:admin_user)
+ @user = create(:member_user, id: 999, name: "cirno")
+
+ as(@mod) { @ban = create(:ban, reason: "blah", user: @user, banner: @mod) }
end
context "new action" do
@@ -29,16 +32,25 @@ class BansControllerTest < ActionDispatch::IntegrationTest
end
context "index action" do
+ setup do
+ as(@admin) { @admin_ban = create(:ban, user: build(:builder_user), banner: @admin, expires_at: 1.day.ago ) }
+ end
+
should "render" do
- get_auth bans_path, @mod
+ get bans_path
assert_response :success
end
- end
- context "search action" do
- should "render" do
- get_auth bans_path(search: { user_name: @ban.user.name }), @mod
- assert_response :success
+ should respond_to_search({}).with { [@admin_ban, @ban] }
+ should respond_to_search(reason_matches: "blah").with { @ban }
+ should respond_to_search(expired: "true").with { @admin_ban }
+
+ context "using includes" do
+ should respond_to_search(banner_name: "danbo").with { @ban }
+ should respond_to_search(banner: {level: User::Levels::ADMIN}).with { @admin_ban }
+ should respond_to_search(user_id: 999).with { @ban }
+ should respond_to_search(user: {name: "cirno"}).with { @ban }
+ should respond_to_search(user: {level: User::Levels::BUILDER}).with { @admin_ban }
end
end
@@ -55,7 +67,6 @@ class BansControllerTest < ActionDispatch::IntegrationTest
should "not allow mods to ban admins" do
assert_difference("Ban.count", 0) do
- @admin = create(:admin_user)
post_auth bans_path, @mod, params: { ban: { duration: 60, reason: "xxx", user_id: @admin.id }}
assert_response 403
diff --git a/test/functional/bulk_update_requests_controller_test.rb b/test/functional/bulk_update_requests_controller_test.rb
index b91a8e04c..5b91dd92f 100644
--- a/test/functional/bulk_update_requests_controller_test.rb
+++ b/test/functional/bulk_update_requests_controller_test.rb
@@ -3,10 +3,11 @@ require 'test_helper'
class BulkUpdateRequestsControllerTest < ActionDispatch::IntegrationTest
context "BulkUpdateRequestsController" do
setup do
- @user = create(:user)
+ @user = create(:user, id: 999)
@builder = create(:builder_user)
@admin = create(:admin_user)
- @bulk_update_request = create(:bulk_update_request, user: @user)
+ as(@admin) { @forum_topic = create(:forum_topic, id: 100, category_id: 0) }
+ as(@user) { @bulk_update_request = create(:bulk_update_request, user: @user, forum_topic: @forum_topic) }
end
context "#new" do
@@ -73,10 +74,31 @@ class BulkUpdateRequestsControllerTest < ActionDispatch::IntegrationTest
end
context "#index" do
+ setup do
+ @other_BUR = create(:bulk_update_request, user: @builder, script: "create alias cirno -> 9")
+ @rejected_BUR = create(:bulk_update_request, status: "rejected")
+ @approved_BUR = create(:bulk_update_request, status: "approved", approver: @admin)
+ end
+
should "render" do
get bulk_update_requests_path
assert_response :success
end
+
+ should respond_to_search({}).with { [@other_BUR, @bulk_update_request, @approved_BUR, @rejected_BUR] }
+ should respond_to_search(order: "id_desc").with { [@approved_BUR, @rejected_BUR, @other_BUR, @bulk_update_request] }
+ should respond_to_search(status: "pending").with { [@other_BUR, @bulk_update_request] }
+ should respond_to_search(script_matches: "cirno -> 9").with { @other_BUR }
+ should respond_to_search(tags_include_any: "cirno").with { @other_BUR }
+
+ context "using includes" do
+ should respond_to_search(forum_topic_id: 100).with { @bulk_update_request }
+ should respond_to_search(forum_topic: {category_id: 0}).with { @bulk_update_request }
+ should respond_to_search(user_id: 999).with { @bulk_update_request }
+ should respond_to_search(user: {level: User::Levels::BUILDER}).with { @other_BUR }
+ should respond_to_search(has_approver: "true").with { @approved_BUR }
+ should respond_to_search(has_approver: "false").with { [@other_BUR, @bulk_update_request, @rejected_BUR] }
+ end
end
context "#show" do
diff --git a/test/functional/comment_votes_controller_test.rb b/test/functional/comment_votes_controller_test.rb
index 5d2b713d8..20cf11ce3 100644
--- a/test/functional/comment_votes_controller_test.rb
+++ b/test/functional/comment_votes_controller_test.rb
@@ -3,9 +3,9 @@ require 'test_helper'
class CommentVotesControllerTest < ActionDispatch::IntegrationTest
context "A comment votes controller" do
setup do
- CurrentUser.user = @user = create(:user)
+ CurrentUser.user = @user = create(:user, name: "cirno")
CurrentUser.ip_addr = "127.0.0.1"
- @comment = create(:comment)
+ @comment = create(:comment, creator: @user)
end
teardown do
@@ -13,12 +13,36 @@ class CommentVotesControllerTest < ActionDispatch::IntegrationTest
CurrentUser.ip_addr = nil
end
- context "#index" do
- should "work" do
- create(:comment_vote, user: @user)
- get_auth comment_votes_path, @user
+ context "index action" do
+ setup do
+ @voter = create(:gold_user, name: "rumia")
+ @vote = as (@voter) { create(:comment_vote, comment: @comment, user: @voter) }
+ @negative_vote = create(:comment_vote, comment: @comment, score: -1)
+ @unrelated_vote = create(:comment_vote)
+ end
- assert_response :success
+ context "as a user" do
+ should "render" do
+ get_auth comment_votes_path, @user
+ assert_response :success
+ end
+
+ should respond_to_search({}).with { [] }
+ end
+
+ context "as a moderator" do
+ setup do
+ CurrentUser.user = create(:mod_user)
+ end
+
+ should respond_to_search({}).with { [@unrelated_vote, @negative_vote, @vote] }
+ should respond_to_search(score: -1).with { @negative_vote }
+
+ context "using includes" do
+ should respond_to_search(comment: {creator_name: "cirno"}).with { [@negative_vote, @vote] }
+ should respond_to_search(user_name: "rumia").with { @vote }
+ should respond_to_search(user: {level: User::Levels::GOLD}).with { @vote }
+ end
end
end
diff --git a/test/functional/comments_controller_test.rb b/test/functional/comments_controller_test.rb
index b0c74dbe5..048726ed0 100644
--- a/test/functional/comments_controller_test.rb
+++ b/test/functional/comments_controller_test.rb
@@ -4,8 +4,8 @@ class CommentsControllerTest < ActionDispatch::IntegrationTest
context "A comments controller" do
setup do
@mod = FactoryBot.create(:moderator_user)
- @user = FactoryBot.create(:member_user)
- @post = create(:post)
+ @user = FactoryBot.create(:member_user, name: "cirno")
+ @post = create(:post, id: 100)
CurrentUser.user = @user
CurrentUser.ip_addr = "127.0.0.1"
@@ -87,10 +87,31 @@ class CommentsControllerTest < ActionDispatch::IntegrationTest
end
end
- should "render by comment" do
- @comment = as(@user) { create(:comment, post: @post) }
- get comments_path(group_by: "comment")
- assert_response :success
+ context "grouped by comment" do
+ setup do
+ @user_comment = create(:comment, post: @post, score: 10, do_not_bump_post: true, creator: @user)
+ @mod_comment = create(:comment, post: build(:post, tag_string: "touhou"), body: "blah", is_sticky: true, creator: @mod)
+ @deleted_comment = create(:comment, is_deleted: true)
+ end
+
+ should "render" do
+ get comments_path(group_by: "comment")
+ assert_response :success
+ end
+
+ should respond_to_search({}, other_params: {group_by: "comment"}).with { [@deleted_comment, @mod_comment, @user_comment] }
+ should respond_to_search(body_matches: "blah").with { @mod_comment }
+ should respond_to_search(score: 10).with { @user_comment }
+ should respond_to_search(is_sticky: "true").with { @mod_comment }
+ should respond_to_search(do_not_bump_post: "true").with { @user_comment }
+ should respond_to_search(is_deleted: "true").with { @deleted_comment }
+
+ context "using includes" do
+ should respond_to_search(post_id: 100).with { @user_comment }
+ should respond_to_search(post_tags_match: "touhou").with { @mod_comment }
+ should respond_to_search(creator_name: "cirno").with { @user_comment }
+ should respond_to_search(creator: {level: User::Levels::MODERATOR}).with { @mod_comment }
+ end
end
context "for atom feeds" do
diff --git a/test/functional/dmails_controller_test.rb b/test/functional/dmails_controller_test.rb
index 5c27628a7..963868a64 100644
--- a/test/functional/dmails_controller_test.rb
+++ b/test/functional/dmails_controller_test.rb
@@ -3,9 +3,9 @@ require 'test_helper'
class DmailsControllerTest < ActionDispatch::IntegrationTest
context "The dmails controller" do
setup do
- @user = create(:user, unread_dmail_count: 1)
- @unrelated_user = create(:user)
- @dmail = create(:dmail, owner: @user)
+ @user = create(:user, id: 999, unread_dmail_count: 1)
+ @unrelated_user = create(:moderator_user, id: 1000, name: "reimu")
+ @dmail = create(:dmail, owner: @user, from: @user)
end
teardown do
@@ -40,28 +40,41 @@ class DmailsControllerTest < ActionDispatch::IntegrationTest
end
context "index action" do
- should "show dmails owned by the current user by sent" do
- get_auth dmails_path, @user, params: {:search => {:owner_id => @dmail.owner_id, :folder => "sent"}}
+ setup do
+ CurrentUser.user = @user
+ @received_dmail = create(:dmail, owner: @user, body: "blah", to: @user, from: @unrelated_user, is_read: true)
+ @deleted_dmail = create(:dmail, owner: @user, title: "UMAD", to: @unrelated_user, from: @user, is_deleted: true)
+ @unrelated_dmail = create(:dmail, owner: @unrelated_user, from: @unrelated_user)
+ end
+
+ should "render" do
+ get_auth dmails_path, @user
assert_response :success
end
- should "show dmails owned by the current user by received" do
- get_auth dmails_path, @user, params: {:search => {:owner_id => @dmail.owner_id, :folder => "received"}}
- assert_response :success
+ should respond_to_search({}).with { [@deleted_dmail, @received_dmail, @dmail] }
+ should respond_to_search(folder: "sent").with { @dmail }
+ should respond_to_search(folder: "received").with { @received_dmail }
+ should respond_to_search(title_matches: "UMAD").with { @deleted_dmail }
+ should respond_to_search(message_matches: "blah").with { @received_dmail }
+ should respond_to_search(is_read: "true").with { @received_dmail }
+ should respond_to_search(is_deleted: "true").with { @deleted_dmail }
+
+ context "using includes" do
+ should respond_to_search(to_id: 1000).with { @deleted_dmail }
+ should respond_to_search(from_id: 999).with { [@deleted_dmail, @dmail] }
+ should respond_to_search(from_name: "reimu").with { @received_dmail }
+ should respond_to_search(from: {level: User::Levels::MODERATOR}).with { @received_dmail }
end
- should "not show dmails not owned by the current user" do
- get_auth dmails_path, @user, params: {:search => {:owner_id => @dmail.owner_id}}
- assert_response :success
- end
+ context "as a banned user" do
+ setup do
+ as(create(:admin_user)) do
+ create(:ban, user: @user)
+ end
- should "work for banned users" do
- as(create(:admin_user)) do
- create(:ban, :user => @user)
+ should respond_to_search({}).with { [@received_dmail, @dmail] }
end
- get_auth dmails_path, @dmail.owner, params: {:search => {:owner_id => @dmail.owner_id, :folder => "sent"}}
-
- assert_response :success
end
end
diff --git a/test/functional/dtext_links_controller_test.rb b/test/functional/dtext_links_controller_test.rb
index 17f6f274a..366a1b510 100644
--- a/test/functional/dtext_links_controller_test.rb
+++ b/test/functional/dtext_links_controller_test.rb
@@ -1,12 +1,30 @@
require "test_helper"
class DtextLinksControllerTest < ActionDispatch::IntegrationTest
+ setup do
+ @user = create(:user)
+ as(@user) do
+ @wiki = create(:wiki_page, title: "case", body: "[[test]]")
+ @forum = create(:forum_post, topic: build(:forum_topic, title: "blah"), body: "[[case]]")
+ create(:tag, name: "test")
+ end
+ end
+
context "index action" do
- should "work" do
- @user = create(:user)
- @wiki = as(@user) { create(:wiki_page, body: "[[test]]") }
+ should "render" do
get dtext_links_path
assert_response :success
end
+
+ should respond_to_search({}).with { @forum.dtext_links + @wiki.dtext_links }
+
+ context "using includes" do
+ should respond_to_search(model_type: "WikiPage").with { @wiki.dtext_links }
+ should respond_to_search(model_type: "ForumPost").with { @forum.dtext_links }
+ should respond_to_search(has_linked_tag: "true").with { @wiki.dtext_links }
+ should respond_to_search(has_linked_wiki: "true").with { @forum.dtext_links }
+ should respond_to_search(ForumPost: {topic: {title_matches: "blah"}}).with { @forum.dtext_links }
+ should respond_to_search(ForumPost: {topic: {title_matches: "nah"}}).with { [] }
+ end
end
end
diff --git a/test/functional/favorite_groups_controller_test.rb b/test/functional/favorite_groups_controller_test.rb
index 1b853dd0e..f9d0d32bb 100644
--- a/test/functional/favorite_groups_controller_test.rb
+++ b/test/functional/favorite_groups_controller_test.rb
@@ -8,10 +8,31 @@ class FavoriteGroupsControllerTest < ActionDispatch::IntegrationTest
end
context "index action" do
+ setup do
+ @mod_favgroup = create(:favorite_group, name: "monochrome", creator: build(:moderator_user, name: "fumimi"))
+ @private_favgroup = create(:favorite_group, creator: @user, is_public: false)
+ end
+
should "render" do
get favorite_groups_path
assert_response :success
end
+
+ should respond_to_search({}).with { [@mod_favgroup, @favgroup] }
+ should respond_to_search(name: "monochrome").with { @mod_favgroup }
+
+ context "using includes" do
+ should respond_to_search(creator_name: "fumimi").with { @mod_favgroup }
+ should respond_to_search(creator: {level: User::Levels::MEMBER}).with { @favgroup }
+ end
+
+ context "for private favorite groups as the creator" do
+ setup do
+ CurrentUser.user = @user
+ end
+
+ should respond_to_search(is_public: "false").with { @private_favgroup }
+ end
end
context "show action" do
diff --git a/test/functional/forum_post_votes_controller_test.rb b/test/functional/forum_post_votes_controller_test.rb
index 5d693d26b..952551cb4 100644
--- a/test/functional/forum_post_votes_controller_test.rb
+++ b/test/functional/forum_post_votes_controller_test.rb
@@ -3,22 +3,35 @@ require 'test_helper'
class ForumPostVotesControllerTest < ActionDispatch::IntegrationTest
context "The forum post votes controller" do
setup do
- @user = create(:user)
+ @user = create(:user, name: "cirno")
@other_user = create(:user)
as(@user) do
- @forum_topic = create(:forum_topic)
- @forum_post = create(:forum_post, topic: @forum_topic)
+ @forum_post = create(:forum_post, body: "blah", creator: @user)
@bulk_update_request = create(:bulk_update_request, forum_post: @forum_post)
end
end
context "index action" do
+ setup do
+ @vote = create(:forum_post_vote, forum_post: @forum_post, creator: build(:user, name: "rumia"), score: 1)
+ @negative_vote = create(:forum_post_vote, forum_post: @forum_post, score: -1)
+ @unrelated_vote = as (@user) { create(:forum_post_vote, score: 0) }
+ end
+
should "render" do
- @forum_post_vote = create(:forum_post_vote, creator: @user, forum_post: @forum_post)
get forum_post_votes_path
assert_response :success
end
+
+ should respond_to_search({}).with { [@unrelated_vote, @negative_vote, @vote] }
+ should respond_to_search(score: -1).with { @negative_vote }
+
+ context "using includes" do
+ should respond_to_search(creator_name: "rumia").with { @vote }
+ should respond_to_search(forum_post: {creator_name: "cirno"}).with { [@negative_vote, @vote] }
+ should respond_to_search(forum_post: {body_matches: "blah"}).with { [@negative_vote, @vote] }
+ end
end
context "create action" do
diff --git a/test/functional/forum_posts_controller_test.rb b/test/functional/forum_posts_controller_test.rb
index d6c643e52..41cde00d0 100644
--- a/test/functional/forum_posts_controller_test.rb
+++ b/test/functional/forum_posts_controller_test.rb
@@ -3,9 +3,9 @@ require 'test_helper'
class ForumPostsControllerTest < ActionDispatch::IntegrationTest
context "The forum posts controller" do
setup do
- @user = create(:user)
+ @user = create(:user, id: 999)
@other_user = create(:user)
- @mod = create(:moderator_user)
+ @mod = create(:moderator_user, name: "okuu")
@forum_topic = as(@user) { create(:forum_topic, title: "my forum topic", creator: @user) }
@forum_post = as(@user) { create(:forum_post, creator: @user, topic: @forum_topic, body: "alias xxx -> yyy") }
end
@@ -52,65 +52,61 @@ class ForumPostsControllerTest < ActionDispatch::IntegrationTest
end
context "index action" do
- should "list all forum posts" do
- get forum_posts_path
- assert_response :success
+ setup do
+ @admin = create(:admin_user)
+ @other_forum = as(@user) { create(:forum_post, body: "[[test]]", topic: build(:forum_topic, title: "my topic", category_id: 1)) }
+ @mod_forum = as(@mod) { create(:forum_post, creator: @mod, topic: build(:forum_topic, min_level: User::Levels::MODERATOR)) }
+ @admin_forum = as(@admin) { create(:forum_post, creator: @admin, topic: build(:forum_topic, min_level: User::Levels::ADMIN)) }
+ @unrelated_forum = as (@user) { create(:forum_post, is_deleted: true) }
+ as (@user) { create(:forum_post_vote, forum_post: @forum_post) }
+ create(:bulk_update_request, forum_post: @other_forum)
end
- context "with search conditions" do
- should "list all matching forum posts" do
- get forum_posts_path, params: { search: { body_matches: "xxx", topic_title_matches: "my forum topic" }}
- assert_response :success
- assert_select "#forum-post-#{@forum_post.id}"
- end
-
- should "list nothing for when the search matches nothing" do
- get forum_posts_path, params: {:search => {:body_matches => "bababa"}}
- assert_response :success
- assert_select "#forum-post-#{@forum_post.id}", false
- end
-
- should "list by creator id" do
- get forum_posts_path, params: {:search => {:creator_id => @user.id}}
- assert_response :success
- assert_select "#forum-post-#{@forum_post.id}"
- end
- end
-
- context "for posts in private topics" do
+ context "as a user" do
setup do
- @admin = create(:admin_user)
- @mod_post = as(@mod) { create(:forum_post, creator: @mod, topic: build(:forum_topic, min_level: User::Levels::MODERATOR)) }
- @admin_post = as(@admin) { create(:forum_post, creator: @admin, topic: build(:forum_topic, min_level: User::Levels::ADMIN)) }
+ CurrentUser.user = @user
end
- should "list only permitted posts for anons" do
- get forum_posts_path
-
+ should "render" do
+ get_auth comment_votes_path, @user
assert_response :success
- assert_select "#forum-post-#{@forum_post.id}"
- assert_select "#forum-post-#{@mod_post.id}", false
- assert_select "#forum-post-#{@admin_post.id}", false
end
- should "list only permitted posts for mods" do
- get_auth forum_posts_path, @mod
+ should respond_to_search({}).with { [@unrelated_forum, @other_forum, @forum_post] }
+ should respond_to_search(body_matches: "xxx").with { @forum_post }
+ should respond_to_search(body_matches: "bababa").with { [] }
+ should respond_to_search(is_deleted: "true").with { @unrelated_forum }
- assert_response :success
- assert_select "#forum-post-#{@forum_post.id}"
- assert_select "#forum-post-#{@mod_post.id}"
- assert_select "#forum-post-#{@admin_post.id}", false
+ context "using includes" do
+ should respond_to_search(topic: {title_matches: "my forum topic"}).with { @forum_post }
+ should respond_to_search(topic: {category_id: 1}).with { @other_forum }
+ should respond_to_search(has_bulk_update_request: "true").with { @other_forum }
+ should respond_to_search(has_votes: "true").with { @forum_post }
+ should respond_to_search(has_dtext_links: "true").with { @other_forum }
+ should respond_to_search(creator_id: 999).with { @forum_post }
+ should respond_to_search(creator: {name: "okuu"}).with { [] }
+ end
+ end
+
+ context "as a moderator" do
+ setup do
+ CurrentUser.user = @mod
end
- should "list only permitted posts for admins" do
- get_auth forum_posts_path, @admin
+ should respond_to_search({}).with { [@unrelated_forum, @mod_forum, @other_forum, @forum_post] }
- assert_response :success
- assert_select "#forum-post-#{@forum_post.id}"
- assert_select "#forum-post-#{@mod_post.id}"
- assert_select "#forum-post-#{@admin_post.id}"
+ context "using includes" do
+ should respond_to_search(creator: {name: "okuu"}).with { @mod_forum }
end
end
+
+ context "as an admin" do
+ setup do
+ CurrentUser.user = @admin
+ end
+
+ should respond_to_search({}).with { [@unrelated_forum, @admin_forum, @mod_forum, @other_forum, @forum_post] }
+ end
end
context "show action" do
diff --git a/test/functional/forum_topics_controller_test.rb b/test/functional/forum_topics_controller_test.rb
index 4b3a0e2e4..06e7d0807 100644
--- a/test/functional/forum_topics_controller_test.rb
+++ b/test/functional/forum_topics_controller_test.rb
@@ -1,15 +1,18 @@
require 'test_helper'
class ForumTopicsControllerTest < ActionDispatch::IntegrationTest
+ def default_search_order(items)
+ ->{ items.each { |val| val.reload }.sort_by(&:updated_at).reverse }
+ end
+
context "The forum topics controller" do
setup do
@user = create(:user)
@other_user = create(:user)
- @mod = create(:moderator_user)
+ @mod = create(:moderator_user, name: "okuu")
as(@user) do
- @forum_topic = create(:forum_topic, creator: @user, title: "my forum topic")
- @forum_post = create(:forum_post, creator: @user, topic: @forum_topic, body: "xxx")
+ @forum_topic = create(:forum_topic, creator: @user, title: "my forum topic", original_post: build(:forum_post, creator: @user, topic: @forum_topic, body: "xxx"))
end
end
@@ -88,25 +91,26 @@ class ForumTopicsControllerTest < ActionDispatch::IntegrationTest
context "index action" do
setup do
as(@user) do
- @topic1 = create(:forum_topic, is_sticky: true, creator: @user)
- @topic2 = create(:forum_topic, creator: @user)
- @post1 = create(:forum_post, topic: @topic1, creator: @user, body: "xxx")
- @post2 = create(:forum_post, topic: @topic2, creator: @user, body: "xxx")
+ @sticky_topic = create(:forum_topic, is_sticky: true, creator: @user, original_post: build(:forum_post))
+ @other_topic = create(:forum_topic, creator: @user, original_post: build(:forum_post))
end
+ @mod_topic = as(@mod) { create(:forum_topic, creator: @mod, min_level: User::Levels::MODERATOR, original_post: build(:forum_post)) }
+ create(:bulk_update_request, forum_topic: @forum_topic)
+ create(:tag_alias, forum_topic: @other_topic)
end
should "list public forum topics for members" do
get forum_topics_path
assert_response :success
- assert_select "a.forum-post-link", count: 1, text: @topic1.title
- assert_select "a.forum-post-link", count: 1, text: @topic2.title
+ assert_select "a.forum-post-link", count: 1, text: @sticky_topic.title
+ assert_select "a.forum-post-link", count: 1, text: @other_topic.title
end
should "not list stickied topics first for JSON responses" do
get forum_topics_path, params: {format: :json}
forum_topics = JSON.parse(response.body)
- assert_equal([@topic2.id, @topic1.id, @forum_topic.id], forum_topics.map {|t| t["id"]})
+ assert_equal(default_search_order([@other_topic, @sticky_topic, @forum_topic]).call.map(&:id), forum_topics.map {|t| t["id"]})
end
should "render for atom feed" do
@@ -117,44 +121,59 @@ class ForumTopicsControllerTest < ActionDispatch::IntegrationTest
should "render for a sitemap" do
get forum_topics_path(format: :sitemap)
assert_response :success
- assert_equal(ForumTopic.count, response.parsed_body.css("urlset url loc").size)
+ assert_equal(ForumTopic.visible(User.anonymous).count, response.parsed_body.css("urlset url loc").size)
end
context "with private topics" do
should "not show private topics to unprivileged users" do
- as(@user) { @topic2.update!(min_level: User::Levels::MODERATOR) }
+ as(@user) { @other_topic.update!(min_level: User::Levels::MODERATOR) }
get forum_topics_path
assert_response :success
- assert_select "a.forum-post-link", count: 1, text: @topic1.title
- assert_select "a.forum-post-link", count: 0, text: @topic2.title
+ assert_select "a.forum-post-link", count: 1, text: @sticky_topic.title
+ assert_select "a.forum-post-link", count: 0, text: @other_topic.title
end
should "show private topics to privileged users" do
- as(@user) { @topic2.update!(min_level: User::Levels::MODERATOR) }
+ as(@user) { @other_topic.update!(min_level: User::Levels::MODERATOR) }
get_auth forum_topics_path, @mod
assert_response :success
- assert_select "a.forum-post-link", count: 1, text: @topic1.title
- assert_select "a.forum-post-link", count: 1, text: @topic2.title
+ assert_select "a.forum-post-link", count: 1, text: @sticky_topic.title
+ assert_select "a.forum-post-link", count: 1, text: @other_topic.title
end
end
context "with search conditions" do
- should "list all matching forum topics" do
- get forum_topics_path, params: {:search => {:title_matches => "forum"}}
- assert_response :success
- assert_select "a.forum-post-link", @forum_topic.title
- assert_select "a.forum-post-link", count: 0, text: @topic1.title
- assert_select "a.forum-post-link", count: 0, text: @topic2.title
+ context "as a user" do
+ setup do
+ CurrentUser.user = @user
+ end
+
+ should respond_to_search({}).with { default_search_order([@sticky_topic, @other_topic, @forum_topic]) }
+ should respond_to_search(order: "id").with { [@other_topic, @sticky_topic, @forum_topic] }
+ should respond_to_search(title_matches: "forum").with { @forum_topic }
+ should respond_to_search(title_matches: "bababa").with { [] }
+ should respond_to_search(is_sticky: "true").with { @sticky_topic }
+
+ context "using includes" do
+ should respond_to_search(forum_posts: {body_matches: "xxx"}).with { @forum_topic }
+ should respond_to_search(has_bulk_update_requests: "true").with { @forum_topic }
+ should respond_to_search(has_tag_aliases: "true").with { @other_topic }
+ should respond_to_search(creator_name: "okuu").with { [] }
+ end
end
- should "list nothing for when the search matches nothing" do
- get forum_topics_path, params: {:search => {:title_matches => "bababa"}}
- assert_response :success
- assert_select "a.forum-post-link", count: 0, text: @forum_topic.title
- assert_select "a.forum-post-link", count: 0, text: @topic1.title
- assert_select "a.forum-post-link", count: 0, text: @topic2.title
+ context "as a moderator" do
+ setup do
+ CurrentUser.user = @mod
+ end
+
+ should respond_to_search({}).with { default_search_order([@sticky_topic, @other_topic, @mod_topic, @forum_topic]) }
+
+ context "using includes" do
+ should respond_to_search(creator_name: "okuu").with { @mod_topic }
+ end
end
end
diff --git a/test/functional/ip_bans_controller_test.rb b/test/functional/ip_bans_controller_test.rb
index bd6465afc..2ac8f3075 100644
--- a/test/functional/ip_bans_controller_test.rb
+++ b/test/functional/ip_bans_controller_test.rb
@@ -3,8 +3,8 @@ require 'test_helper'
class IpBansControllerTest < ActionDispatch::IntegrationTest
context "The ip bans controller" do
setup do
- @admin = create(:admin_user)
- @ip_ban = create(:ip_ban)
+ @admin = create(:admin_user, name: "yukari")
+ @ip_ban = create(:ip_ban, ip_addr: "6.7.8.9")
end
context "new action" do
@@ -24,21 +24,34 @@ class IpBansControllerTest < ActionDispatch::IntegrationTest
should "log a mod action" do
post_auth ip_bans_path, @admin, params: { ip_ban: { ip_addr: "1.2.3.4", reason: "xyz" }}
- assert_equal("ip_ban_create", ModAction.last.category)
+ assert_equal("ip_ban_create", ModAction.last&.category)
end
end
context "index action" do
+ setup do
+ CurrentUser.user = @admin
+ @subnet_ban = create(:ip_ban, ip_addr: "2.0.0.0/24", creator: @admin)
+ @other_ban = create(:ip_ban, reason: "malware")
+ end
+
+ should "render access denied for anonymous users" do
+ get ip_bans_path
+ assert_response 403
+ end
+
should "render" do
get_auth ip_bans_path, @admin
assert_response :success
end
- context "with search parameters" do
- should "render" do
- get_auth ip_bans_path, @admin, params: {:search => {:ip_addr => "1.2.3.4"}}
- assert_response :success
- end
+ should respond_to_search({}).with { [@other_ban, @subnet_ban, @ip_ban] }
+ should respond_to_search(ip_addr: "6.7.8.9").with { @ip_ban }
+ should respond_to_search(reason_matches: "malware").with { @other_ban }
+
+ context "using includes" do
+ should respond_to_search(creator_name: "yukari").with { @subnet_ban }
+ should respond_to_search(creator: {level: User::Levels::ADMIN}).with { @subnet_ban }
end
end
diff --git a/test/functional/mod_actions_controller_test.rb b/test/functional/mod_actions_controller_test.rb
index 9052cdf36..eb97ca25c 100644
--- a/test/functional/mod_actions_controller_test.rb
+++ b/test/functional/mod_actions_controller_test.rb
@@ -2,6 +2,10 @@ require 'test_helper'
class ModActionsControllerTest < ActionDispatch::IntegrationTest
context "The mod actions controller" do
+ setup do
+ @mod_action = create(:mod_action, description: "blah", category: "post_delete")
+ end
+
context "index action" do
setup do
@ban = create(:mod_action, category: :post_ban)
@@ -13,6 +17,15 @@ class ModActionsControllerTest < ActionDispatch::IntegrationTest
assert_response :success
end
+ should respond_to_search({}).with { [@unrelated_action, @promote_action, @mod_action] }
+ should respond_to_search(category: ModAction.categories["user_level_change"]).with { @promote_action }
+ should respond_to_search(description_matches: "blah").with { @mod_action }
+
+ context "using includes" do
+ should respond_to_search(creator_name: "rumia").with { @promote_action }
+ should respond_to_search(creator: {level: User::Levels::BUILDER}).with { @promote_action }
+ end
+
context "category enum searches" do
should respond_to_search(category: "post_ban").with { [@ban] }
should respond_to_search(category: "post_unban").with { [@unban] }
@@ -23,6 +36,7 @@ class ModActionsControllerTest < ActionDispatch::IntegrationTest
should respond_to_search(category_id: "44").with { [@ban] }
should respond_to_search(category_id: "44,45").with { [@unban, @ban] }
should respond_to_search(category_id: ">=44").with { [@unban, @ban] }
+
end
end
diff --git a/test/functional/moderation_reports_controller_test.rb b/test/functional/moderation_reports_controller_test.rb
index 568e6e81b..ff9af203c 100644
--- a/test/functional/moderation_reports_controller_test.rb
+++ b/test/functional/moderation_reports_controller_test.rb
@@ -9,9 +9,8 @@ class ModerationReportsControllerTest < ActionDispatch::IntegrationTest
as(@spammer) do
@dmail = create(:dmail, from: @spammer, owner: @user, to: @user)
- @comment = create(:comment, creator: @spammer)
- @forum_topic = create(:forum_topic, creator: @spammer)
- @forum_post = create(:forum_post, topic: @forum_topic, creator: @spammer)
+ @comment = create(:comment, id: 1234, creator: @spammer)
+ @forum_post = create(:forum_post, topic: build(:forum_topic), body: "xxx", creator: @spammer)
end
end
@@ -29,24 +28,37 @@ class ModerationReportsControllerTest < ActionDispatch::IntegrationTest
context "index action" do
setup do
- create(:moderation_report, model: @comment, creator: @user)
+ @comment_report = create(:moderation_report, model: @comment, creator: @user)
+ @forum_report = create(:moderation_report, model: @forum_post, creator: @user)
+ @dmail_report = create(:moderation_report, reason: "spam", model: @dmail, creator: build(:builder_user, name: "daiyousei", created_at: 2.weeks.ago))
end
- should "render the access denied page for members" do
- get_auth moderation_reports_path, @user
- assert_response 403
+ context "as a user" do
+ should "render the access denied page" do
+ get_auth moderation_reports_path, @user
+ assert_response 403
+ end
end
- should "render for mods" do
- get_auth moderation_reports_path, @mod
- assert_response :success
- end
+ context "as a moderator" do
+ setup do
+ CurrentUser.user = @mod
+ end
- context "with search parameters" do
should "render" do
- get_auth moderation_reports_path, @mod, params: {:search => {:model_id => @comment.id}}
+ get_auth moderation_reports_path, @mod
assert_response :success
end
+
+ should respond_to_search({}).with { [@dmail_report, @forum_report, @comment_report] }
+ should respond_to_search(reason_matches: "spam").with { @dmail_report }
+
+ context "using includes" do
+ should respond_to_search(model_id: 1234).with { @comment_report }
+ should respond_to_search(model_type: "ForumPost").with { @forum_report }
+ should respond_to_search(ForumPost: {body_matches: "xxx"}).with { @forum_report }
+ should respond_to_search(creator_name: "daiyousei").with { @dmail_report }
+ end
end
end
diff --git a/test/functional/note_versions_controller_test.rb b/test/functional/note_versions_controller_test.rb
index cbc100c99..22b5da38d 100644
--- a/test/functional/note_versions_controller_test.rb
+++ b/test/functional/note_versions_controller_test.rb
@@ -3,23 +3,34 @@ require 'test_helper'
class NoteVersionsControllerTest < ActionDispatch::IntegrationTest
context "The note versions controller" do
setup do
- @user = create(:user)
- @user_2 = create(:user)
+ @user = create(:user, id: 100)
+ @user_2 = create(:user, name: "cirno")
- as(@user) { @note = create(:note) }
- as(@user_2) { @note.update(body: "1 2") }
- as(@user) { @note.update(body: "1 2 3") }
+ as(@user) { @note = create(:note, id: 101) }
+ as(@user_2) { @note.update(body: "blah", is_active: false) }
+ as(@user) { @note.update(body: "1 2 3", is_active: true) }
end
context "index action" do
- should "list all versions" do
+ setup do
+ @versions = @note.versions
+ end
+
+ should "render" do
get note_versions_path
assert_response :success
end
- should "list all versions that match the search criteria" do
- get note_versions_path, params: {:search => {:updater_id => @user_2.id}}
- assert_response :success
+ should respond_to_search({}).with { @versions.reverse }
+ should respond_to_search(body_matches: "blah").with { @versions[1] }
+ should respond_to_search(version: 1).with { @versions[0] }
+ should respond_to_search(is_active: "false").with { @versions[1] }
+
+ context "using includes" do
+ should respond_to_search(note_id: 101).with { @versions.reverse }
+ should respond_to_search(note_id: 102).with { [] }
+ should respond_to_search(updater_id: 100).with { [@versions[2], @versions[0]] }
+ should respond_to_search(updater: {name: "cirno"}).with { @versions[1] }
end
end
diff --git a/test/functional/notes_controller_test.rb b/test/functional/notes_controller_test.rb
index 8bae95026..1acb91d36 100644
--- a/test/functional/notes_controller_test.rb
+++ b/test/functional/notes_controller_test.rb
@@ -8,24 +8,25 @@ class NotesControllerTest < ActionDispatch::IntegrationTest
end
context "index action" do
- should "list all notes" do
+ setup do
+ as(@user) do
+ @post_note = create(:note, post: build(:post, id: 2001, tag_string: "touhou"))
+ @deleted_note = create(:note, is_active: false)
+ end
+ end
+
+ should "render" do
get notes_path
assert_response :success
end
- should "list all notes (with search)" do
- params = {
- group_by: "note",
- search: {
- body_matches: "000",
- is_active: true,
- post_id: @note.post_id,
- post_tags_match: @note.post.tag_array.first
- }
- }
+ should respond_to_search({}).with { [@deleted_note, @post_note, @note] }
+ should respond_to_search(body_matches: "000").with { @note }
+ should respond_to_search(is_active: "true").with { [@post_note, @note] }
- get notes_path, params: params
- assert_response :success
+ context "using includes" do
+ should respond_to_search(post_id: 2001).with { @post_note }
+ should respond_to_search(post_tags_match: "touhou").with { @post_note }
end
end
diff --git a/test/functional/post_appeals_controller_test.rb b/test/functional/post_appeals_controller_test.rb
index a8dcc1607..9c1795f1f 100644
--- a/test/functional/post_appeals_controller_test.rb
+++ b/test/functional/post_appeals_controller_test.rb
@@ -3,7 +3,8 @@ require 'test_helper'
class PostAppealsControllerTest < ActionDispatch::IntegrationTest
context "The post appeals controller" do
setup do
- @user = create(:user)
+ @user = create(:user, name: "orin")
+ @post = create(:post, id: 101, is_deleted: true)
end
context "new action" do
@@ -24,8 +25,10 @@ class PostAppealsControllerTest < ActionDispatch::IntegrationTest
context "index action" do
setup do
as(@user) do
- @post = create(:post, :is_deleted => true)
- @post_appeal = create(:post_appeal, :post => @post)
+ @post_appeal = create(:post_appeal, post: @post, creator: @user)
+ @unrelated_appeal = create(:post_appeal, reason: "Good.")
+ @resolved_appeal = create(:post_appeal)
+ @resolved_appeal.post.update(is_deleted: false)
end
end
@@ -34,16 +37,14 @@ class PostAppealsControllerTest < ActionDispatch::IntegrationTest
assert_response :success
end
- should "render for json" do
- get post_appeals_path, as: :json
- assert_response :success
- end
+ should respond_to_search({}).with { [@resolved_appeal, @unrelated_appeal, @post_appeal] }
+ should respond_to_search(reason_matches: "Good.").with { @unrelated_appeal }
+ should respond_to_search(is_resolved: "true").with { @resolved_appeal }
- context "with search parameters" do
- should "render" do
- get_auth post_appeals_path, @user, params: {:search => {:post_id => @post_appeal.post_id}}
- assert_response :success
- end
+ context "using includes" do
+ should respond_to_search(post_id: 101).with { @post_appeal }
+ should respond_to_search(post: {is_deleted: "true"}).with { [@unrelated_appeal, @post_appeal] }
+ should respond_to_search(creator_name: "orin").with { @post_appeal }
end
end
diff --git a/test/functional/post_approvals_controller_test.rb b/test/functional/post_approvals_controller_test.rb
index 813cf62ef..9655733c5 100644
--- a/test/functional/post_approvals_controller_test.rb
+++ b/test/functional/post_approvals_controller_test.rb
@@ -3,7 +3,7 @@ require 'test_helper'
class PostApprovalsControllerTest < ActionDispatch::IntegrationTest
context "The post approvals controller" do
setup do
- @approver = create(:approver)
+ @approver = create(:approver, name: "eiki")
end
context "create action" do
@@ -60,11 +60,25 @@ class PostApprovalsControllerTest < ActionDispatch::IntegrationTest
end
context "index action" do
+ setup do
+ @post = create(:post, tag_string: "touhou", is_pending: true, uploader: build(:user, name: "komachi", created_at: 2.weeks.ago))
+ @post_approval = create(:post_approval, post: @post)
+ @user_approval = create(:post_approval, user: @approver)
+ @unrelated_approval = create(:post_approval)
+ end
+
should "render" do
- @approval = create(:post_approval)
get post_approvals_path
assert_response :success
end
+
+ should respond_to_search({}).with { [@unrelated_approval, @user_approval, @post_approval] }
+
+ context "using includes" do
+ should respond_to_search(user_name: "eiki").with { @user_approval }
+ should respond_to_search(post_tags_match: "touhou").with { @post_approval }
+ should respond_to_search(post: {uploader_name: "komachi"}).with { @post_approval }
+ end
end
end
end
diff --git a/test/functional/post_disapprovals_controller_test.rb b/test/functional/post_disapprovals_controller_test.rb
index 9260dda0f..513b16c67 100644
--- a/test/functional/post_disapprovals_controller_test.rb
+++ b/test/functional/post_disapprovals_controller_test.rb
@@ -3,9 +3,8 @@ require 'test_helper'
class PostDisapprovalsControllerTest < ActionDispatch::IntegrationTest
context "The post disapprovals controller" do
setup do
- @approver = create(:approver)
- @post = create(:post, is_pending: true)
- @post_disapproval = create(:post_disapproval, post: @post)
+ @approver = create(:approver, name: "eiki")
+ @post = create(:post, tag_string: "touhou", is_pending: true, uploader: build(:user, name: "marisa", created_at: 2.weeks.ago))
end
context "create action" do
@@ -40,16 +39,36 @@ class PostDisapprovalsControllerTest < ActionDispatch::IntegrationTest
end
context "index action" do
+ setup do
+ @post_disapproval = create(:post_disapproval, post: @post)
+ @user_disapproval = create(:post_disapproval, user: @approver)
+ @unrelated_disapproval = create(:post_disapproval, message: "bad")
+ end
+
+ should "render" do
+ get post_disapprovals_path
+ assert_response :success
+ end
+
+ should respond_to_search({}).with { [@unrelated_disapproval, @user_disapproval, @post_disapproval] }
+ should respond_to_search(message: "bad").with { @unrelated_disapproval }
+
+ context "using includes" do
+ should respond_to_search(post_tags_match: "touhou").with { @post_disapproval }
+ should respond_to_search(post: {uploader_name: "marisa"}).with { @post_disapproval }
+ should respond_to_search(user_name: "eiki").with { @user_disapproval }
+ end
+
should "allow mods to see disapprover names" do
get_auth post_disapprovals_path, create(:mod_user)
assert_response :success
- assert_select "tr#post-disapproval-#{@post_disapproval.id} .created-column a.user-member", true
+ assert_select "tr#post-disapproval-#{@post_disapproval.id} .created-column a.user-post-approver", true
end
should "not allow non-mods to see disapprover names" do
get post_disapprovals_path
assert_response :success
- assert_select "tr#post-disapproval-#{@post_disapproval.id} .created-column a.user-member", false
+ assert_select "tr#post-disapproval-#{@post_disapproval.id} .created-column a.user-post-approver", false
end
end
end
diff --git a/test/functional/post_flags_controller_test.rb b/test/functional/post_flags_controller_test.rb
index a4766c54f..fe74264ea 100644
--- a/test/functional/post_flags_controller_test.rb
+++ b/test/functional/post_flags_controller_test.rb
@@ -4,10 +4,10 @@ class PostFlagsControllerTest < ActionDispatch::IntegrationTest
context "The post flags controller" do
setup do
@user = create(:user)
- @flagger = create(:gold_user, created_at: 2.weeks.ago)
- @uploader = create(:mod_user, created_at: 2.weeks.ago)
+ @flagger = create(:gold_user, id: 999, created_at: 2.weeks.ago)
+ @uploader = create(:mod_user, name: "chen", created_at: 2.weeks.ago)
@mod = create(:mod_user)
- @post = create(:post, is_flagged: true, uploader: @uploader)
+ @post = create(:post, id: 101, is_flagged: true, uploader: @uploader)
@post_flag = create(:post_flag, post: @post, creator: @flagger)
end
@@ -26,6 +26,11 @@ class PostFlagsControllerTest < ActionDispatch::IntegrationTest
end
context "index action" do
+ setup do
+ @other_flag = create(:post_flag, post: build(:post, is_flagged: true, tag_string: "touhou"))
+ @unrelated_flag = create(:post_flag, reason: "poor quality")
+ end
+
should "render" do
get post_flags_path
assert_response :success
@@ -60,23 +65,46 @@ class PostFlagsControllerTest < ActionDispatch::IntegrationTest
assert_select "tr#post-flag-#{@post_flag.id} .flagged-column a.user-gold", true
end
- context "with search parameters" do
- should "render" do
- get_auth post_flags_path(search: { post_id: @post_flag.post_id }), @user
- assert_response :success
+ context "as a normal user" do
+ setup do
+ CurrentUser.user = @user
end
- should "hide flagged posts when the searcher is the uploader" do
- get_auth post_flags_path(search: { creator_id: @flagger.id }), @uploader
- assert_response :success
- assert_select "tr#post-flag-#{@post_flag.id}", false
+ should respond_to_search({}).with { [@unrelated_flag, @other_flag, @post_flag] }
+ should respond_to_search(reason_matches: "poor quality").with { @unrelated_flag }
+ should respond_to_search(category: "normal").with { [@unrelated_flag, @other_flag, @post_flag] }
+ should respond_to_search(category: "deleted").with { [] }
+
+ context "using includes" do
+ should respond_to_search(post_id: 101).with { @post_flag }
+ should respond_to_search(post_tags_match: "touhou").with { @other_flag }
+ should respond_to_search(post: {uploader_name: "chen"}).with { @post_flag }
+ should respond_to_search(creator_id: 999).with { [] }
+ end
+ end
+
+ context "when the user is the uploader" do
+ setup do
+ CurrentUser.user = @uploader
end
- should "show flagged posts when the searcher is not the uploader" do
- get_auth post_flags_path(search: { creator_id: @flagger.id }), @mod
- assert_response :success
- assert_select "tr#post-flag-#{@post_flag.id}", true
+ should respond_to_search(creator_id: 999).with { [] }
+ end
+
+ context "when the user is a mod and not the uploader" do
+ setup do
+ CurrentUser.user = @mod
end
+
+ should respond_to_search(creator_id: 999).with { @post_flag }
+ end
+
+ context "when the user is the flagger" do
+ setup do
+ CurrentUser.user = @flagger
+ end
+
+ should respond_to_search(creator_id: 999).with { @post_flag }
end
end
diff --git a/test/functional/post_replacements_controller_test.rb b/test/functional/post_replacements_controller_test.rb
index 26f41ccf5..e9021d1de 100644
--- a/test/functional/post_replacements_controller_test.rb
+++ b/test/functional/post_replacements_controller_test.rb
@@ -3,9 +3,9 @@ require 'test_helper'
class PostReplacementsControllerTest < ActionDispatch::IntegrationTest
context "The post replacements controller" do
setup do
- @mod = create(:moderator_user, can_approve_posts: true, created_at: 1.month.ago)
+ @mod = create(:moderator_user, name: "yukari", can_approve_posts: true, created_at: 1.month.ago)
as(@mod) do
- @post = create(:post, source: "https://google.com")
+ @post = create(:post, source: "https://google.com", tag_string: "touhou")
@post_replacement = create(:post_replacement, post: @post)
end
end
@@ -60,10 +60,23 @@ class PostReplacementsControllerTest < ActionDispatch::IntegrationTest
end
context "index action" do
+ setup do
+ as(create(:admin_user)) { @admin_replacement = create(:post_replacement, replacement_url: "https://danbooru.donmai.us") }
+ end
+
should "render" do
- get post_replacements_path, params: {format: "json"}
+ get post_replacements_path
assert_response :success
end
+
+ should respond_to_search({}).with { [@admin_replacement, @post_replacement] }
+ should respond_to_search(replacement_url_like: "*danbooru*").with { @admin_replacement }
+
+ context "using includes" do
+ should respond_to_search(post_tags_match: "touhou").with { @post_replacement }
+ should respond_to_search(creator: {level: User::Levels::ADMIN}).with { @admin_replacement }
+ should respond_to_search(creator_name: "yukari").with { @post_replacement }
+ end
end
end
end
diff --git a/test/functional/post_votes_controller_test.rb b/test/functional/post_votes_controller_test.rb
index 4024010d7..65313b022 100644
--- a/test/functional/post_votes_controller_test.rb
+++ b/test/functional/post_votes_controller_test.rb
@@ -3,17 +3,45 @@ require 'test_helper'
class PostVotesControllerTest < ActionDispatch::IntegrationTest
context "The post vote controller" do
setup do
- @user = create(:gold_user)
- @post = create(:post)
+ @user = create(:gold_user, name: "meiling")
+ @post = create(:post, tag_string: "dragon")
end
context "index action" do
- should "work" do
- as(@user) { create(:post_vote, post_id: @post.id, user_id: @user.id) }
- get_auth post_votes_path, @user
+ setup do
+ @admin = create(:admin_user)
+ as(@user) { @post_vote = create(:post_vote, post: @post, user: @user) }
+ as(@admin) { @admin_vote = create(:post_vote, post: @post, user: @admin) }
+ @unrelated_vote = create(:post_vote)
+ end
+ should "render" do
+ get_auth post_votes_path, @user
assert_response :success
end
+
+ context "as a user" do
+ setup do
+ CurrentUser.user = @user
+ end
+
+ should respond_to_search({}).with { @post_vote }
+ end
+
+ context "as a moderator" do
+ setup do
+ CurrentUser.user = @admin
+ end
+
+ should respond_to_search({}).with { [@unrelated_vote, @admin_vote, @post_vote] }
+ should respond_to_search(score: 1).with { [@unrelated_vote, @admin_vote, @post_vote].select{ |v| v.score == 1 } }
+
+ context "using includes" do
+ should respond_to_search(post_tags_match: "dragon").with { [@admin_vote, @post_vote] }
+ should respond_to_search(user_name: "meiling").with { @post_vote }
+ should respond_to_search(user: {level: User::Levels::ADMIN}).with { @admin_vote }
+ end
+ end
end
context "create action" do
diff --git a/test/functional/tag_aliases_controller_test.rb b/test/functional/tag_aliases_controller_test.rb
index f987f4580..4e6111d83 100644
--- a/test/functional/tag_aliases_controller_test.rb
+++ b/test/functional/tag_aliases_controller_test.rb
@@ -7,14 +7,42 @@ class TagAliasesControllerTest < ActionDispatch::IntegrationTest
end
context "index action" do
- should "list all tag alias" do
+ setup do
+ @user = create(:builder_user, name: "sakuya")
+ as (@user) do
+ @forum_topic = create(:forum_topic, title: "Touhou BUR")
+ @forum_post = create(:forum_post, topic: @forum_topic, body: "because")
+ end
+ @antecedent_tag = create(:copyright_tag, name: "touhou", post_count: 1000)
+ @consequent_tag = create(:copyright_tag, name: "touhou_project", post_count: 10)
+ @antecedent_wiki = create(:wiki_page, title: "touhou", body: "zun project")
+ @consequent_wiki = create(:wiki_page, title: "touhou_project")
+
+ @other_alias = create(:tag_alias, antecedent_name: "touhou", consequent_name: "touhou_project", creator: @user, status: "pending", forum_topic: @forum_topic, forum_post: @forum_post)
+ @unrelated_alias = create(:tag_alias)
+ end
+
+ should "render" do
get tag_aliases_path
assert_response :success
end
- should "list all tag_alias (with search)" do
- get tag_aliases_path, params: {:search => {:antecedent_name => "aaa"}}
- assert_response :success
+ should respond_to_search({}).with { [@unrelated_alias, @other_alias, @tag_alias] }
+ should respond_to_search(antecedent_name: "aaa").with { @tag_alias }
+ should respond_to_search(consequent_name: "bbb").with { @tag_alias }
+ should respond_to_search(status: "pending").with { @other_alias }
+
+ context "using includes" do
+ should respond_to_search(antecedent_tag: {post_count: 1000}).with { @other_alias }
+ should respond_to_search(consequent_tag: {category: Tag.categories.copyright}).with { @other_alias }
+ should respond_to_search(has_antecedent_tag: "true").with { @other_alias }
+ should respond_to_search(has_consequent_tag: "false").with { [@unrelated_alias, @tag_alias] }
+ should respond_to_search(antecedent_wiki: {body_matches: "zun project"}).with { @other_alias }
+ should respond_to_search(has_consequent_wiki: "true").with { @other_alias }
+ should respond_to_search(forum_topic: {title_matches: "Touhou BUR"}).with { @other_alias }
+ should respond_to_search(forum_post: {body: "because"}).with { @other_alias }
+ should respond_to_search(creator_name: "sakuya").with { @other_alias }
+ should respond_to_search(creator: {level: User::Levels::BUILDER}).with { @other_alias }
end
end
diff --git a/test/functional/tag_implications_controller_test.rb b/test/functional/tag_implications_controller_test.rb
index c43858be3..f7f9b4187 100644
--- a/test/functional/tag_implications_controller_test.rb
+++ b/test/functional/tag_implications_controller_test.rb
@@ -7,6 +7,44 @@ class TagImplicationsControllerTest < ActionDispatch::IntegrationTest
end
context "index action" do
+ setup do
+ @user = create(:builder_user, name: "sakuya")
+ as (@user) do
+ @forum_topic = create(:forum_topic, title: "Weapon BUR")
+ @forum_post = create(:forum_post, topic: @forum_topic, body: "because")
+ end
+ @antecedent_tag = create(:copyright_tag, name: "cannon", post_count: 10)
+ @consequent_tag = create(:copyright_tag, name: "weapon", post_count: 1000)
+ @antecedent_wiki = create(:wiki_page, title: "cannon", body: "made of fun")
+ @consequent_wiki = create(:wiki_page, title: "weapon")
+
+ @other_implication = create(:tag_implication, antecedent_name: "cannon", consequent_name: "weapon", creator: @user, status: "pending", forum_topic: @forum_topic, forum_post: @forum_post)
+ @unrelated_implication = create(:tag_implication)
+ end
+
+ should "render" do
+ get tag_implications_path
+ assert_response :success
+ end
+
+ should respond_to_search({}).with { [@unrelated_implication, @other_implication, @tag_implication] }
+ should respond_to_search(antecedent_name: "aaa").with { @tag_implication }
+ should respond_to_search(consequent_name: "bbb").with { @tag_implication }
+ should respond_to_search(status: "pending").with { @other_implication }
+
+ context "using includes" do
+ should respond_to_search(antecedent_tag: {post_count: 10}).with { @other_implication }
+ should respond_to_search(consequent_tag: {category: Tag.categories.copyright}).with { @other_implication }
+ should respond_to_search(has_antecedent_tag: "true").with { @other_implication }
+ should respond_to_search(has_consequent_tag: "false").with { [@unrelated_implication, @tag_implication] }
+ should respond_to_search(antecedent_wiki: {body_matches: "made of fun"}).with { @other_implication }
+ should respond_to_search(has_consequent_wiki: "true").with { @other_implication }
+ should respond_to_search(forum_topic: {title_matches: "Weapon BUR"}).with { @other_implication }
+ should respond_to_search(forum_post: {body: "because"}).with { @other_implication }
+ should respond_to_search(creator_name: "sakuya").with { @other_implication }
+ should respond_to_search(creator: {level: User::Levels::BUILDER}).with { @other_implication }
+ end
+
should "list all tag implications" do
get tag_implications_path
assert_response :success
diff --git a/test/functional/tags_controller_test.rb b/test/functional/tags_controller_test.rb
index 91eea376d..56dead38c 100644
--- a/test/functional/tags_controller_test.rb
+++ b/test/functional/tags_controller_test.rb
@@ -36,27 +36,43 @@ class TagsControllerTest < ActionDispatch::IntegrationTest
context "searching" do
setup do
as(@user) do
- @miku = create(:tag, name: "hatsune_miku", category: Tag.categories.character)
- @wokada = create(:tag, name: "wokada", category: Tag.categories.artist)
- @vocaloid = create(:tag, name: "vocaloid", category: Tag.categories.copyright)
+ @miku = create(:character_tag, name: "hatsune_miku")
+ @wokada = create(:artist_tag, name: "wokada")
+ @vocaloid = create(:copyright_tag, name: "vocaloid")
+ @weapon = create(:tag, name: "weapon")
@empty = create(:tag, name: "empty", post_count: 0)
create(:tag_alias, antecedent_name: "miku", consequent_name: "hatsune_miku")
- create(:wiki_page, title: "hatsune_miku")
+ create(:tag_implication, antecedent_name: "axe", consequent_name: "weapon")
+ create(:wiki_page, title: "hatsune_miku", body: "[[vocaloid]]")
create(:artist, name: "wokada")
end
end
+ should "render" do
+ get tags_path
+ assert_response :success
+ end
+
+ should respond_to_search({}).with { [@weapon, @vocaloid, @wokada, @miku, @tag] }
should respond_to_search(name_matches: "hatsune_miku").with { @miku }
should respond_to_search(name_normalize: "HATSUNE_MIKU ").with { @miku }
should respond_to_search(name_or_alias_matches: "miku").with { @miku }
should respond_to_search(fuzzy_name_matches: "miku_hatsune", order: "similarity").with { @miku }
should respond_to_search(name: "empty", hide_empty: "true").with { [] }
should respond_to_search(name: "empty", hide_empty: "false").with { [@empty] }
- should respond_to_search(name: "wokada", has_artist: "true").with { @wokada }
- should respond_to_search(name: "hatsune_miku", has_artist: "false").with { @miku }
- should respond_to_search(name: "hatsune_miku", has_wiki: "true").with { @miku }
- should respond_to_search(name: "vocaloid", has_wiki: "false").with { @vocaloid }
+
+ context "using includes" do
+ should respond_to_search(name: "wokada", has_artist: "true").with { @wokada }
+ should respond_to_search(name: "hatsune_miku", has_artist: "false").with { @miku }
+ should respond_to_search(name: "hatsune_miku", has_wiki_page: "true").with { @miku }
+ should respond_to_search(name: "vocaloid", has_wiki_page: "false").with { @vocaloid }
+ should respond_to_search(consequent_aliases: {antecedent_name: "miku"}).with { @miku }
+ should respond_to_search(consequent_implications: {antecedent_name: "axe"}).with { @weapon }
+ should respond_to_search(wiki_page: {body_matches: "*vocaloid*"}).with { @miku }
+ should respond_to_search(artist: {is_banned: "false"}).with { @wokada }
+ should respond_to_search(has_dtext_links: "true").with { @vocaloid }
+ end
end
end
diff --git a/test/functional/uploads_controller_test.rb b/test/functional/uploads_controller_test.rb
index e5fcc445c..17bbb071d 100644
--- a/test/functional/uploads_controller_test.rb
+++ b/test/functional/uploads_controller_test.rb
@@ -30,7 +30,7 @@ class UploadsControllerTest < ActionDispatch::IntegrationTest
context "The uploads controller" do
setup do
- @user = create(:contributor_user)
+ @user = create(:contributor_user, name: "marisa")
mock_iqdb_service!
end
@@ -173,8 +173,11 @@ class UploadsControllerTest < ActionDispatch::IntegrationTest
context "index action" do
setup do
as(@user) do
- @upload = create(:source_upload, tag_string: "foo bar")
- @upload2 = create(:source_upload, tag_string: "tagme", rating: "e")
+ @upload = create(:upload, tag_string: "foo bar", source: "http://example.com/foobar")
+ @post_upload = create(:source_upload, status: "completed", post: build(:post, tag_string: "touhou"), rating: "e")
+ end
+ as(create(:user)) do
+ @upload3 = create(:upload)
end
end
@@ -183,23 +186,28 @@ class UploadsControllerTest < ActionDispatch::IntegrationTest
assert_response :success
end
- context "with search parameters" do
- should "render" do
- search_params = {
- uploader_name: @upload.uploader.name,
- source_matches: @upload.source,
- rating: @upload.rating,
- status: @upload.status,
- server: @upload.server
- }
-
- get_auth uploads_path, @user, params: { search: search_params }
- assert_response :success
-
- get_auth uploads_path(format: :json), @user, params: { search: search_params }
- assert_response :success
- assert_equal(@upload.id, response.parsed_body.first["id"])
+ context "as an uploader" do
+ setup do
+ CurrentUser.user = @user
end
+
+ should respond_to_search({}).with { [@post_upload, @upload] }
+ should respond_to_search(source: "http://example.com/foobar").with { @upload }
+ should respond_to_search(rating: "e").with { @post_upload }
+ should respond_to_search(tag_string: "*foo*").with { @upload }
+
+ context "using includes" do
+ should respond_to_search(post_tags_match: "touhou").with { @post_upload }
+ should respond_to_search(uploader: {name: "marisa"}).with { [@post_upload, @upload] }
+ end
+ end
+
+ context "as an admin" do
+ setup do
+ CurrentUser.user = create(:admin_user)
+ end
+
+ should respond_to_search({}).with { [@upload3, @post_upload, @upload] }
end
end
diff --git a/test/functional/user_feedbacks_controller_test.rb b/test/functional/user_feedbacks_controller_test.rb
index 4c88f6f24..012f2be58 100644
--- a/test/functional/user_feedbacks_controller_test.rb
+++ b/test/functional/user_feedbacks_controller_test.rb
@@ -3,9 +3,9 @@ require 'test_helper'
class UserFeedbacksControllerTest < ActionDispatch::IntegrationTest
context "The user feedbacks controller" do
setup do
- @user = create(:user)
- @critic = create(:gold_user)
- @mod = create(:moderator_user)
+ @user = create(:user, name: "cirno")
+ @critic = create(:gold_user, name: "eiki")
+ @mod = create(:moderator_user, id: 1000)
@user_feedback = create(:user_feedback, user: @user, creator: @critic)
end
@@ -37,23 +37,43 @@ class UserFeedbacksControllerTest < ActionDispatch::IntegrationTest
end
context "index action" do
+ setup do
+ @other_feedback = create(:user_feedback, user: @user, creator: @mod, body: "blah", category: "neutral")
+ @unrelated_feedback = create(:user_feedback, is_deleted: true)
+ end
+
should "render" do
get_auth user_feedbacks_path, @user
assert_response :success
end
- should "not allow members to see deleted feedbacks" do
- as(@user) { @user_feedback.update!(is_deleted: true) }
- get_auth user_feedbacks_path, @user
+ context "as a user" do
+ setup do
+ CurrentUser.user = @user
+ end
- assert_response :success
- assert_select "tr#user-feedback-#{@user_feedback.id}", false
+ should respond_to_search({}).with { [@other_feedback, @user_feedback] }
+ should respond_to_search(body_matches: "blah").with { @other_feedback }
+ should respond_to_search(category: "positive").with { @user_feedback }
+ should respond_to_search(is_deleted: "true").with { [] }
+
+ context "using includes" do
+ should respond_to_search(creator_name: "eiki").with { @user_feedback }
+ should respond_to_search(creator_id: 1000).with { @other_feedback }
+ should respond_to_search(creator: {level: User::Levels::GOLD}).with { @user_feedback }
+ end
end
- context "with search parameters" do
- should "render" do
- get_auth user_feedbacks_path, @critic, params: {:search => {:user_id => @user.id}}
- assert_response :success
+ context "as a moderator" do
+ setup do
+ CurrentUser.user = @mod
+ end
+
+ should respond_to_search({}).with { [@unrelated_feedback, @other_feedback, @user_feedback] }
+ should respond_to_search(is_deleted: "true").with { @unrelated_feedback }
+
+ context "using includes" do
+ should respond_to_search(user_name: "cirno").with { [@other_feedback, @user_feedback] }
end
end
end
diff --git a/test/functional/users_controller_test.rb b/test/functional/users_controller_test.rb
index c342a98a0..694c38fe7 100644
--- a/test/functional/users_controller_test.rb
+++ b/test/functional/users_controller_test.rb
@@ -7,7 +7,14 @@ class UsersControllerTest < ActionDispatch::IntegrationTest
end
context "index action" do
- should "list all users" do
+ setup do
+ @first_user = User.find(1)
+ @mod_user = create(:moderator_user, name: "yukari")
+ @other_user = create(:builder_user, can_upload_free: true, inviter: @mod_user, created_at: 2.weeks.ago)
+ @uploader = create(:user, created_at: 2.weeks.ago)
+ end
+
+ should "render" do
get users_path
assert_response :success
end
@@ -28,14 +35,54 @@ class UsersControllerTest < ActionDispatch::IntegrationTest
assert_response 404
end
- should "list all users (with search)" do
- get users_path, params: {:search => {:name_matches => @user.name}}
- assert_response :success
- end
+ should respond_to_search({}).with { [@uploader, @other_user, @mod_user, @user, @first_user] }
+ should respond_to_search(min_level: User::Levels::BUILDER).with { [@other_user, @mod_user, @first_user] }
+ should respond_to_search(can_upload_free: "true").with { @other_user }
+ should respond_to_search(name_matches: "yukari").with { @mod_user }
- should "list all users (with blank search parameters)" do
- get users_path, params: { search: { inviter: { name_matches: "" }, level: "", name: "test" } }
- assert_redirected_to users_path(search: { name: "test" })
+ context "using includes" do
+ setup do
+ as (@uploader) { @post = create(:post, tag_string: "touhou", uploader: @uploader, is_flagged: true) }
+ as (@user) do
+ create(:note, post: @post)
+ create(:artist_commentary, post: @post)
+ create(:artist)
+ create(:wiki_page)
+ @forum = create(:forum_post, creator: @user, topic: build(:forum_topic, creator: @user))
+ end
+ as (@other_user) do
+ @other_post = create(:post, rating: "e", uploader: @other_user)
+ create(:post_appeal, creator: @other_user, post: @post)
+ create(:comment, creator: @other_user, post: @other_post)
+ create(:forum_post_vote, creator: @other_user, forum_post: @forum)
+ create(:tag_alias, creator: @other_user)
+ create(:tag_implication, creator: @other_user)
+ end
+ as (@mod_user) do
+ create(:post_approval, user: @mod_user, post: @post)
+ create(:user_feedback, user: @other_user, creator: @mod_user)
+ create(:ban, user: @other_user, banner: @mod_user)
+ end
+ end
+
+ should respond_to_search(has_artist_versions: "true").with { @user }
+ should respond_to_search(has_wiki_page_versions: "true").with { @user }
+ should respond_to_search(has_forum_topics: "true").with { @user }
+ should respond_to_search(has_forum_posts: "true").with { @user }
+ should respond_to_search(has_forum_post_votes: "true").with { @other_user }
+ should respond_to_search(has_feedback: "true").with { @other_user }
+ should respond_to_search(has_tag_aliases: "true").with { @other_user }
+ should respond_to_search(has_tag_implications: "true").with { @other_user }
+ should respond_to_search(has_bans: "true").with { @other_user }
+ should respond_to_search(has_artist_commentary_versions: "true").with { @user }
+ should respond_to_search(has_comments: "true").with { @other_user }
+ should respond_to_search(has_note_versions: "true").with { @user }
+ should respond_to_search(has_post_appeals: "true").with { @other_user }
+ should respond_to_search(has_post_approvals: "true").with { @mod_user }
+ should respond_to_search(has_posts: "true").with { [@uploader, @other_user] }
+ should respond_to_search(posts_tags_match: "touhou").with { @uploader }
+ should respond_to_search(posts: {rating: "e"}).with { @other_user }
+ should respond_to_search(inviter: {name: "yukari"}).with { @other_user }
end
end
diff --git a/test/functional/wiki_page_versions_controller_test.rb b/test/functional/wiki_page_versions_controller_test.rb
index 110021e59..ad897b10c 100644
--- a/test/functional/wiki_page_versions_controller_test.rb
+++ b/test/functional/wiki_page_versions_controller_test.rb
@@ -3,23 +3,34 @@ require 'test_helper'
class WikiPageVersionsControllerTest < ActionDispatch::IntegrationTest
context "The wiki page versions controller" do
setup do
- @user = create(:user)
- as(@user) do
- @wiki_page = create(:wiki_page)
- @wiki_page.update(:body => "1 2")
- @wiki_page.update(:body => "2 3")
- end
+ @user = create(:user, id: 100)
+ @builder = create(:builder_user, name: "nitori")
+ as(@user) { @wiki_page = create(:wiki_page, id: 101) }
+ as(@builder) { @wiki_page.update(title: "supreme", body: "blah", other_names: ["not_this"]) }
+ as(@user) { @wiki_page.update(body: "blah blah") }
end
context "index action" do
- should "list all versions" do
+ setup do
+ @versions = @wiki_page.versions
+ end
+
+ should "render" do
get wiki_page_versions_path
assert_response :success
end
- should "list all versions that match the search criteria" do
- get wiki_page_versions_path, params: {:search => {:wiki_page_id => @wiki_page.id}}
- assert_response :success
+ should respond_to_search({}).with { @versions.reverse }
+ should respond_to_search(title_matches: "supreme").with { [@versions[2], @versions[1]] }
+ should respond_to_search(body_matches: "blah").with { [@versions[2], @versions[1]] }
+ should respond_to_search(other_names_include_any: "not_this").with { [@versions[2], @versions[1]] }
+
+ context "using includes" do
+ should respond_to_search(wiki_page_id: 101).with { @versions.reverse }
+ should respond_to_search(wiki_page_id: 102).with { [] }
+ should respond_to_search(updater_id: 100).with { [@versions[2], @versions[0]] }
+ should respond_to_search(updater_name: "nitori").with { @versions[1] }
+ should respond_to_search(updater: {level: User::Levels::BUILDER}).with { @versions[1] }
end
end
diff --git a/test/functional/wiki_pages_controller_test.rb b/test/functional/wiki_pages_controller_test.rb
index 713b28e1e..5a4ad9c2b 100644
--- a/test/functional/wiki_pages_controller_test.rb
+++ b/test/functional/wiki_pages_controller_test.rb
@@ -14,11 +14,13 @@ class WikiPagesControllerTest < ActionDispatch::IntegrationTest
@deleted = create(:wiki_page, title: "deleted", is_deleted: true)
@vocaloid = create(:wiki_page, title: "vocaloid")
@miku = create(:wiki_page, title: "hatsune_miku", other_names: ["初音ミク"], body: "miku is a [[vocaloid]]")
- create(:tag, name: "hatsune_miku", category: Tag.categories.character)
+ @picasso = create(:wiki_page, title: "picasso")
+ create(:artist, name: "picasso", is_banned: true)
+ create(:character_tag, name: "hatsune_miku")
end
end
- should "list all wiki_pages" do
+ should "render" do
get wiki_pages_path
assert_response :success
end
@@ -34,19 +36,27 @@ class WikiPagesControllerTest < ActionDispatch::IntegrationTest
assert_redirected_to wiki_pages_path(search: { title_normalize: "tagme" }, redirect: true)
end
+ should respond_to_search({}).with { [@picasso, @miku, @vocaloid, @deleted, @tagme] }
should respond_to_search(title: "tagme").with { @tagme }
should respond_to_search(title: "tagme", order: "post_count").with { @tagme }
should respond_to_search(title_normalize: "TAGME ").with { @tagme }
- should respond_to_search(tag: { category: Tag.categories.character }).with { @miku }
- should respond_to_search(hide_deleted: "true").with { [@miku, @vocaloid, @tagme] }
+ should respond_to_search(hide_deleted: "true").with { [@picasso, @miku, @vocaloid, @tagme] }
should respond_to_search(linked_to: "vocaloid").with { @miku }
- should respond_to_search(not_linked_to: "vocaloid").with { [@vocaloid, @deleted, @tagme] }
+ should respond_to_search(not_linked_to: "vocaloid").with { [@picasso, @vocaloid, @deleted, @tagme] }
should respond_to_search(other_names_match: "初音ミク").with { @miku }
should respond_to_search(other_names_match: "初*").with { @miku }
should respond_to_search(other_names_present: "true").with { @miku }
- should respond_to_search(other_names_present: "false").with { [@vocaloid, @deleted, @tagme] }
+ should respond_to_search(other_names_present: "false").with { [@picasso, @vocaloid, @deleted, @tagme] }
+
+ context "using includes" do
+ should respond_to_search(has_tag: "true").with { @miku }
+ should respond_to_search(tag: { category: Tag.categories.character }).with { @miku }
+ should respond_to_search(has_dtext_links: "true").with { @miku }
+ should respond_to_search(has_artist: "true").with { @picasso }
+ should respond_to_search(artist: {is_banned: "true"}).with { @picasso }
+ end
end
context "search action" do
diff --git a/test/test_helpers/controller_helper.rb b/test/test_helpers/controller_helper.rb
index 716bfaa97..35796d6de 100644
--- a/test/test_helpers/controller_helper.rb
+++ b/test/test_helpers/controller_helper.rb
@@ -9,28 +9,37 @@ module ControllerHelper
# setup { @touhou = create(:tag, name: "touhou") }
# should respond_to_search(name: "touhou").with { @touhou }
#
- def respond_to_search(search_params)
- RespondToSearchMatcher.new(search_params)
+ def respond_to_search(search_params, other_params: {})
+ RespondToSearchMatcher.new(search_params, other_params)
end
- class RespondToSearchMatcher < Struct.new(:params)
+ class RespondToSearchMatcher < Struct.new(:params, :other_params)
def description
"should respond to a search for #{params}"
end
def matches?(subject, &block)
- search_params = { search: params }
+ search_params = other_params.merge({ search: params })
expected_items = @test_case.instance_eval(&@expected)
@test_case.instance_eval do
# calls e.g. "wiki_pages_path" if we're in WikiPagesControllerTest.
index_url = send("#{subject.controller_path}_path")
- get index_url, as: :json, params: search_params
+ # Allows for different authorization levels to be used, instead of just anonymous
+ if CurrentUser.user.present?
+ get_auth index_url, CurrentUser.user, as: :json, params: search_params
+ else
+ get index_url, as: :json, params: search_params
+ end
+ # Don't continue processing if there was an error
+ assert_response :success
+
+ # Some fields like :updated_at do not get finalized until later, so allow lambda functions
+ # to evaluate expressions like a sort after the network call has completed
+ expected_items = expected_items.call if expected_items.respond_to?(:call)
expected_ids = Array(expected_items).map(&:id)
responded_ids = response.parsed_body.map { |item| item["id"] }
-
- assert_response :success
assert_equal(expected_ids, responded_ids)
end
end
diff --git a/test/unit/bulk_update_request_test.rb b/test/unit/bulk_update_request_test.rb
index eb95c7418..c4763e8e1 100644
--- a/test/unit/bulk_update_request_test.rb
+++ b/test/unit/bulk_update_request_test.rb
@@ -83,7 +83,7 @@ class BulkUpdateRequestTest < ActiveSupport::TestCase
context "that has an invalid alias" do
setup do
- @alias1 = create(:tag_alias, creator: @admin)
+ @alias1 = create(:tag_alias, antecedent_name: "aaa", consequent_name: "bbb", creator: @admin)
@req = FactoryBot.build(:bulk_update_request, :script => "create alias bbb -> aaa")
end