]> git.openstreetmap.org Git - rails.git/commitdiff
Add create note subscription api endpoint
authorAnton Khorev <tony29@yandex.ru>
Thu, 24 Oct 2024 01:11:37 +0000 (04:11 +0300)
committerAnton Khorev <tony29@yandex.ru>
Wed, 20 Nov 2024 17:34:52 +0000 (20:34 +0300)
app/abilities/api_capability.rb
app/controllers/api/note_subscriptions_controller.rb [new file with mode: 0644]
config/routes.rb
test/controllers/api/note_subscriptions_controller_test.rb [new file with mode: 0644]

index d8be136438efded684104cbf9dfd0728b27221c8..dade7f6fec0b5cb287c0a27c52ef36baae94e295 100644 (file)
@@ -9,6 +9,7 @@ class ApiCapability
 
       if user&.active?
         can [:create, :comment, :close, :reopen], Note if scope?(token, :write_notes)
+        can :create, NoteSubscription if scope?(token, :write_notes)
         can [:show, :data], Trace if scope?(token, :read_gpx)
         can [:create, :update, :destroy], Trace if scope?(token, :write_gpx)
         can [:details], User if scope?(token, :read_prefs)
diff --git a/app/controllers/api/note_subscriptions_controller.rb b/app/controllers/api/note_subscriptions_controller.rb
new file mode 100644 (file)
index 0000000..348b428
--- /dev/null
@@ -0,0 +1,18 @@
+module Api
+  class NoteSubscriptionsController < ApiController
+    before_action :check_api_writable
+    before_action :authorize
+
+    authorize_resource
+
+    def create
+      note_id = params[:note_id].to_i
+      note = Note.find(note_id)
+      note.subscribers << current_user
+    rescue ActiveRecord::RecordNotFound
+      report_error "Note #{note_id} not found.", :not_found
+    rescue ActiveRecord::RecordNotUnique
+      report_error "You are already subscribed to note #{note_id}.", :conflict
+    end
+  end
+end
index af72c457d25d0b950a52cd8a0a8037fe1f057e9d..96b27c145d64b79d1f7110b613557f02a604cad2 100644 (file)
@@ -108,6 +108,8 @@ OpenStreetMap::Application.routes.draw do
         post "close"
         post "reopen"
       end
+
+      resource :subscription, :only => :create, :controller => "note_subscriptions"
     end
 
     resources :user_blocks, :only => :show, :id => /\d+/, :controller => "user_blocks"
diff --git a/test/controllers/api/note_subscriptions_controller_test.rb b/test/controllers/api/note_subscriptions_controller_test.rb
new file mode 100644 (file)
index 0000000..45aa33a
--- /dev/null
@@ -0,0 +1,77 @@
+require "test_helper"
+
+module Api
+  class NoteSubscriptionsControllerTest < ActionDispatch::IntegrationTest
+    def test_routes
+      assert_routing(
+        { :path => "/api/0.6/notes/1/subscription", :method => :post },
+        { :controller => "api/note_subscriptions", :action => "create", :note_id => "1" }
+      )
+    end
+
+    def test_create
+      user = create(:user)
+      auth_header = bearer_authorization_header user
+      note = create(:note_with_comments)
+      assert_empty note.subscribers
+
+      assert_difference "NoteSubscription.count", 1 do
+        assert_difference "note.subscribers.count", 1 do
+          post api_note_subscription_path(note), :headers => auth_header
+          assert_response :success
+        end
+      end
+      assert_equal user, note.subscribers.last
+    end
+
+    def test_create_fail_anonymous
+      note = create(:note_with_comments)
+
+      assert_no_difference "NoteSubscription.count" do
+        assert_no_difference "note.subscribers.count" do
+          post api_note_subscription_path(note)
+          assert_response :unauthorized
+        end
+      end
+    end
+
+    def test_create_fail_no_scope
+      user = create(:user)
+      auth_header = bearer_authorization_header user, :scopes => %w[read_prefs]
+      note = create(:note_with_comments)
+
+      assert_no_difference "NoteSubscription.count" do
+        assert_no_difference "note.subscribers.count" do
+          post api_note_subscription_path(note), :headers => auth_header
+          assert_response :forbidden
+        end
+      end
+    end
+
+    def test_create_fail_note_not_found
+      user = create(:user)
+      auth_header = bearer_authorization_header user
+
+      assert_no_difference "NoteSubscription.count" do
+        post api_note_subscription_path(999111), :headers => auth_header
+        assert_response :not_found
+      end
+      assert_match "not found", @response.body
+    end
+
+    def test_create_fail_already_subscribed
+      user = create(:user)
+      auth_header = bearer_authorization_header user
+      note = create(:note_with_comments)
+      create(:note_subscription, :user => user, :note => note)
+
+      assert_no_difference "NoteSubscription.count" do
+        assert_no_difference "note.subscribers.count" do
+          post api_note_subscription_path(note), :headers => auth_header
+          assert_response :conflict
+        end
+      end
+      assert_match "already subscribed", @response.body
+    end
+  end
+end