opencellid-client 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,25 @@
1
+ module Opencellid
2
+
3
+ # A helper function that avoids invoking `to_i` on a string when it is null or empty
4
+ # @param string [String] the nullable string containing the data to transformed into an integer
5
+ # @return [Integer] `nil` if the string passed is nil or empty, the result of `to_i` otherwise
6
+ def self.to_i_or_nil(string)
7
+ string and string.length > 0 ? string.to_i : nil
8
+ end
9
+
10
+ # A helper function that avoids invoking `to_f` on a string when it is null or empty
11
+ # @param string [String] the nullable string containing the data to transformed into a float
12
+ # @return [Float] `nil` if the string passed is nil or empty, the result of `to_f` otherwise
13
+ def self.to_f_or_nil(string)
14
+ string and string.length > 0 ? string.to_f : nil
15
+ end
16
+
17
+ # A helper function that avoids invoking `strptime` on a string when it is null or empty
18
+ # @param string [String] the nullable string containing the data to transformed into a DateTime
19
+ # @param format [String] the format string as specified by `strptime`
20
+ # @return [DateTime] `nil` if the string passed is nil or empty, the result of `DateTime.strptime` otherwise
21
+ def self.to_datetime_or_nil(string, format)
22
+ string and string.length > 0 ? DateTime.strptime(string, format) : nil
23
+ end
24
+
25
+ end
@@ -0,0 +1,5 @@
1
+ module Opencellid
2
+
3
+ # This library current version
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "opencellid/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "opencellid-client"
7
+ s.version = Opencellid::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Marco Sandrini"]
10
+ s.email = ["nessche@gmail.com"]
11
+ s.homepage = "https://github.com/nessche/opencellid-client"
12
+ s.summary = "A Ruby client for OpenCellID API"
13
+ s.description = "A Ruby client for OpenCellID API"
14
+
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+
22
+ # specify any dependencies here; for example:
23
+ s.add_development_dependency "rspec"
24
+ s.add_development_dependency "webmock"
25
+ s.add_development_dependency "simplecov"
26
+ # s.add_runtime_dependency "rest-client"
27
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+ require 'opencellid'
3
+
4
+ module Opencellid
5
+
6
+ describe BBox do
7
+
8
+ describe "new" do
9
+
10
+ context "when one or more parameters are nil" do
11
+
12
+ it "should raise an ArgumentError" do
13
+ expect{BBox.new(nil,1.0,1.0,1.0)}.to raise_error ArgumentError
14
+ expect{BBox.new(1.0,nil,1.0,1.0)}.to raise_error ArgumentError
15
+ expect{BBox.new(1.0,1.0,nil,1.0)}.to raise_error ArgumentError
16
+ expect{BBox.new(1.0,1.0,1.0,nil)}.to raise_error ArgumentError
17
+ end
18
+
19
+ end
20
+
21
+ context "when all parameters are not nil" do
22
+
23
+ it "should return the correct object" do
24
+ bbox = BBox.new(1.0,2.0,3.0,4.0)
25
+ bbox.latmin.should == 1.0
26
+ bbox.latmax.should == 3.0
27
+ bbox.lonmin.should == 2.0
28
+ bbox.lonmax.should == 4.0
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+
35
+ describe "to_s" do
36
+
37
+ it "should return a string in the format needed by opencellid" do
38
+ bbox = BBox.new(1.0,2.0,3.0,4.0)
39
+ expected_string = "1.0,2.0,3.0,4.0"
40
+ bbox.to_s.should == expected_string
41
+ end
42
+
43
+ end
44
+
45
+ end
46
+
47
+ end
@@ -0,0 +1,138 @@
1
+ require 'spec_helper'
2
+ require 'opencellid'
3
+ require 'rexml/document'
4
+
5
+ module Opencellid
6
+
7
+ WELL_FORMED_CELL = '<cell lat="60.3276113" mcc="244" lon="24.8689952" nbSamples="5" cellId="118135" mnc="91" lac="" range="6000"/>'
8
+ WELL_FORMED_CELL_WITH_MEASURE = <<XML
9
+
10
+ <cell lat="60.3276113" mcc="244" lon="24.8689952" cellId="118135" nbSamples="5" mnc="91" lac="" range="6000">
11
+ <measure lat="60.3277783333333" lon="24.8693505" takenOn="Fri Jul 22 15:02:17 +0200 2011" takenBy="4207"></measure>
12
+ <measure lat="60.3275705" lon="24.8689813333333" takenOn="Sun Aug 07 23:22:04 +0200 2011" takenBy="4207"></measure>
13
+ <measure lat="60.3273111666667" lon="24.867736" takenOn="Mon Aug 08 11:10:47 +0200 2011" takenBy="4207"></measure>
14
+ <measure lat="60.3278625" lon="24.8698973333333" takenOn="Mon Aug 08 12:31:59 +0200 2011" takenBy="4207"></measure>
15
+ <measure lat="60.327534" lon="24.8690108333333" takenOn="Mon Aug 08 12:32:03 +0200 2011" takenBy="4207"></measure>
16
+ </cell>
17
+
18
+ XML
19
+
20
+ describe "Cell" do
21
+
22
+ describe "from_element" do
23
+
24
+ context "when passed a well formed XML" do
25
+
26
+ it "should parse the cell attributes correctly" do
27
+
28
+ doc = REXML::Document.new WELL_FORMED_CELL
29
+ result = Cell.from_element(doc.root)
30
+ result.should be_a Cell
31
+ result.lat.should == 60.3276113
32
+ result.lon.should == 24.8689952
33
+ result.mcc.should == 244
34
+ result.mnc.should == 91
35
+ result.no_of_samples.should == 5
36
+ result.id.should == 118135
37
+ result.lac.should be_nil
38
+ result.range.should == 6000
39
+
40
+ end
41
+
42
+
43
+ end
44
+
45
+ context "when passed nil" do
46
+
47
+ it "should return nil" do
48
+ Cell.from_element(nil).should be_nil
49
+ end
50
+
51
+ end
52
+
53
+ context "when passed something else than an XML element" do
54
+
55
+ it "should raise an ArgumentError" do
56
+ expect{Cell.from_element "This is just a String"}.to raise_error ArgumentError
57
+ end
58
+
59
+ end
60
+
61
+ context "when passed an XML element not of type cell" do
62
+
63
+ it "should raise an ArgumentError" do
64
+ doc = REXML::Document.new "<a>This is not a cell</a>"
65
+ expect{Cell.from_element doc}.to raise_error ArgumentError
66
+ end
67
+
68
+ end
69
+
70
+ end
71
+
72
+ describe "has_measures?" do
73
+
74
+ context "when measures array is empty" do
75
+
76
+ it "should return false" do
77
+ cell = Cell.new(1,2,3,4)
78
+ cell.has_measures?.should be_false
79
+ end
80
+
81
+ end
82
+
83
+ context "when measures array is not empty" do
84
+
85
+ it "should return true" do
86
+ cell = Cell.new(1,2,3,4)
87
+ cell.add_measure(Measure.new(1.0,1.0))
88
+ cell.has_measures?.should be_true
89
+ end
90
+
91
+ end
92
+
93
+ end
94
+
95
+ describe "to_query_hash" do
96
+
97
+ it "should return a hash" do
98
+ Cell.new(1,2,3,4).to_query_hash.should be_a Hash
99
+ end
100
+
101
+ it "should only have query parameters" do
102
+ cell = Cell.new(1,2,3,4)
103
+ cell.range = 3000
104
+ cell.add_measure Measure.new(1.0,1.0)
105
+ hash = cell.to_query_hash
106
+ hash.count.should == 4
107
+ hash.should include :cellid
108
+ hash.should include :mnc
109
+ hash.should include :mcc
110
+ hash.should include :lac
111
+
112
+ end
113
+
114
+ it "should have parameters correctly mapped" do
115
+ cell = Cell.new(1,2,3,4)
116
+ hash = cell.to_query_hash
117
+ hash[:cellid].should == 1
118
+ hash[:mnc].should == 2
119
+ hash[:mcc].should == 3
120
+ hash[:lac].should == 4
121
+
122
+ end
123
+
124
+ it "should leave out nil parameters" do
125
+ Cell.new(nil,2,3,4).to_query_hash.should_not include :cellid
126
+ Cell.new(1,nil,3,4).to_query_hash.should_not include :mnc
127
+ Cell.new(1,2,nil,4).to_query_hash.should_not include :mcc
128
+ Cell.new(1,2,3,nil).to_query_hash.should_not include :lac
129
+ end
130
+
131
+
132
+ end
133
+
134
+
135
+
136
+ end
137
+
138
+ end
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <rsp stat="fail">
3
+ <err info=" cell not found" code="1"/>
4
+ </rsp>
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <rsp stat="ok">
3
+ <cell lat="60.3276113" mcc="244" lon="24.8689952" cellId="118135" nbSamples="5" mnc="91" lac="" range="6000">
4
+ <measure lat="60.3277783333333" lon="24.8693505" takenOn="Fri Jul 22 15:02:17 +0200 2011" takenBy="4207"></measure>
5
+ <measure lat="60.3275705" lon="24.8689813333333" takenOn="Sun Aug 07 23:22:04 +0200 2011" takenBy="4207"></measure>
6
+ <measure lat="60.3273111666667" lon="24.867736" takenOn="Mon Aug 08 11:10:47 +0200 2011" takenBy="4207"></measure>
7
+ <measure lat="60.3278625" lon="24.8698973333333" takenOn="Mon Aug 08 12:31:59 +0200 2011" takenBy="4207"></measure>
8
+ <measure lat="60.327534" lon="24.8690108333333" takenOn="Mon Aug 08 12:32:03 +0200 2011" takenBy="4207"></measure>
9
+ </cell>
10
+ </rsp>
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <rsp cellid="1252312" stat="ok" id="56216401">
3
+ <res>Measure added, id:56216401</res>
4
+ </rsp>
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <measures total="2">
3
+ <measure lat="60.5" measured_at="Fri Feb 03 15:33:43 +0100 2012" mcc="1" lon="30.3" signal="" cellId="123456" mnc="1" id="56198375" lac="9000"/>
4
+ <measure lat="60.6" measured_at="Fri Feb 03 15:43:06 +0100 2012" mcc="1" lon="30.5" signal="" cellId="123457" mnc="1" id="56198417" lac="9000"/>
5
+ </measures>
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <rsp stat="ok">
3
+ <cell lat="60.3276113" mcc="244" lon="24.8689952" nbSamples="5" cellId="118135" mnc="91" lac="" range="6000"/>
4
+ </rsp>
@@ -0,0 +1,58 @@
1
+ require 'spec_helper'
2
+ require 'opencellid'
3
+
4
+ module Opencellid
5
+
6
+ WELL_FORMED_ERROR = '<err info="cell not found" code="1"/>'
7
+
8
+ describe Error do
9
+
10
+ describe "from_element" do
11
+
12
+ context "when passed a well formed error" do
13
+
14
+ it "should parse the XML correctly" do
15
+ doc = REXML::Document.new WELL_FORMED_ERROR
16
+ error = Error.from_element doc.root
17
+ error.should be_a Error
18
+ error.code.should == 1
19
+ error.info.should == "cell not found"
20
+ end
21
+
22
+ end
23
+
24
+ context "when passed nil" do
25
+
26
+ it "should return nil" do
27
+ Error.from_element(nil).should be_nil
28
+ end
29
+
30
+ end
31
+
32
+ context "when passing something else than an XML element" do
33
+
34
+ it "should raise an ArgumentError" do
35
+ expect{Error.from_element "This is just a String"}. to raise_error ArgumentError
36
+ end
37
+
38
+
39
+ end
40
+
41
+ context "when passed something else then a measure" do
42
+
43
+ it "should raise an Argument Error" do
44
+ doc = REXML::Document.new "<a>this is not an error</a>"
45
+ expect{Error.from_element doc}.to raise_error ArgumentError
46
+ end
47
+
48
+
49
+ end
50
+
51
+ end
52
+
53
+
54
+
55
+ end
56
+
57
+
58
+ end
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+ require 'opencellid'
3
+ require 'rexml/document'
4
+
5
+ module Opencellid
6
+
7
+ WELL_CELL_SUB = '<measure lat="60.3277783333333" lon="24.8693505" takenOn="Fri Jul 22 15:02:17 +0200 2011" takenBy="4207"></measure>'
8
+ MEASURE_LIST_SUB = '<measure measured_at="Fri Jul 22 10:10:10 +0200 2011" lat="1.0" mcc="1" lon="2.0" signal="10" cellId="2" mnc="1" id="56216430" lac="4"/>'
9
+ describe "Measure" do
10
+
11
+ describe "from_element" do
12
+
13
+ context "when passed a well formed measure" do
14
+
15
+ it "should parse the cell sub-element correctly" do
16
+ doc = REXML::Document.new WELL_CELL_SUB
17
+ measure = Measure.from_element doc.root
18
+ measure.should be_a Measure
19
+ measure.lat.should == 60.3277783333333
20
+ measure.lon.should == 24.8693505
21
+ measure.taken_by.should == "4207"
22
+ measure.signal.should be_nil
23
+ measure.id.should be_nil
24
+ expected_data = DateTime.new(2011,7,22,15,2,17,Rational(2,24))
25
+ measure.taken_on.should == expected_data
26
+ end
27
+
28
+ it "should parse the measure list sub-element correctly" do
29
+ doc = REXML::Document.new MEASURE_LIST_SUB
30
+ measure = Measure.from_element doc.root
31
+ measure.should be_a Measure
32
+ measure.lat.should == 1.0
33
+ measure.lon.should == 2.0
34
+ measure.id.should == 56216430
35
+ measure.taken_by.should be_nil
36
+ expected_data = DateTime.new(2011,7,22,10,10,10,Rational(2,24))
37
+ measure.taken_on.should == expected_data
38
+ end
39
+
40
+ end
41
+
42
+ context "when passed nil" do
43
+
44
+ it "should return nil" do
45
+ Measure.from_element(nil).should be_nil
46
+ end
47
+
48
+ end
49
+
50
+ context "when passing something else than an XML element" do
51
+
52
+ it "should raise an ArgumentError" do
53
+ expect{Measure.from_element "This is just a String"}. to raise_error ArgumentError
54
+ end
55
+
56
+
57
+ end
58
+
59
+ context "when passed something else then a measure" do
60
+
61
+ it "should raise an Argument Error" do
62
+ doc = REXML::Document.new "<a>this is not a measure</a>"
63
+ expect{Measure.from_element doc}.to raise_error ArgumentError
64
+ end
65
+
66
+
67
+ end
68
+
69
+ end
70
+
71
+ end
72
+
73
+ end
@@ -0,0 +1,242 @@
1
+ require 'spec_helper'
2
+ require 'opencellid'
3
+
4
+ module Opencellid
5
+
6
+ describe Opencellid do
7
+
8
+ before do
9
+ WebMock.disable_net_connect!
10
+ stub_request(:get, /www\.opencellid\.org/).to_return(status: 200, body: data_file_as_string('one_cell.xml'))
11
+ @oci = Opencellid.new
12
+ @response = double(:response)
13
+ Response.stub(:from_xml).and_return(@response)
14
+ end
15
+
16
+ describe "execute_request_and_parse_response" do
17
+
18
+ before do
19
+ @method = @oci.method(:execute_request_and_parse_response)
20
+
21
+ end
22
+
23
+ context "when the api key is specified" do
24
+
25
+ before do
26
+ @oci = Opencellid.new "myapikey"
27
+ @method = @oci.method(:execute_request_and_parse_response)
28
+ end
29
+
30
+ it "should add it to the parameters" do
31
+ @method.call("/")
32
+ WebMock.should have_requested(:get, "www.opencellid.org/")
33
+ .with(query: { "key" => "myapikey"})
34
+ end
35
+
36
+ end
37
+
38
+ context "when the api key is not specified" do
39
+
40
+ it "should not add it to the parameters" do
41
+ @method.call("/")
42
+ WebMock.should have_requested(:get, "www.opencellid.org/")
43
+ end
44
+
45
+ end
46
+
47
+ it "should add the params as query params" do
48
+
49
+ @method.call("/",{"a" => "10", "b" => "20", "c" => "30"})
50
+ WebMock.should have_requested(:get, "www.opencellid.org/")
51
+ .with(query: {"a" => "10", "b" => "20", "c" => "30"})
52
+ end
53
+
54
+ it "should set the path correctly" do
55
+ @method.call("/mypath")
56
+ WebMock.should have_requested(:get, "www.opencellid.org/mypath")
57
+ end
58
+
59
+ context "when HTTP Response status is 200" do
60
+
61
+ it "should invoke from_xml on Response" do
62
+ expected_xml = data_file_as_string('one_cell.xml')
63
+ Response.should_receive(:from_xml).with(expected_xml)
64
+ @method.call("/")
65
+ end
66
+
67
+ it "should return the Response object" do
68
+ @method.call("/").should == @response
69
+ end
70
+
71
+ end
72
+
73
+ context "when HTTP Response is not 200" do
74
+
75
+ before do
76
+ stub_request(:get, /www\.opencellid\.org/).to_return(status: 500, body: "Internal Server Error")
77
+ end
78
+
79
+ it "should return a response of type failure" do
80
+ response = @method.call("/")
81
+ response.should_not be_ok
82
+ response.error.code.should == 0
83
+ response.error.info.should == "Http Request failed with code 500"
84
+ end
85
+
86
+ end
87
+
88
+ end
89
+
90
+ describe "get_cell" do
91
+
92
+ context "when parameter is not a Cell" do
93
+
94
+ it "should raise an ArgumentError" do
95
+ expect{@oci.get_cell nil}.to raise_error ArgumentError
96
+ expect{@oci.get_cell "This is a not a Cell"}.to raise_error ArgumentError
97
+ end
98
+
99
+ end
100
+
101
+ it "should set the correct path and parameters" do
102
+ @oci.get_cell(Cell.new(1,2,3,4))
103
+ WebMock.should have_requested(:get, "www.opencellid.org/cell/get")
104
+ .with(query: {"cellid" => "1", "mnc" => "2", "mcc" => "3", "lac" => "4"})
105
+ end
106
+
107
+ it "should return a response" do
108
+ @oci.get_cell(Cell.new(1,2,3,4)).should == @response
109
+ end
110
+
111
+ end
112
+
113
+ describe "get_cell_measures" do
114
+
115
+ context "when parameter is not a Cell" do
116
+
117
+ it "should raise an ArgumentError" do
118
+ expect{@oci.get_cell_measures nil}.to raise_error ArgumentError
119
+ expect{@oci.get_cell_measures "This is a not a Cell"}.to raise_error ArgumentError
120
+ end
121
+
122
+ end
123
+
124
+ it "should set the correct path and parameters" do
125
+ @oci.get_cell_measures(Cell.new(1,2,3,4))
126
+ WebMock.should have_requested(:get, "www.opencellid.org/cell/getMeasures")
127
+ .with(query: {"cellid" => "1", "mnc" => "2", "mcc" => "3", "lac" => "4"})
128
+ end
129
+
130
+ it "should return a response" do
131
+ @oci.get_cell_measures(Cell.new(1,2,3,4)).should == @response
132
+ end
133
+
134
+ end
135
+
136
+ describe "get_cells_in_area" do
137
+
138
+ before do
139
+ @bbox = BBox.new(1.0,2.0,3.0,4.0)
140
+ @options = {mnc: 10, mcc: 20, limit: 30}
141
+ end
142
+
143
+ context "when parameters are not of right type" do
144
+
145
+ it "should raise an ArgumentError" do
146
+ expect{@oci.get_cells_in_area nil, @options}.to raise_error ArgumentError
147
+ expect{@oci.get_cells_in_area "This is a not a BBox", @options}.to raise_error ArgumentError
148
+ expect{@oci.get_cells_in_area @bbox, "This is not a hash" }.to raise_error ArgumentError
149
+ end
150
+
151
+ end
152
+
153
+ it "should set the correct path" do
154
+ @oci.get_cells_in_area(@bbox)
155
+ WebMock.should have_requested(:get, "www.opencellid.org/cell/getInArea")
156
+ .with(query: {"bbox" => @bbox.to_s, "fmt" => "xml"})
157
+ end
158
+
159
+ it "should filter out invalid parameters from options" do
160
+ @oci.get_cells_in_area(@bbox, mnc: 20, invalid_params: 50, limit: 30, mcc: 60)
161
+ WebMock.should have_requested(:get, "www.opencellid.org/cell/getInArea")
162
+ .with(query: {"bbox" => @bbox.to_s, "fmt" => "xml", "mnc" => "20", "mcc" => "60", "limit" => "30"})
163
+
164
+ end
165
+
166
+ it "should return a response" do
167
+ @oci.get_cells_in_area(@bbox).should == @response
168
+ end
169
+
170
+ end
171
+
172
+ describe "add_measure" do
173
+
174
+ before do
175
+ @cell = Cell.new(1,2,3,4)
176
+ @measured_at = DateTime.new(2011,7,22,10,10,10,Rational(2,24))
177
+ @measure = Measure.new(1.0, 2.0, @measured_at)
178
+ @measure.signal = 10
179
+ end
180
+
181
+ context "when parameters are of wrong type" do
182
+
183
+ it "should raise an ArgumentError" do
184
+ expect{@oci.add_measure nil, @measure}.to raise_error ArgumentError
185
+ expect{@oci.add_measure "This is not a Cell", @measure}.to raise_error ArgumentError
186
+ expect{@oci.add_measure @cell, nil}.to raise_error ArgumentError
187
+ expect{@oci.add_measure @cell, "This is not a measure"}.to raise_error ArgumentError
188
+ end
189
+
190
+ end
191
+
192
+ it "should set the correct path and parameters" do
193
+ @oci.add_measure(@cell, @measure)
194
+ WebMock.should have_requested(:get, "www.opencellid.org/measure/add")
195
+ .with(query: {"cellid" => "1", "mnc" => "2", "mcc" => "3", "lac" => "4",
196
+ "lat" => "1.0", "lon" => "2.0", "measured_at" => @measured_at.to_s, "signal" => "10"})
197
+ end
198
+
199
+ it "should return a response" do
200
+ @oci.add_measure(@cell, @measure).should == @response
201
+ end
202
+
203
+ end
204
+
205
+ describe "list_measures" do
206
+
207
+ it "should set the correct path and parameters" do
208
+ @oci.list_measures
209
+ WebMock.should have_requested(:get, "www.opencellid.org/measure/list")
210
+ end
211
+
212
+ it "should return a response" do
213
+ @oci.list_measures.should == @response
214
+ end
215
+
216
+ end
217
+
218
+ describe "delete_measure" do
219
+
220
+ context "when measure_id is nil" do
221
+
222
+ it "should raise an ArgumentError" do
223
+ expect{@oci.delete_measure nil}.to raise_error ArgumentError
224
+ end
225
+
226
+ end
227
+
228
+ it "should set the correct path and parameters" do
229
+ @oci.delete_measure 30
230
+ WebMock.should have_requested(:get, "www.opencellid.org/measure/delete")
231
+ .with(query: {"id" => "30"})
232
+ end
233
+
234
+ it "should return a response" do
235
+ @oci.delete_measure(30).should == @response
236
+ end
237
+
238
+ end
239
+
240
+ end
241
+
242
+ end