Skip to content

Commit

Permalink
Merge pull request #5314 from AntonKhorev/note-subscriptions-api
Browse files Browse the repository at this point in the history
Note subscriptions API
  • Loading branch information
gravitystorm authored Nov 20, 2024
2 parents ea3760f + 53a3311 commit 6f04849
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 0 deletions.
1 change: 1 addition & 0 deletions app/abilities/api_capability.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ def initialize(token)

if user&.active?
can [:create, :comment, :close, :reopen], Note if scope?(token, :write_notes)
can [:create, :destroy], 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)
Expand Down
27 changes: 27 additions & 0 deletions app/controllers/api/note_subscriptions_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
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

def destroy
note_id = params[:note_id].to_i
note = Note.find(note_id)
count = note.subscriptions.where(:user => current_user).delete_all
report_error "You are not subscribed to note #{note_id}.", :not_found if count.zero?
rescue ActiveRecord::RecordNotFound
report_error "Note #{note_id} not found.", :not_found
end
end
end
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@
post "close"
post "reopen"
end

resource :subscription, :only => [:create, :destroy], :controller => "note_subscriptions"
end

resources :user_blocks, :only => :show, :id => /\d+/, :controller => "user_blocks"
Expand Down
142 changes: 142 additions & 0 deletions test/controllers/api/note_subscriptions_controller_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
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" }
)
assert_routing(
{ :path => "/api/0.6/notes/1/subscription", :method => :delete },
{ :controller => "api/note_subscriptions", :action => "destroy", :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

def test_destroy
user = create(:user)
auth_header = bearer_authorization_header user
other_user = create(:user)
note = create(:note_with_comments)
other_note = create(:note_with_comments)
create(:note_subscription, :user => user, :note => note)
create(:note_subscription, :user => other_user, :note => note)
create(:note_subscription, :user => user, :note => other_note)

assert_difference "NoteSubscription.count", -1 do
assert_difference "note.subscribers.count", -1 do
delete api_note_subscription_path(note), :headers => auth_header
assert_response :success
end
end
note.reload
assert_equal [other_user], note.subscribers
assert_equal [user], other_note.subscribers
end

def test_destroy_fail_anonymous
note = create(:note_with_comments)

delete api_note_subscription_path(note)
assert_response :unauthorized
end

def test_destroy_fail_no_scope
user = create(:user)
auth_header = bearer_authorization_header user, :scopes => %w[read_prefs]
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
delete api_note_subscription_path(note), :headers => auth_header
assert_response :forbidden
end
end
end

def test_destroy_fail_note_not_found
user = create(:user)
auth_header = bearer_authorization_header user

delete api_note_subscription_path(999111), :headers => auth_header
assert_response :not_found
assert_match "not found", @response.body
end

def test_destroy_fail_not_subscribed
user = create(:user)
auth_header = bearer_authorization_header user
note = create(:note_with_comments)

delete api_note_subscription_path(note), :headers => auth_header
assert_response :not_found
assert_match "not subscribed", @response.body
end
end
end

0 comments on commit 6f04849

Please sign in to comment.