From 2b81437fcd38e74d38a41bfc60a917eadd74159b Mon Sep 17 00:00:00 2001 From: Andy Allan Date: Sun, 24 Feb 2019 12:42:07 +0100 Subject: [PATCH] Move the search controller to the api namespace --- app/controllers/api/search_controller.rb | 102 +++++++++++++++++ app/controllers/search_controller.rb | 100 ---------------- config/routes.rb | 8 +- .../controllers/api/search_controller_test.rb | 108 ++++++++++++++++++ test/controllers/search_controller_test.rb | 106 ----------------- 5 files changed, 214 insertions(+), 210 deletions(-) create mode 100644 app/controllers/api/search_controller.rb delete mode 100644 app/controllers/search_controller.rb create mode 100644 test/controllers/api/search_controller_test.rb delete mode 100644 test/controllers/search_controller_test.rb diff --git a/app/controllers/api/search_controller.rb b/app/controllers/api/search_controller.rb new file mode 100644 index 000000000..0afbbf8e2 --- /dev/null +++ b/app/controllers/api/search_controller.rb @@ -0,0 +1,102 @@ +module Api + class SearchController < ApplicationController + # Support searching for nodes, ways, or all + # Can search by tag k, v, or both (type->k,value->v) + # Can search by name (k=name,v=....) + skip_before_action :verify_authenticity_token + authorize_resource :class => false + + def search_all + do_search(true, true, true) + end + + def search_ways + do_search(true, false, false) + end + + def search_nodes + do_search(false, true, false) + end + + def search_relations + do_search(false, false, true) + end + + def do_search(do_ways, do_nodes, do_relations) + type = params["type"] + value = params["value"] + unless type || value + name = params["name"] + if name + type = "name" + value = name + end + end + + if do_nodes + response.headers["Error"] = "Searching of nodes is currently unavailable" + head :service_unavailable + return false + end + + unless value + response.headers["Error"] = "Searching for a key without value is currently unavailable" + head :service_unavailable + return false + end + + # Matching for node tags table + if do_nodes + nodes = Node.joins(:node_tags) + nodes = nodes.where(:current_node_tags => { :k => type }) if type + nodes = nodes.where(:current_node_tags => { :v => value }) if value + nodes = nodes.limit(100) + else + nodes = [] + end + + # Matching for way tags table + if do_ways + ways = Way.joins(:way_tags) + ways = ways.where(:current_way_tags => { :k => type }) if type + ways = ways.where(:current_way_tags => { :v => value }) if value + ways = ways.limit(100) + else + ways = [] + end + + # Matching for relation tags table + if do_relations + relations = Relation.joins(:relation_tags) + relations = relations.where(:current_relation_tags => { :k => type }) if type + relations = relations.where(:current_relation_tags => { :v => value }) if value + relations = relations.limit(2000) + else + relations = [] + end + + # Fetch any node needed for our ways (only have matching nodes so far) + nodes += Node.find(ways.collect(&:nds).uniq) + + # Print + visible_nodes = {} + changeset_cache = {} + user_display_name_cache = {} + doc = OSM::API.new.get_xml_doc + nodes.each do |node| + doc.root << node.to_xml_node(changeset_cache, user_display_name_cache) + visible_nodes[node.id] = node + end + + ways.each do |way| + doc.root << way.to_xml_node(visible_nodes, changeset_cache, user_display_name_cache) + end + + relations.each do |rel| + doc.root << rel.to_xml_node(changeset_cache, user_display_name_cache) + end + + render :xml => doc.to_s + end + end +end diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb deleted file mode 100644 index 3a2e4040f..000000000 --- a/app/controllers/search_controller.rb +++ /dev/null @@ -1,100 +0,0 @@ -class SearchController < ApplicationController - # Support searching for nodes, ways, or all - # Can search by tag k, v, or both (type->k,value->v) - # Can search by name (k=name,v=....) - skip_before_action :verify_authenticity_token - authorize_resource :class => false - - def search_all - do_search(true, true, true) - end - - def search_ways - do_search(true, false, false) - end - - def search_nodes - do_search(false, true, false) - end - - def search_relations - do_search(false, false, true) - end - - def do_search(do_ways, do_nodes, do_relations) - type = params["type"] - value = params["value"] - unless type || value - name = params["name"] - if name - type = "name" - value = name - end - end - - if do_nodes - response.headers["Error"] = "Searching of nodes is currently unavailable" - head :service_unavailable - return false - end - - unless value - response.headers["Error"] = "Searching for a key without value is currently unavailable" - head :service_unavailable - return false - end - - # Matching for node tags table - if do_nodes - nodes = Node.joins(:node_tags) - nodes = nodes.where(:current_node_tags => { :k => type }) if type - nodes = nodes.where(:current_node_tags => { :v => value }) if value - nodes = nodes.limit(100) - else - nodes = [] - end - - # Matching for way tags table - if do_ways - ways = Way.joins(:way_tags) - ways = ways.where(:current_way_tags => { :k => type }) if type - ways = ways.where(:current_way_tags => { :v => value }) if value - ways = ways.limit(100) - else - ways = [] - end - - # Matching for relation tags table - if do_relations - relations = Relation.joins(:relation_tags) - relations = relations.where(:current_relation_tags => { :k => type }) if type - relations = relations.where(:current_relation_tags => { :v => value }) if value - relations = relations.limit(2000) - else - relations = [] - end - - # Fetch any node needed for our ways (only have matching nodes so far) - nodes += Node.find(ways.collect(&:nds).uniq) - - # Print - visible_nodes = {} - changeset_cache = {} - user_display_name_cache = {} - doc = OSM::API.new.get_xml_doc - nodes.each do |node| - doc.root << node.to_xml_node(changeset_cache, user_display_name_cache) - visible_nodes[node.id] = node - end - - ways.each do |way| - doc.root << way.to_xml_node(visible_nodes, changeset_cache, user_display_name_cache) - end - - relations.each do |rel| - doc.root << rel.to_xml_node(changeset_cache, user_display_name_cache) - end - - render :xml => doc.to_s - end -end diff --git a/config/routes.rb b/config/routes.rb index 314cefe9e..a12490158 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -61,10 +61,10 @@ OpenStreetMap::Application.routes.draw do get "changes" => "api/changes#index" - get "search" => "search#search_all", :as => "api_search" - get "ways/search" => "search#search_ways" - get "relations/search" => "search#search_relations" - get "nodes/search" => "search#search_nodes" + get "search" => "api/search#search_all", :as => "api_search" + get "ways/search" => "api/search#search_ways" + get "relations/search" => "api/search#search_relations" + get "nodes/search" => "api/search#search_nodes" get "user/:id" => "users#api_read", :id => /\d+/ get "user/details" => "users#api_details" diff --git a/test/controllers/api/search_controller_test.rb b/test/controllers/api/search_controller_test.rb new file mode 100644 index 000000000..e11a3c729 --- /dev/null +++ b/test/controllers/api/search_controller_test.rb @@ -0,0 +1,108 @@ +require "test_helper" + +module Api + class SearchControllerTest < ActionController::TestCase + ## + # test all routes which lead to this controller + def test_routes + assert_routing( + { :path => "/api/0.6/search", :method => :get }, + { :controller => "api/search", :action => "search_all" } + ) + assert_routing( + { :path => "/api/0.6/nodes/search", :method => :get }, + { :controller => "api/search", :action => "search_nodes" } + ) + assert_routing( + { :path => "/api/0.6/ways/search", :method => :get }, + { :controller => "api/search", :action => "search_ways" } + ) + assert_routing( + { :path => "/api/0.6/relations/search", :method => :get }, + { :controller => "api/search", :action => "search_relations" } + ) + end + + ## + # test searching nodes + def test_search_nodes + get :search_nodes, :params => { :type => "test" } + assert_response :service_unavailable + assert_equal "Searching of nodes is currently unavailable", response.headers["Error"] + + get :search_nodes, :params => { :type => "test", :value => "yes" } + assert_response :service_unavailable + assert_equal "Searching of nodes is currently unavailable", response.headers["Error"] + + get :search_nodes, :params => { :name => "Test Node" } + assert_response :service_unavailable + assert_equal "Searching of nodes is currently unavailable", response.headers["Error"] + end + + ## + # test searching ways + def test_search_ways + first_way = create(:way_with_nodes, :nodes_count => 2) + deleted_way = create(:way_with_nodes, :deleted, :nodes_count => 2) + third_way = create(:way_with_nodes, :nodes_count => 2) + + [first_way, deleted_way, third_way].each do |way| + create(:way_tag, :way => way, :k => "test", :v => "yes") + end + create(:way_tag, :way => third_way, :k => "name", :v => "Test Way") + + get :search_ways, :params => { :type => "test" } + assert_response :service_unavailable + assert_equal "Searching for a key without value is currently unavailable", response.headers["Error"] + + get :search_ways, :params => { :type => "test", :value => "yes" } + assert_response :success + assert_select "way", 3 + + get :search_ways, :params => { :name => "Test Way" } + assert_response :success + assert_select "way", 1 + end + + ## + # test searching relations + def test_search_relations + first_relation = create(:relation) + deleted_relation = create(:relation) + third_relation = create(:relation) + + [first_relation, deleted_relation, third_relation].each do |relation| + create(:relation_tag, :relation => relation, :k => "test", :v => "yes") + end + create(:relation_tag, :relation => third_relation, :k => "name", :v => "Test Relation") + + get :search_relations, :params => { :type => "test" } + assert_response :service_unavailable + assert_equal "Searching for a key without value is currently unavailable", response.headers["Error"] + + get :search_relations, :params => { :type => "test", :value => "yes" } + assert_response :success + assert_select "relation", 3 + + get :search_relations, :params => { :name => "Test Relation" } + assert_response :success + assert_select "relation", 1 + end + + ## + # test searching nodes, ways and relations + def test_search_all + get :search_all, :params => { :type => "test" } + assert_response :service_unavailable + assert_equal "Searching of nodes is currently unavailable", response.headers["Error"] + + get :search_all, :params => { :type => "test", :value => "yes" } + assert_response :service_unavailable + assert_equal "Searching of nodes is currently unavailable", response.headers["Error"] + + get :search_all, :params => { :name => "Test" } + assert_response :service_unavailable + assert_equal "Searching of nodes is currently unavailable", response.headers["Error"] + end + end +end diff --git a/test/controllers/search_controller_test.rb b/test/controllers/search_controller_test.rb deleted file mode 100644 index 49a70f1b0..000000000 --- a/test/controllers/search_controller_test.rb +++ /dev/null @@ -1,106 +0,0 @@ -require "test_helper" - -class SearchControllerTest < ActionController::TestCase - ## - # test all routes which lead to this controller - def test_routes - assert_routing( - { :path => "/api/0.6/search", :method => :get }, - { :controller => "search", :action => "search_all" } - ) - assert_routing( - { :path => "/api/0.6/nodes/search", :method => :get }, - { :controller => "search", :action => "search_nodes" } - ) - assert_routing( - { :path => "/api/0.6/ways/search", :method => :get }, - { :controller => "search", :action => "search_ways" } - ) - assert_routing( - { :path => "/api/0.6/relations/search", :method => :get }, - { :controller => "search", :action => "search_relations" } - ) - end - - ## - # test searching nodes - def test_search_nodes - get :search_nodes, :params => { :type => "test" } - assert_response :service_unavailable - assert_equal "Searching of nodes is currently unavailable", response.headers["Error"] - - get :search_nodes, :params => { :type => "test", :value => "yes" } - assert_response :service_unavailable - assert_equal "Searching of nodes is currently unavailable", response.headers["Error"] - - get :search_nodes, :params => { :name => "Test Node" } - assert_response :service_unavailable - assert_equal "Searching of nodes is currently unavailable", response.headers["Error"] - end - - ## - # test searching ways - def test_search_ways - first_way = create(:way_with_nodes, :nodes_count => 2) - deleted_way = create(:way_with_nodes, :deleted, :nodes_count => 2) - third_way = create(:way_with_nodes, :nodes_count => 2) - - [first_way, deleted_way, third_way].each do |way| - create(:way_tag, :way => way, :k => "test", :v => "yes") - end - create(:way_tag, :way => third_way, :k => "name", :v => "Test Way") - - get :search_ways, :params => { :type => "test" } - assert_response :service_unavailable - assert_equal "Searching for a key without value is currently unavailable", response.headers["Error"] - - get :search_ways, :params => { :type => "test", :value => "yes" } - assert_response :success - assert_select "way", 3 - - get :search_ways, :params => { :name => "Test Way" } - assert_response :success - assert_select "way", 1 - end - - ## - # test searching relations - def test_search_relations - first_relation = create(:relation) - deleted_relation = create(:relation) - third_relation = create(:relation) - - [first_relation, deleted_relation, third_relation].each do |relation| - create(:relation_tag, :relation => relation, :k => "test", :v => "yes") - end - create(:relation_tag, :relation => third_relation, :k => "name", :v => "Test Relation") - - get :search_relations, :params => { :type => "test" } - assert_response :service_unavailable - assert_equal "Searching for a key without value is currently unavailable", response.headers["Error"] - - get :search_relations, :params => { :type => "test", :value => "yes" } - assert_response :success - assert_select "relation", 3 - - get :search_relations, :params => { :name => "Test Relation" } - assert_response :success - assert_select "relation", 1 - end - - ## - # test searching nodes, ways and relations - def test_search_all - get :search_all, :params => { :type => "test" } - assert_response :service_unavailable - assert_equal "Searching of nodes is currently unavailable", response.headers["Error"] - - get :search_all, :params => { :type => "test", :value => "yes" } - assert_response :service_unavailable - assert_equal "Searching of nodes is currently unavailable", response.headers["Error"] - - get :search_all, :params => { :name => "Test" } - assert_response :service_unavailable - assert_equal "Searching of nodes is currently unavailable", response.headers["Error"] - end -end -- 2.43.2