Browse Source

Add a search query projector to handle requests through bragi

develop
Bèr Kessels 3 months ago
parent
commit
6072a7b2ed

+ 3
- 2
Gemfile View File

@@ -9,6 +9,7 @@ gem 'bootstrap', '~> 4.3'
gem 'erubis'
gem 'event_sourcery'
gem 'event_sourcery-postgres', path: '../libs/event_sourcery-postgres'
gem 'faraday'
gem 'hashie'
gem 'json_expressions'
gem 'jsonapi-rb'
@@ -41,10 +42,10 @@ group :development, :test do
gem 'nokogiri'
gem 'puma' # Used by Capybara to run the web thread
gem 'rack-test'
gem 'rubocop'
gem 'selenium-webdriver'
gem 'timecop'

gem 'rubocop'
gem 'vcr'

gem 'awesome_print'
gem 'better_errors'

+ 6
- 0
Gemfile.lock View File

@@ -75,6 +75,8 @@ GEM
erubis (2.7.0)
event_sourcery (0.22.0)
execjs (2.7.0)
faraday (1.0.0)
multipart-post (>= 1.2, < 3)
ffi (1.11.1)
ffi-compiler (1.0.1)
ffi (>= 1.0.0)
@@ -110,6 +112,7 @@ GEM
minitest
nokogiri
multi_json (1.13.1)
multipart-post (2.1.1)
mustermann (1.0.3)
nio4r (2.5.2)
nokogiri (1.8.5)
@@ -213,6 +216,7 @@ GEM
execjs (>= 0.3.0, < 3)
unicode-display_width (1.4.1)
uuidtools (2.1.5)
vcr (5.1.0)
xpath (3.2.0)
nokogiri (~> 1.8)
yajl (0.3.4)
@@ -233,6 +237,7 @@ DEPENDENCIES
erubis
event_sourcery
event_sourcery-postgres!
faraday
foreman
hashie
json_expressions
@@ -260,6 +265,7 @@ DEPENDENCIES
timecop
uglifier
uuidtools
vcr
yajl
yajl-ruby


+ 65
- 0
app/projections/search_query.rb View File

@@ -0,0 +1,65 @@
# frozen_string_literal: true

require 'faraday'
require 'pagy'
require 'pagy/extras/array'
require 'rgeo/geo_json'

module Hours
module Projections
# Query handler that queries bragi, the rest backend for a string
class SearchQuery
include Pagy::Backend

attr_accessor :page

def self.build
faraday = Faraday.new(url: ENV['BRAGI_URL']) do |conn|
conn.response :raise_error
conn.adapter Faraday.default_adapter
end
new(faraday)
end

def initialize(http_client)
@http_client = http_client
end

def handle(query, page = 1)
@page = page
features = get_bragi_features(query)
pagy, places = pagy_array(features)
Hours::Models::SearchResult.new(
dataset: places,
paginator: pagy,
query: query
)
rescue Faraday::ServerError => e
Hours::Models::SearchResult.new(error: e.message)
end

protected

def pagy_array_get_vars(array, vars = {})
vars[:count] = array.size
vars[:page] = page
vars
end

private

def get_bragi_features(query)
response = @http_client.get('autocomplete') do |req|
req.params[:q] = query
end
RGeo::GeoJSON.decode(response.body).to_a
rescue JSON::ParserError
[]
end

def bragi_url(query)
"autocomplete?q=#{query}"
end
end
end
end

+ 42
- 0
test/projections/search_query_test.rb View File

@@ -0,0 +1,42 @@
# frozen_string_literal: true

require 'test_helper'

describe Hours::Projections::SearchQuery do
let(:bragi_response) { OpenStruct.new(body: '{}', code: 200) }
let(:error_response) { OpenStruct.new(body: '', code: 500) }

let(:http_client) do
Minitest::Mock.new
end

subject do
Hours::Projections::SearchQuery.new(http_client)
end

it 'requests from HTTP service' do
http_client.expect(:get, bragi_response, ['autocomplete'])

assert_kind_of Hours::Models::SearchResult, subject.handle('Smullers')

assert_mock http_client
end

it 'handles broken body from HTTP service' do
http_client.expect(:get, error_response, [String])

assert_kind_of Hours::Models::SearchResult, subject.handle('Smullers')

assert_mock http_client
end

it 'handles HTTP errors from HTTP service' do
error = ->(_args) { raise Faraday::ServerError, '503' }
http_client = OpenStruct.new(get: '')

http_client.stub(:get, error) do
result = Hours::Projections::SearchQuery.new(http_client).handle('')
assert_equal '503', result.error
end
end
end

BIN
vendor/cache/faraday-1.0.0.gem View File


BIN
vendor/cache/multipart-post-2.1.1.gem View File


BIN
vendor/cache/vcr-5.1.0.gem View File


Loading…
Cancel
Save