Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update data source for World Location methods #1203

Merged
merged 3 commits into from
Jul 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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|
brucebolt marked this conversation as resolved.
Show resolved Hide resolved
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
brucebolt marked this conversation as resolved.
Show resolved Hide resolved
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