From 9d0ed94abe86a1e1aa7ecba6ae746dcfdb894a3b Mon Sep 17 00:00:00 2001 From: Hakan Ensari Date: Mon, 11 Apr 2016 14:26:49 +0100 Subject: [PATCH] Refactor quote validation --- lib/api.rb | 18 +++--------------- lib/quote.rb | 13 ++++++++++--- spec/quote_spec.rb | 18 +++++++++++++----- 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/lib/api.rb b/lib/api.rb index 41388f3..325d7de 100644 --- a/lib/api.rb +++ b/lib/api.rb @@ -26,6 +26,8 @@ helpers do ret end + rescue Quote::Invalid => ex + halt_with_message 422, ex.message end def symbols @@ -37,14 +39,6 @@ helpers do end end - def transform_date - params[:date] = Date.new( - params.delete('year').to_i, - params.delete('month').to_i, - params.delete('day').to_i - ) - end - def halt_with_message(status, message) halt status, Yajl::Encoder.encode(error: message) end @@ -59,17 +53,11 @@ get '/latest' do jsonp quote end -get(/(?\d{4})-(?\d{2})-(?\d{2})/) do - transform_date +get(/(?\d{4}-\d{2}-\d{2})/) do last_modified quote[:date] - jsonp quote end not_found do halt_with_message 404, 'Not found' end - -error ArgumentError do - halt_with_message 422, env['sinatra.error'].message.capitalize -end diff --git a/lib/quote.rb b/lib/quote.rb index f014b9c..d28fb40 100644 --- a/lib/quote.rb +++ b/lib/quote.rb @@ -6,6 +6,8 @@ require 'currency' class Quote include Virtus.value_object + Invalid = Class.new(StandardError) + DEFAULT_BASE = 'EUR'.freeze values do @@ -23,9 +25,14 @@ class Quote def date=(date) current_date = Currency.current_date_before(date) - fail ArgumentError, 'Date too old' unless current_date - + raise Invalid, 'Date too old' unless current_date super current_date + rescue Sequel::DatabaseError => ex + if ex.wrapped_exception.is_a?(PG::DatetimeFieldOverflow) + raise Invalid, 'Invalid date' + else + raise + end end def find_rates @@ -45,7 +52,7 @@ class Quote def find_rebased_rates rates = find_default_rates denominator = rates.update(DEFAULT_BASE => 1.0).delete(base) - fail ArgumentError, 'Invalid base' unless denominator + raise Invalid, 'Invalid base' unless denominator rates.each do |iso_code, rate| rates[iso_code] = round_rate(rate / denominator) end diff --git a/spec/quote_spec.rb b/spec/quote_spec.rb index f400164..7dceb94 100644 --- a/spec/quote_spec.rb +++ b/spec/quote_spec.rb @@ -59,18 +59,26 @@ describe Quote do describe 'when given an invalid base' do let(:quote) { Quote.new(base: 'FOO') } - it 'fails' do - proc { quote.to_h }.must_raise ArgumentError + it 'raises validation error' do + proc { quote.to_h }.must_raise Quote::Invalid end end describe 'when given a date that is too old' do - let(:quote) { Quote.new(date: Date.new(1900)) } + let(:quote) { Quote.new(date: '1900-01-01') } - it 'fails' do + it 'raises validation error' do Currency.stub :current_date_before, nil do - proc { quote }.must_raise ArgumentError + proc { quote }.must_raise Quote::Invalid end end end + + describe 'when given a bad date' do + let(:quote) { Quote.new(date: '2000-31-01') } + + it 'raises validation error' do + proc { quote }.must_raise Quote::Invalid + end + end end