diff --git a/app/assets/javascripts/discourse/controllers/topic_bulk_actions_controller.js b/app/assets/javascripts/discourse/controllers/topic_bulk_actions_controller.js index 37245d25a..d0176b28c 100644 --- a/app/assets/javascripts/discourse/controllers/topic_bulk_actions_controller.js +++ b/app/assets/javascripts/discourse/controllers/topic_bulk_actions_controller.js @@ -37,8 +37,9 @@ Discourse.TopicBulkActionsController = Ember.ArrayController.extend(Discourse.Mo changeCategory: function() { var category = Discourse.Category.findById(parseInt(this.get('newCategoryId'), 10)), + categoryName = (category ? category.get('name') : null), self = this; - this.perform({type: 'change_category', category_id: this.get('newCategoryId')}).then(function(topics) { + this.perform({type: 'change_category', category_name: categoryName}).then(function(topics) { topics.forEach(function(t) { t.set('category', category); }); diff --git a/lib/topics_bulk_action.rb b/lib/topics_bulk_action.rb index f0e0dc91c..e4dcc6535 100644 --- a/lib/topics_bulk_action.rb +++ b/lib/topics_bulk_action.rb @@ -6,9 +6,34 @@ class TopicsBulkAction @operation = operation end - def perform! - [] + def self.operations + %w(change_category) end + def perform! + raise Discourse::InvalidParameters.new(:operation) unless TopicsBulkAction.operations.include?(@operation[:type]) + send(@operation[:type]) + end + + private + + def change_category + changed_ids = [] + topics.each do |t| + if guardian.can_edit?(t) + changed_ids << t.id if t.change_category(@operation[:category_name]) + end + end + changed_ids + end + + def guardian + @guardian ||= Guardian.new(@user) + end + + def topics + @topics ||= Topic.where(id: @topic_ids) + end + end diff --git a/spec/components/topics_bulk_action_spec.rb b/spec/components/topics_bulk_action_spec.rb new file mode 100644 index 000000000..3e0d3b7f0 --- /dev/null +++ b/spec/components/topics_bulk_action_spec.rb @@ -0,0 +1,42 @@ +require 'spec_helper' +require 'topics_bulk_action' + +describe TopicsBulkAction do + + describe "invalid operation" do + let(:user) { Fabricate.build(:user) } + + it "raises an error with an invalid operation" do + tba = TopicsBulkAction.new(user, [1], type: 'rm_root') + -> { tba.perform! }.should raise_error(Discourse::InvalidParameters) + end + end + + describe "change_category" do + let(:topic) { Fabricate(:topic) } + let(:category) { Fabricate(:category) } + + context "when the user can edit the topic" do + it "changes the category and returns the topic_id" do + tba = TopicsBulkAction.new(topic.user, [topic.id], type: 'change_category', category_name: category.name) + topic_ids = tba.perform! + topic_ids.should == [topic.id] + topic.reload + topic.category.should == category + end + end + + context "when the user can't edit the topic" do + it "doesn't change the category and returns the topic_id" do + Guardian.any_instance.expects(:can_edit?).returns(false) + tba = TopicsBulkAction.new(topic.user, [topic.id], type: 'change_category', category_name: category.name) + topic_ids = tba.perform! + topic_ids.should == [] + topic.reload + topic.category.should_not == category + end + end + + end +end +