ratis 3.1.2 → 3.1.3
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.
- data/CHANGELOG +4 -1
- data/Gemfile.lock +1 -1
- data/lib/ratis.rb +1 -0
- data/lib/ratis/next_bus.rb +44 -15
- data/lib/ratis/version.rb +1 -1
- data/spec/ratis/next_bus_spec.rb +186 -62
- data/spec/support/vcr_cassettes/Point2Point.yml +26 -26
- metadata +3 -3
data/CHANGELOG
CHANGED
@@ -7,4 +7,7 @@
|
|
7
7
|
|
8
8
|
3.1.2
|
9
9
|
- NextBus#stop added
|
10
|
-
- Contains info about the stop (:side, :stopid, :heading, :lat, :area, :servicetype, :route, :operator)
|
10
|
+
- Contains info about the stop (:side, :stopid, :heading, :lat, :area, :servicetype, :route, :operator)
|
11
|
+
|
12
|
+
3.1.3
|
13
|
+
- Turns out that in the NextBus calls the <service> tag can come back as either a single node or list of nodes. In one case savon turns this into an array, in the other case it's just a single entity. Rewrote NextBus.where to handle these two cases, this also means NextBus would never really represent a single service. Created a NextBus.services method that returns all these entities in a similar manner. Update test specs
|
data/Gemfile.lock
CHANGED
data/lib/ratis.rb
CHANGED
data/lib/ratis/next_bus.rb
CHANGED
@@ -2,17 +2,47 @@ module Ratis
|
|
2
2
|
|
3
3
|
class NextBus
|
4
4
|
|
5
|
-
attr_accessor :
|
5
|
+
attr_accessor :stop, :services, :success
|
6
6
|
|
7
|
-
def initialize(
|
8
|
-
@
|
9
|
-
@stop
|
7
|
+
def initialize(response)
|
8
|
+
@success = response.success?
|
9
|
+
@stop = response.body[:nextbus_response][:atstop]
|
10
|
+
_services = @stop.delete(:service)
|
11
|
+
|
12
|
+
unless _services.is_a?(Array)
|
13
|
+
_services = [_services]
|
14
|
+
end
|
15
|
+
|
16
|
+
@services = _services.map do |service|
|
17
|
+
OpenStruct.new(:status => service[:status],
|
18
|
+
:sign => service[:sign],
|
19
|
+
:routetype => service[:routetype],
|
20
|
+
:times => service[:times],
|
21
|
+
:direction => service[:direction],
|
22
|
+
:servicetype => service[:servicetype],
|
23
|
+
:route => service[:route],
|
24
|
+
:operator => service[:operator],
|
25
|
+
:trips => service[:tripinfo].map do |ti|
|
26
|
+
OpenStruct.new(:triptime => ti[:triptime],
|
27
|
+
:block => ti[:block],
|
28
|
+
:tripid => ti[:tripid],
|
29
|
+
:exception => ti[:exception],
|
30
|
+
:skedtripid => ti[:skedtripid],
|
31
|
+
:realtime => OpenStruct.new(:valid => ti[:realtime][:valid],
|
32
|
+
:adherence => ti[:realtime][:adherence],
|
33
|
+
:estimatedtime => ti[:realtime][:estimatedtime],
|
34
|
+
:estimatedminutes => ti[:realtime][:estimatedminutes],
|
35
|
+
:polltime => ti[:realtime][:polltime],
|
36
|
+
:trend => ti[:realtime][:trend],
|
37
|
+
:speed => ti[:realtime][:speed],
|
38
|
+
:reliable => ti[:realtime][:reliable],
|
39
|
+
:stopped => ti[:realtime][:stopped],
|
40
|
+
:lat => ti[:realtime][:lat],
|
41
|
+
:long => ti[:realtime][:long] ))
|
42
|
+
end
|
43
|
+
)
|
44
|
+
end
|
10
45
|
|
11
|
-
@status = service[:status]
|
12
|
-
@sign = service[:sign]
|
13
|
-
@routetype = service[:routetype]
|
14
|
-
@times = service[:times]
|
15
|
-
@direction = service[:direction]
|
16
46
|
end
|
17
47
|
|
18
48
|
def self.where(conditions)
|
@@ -28,20 +58,19 @@ module Ratis
|
|
28
58
|
|
29
59
|
raise ArgumentError.new('You must provide a stop ID') unless stop_id
|
30
60
|
|
31
|
-
Ratis.all_conditions_used?
|
61
|
+
Ratis.all_conditions_used?(conditions)
|
32
62
|
|
33
63
|
response = Request.get 'Nextbus', {'Stopid' => stop_id,
|
34
64
|
'Appid' => app_id,
|
35
65
|
'Date' => datetime.strftime("%m/%d/%Y"),
|
36
66
|
'Time' => datetime.strftime("%I%M"),
|
37
67
|
'Type' => type }
|
38
|
-
return [] unless response.success?
|
39
68
|
|
40
|
-
|
41
|
-
|
42
|
-
runs = service.delete(:tripinfo)
|
69
|
+
NextBus.new(response)
|
70
|
+
end
|
43
71
|
|
44
|
-
|
72
|
+
def success?
|
73
|
+
@success
|
45
74
|
end
|
46
75
|
|
47
76
|
# Gets description of first stop
|
data/lib/ratis/version.rb
CHANGED
data/spec/ratis/next_bus_spec.rb
CHANGED
@@ -8,87 +8,211 @@ describe Ratis::NextBus do
|
|
8
8
|
config.namespace = 'PX_WEB'
|
9
9
|
end
|
10
10
|
|
11
|
-
@stop_id = 10050
|
12
11
|
@time = Chronic.parse('tomorrow at 6am')
|
13
12
|
end
|
14
13
|
|
15
|
-
|
16
|
-
before do
|
17
|
-
# appid
|
18
|
-
# a short string that can be used to separate requests from different applications or different modules with
|
19
|
-
# Optional (highly recommended)
|
20
|
-
@conditions = {:stop_id => @stop_id,
|
21
|
-
:app_id => 'ratis-specs',
|
22
|
-
:type => 'N',
|
23
|
-
:datetime => @time }
|
24
|
-
end
|
14
|
+
let(:empty_body){ {:nextbus_response => {:atstop => {:service => []}}} }
|
25
15
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
# SOAP - no runs available
|
30
|
-
response = Ratis::NextBus.where(@conditions.dup)
|
31
|
-
expect(response.runs).to have(4).items
|
16
|
+
describe '#success?' do
|
17
|
+
it "do something" do
|
18
|
+
pending
|
32
19
|
end
|
20
|
+
end
|
33
21
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
22
|
+
describe '#where' do
|
23
|
+
describe 'single service return' do
|
24
|
+
before do
|
25
|
+
@stop_id = 10050
|
26
|
+
@conditions = {:stop_id => @stop_id,
|
27
|
+
:app_id => 'ratis-specs', # a short string that can be used to separate requests from different applications or different modules with
|
28
|
+
:type => 'N',
|
29
|
+
:datetime => @time }
|
30
|
+
end
|
39
31
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
options["Type"].should eq('N')
|
32
|
+
it 'returns the next 4 bus times' do
|
33
|
+
# raises exception when no runs available:
|
34
|
+
# Ratis::Errors::SoapError:
|
35
|
+
# SOAP - no runs available
|
36
|
+
response = Ratis::NextBus.where(@conditions.dup)
|
37
|
+
expect(response.services).to have(1).items
|
38
|
+
end
|
48
39
|
|
49
|
-
|
40
|
+
it 'only makes one request' do
|
41
|
+
# false just to stop further processing of response
|
42
|
+
Ratis::Request.should_receive(:get).once.and_call_original
|
43
|
+
Ratis::NextBus.where(@conditions.dup)
|
44
|
+
end
|
50
45
|
|
51
|
-
|
52
|
-
|
46
|
+
it 'requests the correct SOAP action' do
|
47
|
+
Ratis::Request.should_receive(:get) do |action, options|
|
48
|
+
action.should eq('Nextbus')
|
49
|
+
options["Stopid"].should eq(@stop_id)
|
50
|
+
options["Appid"].should eq('ratis-specs')
|
51
|
+
options["Date"].should eq(@time.strftime("%m/%d/%Y"))
|
52
|
+
options["Time"].should eq(@time.strftime("%I%M"))
|
53
|
+
options["Type"].should eq('N')
|
53
54
|
|
54
|
-
|
55
|
-
response = Ratis::NextBus.where(@conditions.dup)
|
56
|
-
expect(response).to be_a(Ratis::NextBus)
|
57
|
-
expect(response.status).to eq('N')
|
58
|
-
expect(response.sign).to eq('0 CENTRAL North to Dunlap/3rd St.')
|
59
|
-
expect(response.routetype).to eq('B')
|
60
|
-
expect(response.times).to eq("05:49 AM, 06:09 AM, 06:29 AM, 06:49 AM")
|
61
|
-
expect(response.direction).to eq('N')
|
62
|
-
end
|
55
|
+
end.and_return(double('response', :success? => false, :body => empty_body)) # false only to stop further running
|
63
56
|
|
64
|
-
|
65
|
-
|
66
|
-
Ratis::NextBus.where(@conditions.dup.merge(:datetime => '01/01/2013'))
|
67
|
-
}.should raise_error(ArgumentError, 'If datetime supplied it should be a Time or DateTime instance, otherwise it defaults to Time.now')
|
57
|
+
Ratis::NextBus.where(@conditions.dup)
|
58
|
+
end
|
68
59
|
|
69
|
-
|
70
|
-
Ratis::NextBus.where(@conditions.dup
|
71
|
-
|
60
|
+
it "should set all the service values to instance vars" do
|
61
|
+
response = Ratis::NextBus.where(@conditions.dup)
|
62
|
+
service = response.services.first
|
63
|
+
expect(response).to be_a(Ratis::NextBus)
|
64
|
+
expect(response.services).to be_a(Array)
|
72
65
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
66
|
+
expect(service.status).to eq('N')
|
67
|
+
expect(service.sign).to eq('0 CENTRAL North to Dunlap/3rd St.')
|
68
|
+
expect(service.routetype).to eq('B')
|
69
|
+
expect(service.times).to eq("05:49 AM, 06:09 AM, 06:29 AM, 06:49 AM")
|
70
|
+
expect(service.direction).to eq('N')
|
71
|
+
expect(service.servicetype).to eq('W')
|
72
|
+
expect(service.route).to eq('0')
|
73
|
+
expect(service.operator).to eq('AP')
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should raise error if datetime condition is not a DateTime or Time" do
|
77
|
+
lambda {
|
78
|
+
Ratis::NextBus.where(@conditions.dup.merge(:datetime => '01/01/2013'))
|
79
|
+
}.should raise_error(ArgumentError, 'If datetime supplied it should be a Time or DateTime instance, otherwise it defaults to Time.now')
|
77
80
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
81
|
+
lambda {
|
82
|
+
Ratis::NextBus.where(@conditions.dup.merge(:datetime => Time.now))
|
83
|
+
}.should_not raise_error(ArgumentError)
|
84
|
+
|
85
|
+
lambda {
|
86
|
+
Ratis::NextBus.where(@conditions.dup.merge(:datetime => DateTime.today))
|
87
|
+
}.should_not raise_error(ArgumentError)
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should raise error if stop id is not provided" do
|
91
|
+
lambda {
|
92
|
+
Ratis::NextBus.where(@conditions.dup.merge(:stop_id => nil))
|
93
|
+
}.should raise_error(ArgumentError, 'You must provide a stop ID')
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should return an empty array if the api request isn't successful" do
|
97
|
+
Ratis::Request.should_receive(:get) do |action, options|
|
98
|
+
action.should eq('Nextbus')
|
99
|
+
options["Stopid"].should eq(@stop_id)
|
100
|
+
options["Appid"].should eq('ratis-specs')
|
101
|
+
options["Date"].should eq(@time.strftime("%m/%d/%Y"))
|
102
|
+
options["Time"].should eq(@time.strftime("%I%M"))
|
103
|
+
options["Type"].should eq('N')
|
104
|
+
|
105
|
+
end.and_return(double('response', :success? => false, :body => empty_body)) # false only to stop further running
|
106
|
+
|
107
|
+
expect(Ratis::NextBus.where(@conditions.dup).services).to be_empty
|
108
|
+
end
|
82
109
|
end
|
83
110
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
111
|
+
describe 'multiple services returned' do
|
112
|
+
before do
|
113
|
+
@stop_id = 15894
|
114
|
+
@conditions = {:stop_id => @stop_id,
|
115
|
+
:app_id => 'ratis-specs', # a short string that can be used to separate requests from different applications or different modules with
|
116
|
+
:type => 'N',
|
117
|
+
:datetime => @time }
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'returns the next 4 bus times' do
|
121
|
+
# raises exception when no runs available:
|
122
|
+
# Ratis::Errors::SoapError:
|
123
|
+
# SOAP - no runs available
|
124
|
+
response = Ratis::NextBus.where(@conditions.dup)
|
125
|
+
expect(response.services).to have(2).items
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'only makes one request' do
|
129
|
+
# false just to stop further processing of response
|
130
|
+
Ratis::Request.should_receive(:get).once.and_call_original
|
131
|
+
Ratis::NextBus.where(@conditions.dup)
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'requests the correct SOAP action' do
|
135
|
+
Ratis::Request.should_receive(:get) do |action, options|
|
136
|
+
action.should eq('Nextbus')
|
137
|
+
options["Stopid"].should eq(@stop_id)
|
138
|
+
options["Appid"].should eq('ratis-specs')
|
139
|
+
options["Date"].should eq(@time.strftime("%m/%d/%Y"))
|
140
|
+
options["Time"].should eq(@time.strftime("%I%M"))
|
141
|
+
options["Type"].should eq('N')
|
142
|
+
|
143
|
+
end.and_return(double('response', :success? => false, :body => empty_body)) # false only to stop further running
|
144
|
+
|
145
|
+
Ratis::NextBus.where(@conditions.dup)
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should map all the services to service openstruct objects" do
|
149
|
+
response = Ratis::NextBus.where(@conditions.dup)
|
150
|
+
expect(response).to be_a(Ratis::NextBus)
|
151
|
+
expect(response.services).to be_a(Array)
|
152
|
+
|
153
|
+
service = response.services.first
|
154
|
+
expect(service).to be_a(OpenStruct)
|
155
|
+
|
156
|
+
expect(service.status).to eq('N')
|
157
|
+
expect(service.sign).to eq('108 Elliot West To Priest')
|
158
|
+
expect(service.routetype).to eq('B')
|
159
|
+
expect(service.times).to eq("06:46 AM, 07:46 AM, 08:46 AM, 09:46 AM")
|
160
|
+
expect(service.direction).to eq('W')
|
161
|
+
expect(service.servicetype).to eq('W')
|
162
|
+
expect(service.route).to eq('108')
|
163
|
+
expect(service.operator).to eq('AT')
|
164
|
+
|
165
|
+
service = response.services.last
|
166
|
+
expect(service).to be_a(OpenStruct)
|
167
|
+
|
168
|
+
expect(service.status).to eq('N')
|
169
|
+
expect(service.sign).to eq('108 Elliot West To Priest Via Sosmn/Bsnln')
|
170
|
+
expect(service.routetype).to eq('B')
|
171
|
+
expect(service.times).to eq("10:46 AM, 02:46 PM, 06:46 PM")
|
172
|
+
expect(service.direction).to eq('W')
|
173
|
+
expect(service.servicetype).to eq('W')
|
174
|
+
expect(service.route).to eq('108')
|
175
|
+
expect(service.operator).to eq('AT')
|
176
|
+
end
|
177
|
+
|
178
|
+
it "should raise error if datetime condition is not a DateTime or Time" do
|
179
|
+
lambda {
|
180
|
+
Ratis::NextBus.where(@conditions.dup.merge(:datetime => '01/01/2013'))
|
181
|
+
}.should raise_error(ArgumentError, 'If datetime supplied it should be a Time or DateTime instance, otherwise it defaults to Time.now')
|
182
|
+
|
183
|
+
lambda {
|
184
|
+
Ratis::NextBus.where(@conditions.dup.merge(:datetime => Time.now))
|
185
|
+
}.should_not raise_error(ArgumentError)
|
186
|
+
|
187
|
+
lambda {
|
188
|
+
Ratis::NextBus.where(@conditions.dup.merge(:datetime => DateTime.today))
|
189
|
+
}.should_not raise_error(ArgumentError)
|
190
|
+
end
|
191
|
+
|
192
|
+
it "should raise error if stop id is not provided" do
|
193
|
+
lambda {
|
194
|
+
Ratis::NextBus.where(@conditions.dup.merge(:stop_id => nil))
|
195
|
+
}.should raise_error(ArgumentError, 'You must provide a stop ID')
|
196
|
+
end
|
197
|
+
|
198
|
+
it "should return an empty array if the api request isn't successful" do
|
199
|
+
Ratis::Request.should_receive('get') do |action, options|
|
200
|
+
action.should eq('Nextbus')
|
201
|
+
options["Time"].should eq(@time.strftime("%I%M") )
|
202
|
+
options["Type"].should eq("N")
|
203
|
+
options["Stopid"].should eq(@stop_id)
|
204
|
+
options["Date"].should eq(@time.strftime("%m/%d/%Y") )
|
205
|
+
options["Appid"].should eq("ratis-specs")
|
206
|
+
|
207
|
+
end.and_return(double('response', :success? => false, :body => empty_body))
|
208
|
+
|
209
|
+
expect(Ratis::NextBus.where(@conditions.dup).services).to be_empty
|
210
|
+
end
|
89
211
|
end
|
90
212
|
end
|
91
213
|
|
214
|
+
|
215
|
+
|
92
216
|
end
|
93
217
|
|
94
218
|
# EXAMPLE RESPONSE
|
@@ -20,12 +20,12 @@ http_interactions:
|
|
20
20
|
aW50MnBvaW50PjwvZW52OkJvZHk+PC9lbnY6RW52ZWxvcGU+
|
21
21
|
|
22
22
|
headers:
|
23
|
-
Accept:
|
24
|
-
- "*/*"
|
25
23
|
Soapaction:
|
26
24
|
- "\"PX_WEB#Point2point\""
|
27
25
|
Content-Type:
|
28
26
|
- text/xml;charset=UTF-8
|
27
|
+
Accept:
|
28
|
+
- "*/*"
|
29
29
|
Content-Length:
|
30
30
|
- "576"
|
31
31
|
response:
|
@@ -33,14 +33,14 @@ http_interactions:
|
|
33
33
|
code: 302
|
34
34
|
message: Found
|
35
35
|
headers:
|
36
|
+
Server:
|
37
|
+
- BigIP
|
38
|
+
Content-Length:
|
39
|
+
- "0"
|
36
40
|
Connection:
|
37
41
|
- Keep-Alive
|
38
42
|
Location:
|
39
43
|
- http://www.iana.org/domains/example/
|
40
|
-
Content-Length:
|
41
|
-
- "0"
|
42
|
-
Server:
|
43
|
-
- BigIP
|
44
44
|
body:
|
45
45
|
base64_string: ""
|
46
46
|
http_version:
|
@@ -51,26 +51,26 @@ http_interactions:
|
|
51
51
|
body:
|
52
52
|
base64_string: |
|
53
53
|
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48ZW52OkVu
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
54
|
+
dmVsb3BlIHhtbG5zOmVudj0iaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcv
|
55
|
+
c29hcC9lbnZlbG9wZS8iIHhtbG5zOndzZGw9IlBYX1dFQiIgeG1sbnM6eHNk
|
56
|
+
PSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSIgeG1sbnM6eHNp
|
57
|
+
PSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSI+
|
58
|
+
PGVudjpCb2R5PjxQb2ludDJwb2ludCB4bWxucz0iUFhfV0VCIj48RW5kdGlt
|
59
|
+
ZT4xODAwPC9FbmR0aW1lPjxEZXN0aW5hdGlvbmxhdD4zMy40NDcwOTg8L0Rl
|
60
|
+
c3RpbmF0aW9ubGF0PjxEZXN0aW5hdGlvbmxvbmc+LTExMi4wNzcyMTM8L0Rl
|
61
|
+
c3RpbmF0aW9ubG9uZz48RGF0ZT4wNi8wNi8yMDEzPC9EYXRlPjxPcmlnaW5s
|
62
|
+
b25nPi0xMTIuMDk3OTAzPC9PcmlnaW5sb25nPjxTdGFydHRpbWU+MTcwMDwv
|
63
|
+
U3RhcnR0aW1lPjxSb3V0ZXNvbmx5Plk8L1JvdXRlc29ubHk+PFJvdXRlcz4x
|
64
64
|
PC9Sb3V0ZXM+PE9yaWdpbmxhdD4zMy40NDY5MzE8L09yaWdpbmxhdD48L1Bv
|
65
65
|
aW50MnBvaW50PjwvZW52OkJvZHk+PC9lbnY6RW52ZWxvcGU+
|
66
66
|
|
67
67
|
headers:
|
68
68
|
Soapaction:
|
69
69
|
- "\"PX_WEB#Point2point\""
|
70
|
-
Accept:
|
71
|
-
- "*/*"
|
72
70
|
Content-Type:
|
73
71
|
- text/xml;charset=UTF-8
|
72
|
+
Accept:
|
73
|
+
- "*/*"
|
74
74
|
Content-Length:
|
75
75
|
- "576"
|
76
76
|
response:
|
@@ -78,18 +78,18 @@ http_interactions:
|
|
78
78
|
code: 200
|
79
79
|
message: OK
|
80
80
|
headers:
|
81
|
-
|
82
|
-
-
|
83
|
-
Soapserver:
|
84
|
-
- SOAP::Lite/Perl/0.55
|
81
|
+
Server:
|
82
|
+
- Apache/2.2.3 (CentOS)
|
85
83
|
Date:
|
86
|
-
- Thu, 06 Jun 2013
|
84
|
+
- Thu, 06 Jun 2013 23:02:44 GMT
|
87
85
|
Content-Type:
|
88
86
|
- text/xml; charset=utf-8
|
87
|
+
Soapserver:
|
88
|
+
- SOAP::Lite/Perl/0.55
|
89
89
|
Content-Length:
|
90
90
|
- "4558"
|
91
|
-
|
92
|
-
-
|
91
|
+
Connection:
|
92
|
+
- close
|
93
93
|
body:
|
94
94
|
base64_string: |
|
95
95
|
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48U09BUC1F
|
@@ -196,5 +196,5 @@ http_interactions:
|
|
196
196
|
RU5WOkVudmVsb3BlPg==
|
197
197
|
|
198
198
|
http_version:
|
199
|
-
recorded_at: Thu, 06 Jun 2013
|
199
|
+
recorded_at: Thu, 06 Jun 2013 23:02:44 GMT
|
200
200
|
recorded_with: VCR 2.4.0
|
metadata
CHANGED