From 1f59507e78e16a281407f16b804e2111323bc767 Mon Sep 17 00:00:00 2001 From: Anton Khorev Date: Thu, 16 Nov 2023 10:03:26 +0300 Subject: [PATCH] Add changeset comment search api with filtering by author and time --- app/abilities/api_ability.rb | 1 + .../api/changeset_comments_controller.rb | 15 +++++- .../_changeset_comment.xml.builder | 12 +++++ .../api/changeset_comments/index.xml.builder | 7 +++ .../api/changesets/_changeset.xml.builder | 13 +---- config/routes.rb | 2 + config/settings.yml | 4 ++ .../api/changeset_comments_controller_test.rb | 51 +++++++++++++++++++ 8 files changed, 91 insertions(+), 14 deletions(-) create mode 100644 app/views/api/changeset_comments/_changeset_comment.xml.builder create mode 100644 app/views/api/changeset_comments/index.xml.builder diff --git a/app/abilities/api_ability.rb b/app/abilities/api_ability.rb index 7bbd9889a..d183aca74 100644 --- a/app/abilities/api_ability.rb +++ b/app/abilities/api_ability.rb @@ -11,6 +11,7 @@ class ApiAbility can :create, Note unless user can [:read, :download], Changeset + can :read, ChangesetComment can :read, Tracepoint can :read, User can :read, [Node, Way, Relation, OldNode, OldWay, OldRelation] diff --git a/app/controllers/api/changeset_comments_controller.rb b/app/controllers/api/changeset_comments_controller.rb index c180571c5..808ac97ea 100644 --- a/app/controllers/api/changeset_comments_controller.rb +++ b/app/controllers/api/changeset_comments_controller.rb @@ -1,7 +1,9 @@ module Api class ChangesetCommentsController < ApiController - before_action :check_api_writable - before_action :authorize + include QueryMethods + + before_action :check_api_writable, :except => [:index] + before_action :authorize, :except => [:index] authorize_resource @@ -9,6 +11,15 @@ module Api 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 def create diff --git a/app/views/api/changeset_comments/_changeset_comment.xml.builder b/app/views/api/changeset_comments/_changeset_comment.xml.builder new file mode 100644 index 000000000..951556fc2 --- /dev/null +++ b/app/views/api/changeset_comments/_changeset_comment.xml.builder @@ -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 diff --git a/app/views/api/changeset_comments/index.xml.builder b/app/views/api/changeset_comments/index.xml.builder new file mode 100644 index 000000000..cfa59c914 --- /dev/null +++ b/app/views/api/changeset_comments/index.xml.builder @@ -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 diff --git a/app/views/api/changesets/_changeset.xml.builder b/app/views/api/changesets/_changeset.xml.builder index 08cfbbc79..072f8fc5d 100644 --- a/app/views/api/changesets/_changeset.xml.builder +++ b/app/views/api/changesets/_changeset.xml.builder @@ -27,18 +27,7 @@ xml.changeset(attrs) do |changeset_xml_node| if @comments changeset_xml_node.discussion do |discussion_xml_node| @comments.each do |comment| - cattrs = { - "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 + discussion_xml_node << render(comment) end end end diff --git a/config/routes.rb b/config/routes.rb index 3971494aa..0a6ab0356 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -38,6 +38,8 @@ OpenStreetMap::Application.routes.draw do end namespace :api, :path => "api/0.6" do + resources :changeset_comments, :only => :index + resources :nodes, :only => [:index, :create] resources :nodes, :path => "node", :id => /\d+/, :only => [:show, :update, :destroy] do scope :module => :nodes do diff --git a/config/settings.yml b/config/settings.yml index 33b5bfb32..51f4444c4 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -35,6 +35,10 @@ tracepoints_per_page: 5000 default_changeset_query_limit: 100 # Maximum limit on the number of changesets returned by the changeset query api method 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_changeset_comments_feed_query_limit: 100 # Maximum limit on the number of changesets comments in feeds diff --git a/test/controllers/api/changeset_comments_controller_test.rb b/test/controllers/api/changeset_comments_controller_test.rb index e456a3ca4..2d8818986 100644 --- a/test/controllers/api/changeset_comments_controller_test.rb +++ b/test/controllers/api/changeset_comments_controller_test.rb @@ -5,6 +5,10 @@ module Api ## # test all routes which lead to this controller def test_routes + assert_routing( + { :path => "/api/0.6/changeset_comments", :method => :get }, + { :controller => "api/changeset_comments", :action => "index" } + ) assert_routing( { :path => "/api/0.6/changeset/1/comment", :method => :post }, { :controller => "api/changeset_comments", :action => "create", :id => "1" } @@ -31,6 +35,38 @@ module Api ) 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 assert_no_difference "ChangesetComment.count" do post changeset_comment_path(create(:changeset, :closed), :text => "This is a comment") @@ -422,5 +458,20 @@ module Api assert_response :success assert comment.reload.visible 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 -- 2.39.5