xively-rb 0.2.09
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/.gitignore +13 -0
- data/.rbenv-version +1 -0
- data/.rspec +2 -0
- data/.rvmrc +1 -0
- data/.travis.yml +7 -0
- data/CHANGELOG.md +91 -0
- data/CONTRIBUTING.md +95 -0
- data/Gemfile +15 -0
- data/LICENSE.md +13 -0
- data/README.md +10 -0
- data/Rakefile +25 -0
- data/ci/build_hudson.sh +24 -0
- data/init.rb +2 -0
- data/lib/xively-rb.rb +44 -0
- data/lib/xively-rb/array_extensions.rb +6 -0
- data/lib/xively-rb/base.rb +52 -0
- data/lib/xively-rb/base/instance_methods.rb +28 -0
- data/lib/xively-rb/client.rb +43 -0
- data/lib/xively-rb/datapoint.rb +72 -0
- data/lib/xively-rb/datastream.rb +127 -0
- data/lib/xively-rb/exceptions.rb +5 -0
- data/lib/xively-rb/feed.rb +109 -0
- data/lib/xively-rb/hash_extensions.rb +16 -0
- data/lib/xively-rb/helpers.rb +41 -0
- data/lib/xively-rb/key.rb +99 -0
- data/lib/xively-rb/nil_content.rb +15 -0
- data/lib/xively-rb/object_extensions.rb +6 -0
- data/lib/xively-rb/parsers/csv/datastream_defaults.rb +50 -0
- data/lib/xively-rb/parsers/csv/feed_defaults.rb +97 -0
- data/lib/xively-rb/parsers/defaults.rb +15 -0
- data/lib/xively-rb/parsers/json/datapoint_defaults.rb +16 -0
- data/lib/xively-rb/parsers/json/datastream_defaults.rb +58 -0
- data/lib/xively-rb/parsers/json/feed_defaults.rb +114 -0
- data/lib/xively-rb/parsers/json/key_defaults.rb +20 -0
- data/lib/xively-rb/parsers/json/search_result_defaults.rb +24 -0
- data/lib/xively-rb/parsers/json/trigger_defaults.rb +16 -0
- data/lib/xively-rb/parsers/xml/datapoint_defaults.rb +27 -0
- data/lib/xively-rb/parsers/xml/datastream_defaults.rb +53 -0
- data/lib/xively-rb/parsers/xml/errors.rb +7 -0
- data/lib/xively-rb/parsers/xml/feed_defaults.rb +83 -0
- data/lib/xively-rb/parsers/xml/helpers.rb +116 -0
- data/lib/xively-rb/parsers/xml/key_defaults.rb +46 -0
- data/lib/xively-rb/parsers/xml/trigger_defaults.rb +28 -0
- data/lib/xively-rb/permission.rb +67 -0
- data/lib/xively-rb/resource.rb +43 -0
- data/lib/xively-rb/search_result.rb +68 -0
- data/lib/xively-rb/string_extensions.rb +6 -0
- data/lib/xively-rb/templates/csv/datapoint_defaults.rb +22 -0
- data/lib/xively-rb/templates/csv/datastream_defaults.rb +43 -0
- data/lib/xively-rb/templates/csv/feed_defaults.rb +47 -0
- data/lib/xively-rb/templates/defaults.rb +14 -0
- data/lib/xively-rb/templates/json/datapoint_defaults.rb +15 -0
- data/lib/xively-rb/templates/json/datastream_defaults.rb +61 -0
- data/lib/xively-rb/templates/json/feed_defaults.rb +90 -0
- data/lib/xively-rb/templates/json/key_defaults.rb +39 -0
- data/lib/xively-rb/templates/json/search_result_defaults.rb +42 -0
- data/lib/xively-rb/templates/json/trigger_defaults.rb +21 -0
- data/lib/xively-rb/templates/xml/datapoint_defaults.rb +25 -0
- data/lib/xively-rb/templates/xml/datastream_defaults.rb +66 -0
- data/lib/xively-rb/templates/xml/feed_defaults.rb +112 -0
- data/lib/xively-rb/templates/xml/search_result_defaults.rb +118 -0
- data/lib/xively-rb/templates/xml_headers.rb +17 -0
- data/lib/xively-rb/trigger.rb +66 -0
- data/lib/xively-rb/validations.rb +9 -0
- data/lib/xively-rb/version.rb +3 -0
- data/spec/fixtures/models.rb +81 -0
- data/spec/spec_helper.rb +29 -0
- data/spec/support/contain_datapoint_eeml_matcher.rb +16 -0
- data/spec/support/contain_datastream_eeml_matcher.rb +60 -0
- data/spec/support/contain_feed_eeml_matcher.rb +98 -0
- data/spec/support/datapoint_helper.rb +53 -0
- data/spec/support/datastream_helper.rb +324 -0
- data/spec/support/describe_eeml_matcher.rb +23 -0
- data/spec/support/feed_helper.rb +783 -0
- data/spec/support/fully_represent_datapoint_matcher.rb +30 -0
- data/spec/support/fully_represent_datastream_matcher.rb +96 -0
- data/spec/support/fully_represent_feed_matcher.rb +234 -0
- data/spec/support/fully_represent_key_matcher.rb +74 -0
- data/spec/support/fully_represent_search_result_matcher.rb +67 -0
- data/spec/support/fully_represent_trigger_matcher.rb +29 -0
- data/spec/support/key_helper.rb +74 -0
- data/spec/support/search_result_helper.rb +252 -0
- data/spec/support/trigger_helper.rb +51 -0
- data/spec/xively-rb/array_extensions_spec.rb +9 -0
- data/spec/xively-rb/base/instance_methods_spec.rb +109 -0
- data/spec/xively-rb/base_spec.rb +56 -0
- data/spec/xively-rb/client_spec.rb +51 -0
- data/spec/xively-rb/datapoint_spec.rb +187 -0
- data/spec/xively-rb/datastream_spec.rb +344 -0
- data/spec/xively-rb/feed_spec.rb +341 -0
- data/spec/xively-rb/hash_extensions_spec.rb +20 -0
- data/spec/xively-rb/helpers_spec.rb +56 -0
- data/spec/xively-rb/key_spec.rb +198 -0
- data/spec/xively-rb/parsers/csv/datastream_defaults_spec.rb +110 -0
- data/spec/xively-rb/parsers/csv/feed_defaults_spec.rb +234 -0
- data/spec/xively-rb/parsers/json/datapoint_defaults_spec.rb +21 -0
- data/spec/xively-rb/parsers/json/datastream_defaults_spec.rb +105 -0
- data/spec/xively-rb/parsers/json/feed_defaults_spec.rb +45 -0
- data/spec/xively-rb/parsers/json/key_defaults_spec.rb +14 -0
- data/spec/xively-rb/parsers/json/search_result_defaults_spec.rb +18 -0
- data/spec/xively-rb/parsers/json/trigger_defaults_spec.rb +22 -0
- data/spec/xively-rb/parsers/xml/datapoint_defaults_spec.rb +19 -0
- data/spec/xively-rb/parsers/xml/datastream_defaults_spec.rb +148 -0
- data/spec/xively-rb/parsers/xml/feed_defaults_spec.rb +254 -0
- data/spec/xively-rb/parsers/xml/key_defaults_spec.rb +22 -0
- data/spec/xively-rb/parsers/xml/trigger_defaults_spec.rb +22 -0
- data/spec/xively-rb/search_result_spec.rb +257 -0
- data/spec/xively-rb/string_extensions_spec.rb +12 -0
- data/spec/xively-rb/templates/csv/datapoint_defaults_spec.rb +41 -0
- data/spec/xively-rb/templates/csv/datastream_defaults_spec.rb +131 -0
- data/spec/xively-rb/templates/csv/feed_defaults_spec.rb +78 -0
- data/spec/xively-rb/templates/json/datapoint_defaults_spec.rb +14 -0
- data/spec/xively-rb/templates/json/datastream_defaults_spec.rb +170 -0
- data/spec/xively-rb/templates/json/feed_defaults_spec.rb +399 -0
- data/spec/xively-rb/templates/json/key_defaults_spec.rb +29 -0
- data/spec/xively-rb/templates/json/search_result_defaults_spec.rb +37 -0
- data/spec/xively-rb/templates/json/trigger_defaults_spec.rb +19 -0
- data/spec/xively-rb/templates/xml/datapoint_defaults_spec.rb +14 -0
- data/spec/xively-rb/templates/xml/datastream_defaults_spec.rb +113 -0
- data/spec/xively-rb/templates/xml/feed_defaults_spec.rb +131 -0
- data/spec/xively-rb/templates/xml/search_result_defaults_spec.rb +44 -0
- data/spec/xively-rb/trigger_spec.rb +157 -0
- data/xively-rb.gemspec +41 -0
- metadata +333 -0
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Xively::Feed do
|
|
4
|
+
|
|
5
|
+
it "should have a constant that defines the allowed keys" do
|
|
6
|
+
Xively::Feed::ALLOWED_KEYS.should == %w(id creator owner_login datastreams description email feed icon location_disposition location_domain location_ele location_exposure location_lat location_lon location_name location_waypoints private status tags title updated created website auto_feed_url product_id device_serial csv_version)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
context "attr accessors" do
|
|
10
|
+
before(:each) do
|
|
11
|
+
@feed = Xively::Feed.new(feed_as_(:json))
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
describe "setting whitelisted fields" do
|
|
15
|
+
Xively::Feed::ALLOWED_KEYS.each do |key|
|
|
16
|
+
it "##{key}=" do
|
|
17
|
+
lambda {
|
|
18
|
+
@feed.send("#{key}=", key)
|
|
19
|
+
}.should_not raise_error
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
describe "getting whitelisted fields" do
|
|
25
|
+
Xively::Feed::ALLOWED_KEYS.each do |key|
|
|
26
|
+
it "##{key}" do
|
|
27
|
+
lambda {
|
|
28
|
+
@feed.send(key)
|
|
29
|
+
}.should_not raise_error
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
describe "setting non-whitelisted keys" do
|
|
35
|
+
it "should not be possible to set non-whitelisted fields" do
|
|
36
|
+
lambda {
|
|
37
|
+
@feed.something_bogus = 'whatevs'
|
|
38
|
+
}.should raise_error
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "should not be possible to get non-whitelisted fields" do
|
|
42
|
+
lambda {
|
|
43
|
+
@feed.something_bogus
|
|
44
|
+
}.should raise_error
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
describe "validation" do
|
|
50
|
+
%w(title).each do |field|
|
|
51
|
+
it "should require a '#{field}'" do
|
|
52
|
+
feed = Xively::Feed.new
|
|
53
|
+
feed.send("#{field}=".to_sym, nil)
|
|
54
|
+
feed.should_not be_valid
|
|
55
|
+
feed.errors[field.to_sym].should == ["can't be blank"]
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "should not allow duplicate datastreams" do
|
|
60
|
+
feed = Xively::Feed.new
|
|
61
|
+
feed.datastreams = [Xively::Datastream.new('id' => '1'), Xively::Datastream.new('id' => '1')]
|
|
62
|
+
feed.should_not be_valid
|
|
63
|
+
feed.errors[:datastreams].should == ["can't have duplicate IDs: 1"]
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it "should validate all datastreams" do
|
|
67
|
+
feed = Xively::Feed.new
|
|
68
|
+
feed.datastreams = [Xively::Datastream.new('id' => '')]
|
|
69
|
+
feed.should_not be_valid
|
|
70
|
+
feed.errors[:datastreams_id].should == ["can't be blank"]
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
describe "#initialize" do
|
|
75
|
+
it "should create a blank slate when passed no arguments" do
|
|
76
|
+
feed = Xively::Feed.new
|
|
77
|
+
Xively::Feed::ALLOWED_KEYS.each do |attr|
|
|
78
|
+
feed.attributes[attr.to_sym].should be_nil
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
%w(xml json hash).each do |format|
|
|
83
|
+
it "should accept #{format}" do
|
|
84
|
+
feed = Xively::Feed.new(feed_as_(format.to_sym))
|
|
85
|
+
feed.title.downcase.should == "xively office environment"
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
%w(to_csv as_json to_xml to_json attributes).each do |output_format|
|
|
89
|
+
it "should be able to output from #{format} using #{output_format}" do
|
|
90
|
+
feed = Xively::Feed.new(feed_as_(format.to_sym))
|
|
91
|
+
lambda {feed.send(output_format.to_sym)}.should_not raise_error
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
context "specifying format" do
|
|
97
|
+
it "should raise known exception if told xml but given csv" do
|
|
98
|
+
expect {
|
|
99
|
+
Xively::Feed.new(feed_as_(:csv), :v2, :xml)
|
|
100
|
+
}.to raise_error(Xively::Parsers::XML::InvalidXMLError)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it "should raise known exception if told xml but given json" do
|
|
104
|
+
expect {
|
|
105
|
+
Xively::Feed.new(feed_as_(:json), nil, :xml)
|
|
106
|
+
}.to raise_error(Xively::Parsers::XML::InvalidXMLError)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it "should raise known exception if told json but given xml" do
|
|
110
|
+
expect {
|
|
111
|
+
Xively::Feed.new(feed_as_(:xml), nil, :json)
|
|
112
|
+
}.to raise_error(Xively::Parsers::JSON::InvalidJSONError)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
it "should raise known exception if told json but given csv" do
|
|
116
|
+
expect {
|
|
117
|
+
Xively::Feed.new(feed_as_(:csv), nil, :json)
|
|
118
|
+
}.to raise_error(Xively::Parsers::JSON::InvalidJSONError)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
it "should raise known exception if told csv but given xml" do
|
|
122
|
+
expect {
|
|
123
|
+
Xively::Feed.new(feed_as_(:xml), :v2, :csv)
|
|
124
|
+
}.to raise_error(Xively::Parsers::CSV::InvalidCSVError)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
it "should raise known exception if told csv but given json" do
|
|
128
|
+
expect {
|
|
129
|
+
Xively::Feed.new(feed_as_(:json), :v2, :csv)
|
|
130
|
+
}.to raise_error(Xively::Parsers::CSV::InvalidCSVError)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it "should raise known exception if told format is something unknown" do
|
|
134
|
+
expect {
|
|
135
|
+
Xively::Feed.new(feed_as_(:json), :v2, :msgpack)
|
|
136
|
+
}.to raise_error(Xively::InvalidFormatError)
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
describe "#attributes" do
|
|
142
|
+
it "should return a hash of feed properties" do
|
|
143
|
+
attrs = {}
|
|
144
|
+
Xively::Feed::ALLOWED_KEYS.each do |key|
|
|
145
|
+
attrs[key] = "key #{rand(1000)}"
|
|
146
|
+
end
|
|
147
|
+
attrs["datastreams"] = [Xively::Datastream.new({"id" => "ein"})]
|
|
148
|
+
feed = Xively::Feed.new(attrs)
|
|
149
|
+
|
|
150
|
+
feed.attributes.should == attrs
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
it "should contain csv_version in the allowed keys" do
|
|
154
|
+
Xively::Feed::ALLOWED_KEYS.should include("csv_version")
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
it "should not return nil values" do
|
|
158
|
+
attrs = {}
|
|
159
|
+
Xively::Feed::ALLOWED_KEYS.each do |key|
|
|
160
|
+
attrs[key] = "key #{rand(1000)}"
|
|
161
|
+
end
|
|
162
|
+
attrs["created_at"] = nil
|
|
163
|
+
feed = Xively::Feed.new(attrs)
|
|
164
|
+
|
|
165
|
+
feed.attributes.should_not include("created_at")
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
describe "#attributes=" do
|
|
170
|
+
it "should accept and save a hash of feed properties" do
|
|
171
|
+
feed = Xively::Feed.new({})
|
|
172
|
+
|
|
173
|
+
attrs = {}
|
|
174
|
+
Xively::Feed::ALLOWED_KEYS.each do |key|
|
|
175
|
+
value = "key #{rand(1000)}"
|
|
176
|
+
attrs[key] = value
|
|
177
|
+
feed.should_receive("#{key}=").with(value)
|
|
178
|
+
end
|
|
179
|
+
feed.attributes=(attrs)
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
context "associated datastreams" do
|
|
184
|
+
|
|
185
|
+
describe "#datastreams" do
|
|
186
|
+
it "should return an array of datastreams" do
|
|
187
|
+
datastreams = [Xively::Datastream.new(datastream_as_(:hash))]
|
|
188
|
+
attrs = {"datastreams" => datastreams}
|
|
189
|
+
feed = Xively::Feed.new(attrs)
|
|
190
|
+
feed.datastreams.each do |ds|
|
|
191
|
+
ds.should be_kind_of(Xively::Datastream)
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
it "should default to an empty array" do
|
|
196
|
+
feed = Xively::Feed.new({})
|
|
197
|
+
feed.datastreams.should == []
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
describe "#datastreams=" do
|
|
202
|
+
before(:each) do
|
|
203
|
+
@feed = Xively::Feed.new({})
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
it "should return an empty array if not an array" do
|
|
207
|
+
@feed.datastreams = "kittens"
|
|
208
|
+
@feed.datastreams.should be_empty
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
it "should accept an array of datastreams and hashes and store an array of datastreams" do
|
|
212
|
+
new_datastream1 = Xively::Datastream.new(datastream_as_(:hash))
|
|
213
|
+
new_datastream2 = Xively::Datastream.new(datastream_as_(:hash))
|
|
214
|
+
Xively::Datastream.should_receive(:new).with(datastream_as_(:hash)).and_return(new_datastream2)
|
|
215
|
+
|
|
216
|
+
datastreams = [new_datastream1, datastream_as_(:hash)]
|
|
217
|
+
@feed.datastreams = datastreams
|
|
218
|
+
@feed.datastreams.length.should == 2
|
|
219
|
+
@feed.datastreams.should include(new_datastream1)
|
|
220
|
+
@feed.datastreams.should include(new_datastream2)
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
it "should accept an array of datastreams and store an array of datastreams" do
|
|
224
|
+
datastreams = [Xively::Datastream.new(datastream_as_(:hash))]
|
|
225
|
+
@feed.datastreams = datastreams
|
|
226
|
+
@feed.datastreams.should == datastreams
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
it "should accept an array of hashes and store an array of datastreams" do
|
|
230
|
+
new_datastream = Xively::Datastream.new(datastream_as_(:hash))
|
|
231
|
+
Xively::Datastream.should_receive(:new).with(datastream_as_(:hash)).and_return(new_datastream)
|
|
232
|
+
|
|
233
|
+
datastreams_hash = [datastream_as_(:hash)]
|
|
234
|
+
@feed.datastreams = datastreams_hash
|
|
235
|
+
@feed.datastreams.should == [new_datastream]
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
it "should accept an array of subclass of datastream and store an array of datastreams" do
|
|
239
|
+
class OurSpecialDatastreamClass < Xively::Datastream
|
|
240
|
+
attr_accessor :something_new
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
datastreams = [OurSpecialDatastreamClass.new(datastream_as_(:hash))]
|
|
244
|
+
@feed.datastreams = datastreams
|
|
245
|
+
@feed.datastreams.should == datastreams
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
# Provided by Xively::Templates::FeedDefaults
|
|
252
|
+
describe "#generate_json" do
|
|
253
|
+
it "should take a version and generate the appropriate template" do
|
|
254
|
+
feed = Xively::Feed.new({})
|
|
255
|
+
feed.generate_json("1.0.0").should == {:version => "1.0.0"}
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
describe "#to_csv" do
|
|
260
|
+
it "should call the csv generator with default version" do
|
|
261
|
+
feed = Xively::Feed.new({})
|
|
262
|
+
feed.should_receive(:generate_csv).with("2", {}).and_return("1,2,3,4")
|
|
263
|
+
feed.to_csv.should == "1,2,3,4"
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
it "should accept optional csv version" do
|
|
267
|
+
version = "1"
|
|
268
|
+
feed = Xively::Feed.new({})
|
|
269
|
+
feed.should_receive(:generate_csv).with(version, {}).and_return("1,2,3,4")
|
|
270
|
+
feed.to_csv(:version => version).should == "1,2,3,4"
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
it "should accept additional options" do
|
|
274
|
+
version = "1"
|
|
275
|
+
feed = Xively::Feed.new({})
|
|
276
|
+
feed.should_receive(:generate_csv).with(version, :full => true).and_return("1,2,3,4")
|
|
277
|
+
feed.to_csv(:version => version, :full => true).should == "1,2,3,4"
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
describe "#to_xml" do
|
|
282
|
+
it "should call the xml generator with default version" do
|
|
283
|
+
feed = Xively::Feed.new({})
|
|
284
|
+
feed.should_receive(:generate_xml).with("0.5.1", {}).and_return("<xml></xml>")
|
|
285
|
+
feed.to_xml.should == "<xml></xml>"
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
it "should accept optional xml version" do
|
|
289
|
+
version = "5"
|
|
290
|
+
feed = Xively::Feed.new({})
|
|
291
|
+
feed.should_receive(:generate_xml).with(version, {}).and_return("<xml></xml>")
|
|
292
|
+
feed.to_xml(:version => version).should == "<xml></xml>"
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
describe "#as_json" do
|
|
297
|
+
it "should call the json generator with default version" do
|
|
298
|
+
feed = Xively::Feed.new({})
|
|
299
|
+
feed.should_receive(:generate_json).with("1.0.0", {}).and_return({"title" => "Environment"})
|
|
300
|
+
feed.as_json.should == {"title" => "Environment"}
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
it "should accept optional json version" do
|
|
304
|
+
version = "0.6-alpha"
|
|
305
|
+
feed = Xively::Feed.new({})
|
|
306
|
+
feed.should_receive(:generate_json).with(version, {}).and_return({"title" => "Environment"})
|
|
307
|
+
feed.as_json(:version => version).should == {"title" => "Environment"}
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
describe "#to_json" do
|
|
312
|
+
it "should call #as_json" do
|
|
313
|
+
feed_hash = {"title" => "Environment"}
|
|
314
|
+
feed = Xively::Feed.new(feed_hash)
|
|
315
|
+
feed.should_receive(:as_json).with({})
|
|
316
|
+
feed.to_json
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
it "should pass options through to #as_json" do
|
|
320
|
+
feed_hash = {"title" => "Environment"}
|
|
321
|
+
feed = Xively::Feed.new(feed_hash)
|
|
322
|
+
feed.should_receive(:as_json).with({:crazy => "options"})
|
|
323
|
+
feed.to_json({:crazy => "options"})
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
it "should generate datastreams" do
|
|
327
|
+
feed = Xively::Feed.new(feed_as_('hash'))
|
|
328
|
+
feed.datastreams = datastream_as_(:hash)
|
|
329
|
+
MultiJson.load(feed.to_json)["datastreams"].should_not be_nil
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
it "should pass the output of #as_json to yajl" do
|
|
333
|
+
feed_hash = {"title" => "Environment"}
|
|
334
|
+
feed = Xively::Feed.new(feed_hash)
|
|
335
|
+
feed.should_receive(:as_json).and_return({:awesome => "hash"})
|
|
336
|
+
MultiJson.should_receive(:dump).with({:awesome => "hash"})
|
|
337
|
+
feed.to_json
|
|
338
|
+
end
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "Hash extensions" do
|
|
4
|
+
it "should add a delete_if_nil_value method to hashes" do
|
|
5
|
+
hash = { "foo" => "awesome", "bar" => nil, :symbol => "" }
|
|
6
|
+
hash.delete_if_nil_value.should == { "foo" => "awesome" }
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# HACK probably
|
|
10
|
+
it "should add a deep_stringify_keys method to hash instances" do
|
|
11
|
+
hash = { :sym => "val", :nested => { "str" => 12, :symtoo => 58 } }
|
|
12
|
+
hash.deep_stringify_keys.should == { "sym" => "val", "nested" => { "str" => 12, "symtoo" => 58 } }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "should have a destructive in place version of the deep_stringify_keys method" do
|
|
16
|
+
hash = { :sym => "val", :nested => { "str" => 12, :symtoo => 58 } }
|
|
17
|
+
hash.deep_stringify_keys!
|
|
18
|
+
hash.should == { "sym" => "val", "nested" => { "str" => 12, "symtoo" => 58 } }
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "Template helpers" do
|
|
4
|
+
include Xively::Helpers
|
|
5
|
+
|
|
6
|
+
describe "#join_tags" do
|
|
7
|
+
|
|
8
|
+
it "should just return the string if it already is one" do
|
|
9
|
+
join_tags('help, me').should == 'help, me'
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "should convert an array into a string" do
|
|
13
|
+
join_tags(['bag', 'jag', 'lag', 'tag']).should == 'bag,jag,lag,tag'
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "should sort the array" do
|
|
17
|
+
join_tags(['zag', 'xag', 'Bag', 'aag']).should == 'aag,Bag,xag,zag'
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
describe "#parse_tag_string" do
|
|
22
|
+
it "should handle single tags" do
|
|
23
|
+
parse_tag_string('tag').should == ['tag']
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "should handle multiple tags" do
|
|
27
|
+
parse_tag_string('tag, bag ,lag,jag').should == ['bag', 'jag', 'lag', 'tag']
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "should handle complex tags" do
|
|
31
|
+
string = 'apple, orange, "red room", " I like space ", "tennis, later"'
|
|
32
|
+
parse_tag_string(string).should ==
|
|
33
|
+
[
|
|
34
|
+
" I like space ",
|
|
35
|
+
"apple",
|
|
36
|
+
"orange",
|
|
37
|
+
"red room",
|
|
38
|
+
"tennis, later"
|
|
39
|
+
]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "should handle tags with escaped double quote" do
|
|
43
|
+
string = 'apple, orange, "horse:height=2\"", " I like space ", "tennis, later", "\"quote\""'
|
|
44
|
+
parse_tag_string(string).should ==
|
|
45
|
+
[
|
|
46
|
+
" I like space ",
|
|
47
|
+
"\"quote\"",
|
|
48
|
+
"apple",
|
|
49
|
+
"horse:height=2\"",
|
|
50
|
+
"orange",
|
|
51
|
+
"tennis, later"
|
|
52
|
+
]
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Xively::Key do
|
|
4
|
+
it "should have a constant that defines the allowed keys" do
|
|
5
|
+
Xively::Key::ALLOWED_KEYS.sort.should == %w(expires_at id key label user permissions private_access).sort
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
describe "validation" do
|
|
9
|
+
before(:each) do
|
|
10
|
+
@key = Xively::Key.new
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
%w(label permissions user).each do |field|
|
|
14
|
+
it "should require a '#{field}'" do
|
|
15
|
+
@key.send("#{field}=".to_sym, nil)
|
|
16
|
+
@key.should_not be_valid
|
|
17
|
+
@key.errors[field.to_sym].should include("can't be blank")
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "should not be valid if resource present with no feed_id" do
|
|
22
|
+
@key.attributes = { :user => "bob", :permissions => [ { :access_methods => ["get"], :resources => [{}] } ] }
|
|
23
|
+
@key.should_not be_valid
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "should not be valid if we have a datastream_id with no feed_id in a resource" do
|
|
27
|
+
@key.attributes = { :user => "bob", :permissions => [ { :access_methods => ["get"], :resources => [{:datastream_id => "0"}] } ] }
|
|
28
|
+
@key.should_not be_valid
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "should always return a boolean from the permission private_access? attribute, even if nil" do
|
|
32
|
+
@key.private_access.should be_nil
|
|
33
|
+
@key.private_access?.should be_false
|
|
34
|
+
@key.private_access = true
|
|
35
|
+
@key.private_access?.should be_true
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "should not be valid if a permission object with no methods is added" do
|
|
39
|
+
@key.attributes = { :user => "bob", :permissions => [ { :label => "label" } ] }
|
|
40
|
+
@key.should_not be_valid
|
|
41
|
+
@key.errors[:permissions_access_methods].should include("can't be blank")
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "should return the key as the id if no id attribute is specified" do
|
|
45
|
+
hash = key_as_(:hash)
|
|
46
|
+
hash.delete("id")
|
|
47
|
+
@key.attributes = hash
|
|
48
|
+
@key.id.should == "abcdefghasdfaoisdj109usasdf0a9sf"
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
describe "#initialize" do
|
|
53
|
+
it "should create a blank slate when passed no arguments" do
|
|
54
|
+
key = Xively::Key.new
|
|
55
|
+
Xively::Key::ALLOWED_KEYS.each do |attr|
|
|
56
|
+
key.attributes[attr.to_sym].should be_nil
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it "should accept xml" do
|
|
61
|
+
key = Xively::Key.new(key_as_(:xml))
|
|
62
|
+
key.permissions.first.access_methods.should == ["get", "put", "post", "delete"]
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it "should accept json" do
|
|
66
|
+
key = Xively::Key.new(key_as_(:json))
|
|
67
|
+
key.permissions.first.access_methods.should == ["get", "put", "post", "delete"]
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it "should accept a hash of attributes" do
|
|
71
|
+
key = Xively::Key.new(key_as_(:hash))
|
|
72
|
+
key.permissions.first.access_methods.should == ["get", "put", "post", "delete"]
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
context "specifying format" do
|
|
76
|
+
it "should raise known exception if told xml but given json" do
|
|
77
|
+
expect {
|
|
78
|
+
Xively::Key.new(key_as_(:json), :xml)
|
|
79
|
+
}.to raise_error(Xively::Parsers::XML::InvalidXMLError)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it "should raise known exception if told json but given xml" do
|
|
83
|
+
expect {
|
|
84
|
+
Xively::Key.new(key_as_(:xml), :json)
|
|
85
|
+
}.to raise_error(Xively::Parsers::JSON::InvalidJSONError)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it "should raise known exception if given unknown format" do
|
|
89
|
+
expect {
|
|
90
|
+
Xively::Key.new(key_as_(:xml), :gif)
|
|
91
|
+
}.to raise_error(Xively::InvalidFormatError)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
describe "#attributes" do
|
|
97
|
+
it "should return a hash of key properties" do
|
|
98
|
+
attrs = {}
|
|
99
|
+
Xively::Key::ALLOWED_KEYS.each do |key|
|
|
100
|
+
attrs[key] = "key #{rand(1000)}"
|
|
101
|
+
end
|
|
102
|
+
attrs["permissions"] = [Xively::Permission.new(:permissions => [:get])]
|
|
103
|
+
key = Xively::Key.new(attrs)
|
|
104
|
+
|
|
105
|
+
key.attributes.should == attrs
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
it "should not return nil values" do
|
|
109
|
+
attrs = {}
|
|
110
|
+
Xively::Key::ALLOWED_KEYS.each do |key|
|
|
111
|
+
attrs[key] = "key #{rand(1000)}"
|
|
112
|
+
end
|
|
113
|
+
attrs["notified_at"] = nil
|
|
114
|
+
key = Xively::Key.new(attrs)
|
|
115
|
+
|
|
116
|
+
key.attributes.should_not include("notified_at")
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
describe "#attributes=" do
|
|
121
|
+
it "should accept and save a hash of properties" do
|
|
122
|
+
key = Xively::Key.new({})
|
|
123
|
+
|
|
124
|
+
attrs = {}
|
|
125
|
+
Xively::Key::ALLOWED_KEYS.each do |attr|
|
|
126
|
+
value = "key #{rand(1000)}"
|
|
127
|
+
attrs[attr] = value
|
|
128
|
+
key.should_receive("#{attr}=").with(value)
|
|
129
|
+
end
|
|
130
|
+
key.attributes=(attrs)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it "should accept deep nested attributes for permissions array" do
|
|
134
|
+
key = Xively::Key.new({})
|
|
135
|
+
key.attributes = { :permissions_attributes => [{:label => "label", :access_methods => [:get, :put], :resources_attributes => [{:feed_id => 123, :datastream_id => "0"}]}] }
|
|
136
|
+
key.permissions.size.should == 1
|
|
137
|
+
key.permissions.first.label.should == "label"
|
|
138
|
+
key.permissions.first.resources.size.should == 1
|
|
139
|
+
key.permissions.first.resources.first.feed_id.should == 123
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
it "should set deep nested attributes using class instances as well (not just hashes of attributes)" do
|
|
143
|
+
resource = Xively::Resource.new(:feed_id => 123)
|
|
144
|
+
permission = Xively::Permission.new(:label => "label", :access_methods => [:get], :resources => [resource])
|
|
145
|
+
key = Xively::Key.new(:permissions => [permission])
|
|
146
|
+
key.permissions.size.should == 1
|
|
147
|
+
key.permissions.first.resources.size.should == 1
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
describe "#as_json" do
|
|
152
|
+
it "should call the json generator" do
|
|
153
|
+
options = {:include_blanks => true}
|
|
154
|
+
key = Xively::Key.new
|
|
155
|
+
key.should_receive(:generate_json).with(options).and_return({"permissions" => [:get, :put]})
|
|
156
|
+
key.as_json(options).should == {"permissions" => [:get, :put]}
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
it "should accept *very* nil options" do
|
|
160
|
+
key = Xively::Key.new
|
|
161
|
+
key.should_receive(:generate_json).with({}).and_return({"permissions" => [:get, :put]})
|
|
162
|
+
key.as_json(nil).should == {"permissions" => [:get, :put]}
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
it "should return iso8601 formatted expires_at string if present" do
|
|
166
|
+
time = Time.now
|
|
167
|
+
key = Xively::Key.new(:expires_at => time)
|
|
168
|
+
key.as_json[:key][:expires_at].should == time.iso8601(6)
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
describe "#to_json" do
|
|
173
|
+
before(:each) do
|
|
174
|
+
@time = Time.now
|
|
175
|
+
@key_hash = { "label" => "label", :expires_at => @time, "permissions" => [{"permissions" => [:get, :put, :post], :resources => [{:feed_id => 504, :datastream_id => "0"}]}] }
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
it "should call #as_json" do
|
|
179
|
+
key = Xively::Key.new(@key_hash)
|
|
180
|
+
key.should_receive(:as_json).with(nil)
|
|
181
|
+
key.to_json
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
it "should pass options through to #as_json" do
|
|
185
|
+
key = Xively::Key.new(@key_hash)
|
|
186
|
+
key.should_receive(:as_json).with({:crazy => "options"})
|
|
187
|
+
key.to_json({:crazy => "options"})
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
it "should pass the output of #as_json to yajl" do
|
|
191
|
+
key = Xively::Key.new(@key_hash)
|
|
192
|
+
key.should_receive(:as_json).and_return({:awesome => "hash"})
|
|
193
|
+
MultiJson.should_receive(:dump).with({:awesome => "hash"})
|
|
194
|
+
key.to_json
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
end
|