]> git.openstreetmap.org Git - rails.git/commitdiff
JSON output added to changeset(s) endpoints
authormmd-osm <mmd.osm@gmail.com>
Wed, 9 Mar 2022 19:02:17 +0000 (20:02 +0100)
committermmd-osm <mmd.osm@gmail.com>
Mon, 14 Mar 2022 14:52:49 +0000 (15:52 +0100)
app/controllers/api/changeset_comments_controller.rb
app/controllers/api/changesets_controller.rb
app/views/api/changesets/_changeset.json.jbuilder [new file with mode: 0644]
app/views/api/changesets/_changeset.xml.builder [moved from app/views/api/changesets/_changeset.builder with 100% similarity]
app/views/api/changesets/changeset.json.jbuilder [new file with mode: 0644]
app/views/api/changesets/changeset.xml.builder [moved from app/views/api/changesets/changeset.builder with 100% similarity]
app/views/api/changesets/changesets.json.jbuilder [new file with mode: 0644]
app/views/api/changesets/changesets.xml.builder [moved from app/views/api/changesets/changesets.builder with 100% similarity]
test/controllers/api/changeset_comments_controller_test.rb
test/controllers/api/changesets_controller_test.rb

index 4cd33a92b6b3115b5b76a5e24f2cd5d69d5b2ee7..86ac612777bc1e320f5403dfe2fe71978ce7333b 100644 (file)
@@ -7,6 +7,7 @@ module Api
     before_action :require_public_data, :only => [:create]
     before_action :check_api_writable
     before_action :check_api_readable, :except => [:create]
+    before_action :set_request_formats
     around_action :api_call_handle_error
     around_action :api_call_timeout
 
@@ -41,6 +42,11 @@ module Api
       # Return a copy of the updated changeset
       @changeset = changeset
       render "api/changesets/changeset"
+
+      respond_to do |format|
+        format.xml
+        format.json
+      end
     end
 
     ##
@@ -61,6 +67,11 @@ module Api
       # Return a copy of the updated changeset
       @changeset = comment.changeset
       render "api/changesets/changeset"
+
+      respond_to do |format|
+        format.xml
+        format.json
+      end
     end
 
     ##
@@ -81,6 +92,11 @@ module Api
       # Return a copy of the updated changeset
       @changeset = comment.changeset
       render "api/changesets/changeset"
+
+      respond_to do |format|
+        format.xml
+        format.json
+      end
     end
   end
 end
index df27ab5ca7a1866ea6dfa0577a01d0893978573f..354b0b9c224b43dc96b569593b8fd3b94d26d80c 100644 (file)
@@ -11,7 +11,7 @@ module Api
     before_action :require_public_data, :only => [:create, :update, :upload, :close, :subscribe, :unsubscribe]
     before_action :check_api_writable, :only => [:create, :update, :upload, :subscribe, :unsubscribe]
     before_action :check_api_readable, :except => [:create, :update, :upload, :download, :query, :subscribe, :unsubscribe]
-    before_action :set_request_formats, :only => [:download]
+    before_action :set_request_formats, :except => [:create, :close, :upload]
 
     around_action :api_call_handle_error
     around_action :api_call_timeout, :except => [:upload]
@@ -42,6 +42,11 @@ module Api
       @changeset = Changeset.find(params[:id])
       @include_discussion = params[:include_discussion].presence
       render "changeset"
+
+      respond_to do |format|
+        format.xml
+        format.json
+      end
     end
 
     ##
@@ -171,6 +176,11 @@ module Api
       # preload users, tags and comments, and render result
       @changesets = changesets.preload(:user, :changeset_tags, :comments)
       render "changesets"
+
+      respond_to do |format|
+        format.xml
+        format.json
+      end
     end
 
     ##
@@ -191,6 +201,11 @@ module Api
       check_changeset_consistency(@changeset, current_user)
       @changeset.update_from(new_changeset, current_user)
       render "changeset"
+
+      respond_to do |format|
+        format.xml
+        format.json
+      end
     end
 
     ##
@@ -212,6 +227,11 @@ module Api
       # Return a copy of the updated changeset
       @changeset = changeset
       render "changeset"
+
+      respond_to do |format|
+        format.xml
+        format.json
+      end
     end
 
     ##
@@ -233,6 +253,11 @@ module Api
       # Return a copy of the updated changeset
       @changeset = changeset
       render "changeset"
+
+      respond_to do |format|
+        format.xml
+        format.json
+      end
     end
 
     private
diff --git a/app/views/api/changesets/_changeset.json.jbuilder b/app/views/api/changesets/_changeset.json.jbuilder
new file mode 100644 (file)
index 0000000..25b3660
--- /dev/null
@@ -0,0 +1,33 @@
+# basic attributes
+json.id changeset.id
+json.created_at changeset.created_at.xmlschema
+json.open changeset.open?
+json.comments_count changeset.comments.length
+json.changes_count changeset.num_changes
+
+json.closed_at changeset.closed_at.xmlschema unless changeset.open?
+if changeset.bbox.complete?
+  json.min_lat GeoRecord::Coord.new(changeset.bbox.to_unscaled.min_lat)
+  json.min_lon GeoRecord::Coord.new(changeset.bbox.to_unscaled.min_lon)
+  json.max_lat GeoRecord::Coord.new(changeset.bbox.to_unscaled.max_lat)
+  json.max_lon GeoRecord::Coord.new(changeset.bbox.to_unscaled.max_lon)
+end
+
+# user attributes
+if changeset.user.data_public?
+  json.uid changeset.user_id
+  json.user changeset.user.display_name
+end
+
+json.tags changeset.tags unless changeset.tags.empty?
+
+if @include_discussion
+  json.comments(changeset.comments) do |comment|
+    json.date comment.created_at.xmlschema
+    if comment.author.data_public?
+      json.uid comment.author.id
+      json.user comment.author.display_name
+    end
+    json.text comment.body
+  end
+end
diff --git a/app/views/api/changesets/changeset.json.jbuilder b/app/views/api/changesets/changeset.json.jbuilder
new file mode 100644 (file)
index 0000000..7a840c1
--- /dev/null
@@ -0,0 +1,5 @@
+json.partial! "api/root_attributes"
+
+json.changeset do
+  json.partial! @changeset
+end
diff --git a/app/views/api/changesets/changesets.json.jbuilder b/app/views/api/changesets/changesets.json.jbuilder
new file mode 100644 (file)
index 0000000..f52d698
--- /dev/null
@@ -0,0 +1,5 @@
+json.partial! "api/root_attributes"
+
+json.changesets(@changesets) do |changeset|
+  json.partial! changeset
+end
index ce7c08a659d8b63269b7d8fb353d486e1eb6f15a..26500babdcb24f47b727c3be384ecc084a668db8 100644 (file)
@@ -9,14 +9,26 @@ module Api
         { :path => "/api/0.6/changeset/1/comment", :method => :post },
         { :controller => "api/changeset_comments", :action => "create", :id => "1" }
       )
+      assert_routing(
+        { :path => "/api/0.6/changeset/1/comment.json", :method => :post },
+        { :controller => "api/changeset_comments", :action => "create", :id => "1", :format => "json" }
+      )
       assert_routing(
         { :path => "/api/0.6/changeset/comment/1/hide", :method => :post },
         { :controller => "api/changeset_comments", :action => "destroy", :id => "1" }
       )
+      assert_routing(
+        { :path => "/api/0.6/changeset/comment/1/hide.json", :method => :post },
+        { :controller => "api/changeset_comments", :action => "destroy", :id => "1", :format => "json" }
+      )
       assert_routing(
         { :path => "/api/0.6/changeset/comment/1/unhide", :method => :post },
         { :controller => "api/changeset_comments", :action => "restore", :id => "1" }
       )
+      assert_routing(
+        { :path => "/api/0.6/changeset/comment/1/unhide.json", :method => :post },
+        { :controller => "api/changeset_comments", :action => "restore", :id => "1", :format => "json" }
+      )
     end
 
     ##
index 3b4eef25a35fd71e5abe4ef548cb1523ffbfa51e..af5cabbaaa771b4ea9baa3500b22c242cba14fa4 100644 (file)
@@ -21,14 +21,26 @@ module Api
         { :path => "/api/0.6/changeset/1", :method => :get },
         { :controller => "api/changesets", :action => "show", :id => "1" }
       )
+      assert_routing(
+        { :path => "/api/0.6/changeset/1.json", :method => :get },
+        { :controller => "api/changesets", :action => "show", :id => "1", :format => "json" }
+      )
       assert_routing(
         { :path => "/api/0.6/changeset/1/subscribe", :method => :post },
         { :controller => "api/changesets", :action => "subscribe", :id => "1" }
       )
+      assert_routing(
+        { :path => "/api/0.6/changeset/1/subscribe.json", :method => :post },
+        { :controller => "api/changesets", :action => "subscribe", :id => "1", :format => "json" }
+      )
       assert_routing(
         { :path => "/api/0.6/changeset/1/unsubscribe", :method => :post },
         { :controller => "api/changesets", :action => "unsubscribe", :id => "1" }
       )
+      assert_routing(
+        { :path => "/api/0.6/changeset/1/unsubscribe.json", :method => :post },
+        { :controller => "api/changesets", :action => "unsubscribe", :id => "1", :format => "json" }
+      )
       assert_routing(
         { :path => "/api/0.6/changeset/1", :method => :put },
         { :controller => "api/changesets", :action => "update", :id => "1" }
@@ -41,6 +53,10 @@ module Api
         { :path => "/api/0.6/changesets", :method => :get },
         { :controller => "api/changesets", :action => "query" }
       )
+      assert_routing(
+        { :path => "/api/0.6/changesets.json", :method => :get },
+        { :controller => "api/changesets", :action => "query", :format => "json" }
+      )
     end
 
     # -----------------------
@@ -168,6 +184,99 @@ module Api
       assert_select "osm>changeset>discussion>comment", 3
     end
 
+    def test_show_json
+      changeset = create(:changeset)
+
+      get changeset_show_path(changeset), :params => { :format => "json" }
+      assert_response :success, "cannot get first changeset"
+
+      js = ActiveSupport::JSON.decode(@response.body)
+      assert_not_nil js
+
+      assert_equal Settings.api_version, js["version"]
+      assert_equal "OpenStreetMap server", js["generator"]
+      assert_equal changeset.id, js["changeset"]["id"]
+      assert js["changeset"]["open"]
+      assert_equal changeset.created_at.xmlschema, js["changeset"]["created_at"]
+      assert_nil js["changeset"]["closed_at"]
+      assert_nil js["changeset"]["tags"]
+      assert_nil js["changeset"]["comments"]
+      assert_equal changeset.user.id, js["changeset"]["uid"]
+      assert_equal changeset.user.display_name, js["changeset"]["user"]
+
+      get changeset_show_path(changeset), :params => { :format => "json", :include_discussion => true }
+      assert_response :success, "cannot get first changeset with comments"
+
+      js = ActiveSupport::JSON.decode(@response.body)
+      assert_not_nil js
+      assert_equal Settings.api_version, js["version"]
+      assert_equal "OpenStreetMap server", js["generator"]
+      assert_equal changeset.id, js["changeset"]["id"]
+      assert js["changeset"]["open"]
+      assert_equal changeset.created_at.xmlschema, js["changeset"]["created_at"]
+      assert_nil js["changeset"]["closed_at"]
+      assert_nil js["changeset"]["tags"]
+      assert_nil js["changeset"]["min_lat"]
+      assert_nil js["changeset"]["min_lon"]
+      assert_nil js["changeset"]["max_lat"]
+      assert_nil js["changeset"]["max_lon"]
+      assert_equal 0, js["changeset"]["comments"].count
+    end
+
+    def test_show_tag_and_discussion_json
+      changeset = create(:changeset, :closed)
+
+      tag1 = ChangesetTag.new
+      tag1.changeset_id = changeset.id
+      tag1.k = "created_by"
+      tag1.v = "JOSM/1.5 (18364)"
+
+      tag2 = ChangesetTag.new
+      tag2.changeset_id = changeset.id
+      tag2.k = "comment"
+      tag2.v = "changeset comment"
+
+      changeset.changeset_tags = [tag1, tag2]
+
+      create_list(:changeset_comment, 3, :changeset_id => changeset.id)
+
+      get changeset_show_path(changeset), :params => { :format => "json", :include_discussion => true }
+      assert_response :success, "cannot get closed changeset with comments"
+
+      js = ActiveSupport::JSON.decode(@response.body)
+
+      assert_not_nil js
+      assert_equal Settings.api_version, js["version"]
+      assert_equal "OpenStreetMap server", js["generator"]
+      assert_equal changeset.id, js["changeset"]["id"]
+      assert_not js["changeset"]["open"]
+      assert_equal changeset.created_at.xmlschema, js["changeset"]["created_at"]
+      assert_equal changeset.closed_at.xmlschema, js["changeset"]["closed_at"]
+      assert_equal 2, js["changeset"]["tags"].count
+      assert_equal 3, js["changeset"]["comments"].count
+      assert_equal 3, js["changeset"]["comments_count"]
+      assert_equal 0, js["changeset"]["changes_count"]
+      assert_not_nil js["changeset"]["comments"][0]["uid"]
+      assert_not_nil js["changeset"]["comments"][0]["user"]
+      assert_not_nil js["changeset"]["comments"][0]["text"]
+    end
+
+    def test_show_bbox_json
+      # test bbox attribute
+      changeset = create(:changeset, :min_lat => (-5 * GeoRecord::SCALE).round, :min_lon => (5 * GeoRecord::SCALE).round,
+                                     :max_lat => (15 * GeoRecord::SCALE).round, :max_lon => (12 * GeoRecord::SCALE).round)
+
+      get changeset_show_path(changeset), :params => { :format => "json" }
+      assert_response :success, "cannot get first changeset"
+
+      js = ActiveSupport::JSON.decode(@response.body)
+      assert_not_nil js
+      assert_equal(-5, js["changeset"]["min_lat"])
+      assert_equal  5, js["changeset"]["min_lon"]
+      assert_equal 15, js["changeset"]["max_lat"]
+      assert_equal 12, js["changeset"]["max_lon"]
+    end
+
     ##
     # check that a changeset that doesn't exist returns an appropriate message
     def test_show_not_found
@@ -1542,6 +1651,17 @@ module Api
       assert_response :success, "can't get changesets by user name"
       assert_changesets [private_user_changeset, private_user_closed_changeset]
 
+      # test json endpoint
+      get changesets_path(:display_name => private_user.display_name), :headers => auth_header, :params => { :format => "json" }
+      assert_response :success, "can't get changesets by user name"
+
+      js = ActiveSupport::JSON.decode(@response.body)
+      assert_not_nil js
+
+      assert_equal Settings.api_version, js["version"]
+      assert_equal "OpenStreetMap server", js["generator"]
+      assert_equal 2, js["changesets"].count
+
       # check that the correct error is given when we provide both UID and name
       get changesets_path(:user => private_user.id,
                           :display_name => private_user.display_name), :headers => auth_header