diff --git a/app/controllers/tag_alias_corrections_controller.rb b/app/controllers/tag_alias_corrections_controller.rb index 23c00b723..2ceb919d2 100644 --- a/app/controllers/tag_alias_corrections_controller.rb +++ b/app/controllers/tag_alias_corrections_controller.rb @@ -1,10 +1,6 @@ class TagAliasCorrectionsController < ApplicationController before_filter :moderator_only - def new - @correction = TagAliasCorrection.new(params[:tag_alias_id]) - end - def create @correction = TagAliasCorrection.new(params[:tag_alias_id]) @@ -13,7 +9,7 @@ class TagAliasCorrectionsController < ApplicationController flash[:notice] = "The fix has been queued and will be processed" end - redirect_to tag_alias_correction_path(:id => params[:tag_alias_id]) + redirect_to tag_alias_correction_path(:tag_alias_id => params[:tag_alias_id]) end def show diff --git a/app/controllers/tag_alias_requests_controller.rb b/app/controllers/tag_alias_requests_controller.rb new file mode 100644 index 000000000..58737998a --- /dev/null +++ b/app/controllers/tag_alias_requests_controller.rb @@ -0,0 +1,17 @@ +class TagAliasRequestsController < ApplicationController + before_filter :member_only + rescue_from TagAliasRequest::ValidationError, :with => :rescue_exception + + def new + end + + def create + @tag_alias_request = TagAliasRequest.new( + params[:tag_alias_request][:antecedent_name], + params[:tag_alias_request][:consequent_name], + params[:tag_alias_request][:reason] + ) + @tag_alias_request.create + redirect_to(forum_topic_path(@tag_alias_request.forum_topic)) + end +end diff --git a/app/controllers/tag_aliases_controller.rb b/app/controllers/tag_aliases_controller.rb index 1dd675ef1..1e9329984 100644 --- a/app/controllers/tag_aliases_controller.rb +++ b/app/controllers/tag_aliases_controller.rb @@ -1,5 +1,5 @@ class TagAliasesController < ApplicationController - before_filter :admin_only, :only => [:approve, :destroy, :create] + before_filter :admin_only, :only => [:approve, :destroy, :new, :create] respond_to :html, :xml, :json, :js def new diff --git a/app/controllers/tag_implication_requests_controller.rb b/app/controllers/tag_implication_requests_controller.rb new file mode 100644 index 000000000..c212fc3fc --- /dev/null +++ b/app/controllers/tag_implication_requests_controller.rb @@ -0,0 +1,17 @@ +class TagImplicationRequestsController < ApplicationController + before_filter :member_only + rescue_from TagImplicationRequest::ValidationError, :with => :rescue_exception + + def new + end + + def create + @tag_implication_request = TagImplicationRequest.new( + params[:tag_implication_request][:antecedent_name], + params[:tag_implication_request][:consequent_name], + params[:tag_implication_request][:reason] + ) + @tag_implication_request.create + redirect_to(forum_topic_path(@tag_implication_request.forum_topic)) + end +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index cc356df71..7aa494cf3 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -143,10 +143,10 @@ protected when "moderator/dashboards" /^\/moderator/ - when "tag_aliases", "tag_alias_corrections" + when "tag_aliases", "tag_alias_corrections", "tag_alias_requests" /^\/tag_aliases/ - when "tag_implications" + when "tag_implications", "tag_implication_requests" /^\/tag_implications/ when "wiki_pages", "wiki_page_versions" diff --git a/app/logical/tag_alias_request.rb b/app/logical/tag_alias_request.rb new file mode 100644 index 000000000..d97541bae --- /dev/null +++ b/app/logical/tag_alias_request.rb @@ -0,0 +1,39 @@ +class TagAliasRequest + class ValidationError < Exception ; end + + attr_reader :antecedent_name, :consequent_name, :reason, :tag_alias, :forum_topic + + def initialize(antecedent_name, consequent_name, reason) + @antecedent_name = antecedent_name + @consequent_name = consequent_name + @reason = reason + end + + def create + TagAlias.transaction do + create_alias + create_forum_topic + end + end + + def create_alias + @tag_alias = TagAlias.create(:antecedent_name => antecedent_name, :consequent_name => consequent_name, :status => "pending") + if @tag_alias.errors.any? + raise ValidationError.new(@tag_alias.errors.full_messages.join("; ")) + end + end + + def create_forum_topic + @forum_topic = ForumTopic.create( + :title => "Tag alias: #{antecedent_name} -> #{consequent_name}", + :original_post_attributes => { + :body => reason + "\n\n\"Link to alias\":/tag_aliases?search[id]=#{tag_alias.id}" + } + ) + if @forum_topic.errors.any? + raise ValidationError.new(@forum_topic.errors.full_messages.join("; ")) + end + + tag_alias.update_attribute(:forum_topic_id, @forum_topic.id) + end +end diff --git a/app/logical/tag_implication_request.rb b/app/logical/tag_implication_request.rb new file mode 100644 index 000000000..bd148efc0 --- /dev/null +++ b/app/logical/tag_implication_request.rb @@ -0,0 +1,39 @@ +class TagImplicationRequest + class ValidationError < Exception ; end + + attr_reader :antecedent_name, :consequent_name, :reason, :tag_implication, :forum_topic + + def initialize(antecedent_name, consequent_name, reason) + @antecedent_name = antecedent_name + @consequent_name = consequent_name + @reason = reason + end + + def create + TagImplication.transaction do + create_implication + create_forum_topic + end + end + + def create_implication + @tag_implication = TagImplication.create(:antecedent_name => antecedent_name, :consequent_name => consequent_name, :status => "pending") + if @tag_implication.errors.any? + raise ValidationError.new(@tag_implication.errors.full_messages.join("; ")) + end + end + + def create_forum_topic + @forum_topic = ForumTopic.create( + :title => "Tag implication: #{antecedent_name} -> #{consequent_name}", + :original_post_attributes => { + :body => reason + "\n\n\"Link to implication\":/tag_implications?search[id]=#{tag_implication.id}" + } + ) + if @forum_topic.errors.any? + raise ValidationError.new(@forum_topic.errors.full_messages.join("; ")) + end + + tag_implication.update_attribute(:forum_topic_id, @forum_topic.id) + end +end diff --git a/app/models/tag_alias.rb b/app/models/tag_alias.rb index 5705e415a..0101b25ab 100644 --- a/app/models/tag_alias.rb +++ b/app/models/tag_alias.rb @@ -4,10 +4,11 @@ class TagAlias < ActiveRecord::Base after_save :ensure_category_consistency after_destroy :clear_all_cache before_validation :initialize_creator, :on => :create - validates_presence_of :creator_id + validates_presence_of :creator_id, :antecedent_name, :consequent_name validates_uniqueness_of :antecedent_name validate :absence_of_transitive_relation belongs_to :creator, :class_name => "User" + belongs_to :forum_topic module SearchMethods def name_matches(name) diff --git a/app/models/tag_implication.rb b/app/models/tag_implication.rb index a0a448330..f5f692d43 100644 --- a/app/models/tag_implication.rb +++ b/app/models/tag_implication.rb @@ -3,7 +3,7 @@ class TagImplication < ActiveRecord::Base after_save :update_descendant_names_for_parent belongs_to :creator, :class_name => "User" before_validation :initialize_creator, :on => :create - validates_presence_of :creator_id + validates_presence_of :creator_id, :antecedent_name, :consequent_name validates_uniqueness_of :antecedent_name, :scope => :consequent_name validate :absence_of_circular_relation diff --git a/app/views/tag_alias_corrections/show.html.erb b/app/views/tag_alias_corrections/show.html.erb index cac335921..36042bef1 100644 --- a/app/views/tag_alias_corrections/show.html.erb +++ b/app/views/tag_alias_corrections/show.html.erb @@ -16,8 +16,7 @@

You can try to fix this alias. This will clear the cache and re-save all posts associated with <%= @correction.antecedent_name %>.

-<%= form_tag(tag_alias_correction_path) do %> - <%= hidden_field "tag_alias_id", params[:tag_alias_id] %> +<%= form_tag(tag_alias_correction_path(:tag_alias_id => @correction.tag_alias_id)) do %> <%= submit_tag "Fix" %> <%= submit_tag "Cancel" %> <% end %> diff --git a/app/views/tag_alias_requests/new.html.erb b/app/views/tag_alias_requests/new.html.erb new file mode 100644 index 000000000..30bd8363c --- /dev/null +++ b/app/views/tag_alias_requests/new.html.erb @@ -0,0 +1,30 @@ +
+
+

Tag Alias Request

+ +

You can request a new tag alias be created. This will create a corresponding forum topic for community review.

+ + <%= form_tag(tag_alias_request_path, :class => "simple_form") do %> +
+ + <%= text_field "tag_alias_request", "antecedent_name" %> +
+ +
+ + <%= text_field "tag_alias_request", "consequent_name" %> +
+ +
+ + <%= text_area "tag_alias_request", "reason" %> +
+ +
+ <%= submit_tag "Submit" %> +
+ <% end %> + + <%= render "tag_aliases/secondary_links" %> +
+
diff --git a/app/views/tag_aliases/_secondary_links.html.erb b/app/views/tag_aliases/_secondary_links.html.erb index f46665a77..6ae9582db 100644 --- a/app/views/tag_aliases/_secondary_links.html.erb +++ b/app/views/tag_aliases/_secondary_links.html.erb @@ -1,7 +1,11 @@ <% content_for(:secondary_links) do %>
  • <%= link_to "Listing", tag_aliases_path %>
  • -
  • <%= link_to "New", new_tag_alias_path %>
  • + <% if CurrentUser.is_admin? %> +
  • <%= link_to "New", new_tag_alias_path %>
  • + <% else %> +
  • <%= link_to "Request", new_tag_alias_request_path %>
  • + <% end %>
  • <%= link_to "Help", wiki_pages_path(:title => "help:tag_aliases") %>
  • <% end %> diff --git a/app/views/tag_implication_requests/new.html.erb b/app/views/tag_implication_requests/new.html.erb new file mode 100644 index 000000000..7399fddb2 --- /dev/null +++ b/app/views/tag_implication_requests/new.html.erb @@ -0,0 +1,30 @@ +
    +
    +

    Tag Implication Request

    + +

    You can request a new tag implication be created. This will create a corresponding forum topic for community review.

    + + <%= form_tag(tag_implication_request_path, :class => "simple_form") do %> +
    + + <%= text_field "tag_implication_request", "antecedent_name" %> +
    + +
    + + <%= text_field "tag_implication_request", "consequent_name" %> +
    + +
    + + <%= text_area "tag_implication_request", "reason" %> +
    + +
    + <%= submit_tag "Submit" %> +
    + <% end %> + + <%= render "tag_implications/secondary_links" %> +
    +
    diff --git a/app/views/tag_implications/_secondary_links.html.erb b/app/views/tag_implications/_secondary_links.html.erb index 33d8432c8..c0d9bb58c 100644 --- a/app/views/tag_implications/_secondary_links.html.erb +++ b/app/views/tag_implications/_secondary_links.html.erb @@ -1,7 +1,11 @@ <% content_for(:secondary_links) do %>
  • <%= link_to "Listing", tag_implications_path %>
  • -
  • <%= link_to "New", new_tag_implication_path %>
  • + <% if CurrentUser.is_admin? %> +
  • <%= link_to "New", new_tag_implication_path %>
  • + <% else %> +
  • <%= link_to "Request", new_tag_implication_request_path %>
  • + <% end %>
  • <%= link_to "Help", wiki_pages_path(:title => "help:tag_implications") %>
  • <% end %> diff --git a/config/routes.rb b/config/routes.rb index 6d125ea72..ad5c9d84e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -167,11 +167,13 @@ Danbooru::Application.routes.draw do end end resource :tag_alias_correction, :only => [:new, :create, :show] + resource :tag_alias_request, :only => [:new, :create] resources :tag_implications do member do post :approve end end + resource :tag_implication_request, :only => [:new, :create] resources :tag_subscriptions do member do get :posts diff --git a/test/functional/tag_alias_corrections_controller_test.rb b/test/functional/tag_alias_corrections_controller_test.rb new file mode 100644 index 000000000..6a3163f54 --- /dev/null +++ b/test/functional/tag_alias_corrections_controller_test.rb @@ -0,0 +1,33 @@ +require 'test_helper' + +class TagAliasCorrectionsControllerTest < ActionController::TestCase + context "The tag alias correction controller" do + setup do + @admin = FactoryGirl.create(:admin_user) + CurrentUser.user = @admin + CurrentUser.ip_addr = "127.0.0.1" + MEMCACHE.flush_all + Delayed::Worker.delay_jobs = false + @tag_alias = FactoryGirl.create(:tag_alias, :antecedent_name => "aaa", :consequent_name => "bbb") + end + + teardown do + CurrentUser.user = nil + CurrentUser.ip_addr = nil + end + + context "show action" do + should "render" do + get :show, {:tag_alias_id => @tag_alias.id}, {:user => @admin.id} + assert_response :success + end + end + + context "create action" do + should "render" do + post :create, {:tag_alias_id => @tag_alias.id, :commit => "Fix"}, {:user => @admin.id} + assert_redirected_to(tag_alias_correction_path(:tag_alias_id => @tag_alias.id)) + end + end + end +end diff --git a/test/functional/tag_alias_requests_controller_test.rb b/test/functional/tag_alias_requests_controller_test.rb new file mode 100644 index 000000000..3272ed316 --- /dev/null +++ b/test/functional/tag_alias_requests_controller_test.rb @@ -0,0 +1,34 @@ +require 'test_helper' + +class TagAliasRequestsControllerTest < ActionController::TestCase + context "The tag alias request controller" do + setup do + @user = FactoryGirl.create(:user) + CurrentUser.user = @user + CurrentUser.ip_addr = "127.0.0.1" + MEMCACHE.flush_all + Delayed::Worker.delay_jobs = false + end + + teardown do + CurrentUser.user = nil + CurrentUser.ip_addr = nil + end + + context "new action" do + should "render" do + get :new, {}, {:user => @user.id} + assert_response :success + end + end + + context "create action" do + should "render" do + assert_difference("ForumTopic.count", 1) do + post :create, {:tag_alias_request => {:antecedent_name => "aaa", :consequent_name => "bbb", :reason => "ccc"}}, {:user => @user.id} + end + assert_redirected_to(forum_topic_path(ForumTopic.last)) + end + end + end +end diff --git a/test/functional/tag_implication_requests_controller.rb b/test/functional/tag_implication_requests_controller.rb new file mode 100644 index 000000000..0cbf03247 --- /dev/null +++ b/test/functional/tag_implication_requests_controller.rb @@ -0,0 +1,34 @@ +require 'test_helper' + +class TagImplicationRequestsControllerTest < ActionController::TestCase + context "The tag implication request controller" do + setup do + @user = FactoryGirl.create(:user) + CurrentUser.user = @user + CurrentUser.ip_addr = "127.0.0.1" + MEMCACHE.flush_all + Delayed::Worker.delay_jobs = false + end + + teardown do + CurrentUser.user = nil + CurrentUser.ip_addr = nil + end + + context "new action" do + should "render" do + get :new, {}, {:user => @user.id} + assert_response :success + end + end + + context "create action" do + should "render" do + assert_difference("ForumTopic.count", 1) do + post :create, {:tag_implication_request => {:antecedent_name => "aaa", :consequent_name => "bbb", :reason => "ccc"}}, {:user => @user.id} + end + assert_redirected_to(forum_topic_path(ForumTopic.last)) + end + end + end +end diff --git a/test/functional/tag_implications_controller_test.rb b/test/functional/tag_implications_controller_test.rb index 393371dcf..fb7589d9f 100644 --- a/test/functional/tag_implications_controller_test.rb +++ b/test/functional/tag_implications_controller_test.rb @@ -1,7 +1,7 @@ require 'test_helper' class TagImplicationsControllerTest < ActionController::TestCase - context "The tag implicationes controller" do + context "The tag implications controller" do setup do @user = FactoryGirl.create(:admin_user) CurrentUser.user = @user diff --git a/test/unit/tag_alias_correction_test.rb b/test/unit/tag_alias_correction_test.rb index 2790f7824..32705e631 100644 --- a/test/unit/tag_alias_correction_test.rb +++ b/test/unit/tag_alias_correction_test.rb @@ -1,7 +1,7 @@ require 'test_helper' -class TagAliasTest < ActiveSupport::TestCase - context "A tag alias" do +class TagAliasCorrectionTest < ActiveSupport::TestCase + context "A tag alias correction" do setup do @mod = FactoryGirl.create(:moderator_user) CurrentUser.user = @mod diff --git a/test/unit/tag_alias_request_test.rb b/test/unit/tag_alias_request_test.rb new file mode 100644 index 000000000..452ddb8b0 --- /dev/null +++ b/test/unit/tag_alias_request_test.rb @@ -0,0 +1,44 @@ +require 'test_helper' + +class TagAliasRequestTest < ActiveSupport::TestCase + context "A tag alias request" do + setup do + @user = FactoryGirl.create(:user) + CurrentUser.user = @user + CurrentUser.ip_addr = "127.0.0.1" + MEMCACHE.flush_all + Delayed::Worker.delay_jobs = false + end + + teardown do + MEMCACHE.flush_all + CurrentUser.user = nil + CurrentUser.ip_addr = nil + end + + should "raise an exception if invalid" do + assert_raises(TagAliasRequest::ValidationError) do + TagAliasRequest.new("", "", "reason").create + end + end + + should "create a tag alias" do + assert_difference("TagAlias.count", 1) do + TagAliasRequest.new("aaa", "bbb", "reason").create + end + assert_equal("pending", TagAlias.last.status) + end + + should "create a forum topic" do + assert_difference("ForumTopic.count", 1) do + TagAliasRequest.new("aaa", "bbb", "reason").create + end + end + + should "create a forum post" do + assert_difference("ForumPost.count", 1) do + TagAliasRequest.new("aaa", "bbb", "reason").create + end + end + end +end diff --git a/test/unit/tag_implication_request_test.rb b/test/unit/tag_implication_request_test.rb new file mode 100644 index 000000000..f53f50633 --- /dev/null +++ b/test/unit/tag_implication_request_test.rb @@ -0,0 +1,44 @@ +require 'test_helper' + +class TagImplicationRequestTest < ActiveSupport::TestCase + context "A tag implication request" do + setup do + @user = FactoryGirl.create(:user) + CurrentUser.user = @user + CurrentUser.ip_addr = "127.0.0.1" + MEMCACHE.flush_all + Delayed::Worker.delay_jobs = false + end + + teardown do + MEMCACHE.flush_all + CurrentUser.user = nil + CurrentUser.ip_addr = nil + end + + should "raise an exception if invalid" do + assert_raises(TagImplicationRequest::ValidationError) do + TagImplicationRequest.new("", "", "reason").create + end + end + + should "create a tag implication" do + assert_difference("TagImplication.count", 1) do + TagImplicationRequest.new("aaa", "bbb", "reason").create + end + assert_equal("pending", TagImplication.last.status) + end + + should "create a forum topic" do + assert_difference("ForumTopic.count", 1) do + TagImplicationRequest.new("aaa", "bbb", "reason").create + end + end + + should "create a forum post" do + assert_difference("ForumPost.count", 1) do + TagImplicationRequest.new("aaa", "bbb", "reason").create + end + end + end +end