From 58c3d2af13fef984c85db0f0080f4bd7921033ed Mon Sep 17 00:00:00 2001 From: albert Date: Sat, 16 Jul 2011 19:20:02 -0400 Subject: [PATCH] fixing tests --- Gemfile.lock | 33 +- app/assets/stylesheets/application.css.scss | 33 ++ app/controllers/ip_bans_controller.rb | 2 +- .../moderator/dashboards_controller.rb | 9 + app/controllers/notes_controller.rb | 2 +- app/helpers/moderator/dashboards_helper.rb | 17 + .../moderator/dashboard/queries/comment.rb | 14 + .../moderator/dashboard/queries/post.rb | 14 + .../dashboard/queries/post_appeal.rb | 30 ++ .../moderator/dashboard/queries/post_flag.rb | 31 ++ .../moderator/dashboard/queries/upload.rb | 13 + .../moderator/dashboard/queries/user.rb | 14 + app/logical/moderator/report.rb | 6 + app/logical/moderator_dashboard.rb | 54 ++++ app/logical/post_sets/favorite.rb | 2 +- app/logical/post_sets/pool.rb | 18 +- app/logical/post_sets/post.rb | 24 +- app/models/artist.rb | 1 + app/models/dmail.rb | 6 +- app/models/forum_post.rb | 2 +- app/models/janitor_trial.rb | 9 +- app/models/jobs/calculate_uploaded_tags.rb | 2 +- app/models/pool.rb | 3 +- app/models/post.rb | 78 ++--- app/models/post_flag.rb | 4 +- app/models/tag.rb | 24 +- app/models/upload.rb | 18 +- app/models/user.rb | 12 +- app/views/layouts/default.html.erb | 3 + app/views/moderator/dashboards/show.html.erb | 222 +++++++++++++ .../initializers/active_record_extensions.rb | 18 ++ config/routes.rb | 11 +- db/development_structure.sql | 21 +- db/migrate/20100204214746_create_posts.rb | 6 +- .../20100309211553_create_janitor_trials.rb | 1 + .../paginator/active_record_extension.rb | 2 +- lib/danbooru/paginator/pagination_error.rb | 6 + script/testing/reset_post_1.sh | 2 +- test/factories/upload.rb | 2 +- test/factories/user.rb | 10 +- test/unit/post_sets/favorite_test.rb | 58 +--- test/unit/post_sets/pool_test.rb | 39 +-- test/unit/post_sets/post_test.rb | 85 ++--- test/unit/post_sets/wiki_page_test.rb | 73 ----- test/unit/post_test.rb | 14 +- test/unit/tag_alias_test.rb | 2 +- test/unit/tag_implication_test.rb | 2 +- test/unit/upload_test.rb | 306 +++++++++--------- test/unit/user_test.rb | 26 +- 49 files changed, 896 insertions(+), 488 deletions(-) create mode 100644 app/controllers/moderator/dashboards_controller.rb create mode 100644 app/helpers/moderator/dashboards_helper.rb create mode 100644 app/logical/moderator/dashboard/queries/comment.rb create mode 100644 app/logical/moderator/dashboard/queries/post.rb create mode 100644 app/logical/moderator/dashboard/queries/post_appeal.rb create mode 100644 app/logical/moderator/dashboard/queries/post_flag.rb create mode 100644 app/logical/moderator/dashboard/queries/upload.rb create mode 100644 app/logical/moderator/dashboard/queries/user.rb create mode 100644 app/logical/moderator/report.rb create mode 100644 app/logical/moderator_dashboard.rb create mode 100644 app/views/moderator/dashboards/show.html.erb create mode 100644 lib/danbooru/paginator/pagination_error.rb delete mode 100644 test/unit/post_sets/wiki_page_test.rb diff --git a/Gemfile.lock b/Gemfile.lock index f424c75d0..6858f8b1a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,8 +1,8 @@ GIT remote: git://github.com/ernie/meta_search.git - revision: 79806e6a9db5dc4eedbd45bccc5929cf6fbf3593 + revision: dfdd9c3a9956c4a2ad96724e2a801ad77a962b70 specs: - meta_search (1.1.0.pre) + meta_search (1.1.0.pre2) actionpack (~> 3.1.0.alpha) activerecord (~> 3.1.0.alpha) activesupport (~> 3.1.0.alpha) @@ -46,33 +46,38 @@ GEM activesupport (= 3.1.0.rc1) activesupport (3.1.0.rc1) multi_json (~> 1.0) - arel (2.1.1) + arel (2.1.3) bcrypt-ruby (2.1.4) builder (3.0.0) - daemons (1.1.3) + daemons (1.1.4) delayed_job (2.1.4) activesupport (~> 3.0) daemons erubis (2.7.0) factory_girl (1.3.3) - haml (3.1.1) - hike (1.0.0) + haml (3.1.2) + hike (1.1.0) i18n (0.6.0) imagesize (0.1.1) mail (2.3.0) i18n (>= 0.4.0) mime-types (~> 1.16) treetop (~> 1.4.8) - mechanize (1.0.0) - nokogiri (>= 1.2.1) + mechanize (2.0.1) + net-http-digest_auth (~> 1.1, >= 1.1.1) + net-http-persistent (~> 1.8) + nokogiri (~> 1.4) + webrobots (~> 0.0, >= 0.0.9) memcache-client (1.8.5) mime-types (1.16) mocha (0.9.12) multi_json (1.0.3) - nokogiri (1.4.4) + net-http-digest_auth (1.1.1) + net-http-persistent (1.8) + nokogiri (1.5.0) pg (0.11.0) polyglot (0.3.1) - rack (1.3.0) + rack (1.3.1) rack-cache (1.0.2) rack (>= 0.4) rack-mount (0.8.1) @@ -98,7 +103,9 @@ GEM rake (0.9.2) shoulda (2.11.3) silent-postgres (0.0.8) - simple_form (1.4.0) + simple_form (1.4.2) + actionpack (~> 3.0) + activemodel (~> 3.0) simplecov (0.4.2) simplecov-html (~> 0.4.4) simplecov-html (0.4.5) @@ -113,7 +120,9 @@ GEM tilt (1.3.2) treetop (1.4.9) polyglot (>= 0.3.1) - tzinfo (0.3.27) + tzinfo (0.3.29) + webrobots (0.0.10) + nokogiri (>= 1.4.4) PLATFORMS ruby diff --git a/app/assets/stylesheets/application.css.scss b/app/assets/stylesheets/application.css.scss index a1cfac4eb..a26344dda 100644 --- a/app/assets/stylesheets/application.css.scss +++ b/app/assets/stylesheets/application.css.scss @@ -1006,3 +1006,36 @@ div#c-static { } } } + + + +/*** moderator dashboard ***/ +div#moderator-dashboard { + div#comment-activity { + width: 45%; + float: left; + } + + div#post-activity { + width: 45%; + float: left; + margin-left: 2em; + } + + div#ip-addr-search { + margin-bottom: 2em; + } + + div#activity-search { + margin-bottom: 2em; + } + + table { + margin-bottom: 2em; + } + + caption { + font-weight: bold; + font-size: 1.5em; + } +} diff --git a/app/controllers/ip_bans_controller.rb b/app/controllers/ip_bans_controller.rb index 580a6dec1..afe1ca24b 100644 --- a/app/controllers/ip_bans_controller.rb +++ b/app/controllers/ip_bans_controller.rb @@ -1,5 +1,5 @@ class IpBansController < ApplicationController - before_filter :admin_only + before_filter :janitor_only def new @ip_ban = IpBan.new diff --git a/app/controllers/moderator/dashboards_controller.rb b/app/controllers/moderator/dashboards_controller.rb new file mode 100644 index 000000000..a066376da --- /dev/null +++ b/app/controllers/moderator/dashboards_controller.rb @@ -0,0 +1,9 @@ +module Moderator + class DashboardsController < ApplicationController + before_filter :janitor_only + + def show + @dashboard = ModeratorDashboard.new(params[:min_date] || 2.days.ago.to_date, params[:max_level] || 20) + end + end +end diff --git a/app/controllers/notes_controller.rb b/app/controllers/notes_controller.rb index 55861c5af..9e7280bd8 100644 --- a/app/controllers/notes_controller.rb +++ b/app/controllers/notes_controller.rb @@ -37,7 +37,7 @@ class NotesController < ApplicationController def destroy @note = Note.find(params[:id]) - @note.update_attribute(:is_active, false) + @note.update_column(:is_active, false) respond_with(@note) end diff --git a/app/helpers/moderator/dashboards_helper.rb b/app/helpers/moderator/dashboards_helper.rb new file mode 100644 index 000000000..fadf8f452 --- /dev/null +++ b/app/helpers/moderator/dashboards_helper.rb @@ -0,0 +1,17 @@ +module Moderator + module DashboardsHelper + def user_level_select_tag(name, options = {}) + choices = [ + ["", ""], + ["Member", 0], + ["Privileged", 100], + ["Contributor", 200], + ["Janitor", 300], + ["Moderator", 400], + ["Admin", 500] + ] + + select_tag(name, options_for_select(choices, params[name].to_i), options) + end + end +end diff --git a/app/logical/moderator/dashboard/queries/comment.rb b/app/logical/moderator/dashboard/queries/comment.rb new file mode 100644 index 000000000..197b6f997 --- /dev/null +++ b/app/logical/moderator/dashboard/queries/comment.rb @@ -0,0 +1,14 @@ +module Moderator + module Dashboard + module Queries + class Comment + attr_reader :comment, :count + + def initialize(hash) + @comment = Comment.find(hash["comment_id"]) + @count = hash["count"] + end + end + end + end +end diff --git a/app/logical/moderator/dashboard/queries/post.rb b/app/logical/moderator/dashboard/queries/post.rb new file mode 100644 index 000000000..09e8818db --- /dev/null +++ b/app/logical/moderator/dashboard/queries/post.rb @@ -0,0 +1,14 @@ +module Moderator + module Dashboard + module Queries + class Post + attr_reader :post, :count + + def initialize(hash) + @post = Post.find(hash["post_id"]) + @count = hash["count"] + end + end + end + end +end diff --git a/app/logical/moderator/dashboard/queries/post_appeal.rb b/app/logical/moderator/dashboard/queries/post_appeal.rb new file mode 100644 index 000000000..a870f0b5d --- /dev/null +++ b/app/logical/moderator/dashboard/queries/post_appeal.rb @@ -0,0 +1,30 @@ +module Moderator + module Dashboard + module Queries + class PostAppeal + attr_reader :post, :reason + + def self.all(min_date) + sql = <<-EOS + SELECT post_appeals.post_id, count(*) + FROM post_appeals + JOIN posts ON posts.id = post_appeals.post_id + WHERE + post_appeals.created_at > ? + and posts.status <> ? + GROUP BY post_appeals.post_id + ORDER BY count(*) DESC + LIMIT 10 + EOS + + ActiveRecord::Base.select_all_sql(sql, min_date).map {|x| new(x)} + end + + def initialize(hash) + @post = Post.find(hash["post_id"]) + @reason = hash["reason"] + end + end + end + end +end diff --git a/app/logical/moderator/dashboard/queries/post_flag.rb b/app/logical/moderator/dashboard/queries/post_flag.rb new file mode 100644 index 000000000..01374ab1b --- /dev/null +++ b/app/logical/moderator/dashboard/queries/post_flag.rb @@ -0,0 +1,31 @@ +module Moderator + module Dashboard + module Queries + class PostFlag + attr_reader :post, :count + + def self.all(min_date) + sql = <<-EOS + SELECT post_flags.post_id, count(*) + FROM post_flags + JOIN posts ON posts.id = post_flags.post_id + WHERE + post_flags.created_at > ? + AND post_flags.reason <> ? + AND posts.status <> 'deleted' + GROUP BY post_flags.post_id + ORDER BY count(*) DESC + LIMIT 10 + EOS + + ActiveRecord::Base.select_all_sql(sql, min_date, "Unapproved in three days").map {|x| new(x)} + end + + def initialize(hash) + @post = Post.find(hash["post_id"]) + @count = hash["count"] + end + end + end + end +end diff --git a/app/logical/moderator/dashboard/queries/upload.rb b/app/logical/moderator/dashboard/queries/upload.rb new file mode 100644 index 000000000..2e9751bae --- /dev/null +++ b/app/logical/moderator/dashboard/queries/upload.rb @@ -0,0 +1,13 @@ +module Moderator + module Dashboard + module Queries + class Upload + def self.all(min_date) + ActiveRecord::Base.without_timeout do + @upload_activity = ActiveRecord::Base.select_all_sql("select posts.uploader_string, count(*) from posts join users on posts.user_id = users.id where posts.created_at > ? and users.level <= ? group by posts.user_id order by count(*) desc limit 10", min_date, max_level).map {|x| UserActivity.new(x)} + end + end + end + end + end +end diff --git a/app/logical/moderator/dashboard/queries/user.rb b/app/logical/moderator/dashboard/queries/user.rb new file mode 100644 index 000000000..0ef2031cf --- /dev/null +++ b/app/logical/moderator/dashboard/queries/user.rb @@ -0,0 +1,14 @@ +module Moderator + module Dashboard + module Queries + class User + attr_reader :user, :count + + def initialize(hash) + @user = User.find(hash["user_id"]) + @count = hash["count"] + end + end + end + end +end \ No newline at end of file diff --git a/app/logical/moderator/report.rb b/app/logical/moderator/report.rb new file mode 100644 index 000000000..92bfb5f42 --- /dev/null +++ b/app/logical/moderator/report.rb @@ -0,0 +1,6 @@ +module Moderator + module Dashboard + class Report + end + end +end diff --git a/app/logical/moderator_dashboard.rb b/app/logical/moderator_dashboard.rb new file mode 100644 index 000000000..3286bf47d --- /dev/null +++ b/app/logical/moderator_dashboard.rb @@ -0,0 +1,54 @@ +class ModeratorDashboard + attr_reader :min_date, :max_level + + def initialize(min_date, max_level) + @min_date = min_date + @max_level = max_level + end + + def upload_activity + + + @upload_activity + end + + def comment_activity(positive = false) + if positive + ActiveRecord::Base.select_all_sql("SELECT comment_votes.comment_id, count(*) FROM comment_votes JOIN comments ON comments.id = comment_votes.comment_id JOIN users ON users.id = comments.user_id WHERE comment_votes.created_at > ? AND comments.score > 0 AND users.level <= ? GROUP BY comment_votes.comment_id HAVING count(*) >= 3 ORDER BY count(*) DESC LIMIT 10", min_date, max_level).map {|x| CommentActivity.new(x)} + else + ActiveRecord::Base.select_all_sql("SELECT comment_votes.comment_id, count(*) FROM comment_votes JOIN comments ON comments.id = comment_votes.comment_id JOIN users ON users.id = comments.user_id WHERE comment_votes.created_at > ? AND comments.score < 0 AND users.level <= ? GROUP BY comment_votes.comment_id HAVING count(*) >= 3 ORDER BY count(*) DESC LIMIT 10", min_date, max_level).map {|x| CommentActivity.new(x)} + end + end + + def post_activity(positive = false) + ActiveRecord::Base.without_timeout do + if positive + @post_activity = ActiveRecord::Base.select_all_sql("SELECT post_votes.post_id, count(*) FROM post_votes JOIN posts ON posts.id = post_votes.post_id JOIN users ON users.id = posts.user_id WHERE post_votes.created_at > ? AND posts.score > 0 AND users.level <= ? GROUP BY post_votes.post_id HAVING count(*) >= 3 ORDER BY count(*) DESC LIMIT 10", min_date, max_level).map {|x| PostActivity.new(x)} + else + @post_activity = ActiveRecord::Base.select_all_sql("SELECT post_votes.post_id, count(*) FROM post_votes JOIN posts ON posts.id = post_votes.post_id JOIN users ON users.id = posts.user_id WHERE post_votes.created_at > ? AND posts.score < 0 AND users.level <= ? AND posts.status <> 'deleted' GROUP BY post_votes.post_id HAVING count(*) >= 3 ORDER BY count(*) DESC LIMIT 10", min_date, max_level).map {|x| PostActivity.new(x)} + end + end + + @post_activity + end + + def tag_activity + ActiveRecord::Base.without_timeout do + @tag_activity = ActiveRecord::Base.select_all_sql("SELECT post_tag_histories.user_id, count(*) FROM post_tag_histories JOIN users ON users.id = post_tag_histories.user_id WHERE post_tag_histories.created_at > ? AND users.level <= ? GROUP BY post_tag_histories.user_id ORDER BY count(*) DESC LIMIT 10", min_date, max_level).map {|x| UserActivity.new(x)} + end + + @tag_activity + end + + def note_activity + ActiveRecord::Base.select_all_sql("SELECT note_versions.user_id, count(*) FROM note_versions JOIN users ON users.id = note_versions.user_id WHERE note_versions.created_at > ? AND users.level <= ? GROUP BY note_versions.user_id ORDER BY count(*) DESC LIMIT 10", min_date, max_level).map {|x| UserActivity.new(x)} + end + + def wiki_page_activity + ActiveRecord::Base.select_all_sql("SELECT wiki_page_versions.user_id, count(*) FROM wiki_page_versions JOIN users ON users.id = wiki_page_versions.user_id WHERE wiki_page_versions.created_at > ? AND users.level <= ? GROUP BY wiki_page_versions.user_id ORDER BY count(*) DESC LIMIT 10", min_date, max_level).map {|x| UserActivity.new(x)} + end + + def artist_activity + ActiveRecord::Base.select_all_sql("SELECT artist_versions.updater_id AS user_id, count(*) FROM artist_versions JOIN users ON users.id = artist_versions.updater_id WHERE artist_versions.created_at > ? AND users.level <= ? GROUP BY artist_versions.updater_id ORDER BY count(*) DESC LIMIT 10", min_date, max_level).map {|x| UserActivity.new(x)} + end +end diff --git a/app/logical/post_sets/favorite.rb b/app/logical/post_sets/favorite.rb index 325a9b9e4..fe4c2d4fe 100644 --- a/app/logical/post_sets/favorite.rb +++ b/app/logical/post_sets/favorite.rb @@ -2,7 +2,7 @@ module PostSets class Favorite < Base attr_reader :user, :page, :favorites - def initialize(user_id, page) + def initialize(user_id, page = 1) @user = ::User.find(user_id) @favorites = ::Favorite.model_for(user.id).for_user(user.id).paginate(page) end diff --git a/app/logical/post_sets/pool.rb b/app/logical/post_sets/pool.rb index 7caf81532..0d345b5f4 100644 --- a/app/logical/post_sets/pool.rb +++ b/app/logical/post_sets/pool.rb @@ -4,15 +4,11 @@ module PostSets attr_accessor :total_pages, :current_page end - attr_reader :pool, :page, :posts + attr_reader :pool, :page - def initialize(pool, page) + def initialize(pool, page = 1) @pool = pool @page = page - @posts = pool.posts(:offset => offset, :limit => limit) - @posts.extend(ActiveRecordExtension) - @posts.total_pages = total_pages - @posts.current_page = current_page end def offset @@ -27,6 +23,16 @@ module PostSets ["pool:#{pool.id}"] end + def posts + @posts ||= begin + x = pool.posts(:offset => offset, :limit => limit) + x.extend(ActiveRecordExtension) + x.total_pages = total_pages + x.current_page = current_page + x + end + end + def tag_string tag_array.join("") end diff --git a/app/logical/post_sets/post.rb b/app/logical/post_sets/post.rb index 3a668c3e8..46f4e017a 100644 --- a/app/logical/post_sets/post.rb +++ b/app/logical/post_sets/post.rb @@ -1,11 +1,13 @@ module PostSets + class SearchError < Exception + end + class Post < Base - attr_reader :tag_array, :page, :posts + attr_reader :tag_array, :page - def initialize(params) - @tag_array = Tag.scan_query(params[:tags]) - @page = params[:page] - @posts = ::Post.tag_match(tag_string).paginate(page) + def initialize(tags, page = 1) + @tag_array = Tag.scan_query(tags) + @page = page end def tag_string @@ -24,6 +26,14 @@ module PostSets end end + def posts + if tag_array.size > 2 && !CurrentUser.is_privileged? + raise SearchError + end + + @posts ||= ::Post.tag_match(tag_string).paginate(page) + end + def has_artist? tag_array.any? && ::Artist.name_equals(tag_string).exists? end @@ -36,6 +46,10 @@ module PostSets tag_array.size == 1 end + def current_page + [page.to_i, 1].max + end + def presenter @presenter ||= ::PostSetPresenters::Post.new(self) end diff --git a/app/models/artist.rb b/app/models/artist.rb index 7f0f55a3e..c405f18d7 100644 --- a/app/models/artist.rb +++ b/app/models/artist.rb @@ -14,6 +14,7 @@ class Artist < ActiveRecord::Base attr_accessible :name, :url_string, :other_names, :group_name, :wiki_page_attributes, :notes scope :url_match, lambda {|string| where(["id in (?)", Artist.find_all_by_url(string).map(&:id)])} scope :other_names_match, lambda {|string| where(["other_names_index @@ to_tsquery('danbooru', ?)", Artist.normalize_name(string)])} + scope :name_equals, lambda {|string| where("name = ?", string)} search_methods :url_match, :other_names_match module UrlMethods diff --git a/app/models/dmail.rb b/app/models/dmail.rb index 97758344f..503721a58 100644 --- a/app/models/dmail.rb +++ b/app/models/dmail.rb @@ -89,15 +89,15 @@ class Dmail < ActiveRecord::Base end def mark_as_read! - update_attribute(:is_read, true) + update_column(:is_read, true) unless Dmail.exists?(["to_id = ? AND is_read = false", to_id]) - to.update_attribute(:has_mail, false) + to.update_column(:has_mail, false) end end def update_recipient - to.update_attribute(:has_mail, true) + to.update_column(:has_mail, true) end def visible_to?(user) diff --git a/app/models/forum_post.rb b/app/models/forum_post.rb index 260239f1b..9002ec4aa 100644 --- a/app/models/forum_post.rb +++ b/app/models/forum_post.rb @@ -39,7 +39,7 @@ class ForumPost < ActiveRecord::Base def update_topic_updated_at if topic - topic.update_attribute(:updater_id, CurrentUser.id) + topic.update_column(:updater_id, CurrentUser.id) topic.touch end end diff --git a/app/models/janitor_trial.rb b/app/models/janitor_trial.rb index 4e50c9446..150899955 100644 --- a/app/models/janitor_trial.rb +++ b/app/models/janitor_trial.rb @@ -5,11 +5,16 @@ class JanitorTrial < ActiveRecord::Base after_destroy :create_feedback validates_presence_of :user before_validation :initialize_creator + before_validation :initialize_original_level def initialize_creator self.creator_id = CurrentUser.id end + def initialize_original_level + self.original_level = user.level + end + def user_name=(name) self.user_id = User.name_to_id(name) end @@ -21,7 +26,7 @@ class JanitorTrial < ActiveRecord::Base end def promote_user - user.update_attribute(:is_janitor, true) + user.update_column(:level, User::Levels::JANITOR) end def create_feedback @@ -36,7 +41,7 @@ class JanitorTrial < ActiveRecord::Base end def demote! - user.update_attribute(:is_janitor, false) + user.update_column(:level, original_level) destroy end end diff --git a/app/models/jobs/calculate_uploaded_tags.rb b/app/models/jobs/calculate_uploaded_tags.rb index 28db8725a..a3f750df9 100644 --- a/app/models/jobs/calculate_uploaded_tags.rb +++ b/app/models/jobs/calculate_uploaded_tags.rb @@ -6,7 +6,7 @@ module Jobs CONFIG["tag_types"].values.uniq.each do |tag_type| tags += user.calculate_uploaded_tags(tag_type) end - user.update_attribute(:uploaded_tags, tags.join("\n")) + user.update_column(:uploaded_tags, tags.join("\n")) end end end diff --git a/app/models/pool.rb b/app/models/pool.rb index c962c61c5..dda6bdaaf 100644 --- a/app/models/pool.rb +++ b/app/models/pool.rb @@ -91,7 +91,6 @@ class Pool < ActiveRecord::Base offset = options[:offset] || 0 limit = options[:limit] || Danbooru.config.posts_per_page slice = post_id_array.slice(offset, limit) - puts slice.inspect if slice && slice.any? Post.where("id in (?)", slice).order(arbitrary_sql_order_clause(slice, "posts")) else @@ -150,7 +149,7 @@ class Pool < ActiveRecord::Base last_version = versions.last if last_version && CurrentUser.ip_addr == last_version.updater_ip_addr && CurrentUser.id == last_version.updater_id - last_version.update_attribute(:post_ids, post_ids) + last_version.update_column(:post_ids, post_ids) else versions.create(:post_ids => post_ids) end diff --git a/app/models/post.rb b/app/models/post.rb index 31725a0ac..7b4bbfe08 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -15,6 +15,7 @@ class Post < ActiveRecord::Base before_validation :initialize_uploader, :on => :create belongs_to :updater, :class_name => "User" belongs_to :approver, :class_name => "User" + belongs_to :uploader, :class_name => "User" belongs_to :parent, :class_name => "Post" has_one :upload, :dependent => :destroy has_many :flags, :class_name => "PostFlag", :dependent => :destroy @@ -36,7 +37,7 @@ class Post < ActiveRecord::Base scope :visible, lambda {|user| Danbooru.config.can_user_see_post_conditions(user)} scope :commented_before, lambda {|date| where("last_commented_at < ?", date).order("last_commented_at DESC")} scope :has_notes, where("last_noted_at is not null") - scope :for_user, lambda {|user_id| where(["uploader_string = ?", "uploader:#{user_id}"])} + scope :for_user, lambda {|user_id| where(["uploader_id = ?", user_id])} scope :available_for_moderation, lambda {where(["id NOT IN (SELECT pd.post_id FROM post_disapprovals pd WHERE pd.user_id = ?)", CurrentUser.id])} scope :hidden_from_moderation, lambda {where(["id IN (SELECT pd.post_id FROM post_disapprovals pd WHERE pd.user_id = ?)", CurrentUser.id])} scope :tag_match, lambda {|query| Post.tag_match_helper(query)} @@ -233,7 +234,7 @@ class Post < ActiveRecord::Base module ApprovalMethods def is_approvable? - (is_pending? || is_flagged? || is_deleted?) && approver_string != "approver:#{CurrentUser.name}" + (is_pending? || is_flagged? || is_deleted?) && approver_id != CurrentUser.id end def flag!(reason) @@ -243,7 +244,7 @@ class Post < ActiveRecord::Base raise PostFlag::Error.new(flag.errors.full_messages.join("; ")) end - update_attribute(:is_flagged, true) + update_column(:is_flagged, true) end def appeal!(reason) @@ -255,13 +256,13 @@ class Post < ActiveRecord::Base end def approve! - raise ApprovalError.new("You have previously approved this post and cannot approve it again") if approver_string == "approver:#{CurrentUser.name}" + raise ApprovalError.new("You have previously approved this post and cannot approve it again") if approver_id == CurrentUser.id flags.each {|x| x.resolve!} self.is_flagged = false self.is_pending = false self.is_deleted = false - self.approver_string = "approver:#{CurrentUser.name}" + self.approver_id = CurrentUser.id save! end end @@ -295,7 +296,7 @@ class Post < ActiveRecord::Base end def create_tags - set_tag_string(tag_array.map {|x| Tag.find_or_create_by_name(x).name}.join(" ")) + set_tag_string(tag_array.map {|x| Tag.find_or_create_by_name(x).name}.uniq.join(" ")) end def increment_tag_post_counts @@ -373,11 +374,12 @@ class Post < ActiveRecord::Base normalized_tags = TagAlias.to_aliased(normalized_tags) normalized_tags = TagImplication.with_descendants(normalized_tags) normalized_tags = filter_metatags(normalized_tags) + normalized_tags = %w(tagme) if normalized_tags.empty? set_tag_string(normalized_tags.uniq.join(" ")) end def filter_metatags(tags) - tags.reject {|tag| tag =~ /\A(?:pool|rating|fav|approver|uploader):/} + tags.reject {|tag| tag =~ /\A(?:pool|rating|fav):/} end def has_tag?(tag) @@ -395,7 +397,7 @@ class Post < ActiveRecord::Base end def append_user_to_fav_string(user_id) - update_attribute(:fav_string, (fav_string + " fav:#{user_id}").strip) + update_column(:fav_string, (fav_string + " fav:#{user_id}").strip) end def add_favorite!(user) @@ -405,7 +407,7 @@ class Post < ActiveRecord::Base end def delete_user_from_fav_string(user_id) - update_attribute(:fav_string, fav_string.gsub(/(?:\A| )fav:#{user_id}(?:\Z| )/, " ").strip) + update_column(:fav_string, fav_string.gsub(/(?:\A| )fav:#{user_id}(?:\Z| )/, " ").strip) end def remove_favorite!(user) @@ -542,6 +544,22 @@ class Post < ActiveRecord::Base relation = add_tag_string_search_relation(q[:tags], relation) + if q[:uploader_id_neg] + relation = relation.where("posts.uploader_id not in (?)", q[:uploader_id_neg]) + end + + if q[:uploader_id] + relation = relation.where("posts.uploader_id = ?", q[:uploader_id]) + end + + if q[:approver_id_neg] + relation = relation.where("posts.approver_id not in (?)", q[:approver_id_neg]) + end + + if q[:approver_id] + relation = relation.where("posts.approver_id = ?", q[:approver_id]) + end + if q[:rating] == "q" relation = relation.where("posts.rating = 'q'") elsif q[:rating] == "s" @@ -601,29 +619,15 @@ class Post < ActiveRecord::Base module UploaderMethods def initialize_uploader - self.uploader = CurrentUser.user - self.uploader_ip_addr = CurrentUser.ip_addr - end - - def uploader_id=(user_id) - self.uploader = User.find(user_id) - end - - def uploader_id - uploader_string[9..-1].to_i + if uploader_id.blank? + self.uploader_id = CurrentUser.id + self.uploader_ip_addr = CurrentUser.ip_addr + end end def uploader_name User.id_to_name(uploader_id) end - - def uploader - User.find(uploader_id) - end - - def uploader=(user) - self.uploader_string = "uploader:#{user.id}" - end end module PoolMethods @@ -640,13 +644,15 @@ class Post < ActiveRecord::Base def add_pool!(pool) return if belongs_to_pool?(pool) - update_attribute(:pool_string, "#{pool_string} pool:#{pool.id}".strip) + self.pool_string = "#{pool_string} pool:#{pool.id}".strip + update_column(:pool_string, pool_string) pool.add!(self) end def remove_pool!(pool) return unless belongs_to_pool?(pool) - update_attribute(:pool_string, pool_string.gsub(/(?:\A| )pool:#{pool.id}(?:\Z| )/, " ").strip) + self.pool_string = pool_string.gsub(/(?:\A| )pool:#{pool.id}(?:\Z| )/, " ").strip + update_column(:pool_string, pool_string) pool.remove!(self) end end @@ -762,13 +768,11 @@ class Post < ActiveRecord::Base if children.size == 0 # do nothing elsif children.size == 1 - children.first.update_attribute(:parent_id, nil) + children.first.update_column(:parent_id, nil) else cached_children = children - cached_children[1..-1].each do |child| - child.update_attribute(:parent_id, cached_children[0].id) - end - cached_children[0].update_attribute(:parent_id, nil) + Post.update_all({:parent_id => cached_children[0].id}, :id => cached_children[1..-1].map(&:id)) + cached_children[0].update_column(:parent_id, nil) end end @@ -800,14 +804,14 @@ class Post < ActiveRecord::Base update_children_on_destroy delete_favorites decrement_tag_post_counts - update_attribute(:is_deleted, true) + update_column(:is_deleted, true) update_parent_on_destroy tag_array.each {|x| expire_cache(x)} end end def undelete! - update_attribute(:is_deleted, false) + update_column(:is_deleted, false) tag_array.each {|x| expire_cache(x)} update_parent_on_save end @@ -822,7 +826,7 @@ class Post < ActiveRecord::Base :add_tags => tag_string, :parent_id => parent_id ) - else + elsif rating_changed? || source_changed? || parent_id_changed? || tag_string_changed? versions.create( :rating => rating_changed? ? rating : nil, :source => source_changed? ? source : nil, diff --git a/app/models/post_flag.rb b/app/models/post_flag.rb index c7ddcbf7e..4cc15223b 100644 --- a/app/models/post_flag.rb +++ b/app/models/post_flag.rb @@ -13,7 +13,7 @@ class PostFlag < ActiveRecord::Base scope :unresolved, where(["is_resolved = ?", false]) def update_post - post.update_attribute(:is_flagged, true) + post.update_column(:is_flagged, true) end def validate_creator_is_not_limited @@ -40,7 +40,7 @@ class PostFlag < ActiveRecord::Base end def resolve! - update_attribute(:is_resolved, true) + update_column(:is_resolved, true) end def flag_count_for_creator diff --git a/app/models/tag.rb b/app/models/tag.rb index f4423aa1c..ee6d65cf6 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -88,15 +88,15 @@ class Tag < ActiveRecord::Base if tag if category > 0 && !(options[:user] && !options[:user].is_privileged? && tag.post_count > 10) - tag.update_attribute(:category, category) + tag.update_column(:category, category) end tag else - Tag.new.tap do |tag| - tag.name = name - tag.category = category - tag.save + Tag.new.tap do |t| + t.name = name + t.category = category + t.save end end end @@ -216,13 +216,21 @@ class Tag < ActiveRecord::Base } scan_query(query).each do |token| - if token =~ /\A(-uploader|uploader|-pool|pool|-fav|fav|sub|md5|-rating|rating|width|height|mpixels|score|filesize|source|id|date|order|status|tagcount|gentags|arttags|chartags|copytags):(.+)\Z/ + if token =~ /\A(-uploader|uploader|-approver|approver|-pool|pool|-fav|fav|sub|md5|-rating|rating|width|height|mpixels|score|filesize|source|id|date|order|status|tagcount|gentags|arttags|chartags|copytags):(.+)\Z/ case $1 when "-uploader" - q[:tags][:exclude] << "uploader:#{User.name_to_id($2)}" + q[:uploader_id_neg] ||= [] + q[:uploader_id_neg] << User.name_to_id($2) when "uploader" - q[:tags][:related] << "uploader:#{User.name_to_id($2)}" + q[:uploader_id] = User.name_to_id($2) + + when "-approver" + q[:approver_id_neg] ||= [] + q[:approver_id_neg] << User.name.to_id($2) + + when "approver" + q[:approver_id] = User.name.to_id($2) when "-pool" q[:tags][:exclude] << "pool:#{Pool.name_to_id($2)}" diff --git a/app/models/upload.rb b/app/models/upload.rb index 7b2ccce4e..b037e60de 100644 --- a/app/models/upload.rb +++ b/app/models/upload.rb @@ -17,7 +17,7 @@ class Upload < ActiveRecord::Base module ValidationMethods def uploader_is_not_limited if !uploader.can_upload? - update_attribute(:status, "error: uploader has reached their daily limit") + update_column(:status, "error: uploader has reached their daily limit") end end @@ -29,19 +29,19 @@ class Upload < ActiveRecord::Base def validate_file_exists unless File.exists?(file_path) - update_attribute(:status, "error: file does not exist") + update_column(:status, "error: file does not exist") end end def validate_file_content_type unless is_valid_content_type? - update_attribute(:status, "error: invalid content type (#{file_ext} not allowed)") + update_column(:status, "error: invalid content type (#{file_ext} not allowed)") end end def validate_md5_confirmation if !md5_confirmation.blank? && md5_confirmation != md5 - update_attribute(:status, "error: md5 mismatch") + update_column(:status, "error: md5 mismatch") end end end @@ -49,7 +49,7 @@ class Upload < ActiveRecord::Base module ConversionMethods def process! CurrentUser.scoped(uploader, uploader_ip_addr) do - update_attribute(:status, "processing") + update_column(:status, "processing") if is_downloadable? download_from_source(temp_file_path) end @@ -67,12 +67,12 @@ class Upload < ActiveRecord::Base if post.save update_attributes(:status => "completed", :post_id => post.id) else - update_attribute(:status, "error: " + post.errors.full_messages.join(", ")) + update_column(:status, "error: " + post.errors.full_messages.join(", ")) end end rescue Exception => x raise - update_attribute(:status, "error: #{x} - #{x.message}") + update_column(:status, "error: #{x} - #{x.message}") ensure delete_temp_file end @@ -87,6 +87,8 @@ class Upload < ActiveRecord::Base p.rating = rating p.source = source p.file_size = file_size + p.uploader_id = uploader_id + p.uploader_ip_addr = uploader_ip_addr unless uploader.is_contributor? p.is_pending = true @@ -97,7 +99,7 @@ class Upload < ActiveRecord::Base def merge_tags(post) post.tag_string += " #{tag_string}" post.save - update_attribute(:status, "duplicate: #{post.id}") + update_column(:status, "duplicate: #{post.id}") end end diff --git a/app/models/user.rb b/app/models/user.rb index a84d05dbb..bfe2de516 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -28,6 +28,7 @@ class User < ActiveRecord::Base after_save :update_cache before_create :promote_to_admin_if_first_user has_many :feedback, :class_name => "UserFeedback", :dependent => :destroy + has_many :posts, :foreign_key => "uploader_id" has_one :ban has_many :subscriptions, :class_name => "TagSubscription" has_many :note_versions, :foreign_key => "updater_id" @@ -46,7 +47,7 @@ class User < ActiveRecord::Base end def unban! - update_attribute(:is_banned, false) + update_column(:is_banned, false) ban.destroy end end @@ -218,7 +219,7 @@ class User < ActiveRecord::Base def verify!(key) if email_verification_key == key - self.update_attribute(:email_verification_key, nil) + self.update_column(:email_verification_key, nil) else raise User::Error.new("Verification key does not match") end @@ -293,12 +294,6 @@ class User < ActiveRecord::Base end end - module PostMethods - def posts - Post.where("uploader_string = ?", "uploader:#{id}") - end - end - include BanMethods include NameMethods include PasswordMethods @@ -309,7 +304,6 @@ class User < ActiveRecord::Base include BlacklistMethods include ForumMethods include LimitMethods - include PostMethods def initialize_default_image_size self.default_image_size = "Medium" diff --git a/app/views/layouts/default.html.erb b/app/views/layouts/default.html.erb index a8435c406..9b202fd16 100644 --- a/app/views/layouts/default.html.erb +++ b/app/views/layouts/default.html.erb @@ -42,6 +42,9 @@ <%= nav_link_to("Pools", pools_path) %> <%= nav_link_to("Wiki", wiki_pages_path(:title => "help:home")) %> <%= nav_link_to("Forum", forum_topics_path, :class => (CurrentUser.user.has_forum_been_updated? ? "forum-updated" : nil)) %> + <% if CurrentUser.is_moderator? %> + <%= nav_link_to("Dashboard", moderator_dashboard_path) %> + <% end %> <%= nav_link_to("»".html_safe, site_map_path) %> <%= yield :secondary_links %> diff --git a/app/views/moderator/dashboards/show.html.erb b/app/views/moderator/dashboards/show.html.erb new file mode 100644 index 000000000..ec8a8872a --- /dev/null +++ b/app/views/moderator/dashboards/show.html.erb @@ -0,0 +1,222 @@ +
+

Moderator Dashboard

+ + + + + +
+ + + + + + + + + + <% @dashboard.upload_activity.each do |activity| %> + + + + + <% end %> + +
Uploads
UserCount
<%= admin_link_to_user(activity.user, :positive) %><%= link_to activity.count, {:controller => "post", :action => "index", :tags => "user:#{activity.user.name}"} %>
+ + + + + + + + + + + <% @dashboard.note_activity.each do |activity| %> + + + + + <% end %> + +
Note Updates
UserCount
<%= admin_link_to_user(activity.user, :positive) %><%= link_to activity.count, {:controller => "note", :action => "history", :user_id => activity.user.id} %>
+ + + + + + + + + + + + <% @dashboard.tag_activity.each do |activity| %> + + + + + <% end %> + +
Tag Updates
UserCount
<%= admin_link_to_user(activity.user, :positive) %><%= link_to activity.count, {:controller => "post_tag_history", :action => "index", :user_id => activity.user.id} %>
+ + + + + + + + + + + + <% @dashboard.wiki_page_activity.each do |activity| %> + + + + + <% end %> + +
Wiki Page Updates
UserCount
<%= admin_link_to_user(activity.user, :positive) %><%= link_to activity.count, {:controller => "wiki", :action => "recent_changes", :user_id => activity.user.id} %>
+ + + + + + + + + + + + <% @dashboard.artist_activity.each do |activity| %> + + + + + <% end %> + +
Artist Updates
UserCount
<%= admin_link_to_user(activity.user, :positive) %><%= link_to activity.count, {:controller => "artist", :action => "recent_changes", :user_id => activity.user.id} %>
+ + + + + + + + + + + + + + <% @dashboard.comment_activity.each do |activity| %> + + + + + + + <% end %> + +
Comment Activity (Negative)
CommentUserVotesScore
<%= link_to activity.comment.body, :controller => "post", :action => "show", :id => activity.comment.post_id %><%= admin_link_to_user(activity.comment.user, :negative) %><%= activity.count %><%= activity.comment.score %>
+
+ +
+ + + + + + + + + + + + + + + + + + <% @dashboard.appealed_posts.each do |appeal| %> + + + + + + + + <% end %> + +
Appealed Posts
PostUserFlagsAppealsScore
<%= link_to "View all posts", :controller => "post_appeal", :action => "index" %>
<%= link_to image_tag(appeal.post.preview_url), :controller => "post", :action => "show", :id => appeal.post.id %><%= admin_link_to_user appeal.post.user, :negative %><%= post_flag_summary(appeal.post) %><%= post_appeal_summary(appeal.post) %><%= appeal.post.score %>
+ + + + + + + + + + + + <% UserRecord.recent(@dashboard.min_date).all(:order => "id desc").each do |record| %> + + + + + + <% end %> + +
User Records
UserMessageDate
<%= link_to(record.user.name, :controller => "user", :action => "show", :id => record.user_id) %><%= format_text(record.body) %><%= time_ago_in_words(record.created_at) %> ago
+ + + + + + + + + + + + + + + + + <% ModAction.all(:order => "id desc", :limit => 10).each do |mod_action| %> + + + + + <% end %> + +
Mod Actions
ModeratorDescription
<%= link_to "View all actions", :controller => "mod_action", :action => "index" %>
<%= link_to mod_action.user.name, :controller => "user", :action => "show", :id => mod_action.user_id %><%= format_text(mod_action.description) %>
+
+
\ No newline at end of file diff --git a/config/initializers/active_record_extensions.rb b/config/initializers/active_record_extensions.rb index b83192c25..34500b6b7 100644 --- a/config/initializers/active_record_extensions.rb +++ b/config/initializers/active_record_extensions.rb @@ -1,6 +1,24 @@ module Danbooru module Extensions module ActiveRecord + extend ActiveSupport::Concern + + module ClassMethods + def without_timeout + connection.execute("SET STATEMENT_TIMEOUT = 0") + yield + ensure + connection.execute("SET STATEMENT_TIMEOUT = 10000") + end + + def with_timeout(n) + connection.execute("SET STATEMENT_TIMEOUT = #{n}") + yield + ensure + connection.execute("SET STATEMENT_TIMEOUT = 10000") + end + end + %w(execute select_value select_values select_all).each do |method_name| define_method("#{method_name}_sql") do |sql, *params| connection.__send__(method_name, self.class.sanitize_sql_array([sql, *params])) diff --git a/config/routes.rb b/config/routes.rb index 3fea37392..84d5d407a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,7 +1,14 @@ Danbooru::Application.routes.draw do namespace :admin do - match 'users/edit' => 'users#edit', :via => :get - match 'users' => 'users#update', :via => :put + resources :users, :only => [:get, :put, :destroy] + end + namespace :moderator do + resource :dashboard, :only => [:show] + resources :ip_addrs, :only => [:index] do + collection do + get :search + end + end end resources :advertisements do resources :hits, :controller => "advertisement_hits", :only => [:create] diff --git a/db/development_structure.sql b/db/development_structure.sql index 14ee6d555..612948af8 100644 --- a/db/development_structure.sql +++ b/db/development_structure.sql @@ -3573,6 +3573,7 @@ CREATE TABLE janitor_trials ( id integer NOT NULL, creator_id integer NOT NULL, user_id integer NOT NULL, + original_level integer NOT NULL, created_at timestamp without time zone, updated_at timestamp without time zone ); @@ -3604,6 +3605,7 @@ ALTER SEQUENCE janitor_trials_id_seq OWNED BY janitor_trials.id; CREATE TABLE note_versions ( id integer NOT NULL, note_id integer NOT NULL, + post_id integer NOT NULL, updater_id integer NOT NULL, updater_ip_addr inet NOT NULL, x integer NOT NULL, @@ -3936,9 +3938,9 @@ CREATE TABLE posts ( is_pending boolean DEFAULT false NOT NULL, is_flagged boolean DEFAULT false NOT NULL, is_deleted boolean DEFAULT false NOT NULL, - uploader_string character varying(255) NOT NULL, + uploader_id integer NOT NULL, uploader_ip_addr inet NOT NULL, - approver_string character varying(255) DEFAULT ''::character varying NOT NULL, + approver_id integer, fav_string text DEFAULT ''::text NOT NULL, pool_string text DEFAULT ''::text NOT NULL, last_noted_at timestamp without time zone, @@ -4214,11 +4216,7 @@ CREATE TABLE users ( email_verification_key character varying(255), inviter_id integer, is_banned boolean DEFAULT false NOT NULL, - is_privileged boolean DEFAULT false NOT NULL, - is_contributor boolean DEFAULT false NOT NULL, - is_janitor boolean DEFAULT false NOT NULL, - is_moderator boolean DEFAULT false NOT NULL, - is_admin boolean DEFAULT false NOT NULL, + level integer DEFAULT 0 NOT NULL, base_upload_limit integer DEFAULT 10 NOT NULL, last_logged_in_at timestamp without time zone, last_forum_read_at timestamp without time zone, @@ -7922,6 +7920,13 @@ CREATE INDEX index_janitor_trials_on_user_id ON janitor_trials USING btree (user CREATE INDEX index_note_versions_on_note_id ON note_versions USING btree (note_id); +-- +-- Name: index_note_versions_on_post_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- + +CREATE INDEX index_note_versions_on_post_id ON note_versions USING btree (post_id); + + -- -- Name: index_note_versions_on_updater_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- @@ -8304,7 +8309,7 @@ CREATE TRIGGER trigger_notes_on_update CREATE TRIGGER trigger_posts_on_tag_index_update BEFORE INSERT OR UPDATE ON posts FOR EACH ROW - EXECUTE PROCEDURE tsvector_update_trigger('tag_index', 'public.danbooru', 'tag_string', 'fav_string', 'pool_string', 'uploader_string', 'approver_string'); + EXECUTE PROCEDURE tsvector_update_trigger('tag_index', 'public.danbooru', 'tag_string', 'fav_string', 'pool_string'); -- diff --git a/db/migrate/20100204214746_create_posts.rb b/db/migrate/20100204214746_create_posts.rb index 3216bea02..6848d6138 100644 --- a/db/migrate/20100204214746_create_posts.rb +++ b/db/migrate/20100204214746_create_posts.rb @@ -18,11 +18,11 @@ class CreatePosts < ActiveRecord::Migration t.column :is_deleted, :boolean, :null => false, :default => false # Uploader - t.column :uploader_string, :string, :null => false + t.column :uploader_id, :integer, :null => false t.column :uploader_ip_addr, "inet", :null => false # Approver - t.column :approver_string, :string, :null => false, :default => "" + t.column :approver_id, :integer # Favorites t.column :fav_string, :text, :null => false, :default => "" @@ -101,7 +101,7 @@ class CreatePosts < ActiveRecord::Migration execute "CREATE TEXT SEARCH CONFIGURATION public.danbooru (PARSER = public.testparser)" execute "ALTER TEXT SEARCH CONFIGURATION public.danbooru ADD MAPPING FOR WORD WITH SIMPLE" execute "SET default_text_search_config = 'public.danbooru'" - execute "CREATE TRIGGER trigger_posts_on_tag_index_update BEFORE INSERT OR UPDATE ON posts FOR EACH ROW EXECUTE PROCEDURE tsvector_update_trigger('tag_index', 'public.danbooru', 'tag_string', 'fav_string', 'pool_string', 'uploader_string', 'approver_string')" + execute "CREATE TRIGGER trigger_posts_on_tag_index_update BEFORE INSERT OR UPDATE ON posts FOR EACH ROW EXECUTE PROCEDURE tsvector_update_trigger('tag_index', 'public.danbooru', 'tag_string', 'fav_string', 'pool_string')" end def self.down diff --git a/db/migrate/20100309211553_create_janitor_trials.rb b/db/migrate/20100309211553_create_janitor_trials.rb index d9ebe4030..d16fd7c9d 100644 --- a/db/migrate/20100309211553_create_janitor_trials.rb +++ b/db/migrate/20100309211553_create_janitor_trials.rb @@ -3,6 +3,7 @@ class CreateJanitorTrials < ActiveRecord::Migration create_table :janitor_trials do |t| t.column :creator_id, :integer, :null => false t.column :user_id, :integer, :null => false + t.column :original_level, :integer, :null => false t.timestamps end diff --git a/lib/danbooru/paginator/active_record_extension.rb b/lib/danbooru/paginator/active_record_extension.rb index 37f9ab6ab..820c67f97 100644 --- a/lib/danbooru/paginator/active_record_extension.rb +++ b/lib/danbooru/paginator/active_record_extension.rb @@ -52,7 +52,7 @@ module Danbooru page = [page.to_i, 1].max if page > Danbooru.config.max_numbered_pages - raise "You cannot go beyond page #{Danbooru.config.max_numbered_pages}. Please narrow your search terms." + raise PaginationError.new("You cannot go beyond page #{Danbooru.config.max_numbered_pages}. Please narrow your search terms.") end limit(records_per_page).offset((page - 1) * records_per_page).tap do |obj| diff --git a/lib/danbooru/paginator/pagination_error.rb b/lib/danbooru/paginator/pagination_error.rb new file mode 100644 index 000000000..f5da127c9 --- /dev/null +++ b/lib/danbooru/paginator/pagination_error.rb @@ -0,0 +1,6 @@ +module Danbooru + module Paginator + class PaginationError < Exception + end + end +end diff --git a/script/testing/reset_post_1.sh b/script/testing/reset_post_1.sh index d38464344..176111dbb 100755 --- a/script/testing/reset_post_1.sh +++ b/script/testing/reset_post_1.sh @@ -1,4 +1,4 @@ #!/usr/bin/env bash -psql -c "UPDATE posts SET is_flagged = false, is_pending = true, approver_string = '' WHERE id = 1" danbooru2 +psql -c "UPDATE posts SET is_flagged = false, is_pending = true, approver_id = null WHERE id = 1" danbooru2 psql -c "DELETE FROM unapprovals" danbooru2 diff --git a/test/factories/upload.rb b/test/factories/upload.rb index 591f2b251..0ab078627 100644 --- a/test/factories/upload.rb +++ b/test/factories/upload.rb @@ -2,7 +2,7 @@ require 'fileutils' Factory.define(:upload) do |f| f.rating "s" - f.uploader {|x| x.association(:user, :is_contributor => true)} + f.uploader {|x| x.association(:user, :level => 200)} f.uploader_ip_addr "127.0.0.1" f.tag_string "special" f.status "pending" diff --git a/test/factories/user.rb b/test/factories/user.rb index 1fcc68dff..9abebc11f 100644 --- a/test/factories/user.rb +++ b/test/factories/user.rb @@ -13,21 +13,21 @@ Factory.define(:banned_user, :parent => :user) do |f| end Factory.define(:privileged_user, :parent => :user) do |f| - f.is_privileged true + f.level 100 end Factory.define(:contributor_user, :parent => :user) do |f| - f.is_contributor true + f.level 200 end Factory.define(:janitor_user, :parent => :user) do |f| - f.is_janitor true + f.level 300 end Factory.define(:moderator_user, :parent => :user) do |f| - f.is_moderator true + f.level 400 end Factory.define(:admin_user, :parent => :user) do |f| - f.is_admin true + f.level 500 end diff --git a/test/unit/post_sets/favorite_test.rb b/test/unit/post_sets/favorite_test.rb index 2e8776eda..e05d53ab7 100644 --- a/test/unit/post_sets/favorite_test.rb +++ b/test/unit/post_sets/favorite_test.rb @@ -25,16 +25,11 @@ module PostSets context "a favorite set for before the most recent post" do setup do id = ::Favorite.model_for(@user.id).where(:user_id => @user.id, :post_id => @post_3.id).first.id - @set = PostSets::Base.new(:id => @user.id, :before_id => id) - @set.stubs(:limit).returns(1) - @set.extend(PostSets::Favorite) + ::Favorite.model_for(@user.id).stubs(:records_per_page).returns(1) + @set = PostSets::Favorite.new(@user.id, "b#{id}") end context "a sequential paginator" do - setup do - @set.extend(PostSets::Sequential) - end - should "return the second most recent element" do assert_equal(1, @set.posts.size) assert_equal(@post_1.id, @set.posts.first.id) @@ -45,35 +40,25 @@ module PostSets context "a favorite set for after the second most recent post" do setup do id = ::Favorite.model_for(@user.id).where(:user_id => @user.id, :post_id => @post_2.id).first.id - @set = PostSets::Base.new(:id => @user.id, :after_id => id) - @set.stubs(:limit).returns(1) - @set.extend(PostSets::Favorite) + ::Favorite.model_for(@user.id).stubs(:records_per_page).returns(1) + @set = PostSets::Favorite.new(@user.id, "a#{id}") end context "a sequential paginator" do - setup do - @set.extend(PostSets::Sequential) - end - should "return the most recent element" do assert_equal(1, @set.posts.size) - assert_equal(@post_3.id, @set.posts.first.id) + assert_equal(@post_1.id, @set.posts.first.id) end end end context "a favorite set for page 2" do setup do - @set = PostSets::Base.new(:id => @user.id, :page => 2) - @set.stubs(:limit).returns(1) - @set.extend(PostSets::Favorite) + ::Favorite.model_for(@user.id).stubs(:records_per_page).returns(1) + @set = PostSets::Favorite.new(@user.id, 2) end context "a numbered paginator" do - setup do - @set.extend(PostSets::Numbered) - end - should "return the second most recent element" do assert_equal(1, @set.posts.size) assert_equal(@post_1.id, @set.posts.first.id) @@ -83,32 +68,13 @@ module PostSets context "a favorite set with no page specified" do setup do - @set = PostSets::Base.new(:id => @user.id) - @set.stubs(:limit).returns(1) - @set.extend(PostSets::Favorite) + ::Favorite.model_for(@user.id).stubs(:records_per_page).returns(1) + @set = PostSets::Favorite.new(@user.id) end - context "a numbered paginator" do - setup do - @set.extend(PostSets::Numbered) - end - - should "return the most recent element" do - assert_equal(3, @set.count) - assert_equal(1, @set.posts.size) - assert_equal(@post_3.id, @set.posts.first.id) - end - end - - context "a sequential paginator" do - setup do - @set.extend(PostSets::Sequential) - end - - should "return the most recent element" do - assert_equal(1, @set.posts.size) - assert_equal(@post_3.id, @set.posts.first.id) - end + should "return the most recent element" do + assert_equal(1, @set.posts.size) + assert_equal(@post_3.id, @set.posts.first.id) end end end diff --git a/test/unit/post_sets/pool_test.rb b/test/unit/post_sets/pool_test.rb index 54561acb3..bbf8ad1f5 100644 --- a/test/unit/post_sets/pool_test.rb +++ b/test/unit/post_sets/pool_test.rb @@ -25,40 +25,33 @@ module PostSets context "a post pool set for page 2" do setup do - @set = PostSets::Base.new(:id => @pool.id, :page => 2) + @set = PostSets::Pool.new(@pool, 2) @set.stubs(:limit).returns(1) - @set.extend(PostSets::Pool) end - context "a numbered paginator" do - setup do - @set.extend(PostSets::Numbered) - end - - should "return the second element" do - assert_equal(1, @set.posts.size) - assert_equal(@post_1.id, @set.posts.first.id) - end + should "return the second element" do + assert_equal(1, @set.posts.size) + assert_equal(@post_1.id, @set.posts.first.id) + end + + should "know the total number of pages" do + assert_equal(3, @set.total_pages) + end + + should "know the current page" do + assert_equal(2, @set.current_page) end end context "a post pool set with no page specified" do setup do - @set = PostSets::Base.new(:id => @pool.id) + @set = PostSets::Pool.new(@pool) @set.stubs(:limit).returns(1) - @set.extend(PostSets::Pool) end - context "a numbered paginator" do - setup do - @set.extend(PostSets::Numbered) - end - - should "return the first element" do - assert_equal(3, @set.count) - assert_equal(1, @set.posts.size) - assert_equal(@post_2.id, @set.posts.first.id) - end + should "return the first element" do + assert_equal(1, @set.posts.size) + assert_equal(@post_2.id, @set.posts.first.id) end end end diff --git a/test/unit/post_sets/post_test.rb b/test/unit/post_sets/post_test.rb index 9a0e4500c..a24ce63d7 100644 --- a/test/unit/post_sets/post_test.rb +++ b/test/unit/post_sets/post_test.rb @@ -1,4 +1,5 @@ require_relative '../../test_helper' +require "danbooru/paginator/pagination_error" module PostSets class PostTest < ActiveSupport::TestCase @@ -19,12 +20,10 @@ module PostSets CurrentUser.ip_addr = nil end - context "a numbered set for page 2" do + context "a set for page 2" do setup do - @set = PostSets::Base.new(:page => 2) - @set.extend(PostSets::Sequential) - @set.extend(PostSets::Post) - @set.stubs(:limit).returns(1) + @set = PostSets::Post.new("", 2) + ::Post.stubs(:records_per_page).returns(1) end should "return the second element" do @@ -32,18 +31,16 @@ module PostSets end end - context "a sequential set for the 'a' tag query" do + context "a set for the 'a' tag query" do setup do @post_4 = Factory.create(:post, :tag_string => "a") @post_5 = Factory.create(:post, :tag_string => "a") end - context "with no before_id parameter" do + context "with no page" do setup do - @set = PostSets::Base.new(:tags => "a") - @set.extend(PostSets::Sequential) - @set.extend(PostSets::Post) - @set.stubs(:limit).returns(1) + @set = PostSets::Post.new("a") + ::Post.stubs(:records_per_page).returns(1) end should "return the first element" do @@ -51,12 +48,10 @@ module PostSets end end - context "with a before_id parameter for the first element" do + context "for before the first element" do setup do - @set = PostSets::Base.new(:tags => "a", :before_id => @post_5.id) - @set.extend(PostSets::Sequential) - @set.extend(PostSets::Post) - @set.stubs(:limit).returns(1) + @set = PostSets::Post.new("a", "b#{@post_5.id}") + ::Post.stubs(:records_per_page).returns(1) end should "return the second element" do @@ -64,12 +59,10 @@ module PostSets end end - context "with an after_id parameter for the second element" do + context "for after the second element" do setup do - @set = PostSets::Base.new(:tags => "a", :after_id => @post_4.id) - @set.extend(PostSets::Sequential) - @set.extend(PostSets::Post) - @set.stubs(:limit).returns(1) + @set = PostSets::Post.new("a", "a#{@post_4.id}") + @set.stubs(:records_per_page).returns(1) end should "return the first element" do @@ -78,11 +71,9 @@ module PostSets end end - context "a new numbered set for the 'a b' tag query" do + context "a set for the 'a b' tag query" do setup do - @set = PostSets::Base.new(:tags => "a b") - @set.extend(PostSets::Numbered) - @set.extend(PostSets::Post) + @set = PostSets::Post.new("a b") end should "know it isn't a single tag" do @@ -90,31 +81,27 @@ module PostSets end end - context "a new numbered set going to the 1,001st page" do + context "a set going to the 1,001st page" do setup do - @set = PostSets::Base.new(:tags => "a", :page => 1_001) - @set.extend(PostSets::Numbered) - @set.extend(PostSets::Post) + @set = PostSets::Post.new("a", 1_001) end - should "not validate" do - assert_raises(PostSets::Error) do - @set.validate + should "fail" do + assert_raises(Danbooru::Paginator::PaginationError) do + @set.posts end end end - context "a new numbered set for the 'a b c' tag query" do + context "a set for the 'a b c' tag query" do setup do - @set = PostSets::Base.new(:tags => "a b c") - @set.extend(PostSets::Numbered) - @set.extend(PostSets::Post) + @set = PostSets::Post.new("a b c") end context "for a non-privileged user" do - should "not validate" do - assert_raises(PostSets::Error) do - @set.validate + should "fail" do + assert_raises(PostSets::SearchError) do + @set.posts end end end @@ -124,25 +111,17 @@ module PostSets CurrentUser.user = Factory.create(:privileged_user) end - should "not validate" do + should "pass" do assert_nothing_raised do - @set.validate + @set.posts end end end end - context "a new numbered set for the 'a' tag query" do + context "a set for the 'a' tag query" do setup do - @set = PostSets::Base.new(:tags => "A") - @set.extend(PostSets::Numbered) - @set.extend(PostSets::Post) - end - - should "validate" do - assert_nothing_raised do - @set.validate - end + @set = PostSets::Post.new("a") end should "know it is a single tag" do @@ -153,8 +132,8 @@ module PostSets assert_equal("a", @set.tag_string) end - should "find the count" do - assert_equal(1, @set.count) + should "know the count" do + assert_equal(1, @set.posts.total_count) end should "find the posts" do diff --git a/test/unit/post_sets/wiki_page_test.rb b/test/unit/post_sets/wiki_page_test.rb deleted file mode 100644 index d730b9f05..000000000 --- a/test/unit/post_sets/wiki_page_test.rb +++ /dev/null @@ -1,73 +0,0 @@ -require 'test_helper' - -module PostSets - class WikiPageTest < ActiveSupport::TestCase - context "In all cases" do - setup do - @user = Factory.create(:user) - CurrentUser.user = @user - CurrentUser.ip_addr = "127.0.0.1" - MEMCACHE.flush_all - - @wiki_page = Factory.create(:wiki_page, :title => "a") - @post_1 = Factory.create(:post, :tag_string => "a") - @post_2 = Factory.create(:post, :tag_string => "a") - @post_3 = Factory.create(:post, :tag_string => "a") - end - - context "a numbered wiki page set" do - setup do - @set = PostSets::Base.new(:page => 2, :id => @wiki_page.id) - @set.extend(PostSets::Numbered) - @set.extend(PostSets::WikiPage) - @set.stubs(:limit).returns(1) - end - - should "return the count" do - assert_equal(3, @set.count) - end - end - - context "a sequential wiki page set" do - context "with a before_id for the first element" do - setup do - @set = PostSets::Base.new(:id => @wiki_page.id, :before_id => @post_3.id) - @set.extend(PostSets::Sequential) - @set.extend(PostSets::WikiPage) - @set.stubs(:limit).returns(1) - end - - should "return the second element" do - assert_equal(@post_2.id, @set.posts.first.id) - end - end - - context "with an after_id for the second element" do - setup do - @set = PostSets::Base.new(:after_id => @post_2.id, :id => @wiki_page.id) - @set.extend(PostSets::Sequential) - @set.extend(PostSets::WikiPage) - @set.stubs(:limit).returns(1) - end - - should "return the first element" do - assert_equal(@post_3.id, @set.posts.first.id) - end - end - end - - context "a numbered wiki page set for page 2" do - setup do - @set = PostSets::Base.new(:page => 2, :id => @wiki_page.id) - @set.extend(PostSets::Numbered) - @set.extend(PostSets::WikiPage) - @set.stubs(:limit).returns(1) - end - - should "return the second element" do - assert_equal(@post_2.id, @set.posts.first.id) - end - end - end - end -end diff --git a/test/unit/post_test.rb b/test/unit/post_test.rb index f5368db64..5ade7165d 100644 --- a/test/unit/post_test.rb +++ b/test/unit/post_test.rb @@ -178,13 +178,13 @@ class PostTest < ActiveSupport::TestCase should "preserve the approver's identity when approved" do post = Factory.create(:post, :is_pending => true) post.approve! - assert_equal("approver:#{CurrentUser.name}", post.approver_string) + assert_equal(post.approver_id, CurrentUser.id) end context "that was previously approved by person X" do should "not allow person X to reapprove that post" do user = Factory.create(:janitor_user, :name => "xxx") - post = Factory.create(:post, :approver_string => "approver:xxx") + post = Factory.create(:post, :approver_id => user.id) post.flag!("bad") CurrentUser.scoped(user, "127.0.0.1") do assert_raises(Post::ApprovalError) do @@ -396,10 +396,10 @@ class PostTest < ActiveSupport::TestCase user3 = Factory.create(:user) post.uploader = user1 - assert_equal("uploader:#{user1.id}", post.uploader_string) + assert_equal(user1.id, post.uploader_id) post.uploader_id = user2.id - assert_equal("uploader:#{user2.id}", post.uploader_string) + assert_equal(user2.id, post.uploader_id) assert_equal(user2.id, post.uploader_id) assert_equal(user2.name, post.uploader_name) end @@ -493,13 +493,15 @@ class PostTest < ActiveSupport::TestCase should "return posts for the metatag" do second_user = Factory.create(:user) - post1 = Factory.create(:post) + post1 = Factory.create(:post, :uploader => CurrentUser.user) + + assert_equal(CurrentUser.id, post1.uploader_id) CurrentUser.scoped(second_user, "127.0.0.2") do post2 = Factory.create(:post) post3 = Factory.create(:post) end - + relation = Post.tag_match("uploader:#{CurrentUser.user.name}") assert_equal(1, relation.count) assert_equal(post1.id, relation.first.id) diff --git a/test/unit/tag_alias_test.rb b/test/unit/tag_alias_test.rb index d4a148e29..f38d92425 100644 --- a/test/unit/tag_alias_test.rb +++ b/test/unit/tag_alias_test.rb @@ -67,7 +67,7 @@ class TagAliasTest < ActiveSupport::TestCase end ta1 = Factory.create(:tag_alias, :antecedent_name => "aaa", :consequent_name => "xxx") p1.reload - assert_not_equal("uploader:#{ta1.creator_id}", p1.uploader_string) + assert_not_equal(ta1.creator_id, p1.uploader_id) assert_equal(ta1.creator_id, p1.versions.last.updater_id) end end diff --git a/test/unit/tag_implication_test.rb b/test/unit/tag_implication_test.rb index 37153fa22..84e10d5c2 100644 --- a/test/unit/tag_implication_test.rb +++ b/test/unit/tag_implication_test.rb @@ -113,7 +113,7 @@ class TagImplicationTest < ActiveSupport::TestCase end ti1 = Factory.create(:tag_implication, :antecedent_name => "aaa", :consequent_name => "xxx") p1.reload - assert_not_equal("uploader:#{ti1.creator_id}", p1.uploader_string) + assert_not_equal(ti1.creator_id, p1.uploader_id) assert_equal(ti1.creator_id, p1.versions.last.updater_id) end end diff --git a/test/unit/upload_test.rb b/test/unit/upload_test.rb index c0c52b66c..68a3bfe3b 100644 --- a/test/unit/upload_test.rb +++ b/test/unit/upload_test.rb @@ -1,181 +1,183 @@ require_relative '../test_helper' class UploadTest < ActiveSupport::TestCase - setup do - user = Factory.create(:contributor_user) - CurrentUser.user = user - CurrentUser.ip_addr = "127.0.0.1" - MEMCACHE.flush_all - end - - teardown do - CurrentUser.user = nil - CurrentUser.ip_addr = nil - - @upload.delete_temp_file if @upload - end - - context "An upload" do + context "In all cases" do + setup do + user = Factory.create(:contributor_user) + CurrentUser.user = user + CurrentUser.ip_addr = "127.0.0.1" + MEMCACHE.flush_all + end + teardown do - FileUtils.rm_f(Dir.glob("#{Rails.root}/tmp/test.*")) + CurrentUser.user = nil + CurrentUser.ip_addr = nil + + @upload.delete_temp_file if @upload end - context "image size calculator" do - should "discover the dimensions for a JPG" do - @upload = Factory.create(:jpg_upload) - assert_nothing_raised {@upload.calculate_dimensions(@upload.file_path)} - assert_equal(500, @upload.image_width) - assert_equal(335, @upload.image_height) - end - - should "discover the dimensions for a PNG" do - @upload = Factory.create(:png_upload) - assert_nothing_raised {@upload.calculate_dimensions(@upload.file_path)} - assert_equal(768, @upload.image_width) - assert_equal(1024, @upload.image_height) - end - - should "discover the dimensions for a GIF" do - @upload = Factory.create(:gif_upload) - assert_nothing_raised {@upload.calculate_dimensions(@upload.file_path)} - assert_equal(400, @upload.image_width) - assert_equal(400, @upload.image_height) - end - end - - context "content type calculator" do - should "know how to parse jpeg, png, gif, and swf file extensions" do - @upload = Factory.create(:jpg_upload) - assert_equal("image/jpeg", @upload.file_ext_to_content_type("test.jpeg")) - assert_equal("image/gif", @upload.file_ext_to_content_type("test.gif")) - assert_equal("image/png", @upload.file_ext_to_content_type("test.png")) - assert_equal("application/x-shockwave-flash", @upload.file_ext_to_content_type("test.swf")) - assert_equal("application/octet-stream", @upload.file_ext_to_content_type("")) - end - - should "know how to parse jpeg, png, gif, and swf content types" do - @upload = Factory.create(:jpg_upload) - assert_equal("jpg", @upload.content_type_to_file_ext("image/jpeg")) - assert_equal("gif", @upload.content_type_to_file_ext("image/gif")) - assert_equal("png", @upload.content_type_to_file_ext("image/png")) - assert_equal("swf", @upload.content_type_to_file_ext("application/x-shockwave-flash")) - assert_equal("bin", @upload.content_type_to_file_ext("")) - end - end - - context "downloader" do - should "initialize the final path and content type after downloading a file" do - @upload = Factory.create(:source_upload) - path = "#{Rails.root}/tmp/test.download.jpg" - assert_nothing_raised {@upload.download_from_source(path)} - assert(File.exists?(path)) - assert_equal(8558, File.size(path)) - assert_equal("image/gif", @upload.content_type) - assert_equal(path, @upload.file_path) - assert_equal("gif", @upload.file_ext) - end - end - - context "file processor" do - should "parse and process a cgi file representation" do - FileUtils.cp("#{Rails.root}/test/files/test.jpg", "#{Rails.root}/tmp") - @upload = Upload.new(:file => upload_jpeg("#{Rails.root}/tmp/test.jpg")) - assert_nothing_raised {@upload.convert_cgi_file} - assert_equal("image/jpeg", @upload.content_type) - assert(File.exists?(@upload.file_path)) - assert_equal(28086, File.size(@upload.file_path)) - assert_equal("jpg", @upload.file_ext) - end - end - - context "hash calculator" do - should "caculate the hash" do - @upload = Factory.create(:jpg_upload) - @upload.calculate_hash(@upload.file_path) - assert_equal("ecef68c44edb8a0d6a3070b5f8e8ee76", @upload.md5) - end - end - - context "resizer" do + context "An upload" do teardown do - FileUtils.rm_f(Dir.glob("#{Rails.root}/public/data/thumb/test.*.jpg")) - FileUtils.rm_f(Dir.glob("#{Rails.root}/public/data/medium/test.*.jpg")) - FileUtils.rm_f(Dir.glob("#{Rails.root}/public/data/large/test.*.jpg")) - FileUtils.rm_f(Dir.glob("#{Rails.root}/public/data/original/test.*.jpg")) + FileUtils.rm_f(Dir.glob("#{Rails.root}/tmp/test.*")) end - - should "generate several resized versions of the image" do - @upload = Factory.create(:large_jpg_upload) - @upload.calculate_hash(@upload.file_path) - @upload.calculate_dimensions(@upload.file_path) - assert_nothing_raised {@upload.generate_resizes(@upload.file_path)} - assert(File.exists?(@upload.resized_file_path_for(Danbooru.config.small_image_width))) - assert_equal(6556, File.size(@upload.resized_file_path_for(Danbooru.config.small_image_width))) - assert(File.exists?(@upload.resized_file_path_for(Danbooru.config.medium_image_width))) - assert_equal(39411, File.size(@upload.resized_file_path_for(Danbooru.config.medium_image_width))) - assert(File.exists?(@upload.resized_file_path_for(Danbooru.config.large_image_width))) - assert_equal(179324, File.size(@upload.resized_file_path_for(Danbooru.config.large_image_width))) + + context "image size calculator" do + should "discover the dimensions for a JPG" do + @upload = Factory.create(:jpg_upload) + assert_nothing_raised {@upload.calculate_dimensions(@upload.file_path)} + assert_equal(500, @upload.image_width) + assert_equal(335, @upload.image_height) + end + + should "discover the dimensions for a PNG" do + @upload = Factory.create(:png_upload) + assert_nothing_raised {@upload.calculate_dimensions(@upload.file_path)} + assert_equal(768, @upload.image_width) + assert_equal(1024, @upload.image_height) + end + + should "discover the dimensions for a GIF" do + @upload = Factory.create(:gif_upload) + assert_nothing_raised {@upload.calculate_dimensions(@upload.file_path)} + assert_equal(400, @upload.image_width) + assert_equal(400, @upload.image_height) + end + end + + context "content type calculator" do + should "know how to parse jpeg, png, gif, and swf file extensions" do + @upload = Factory.create(:jpg_upload) + assert_equal("image/jpeg", @upload.file_ext_to_content_type("test.jpeg")) + assert_equal("image/gif", @upload.file_ext_to_content_type("test.gif")) + assert_equal("image/png", @upload.file_ext_to_content_type("test.png")) + assert_equal("application/x-shockwave-flash", @upload.file_ext_to_content_type("test.swf")) + assert_equal("application/octet-stream", @upload.file_ext_to_content_type("")) + end + + should "know how to parse jpeg, png, gif, and swf content types" do + @upload = Factory.create(:jpg_upload) + assert_equal("jpg", @upload.content_type_to_file_ext("image/jpeg")) + assert_equal("gif", @upload.content_type_to_file_ext("image/gif")) + assert_equal("png", @upload.content_type_to_file_ext("image/png")) + assert_equal("swf", @upload.content_type_to_file_ext("application/x-shockwave-flash")) + assert_equal("bin", @upload.content_type_to_file_ext("")) + end + end + + context "downloader" do + should "initialize the final path and content type after downloading a file" do + @upload = Factory.create(:source_upload) + path = "#{Rails.root}/tmp/test.download.jpg" + assert_nothing_raised {@upload.download_from_source(path)} + assert(File.exists?(path)) + assert_equal(8558, File.size(path)) + assert_equal("image/gif", @upload.content_type) + assert_equal(path, @upload.file_path) + assert_equal("gif", @upload.file_ext) + end + end + + context "file processor" do + should "parse and process a cgi file representation" do + FileUtils.cp("#{Rails.root}/test/files/test.jpg", "#{Rails.root}/tmp") + @upload = Upload.new(:file => upload_jpeg("#{Rails.root}/tmp/test.jpg")) + assert_nothing_raised {@upload.convert_cgi_file} + assert_equal("image/jpeg", @upload.content_type) + assert(File.exists?(@upload.file_path)) + assert_equal(28086, File.size(@upload.file_path)) + assert_equal("jpg", @upload.file_ext) + end + end + + context "hash calculator" do + should "caculate the hash" do + @upload = Factory.create(:jpg_upload) + @upload.calculate_hash(@upload.file_path) + assert_equal("ecef68c44edb8a0d6a3070b5f8e8ee76", @upload.md5) + end + end + + context "resizer" do + teardown do + FileUtils.rm_f(Dir.glob("#{Rails.root}/public/data/thumb/test.*.jpg")) + FileUtils.rm_f(Dir.glob("#{Rails.root}/public/data/medium/test.*.jpg")) + FileUtils.rm_f(Dir.glob("#{Rails.root}/public/data/large/test.*.jpg")) + FileUtils.rm_f(Dir.glob("#{Rails.root}/public/data/original/test.*.jpg")) + end + + should "generate several resized versions of the image" do + @upload = Factory.create(:large_jpg_upload) + @upload.calculate_hash(@upload.file_path) + @upload.calculate_dimensions(@upload.file_path) + assert_nothing_raised {@upload.generate_resizes(@upload.file_path)} + assert(File.exists?(@upload.resized_file_path_for(Danbooru.config.small_image_width))) + assert_equal(6556, File.size(@upload.resized_file_path_for(Danbooru.config.small_image_width))) + assert(File.exists?(@upload.resized_file_path_for(Danbooru.config.medium_image_width))) + assert_equal(39411, File.size(@upload.resized_file_path_for(Danbooru.config.medium_image_width))) + assert(File.exists?(@upload.resized_file_path_for(Danbooru.config.large_image_width))) + assert_equal(179324, File.size(@upload.resized_file_path_for(Danbooru.config.large_image_width))) + end + end + + should "process completely for a downloaded image" do + @upload = Factory.create(:source_upload, + :rating => "s", + :uploader_ip_addr => "127.0.0.1", + :tag_string => "hoge foo" + ) + assert_difference("Post.count") do + assert_nothing_raised {@upload.process!} + end + + post = Post.last + assert_equal("hoge foo", post.tag_string) + assert_equal("s", post.rating) + assert_equal(@upload.uploader_id, post.uploader_id) + assert_equal("127.0.0.1", post.uploader_ip_addr) + assert_equal(@upload.md5, post.md5) + assert_equal("gif", post.file_ext) + assert_equal(276, post.image_width) + assert_equal(110, post.image_height) + assert_equal(8558, post.file_size) + assert_equal(post.id, @upload.post_id) + assert_equal("completed", @upload.status) end end - - should "process completely for a downloaded image" do - @upload = Factory.create(:source_upload, + + should "process completely for an uploaded image" do + @upload = Factory.create(:jpg_upload, :rating => "s", :uploader_ip_addr => "127.0.0.1", :tag_string => "hoge foo" ) + @upload.file = upload_jpeg("#{Rails.root}/test/files/test.jpg") + @upload.convert_cgi_file + assert_difference("Post.count") do assert_nothing_raised {@upload.process!} end - post = Post.last assert_equal("hoge foo", post.tag_string) assert_equal("s", post.rating) assert_equal(@upload.uploader_id, post.uploader_id) assert_equal("127.0.0.1", post.uploader_ip_addr) assert_equal(@upload.md5, post.md5) - assert_equal("gif", post.file_ext) - assert_equal(276, post.image_width) - assert_equal(110, post.image_height) - assert_equal(8558, post.file_size) + assert_equal("jpg", post.file_ext) + assert(File.exists?(post.file_path)) + assert_equal(28086, File.size(post.file_path)) assert_equal(post.id, @upload.post_id) - assert_equal("completed", @upload.status) + assert_equal("completed", @upload.status) end - end - - should "process completely for an uploaded image" do - @upload = Factory.create(:jpg_upload, - :rating => "s", - :uploader_ip_addr => "127.0.0.1", - :tag_string => "hoge foo" - ) - @upload.file = upload_jpeg("#{Rails.root}/test/files/test.jpg") - @upload.convert_cgi_file - assert_difference("Post.count") do - assert_nothing_raised {@upload.process!} + should "delete the temporary file upon completion" do + @upload = Factory.create(:source_upload, + :rating => "s", + :uploader_ip_addr => "127.0.0.1", + :tag_string => "hoge foo" + ) + + @upload.process! + assert(!File.exists?(@upload.temp_file_path)) end - post = Post.last - assert_equal("hoge foo", post.tag_string) - assert_equal("s", post.rating) - assert_equal(@upload.uploader_id, post.uploader_id) - assert_equal("127.0.0.1", post.uploader_ip_addr) - assert_equal(@upload.md5, post.md5) - assert_equal("jpg", post.file_ext) - assert(File.exists?(post.file_path)) - assert_equal(28086, File.size(post.file_path)) - assert_equal(post.id, @upload.post_id) - assert_equal("completed", @upload.status) - end - - should "delete the temporary file upon completion" do - @upload = Factory.create(:source_upload, - :rating => "s", - :uploader_ip_addr => "127.0.0.1", - :tag_string => "hoge foo" - ) - - @upload.process! - assert(!File.exists?(@upload.temp_file_path)) end end diff --git a/test/unit/user_test.rb b/test/unit/user_test.rb index 17841e05e..4d773570b 100644 --- a/test/unit/user_test.rb +++ b/test/unit/user_test.rb @@ -24,9 +24,9 @@ class UserTest < ActiveSupport::TestCase should "limit post uploads" do assert(!@user.can_upload?) - @user.update_attribute(:is_contributor, true) + @user.update_column(:level, User::Levels::CONTRIBUTOR) assert(@user.can_upload?) - @user.update_attribute(:is_contributor, false) + @user.update_column(:level, User::Levels::MEMBER) 40.times do Factory.create(:post, :uploader => @user, :is_deleted => true) @@ -49,10 +49,10 @@ class UserTest < ActiveSupport::TestCase should "limit comments" do assert(!@user.can_comment?) - @user.update_attribute(:is_privileged, true) + @user.update_column(:level, User::Levels::PRIVILEGED) assert(@user.can_comment?) - @user.update_attribute(:is_privileged, false) - @user.update_attribute(:created_at, 1.year.ago) + @user.update_column(:level, User::Levels::MEMBER) + @user.update_column(:created_at, 1.year.ago) assert(@user.can_comment?) (Danbooru.config.member_comment_limit).times do Factory.create(:comment) @@ -79,34 +79,34 @@ class UserTest < ActiveSupport::TestCase end should "normalize its level" do - user = Factory.create(:user, :is_admin => true) + user = Factory.create(:user, :level => User::Levels::ADMIN) assert(user.is_moderator?) assert(user.is_janitor?) assert(user.is_contributor?) assert(user.is_privileged?) - user = Factory.create(:user, :is_moderator => true) + user = Factory.create(:user, :level => User::Levels::MODERATOR) assert(!user.is_admin?) assert(user.is_moderator?) assert(user.is_janitor?) - assert(!user.is_contributor?) + assert(user.is_contributor?) assert(user.is_privileged?) - user = Factory.create(:user, :is_janitor => true) + user = Factory.create(:user, :level => User::Levels::JANITOR) assert(!user.is_admin?) assert(!user.is_moderator?) assert(user.is_janitor?) assert(!user.is_contributor?) assert(user.is_privileged?) - user = Factory.create(:user, :is_contributor => true) + user = Factory.create(:user, :level => User::Levels::CONTRIBUTOR) assert(!user.is_admin?) assert(!user.is_moderator?) assert(!user.is_janitor?) assert(user.is_contributor?) assert(user.is_privileged?) - user = Factory.create(:user, :is_privileged => true) + user = Factory.create(:user, :level => User::LEvels::PRIVILEGED) assert(!user.is_admin?) assert(!user.is_moderator?) assert(!user.is_janitor?) @@ -133,8 +133,8 @@ class UserTest < ActiveSupport::TestCase should "be updated" do @user = Factory.create(:user) - @user.update_attribute(:name, "danzig") - assert_equal("danzig", User.id_to_name(@user.id)) + @user.update_column(:name, "danzig") + assert_equal(@user.name, User.id_to_name(@user.id)) end end