Skip to content

Commit

Permalink
Merge pull request #1203 from alphagov/update-world-method
Browse files Browse the repository at this point in the history
Update data source for World Location methods
  • Loading branch information
brucebolt authored Jul 19, 2023
2 parents 608e8c0 + 1ab0e84 commit ade2e5f
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 210 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# 89.0.0

* BREAKING: Change source for `GdsApi.worldwide.world_locations` method and remove pagination.
* Change source for `GdsApi.worldwide.world_location` method (the response is backwards compatible).

# 88.2.0

* Add `whitehall_media` method to Asset Manager.
Expand Down
140 changes: 33 additions & 107 deletions lib/gds_api/test_helpers/worldwide.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,95 +8,48 @@ module Worldwide

WORLDWIDE_API_ENDPOINT = Plek.new.website_root

# Sets up the index endpoints for the given country slugs
# The stubs are setup to paginate in chunks of 20
#
# This also sets up the individual endpoints for each slug
# by calling stub_worldwide_api_has_location below
def stub_worldwide_api_has_locations(location_slugs)
location_slugs.each { |s| stub_worldwide_api_has_location(s) }
pages = []
location_slugs.each_slice(20) do |slugs|
pages << slugs.map { |s| world_location_details_for_slug(s) }
international_delegation_slugs = location_slugs.select do |slug|
slug =~ /(delegation|mission)/
end

pages.each_with_index do |page, i|
page_details = plural_response_base.merge(
"results" => page,
"total" => location_slugs.size,
"pages" => pages.size,
"current_page" => i + 1,
"page_size" => 20,
"start_index" => i * 20 + 1,
)

links = { self: "#{WORLDWIDE_API_ENDPOINT}/api/world-locations?page=#{i + 1}" }
links[:next] = "#{WORLDWIDE_API_ENDPOINT}/api/world-locations?page=#{i + 2}" if pages[i + 1]
links[:previous] = "#{WORLDWIDE_API_ENDPOINT}/api/world-locations?page=#{i}" unless i.zero?
page_details["_response_info"]["links"] = []
link_headers = []
links.each do |rel, href|
page_details["_response_info"]["links"] << { "rel" => rel, "href" => href }
link_headers << "<#{href}>; rel=\"#{rel}\""
end

stub_request(:get, links[:self])
.to_return(status: 200, body: page_details.to_json, headers: { "Link" => link_headers.join(", ") })

next unless i.zero?
international_delegations = international_delegation_slugs.map do |slug|
{
"active": true,
"analytics_identifier": "WL1",
"content_id": "content_id_for_#{slug}",
"iso2": slug[0..1].upcase,
"name": titleize_slug(slug, title_case: true),
"slug": slug,
"updated_at": "2013-03-25T13:06:42+00:00",
}
end

# First page exists at URL with and without page param
stub_request(:get, links[:self].sub(/\?page=1/, ""))
.to_return(status: 200, body: page_details.to_json, headers: { "Link" => link_headers.join(", ") })
world_locations = (location_slugs - international_delegation_slugs).map do |slug|
{
"active": true,
"analytics_identifier": "WL1",
"content_id": "content_id_for_#{slug}",
"iso2": slug[0..1].upcase,
"name": titleize_slug(slug, title_case: true),
"slug": slug,
"updated_at": "2013-03-25T13:06:42+00:00",
}
end
end

def stub_worldwide_api_has_selection_of_locations
stub_worldwide_api_has_locations %w[
afghanistan
angola
australia
bahamas
belarus
brazil
brunei
cambodia
chad
croatia
denmark
eritrea
france
ghana
iceland
japan
laos
luxembourg
malta
micronesia
mozambique
nicaragua
panama
portugal
sao-tome-and-principe
singapore
south-korea
sri-lanka
uk-delegation-to-council-of-europe
uk-delegation-to-organization-for-security-and-co-operation-in-europe
united-kingdom
venezuela
vietnam
]
end
content_item = {
"details": {
"international_delegation": international_delegations,
"world_locations": world_locations,
},
}

def stub_worldwide_api_has_location(location_slug, details = nil)
details ||= world_location_for_slug(location_slug)
stub_request(:get, "#{WORLDWIDE_API_ENDPOINT}/api/world-locations/#{location_slug}")
.to_return(status: 200, body: details.to_json)
stub_request(:get, "#{WORLDWIDE_API_ENDPOINT}/api/content/world")
.to_return(status: 200, body: content_item.to_json)
end

def stub_worldwide_api_does_not_have_location(location_slug)
stub_request(:get, "#{WORLDWIDE_API_ENDPOINT}/api/world-locations/#{location_slug}").to_return(status: 404)
def stub_worldwide_api_has_location(location_slug)
stub_worldwide_api_has_locations([location_slug])
end

def stub_worldwide_api_has_organisations_for_location(location_slug, json_or_hash)
Expand All @@ -112,33 +65,6 @@ def stub_worldwide_api_has_no_organisations_for_location(location_slug)
stub_request(:get, url)
.to_return(status: 200, body: details.to_json, headers: { "Link" => "<#{url}; rel\"self\"" })
end

def world_location_for_slug(slug)
singular_response_base.merge(world_location_details_for_slug(slug))
end

# Constructs a sample world_location
#
# if the slug contains 'delegation' or 'mission' the format will be set to 'International delegation'
# othersiwe it will be set to 'World location'
def world_location_details_for_slug(slug)
{
"id" => "https://www.gov.uk/api/world-locations/#{slug}",
"title" => titleize_slug(slug, title_case: true),
"format" => (slug =~ /(delegation|mission)/ ? "International delegation" : "World location"),
"updated_at" => "2013-03-25T13:06:42+00:00",
"web_url" => "https://www.gov.uk/government/world/#{slug}",
"details" => {
"slug" => slug,
"iso2" => slug[0..1].upcase,
},
"organisations" => {
"id" => "https://www.gov.uk/api/world-locations/#{slug}/organisations",
"web_url" => "https://www.gov.uk/government/world/#{slug}#organisations",
},
"content_id" => "content_id_for_#{slug}",
}
end
end
end
end
2 changes: 1 addition & 1 deletion lib/gds_api/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module GdsApi
VERSION = "88.2.0".freeze
VERSION = "89.0.0".freeze
end
41 changes: 39 additions & 2 deletions lib/gds_api/worldwide.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,17 @@

class GdsApi::Worldwide < GdsApi::Base
def world_locations
get_list("#{base_url}/world-locations")
all_world_locations
end

def world_location(location_slug)
get_json("#{base_url}/world-locations/#{location_slug}")
world_location = all_world_locations.find do |location|
location.dig("details", "slug") == location_slug
end

raise GdsApi::HTTPNotFound, 404 unless world_location

world_location
end

def organisations_for_world_location(location_slug)
Expand All @@ -18,4 +24,35 @@ def organisations_for_world_location(location_slug)
def base_url
"#{endpoint}/api"
end

def all_world_locations
content_item = JSON.parse(get_raw("#{base_url}/content/world"))

world_locations = format_locations(content_item.dig("details", "world_locations"), "World location")
international_delegations = format_locations(content_item.dig("details", "international_delegations"), "International delegation")

Array(world_locations) + Array(international_delegations)
end

def format_locations(locations, type)
locations&.map do |location|
{
"id" => "#{Plek.new.website_root}/world/#{location['slug']}",
"title" => location["name"],
"format" => type,
"updated_at" => location["updated_at"],
"web_url" => "#{Plek.new.website_root}/world/#{location['slug']}",
"analytics_identifier" => location["analytics_identifier"],
"details" => {
"slug" => location["slug"],
"iso2" => location["iso2"],
},
"organisations" => {
"id" => "#{Plek.new.website_root}/world/#{location['slug']}#organisations",
"web_url" => "#{Plek.new.website_root}/world/#{location['slug']}#organisations",
},
"content_id" => location["content_id"],
}
end
end
end
78 changes: 0 additions & 78 deletions test/pacts/worldwide_api_pact_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,85 +6,7 @@

let(:api_client) { GdsApi::Worldwide.new(whitehall_api_host) }

describe "#world_locations" do
it "responds with 200 and all world locations" do
whitehall_api
.given("a world location exists")
.upon_receiving("a request to return all world locations")
.with(
method: :get,
path: "/api/world-locations",
headers: GdsApi::JsonClient.default_request_headers,
)
.will_respond_with(
status: 200,
body: {
results: [
Pact.like(
id: "https://www.gov.uk/api/world-locations/france",
title: "France",
format: "World location",
updated_at: "2020-09-02T06:47:34.000+01:00",
web_url: "https://www.gov.uk/world/france",
analytics_identifier: "WL1",
details: {
slug: "france",
iso2: nil,
},
organisations: {
id: "https://www.gov.uk/api/world-locations/france/organisations",
web_url: "https://www.gov.uk/world/france#organisations",
},
content_id: "5e9ecbce-7706-11e4-a3cb-005056011aef",
),
],
},
headers: {
"Content-Type" => "application/json; charset=utf-8",
},
)

api_client.world_locations
end
end

describe "#world_location" do
it "responds with 200 and requested world location" do
whitehall_api
.given("a world location exists")
.upon_receiving("a request to return a specific world location")
.with(
method: :get,
path: "/api/world-locations/france",
headers: GdsApi::JsonClient.default_request_headers,
)
.will_respond_with(
status: 200,
body: {
id: Pact.like("https://www.gov.uk/api/world-locations/france"),
title: "France",
format: "World location",
updated_at: Pact.like("2020-09-02T06:47:34.000+01:00"),
web_url: Pact.like("https://www.gov.uk/world/france"),
analytics_identifier: Pact.like("WL1"),
details: {
slug: "france",
iso2: nil,
},
organisations: Pact.like(
id: "https://www.gov.uk/api/world-locations/france/organisations",
web_url: "https://www.gov.uk/world/france#organisations",
),
content_id: Pact.like("5e9ecbce-7706-11e4-a3cb-005056011aef"),
},
headers: {
"Content-Type" => "application/json; charset=utf-8",
},
)

api_client.world_location("france")
end

describe "#organisations_for_world_location" do
it "responds with 200 and all worldwide organisations" do
whitehall_api
Expand Down
25 changes: 3 additions & 22 deletions test/worldwide_api_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,39 +17,20 @@
stub_worldwide_api_has_locations(country_slugs)

response = @api.world_locations
assert_equal(country_slugs, response.map { |r| r["details"]["slug"] })
assert_equal "Rohan", response["results"][2]["title"]
end

it "should handle the pagination" do
country_slugs = (1..50).map { |n| "country-#{n}" }
stub_worldwide_api_has_locations(country_slugs)

response = @api.world_locations
assert_equal(
country_slugs,
response.with_subsequent_pages.map { |r| r["details"]["slug"] },
)
end

it "should raise error if endpoint 404s" do
stub_request(:get, "#{@base_api_url}/api/world-locations").to_return(status: 404)
assert_raises GdsApi::HTTPNotFound do
@api.world_locations
end
assert_equal(country_slugs, response.map { |r| r.dig("details", "slug") })
end
end

describe "fetching a world location" do
it "should return the details" do
stub_worldwide_api_has_location("rohan")
stub_worldwide_api_has_locations(%w[rohan])

response = @api.world_location("rohan")
assert_equal "Rohan", response["title"]
end

it "raises for a non-existent location" do
stub_worldwide_api_does_not_have_location("non-existent")
stub_worldwide_api_has_locations(%w[rohan])

assert_raises(GdsApi::HTTPNotFound) do
@api.world_location("non-existent")
Expand Down

0 comments on commit ade2e5f

Please sign in to comment.