Browse Source

Handle 404 and empty cities as "not found" from upstream.

tags/0.3.6^2
Bèr Kessels 1 month ago
parent
commit
afc8e72daa

+ 6
- 3
app/projections/city_query.rb View File

@@ -45,9 +45,12 @@ module Hours

response = @http_client.get('/autocomplete', city_params)

@city = Hours::Models::City.from_geojson_feature(
RGeo::GeoJSON.decode(response.body).first
)
geojson = RGeo::GeoJSON.decode(response.body).first
raise Hours::CityNotFound unless geojson

@city = Hours::Models::City.from_geojson_feature(geojson)
rescue Faraday::ResourceNotFound
raise Hours::CityNotFound
end

def places

+ 12
- 4
lib/app.rb View File

@@ -3,6 +3,7 @@
# This contains the Sinatra App
require_relative './hours.rb'
require_relative './capture_helpers.rb'
require_relative './errors.rb'
require_relative './json_helpers.rb'
require_relative './pagination_helpers.rb'
require_relative Hours.base_path.join('config/event_sourcery.rb')
@@ -88,6 +89,11 @@ module Hours
status 400
end

def not_found
body "Not Found: 404"
status 404
end

def places_url(id)
URI.join(request.base_url, "/places/#{id}").to_s
end
@@ -97,7 +103,7 @@ module Hours
if @place
yield block
else
404
not_found
end
end

@@ -129,15 +135,17 @@ module Hours
page_param
)
erb :region
rescue Faraday::BadRequestError
400
rescue Faraday::BadRequestError => e
bad_request(e)
rescue Hours::CityNotFound
not_found
end

get %r{/places/(?<id>[\w:]+)}, provides: 'html' do
@place = Hours::Projections::PlaceQuery.build.handle(params[:id])
erb :place
rescue Faraday::ResourceNotFound
404
not_found
end
end
end

+ 4
- 0
lib/errors.rb View File

@@ -0,0 +1,4 @@
## Raised when we recieved an empty city or a 404 for a city
module Hours
class CityNotFound < ::StandardError; end
end

+ 3
- 2
test/fixtures/vcr_cassettes/city_error_400.yml View File

@@ -26,12 +26,13 @@ http_interactions:
- Mon, 15 Jun 2020 14:40:53 GMT
body:
encoding: UTF-8
string: '{"type":"FeatureCollection","geocoding":{"version":"0.1.0","query":""},"features":[]}'
## Note to emulate reailyt that goes amiss: return empty BBOX
string: '{"type":"FeatureCollection","geocoding":{"version":"0.1.0","query":""},"features":[{"type":"Feature","geometry":{"coordinates":[5.9108573,51.984257],"type":"Point"},"properties":{"geocoding":{"bbox":[]}}}]}'
http_version: null
recorded_at: Mon, 15 Jun 2020 14:40:53 GMT
- request:
method: post
uri: http://localhost:4000/features?lat=0&limit=20&lon=0&type%5B%5D=poi
uri: http://localhost:4000/features?lat=51.984257&limit=20&lon=5.9108573&type%5B%5D=poi
body:
encoding: UTF-8
string: ''

+ 31
- 0
test/fixtures/vcr_cassettes/city_not_found.yml View File

@@ -0,0 +1,31 @@
---
http_interactions:
- request:
method: get
uri: http://localhost:4000/autocomplete?limit=1&q=nonexisting&type%5B%5D=city
body:
encoding: US-ASCII
string: ''
headers:
User-Agent:
- Faraday v1.0.0
response:
status:
code: 200 # NOTE: thsi is correct: Bragi returns a 200 when no city is found
message: OK
headers:
content-length:
- '85'
connection:
- close
content-type:
- application/json
cache-control:
- max-age=3600
date:
- Wed, 17 Jun 2020 12:48:18 GMT
body:
encoding: UTF-8
string: '{"type":"FeatureCollection","geocoding":{"version":"0.1.0","query":""},"features":[]}'
http_version: null
recorded_at: Wed, 17 Jun 2020 12:48:18 GMT

+ 11
- 1
test/integration/web/view_regions_test.rb View File

@@ -126,7 +126,6 @@ describe 'web views regions' do

describe 'GET /in/eindhoven empty place' do
it 'shows empty text' do
#@INK: implementing bbox as shape. but the Eindhoven vcr-cassette has no bbox
VCR.use_cassette :city_eindhoven do
visit '/in/eindhoven'
end
@@ -134,12 +133,23 @@ describe 'web views regions' do
end
end

describe 'GET /in/nonexisting nonexisting place' do
it 'shows 404 text' do
VCR.use_cassette :city_not_found do
visit '/in/nonexisting'
end
assert_equal 404, page.status_code
assert_includes page.body, 'Not Found'
end
end

describe 'GET /in/foo returns a 400 error' do
it 'shows an error message' do
VCR.use_cassette :city_error_400 do
visit '/in/foo'
end
assert_equal 400, page.status_code
assert_includes page.body, 'Bad Request'
end
end
end

+ 29
- 2
test/projections/city_query_test.rb View File

@@ -19,7 +19,7 @@ describe Hours::Projections::CityQuery do
let(:features_response) { OpenStruct.new(body: body.to_json, code: 200) }
let(:error_response) { OpenStruct.new(body: '[]', code: 400) }

class ClientRaises
class ClientRaisesBadRequest
def initialize(search_response, error_response)
@search_response = search_response
@error_response = error_response
@@ -36,6 +36,15 @@ describe Hours::Projections::CityQuery do
end
end

class ClientRaisesNotFound
def get(*args)
raise(
Faraday::ResourceNotFound,
{ status: 404, headers: [], body: "" }
)
end
end

it '#handle fetches a single city and then its places from bragi' do
http_client = Minitest::Mock.new
http_client.expect(
@@ -57,8 +66,26 @@ describe Hours::Projections::CityQuery do
end

it '#handle catches error 400 from upstream' do
http_client = ClientRaises.new(search_response, error_response)
http_client = ClientRaisesBadRequest.new(search_response, error_response)
subject = Hours::Projections::CityQuery.new(http_client)
assert_raises(Faraday::BadRequestError) { subject.handle('nijmegen') }
end

it '#handle raises a 404 if upstream gives a 404' do
http_client = ClientRaisesNotFound.new
subject = Hours::Projections::CityQuery.new(http_client)
assert_raises(Hours::CityNotFound) { subject.handle('nijmegen') }
end

it '#handle raises a 404 if city is empty' do
body = '{"type":"FeatureCollection","features":[]}'
http_client = Minitest::Mock.new
http_client.expect(
:get,
OpenStruct.new(body: body, code: 200),
['/autocomplete', { q: 'nonexisting', limit: 1, type: ['city'] }]
)
subject = Hours::Projections::CityQuery.new(http_client)
assert_raises(Hours::CityNotFound) { subject.handle('nonexisting') }
end
end

Loading…
Cancel
Save