From 9139b9948829b4cdbb79534df29f1bf7382db723 Mon Sep 17 00:00:00 2001 From: Martyn Lloyd-Kelly Date: Wed, 6 Sep 2023 15:57:28 +0100 Subject: [PATCH 1/2] Add an adapter for `search-api-v2` In the short-term, `search-api-v2` will exist alongside the current `search-api` service. `search-api-v2` provides a compatible API for pure search (GET requests) so the adapter is almost equivalent to `search-api`. The reasoning for this is so that, from a consuming service's perspective, the search interface is the same. --- lib/gds_api.rb | 1 + lib/gds_api/search_api_v2.rb | 8 ++++ test/search_api_v2_test.rb | 80 ++++++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 lib/gds_api/search_api_v2.rb create mode 100644 test/search_api_v2_test.rb diff --git a/lib/gds_api.rb b/lib/gds_api.rb index 338efedd..3e5cd2e6 100644 --- a/lib/gds_api.rb +++ b/lib/gds_api.rb @@ -16,6 +16,7 @@ require "gds_api/publishing_api" require "gds_api/router" require "gds_api/search" +require "gds_api/search_api_v2" require "gds_api/support" require "gds_api/support_api" require "gds_api/worldwide" diff --git a/lib/gds_api/search_api_v2.rb b/lib/gds_api/search_api_v2.rb new file mode 100644 index 00000000..9e374b21 --- /dev/null +++ b/lib/gds_api/search_api_v2.rb @@ -0,0 +1,8 @@ +module GdsApi + class SearchApiV2 < Base + def search(args, additional_headers = {}) + request_url = "#{endpoint}/search.json?#{Rack::Utils.build_nested_query(args)}" + get_json(request_url, additional_headers) + end + end +end diff --git a/test/search_api_v2_test.rb b/test/search_api_v2_test.rb new file mode 100644 index 00000000..c2d59e72 --- /dev/null +++ b/test/search_api_v2_test.rb @@ -0,0 +1,80 @@ +require "test_helper" +require "gds_api/search_api_v2" + +describe GdsApi::SearchApiV2 do + before(:each) do + stub_request(:get, /example.com\/search/).to_return(body: "[]") + end + + it "#search should raise an exception if the service at the search URI returns a 500" do + stub_request(:get, /example.com\/search.json/).to_return(status: [500, "Internal Server Error"]) + assert_raises(GdsApi::HTTPServerError) do + GdsApi::SearchApiV2.new("http://example.com").search(q: "query") + end + end + + it "#search should raise an exception if the service at the search URI returns a 404" do + stub_request(:get, /example.com\/search/).to_return(status: [404, "Not Found"]) + assert_raises(GdsApi::HTTPNotFound) do + GdsApi::SearchApiV2.new("http://example.com").search(q: "query") + end + end + + it "#search should raise an exception if the service at the search URI returns a 400" do + stub_request(:get, /example.com\/search/).to_return( + status: [400, "Bad Request"], + body: '"error":"Filtering by \"coffee\" is not allowed"', + ) + assert_raises(GdsApi::HTTPClientError) do + GdsApi::SearchApiV2.new("http://example.com").search(q: "query", filter_coffee: "tea") + end + end + + it "#search should raise an exception if the service at the search URI returns a 422" do + stub_request(:get, /example.com\/search/).to_return( + status: [422, "Bad Request"], + body: '"error":"Filtering by \"coffee\" is not allowed"', + ) + assert_raises(GdsApi::HTTPUnprocessableEntity) do + GdsApi::SearchApiV2.new("http://example.com").search(q: "query", filter_coffee: "tea") + end + end + + it "#search should raise an exception if the service at the search URI times out" do + stub_request(:get, /example.com\/search/).to_timeout + assert_raises(GdsApi::TimedOutException) do + GdsApi::SearchApiV2.new("http://example.com").search(q: "query") + end + end + + it "#search should return the search deserialized from json" do + search_results = [{ "title" => "document-title" }] + stub_request(:get, /example.com\/search/).to_return(body: search_results.to_json) + results = GdsApi::SearchApiV2.new("http://example.com").search(q: "query") + assert_equal search_results, results.to_hash + end + + it "#search should request the search results in JSON format" do + GdsApi::SearchApiV2.new("http://example.com").search(q: "query") + + assert_requested :get, /.*/, headers: { "Accept" => "application/json" } + end + + it "#search should issue a request for all the params supplied" do + GdsApi::SearchApiV2.new("http://example.com").search( + q: "query & stuff", + filter_topics: %w[1 2], + order: "-public_timestamp", + ) + + assert_requested :get, /q=query%20%26%20stuff/ + assert_requested :get, /filter_topics\[\]=1&filter_topics\[\]=2/ + assert_requested :get, /order=-public_timestamp/ + end + + it "#search can pass additional headers" do + GdsApi::SearchApiV2.new("http://example.com").search({ q: "query" }, "authorization" => "token") + + assert_requested :get, /.*/, headers: { "authorization" => "token" } + end +end From fe9103b34cda50f856456a8b8e3ba6b0d714412d Mon Sep 17 00:00:00 2001 From: Christian Sutter Date: Thu, 7 Sep 2023 12:41:32 +0100 Subject: [PATCH 2/2] Amend changelog with `search-api-v2` changes --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 009ff33a..960c4a57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ * BREAKING: Remove Account API `get_email_subscription` method and helpers * BREAKING: Remove Account API `put_email_subscription` method and helpers * BREAKING: Remove Account API `delete_email_subscription` method and helpers +* Add a basic adapter for the new `search-api-v2` service, intially with a `#search` method along + the lines of the existing adapter for `search-api` for consistency * Note: These are no longer used by any apps, so should not be breaking in practice. # 90.0.0