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

Handle invalid parameter values #130

Merged
merged 4 commits into from
Nov 25, 2024
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
28 changes: 21 additions & 7 deletions app/controllers/forecasts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ class ForecastsController < ApplicationController
def show
@maptiler_api_key = ENV.fetch("MAPTILER_API_KEY")
@zone = zone
@date = Date.parse(params.fetch("date")) if params[:date]
@day = @date ? day_from_date(@date) : params.fetch("day", "today")
@pollutant = params.fetch("pollutant", "Total")
@date = date
@day = @date ? day_from_date(@date) : day
@pollutant = pollutant
@map_lat = params.fetch("lat", nil)
@map_lon = params.fetch("lon", nil)
@map_zoom = params.fetch("zoom", nil)
Expand All @@ -22,8 +22,6 @@ def day_from_date(date)
"tomorrow"
elsif date >= Date.tomorrow
"day_after_tomorrow"
else
"today"
end
end

Expand All @@ -35,8 +33,6 @@ def forecast_for_day(day, forecasts)
forecasts.second
when "day_after_tomorrow"
forecasts.third
else
raise ArgumentError, "Invalid day: #{day}"
end
end

Expand All @@ -45,4 +41,22 @@ def zone

Zone.find_by(name: params[:zone])
end

def date
Date.parse(params.fetch("date")) if params[:date].present?
rescue ArgumentError
Date.today # default to today
end

def day
return params.fetch("day") if %w[today tomorrow day_after_tomorrow].include?(params.dig("day"))

"today" # default to today
end

def pollutant
return params.fetch("pollutant", "Total") if %w[Total PM10 PM25 NO2 O3].include?(params.dig("pollutant"))

"Total" # default to Total
end
end
65 changes: 45 additions & 20 deletions spec/controllers/forecasts_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
before do
allow(Zone).to receive(:find_by).and_return(barnet)
allow(Zone).to receive(:default).and_return(southwark)
allow(CercForecastService).to receive(:latest_forecasts_for).and_return(forecasts)
end

let(:forecasts) do
Expand All @@ -14,8 +15,6 @@
describe "GET :show" do
context "when NO zone is given" do
it "obtains forecasts for the default zone (Southwark) from the CercForecastService" do
allow(CercForecastService).to receive(:latest_forecasts_for).and_return(forecasts)

get :show

expect(CercForecastService).to have_received(:latest_forecasts_for).with(southwark)
Expand All @@ -24,46 +23,42 @@

context "when zone IS given" do
it "obtains forecasts for the given zone from the CercForecastService" do
allow(CercForecastService).to receive(:latest_forecasts_for).and_return(forecasts)

get :show, params: {zone: double}

expect(CercForecastService).to have_received(:latest_forecasts_for).with(barnet)
end
end

it "renders the _show_ template" do
allow(CercForecastService).to receive(:latest_forecasts_for).and_return(forecasts)

get :show

expect(response).to render_template("show")
end

context "when a recognised _day_ parameter is received" do
it "renders the _show_ template" do
allow(CercForecastService).to receive(:latest_forecasts_for).and_return(forecasts)
context "when a _day_ parameter is received" do
before do
get :show, params: {day: day}
end

get :show, params: {day: :today}
context "when a recognised _day_ parameter is received" do
let(:day) { "tomorrow" }

expect(CercForecastService).to have_received(:latest_forecasts_for).with(southwark)
expect(response).to render_template("show")
it "shows the forecast for the given day" do
expect(assigns(:day_forecast)).to eq(forecasts.data.second)
end
end
end

context "when an unrecognised _day_ parameter is received" do
it "raises a helpful error" do
allow(CercForecastService).to receive(:latest_forecasts_for).and_return(forecasts)
context "when an unrecognised _day_ parameter is received" do
let(:day) { "invalid" }

expect {
get :show, params: {day: :yesterday}
}.to raise_error(ArgumentError, "Invalid day: yesterday")
it "shows today's forecast" do
expect(assigns(:day_forecast)).to eq(forecasts.data.first)
end
end
end

context "when a _date_ parameter is received" do
before do
allow(CercForecastService).to receive(:latest_forecasts_for).and_return(forecasts)
get :show, params: {date: date.to_s}
end

Expand Down Expand Up @@ -106,6 +101,36 @@
expect(assigns(:day_forecast)).to eq(forecasts.data.third)
end
end

context "when the date is invalid" do
let(:date) { "invalid" }

it "shows the forecast for today" do
expect(assigns(:day_forecast)).to eq(forecasts.data.first)
end
end
end
end

context "when a _pollutant_ parameter is received" do
before do
get :show, params: {pollutant: pollutant}
end

context "when the pollutant is recognised" do
let(:pollutant) { "PM10" }

it "set the pollutant to the given value" do
expect(assigns(:pollutant)).to eq("PM10")
end
end

context "when the pollutant is not recognised" do
let(:pollutant) { "invalid" }

it "defaults to showing the Total forecast" do
expect(assigns(:pollutant)).to eq("Total")
end
end
end
end