diff --git a/app/controllers/forem/topics_controller.rb b/app/controllers/forem/topics_controller.rb index c3710649a..6fdbdb95a 100644 --- a/app/controllers/forem/topics_controller.rb +++ b/app/controllers/forem/topics_controller.rb @@ -51,6 +51,9 @@ def subscribe def unsubscribe if find_topic + subscription = @topic.subscriptions.find_by(subscriber_id: forem_user.id, token: params[:token]) + unsubscribe_unsuccessful and return unless subscription + @topic.unsubscribe_user(forem_user.id) unsubscribe_successful end @@ -93,6 +96,11 @@ def unsubscribe_successful redirect_to forum_topic_url(@topic.forum, @topic) end + def unsubscribe_unsuccessful + flash.alert = t("forem.topic.unsubscription_failed") + redirect_to forum_topic_url(@topic.forum, @topic) + end + private def find_forum @forum = Forem::Forum.friendly.find(params[:forum_id]) diff --git a/app/models/forem/subscription.rb b/app/models/forem/subscription.rb index 9551d14b7..acb98f0ac 100644 --- a/app/models/forem/subscription.rb +++ b/app/models/forem/subscription.rb @@ -5,6 +5,8 @@ class Subscription < ActiveRecord::Base validates :subscriber_id, :presence => true + before_create :set_token + def send_notification(post_id) # If a user cannot be found, then no-op # This will happen if the user record has been deleted. @@ -12,5 +14,11 @@ def send_notification(post_id) SubscriptionMailer.topic_reply(post_id, subscriber.id).deliver end end + + private + + def set_token + self.token = SecureRandom.hex(24) + end end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 6ed4ceae3..7a40b2d48 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -122,6 +122,7 @@ en: not_updated: This topic could not be updated. subscribed: You have subscribed to this topic. unsubscribed: You have unsubscribed from this topic. + unsubscription_failed: Failed to unsubscribe you from this topic. none: There are no topics in this forum currently. links: new: New topic diff --git a/config/routes.rb b/config/routes.rb index 196843b65..2e6193a0b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -44,7 +44,7 @@ resources :posts, :except => :index member do post :subscribe - post :unsubscribe + get :unsubscribe end end end diff --git a/spec/controllers/topics_controller_spec.rb b/spec/controllers/topics_controller_spec.rb index 0b153388a..a2fbb201a 100644 --- a/spec/controllers/topics_controller_spec.rb +++ b/spec/controllers/topics_controller_spec.rb @@ -68,4 +68,34 @@ flash.alert.should == "You must sign in first." end end + + context "subscribing & unsubscribing" do + let!(:forum) { create(:forum) } + let!(:user) { create(:user) } + let!(:topic) { create(:approved_topic, forum: forum, forem_user: user) } + let(:subscription) { topic.subscriptions.first } + + before do + sign_in(user) + controller.current_user.stub :can_read_topic? => true + end + + it "can subscribe to a topic" do + post :subscribe, forum_id: forum.to_param, id: topic.to_param + expect(flash[:notice]).to eq(I18n.t("forem.topic.subscribed")) + expect(response).to redirect_to(forum_topic_path(forum, topic)) + end + + it "can unsubscribe with a valid token" do + get :unsubscribe, forum_id: forum.to_param, id: topic.to_param, token: subscription.token + expect(flash[:notice]).to eq(I18n.t("forem.topic.unsubscribed")) + expect(response).to redirect_to(forum_topic_path(forum, topic)) + end + + it "cannot unsubscribe without a token" do + get :unsubscribe, forum_id: forum.to_param, id: topic.to_param, token: "fake" + expect(flash[:alert]).to eq(I18n.t("forem.topic.unsubscription_failed")) + expect(response).to redirect_to(forum_topic_path(forum, topic)) + end + end end diff --git a/spec/models/subscription_spec.rb b/spec/models/subscription_spec.rb index 679bcfa78..57eba71c0 100644 --- a/spec/models/subscription_spec.rb +++ b/spec/models/subscription_spec.rb @@ -6,6 +6,13 @@ FactoryGirl.build(:subscription).should be_valid end + context "set_token" do + it "sets a unique token for the subscription" do + subscription = Forem::Subscription.create!(subscriber_id: 1) + expect(subscription.token).to be_present + end + end + describe "topic subscriptions" do before(:each) do Forem::Topic.any_instance.stub(:set_first_post_user)