]> git.openstreetmap.org Git - rails.git/commitdiff
Merge remote-tracking branch 'upstream/pull/5620'
authorTom Hughes <tom@compton.nu>
Wed, 5 Feb 2025 19:00:14 +0000 (19:00 +0000)
committerTom Hughes <tom@compton.nu>
Wed, 5 Feb 2025 19:00:14 +0000 (19:00 +0000)
14 files changed:
app/abilities/api_ability.rb
app/controllers/api/relations_controller.rb
app/controllers/api/ways_controller.rb
app/views/api/relations/full.json.jbuilder [deleted file]
app/views/api/relations/full.xml.builder [deleted file]
app/views/api/relations/show.json.jbuilder
app/views/api/relations/show.xml.builder
app/views/api/ways/full.json.jbuilder [deleted file]
app/views/api/ways/full.xml.builder [deleted file]
app/views/api/ways/show.json.jbuilder
app/views/api/ways/show.xml.builder
config/routes.rb
test/controllers/api/relations_controller_test.rb
test/controllers/api/ways_controller_test.rb

index c74a4d0996adedcebd66ec59d47d696b01ddd28c..97b461b1f602282669b706f1ef4421d5e5f8b96e 100644 (file)
@@ -16,8 +16,8 @@ class ApiAbility
       can :read, Tracepoint
       can :read, User
       can :read, Node
-      can [:read, :full, :ways_for_node], Way
-      can [:read, :full, :relations_for_node, :relations_for_way, :relations_for_relation], Relation
+      can [:read, :ways_for_node], Way
+      can [:read, :relations_for_node, :relations_for_way, :relations_for_relation], Relation
       can [:history, :read], [OldNode, OldWay, OldRelation]
       can :read, UserBlock
 
index f712534f001aebdb747234abf27d1f68a87ce982..006b3e8a624f88d9536e500d7f034c3bf6cb6cf8 100644 (file)
@@ -26,9 +26,64 @@ module Api
     end
 
     def show
-      @relation = Relation.find(params[:id])
-      response.last_modified = @relation.timestamp
-      if @relation.visible
+      relation = Relation.find(params[:id])
+
+      response.last_modified = relation.timestamp unless params[:full]
+
+      @nodes = []
+      @ways = []
+      @relations = []
+
+      if relation.visible
+        if params[:full]
+          # with parameter :full
+          # returns representation of one relation object plus all its
+          # members, plus all nodes part of member ways
+
+          # first find the ids of nodes, ways and relations referenced by this
+          # relation - note that we exclude this relation just in case.
+
+          node_ids = relation.members.select { |m| m[0] == "Node" }.pluck(1)
+          way_ids = relation.members.select { |m| m[0] == "Way" }.pluck(1)
+          relation_ids = relation.members.select { |m| m[0] == "Relation" && m[1] != relation.id }.pluck(1)
+
+          # next load the relations and the ways.
+
+          relations = Relation.where(:id => relation_ids).includes(:relation_tags)
+          ways = Way.where(:id => way_ids).includes(:way_nodes, :way_tags)
+
+          # now additionally collect nodes referenced by ways. Note how we
+          # recursively evaluate ways but NOT relations.
+
+          way_node_ids = ways.collect do |way|
+            way.way_nodes.collect(&:node_id)
+          end
+          node_ids += way_node_ids.flatten
+          nodes = Node.where(:id => node_ids.uniq).includes(:node_tags)
+
+          @nodes = []
+          nodes.each do |node|
+            next unless node.visible? # should be unnecessary if data is consistent.
+
+            @nodes << node
+          end
+
+          ways.each do |way|
+            next unless way.visible? # should be unnecessary if data is consistent.
+
+            @ways << way
+          end
+
+          relations.each do |rel|
+            next unless rel.visible? # should be unnecessary if data is consistent.
+
+            @relations << rel
+          end
+        end
+
+        # finally add self
+        @relations << relation
+
         # Render the result
         respond_to do |format|
           format.xml
@@ -68,74 +123,6 @@ module Api
       end
     end
 
-    # -----------------------------------------------------------------
-    # full
-    #
-    # input parameters: id
-    #
-    # returns XML representation of one relation object plus all its
-    # members, plus all nodes part of member ways
-    # -----------------------------------------------------------------
-    def full
-      relation = Relation.find(params[:id])
-
-      if relation.visible
-
-        # first find the ids of nodes, ways and relations referenced by this
-        # relation - note that we exclude this relation just in case.
-
-        node_ids = relation.members.select { |m| m[0] == "Node" }.pluck(1)
-        way_ids = relation.members.select { |m| m[0] == "Way" }.pluck(1)
-        relation_ids = relation.members.select { |m| m[0] == "Relation" && m[1] != relation.id }.pluck(1)
-
-        # next load the relations and the ways.
-
-        relations = Relation.where(:id => relation_ids).includes(:relation_tags)
-        ways = Way.where(:id => way_ids).includes(:way_nodes, :way_tags)
-
-        # now additionally collect nodes referenced by ways. Note how we
-        # recursively evaluate ways but NOT relations.
-
-        way_node_ids = ways.collect do |way|
-          way.way_nodes.collect(&:node_id)
-        end
-        node_ids += way_node_ids.flatten
-        nodes = Node.where(:id => node_ids.uniq).includes(:node_tags)
-
-        @nodes = []
-        nodes.each do |node|
-          next unless node.visible? # should be unnecessary if data is consistent.
-
-          @nodes << node
-        end
-
-        @ways = []
-        ways.each do |way|
-          next unless way.visible? # should be unnecessary if data is consistent.
-
-          @ways << way
-        end
-
-        @relations = []
-        relations.each do |rel|
-          next unless rel.visible? # should be unnecessary if data is consistent.
-
-          @relations << rel
-        end
-
-        # finally add self
-        @relations << relation
-
-        # Render the result
-        respond_to do |format|
-          format.xml
-          format.json
-        end
-      else
-        head :gone
-      end
-    end
-
     def relations_for_way
       relations_for_object("Way")
     end
index 285ed46046041af296b1dc223e9320293fcd14d5..b1bc8d799b0747c3f35dc3b36bdadcadd21f26e7 100644 (file)
@@ -26,12 +26,21 @@ module Api
     end
 
     def show
-      @way = Way.find(params[:id])
+      @way = Way
+      @way = @way.includes(:nodes => :node_tags) if params[:full]
+      @way = @way.find(params[:id])
 
-      response.last_modified = @way.timestamp
+      response.last_modified = @way.timestamp unless params[:full]
 
       if @way.visible
-        # Render the result
+        if params[:full]
+          @nodes = []
+
+          @way.nodes.uniq.each do |node|
+            @nodes << node if node.visible
+          end
+        end
+
         respond_to do |format|
           format.xml
           format.json
@@ -72,26 +81,6 @@ module Api
       end
     end
 
-    def full
-      @way = Way.includes(:nodes => :node_tags).find(params[:id])
-
-      if @way.visible
-        @nodes = []
-
-        @way.nodes.uniq.each do |node|
-          @nodes << node if node.visible
-        end
-
-        # Render the result
-        respond_to do |format|
-          format.xml
-          format.json
-        end
-      else
-        head :gone
-      end
-    end
-
     ##
     # returns all the ways which are currently using the node given in the
     # :id parameter. note that this used to return deleted ways as well, but
diff --git a/app/views/api/relations/full.json.jbuilder b/app/views/api/relations/full.json.jbuilder
deleted file mode 100644 (file)
index 16331a8..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-json.partial! "api/root_attributes"
-
-json.elements do
-  json.array! @nodes, :partial => "/api/nodes/node", :as => :node
-  json.array! @ways, :partial => "/api/ways/way", :as => :way
-  json.array! @relations, :partial => "/api/relations/relation", :as => :relation
-end
diff --git a/app/views/api/relations/full.xml.builder b/app/views/api/relations/full.xml.builder
deleted file mode 100644 (file)
index e230617..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-xml.instruct!
-
-xml.osm(OSM::API.new.xml_root_attributes) do |osm|
-  osm << (render(@nodes) || "")
-  osm << (render(@ways) || "")
-  osm << (render(@relations) || "")
-end
index e5da7cd3f48fa4553f70a2b2adb6cdf2c2d41214..16331a89e6fd9aac3226a8b273877cb5fbea78b0 100644 (file)
@@ -1,5 +1,7 @@
 json.partial! "api/root_attributes"
 
 json.elements do
-  json.array! [@relation], :partial => "relation", :as => :relation
+  json.array! @nodes, :partial => "/api/nodes/node", :as => :node
+  json.array! @ways, :partial => "/api/ways/way", :as => :way
+  json.array! @relations, :partial => "/api/relations/relation", :as => :relation
 end
index 555eb4db5f73d5a53bcd41b9222bac4f758e6003..e23061727c4c1d2756d5a5a3e4cd08836a3ea71e 100644 (file)
@@ -1,5 +1,7 @@
 xml.instruct!
 
 xml.osm(OSM::API.new.xml_root_attributes) do |osm|
-  osm << (render(@relation) || "")
+  osm << (render(@nodes) || "")
+  osm << (render(@ways) || "")
+  osm << (render(@relations) || "")
 end
diff --git a/app/views/api/ways/full.json.jbuilder b/app/views/api/ways/full.json.jbuilder
deleted file mode 100644 (file)
index 1bd127d..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-json.partial! "api/root_attributes"
-
-json.elements do
-  json.array! @nodes, :partial => "/api/nodes/node", :as => :node
-  json.array! [@way], :partial => "/api/ways/way", :as => :way
-end
diff --git a/app/views/api/ways/full.xml.builder b/app/views/api/ways/full.xml.builder
deleted file mode 100644 (file)
index 0252916..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-xml.instruct!
-
-xml.osm(OSM::API.new.xml_root_attributes) do |osm|
-  osm << (render(@nodes) || "")
-  osm << (render(@way) || "")
-end
index 92e570d869f300204bb8d92eb9a20190b242f4de..adf8beab2d3d1b2196a6281a6b68f0ed9a4a2ab5 100644 (file)
@@ -1,5 +1,6 @@
 json.partial! "api/root_attributes"
 
 json.elements do
+  json.array! @nodes, :partial => "/api/nodes/node", :as => :node if @nodes
   json.array! [@way], :partial => "way", :as => :way
 end
index d520a08444376f96f25a5eb93099fb43e70bd526..72b22e7374c97a6b56e06a7228085e5ec95c29ff 100644 (file)
@@ -1,5 +1,6 @@
 xml.instruct!
 
 xml.osm(OSM::API.new.xml_root_attributes) do |osm|
+  osm << (render(@nodes) || "") if @nodes
   osm << (render(@way) || "")
 end
index b562ca9f4a0c60b6d1984b5db21acf80aec0153a..bc06e5f38e123a787de5084a818e1714e79eabb3 100644 (file)
@@ -37,14 +37,12 @@ OpenStreetMap::Application.routes.draw do
     get "node/:id/:version" => "old_nodes#show", :as => :api_old_node, :id => /\d+/, :version => /\d+/
 
     get "way/:id/history" => "old_ways#history", :as => :api_way_history, :id => /\d+/
-    get "way/:id/full" => "ways#full", :as => :way_full, :id => /\d+/
     get "way/:id/relations" => "relations#relations_for_way", :as => :way_relations, :id => /\d+/
     post "way/:id/:version/redact" => "old_ways#redact", :as => :way_version_redact, :version => /\d+/, :id => /\d+/
     get "way/:id/:version" => "old_ways#show", :as => :api_old_way, :id => /\d+/, :version => /\d+/
 
     get "relation/:id/relations" => "relations#relations_for_relation", :as => :relation_relations, :id => /\d+/
     get "relation/:id/history" => "old_relations#history", :as => :api_relation_history, :id => /\d+/
-    get "relation/:id/full" => "relations#full", :as => :relation_full, :id => /\d+/
     post "relation/:id/:version/redact" => "old_relations#redact", :as => :relation_version_redact, :version => /\d+/, :id => /\d+/
     get "relation/:id/:version" => "old_relations#show", :as => :api_old_relation, :id => /\d+/, :version => /\d+/
   end
@@ -55,11 +53,19 @@ OpenStreetMap::Application.routes.draw do
     put "node/create" => "nodes#create", :as => nil
 
     resources :ways, :only => [:index, :create]
-    resources :ways, :path => "way", :id => /\d+/, :only => [:show, :update, :destroy]
+    resources :ways, :path => "way", :id => /\d+/, :only => [:show, :update, :destroy] do
+      member do
+        get :full, :action => :show, :full => true, :as => nil
+      end
+    end
     put "way/create" => "ways#create", :as => nil
 
     resources :relations, :only => [:index, :create]
-    resources :relations, :path => "relation", :id => /\d+/, :only => [:show, :update, :destroy]
+    resources :relations, :path => "relation", :id => /\d+/, :only => [:show, :update, :destroy] do
+      member do
+        get :full, :action => :show, :full => true, :as => nil
+      end
+    end
     put "relation/create" => "relations#create", :as => nil
 
     resource :map, :only => :show
index 34953f7b7ac62841a1e27002ab383a9130393574..803a57acf52995448e082e6177a2f6184ab469d3 100644 (file)
@@ -27,11 +27,11 @@ module Api
       )
       assert_routing(
         { :path => "/api/0.6/relation/1/full", :method => :get },
-        { :controller => "api/relations", :action => "full", :id => "1" }
+        { :controller => "api/relations", :action => "show", :full => true, :id => "1" }
       )
       assert_routing(
         { :path => "/api/0.6/relation/1/full.json", :method => :get },
-        { :controller => "api/relations", :action => "full", :id => "1", :format => "json" }
+        { :controller => "api/relations", :action => "show", :full => true, :id => "1", :format => "json" }
       )
       assert_routing(
         { :path => "/api/0.6/relation/1", :method => :put },
@@ -149,19 +149,19 @@ module Api
     end
 
     def test_full_not_found
-      get relation_full_path(999999)
+      get api_relation_path(999999, :full => true)
       assert_response :not_found
     end
 
     def test_full_deleted
-      get relation_full_path(create(:relation, :deleted))
+      get api_relation_path(create(:relation, :deleted), :full => true)
       assert_response :gone
     end
 
     def test_full_empty
       relation = create(:relation)
 
-      get relation_full_path(relation)
+      get api_relation_path(relation, :full => true)
 
       assert_response :success
       assert_dom "relation", :count => 1 do
@@ -174,7 +174,7 @@ module Api
       node = create(:node)
       create(:relation_member, :relation => relation, :member => node)
 
-      get relation_full_path(relation)
+      get api_relation_path(relation, :full => true)
 
       assert_response :success
       assert_dom "node", :count => 1 do
@@ -190,7 +190,7 @@ module Api
       way = create(:way_with_nodes)
       create(:relation_member, :relation => relation, :member => way)
 
-      get relation_full_path(relation)
+      get api_relation_path(relation, :full => true)
 
       assert_response :success
       assert_dom "node", :count => 1 do
@@ -204,6 +204,30 @@ module Api
       end
     end
 
+    def test_full_with_node_member_json
+      relation = create(:relation)
+      node = create(:node)
+      create(:relation_member, :relation => relation, :member => node)
+
+      get api_relation_path(relation, :full => true, :format => "json")
+
+      assert_response :success
+      js = ActiveSupport::JSON.decode(@response.body)
+      assert_not_nil js
+      assert_equal 2, js["elements"].count
+
+      js_relations = js["elements"].filter { |e| e["type"] == "relation" }
+      assert_equal 1, js_relations.count
+      assert_equal relation.id, js_relations[0]["id"]
+      assert_equal 1, js_relations[0]["members"].count
+      assert_equal "node", js_relations[0]["members"][0]["type"]
+      assert_equal node.id, js_relations[0]["members"][0]["ref"]
+
+      js_nodes = js["elements"].filter { |e| e["type"] == "node" }
+      assert_equal 1, js_nodes.count
+      assert_equal node.id, js_nodes[0]["id"]
+    end
+
     ##
     # check that all relations containing a particular node, and no extra
     # relations, are returned from the relations_for_node call.
index 2ff5e6f29f786a94b3c7080535fcc371ce9150d3..191f9a82037b14c8f2437c0e1bb5f9661953dd81 100644 (file)
@@ -27,11 +27,11 @@ module Api
       )
       assert_routing(
         { :path => "/api/0.6/way/1/full", :method => :get },
-        { :controller => "api/ways", :action => "full", :id => "1" }
+        { :controller => "api/ways", :action => "show", :full => true, :id => "1" }
       )
       assert_routing(
         { :path => "/api/0.6/way/1/full.json", :method => :get },
-        { :controller => "api/ways", :action => "full", :id => "1", :format => "json" }
+        { :controller => "api/ways", :action => "show", :full => true, :id => "1", :format => "json" }
       )
       assert_routing(
         { :path => "/api/0.6/way/1", :method => :put },
@@ -136,10 +136,10 @@ module Api
 
     ##
     # check the "full" mode
-    def test_full
+    def test_show_full
       way = create(:way_with_nodes, :nodes_count => 3)
 
-      get way_full_path(way)
+      get api_way_path(way, :full => true)
 
       assert_response :success
 
@@ -154,10 +154,42 @@ module Api
       end
     end
 
-    def test_full_deleted
+    def test_show_full_json
+      way = create(:way_with_nodes, :nodes_count => 3)
+
+      get api_way_path(way, :full => true, :format => "json")
+
+      assert_response :success
+
+      # Check the way is correctly returned
+      js = ActiveSupport::JSON.decode(@response.body)
+      assert_not_nil js
+      assert_equal 4, js["elements"].count
+      js_ways = js["elements"].filter { |e| e["type"] == "way" }
+      assert_equal 1, js_ways.count
+      assert_equal way.id, js_ways[0]["id"]
+      assert_equal 1, js_ways[0]["version"]
+
+      # check that each node in the way appears once in the output as a
+      # reference and as the node element.
+      js_nodes = js["elements"].filter { |e| e["type"] == "node" }
+      assert_equal 3, js_nodes.count
+
+      way.nodes.each_with_index do |n, i|
+        assert_equal n.id, js_ways[0]["nodes"][i]
+        js_nodes_with_id = js_nodes.filter { |e| e["id"] == n.id }
+        assert_equal 1, js_nodes_with_id.count
+        assert_equal n.id, js_nodes_with_id[0]["id"]
+        assert_equal 1, js_nodes_with_id[0]["version"]
+        assert_equal n.lat, js_nodes_with_id[0]["lat"]
+        assert_equal n.lon, js_nodes_with_id[0]["lon"]
+      end
+    end
+
+    def test_show_full_deleted
       way = create(:way, :deleted)
 
-      get way_full_path(way)
+      get api_way_path(way, :full => true)
 
       assert_response :gone
     end