opencellid-client 0.1.0

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.
@@ -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