noaa_weather_client 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.rspec +1 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +7 -0
- data/.yardopts +2 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +22 -0
- data/README.md +107 -0
- data/Rakefile +8 -0
- data/bin/noaa_weather_client +43 -0
- data/data/xml/current_observation.xsd +79 -0
- data/data/xml/dwml.xsd +97 -0
- data/data/xml/location.xsd +142 -0
- data/data/xml/meta_data.xsd +100 -0
- data/data/xml/moreWeatherInformation.xsd +23 -0
- data/data/xml/ndfd_data.xsd +43 -0
- data/data/xml/parameters.xsd +1173 -0
- data/data/xml/summarizationType.xsd +29 -0
- data/data/xml/time_layout.xsd +51 -0
- data/lib/noaa_weather_client.rb +9 -0
- data/lib/noaa_weather_client/cli.rb +53 -0
- data/lib/noaa_weather_client/cli/templates.rb +53 -0
- data/lib/noaa_weather_client/client.rb +61 -0
- data/lib/noaa_weather_client/errors.rb +7 -0
- data/lib/noaa_weather_client/responses/current_observation.rb +93 -0
- data/lib/noaa_weather_client/responses/forecast.rb +84 -0
- data/lib/noaa_weather_client/responses/generic_response.rb +9 -0
- data/lib/noaa_weather_client/responses/lat_lon_list.rb +25 -0
- data/lib/noaa_weather_client/responses/reactive_xml_response.rb +29 -0
- data/lib/noaa_weather_client/responses/station.rb +28 -0
- data/lib/noaa_weather_client/responses/stations.rb +41 -0
- data/lib/noaa_weather_client/responses/validatable_xml_response.rb +22 -0
- data/lib/noaa_weather_client/rest_client_factory.rb +12 -0
- data/lib/noaa_weather_client/services/calculate_distance_between_lat_lon.rb +20 -0
- data/lib/noaa_weather_client/services/current_observations.rb +32 -0
- data/lib/noaa_weather_client/services/find_nearest_station.rb +16 -0
- data/lib/noaa_weather_client/services/forecast_by_day.rb +52 -0
- data/lib/noaa_weather_client/services/postal_code_to_coordinate.rb +36 -0
- data/lib/noaa_weather_client/services/rest_service.rb +28 -0
- data/lib/noaa_weather_client/services/soap_service.rb +16 -0
- data/lib/noaa_weather_client/services/weather_stations.rb +32 -0
- data/lib/noaa_weather_client/soap_client_factory.rb +17 -0
- data/lib/noaa_weather_client/station_filters.rb +8 -0
- data/lib/noaa_weather_client/version.rb +3 -0
- data/lib/noaa_weather_client/xml_parser_factory.rb +9 -0
- data/noaa_weather_client.gemspec +27 -0
- data/spec/fixtures/vcr_cassettes/current_observations.yml +25890 -0
- data/spec/fixtures/vcr_cassettes/forecast_by_day_3.yml +772 -0
- data/spec/fixtures/vcr_cassettes/forecast_by_day_7.yml +829 -0
- data/spec/fixtures/vcr_cassettes/nearest_weather_station.yml +25842 -0
- data/spec/fixtures/vcr_cassettes/postal_code_to_coordinate.yml +75 -0
- data/spec/fixtures/vcr_cassettes/weather_stations.yml +25842 -0
- data/spec/fixtures/xml/forecast.xml +144 -0
- data/spec/lib/noaa_client/client_spec.rb +93 -0
- data/spec/lib/noaa_client/responses/current_observation_spec.rb +122 -0
- data/spec/lib/noaa_client/responses/forecast_spec.rb +66 -0
- data/spec/lib/noaa_client/responses/lat_lon_list_spec.rb +30 -0
- data/spec/lib/noaa_client/responses/station_spec.rb +53 -0
- data/spec/lib/noaa_client/responses/stations_spec.rb +86 -0
- data/spec/lib/noaa_client/rest_client_factory_spec.rb +15 -0
- data/spec/lib/noaa_client/services/calculate_distance_between_lat_lon_spec.rb +16 -0
- data/spec/lib/noaa_client/services/current_observations_spec.rb +47 -0
- data/spec/lib/noaa_client/services/find_nearest_station_spec.rb +36 -0
- data/spec/lib/noaa_client/services/forecast_by_day_spec.rb +62 -0
- data/spec/lib/noaa_client/services/postal_code_to_coordinate_spec.rb +41 -0
- data/spec/lib/noaa_client/services/rest_service_spec.rb +45 -0
- data/spec/lib/noaa_client/services/soap_service_spec.rb +56 -0
- data/spec/lib/noaa_client/services/weather_stations_spec.rb +40 -0
- data/spec/lib/noaa_client/soap_client_factory_spec.rb +13 -0
- data/spec/lib/noaa_client/xml_parser_factory_spec.rb +14 -0
- data/spec/spec_helper.rb +31 -0
- metadata +228 -0
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require_relative '../../../spec_helper'
|
3
|
+
require_relative '../../../../lib/noaa_weather_client/responses/station'
|
4
|
+
|
5
|
+
module NoaaWeatherClient
|
6
|
+
module Responses
|
7
|
+
describe Station do
|
8
|
+
let(:source) {
|
9
|
+
<<-xml
|
10
|
+
<station>
|
11
|
+
<station_id>TAPA</station_id>
|
12
|
+
<state>AG</state>
|
13
|
+
<station_name>Vc Bird Intl Airport Antigua</station_name>
|
14
|
+
<latitude>17.117</latitude>
|
15
|
+
<longitude>-61.783</longitude>
|
16
|
+
<html_url>http://weather.noaa.gov/weather/current/TAPA.html</html_url>
|
17
|
+
<rss_url>http://weather.gov/xml/current_obs/TAPA.rss</rss_url>
|
18
|
+
<xml_url>http://weather.gov/xml/current_obs/TAPA.xml</xml_url>
|
19
|
+
</station>
|
20
|
+
xml
|
21
|
+
}
|
22
|
+
let(:station) { Station.new Nokogiri::XML.parse(source) }
|
23
|
+
|
24
|
+
it "accepts an attributes hash" do
|
25
|
+
station
|
26
|
+
end
|
27
|
+
|
28
|
+
it "exposes station id" do
|
29
|
+
expect(station.station_id).to eq('TAPA')
|
30
|
+
end
|
31
|
+
|
32
|
+
it "exposes station name" do
|
33
|
+
expect(station.station_name).to eq('Vc Bird Intl Airport Antigua')
|
34
|
+
end
|
35
|
+
|
36
|
+
it "exposes state" do
|
37
|
+
expect(station.state).to eq('AG')
|
38
|
+
end
|
39
|
+
|
40
|
+
it "exposes latitude" do
|
41
|
+
expect(station.latitude).to eq(17.117)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "exposes longitude" do
|
45
|
+
expect(station.longitude).to eq(-61.783)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "exposes xml url" do
|
49
|
+
expect(station.xml_url).to eq('http://w1.weather.gov/xml/current_obs/TAPA.xml')
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require_relative '../../../spec_helper'
|
3
|
+
require_relative '../../../../lib/noaa_weather_client/responses/stations'
|
4
|
+
|
5
|
+
module NoaaWeatherClient
|
6
|
+
module Responses
|
7
|
+
describe Stations do
|
8
|
+
let(:fake_response) { STATIONS_XML }
|
9
|
+
let(:stations) { Stations.new fake_response }
|
10
|
+
|
11
|
+
it "requires a response" do
|
12
|
+
stations
|
13
|
+
expect { Stations.new }.to raise_error(ArgumentError)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "exposes a list of stations via enumerable" do
|
17
|
+
count = 0
|
18
|
+
expect { stations.each { |d| count += 1 } }.to change { count }.by(2)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "passes station xml to the station class" do
|
22
|
+
mock_station_class = double(new: nil)
|
23
|
+
first, last = Nokogiri::XML.parse(fake_response).css('station')
|
24
|
+
expect(mock_station_class).to receive(:new).with { |station|
|
25
|
+
station.to_xml == first.to_xml
|
26
|
+
}
|
27
|
+
expect(mock_station_class).to receive(:new).with { |station|
|
28
|
+
station.to_xml == last.to_xml
|
29
|
+
}
|
30
|
+
Stations.new(fake_response, station_class: mock_station_class).each { |s| }
|
31
|
+
end
|
32
|
+
|
33
|
+
it "allows fetching of stations via array#fetch" do
|
34
|
+
expect(stations.fetch(0).station_id).to eq('TAPA')
|
35
|
+
end
|
36
|
+
|
37
|
+
it "allows fetching of stations via array#[]" do
|
38
|
+
expect(stations[0].station_id).to eq('TAPA')
|
39
|
+
end
|
40
|
+
|
41
|
+
it "exposes number of stations via size" do
|
42
|
+
expect(stations.size).to eq(2)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "exposes source xml" do
|
46
|
+
expect(stations.to_xml).to eq(Nokogiri::XML.parse(fake_response).to_xml)
|
47
|
+
end
|
48
|
+
|
49
|
+
STATIONS_XML =<<-RESPONSE
|
50
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
51
|
+
<wx_station_index>
|
52
|
+
<credit>NOAA's National Weather Service</credit>
|
53
|
+
<credit_URL>http://weather.gov/</credit_URL>
|
54
|
+
<image>
|
55
|
+
<url>http://weather.gov/images/xml_logo.gif</url>
|
56
|
+
<title>NOAA's National Weather Service</title>
|
57
|
+
<link>http://weather.gov</link>
|
58
|
+
</image>
|
59
|
+
<suggested_pickup>08:00 EST</suggested_pickup>
|
60
|
+
<suggested_pickup_period>1140</suggested_pickup_period>
|
61
|
+
<station>
|
62
|
+
<station_id>TAPA</station_id>
|
63
|
+
<state>AG</state>
|
64
|
+
<station_name>Vc Bird Intl Airport Antigua</station_name>
|
65
|
+
<latitude>17.117</latitude>
|
66
|
+
<longitude>-61.783</longitude>
|
67
|
+
<html_url>http://weather.noaa.gov/weather/current/TAPA.html</html_url>
|
68
|
+
<rss_url>http://weather.gov/xml/current_obs/TAPA.rss</rss_url>
|
69
|
+
<xml_url>http://weather.gov/xml/current_obs/TAPA.xml</xml_url>
|
70
|
+
</station>
|
71
|
+
|
72
|
+
<station>
|
73
|
+
<station_id>TKPN</station_id>
|
74
|
+
<state>AG</state>
|
75
|
+
<station_name>Charlestown/Newcast</station_name>
|
76
|
+
<latitude>17.2</latitude>
|
77
|
+
<longitude>-62.583</longitude>
|
78
|
+
<html_url>http://weather.noaa.gov/weather/current/TKPN.html</html_url>
|
79
|
+
<rss_url>http://weather.gov/xml/current_obs/TKPN.rss</rss_url>
|
80
|
+
<xml_url>http://weather.gov/xml/current_obs/TKPN.xml</xml_url>
|
81
|
+
</station>
|
82
|
+
</wx_station_index>
|
83
|
+
RESPONSE
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require_relative '../../spec_helper'
|
3
|
+
require_relative '../../../lib/noaa_weather_client/rest_client_factory'
|
4
|
+
|
5
|
+
module NoaaWeatherClient
|
6
|
+
describe RestClientFactory do
|
7
|
+
it "builds a rest client with the provided url" do
|
8
|
+
mock_provider = double()
|
9
|
+
url = "http://www.google.com"
|
10
|
+
uri = URI(url)
|
11
|
+
expect(mock_provider).to receive(:new).with(uri.host, uri.port)
|
12
|
+
RestClientFactory.build_client provider: mock_provider, url: url
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require_relative '../../../spec_helper'
|
2
|
+
require_relative '../../../../lib/noaa_weather_client/services/calculate_distance_between_lat_lon'
|
3
|
+
|
4
|
+
module NoaaWeatherClient
|
5
|
+
module Services
|
6
|
+
describe CalculateDistanceBetweenLatLon do
|
7
|
+
let(:springfield) { [ 37.1962, -93.2861 ] }
|
8
|
+
let(:kansas_city) { [ 39.1000, -94.5800 ] }
|
9
|
+
|
10
|
+
it "calculates the distance between two points" do
|
11
|
+
expect(CalculateDistanceBetweenLatLon.get_distance(*springfield, *kansas_city))
|
12
|
+
.to eq(240.02560432981815)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require_relative '../../../spec_helper'
|
2
|
+
require_relative '../../../../lib/noaa_weather_client/services/current_observations'
|
3
|
+
|
4
|
+
module NoaaWeatherClient
|
5
|
+
module Services
|
6
|
+
describe CurrentObservations do
|
7
|
+
let(:mock_station) { double(xml_url: 'http://w1.weather.gov/xml/current_obs/KSGF.xml') }
|
8
|
+
let(:current_observations) { CurrentObservations.new options }
|
9
|
+
|
10
|
+
it "accepts an options hash" do
|
11
|
+
CurrentObservations.new {}
|
12
|
+
end
|
13
|
+
|
14
|
+
context "#fetch" do
|
15
|
+
let(:options) { { rest_service: double(object_from_response: nil) } }
|
16
|
+
|
17
|
+
it "requires a station" do
|
18
|
+
current_observations.fetch mock_station, options
|
19
|
+
expect { current_observations.fetch }.to raise_error(ArgumentError)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "accepts an options hash" do
|
23
|
+
current_observations.fetch mock_station, options
|
24
|
+
end
|
25
|
+
|
26
|
+
it "passes the stations xml url to the service" do
|
27
|
+
expect(options[:rest_service]).to receive(:object_from_response)
|
28
|
+
.with(anything, mock_station.xml_url, anything)
|
29
|
+
current_observations.fetch mock_station
|
30
|
+
end
|
31
|
+
|
32
|
+
it "passes the get action to the service" do
|
33
|
+
expect(options[:rest_service]).to receive(:object_from_response)
|
34
|
+
.with(:get, anything, anything)
|
35
|
+
current_observations.fetch mock_station
|
36
|
+
end
|
37
|
+
|
38
|
+
it "passes an optional response class to the service" do
|
39
|
+
options[:response_class] = :some_response_class
|
40
|
+
expect(options[:rest_service]).to receive(:object_from_response)
|
41
|
+
.with(anything, anything, hash_including(response_class: options[:response_class]))
|
42
|
+
current_observations.fetch mock_station
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require_relative '../../../spec_helper'
|
2
|
+
require_relative '../../../../lib/noaa_weather_client/services/find_nearest_station'
|
3
|
+
|
4
|
+
module NoaaWeatherClient
|
5
|
+
module Services
|
6
|
+
describe FindNearestStation do
|
7
|
+
let(:location) { double(latitude:39.1000, longitude: -94.5800) } #kansas city
|
8
|
+
let(:washington_dc) { double(station_name: 'Washington D.C.', latitude: 38.8951 , longitude: -77.0367) }
|
9
|
+
let(:detroit) { double(station_name: 'Detroit', latitude: 42.3314 , longitude: -83.0458) }
|
10
|
+
let(:stations) { [ washington_dc, detroit ] }
|
11
|
+
|
12
|
+
it "requires latitude, longitude, and a list of stations" do
|
13
|
+
FindNearestStation.find(location.latitude, location.longitude, stations)
|
14
|
+
expect { FindNearestStation.find }.to raise_error(ArgumentError)
|
15
|
+
expect { FindNearestStation.find location.latitude}.to raise_error(ArgumentError)
|
16
|
+
expect { FindNearestStation.find location.latitude, location.longitude}.to raise_error(ArgumentError)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "accepts an options hash" do
|
20
|
+
FindNearestStation.find(location.latitude, location.longitude, stations, {})
|
21
|
+
end
|
22
|
+
|
23
|
+
it "accepts a callable filter for the stations" do
|
24
|
+
mock_filter = ->(station) { station == washington_dc ? true : false }
|
25
|
+
FindNearestStation.find(location.latitude, location.longitude, stations, { filter: mock_filter })
|
26
|
+
end
|
27
|
+
|
28
|
+
it "returns the closest of the provided stations" do
|
29
|
+
expect(
|
30
|
+
FindNearestStation.find(location.latitude, location.longitude, stations)
|
31
|
+
.station_name
|
32
|
+
).to eq(detroit.station_name)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require_relative '../../../spec_helper'
|
2
|
+
require_relative '../../../../lib/noaa_weather_client/services/forecast_by_day'
|
3
|
+
|
4
|
+
module NoaaWeatherClient
|
5
|
+
module Services
|
6
|
+
describe ForecastByDay do
|
7
|
+
it "accepts an options hash" do
|
8
|
+
ForecastByDay.new {}
|
9
|
+
end
|
10
|
+
|
11
|
+
context "#fetch" do
|
12
|
+
let(:options) { { soap_service: double(object_from_response: nil) } }
|
13
|
+
let(:forecast) { ForecastByDay.new options }
|
14
|
+
let(:lat) { 37.1962 }
|
15
|
+
let(:lon) { -93.2861 }
|
16
|
+
|
17
|
+
it "requires lat and lon" do
|
18
|
+
forecast.fetch lat, lon
|
19
|
+
expect { forecast.fetch }.to raise_error(ArgumentError)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "accepts an options hash" do
|
23
|
+
forecast.fetch lat, lon, {}
|
24
|
+
end
|
25
|
+
|
26
|
+
it "passes optional arguments to the service" do
|
27
|
+
args = { key: 'value' }
|
28
|
+
expect(options[:soap_service]).to receive(:object_from_response)
|
29
|
+
.with(anything, hash_including(key: 'value'), anything)
|
30
|
+
forecast.fetch lat, lon, args
|
31
|
+
end
|
32
|
+
|
33
|
+
it "passes lat as string to the service" do
|
34
|
+
expect(options[:soap_service]).to receive(:object_from_response)
|
35
|
+
.with(anything, hash_including(latitude: lat.to_s), anything)
|
36
|
+
forecast.fetch lat, lon
|
37
|
+
end
|
38
|
+
|
39
|
+
it "passes lon as string to the service" do
|
40
|
+
expect(options[:soap_service]).to receive(:object_from_response)
|
41
|
+
.with(anything, hash_including(longitude: lon.to_s), anything)
|
42
|
+
forecast.fetch lat, lon
|
43
|
+
end
|
44
|
+
|
45
|
+
it "passes the soap action to the service" do
|
46
|
+
expect(options[:soap_service]).to receive(:object_from_response)
|
47
|
+
.with(:ndf_dgen_by_day, anything, anything)
|
48
|
+
forecast.fetch lat, lon
|
49
|
+
end
|
50
|
+
|
51
|
+
it "passes an optional response class to the service" do
|
52
|
+
options[:response_class] = :some_response_class
|
53
|
+
expect(options[:soap_service]).to receive(:object_from_response)
|
54
|
+
.with(anything, anything, hash_including(response_class: options[:response_class]))
|
55
|
+
|
56
|
+
forecast = ForecastByDay.new options
|
57
|
+
forecast.fetch lat, lon
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require_relative '../../../spec_helper'
|
2
|
+
require_relative '../../../../lib/noaa_weather_client/services/postal_code_to_coordinate'
|
3
|
+
|
4
|
+
module NoaaWeatherClient
|
5
|
+
module Services
|
6
|
+
describe PostalCodeToCoordinate do
|
7
|
+
it "accepts an options hash" do
|
8
|
+
PostalCodeToCoordinate.new {}
|
9
|
+
end
|
10
|
+
|
11
|
+
context "#resolve" do
|
12
|
+
let(:options) { { rest_service: double(object_from_response: nil) } }
|
13
|
+
let(:zip) { 90210 }
|
14
|
+
let(:zip_lat_lon) { PostalCodeToCoordinate.new options }
|
15
|
+
|
16
|
+
it "accepts an options hash" do
|
17
|
+
zip_lat_lon.resolve options
|
18
|
+
end
|
19
|
+
|
20
|
+
it "passes action to the service" do
|
21
|
+
expect(options[:rest_service]).to receive(:object_from_response)
|
22
|
+
.with(:get, anything, anything)
|
23
|
+
zip_lat_lon.resolve zip
|
24
|
+
end
|
25
|
+
|
26
|
+
it "passes zip as string to the service" do
|
27
|
+
expect(options[:rest_service]).to receive(:object_from_response)
|
28
|
+
.with(anything, /#{zip}/, anything)
|
29
|
+
zip_lat_lon.resolve zip
|
30
|
+
end
|
31
|
+
|
32
|
+
it "passes an optional response class to the service" do
|
33
|
+
options[:response_class] = :some_response_class
|
34
|
+
expect(options[:rest_service]).to receive(:object_from_response)
|
35
|
+
.with(anything, anything, hash_including(response_class: options[:response_class]))
|
36
|
+
zip_lat_lon.resolve zip
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require_relative '../../../spec_helper'
|
2
|
+
require_relative '../../../../lib/noaa_weather_client/services/rest_service'
|
3
|
+
|
4
|
+
module NoaaWeatherClient
|
5
|
+
module Services
|
6
|
+
describe RestService do
|
7
|
+
let(:fake_response) { double(body: 'fake_response_body') }
|
8
|
+
let(:mock_client) { double(request: fake_response) }
|
9
|
+
let(:mock_response_class) { double(new: nil) }
|
10
|
+
let(:implementer) { Class.new { include RestService }.new }
|
11
|
+
let(:args) { [ :get, 'http://www.google.com', { client: mock_client } ] }
|
12
|
+
|
13
|
+
context "#object_from_response" do
|
14
|
+
it "requires an action and url" do
|
15
|
+
implementer.object_from_response :get, 'http://www.google.com', client: mock_client
|
16
|
+
expect { implementer.object_from_response }.to raise_error(ArgumentError)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "accepts an options hash" do
|
20
|
+
implementer.object_from_response :get, 'http://www.google.com', client: mock_client
|
21
|
+
end
|
22
|
+
|
23
|
+
it "builds a request from the args" do
|
24
|
+
expect(implementer).to receive(:build_request_for_action).with(*args)
|
25
|
+
implementer.object_from_response(*args)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "passes the rest response to the response class" do
|
29
|
+
expect(mock_client).to receive(:request).and_return(fake_response)
|
30
|
+
expect(mock_response_class).to receive(:new).with(fake_response.body)
|
31
|
+
action, url, opts = *args
|
32
|
+
implementer.object_from_response(action, url, opts.merge(response_class: mock_response_class))
|
33
|
+
end
|
34
|
+
|
35
|
+
it "returns a new wrapped response body" do
|
36
|
+
expect(mock_response_class).to receive(:new).with(fake_response.body).and_return(mock_response_class)
|
37
|
+
action, url, opts = *args
|
38
|
+
expect(
|
39
|
+
implementer.object_from_response(action, url, opts.merge(response_class: mock_response_class))
|
40
|
+
).to eq(mock_response_class)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require_relative '../../../spec_helper'
|
2
|
+
require_relative '../../../../lib/noaa_weather_client/services/soap_service'
|
3
|
+
|
4
|
+
module NoaaWeatherClient
|
5
|
+
module Services
|
6
|
+
describe SoapService do
|
7
|
+
let(:fake_response) { double(body: 'fake_response_body') }
|
8
|
+
let(:mock_client) { double(call: fake_response) }
|
9
|
+
let(:mock_response_class) { double(new: nil) }
|
10
|
+
let(:implementer) { Class.new { include SoapService }.new }
|
11
|
+
|
12
|
+
context "#object_from_response" do
|
13
|
+
it "requires a soap action and message" do
|
14
|
+
implementer.object_from_response :soap_action, :message, client: mock_client
|
15
|
+
expect { implementer.object_from_response }.to raise_error(ArgumentError)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "accepts an options hash" do
|
19
|
+
implementer.object_from_response :soap_action, :message, client: mock_client
|
20
|
+
end
|
21
|
+
|
22
|
+
it "calls the soap client with the soap action" do
|
23
|
+
expect(mock_client).to receive(:call).with(:soap_action, anything)
|
24
|
+
implementer.object_from_response :soap_action, :message, client: mock_client
|
25
|
+
end
|
26
|
+
|
27
|
+
it "calls the soap client with the message" do
|
28
|
+
expect(mock_client).to receive(:call).with(anything, hash_including(message: :message))
|
29
|
+
implementer.object_from_response :soap_action, :message, client: mock_client
|
30
|
+
end
|
31
|
+
|
32
|
+
it "passes the soap response to the response" do
|
33
|
+
expect(mock_client).to receive(:call).and_return(fake_response)
|
34
|
+
expect(mock_response_class).to receive(:new).with(fake_response.body)
|
35
|
+
implementer.object_from_response :soap_action, :message, client: mock_client, response_class: mock_response_class
|
36
|
+
end
|
37
|
+
|
38
|
+
it "returns a new wrapped response body" do
|
39
|
+
expect(mock_response_class).to receive(:new).with(fake_response.body).and_return(mock_response_class)
|
40
|
+
expect(implementer.object_from_response(:soap_action,
|
41
|
+
:message,
|
42
|
+
client: mock_client,
|
43
|
+
response_class: mock_response_class)).to eq(mock_response_class)
|
44
|
+
end
|
45
|
+
|
46
|
+
context "when a Savon:Error occurs" do
|
47
|
+
it "raises a CommunicationError" do
|
48
|
+
allow(mock_client).to receive(:call).and_raise(Savon::Error)
|
49
|
+
expect { implementer.object_from_response :soap_action, :message, client: mock_client }
|
50
|
+
.to raise_error(Errors::CommunicationError)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|