Add changeset comment search api with filtering by author and time

This commit is contained in:
Anton Khorev 2023-11-16 10:03:26 +03:00
parent bd278a07fe
commit 1f59507e78
8 changed files with 91 additions and 14 deletions

View file

@ -11,6 +11,7 @@ class ApiAbility
can :create, Note unless user can :create, Note unless user
can [:read, :download], Changeset can [:read, :download], Changeset
can :read, ChangesetComment
can :read, Tracepoint can :read, Tracepoint
can :read, User can :read, User
can :read, [Node, Way, Relation, OldNode, OldWay, OldRelation] can :read, [Node, Way, Relation, OldNode, OldWay, OldRelation]

View file

@ -1,7 +1,9 @@
module Api module Api
class ChangesetCommentsController < ApiController class ChangesetCommentsController < ApiController
before_action :check_api_writable include QueryMethods
before_action :authorize
before_action :check_api_writable, :except => [:index]
before_action :authorize, :except => [:index]
authorize_resource authorize_resource
@ -9,6 +11,15 @@ module Api
before_action :set_request_formats before_action :set_request_formats
##
# show all comments or search for a subset
def index
@comments = ChangesetComment.includes(:author).where(:visible => true).order("created_at DESC")
@comments = query_conditions_time(@comments)
@comments = query_conditions_user(@comments, :author)
@comments = query_limit(@comments)
end
## ##
# Add a comment to a changeset # Add a comment to a changeset
def create def create

View file

@ -0,0 +1,12 @@
cattrs = {
"id" => changeset_comment.id,
"date" => changeset_comment.created_at.xmlschema,
"visible" => changeset_comment.visible
}
if changeset_comment.author.data_public?
cattrs["uid"] = changeset_comment.author.id
cattrs["user"] = changeset_comment.author.display_name
end
xml.comment(cattrs) do |comment_xml_node|
comment_xml_node.text(changeset_comment.body)
end

View file

@ -0,0 +1,7 @@
xml.instruct! :xml, :version => "1.0"
xml.osm(OSM::API.new.xml_root_attributes) do |osm|
@comments.includes(:author).each do |comment|
osm << render(comment)
end
end

View file

@ -27,18 +27,7 @@ xml.changeset(attrs) do |changeset_xml_node|
if @comments if @comments
changeset_xml_node.discussion do |discussion_xml_node| changeset_xml_node.discussion do |discussion_xml_node|
@comments.each do |comment| @comments.each do |comment|
cattrs = { discussion_xml_node << render(comment)
"id" => comment.id,
"date" => comment.created_at.xmlschema,
"visible" => comment.visible
}
if comment.author.data_public?
cattrs["uid"] = comment.author.id
cattrs["user"] = comment.author.display_name
end
discussion_xml_node.comment(cattrs) do |comment_xml_node|
comment_xml_node.text(comment.body)
end
end end
end end
end end

View file

@ -38,6 +38,8 @@ OpenStreetMap::Application.routes.draw do
end end
namespace :api, :path => "api/0.6" do namespace :api, :path => "api/0.6" do
resources :changeset_comments, :only => :index
resources :nodes, :only => [:index, :create] resources :nodes, :only => [:index, :create]
resources :nodes, :path => "node", :id => /\d+/, :only => [:show, :update, :destroy] do resources :nodes, :path => "node", :id => /\d+/, :only => [:show, :update, :destroy] do
scope :module => :nodes do scope :module => :nodes do

View file

@ -35,6 +35,10 @@ tracepoints_per_page: 5000
default_changeset_query_limit: 100 default_changeset_query_limit: 100
# Maximum limit on the number of changesets returned by the changeset query api method # Maximum limit on the number of changesets returned by the changeset query api method
max_changeset_query_limit: 100 max_changeset_query_limit: 100
# Default limit on the number of changeset comments returned by the api
default_changeset_comment_query_limit: 100
# Maximum limit on the number of changesets comments returned by the api
max_changeset_comment_query_limit: 10000
# Default limit on the number of changeset comments in feeds # Default limit on the number of changeset comments in feeds
default_changeset_comments_feed_query_limit: 100 default_changeset_comments_feed_query_limit: 100
# Maximum limit on the number of changesets comments in feeds # Maximum limit on the number of changesets comments in feeds

View file

@ -5,6 +5,10 @@ module Api
## ##
# test all routes which lead to this controller # test all routes which lead to this controller
def test_routes def test_routes
assert_routing(
{ :path => "/api/0.6/changeset_comments", :method => :get },
{ :controller => "api/changeset_comments", :action => "index" }
)
assert_routing( assert_routing(
{ :path => "/api/0.6/changeset/1/comment", :method => :post }, { :path => "/api/0.6/changeset/1/comment", :method => :post },
{ :controller => "api/changeset_comments", :action => "create", :id => "1" } { :controller => "api/changeset_comments", :action => "create", :id => "1" }
@ -31,6 +35,38 @@ module Api
) )
end end
def test_index
user1 = create(:user)
user2 = create(:user)
changeset1 = create(:changeset, :closed, :user => user2)
comment11 = create(:changeset_comment, :changeset => changeset1, :author => user1, :created_at => "2023-01-01", :body => "changeset 1 question")
comment12 = create(:changeset_comment, :changeset => changeset1, :author => user2, :created_at => "2023-02-01", :body => "changeset 1 answer")
changeset2 = create(:changeset, :closed, :user => user1)
comment21 = create(:changeset_comment, :changeset => changeset2, :author => user1, :created_at => "2023-03-01", :body => "changeset 2 note")
comment22 = create(:changeset_comment, :changeset => changeset2, :author => user1, :created_at => "2023-04-01", :body => "changeset 2 extra note")
comment23 = create(:changeset_comment, :changeset => changeset2, :author => user2, :created_at => "2023-05-01", :body => "changeset 2 review")
get api_changeset_comments_path
assert_response :success
assert_comments_in_order [comment23, comment22, comment21, comment12, comment11]
get api_changeset_comments_path(:limit => 3)
assert_response :success
assert_comments_in_order [comment23, comment22, comment21]
get api_changeset_comments_path(:from => "2023-03-15T00:00:00Z")
assert_response :success
assert_comments_in_order [comment23, comment22]
get api_changeset_comments_path(:from => "2023-01-15T00:00:00Z", :to => "2023-04-15T00:00:00Z")
assert_response :success
assert_comments_in_order [comment22, comment21, comment12]
get api_changeset_comments_path(:user => user1.id)
assert_response :success
assert_comments_in_order [comment22, comment21, comment11]
end
def test_create_by_unauthorized def test_create_by_unauthorized
assert_no_difference "ChangesetComment.count" do assert_no_difference "ChangesetComment.count" do
post changeset_comment_path(create(:changeset, :closed), :text => "This is a comment") post changeset_comment_path(create(:changeset, :closed), :text => "This is a comment")
@ -422,5 +458,20 @@ module Api
assert_response :success assert_response :success
assert comment.reload.visible assert comment.reload.visible
end end
private
##
# check that certain comments exist in the output in the specified order
def assert_comments_in_order(comments)
assert_dom "osm > comment", comments.size do |dom_comments|
comments.zip(dom_comments).each do |comment, dom_comment|
assert_dom dom_comment, "> @id", comment.id.to_s
assert_dom dom_comment, "> @uid", comment.author.id.to_s
assert_dom dom_comment, "> @user", comment.author.display_name
assert_dom dom_comment, "> text", comment.body
end
end
end
end end
end end