diff --git a/plugins/poll/assets/javascripts/discourse/templates/poll.js.handlebars b/plugins/poll/assets/javascripts/discourse/templates/poll.js.handlebars
index 82b3ecd4f26..c7197451306 100644
--- a/plugins/poll/assets/javascripts/discourse/templates/poll.js.handlebars
+++ b/plugins/poll/assets/javascripts/discourse/templates/poll.js.handlebars
@@ -24,6 +24,18 @@
{{/if}}
+{{#if poll.post.topic.details.can_edit}}
+
+{{/if}}
+
{{#if loading}}
{{/if}}
diff --git a/plugins/poll/assets/javascripts/poll_ui.js b/plugins/poll/assets/javascripts/poll_ui.js
index 4e4bc8a560f..90407615f3e 100644
--- a/plugins/poll/assets/javascripts/poll_ui.js
+++ b/plugins/poll/assets/javascripts/poll_ui.js
@@ -44,7 +44,6 @@ var Poll = Discourse.Model.extend({
var PollController = Discourse.Controller.extend({
poll: null,
showResults: Em.computed.oneWay('poll.closed'),
-
disableRadio: Em.computed.any('poll.closed', 'loading'),
actions: {
@@ -67,6 +66,18 @@ var PollController = Discourse.Controller.extend({
toggleShowResults: function() {
this.set('showResults', !this.get('showResults'));
+ },
+
+ toggleClosePoll: function() {
+ this.set('loading', true);
+ return Discourse.ajax("/poll/toggle_close", {
+ type: "PUT",
+ data: {post_id: this.get('poll.post.id')}
+ }).then(function(topicJson) {
+ this.set('poll.post.topic.title', topicJson.basic_topic.title);
+ this.set('poll.post.topic.fancy_title', topicJson.basic_topic.title);
+ this.set('loading', false);
+ }.bind(this));
}
}
});
diff --git a/plugins/poll/config/locales/client.en.yml b/plugins/poll/config/locales/client.en.yml
index 0d9ed7c52bc..23169bcfcc1 100644
--- a/plugins/poll/config/locales/client.en.yml
+++ b/plugins/poll/config/locales/client.en.yml
@@ -15,3 +15,6 @@ en:
results:
show: Show Results
hide: Hide Results
+
+ close_poll: "Close Poll"
+ open_poll: "Open Poll"
diff --git a/plugins/poll/plugin.rb b/plugins/poll/plugin.rb
index 64d1a598bc3..fddf8251617 100644
--- a/plugins/poll/plugin.rb
+++ b/plugins/poll/plugin.rb
@@ -58,11 +58,45 @@ after_initialize do
render json: poll.serialize(current_user)
end
+
+ def toggle_close
+ post = Post.find(params[:post_id])
+ topic = post.topic
+ poll = PollPlugin::Poll.new(post)
+
+ # Make sure the user is allowed to close the poll.
+ Guardian.new(current_user).ensure_can_edit!(topic)
+
+ # Make sure this is actually a poll.
+ unless poll.has_poll_details?
+ render status: 400, json: false
+ return
+ end
+
+ # Make sure the topic is not closed.
+ if topic.closed?
+ render status: 400, json: false
+ return
+ end
+
+ # Modify topic title.
+ if topic.title =~ /^(#{I18n.t('poll.prefix').strip})\s?:/i
+ topic.title = topic.title.gsub(/^(#{I18n.t('poll.prefix').strip})\s?:/i, I18n.t('poll.closed_prefix') + ':')
+ elsif topic.title =~ /^(#{I18n.t('poll.closed_prefix').strip})\s?:/i
+ topic.title = topic.title.gsub(/^(#{I18n.t('poll.closed_prefix').strip})\s?:/i, I18n.t('poll.prefix') + ':')
+ end
+
+ topic.acting_user = current_user
+ topic.save!
+
+ render json: topic, serializer: BasicTopicSerializer
+ end
end
end
PollPlugin::Engine.routes.draw do
put '/' => 'poll#vote'
+ put '/toggle_close' => 'poll#toggle_close'
end
Discourse::Application.routes.append do
diff --git a/plugins/poll/spec/poll_plugin/poll_controller_spec.rb b/plugins/poll/spec/poll_plugin/poll_controller_spec.rb
index 7ccdc471ffe..a621db5762d 100644
--- a/plugins/poll/spec/poll_plugin/poll_controller_spec.rb
+++ b/plugins/poll/spec/poll_plugin/poll_controller_spec.rb
@@ -2,52 +2,89 @@ require 'spec_helper'
describe PollPlugin::PollController, type: :controller do
let(:topic) { create_topic(title: "Poll: Chitoge vs Onodera") }
- let(:post) { create_post(topic: topic, raw: "Pick one.\n\n[poll]\n* Chitoge\n* Onodera\n[/poll]") }
+ let!(:post) { create_post(topic: topic, raw: "Pick one.\n\n[poll]\n* Chitoge\n* Onodera\n[/poll]") }
let(:user1) { Fabricate(:user) }
let(:user2) { Fabricate(:user) }
+ let(:admin) { Fabricate(:admin) }
- it "should return 403 if no user is logged in" do
- xhr :put, :vote, post_id: post.id, option: "Chitoge", use_route: :poll
- response.should be_forbidden
+ describe 'vote' do
+ it "returns 403 if no user is logged in" do
+ xhr :put, :vote, post_id: post.id, option: "Chitoge", use_route: :poll
+ response.should be_forbidden
+ end
+
+ it "returns 400 if post_id or invalid option is not specified" do
+ log_in_user user1
+ xhr :put, :vote, use_route: :poll
+ response.status.should eq(400)
+ xhr :put, :vote, post_id: post.id, use_route: :poll
+ response.status.should eq(400)
+ xhr :put, :vote, option: "Chitoge", use_route: :poll
+ response.status.should eq(400)
+ xhr :put, :vote, post_id: post.id, option: "Tsugumi", use_route: :poll
+ response.status.should eq(400)
+ end
+
+ it "returns 400 if post_id doesn't correspond to a poll post" do
+ log_in_user user1
+ post2 = create_post(topic: topic, raw: "Generic reply")
+ xhr :put, :vote, post_id: post2.id, option: "Chitoge", use_route: :poll
+ end
+
+ it "saves votes correctly" do
+ MessageBus.expects(:publish).times(3)
+
+ log_in_user user1
+ xhr :put, :vote, post_id: post.id, option: "Chitoge", use_route: :poll
+ PollPlugin::Poll.new(post).get_vote(user1).should eq("Chitoge")
+
+ log_in_user user2
+ xhr :put, :vote, post_id: post.id, option: "Onodera", use_route: :poll
+ PollPlugin::Poll.new(post).get_vote(user2).should eq("Onodera")
+
+ PollPlugin::Poll.new(post).details["Chitoge"].should eq(1)
+ PollPlugin::Poll.new(post).details["Onodera"].should eq(1)
+
+ xhr :put, :vote, post_id: post.id, option: "Chitoge", use_route: :poll
+ PollPlugin::Poll.new(post).get_vote(user2).should eq("Chitoge")
+
+ PollPlugin::Poll.new(post).details["Chitoge"].should eq(2)
+ PollPlugin::Poll.new(post).details["Onodera"].should eq(0)
+ end
end
- it "should return 400 if post_id or invalid option is not specified" do
- log_in_user user1
- xhr :put, :vote, use_route: :poll
- response.status.should eq(400)
- xhr :put, :vote, post_id: post.id, use_route: :poll
- response.status.should eq(400)
- xhr :put, :vote, option: "Chitoge", use_route: :poll
- response.status.should eq(400)
- xhr :put, :vote, post_id: post.id, option: "Tsugumi", use_route: :poll
- response.status.should eq(400)
- end
+ describe 'toggle_close' do
+ it "returns 400 if post_id doesn't correspond to a poll post" do
+ log_in_user admin
+ post2 = create_post(topic: topic, raw: "Generic reply")
+ xhr :put, :toggle_close, post_id: post2.id, use_route: :poll
+ response.status.should eq(400)
+ end
- it "should return 400 if post_id doesn't correspond to a poll post" do
- log_in_user user1
- post2 = create_post(topic: topic, raw: "Generic reply")
- xhr :put, :vote, post_id: post2.id, option: "Chitoge", use_route: :poll
- response.status.should eq(400)
- end
+ it "returns 400 if the topic is locked" do
+ log_in_user admin
+ topic.update_attributes closed: true
+ xhr :put, :toggle_close, post_id: post.id, use_route: :poll
+ response.status.should eq(400)
+ end
- it "should save votes correctly" do
- MessageBus.expects(:publish).times(4)
+ it "raises Discourse::InvalidAccess is the user is not authorized" do
+ log_in_user user1
+ expect do
+ xhr :put, :toggle_close, post_id: post.id, use_route: :poll
+ end.to raise_error(Discourse::InvalidAccess)
+ end
- log_in_user user1
- xhr :put, :vote, post_id: post.id, option: "Chitoge", use_route: :poll
- PollPlugin::Poll.new(post).get_vote(user1).should eq("Chitoge")
-
- log_in_user user2
- xhr :put, :vote, post_id: post.id, option: "Onodera", use_route: :poll
- PollPlugin::Poll.new(post).get_vote(user2).should eq("Onodera")
-
- PollPlugin::Poll.new(post).details["Chitoge"].should eq(1)
- PollPlugin::Poll.new(post).details["Onodera"].should eq(1)
-
- xhr :put, :vote, post_id: post.id, option: "Chitoge", use_route: :poll
- PollPlugin::Poll.new(post).get_vote(user2).should eq("Chitoge")
-
- PollPlugin::Poll.new(post).details["Chitoge"].should eq(2)
- PollPlugin::Poll.new(post).details["Onodera"].should eq(0)
+ it "renames the topic" do
+ I18n.stubs(:t).with('poll.prefix').returns("Poll ")
+ I18n.stubs(:t).with('poll.closed_prefix').returns("Closed Poll ")
+ log_in_user admin
+ xhr :put, :toggle_close, post_id: post.id, use_route: :poll
+ response.status.should eq(200)
+ topic.reload.title.should == "Closed Poll : Chitoge vs Onodera"
+ xhr :put, :toggle_close, post_id: post.id, use_route: :poll
+ response.status.should eq(200)
+ topic.reload.title.should == "Poll : Chitoge vs Onodera"
+ end
end
end