diff --git a/lib/tenkit/client.rb b/lib/tenkit/client.rb index 3386ab7..57614eb 100644 --- a/lib/tenkit/client.rb +++ b/lib/tenkit/client.rb @@ -24,14 +24,21 @@ def initialize Tenkit.config.validate! end - def availability(lat, lon, country: 'US') - get("/availability/#{lat}/#{lon}?country=#{country}") + def availability(lat, lon, **options) + options[:country] ||= 'US' + + query = { country: options[:country] } + get("/availability/#{lat}/#{lon}", query: query) end - def weather(lat, lon, data_sets: [:current_weather], language: 'en') - path_root = "/weather/#{language}/#{lat}/#{lon}?dataSets=" - path = path_root + data_sets.map { |ds| DATA_SETS[ds] }.compact.join(',') - response = get(path) + def weather(lat, lon, **options) + options[:data_sets] ||= [:current_weather] + options[:language] ||= 'en' + + query = weather_query_for_options(options) + path = "/weather/#{options[:language]}/#{lat}/#{lon}" + + response = get(path, query: query) WeatherResponse.new(response) end @@ -43,9 +50,15 @@ def weather_alert(id, language: 'en') private - def get(url) + def get(url, query: nil) headers = { Authorization: "Bearer #{token}" } - self.class.get(url, { headers: headers }) + params = { headers: headers } + + if !query.nil? + params[:query] = query + end + + self.class.get(url, params) end def header @@ -72,5 +85,22 @@ def key def token JWT.encode payload, key, 'ES256', header end + + # Snake case options to expected query parameters + # https://developer.apple.com/documentation/weatherkitrestapi/get-api-v1-weather-_language_-_latitude_-_longitude_#query-parameters + def weather_query_for_options(options) + data_sets_param = options[:data_sets].map { |ds| DATA_SETS[ds] }.compact.join(',') + + { + countryCode: options[:country_code], + currentAsOf: options[:current_as_of], + dailyEnd: options[:daily_end], + dailyStart: options[:daily_start], + dataSets: data_sets_param, + hourlyEnd: options[:hourly_end], + hourlyStart: options[:hourly_start], + timezone: options[:timezone] + }.compact + end end end diff --git a/spec/tenkit/tenkit/weather_spec.rb b/spec/tenkit/tenkit/weather_spec.rb index 1176cc5..4a290d7 100644 --- a/spec/tenkit/tenkit/weather_spec.rb +++ b/spec/tenkit/tenkit/weather_spec.rb @@ -3,6 +3,10 @@ RSpec.describe Tenkit::Weather do let(:lat) { 37.32 } let(:lon) { 122.03 } + let(:path) { "/weather/en/#{lat}/#{lon}" } + let(:data_sets) { [Tenkit::Utils.snake(data_set).to_sym] } + let(:query) { {query: {dataSets: data_set}} } + let(:client) { Tenkit::Client.new } let(:api_response) { double("WeatherResponse", body: json) } let(:json) { File.read("test/fixtures/#{data_set}.json") } @@ -12,7 +16,12 @@ describe "currentWeather" do let(:data_set) { "currentWeather" } - subject { client.weather(lat, lon).weather.current_weather } + subject { client.weather(lat, lon, data_sets: data_sets).weather.current_weather } + + it "returns response from correct data_sets" do + subject + expect(client).to have_received(:get).with(path, query) + end it "includes expected metadata" do expect(subject.name).to eq "CurrentWeather" @@ -30,16 +39,26 @@ expect(subject.temperature).to be(-5.68) expect(subject.temperature_apparent).to be(-6.88) end + + context "without options" do + subject { client.weather(lat, lon).weather.current_weather } + + it "returns response from default currentWeather data set" do + expect(subject.name).to eq "CurrentWeather" + expect(client).to have_received(:get).with(path, query) + end + end end describe "forecastDaily" do let(:data_set) { "forecastDaily" } let(:first_day) { subject.days.first } - subject { client.weather(lat, lon).weather.forecast_daily } + subject { client.weather(lat, lon, data_sets: data_sets).weather.forecast_daily } - it "returns 10 days of data" do + it "returns 10 days of data from correct data sets" do expect(subject.days.size).to be 10 + expect(client).to have_received(:get).with(path, query) end it "returns correct object types" do @@ -80,10 +99,11 @@ let(:data_set) { "forecastHourly" } let(:first_hour) { subject.hours.first } - subject { client.weather(lat, lon).weather.forecast_hourly } + subject { client.weather(lat, lon, data_sets: data_sets).weather.forecast_hourly } - it "returns 25 hours of data" do + it "returns 25 hours of data from correct data sets" do expect(subject.hours.size).to be 25 + expect(client).to have_received(:get).with(path, query) end it "includes expected metadata" do