device_cloud 0.2.3 → 0.2.4
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 +15 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -1
- data/README.md +87 -30
- data/Rakefile +19 -0
- data/device_cloud.gemspec +6 -4
- data/lib/device_cloud.rb +5 -1
- data/lib/device_cloud/configuration.rb +15 -9
- data/lib/device_cloud/monitor.rb +140 -0
- data/lib/device_cloud/push_notification.rb +3 -3
- data/lib/device_cloud/request.rb +79 -0
- data/lib/device_cloud/response.rb +17 -0
- data/lib/device_cloud/version.rb +1 -1
- data/spec/device_cloud/monitor_spec.rb +277 -0
- data/spec/device_cloud/request_spec.rb +65 -0
- data/spec/device_cloud/response_spec.rb +47 -0
- data/spec/spec_helper.rb +18 -3
- data/spec/version_spec.rb +2 -2
- data/wercker.yml +8 -0
- metadata +60 -15
checksums.yaml
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
!binary "U0hBMQ==":
|
|
3
|
+
metadata.gz: !binary |-
|
|
4
|
+
MGExNTcxYzU4ZTZiNDdkYjkzODcwNjM5YzA4OTBkYTZiOTQ5ZjI4MA==
|
|
5
|
+
data.tar.gz: !binary |-
|
|
6
|
+
YTlkYTdmZjMzMGM5ZWFjZjEwY2FjYjc0M2FkNGNhNDMyOTdjNDBhNw==
|
|
7
|
+
SHA512:
|
|
8
|
+
metadata.gz: !binary |-
|
|
9
|
+
YjhiYzU1Mzk3ODhjMWVmMTViODM4OWJkMDNiZjJkOTY1NDRmYTA3ZTU0OWJk
|
|
10
|
+
YjhhNDU0YTUyMTA5MDdhNzA3NWJkYzczMWNjODc0YmVhNGQ5ZTdkNzBlNDk5
|
|
11
|
+
MDQxY2QxN2FjMDU3YjExODk0NGIzMDY2MGQ0N2RjNzEwM2MzNzU=
|
|
12
|
+
data.tar.gz: !binary |-
|
|
13
|
+
YzE5NThhZmM2NjJiMzdkY2ZjZDllMGYxNzNkNWEzNmNlZGZhNTI5NzNkODY3
|
|
14
|
+
YzMzOWIwNjYzY2ZiYWU2YmJlMjRjNzU2YjY2NjU1ODk4NmExMzVmNzQ5ZGQz
|
|
15
|
+
MDFmNzk4ZTRlODA3YWU4MzhiYTZlNmJkYjU1MzU0OGMzMTlkNjE=
|
data/.ruby-gemset
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
device_cloud
|
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.9.3-
|
|
1
|
+
1.9.3-p484
|
data/README.md
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
# DeviceCloud
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
- remove any assumptions about Device Cloud FileData contents .. probably should only parse them if asked
|
|
5
|
-
- add code for maintaining monitors
|
|
3
|
+
[](http://badge.fury.io/rb/device_cloud)
|
|
6
4
|
|
|
7
|
-
|
|
5
|
+
[](https://app.wercker.com/project/bykey/88a596a14228b6d5b8e7a57dd5d6db55)
|
|
6
|
+
|
|
7
|
+
#####TODO:
|
|
8
8
|
|
|
9
|
+
* Add code for maintaining devices
|
|
10
|
+
* Add code for maintaining alarms
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
9
13
|
Add this line to your application's Gemfile:
|
|
10
14
|
|
|
11
15
|
gem 'device_cloud'
|
|
@@ -20,25 +24,86 @@ Or install it yourself as:
|
|
|
20
24
|
|
|
21
25
|
## Usage
|
|
22
26
|
|
|
23
|
-
|
|
27
|
+
### Configuration
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
DeviceCloud.configure do |config|
|
|
31
|
+
config.username = 'your idigi username'
|
|
32
|
+
config.password = 'your idigi password'
|
|
33
|
+
end
|
|
34
|
+
# =>
|
|
35
|
+
# {
|
|
36
|
+
# username: 'your idigi username,
|
|
37
|
+
# password: 'your idigi password',
|
|
38
|
+
# root_url: 'https://my.idigi.com',
|
|
39
|
+
# host: 'my.idigi.com',
|
|
40
|
+
# alert_notification_handler: nil,
|
|
41
|
+
# empty_alert_notification_handler: nil,
|
|
42
|
+
# data_notification_handler: nil,
|
|
43
|
+
# empty_data_notification_handler: nil,
|
|
44
|
+
# event_notification_handler: nil,
|
|
45
|
+
# empty_event_notification_handler: nil,
|
|
46
|
+
# logger: Logger.new(STDOUT) # default
|
|
47
|
+
# }
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
### Push Notifications
|
|
52
|
+
|
|
53
|
+
`device_cloud` is currently only able to handle JSON push notifications via http, so your monitor must be set up accordingly. Read more about Monitors below.
|
|
54
|
+
|
|
55
|
+
When your application receives an HTTP push notification, it can be passed to the DeviceCloud gem using the following:
|
|
56
|
+
|
|
57
|
+
```ruby
|
|
58
|
+
push_notification = DeviceCloud::PushNotification( http_response_body )
|
|
59
|
+
# where http_response_body is a hash of the parsed JSON body content sent by DeviceCloud
|
|
60
|
+
|
|
61
|
+
push_notification.handle_each!
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The event will then be handled by one of your defined Notification Handlers.
|
|
65
|
+
|
|
66
|
+
#### Notification Handlers
|
|
67
|
+
|
|
68
|
+
Notification handlers take a Proc, and are called with a relevant alert or event object. A list of supported topic handlers are listed as follows:
|
|
69
|
+
|
|
70
|
+
alert_notification_handler
|
|
71
|
+
data_notification_handler
|
|
72
|
+
event_notification_handler
|
|
73
|
+
|
|
74
|
+
The following empty notification handlers are also available:
|
|
75
|
+
|
|
76
|
+
empty_alert_notification_handler
|
|
77
|
+
empty_data_notification_handler
|
|
78
|
+
empty_event_notification_handler
|
|
79
|
+
|
|
80
|
+
An example definition may look like the following
|
|
81
|
+
|
|
82
|
+
```ruby
|
|
83
|
+
DeviceCloud.alert_notification_handler = Proc.new do |alert|
|
|
84
|
+
puts "#{alert.type} Alert: for device #{alert.device_id}"
|
|
85
|
+
puts "Base 64 encoded data #{alert.raw_data}"
|
|
86
|
+
end
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
#### Example Push Notification
|
|
24
90
|
|
|
25
|
-
## Example Push Notification
|
|
26
91
|
|
|
27
92
|
```json
|
|
28
93
|
{
|
|
29
94
|
"Document": {
|
|
30
95
|
"Msg": {
|
|
31
96
|
"timestamp": "2013-10-21T19:34:56Z",
|
|
32
|
-
"topic": "
|
|
97
|
+
"topic": "device/event/event.json",
|
|
33
98
|
"FileData": {
|
|
34
99
|
"id": {
|
|
35
|
-
"fdPath": "/
|
|
36
|
-
"fdName": "
|
|
100
|
+
"fdPath": "/device/event/",
|
|
101
|
+
"fdName": "event.json"
|
|
37
102
|
},
|
|
38
103
|
"fdLastModifiedDate": "2013-10-21T19:34:56Z",
|
|
39
104
|
"fdSize": 545,
|
|
40
105
|
"fdContentType": "application/json",
|
|
41
|
-
"fdData": "
|
|
106
|
+
"fdData": "eW91IGhhdmUgdG9vIG11Y2ggZnJlZSB0aW1l\n",
|
|
42
107
|
"fdArchive": false,
|
|
43
108
|
"cstId": 4044,
|
|
44
109
|
"fdType": "event",
|
|
@@ -52,27 +117,9 @@ TODO: Write usage instructions here
|
|
|
52
117
|
}
|
|
53
118
|
```
|
|
54
119
|
|
|
55
|
-
|
|
120
|
+
### Monitors
|
|
56
121
|
|
|
57
|
-
|
|
58
|
-
{
|
|
59
|
-
"value": {
|
|
60
|
-
"plate": "941GVT",
|
|
61
|
-
"confidence": "99",
|
|
62
|
-
"country": "US",
|
|
63
|
-
"towards_camera": "false",
|
|
64
|
-
"timestamp": "2013-10-21T14:34:40Z",
|
|
65
|
-
"overview_image_id": "lot_overview_cap_10_21_2013_143440.jpg",
|
|
66
|
-
"state": "MN",
|
|
67
|
-
"patch_image_id": "lot_patch_cap_10_21_2013_143440.jpg"
|
|
68
|
-
},
|
|
69
|
-
"class": "event",
|
|
70
|
-
"queued_dt": "2013-10-21T19:34:56Z",
|
|
71
|
-
"type": "parking_lot_event_exit",
|
|
72
|
-
"id": "dd9d57363a8711e3a9bd0013950e6017",
|
|
73
|
-
"device_id": "m:0013950E6017"
|
|
74
|
-
}
|
|
75
|
-
```
|
|
122
|
+
TODO: write about Monitor class
|
|
76
123
|
|
|
77
124
|
## Contributing
|
|
78
125
|
|
|
@@ -81,3 +128,13 @@ That notification's unencoded fdData:
|
|
|
81
128
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
82
129
|
4. Push to the branch (`git push origin my-new-feature`)
|
|
83
130
|
5. Create new Pull Request
|
|
131
|
+
|
|
132
|
+
### Development
|
|
133
|
+
|
|
134
|
+
You can get a pry console by using the `:console` Rake task
|
|
135
|
+
|
|
136
|
+
$ rake console
|
|
137
|
+
|
|
138
|
+
You can also optionally pass your Device Cloud username and password like so
|
|
139
|
+
|
|
140
|
+
$ IDIGI_USERNAME=youruser IDIGI_PASSWORD=yourpass rake console
|
data/Rakefile
CHANGED
|
@@ -1 +1,20 @@
|
|
|
1
1
|
require "bundler/gem_tasks"
|
|
2
|
+
require 'rspec/core/rake_task'
|
|
3
|
+
|
|
4
|
+
RSpec::Core::RakeTask.new(:spec)
|
|
5
|
+
|
|
6
|
+
task :default => :spec
|
|
7
|
+
|
|
8
|
+
desc 'Run a console with device_cloud loaded'
|
|
9
|
+
task :console do
|
|
10
|
+
require 'device_cloud'
|
|
11
|
+
require 'pry'
|
|
12
|
+
require 'awesome_print'
|
|
13
|
+
|
|
14
|
+
DeviceCloud.configure do |config|
|
|
15
|
+
config.username = ENV['IDIGI_USERNAME']
|
|
16
|
+
config.password = ENV['IDIGI_PASSWORD']
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
Pry.start
|
|
20
|
+
end
|
data/device_cloud.gemspec
CHANGED
|
@@ -7,10 +7,10 @@ Gem::Specification.new do |spec|
|
|
|
7
7
|
spec.name = "device_cloud"
|
|
8
8
|
spec.version = DeviceCloud::VERSION
|
|
9
9
|
spec.authors = ["Erik Straub"]
|
|
10
|
-
spec.email = ["erik@
|
|
10
|
+
spec.email = ["erik@madglory.com"]
|
|
11
11
|
spec.description = %q{A Ruby wrapper for the Etherios Device Cloud}
|
|
12
12
|
spec.summary = %q{A Ruby wrapper for the Etherios Device Cloud}
|
|
13
|
-
spec.homepage = "http://github.com/
|
|
13
|
+
spec.homepage = "http://github.com/madglory/device_cloud"
|
|
14
14
|
spec.license = "MIT"
|
|
15
15
|
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
|
@@ -20,6 +20,8 @@ Gem::Specification.new do |spec|
|
|
|
20
20
|
|
|
21
21
|
spec.add_development_dependency "bundler", "~> 1.3"
|
|
22
22
|
spec.add_development_dependency "rake"
|
|
23
|
-
|
|
24
23
|
spec.add_development_dependency 'rspec'
|
|
25
|
-
|
|
24
|
+
spec.add_development_dependency 'webmock'
|
|
25
|
+
spec.add_development_dependency 'pry'
|
|
26
|
+
spec.add_development_dependency 'awesome_print'
|
|
27
|
+
end
|
data/lib/device_cloud.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
require 'device_cloud/configuration'
|
|
2
2
|
require 'device_cloud/utils'
|
|
3
3
|
require 'device_cloud/version'
|
|
4
|
+
require 'device_cloud/monitor'
|
|
4
5
|
require 'device_cloud/push_notification'
|
|
5
6
|
require 'device_cloud/push_notification/base_notification'
|
|
6
7
|
require 'device_cloud/push_notification/alert_notification'
|
|
@@ -8,8 +9,11 @@ require 'device_cloud/push_notification/event_notification'
|
|
|
8
9
|
require 'device_cloud/push_notification/data_notification'
|
|
9
10
|
require 'device_cloud/push_notification/message'
|
|
10
11
|
require 'device_cloud/push_notification/message/file_data'
|
|
12
|
+
require 'device_cloud/request'
|
|
13
|
+
require 'device_cloud/response'
|
|
11
14
|
|
|
12
15
|
module DeviceCloud
|
|
13
16
|
extend Configuration
|
|
14
17
|
extend Utils
|
|
15
|
-
end
|
|
18
|
+
class Error < StandardError; end
|
|
19
|
+
end
|
|
@@ -3,9 +3,6 @@ require 'logger'
|
|
|
3
3
|
module DeviceCloud
|
|
4
4
|
module Configuration
|
|
5
5
|
|
|
6
|
-
# DeviceCloud account root_url
|
|
7
|
-
attr_writer :root_url
|
|
8
|
-
|
|
9
6
|
# DeviceCloud account username
|
|
10
7
|
attr_writer :username
|
|
11
8
|
|
|
@@ -53,11 +50,12 @@ module DeviceCloud
|
|
|
53
50
|
#
|
|
54
51
|
# Example:
|
|
55
52
|
#
|
|
56
|
-
#
|
|
53
|
+
# DeviceCloud.configure do |configuration|
|
|
57
54
|
# configuration.root_url = 'https://example.com'
|
|
58
55
|
# end
|
|
59
56
|
def configure
|
|
60
57
|
yield self
|
|
58
|
+
config
|
|
61
59
|
end
|
|
62
60
|
|
|
63
61
|
def config
|
|
@@ -65,6 +63,7 @@ module DeviceCloud
|
|
|
65
63
|
username: username,
|
|
66
64
|
password: password,
|
|
67
65
|
root_url: root_url,
|
|
66
|
+
host: host,
|
|
68
67
|
alert_notification_handler: @alert_notification_handler,
|
|
69
68
|
empty_alert_notification_handler: @empty_alert_notification_handler,
|
|
70
69
|
data_notification_handler: @data_notification_handler,
|
|
@@ -77,16 +76,23 @@ module DeviceCloud
|
|
|
77
76
|
|
|
78
77
|
# DeviceCloud url
|
|
79
78
|
#
|
|
80
|
-
# @return the DeviceCloud url
|
|
79
|
+
# @return the DeviceCloud url - 'https://my.idigi.com'
|
|
81
80
|
def root_url
|
|
82
|
-
|
|
81
|
+
'https://my.idigi.com'
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# DeviceCloud url
|
|
85
|
+
#
|
|
86
|
+
# @return the DeviceCloud host - 'my.idigi.com'
|
|
87
|
+
def host
|
|
88
|
+
'my.idigi.com'
|
|
83
89
|
end
|
|
84
90
|
|
|
85
91
|
# DeviceCloud username
|
|
86
92
|
#
|
|
87
93
|
# @return the DeviceCloud username or raises an error
|
|
88
94
|
def username
|
|
89
|
-
raise 'DeviceCloud username is blank' if @username.
|
|
95
|
+
raise 'DeviceCloud username is blank' if @username.nil? || @password == ''
|
|
90
96
|
@username
|
|
91
97
|
end
|
|
92
98
|
|
|
@@ -94,7 +100,7 @@ module DeviceCloud
|
|
|
94
100
|
#
|
|
95
101
|
# @return the DeviceCloud password or raises an error
|
|
96
102
|
def password
|
|
97
|
-
raise 'DeviceCloud password is blank' if @password.
|
|
103
|
+
raise 'DeviceCloud password is blank' if @password.nil? || @password == ''
|
|
98
104
|
@password
|
|
99
105
|
end
|
|
100
106
|
|
|
@@ -105,4 +111,4 @@ module DeviceCloud
|
|
|
105
111
|
@logger ||= Logger.new(STDOUT)
|
|
106
112
|
end
|
|
107
113
|
end
|
|
108
|
-
end
|
|
114
|
+
end
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
module DeviceCloud
|
|
2
|
+
class Monitor
|
|
3
|
+
attr_accessor :monId, :cstId, :monLastConnect, :monLastSent, :monTopic, :monTransportType, :monTransportToken, :monTransportUrl, :monFormatType, :monBatchSize, :monCompression, :monStatus, :monBatchDuration, :monAutoReplayOnConnect, :monLastSentUuid
|
|
4
|
+
attr_reader :error
|
|
5
|
+
|
|
6
|
+
DEFAULT_CREATE_OPTIONS = {
|
|
7
|
+
'monTransportType' => 'http',
|
|
8
|
+
'monTransportUrl' => "http://www.example.com/push_notifications",
|
|
9
|
+
'monTransportToken' => "USERNAME:PASSWORD",
|
|
10
|
+
'monFormatType' => 'json',
|
|
11
|
+
'monBatchSize' => '1',
|
|
12
|
+
'monCompression' => 'none',
|
|
13
|
+
'monBatchDuration' => '0',
|
|
14
|
+
'monAutoReplayOnConnect' => 'true'
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
class << self
|
|
18
|
+
def all
|
|
19
|
+
monitors = DeviceCloud::Request.new(path: '/ws/Monitor/.json').get.to_hash_from_json
|
|
20
|
+
|
|
21
|
+
return [] unless monitors['resultSize'].to_i > 0
|
|
22
|
+
|
|
23
|
+
monitors['items'].map { |monitor|
|
|
24
|
+
Monitor.new monitor
|
|
25
|
+
}
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def find(monitor_id)
|
|
29
|
+
monitors = DeviceCloud::Request.new(path: "/ws/Monitor/#{monitor_id}.json").get.to_hash_from_json
|
|
30
|
+
|
|
31
|
+
return nil unless monitors['resultSize'].to_i > 0
|
|
32
|
+
|
|
33
|
+
Monitor.new monitors['items'].first
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def initialize(attributes = {})
|
|
38
|
+
attributes.each do |name, value|
|
|
39
|
+
send("#{name}=", value)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
@error = nil
|
|
43
|
+
|
|
44
|
+
set_defaults
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def persist!
|
|
48
|
+
@error = nil
|
|
49
|
+
monId.nil? ? create : update
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def reset!
|
|
53
|
+
@error = nil
|
|
54
|
+
if monId.nil?
|
|
55
|
+
@error = 'monId is nil'
|
|
56
|
+
return false
|
|
57
|
+
else
|
|
58
|
+
reset_monitor!
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def destroy!
|
|
63
|
+
return false if monId.nil?
|
|
64
|
+
|
|
65
|
+
response = DeviceCloud::Request.new(path: "/ws/Monitor/#{monId}").delete
|
|
66
|
+
|
|
67
|
+
response.code == '200' ? true : false
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def attributes
|
|
71
|
+
{
|
|
72
|
+
'monTopic' => monTopic,
|
|
73
|
+
'monTransportType' => monTransportType,
|
|
74
|
+
'monTransportToken' => monTransportToken,
|
|
75
|
+
'monTransportUrl' => monTransportUrl,
|
|
76
|
+
'monFormatType' => monFormatType,
|
|
77
|
+
'monBatchSize' => monBatchSize,
|
|
78
|
+
'monCompression' => monCompression,
|
|
79
|
+
'monBatchDuration' => monBatchDuration,
|
|
80
|
+
'monAutoReplayOnConnect' => monAutoReplayOnConnect
|
|
81
|
+
}
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
private
|
|
85
|
+
def set_defaults
|
|
86
|
+
DEFAULT_CREATE_OPTIONS.each do |option, value|
|
|
87
|
+
send("#{option}=", value) if attributes[:option].nil?
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def create
|
|
92
|
+
response = DeviceCloud::Request.new(path: '/ws/Monitor', body: to_xml).post
|
|
93
|
+
if response.code == '201'
|
|
94
|
+
self.monId = response.headers['location'][0].sub(/Monitor\//, '')
|
|
95
|
+
return true
|
|
96
|
+
else
|
|
97
|
+
@error = error_from_response_xml(response)
|
|
98
|
+
return false
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def update
|
|
103
|
+
response = DeviceCloud::Request.new(path: "/ws/Monitor/#{monId}", body: to_xml).put
|
|
104
|
+
|
|
105
|
+
if response.code == '200'
|
|
106
|
+
return true
|
|
107
|
+
else
|
|
108
|
+
@error = error_from_response_xml(response)
|
|
109
|
+
return false
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def reset_monitor!
|
|
114
|
+
response = DeviceCloud::Request.new(path: "/ws/Monitor", body: reset_xml).put
|
|
115
|
+
|
|
116
|
+
if response.code == '200'
|
|
117
|
+
return true
|
|
118
|
+
else
|
|
119
|
+
@error = error_from_response_xml(response)
|
|
120
|
+
return false
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def reset_xml
|
|
125
|
+
"<Monitor><monId>#{monId}</monId></Monitor>"
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def to_xml
|
|
129
|
+
xml = '<Monitor>'
|
|
130
|
+
attributes.each do |key,value|
|
|
131
|
+
xml << "<#{key}>#{value}</#{key}>"
|
|
132
|
+
end
|
|
133
|
+
xml << '</Monitor>'
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def error_from_response_xml(response)
|
|
137
|
+
response.body.match(/<error>(.*)<\/error>/)[1]
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
@@ -2,8 +2,8 @@ module DeviceCloud
|
|
|
2
2
|
class PushNotification
|
|
3
3
|
attr_reader :messages
|
|
4
4
|
|
|
5
|
-
def initialize(
|
|
6
|
-
@messages = DeviceCloud::PushNotification::Message.parse_raw_messages(
|
|
5
|
+
def initialize(response_body)
|
|
6
|
+
@messages = DeviceCloud::PushNotification::Message.parse_raw_messages(response_body)
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
def handle_each!
|
|
@@ -20,4 +20,4 @@ module DeviceCloud
|
|
|
20
20
|
DeviceCloud.constantize "DeviceCloud::PushNotification::#{class_name.capitalize}Notification"
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
|
-
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
require 'net/http'
|
|
2
|
+
|
|
3
|
+
module DeviceCloud
|
|
4
|
+
# Public: Used to send Net::HTTP requests.
|
|
5
|
+
#
|
|
6
|
+
# Examples:
|
|
7
|
+
#
|
|
8
|
+
# get_response = DeviceCloud::Request.new("/ws/FileData").get
|
|
9
|
+
# post_response = DeviceCloud::Request.new("/ws/sci").post(data)
|
|
10
|
+
class Request
|
|
11
|
+
attr_reader :path, :body
|
|
12
|
+
|
|
13
|
+
# Public: Create a new instance of Request.
|
|
14
|
+
#
|
|
15
|
+
# path - The path String to use.
|
|
16
|
+
def initialize(options = {})
|
|
17
|
+
@path = options[:path]
|
|
18
|
+
@body = options[:body]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Public: Send a GET request.
|
|
22
|
+
#
|
|
23
|
+
# Returns a DeviceCloud::Response instance.
|
|
24
|
+
def get
|
|
25
|
+
make_request do
|
|
26
|
+
Net::HTTP::Get.new request_uri
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Public: Send a POST request.
|
|
31
|
+
#
|
|
32
|
+
# body
|
|
33
|
+
#
|
|
34
|
+
# Returns a DeviceCloud::Response instance.
|
|
35
|
+
def post
|
|
36
|
+
make_request do
|
|
37
|
+
Net::HTTP::Post.new request_uri
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Public: Send a PUT request.
|
|
42
|
+
#
|
|
43
|
+
# body
|
|
44
|
+
#
|
|
45
|
+
# Returns a DeviceCloud::Response instance.
|
|
46
|
+
def put
|
|
47
|
+
make_request do
|
|
48
|
+
Net::HTTP::Put.new request_uri
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Public: Send a DELETE request.
|
|
53
|
+
#
|
|
54
|
+
# Returns a DeviceCloud::Response instance.
|
|
55
|
+
def delete
|
|
56
|
+
make_request do
|
|
57
|
+
Net::HTTP::Delete.new request_uri
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
private
|
|
62
|
+
def request_uri
|
|
63
|
+
uri.request_uri
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def uri
|
|
67
|
+
@uri ||= URI.parse(DeviceCloud.root_url + path)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def make_request
|
|
71
|
+
Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
|
|
72
|
+
request = yield
|
|
73
|
+
request.basic_auth DeviceCloud.username, DeviceCloud.password
|
|
74
|
+
|
|
75
|
+
DeviceCloud::Response.new http.request(request, body)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module DeviceCloud
|
|
2
|
+
class Response
|
|
3
|
+
attr_reader :code, :message, :headers, :body, :original_response
|
|
4
|
+
|
|
5
|
+
def initialize(http_response)
|
|
6
|
+
@original_response = http_response
|
|
7
|
+
@code = original_response.code
|
|
8
|
+
@message = original_response.message
|
|
9
|
+
@headers = original_response.header.to_hash
|
|
10
|
+
@body = original_response.body
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def to_hash_from_json
|
|
14
|
+
JSON.parse(body)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
data/lib/device_cloud/version.rb
CHANGED
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe DeviceCloud::Monitor do
|
|
4
|
+
|
|
5
|
+
describe '::all' do
|
|
6
|
+
before(:each) do
|
|
7
|
+
stub_request(:get, authenticated_host + '/ws/Monitor/.json').
|
|
8
|
+
with(:headers => {'Accept'=>'*/*', 'User-Agent'=>'Ruby'}).
|
|
9
|
+
to_return(:status => 200, :body => monitors_json, :headers => {})
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
subject { DeviceCloud::Monitor.all }
|
|
13
|
+
|
|
14
|
+
context 'with results' do
|
|
15
|
+
let(:monitors_json) do
|
|
16
|
+
{
|
|
17
|
+
"resultTotalRows" => "1",
|
|
18
|
+
"requestedStartRow" => "0",
|
|
19
|
+
"resultSize" => "1",
|
|
20
|
+
"requestedSize" => "1000",
|
|
21
|
+
"remainingSize" => "0",
|
|
22
|
+
"items" => [
|
|
23
|
+
{
|
|
24
|
+
"monId" => "109012",
|
|
25
|
+
"cstId" => "4044",
|
|
26
|
+
"monLastConnect" => "2014-02-05T18:57:49.603Z",
|
|
27
|
+
"monLastSent" => "2014-02-11T02:38:46.770Z",
|
|
28
|
+
"monTopic" => "[group=Staging]FileData/*.*",
|
|
29
|
+
"monTransportType" => "http",
|
|
30
|
+
"monTransportUrl" => "http://example.com/device_cloud/push_notifications",
|
|
31
|
+
"monFormatType" => "json",
|
|
32
|
+
"monBatchSize" => "1",
|
|
33
|
+
"monCompression" => "none",
|
|
34
|
+
"monStatus" => "ACTIVE",
|
|
35
|
+
"monBatchDuration" => "0",
|
|
36
|
+
"monAutoReplayOnConnect" => "true",
|
|
37
|
+
"monLastSentUuid" => "a18afa9d-92c5-11e3-a346-bc764e1023af"
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
}.to_json
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it { should be_a(Array) }
|
|
44
|
+
its(:size) { should eq 1 }
|
|
45
|
+
its(:first) { should be_a(DeviceCloud::Monitor) }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
context 'with no results' do
|
|
49
|
+
let(:monitors_json) do
|
|
50
|
+
{
|
|
51
|
+
"resultTotalRows"=>"0",
|
|
52
|
+
"requestedStartRow"=>"0",
|
|
53
|
+
"resultSize"=>"0",
|
|
54
|
+
"requestedSize"=>"1000",
|
|
55
|
+
"remainingSize"=>"0",
|
|
56
|
+
"items"=>[]
|
|
57
|
+
}.to_json
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it { should eq [] }
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
describe '::find' do
|
|
65
|
+
before(:each) do
|
|
66
|
+
stub_request(:get, authenticated_host + '/ws/Monitor/123.json').
|
|
67
|
+
with(:headers => {'Accept'=>'*/*', 'User-Agent'=>'Ruby'}).
|
|
68
|
+
to_return(:status => 200, :body => monitor_json, :headers => {})
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
subject { DeviceCloud::Monitor.find 123 }
|
|
72
|
+
|
|
73
|
+
context 'with result' do
|
|
74
|
+
let(:monitor_json) do
|
|
75
|
+
{"resultTotalRows"=>"1",
|
|
76
|
+
"requestedStartRow"=>"0",
|
|
77
|
+
"resultSize"=>"1",
|
|
78
|
+
"requestedSize"=>"1000",
|
|
79
|
+
"remainingSize"=>"0",
|
|
80
|
+
"items"=>
|
|
81
|
+
[{"monId"=>"109012",
|
|
82
|
+
"cstId"=>"4044",
|
|
83
|
+
"monLastConnect"=>"2014-02-05T18:57:49.603Z",
|
|
84
|
+
"monLastSent"=>"2014-02-11T02:54:07.143Z",
|
|
85
|
+
"monTopic"=>"[group=Staging]FileData/*.*",
|
|
86
|
+
"monTransportType"=>"http",
|
|
87
|
+
"monTransportUrl"=>
|
|
88
|
+
"http://example.com/device_cloud/push_notifications",
|
|
89
|
+
"monFormatType"=>"json",
|
|
90
|
+
"monBatchSize"=>"1",
|
|
91
|
+
"monCompression"=>"none",
|
|
92
|
+
"monStatus"=>"ACTIVE",
|
|
93
|
+
"monBatchDuration"=>"0",
|
|
94
|
+
"monAutoReplayOnConnect"=>"true",
|
|
95
|
+
"monLastSentUuid"=>"7b4b2515-92c7-11e3-a346-bc764e1023af"}]}.to_json
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it { should be_a(DeviceCloud::Monitor) }
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
context 'with no results' do
|
|
102
|
+
let(:monitor_json) do
|
|
103
|
+
{"error"=>["GET Monitor error. Error reading Monitor entity id='12123'"]}.to_json
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it { should be_nil }
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
describe '#persist!' do
|
|
111
|
+
context 'when monId is nil' do
|
|
112
|
+
let(:request_body) { new_monitor.send(:to_xml) }
|
|
113
|
+
before(:each) do
|
|
114
|
+
stub_request(:post, authenticated_host + '/ws/Monitor').
|
|
115
|
+
with(:body => request_body,
|
|
116
|
+
:headers => {'Accept'=>'*/*', 'User-Agent'=>'Ruby'}).
|
|
117
|
+
to_return(:status => response_status, :body => response_body, :headers => response_headers)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
subject { new_monitor }
|
|
121
|
+
|
|
122
|
+
context 'when successful' do
|
|
123
|
+
let(:new_monitor) { DeviceCloud::Monitor.new monTopic: 'AlarmStatus' }
|
|
124
|
+
let(:response_body) { "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n<result>\n <location>Monitor/115848</location>\n</result>" }
|
|
125
|
+
let(:response_status) { 201 }
|
|
126
|
+
let(:response_headers) do
|
|
127
|
+
{ 'location' => ['Monitor/1234567'] }
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
its(:persist!) { should be_true }
|
|
132
|
+
|
|
133
|
+
context 'after #persist!' do
|
|
134
|
+
before(:each) { subject.persist! }
|
|
135
|
+
its(:monId) { should_not be_nil }
|
|
136
|
+
its(:error) { should be_nil }
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
context 'when unsuccessful' do
|
|
141
|
+
let(:new_monitor) { DeviceCloud::Monitor.new monTopic: 'Invalid' }
|
|
142
|
+
let(:response_body) { "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n<result>\n <error>POST Monitor error. Invalid request. Invalid monTopic specified</error>\n</result>" }
|
|
143
|
+
let(:response_status) { 400 }
|
|
144
|
+
let(:response_headers) { Hash.new }
|
|
145
|
+
|
|
146
|
+
its(:persist!) { should be_false }
|
|
147
|
+
|
|
148
|
+
context 'after #persist!' do
|
|
149
|
+
before(:each) { subject.persist! }
|
|
150
|
+
its(:monId) { should be_nil }
|
|
151
|
+
its(:error) { should eq "POST Monitor error. Invalid request. Invalid monTopic specified" }
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
context 'when monId is not nil' do
|
|
157
|
+
let(:request_body) { existing_monitor.send(:to_xml) }
|
|
158
|
+
before(:each) do
|
|
159
|
+
stub_request(:put, "https://foouser:barpass@my.idigi.com/ws/Monitor/12345").
|
|
160
|
+
with(:body => request_body,
|
|
161
|
+
:headers => {'Accept'=>'*/*', 'User-Agent'=>'Ruby'}).
|
|
162
|
+
to_return(:status => response_status, :body => response_body, :headers => {})
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
subject { existing_monitor }
|
|
166
|
+
|
|
167
|
+
context 'when successful' do
|
|
168
|
+
let(:existing_monitor) { DeviceCloud::Monitor.new monTopic: 'FileData', monId: 12345 }
|
|
169
|
+
let(:response_body) { "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n<result/>" }
|
|
170
|
+
let(:response_status) { 200 }
|
|
171
|
+
|
|
172
|
+
its(:persist!) { should be_true }
|
|
173
|
+
|
|
174
|
+
context 'after #persist!' do
|
|
175
|
+
before(:each) { subject.persist! }
|
|
176
|
+
its(:error) { should be_nil }
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
context 'when unsuccessful' do
|
|
181
|
+
let(:existing_monitor) { DeviceCloud::Monitor.new monTopic: 'Invalid', monId: 12345 }
|
|
182
|
+
let(:response_body) { "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n<result>\n <error>PUT Monitor error. Invalid request. Invalid monTopic specified</error>\n</result>" }
|
|
183
|
+
let(:response_status) { 400 }
|
|
184
|
+
|
|
185
|
+
its(:persist!) { should be_false }
|
|
186
|
+
|
|
187
|
+
context 'after #persist!' do
|
|
188
|
+
before(:each) { subject.persist! }
|
|
189
|
+
its(:error) { should eq "PUT Monitor error. Invalid request. Invalid monTopic specified" }
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
describe '#destroy!' do
|
|
196
|
+
context 'when monId is nil' do
|
|
197
|
+
its(:destroy!) { should be_false }
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
context 'when monId is not nil' do
|
|
201
|
+
let(:existing_monitor) { DeviceCloud::Monitor.new monId: 12345 }
|
|
202
|
+
before(:each) do
|
|
203
|
+
stub_request(:delete, "https://foouser:barpass@my.idigi.com/ws/Monitor/12345").
|
|
204
|
+
with(:headers => {'Accept'=>'*/*', 'User-Agent'=>'Ruby'}).
|
|
205
|
+
to_return(:status => response_status, :body => response_body, :headers => {})
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
subject { existing_monitor.destroy! }
|
|
209
|
+
|
|
210
|
+
context 'when successful' do
|
|
211
|
+
let(:response_body) { "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n<result>\n <message>1 items deleted</message>\n</result>" }
|
|
212
|
+
let(:response_status) { 200 }
|
|
213
|
+
|
|
214
|
+
it { should be_true }
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
context 'when unsuccessful' do
|
|
218
|
+
let(:response_body) { "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n<result>\n <error>DELETE Monitor error. Invalid request. For input string: \"gigo\"</error>\n</result>" }
|
|
219
|
+
let(:response_status) { 400 }
|
|
220
|
+
|
|
221
|
+
it { should be_false }
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
describe '#reset!' do
|
|
227
|
+
context 'when monId is nil' do
|
|
228
|
+
its(:reset!) { should be_false }
|
|
229
|
+
|
|
230
|
+
context 'after #reset!' do
|
|
231
|
+
before(:each) { subject.reset! }
|
|
232
|
+
|
|
233
|
+
its(:error) { should eq 'monId is nil'}
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
context 'when monId is not nil' do
|
|
238
|
+
before(:each) do
|
|
239
|
+
stub_request(:put, "https://foouser:barpass@my.idigi.com/ws/Monitor").
|
|
240
|
+
with(:body => request_body,
|
|
241
|
+
:headers => {'Accept'=>'*/*', 'User-Agent'=>'Ruby'}).
|
|
242
|
+
to_return(:status => response_status, :body => response_body, :headers => {})
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
context 'when successful' do
|
|
247
|
+
subject { DeviceCloud::Monitor.new monId: 12345 }
|
|
248
|
+
let(:request_body) { '<Monitor><monId>12345</monId></Monitor>'}
|
|
249
|
+
let(:response_body) { "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n<result/>" }
|
|
250
|
+
let(:response_status) { 200 }
|
|
251
|
+
|
|
252
|
+
its(:reset!) { should be_true }
|
|
253
|
+
|
|
254
|
+
context 'after #reset!' do
|
|
255
|
+
before(:each) { subject.reset! }
|
|
256
|
+
|
|
257
|
+
its(:error) { should be_nil }
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
context 'when unsuccessful' do
|
|
262
|
+
subject { DeviceCloud::Monitor.new monId: 1 }
|
|
263
|
+
let(:request_body) { '<Monitor><monId>1</monId></Monitor>' }
|
|
264
|
+
let(:response_body) { "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n<result>\n <error>PUT Monitor error. Error reading Monitor entity id='<monId>1</monId>'</error>\n</result>" }
|
|
265
|
+
let(:response_status) { 400 }
|
|
266
|
+
|
|
267
|
+
its(:reset!) { should be_false }
|
|
268
|
+
|
|
269
|
+
context 'after #reset!' do
|
|
270
|
+
before(:each) { subject.reset! }
|
|
271
|
+
|
|
272
|
+
its(:error) { should eq "PUT Monitor error. Error reading Monitor entity id='<monId>1</monId>'"}
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe DeviceCloud::Request do
|
|
4
|
+
let(:path) { '/the/road/less/travelled' }
|
|
5
|
+
let(:body) { 'badguts' }
|
|
6
|
+
let(:request_uri) { authenticated_host + path }
|
|
7
|
+
|
|
8
|
+
its(:path) { should be_nil }
|
|
9
|
+
its(:body) { should be_nil }
|
|
10
|
+
|
|
11
|
+
context 'when passed options' do
|
|
12
|
+
subject { DeviceCloud::Request.new path: '/boom/boom/boom', body: 'HEYO' }
|
|
13
|
+
|
|
14
|
+
its(:path) { should eq '/boom/boom/boom' }
|
|
15
|
+
its(:body) { should eq 'HEYO' }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe '#get' do
|
|
19
|
+
before(:each) do
|
|
20
|
+
stub_request(:get, request_uri).
|
|
21
|
+
with(:headers => {'Accept'=>'*/*', 'User-Agent'=>'Ruby'}).
|
|
22
|
+
to_return(:status => 200, :body => "", :headers => {})
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
subject { DeviceCloud::Request.new(path: path) }
|
|
26
|
+
|
|
27
|
+
its(:get) { should be_a(DeviceCloud::Response) }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
describe '#post' do
|
|
31
|
+
before(:each) do
|
|
32
|
+
stub_request(:post, request_uri).
|
|
33
|
+
with(:headers => {'Accept'=>'*/*', 'User-Agent'=>'Ruby'}, body: body).
|
|
34
|
+
to_return(:status => 200, :body => "", :headers => {})
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
subject { DeviceCloud::Request.new(path: path, body: body) }
|
|
38
|
+
|
|
39
|
+
its(:post) { should be_a(DeviceCloud::Response) }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
describe '#put' do
|
|
43
|
+
before(:each) do
|
|
44
|
+
stub_request(:put, request_uri).
|
|
45
|
+
with(:headers => {'Accept'=>'*/*', 'User-Agent'=>'Ruby'}, body: body).
|
|
46
|
+
to_return(:status => 200, :body => "", :headers => {})
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
subject { DeviceCloud::Request.new(path: path, body: body) }
|
|
50
|
+
|
|
51
|
+
its(:put) { should be_a(DeviceCloud::Response) }
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
describe '#delete' do
|
|
55
|
+
before(:each) do
|
|
56
|
+
stub_request(:delete, request_uri).
|
|
57
|
+
with(:headers => {'Accept'=>'*/*', 'User-Agent'=>'Ruby'}).
|
|
58
|
+
to_return(:status => 200, :body => "", :headers => {})
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
subject { DeviceCloud::Request.new(path: path) }
|
|
62
|
+
|
|
63
|
+
its(:delete) { should be_a(DeviceCloud::Response) }
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe DeviceCloud::Response do
|
|
4
|
+
let(:headers_hash) do
|
|
5
|
+
{ 'location' => ['here'] }
|
|
6
|
+
end
|
|
7
|
+
let(:header) do
|
|
8
|
+
OpenStruct.new to_hash: headers_hash
|
|
9
|
+
end
|
|
10
|
+
let(:message) { 'OK' }
|
|
11
|
+
let(:code) { 200 }
|
|
12
|
+
let(:body) { 'HEYO' }
|
|
13
|
+
let(:http_response) do
|
|
14
|
+
OpenStruct.new(
|
|
15
|
+
code: code,
|
|
16
|
+
message: message,
|
|
17
|
+
header: header,
|
|
18
|
+
body: body
|
|
19
|
+
)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
subject { DeviceCloud::Response.new http_response }
|
|
23
|
+
|
|
24
|
+
its(:code) { should eq code }
|
|
25
|
+
its(:message) { should eq message }
|
|
26
|
+
its(:body) { should eq body }
|
|
27
|
+
its(:headers) { should eq headers_hash }
|
|
28
|
+
|
|
29
|
+
describe '#to_hash_from_json' do
|
|
30
|
+
context 'when valid JSON' do
|
|
31
|
+
let(:json) do
|
|
32
|
+
{
|
|
33
|
+
'hello' => 'world'
|
|
34
|
+
}
|
|
35
|
+
end
|
|
36
|
+
let(:body) { json.to_json }
|
|
37
|
+
|
|
38
|
+
its(:to_hash_from_json) { should eq json }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
context 'when not valid json' do
|
|
42
|
+
it 'raises an error' do
|
|
43
|
+
expect{ subject.to_hash_from_json }.to raise_error(JSON::ParserError)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,13 +1,28 @@
|
|
|
1
1
|
require 'device_cloud'
|
|
2
2
|
require 'ostruct'
|
|
3
|
+
require 'webmock/rspec'
|
|
4
|
+
require 'pry'
|
|
5
|
+
require 'awesome_print'
|
|
6
|
+
|
|
7
|
+
def idigi_username
|
|
8
|
+
'foouser'
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def idigi_password
|
|
12
|
+
'barpass'
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def authenticated_host
|
|
16
|
+
"https://#{DeviceCloud.username}:#{DeviceCloud.password}@#{DeviceCloud.host}"
|
|
17
|
+
end
|
|
3
18
|
|
|
4
19
|
RSpec.configure do |config|
|
|
5
20
|
config.mock_with :rspec
|
|
6
21
|
|
|
7
22
|
config.before(:each) do
|
|
8
23
|
DeviceCloud.configure do |configuration|
|
|
9
|
-
configuration.username =
|
|
10
|
-
configuration.password =
|
|
24
|
+
configuration.username = idigi_username
|
|
25
|
+
configuration.password = idigi_password
|
|
11
26
|
end
|
|
12
27
|
end
|
|
13
|
-
end
|
|
28
|
+
end
|
data/spec/version_spec.rb
CHANGED
data/wercker.yml
ADDED
metadata
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: device_cloud
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
5
|
-
prerelease:
|
|
4
|
+
version: 0.2.4
|
|
6
5
|
platform: ruby
|
|
7
6
|
authors:
|
|
8
7
|
- Erik Straub
|
|
9
8
|
autorequire:
|
|
10
9
|
bindir: bin
|
|
11
10
|
cert_chain: []
|
|
12
|
-
date:
|
|
11
|
+
date: 2014-09-02 00:00:00.000000000 Z
|
|
13
12
|
dependencies:
|
|
14
13
|
- !ruby/object:Gem::Dependency
|
|
15
14
|
name: bundler
|
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
|
17
|
-
none: false
|
|
18
16
|
requirements:
|
|
19
17
|
- - ~>
|
|
20
18
|
- !ruby/object:Gem::Version
|
|
@@ -22,7 +20,6 @@ dependencies:
|
|
|
22
20
|
type: :development
|
|
23
21
|
prerelease: false
|
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
-
none: false
|
|
26
23
|
requirements:
|
|
27
24
|
- - ~>
|
|
28
25
|
- !ruby/object:Gem::Version
|
|
@@ -30,7 +27,6 @@ dependencies:
|
|
|
30
27
|
- !ruby/object:Gem::Dependency
|
|
31
28
|
name: rake
|
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
|
33
|
-
none: false
|
|
34
30
|
requirements:
|
|
35
31
|
- - ! '>='
|
|
36
32
|
- !ruby/object:Gem::Version
|
|
@@ -38,7 +34,6 @@ dependencies:
|
|
|
38
34
|
type: :development
|
|
39
35
|
prerelease: false
|
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
41
|
-
none: false
|
|
42
37
|
requirements:
|
|
43
38
|
- - ! '>='
|
|
44
39
|
- !ruby/object:Gem::Version
|
|
@@ -46,7 +41,6 @@ dependencies:
|
|
|
46
41
|
- !ruby/object:Gem::Dependency
|
|
47
42
|
name: rspec
|
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
|
49
|
-
none: false
|
|
50
44
|
requirements:
|
|
51
45
|
- - ! '>='
|
|
52
46
|
- !ruby/object:Gem::Version
|
|
@@ -54,20 +48,62 @@ dependencies:
|
|
|
54
48
|
type: :development
|
|
55
49
|
prerelease: false
|
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
-
|
|
51
|
+
requirements:
|
|
52
|
+
- - ! '>='
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: webmock
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ! '>='
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ! '>='
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: pry
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - ! '>='
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '0'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - ! '>='
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: awesome_print
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - ! '>='
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
58
93
|
requirements:
|
|
59
94
|
- - ! '>='
|
|
60
95
|
- !ruby/object:Gem::Version
|
|
61
96
|
version: '0'
|
|
62
97
|
description: A Ruby wrapper for the Etherios Device Cloud
|
|
63
98
|
email:
|
|
64
|
-
- erik@
|
|
99
|
+
- erik@madglory.com
|
|
65
100
|
executables: []
|
|
66
101
|
extensions: []
|
|
67
102
|
extra_rdoc_files: []
|
|
68
103
|
files:
|
|
69
104
|
- .gitignore
|
|
70
105
|
- .rspec
|
|
106
|
+
- .ruby-gemset
|
|
71
107
|
- .ruby-version
|
|
72
108
|
- Gemfile
|
|
73
109
|
- LICENSE.txt
|
|
@@ -76,6 +112,7 @@ files:
|
|
|
76
112
|
- device_cloud.gemspec
|
|
77
113
|
- lib/device_cloud.rb
|
|
78
114
|
- lib/device_cloud/configuration.rb
|
|
115
|
+
- lib/device_cloud/monitor.rb
|
|
79
116
|
- lib/device_cloud/push_notification.rb
|
|
80
117
|
- lib/device_cloud/push_notification/alert_notification.rb
|
|
81
118
|
- lib/device_cloud/push_notification/base_notification.rb
|
|
@@ -83,8 +120,11 @@ files:
|
|
|
83
120
|
- lib/device_cloud/push_notification/event_notification.rb
|
|
84
121
|
- lib/device_cloud/push_notification/message.rb
|
|
85
122
|
- lib/device_cloud/push_notification/message/file_data.rb
|
|
123
|
+
- lib/device_cloud/request.rb
|
|
124
|
+
- lib/device_cloud/response.rb
|
|
86
125
|
- lib/device_cloud/utils.rb
|
|
87
126
|
- lib/device_cloud/version.rb
|
|
127
|
+
- spec/device_cloud/monitor_spec.rb
|
|
88
128
|
- spec/device_cloud/push_notification/alert_notification_spec.rb
|
|
89
129
|
- spec/device_cloud/push_notification/base_notification_spec.rb
|
|
90
130
|
- spec/device_cloud/push_notification/data_notification_spec.rb
|
|
@@ -92,34 +132,37 @@ files:
|
|
|
92
132
|
- spec/device_cloud/push_notification/message/file_data_spec.rb
|
|
93
133
|
- spec/device_cloud/push_notification/message_spec.rb
|
|
94
134
|
- spec/device_cloud/push_notification_spec.rb
|
|
135
|
+
- spec/device_cloud/request_spec.rb
|
|
136
|
+
- spec/device_cloud/response_spec.rb
|
|
95
137
|
- spec/spec_helper.rb
|
|
96
138
|
- spec/version_spec.rb
|
|
97
|
-
|
|
139
|
+
- wercker.yml
|
|
140
|
+
homepage: http://github.com/madglory/device_cloud
|
|
98
141
|
licenses:
|
|
99
142
|
- MIT
|
|
143
|
+
metadata: {}
|
|
100
144
|
post_install_message:
|
|
101
145
|
rdoc_options: []
|
|
102
146
|
require_paths:
|
|
103
147
|
- lib
|
|
104
148
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
105
|
-
none: false
|
|
106
149
|
requirements:
|
|
107
150
|
- - ! '>='
|
|
108
151
|
- !ruby/object:Gem::Version
|
|
109
152
|
version: '0'
|
|
110
153
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
111
|
-
none: false
|
|
112
154
|
requirements:
|
|
113
155
|
- - ! '>='
|
|
114
156
|
- !ruby/object:Gem::Version
|
|
115
157
|
version: '0'
|
|
116
158
|
requirements: []
|
|
117
159
|
rubyforge_project:
|
|
118
|
-
rubygems_version:
|
|
160
|
+
rubygems_version: 2.2.1
|
|
119
161
|
signing_key:
|
|
120
|
-
specification_version:
|
|
162
|
+
specification_version: 4
|
|
121
163
|
summary: A Ruby wrapper for the Etherios Device Cloud
|
|
122
164
|
test_files:
|
|
165
|
+
- spec/device_cloud/monitor_spec.rb
|
|
123
166
|
- spec/device_cloud/push_notification/alert_notification_spec.rb
|
|
124
167
|
- spec/device_cloud/push_notification/base_notification_spec.rb
|
|
125
168
|
- spec/device_cloud/push_notification/data_notification_spec.rb
|
|
@@ -127,5 +170,7 @@ test_files:
|
|
|
127
170
|
- spec/device_cloud/push_notification/message/file_data_spec.rb
|
|
128
171
|
- spec/device_cloud/push_notification/message_spec.rb
|
|
129
172
|
- spec/device_cloud/push_notification_spec.rb
|
|
173
|
+
- spec/device_cloud/request_spec.rb
|
|
174
|
+
- spec/device_cloud/response_spec.rb
|
|
130
175
|
- spec/spec_helper.rb
|
|
131
176
|
- spec/version_spec.rb
|