shove 1.0.5 → 1.0.7

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/Gemfile CHANGED
@@ -9,9 +9,12 @@ end
9
9
 
10
10
  group :test do
11
11
  gem "rspec"
12
- gem "vcr", "2.0.0.rc1"
12
+ gem "vcr", "2.0.1"
13
13
  gem "webmock"
14
14
  gem "net-http-spy"
15
15
  end
16
16
 
17
- gemspec
17
+ gem "em-http-request", ">= 1.0.0"
18
+ gem "em-ws-client", ">= 0.2.0"
19
+ gem "yajl-ruby", ">= 1.1.0"
20
+ gem "confstruct", ">= 0.2.1"
data/Gemfile.lock CHANGED
@@ -1,12 +1,3 @@
1
- PATH
2
- remote: .
3
- specs:
4
- shove (1.0.4)
5
- confstruct (>= 0.2.1)
6
- em-http-request (>= 1.0.0)
7
- em-ws-client (>= 0.1.2)
8
- yajl-ruby (>= 1.1.0)
9
-
10
1
  GEM
11
2
  remote: http://rubygems.org/
12
3
  specs:
@@ -25,9 +16,8 @@ GEM
25
16
  http_parser.rb (>= 0.5.3)
26
17
  em-socksify (0.2.0)
27
18
  eventmachine (>= 1.0.0.beta.4)
28
- em-ws-client (0.1.2)
19
+ em-ws-client (0.2.0)
29
20
  eventmachine (~> 1.0.0.beta.4)
30
- state_machine (~> 1.0.2)
31
21
  eventmachine (1.0.0.beta.4)
32
22
  http_parser.rb (0.5.3)
33
23
  net-http-spy (0.2.1)
@@ -42,8 +32,7 @@ GEM
42
32
  rspec-expectations (2.9.1)
43
33
  diff-lcs (~> 1.1.3)
44
34
  rspec-mocks (2.9.0)
45
- state_machine (1.0.3)
46
- vcr (2.0.0.rc1)
35
+ vcr (2.0.1)
47
36
  webmock (1.8.6)
48
37
  addressable (>= 2.2.7)
49
38
  crack (>= 0.1.7)
@@ -54,10 +43,13 @@ PLATFORMS
54
43
 
55
44
  DEPENDENCIES
56
45
  albino
46
+ confstruct (>= 0.2.1)
47
+ em-http-request (>= 1.0.0)
48
+ em-ws-client (>= 0.2.0)
57
49
  net-http-spy
58
50
  rake
59
51
  redcarpet
60
52
  rspec
61
- shove!
62
- vcr (= 2.0.0.rc1)
53
+ vcr (= 2.0.1)
63
54
  webmock
55
+ yajl-ruby (>= 1.1.0)
data/README.markdown CHANGED
@@ -2,6 +2,7 @@ shove ruby client
2
2
  =================
3
3
  Ruby client and CLI for the shove.io HTTP and WebSocket APIs
4
4
 
5
+ <a name="installation"></a>
5
6
  Installation
6
7
  ------------
7
8
 
@@ -9,8 +10,7 @@ Installation
9
10
  gem install shove
10
11
  ```
11
12
 
12
- Grab your App ID and App Key from shove at [https://shove.io/apps][0]
13
-
13
+ <a name="configuration"></a>
14
14
  Configuring Shove
15
15
  -----------------
16
16
 
@@ -34,96 +34,136 @@ app = Shove::App.new do
34
34
  end
35
35
  ```
36
36
 
37
+ Grab your App ID and App Key from shove: [https://shove.io][0]
38
+
39
+ <a name="http_client"></a>
37
40
  Using the HTTP Client
38
41
  ---------------------
39
42
  The HTTP client gives publishing and access control capabilities without
40
- a persistent WebSocket connection
43
+ a persistent WebSocket connection. The HTTP client does not act as a subscriber.
41
44
 
42
- Publish "Hello World!" to all connections on the notifications channel
45
+ Simple Publish
43
46
 
44
47
  ```ruby
45
- Shove.channel("notifications").publish("Hello World!") do |response|
46
- # handle response
47
- end
48
+ Shove.channel("notifications").publish("Hello World!")
48
49
  ```
49
50
 
50
- Publish "Hey buddy" to the client with id buddy.
51
+ Publish Direct
51
52
 
52
53
  ```ruby
53
- Shove.channel("direct:buddy").publish("Hey buddy") do |response|
54
- # handle response
55
- end
54
+ Shove.channel("direct:buddy").publish("Hey buddy")
56
55
  ```
57
56
 
58
- Apps, channels, and clients can be controlled from the HTTP API
59
-
60
- Grant a connection to dan@shove.io
57
+ Publish and handle the HTTP response
61
58
 
62
59
  ```ruby
63
- Shove.grant_connect("dan@shove.io") do |response|
64
- # handle response
60
+ Shove.channel("notifications").publish("...") do |response|
61
+ if reponse.error?
62
+ puts "#{response.status} - #{response.error}"
63
+ end
65
64
  end
66
65
  ```
67
66
 
68
- Grant subscription on the notifications channel to client dan
67
+ You can control access to your apps and channels, allowing for
68
+ granular security.
69
+
70
+ Grant subscription on the notifications channel
69
71
 
70
72
  ```ruby
71
- Shove.channel("notifications").grant_subscribe("dan") do |response|
72
- # handle response
73
- end
73
+ Shove.channel("notifications").grant_subscribe("dan@shove.io")
74
74
  ```
75
75
 
76
76
  Grant subscription on all channels to client dan
77
77
 
78
78
  ```ruby
79
- Shove.channel("*").grant_subscribe("dan@shove.io") do |response|
80
- # handle response
81
- end
79
+ Shove.channel("*").grant_subscribe("dan@shove.io")
82
80
  ```
83
81
 
84
82
  Grant publishing on chat:client_22733 channel to client dan
85
83
 
86
84
  ```ruby
87
- Shove.channel("chat:client_22733").grant_publish("dan") do |response|
88
- # handle response
89
- end
85
+ Shove.channel("chat:client_22733").grant_publish("dan")
90
86
  ```
91
87
 
92
88
  Deny publishing on chat:client_22733 channel to dan
93
89
 
94
90
  ```ruby
95
- Shove.channel("chat:client_22733").deny_publish("dan") do |response|
96
- # handle response
97
- end
91
+ Shove.channel("chat:client_22733").deny_publish("dan")
98
92
  ```
99
93
 
100
- Using the WebSocket Client
101
- --------------------------
94
+ Sometimes it's easier to give out an access key to a specific
95
+ channel, which is also an option.
96
+
97
+ <a name="channel_keys"></a>
98
+ Channel Keys
99
+ ------------
100
+ You can generate channel keys which allow clients of
101
+ your shove network to publish and subscribe to specific
102
+ channels.
102
103
 
103
- Create a WebSocket client on the default app
104
+ Example: Create a key for the channel groups:788
104
105
 
105
106
  ```ruby
106
- client = Shove.app.connect
107
+ key = Shove.channel_key "group:788"
107
108
  ```
108
109
 
109
- Or
110
+ If it's for a particular App, use:
110
111
 
111
112
  ```ruby
112
- app = Shove::App.new do
113
- app_id "myappid"
113
+ key = app.channel_key "group:788"
114
+ ```
115
+
116
+ This functionality becomes useful when you want to give
117
+ you site users access. A little haml for you:
118
+
119
+ ```haml
120
+ :javascript
121
+ var channel = "#{@channel}";
122
+ var key = "#{@shove.channel_key(@channel)}";
123
+ ```
124
+
125
+ Note: Channel keys are based off the app key. So, in order for
126
+ them to work, you must specify the app key:
127
+
128
+ ```ruby
129
+ Shove.configure do
130
+ app_key "key"
131
+ end
132
+ ```
133
+
134
+ <a name="websocket_client"></a>
135
+ Using the WebSocket Client
136
+ --------------------------
137
+ You can also use the gem to run a persistent client. This
138
+ requires that you are running an EventMachine reactor.
139
+
140
+ ```ruby
141
+ EM.run do
142
+ app = Shove::App.new do
143
+ app_id "myapp"
144
+ end
145
+
146
+ app.connect
147
+
148
+ # alternatively, supply your user id
149
+ client = app.connect "unique_id"
114
150
  end
115
- client = app.connect
116
151
  ```
117
152
 
118
- Create a client with a custom ID
153
+ ### Authorization
154
+ The client is treated like any other websocket
155
+ client and must be authorized to publish and subscribe.
119
156
 
120
157
  ```ruby
121
- client = Shove.app.connect("unique_id")
158
+ client.authorize "app_key"
159
+
160
+ # self authorize a particular channel
161
+ client.channel("channel").authorize "channel_key"
122
162
  ```
123
163
 
124
164
  ### Client events
125
165
 
126
- Handle connect event
166
+ Connect event:
127
167
 
128
168
  ```ruby
129
169
  client.on("connect") do
@@ -131,34 +171,31 @@ client.on("connect") do
131
171
  end
132
172
  ```
133
173
 
134
- Handle connect denies (private app)
174
+ Disconnect event:
135
175
 
136
176
  ```ruby
137
- client.on("connect_denied") do |id|
138
- # Silly, but:
139
- Shove.client(id).grant_connect do |response|
140
- # At this point, the client should receive
141
- # a connect event (through the shove app)
142
- end
177
+ client.on("disconnect") do
178
+ # disconnect code
143
179
  end
144
180
  ```
145
181
 
146
- And disconnect events
182
+ Error event:
147
183
 
148
184
  ```ruby
149
- client.on("disconnect") do
185
+ client.on("error") do |error|
186
+ log.error "Shove error: #{error}"
150
187
  end
151
188
  ```
152
189
 
153
- If there is any kind of error, log it
190
+ Connect denied event: (don't forget to authorize)
154
191
 
155
192
  ```ruby
156
- client.on("error") do |error|
157
- log.error "Shove error: #{error}"
193
+ client.on("connect_denied") do |id|
194
+ client.authorize
158
195
  end
159
196
  ```
160
197
 
161
- ### Clients and Channels
198
+ ### Publish and Subscribe
162
199
 
163
200
  Subscribe to a channel or get a subscribed channel
164
201
 
@@ -187,8 +224,8 @@ handle the subscribe_denied event
187
224
 
188
225
  ```ruby
189
226
  channel.on("subscribe_denied") do
190
- # Silly example
191
- Shove.client(client.id).grant_subscribe(channel.name)
227
+ channel.authorize "key"
228
+ channel.subscribe
192
229
  end
193
230
  ```
194
231
 
@@ -196,6 +233,7 @@ You can get the binding for a callback and cancel it
196
233
 
197
234
  ```ruby
198
235
  binding = channel.on("message") do |msg|
236
+ # important stuff here
199
237
  end
200
238
 
201
239
  binding.cancel
@@ -227,27 +265,6 @@ channel.publish("hi!")
227
265
  channel.publish(obj.to_json)
228
266
  ```
229
267
 
230
- Channel Keys
231
- ------------
232
- You can generate channel keys which allow clients of
233
- your shove network to publish and subscribe to specific
234
- channels.
235
-
236
- Example: Create a key for the channel groups:788
237
-
238
- ```ruby
239
- key = Shove.channel_key "group:788"
240
- ```
241
-
242
- If it's for a particular App, use:
243
-
244
- ```ruby
245
- key = app.channel_key "group:788"
246
- ```
247
-
248
- Note: if you don't have the app key speficied for the app, the
249
- channel key generated will not be correct.
250
-
251
268
  Using the Command Line
252
269
  ----------------------
253
270
 
@@ -281,5 +298,5 @@ Watch all activity on a channel
281
298
  shove watch -c chan
282
299
  ```
283
300
 
284
- [0]: https://shove.io/apps
285
- [1]: http://shove.io/documentation/cli
301
+ [0]: https://shove.io
302
+ [1]: https://shove.io
@@ -1,4 +1,3 @@
1
-
2
1
  module Shove
3
2
 
4
3
  # Used for storing and accessing shove credentials
@@ -10,8 +10,9 @@ module Shove
10
10
  # +name+ The name of the channel
11
11
  def initialize name, conn
12
12
  @conn = conn
13
- @name = name
13
+ @name = name.to_s
14
14
  @callbacks = {}
15
+ @subscribe_sent = false
15
16
  end
16
17
 
17
18
  # Bind a block to an event
@@ -23,6 +24,11 @@ module Shove
23
24
  end
24
25
  result = Callback.new(@callbacks[event], block)
25
26
  @callbacks[event] << result
27
+
28
+ if @name != "direct" && !@subscribe_sent
29
+ subscribe
30
+ end
31
+
26
32
  result
27
33
  end
28
34
 
@@ -46,6 +52,10 @@ module Shove
46
52
  when UNSUBSCRIBE_COMPLETE
47
53
  emit("unsubscribe")
48
54
  @callbacks.clear
55
+ when AUTHORIZE_DENIED
56
+ emit("authorize_denied")
57
+ when AUTHORIZE_COMPLETE
58
+ emit("authorize_complete")
49
59
  end
50
60
 
51
61
  end
@@ -59,6 +69,7 @@ module Shove
59
69
  # subscribe to the channel, by sending to the remote
60
70
  def subscribe
61
71
  @conn.send_data :opcode => SUBSCRIBE, :channel => @name
72
+ @subscribe_sent = true
62
73
  end
63
74
 
64
75
  # unsubscribe from the channel
@@ -68,7 +79,7 @@ module Shove
68
79
 
69
80
  # authorize pub/sub on this channel
70
81
  def authorize channel_key
71
- @conn.send_data :opcode => AUTHORIZE, :channel => @name, :data => channel_key
82
+ @conn.send_data :opcode => AUTHORIZE, :channel => @name, :data => channel_key.to_s
72
83
  end
73
84
 
74
85
  private
@@ -39,6 +39,14 @@ module Shove
39
39
  end
40
40
 
41
41
  @socket = EM::WebSocketClient.new(url)
42
+
43
+ @socket.onclose do
44
+ @connected = false
45
+ unless @forcedc
46
+ reconnect
47
+ end
48
+ end
49
+
42
50
  @socket.onopen do
43
51
  @connected = true
44
52
  send_data :opcode => CONNECT, :data => @id
@@ -46,23 +54,17 @@ module Shove
46
54
  send_data @queue.shift
47
55
  end
48
56
  end
49
-
50
- @socket.onmessage do |m|
51
- process Yajl::Parser.parse(m)
52
- end
53
57
 
54
- @socket.onclose do
55
- @connected = false
56
- unless @forcedc
57
- reconnect
58
- end
58
+ @socket.onmessage do |m, binary|
59
+ process(Yajl::Parser.parse(m))
59
60
  end
61
+
60
62
  end
61
63
 
62
64
  # Disconnect form the server
63
65
  def disconnect
64
66
  @forcedc = true
65
- @socket.disconnect
67
+ @socket.unbind
66
68
  end
67
69
 
68
70
  # Bind to events for a given channel.
@@ -81,9 +83,6 @@ module Shove
81
83
  def channel name
82
84
  unless @channels.key?(name)
83
85
  @channels[name] = Channel.new(name, self)
84
- if name != "direct"
85
- @channels[name].subscribe
86
- end
87
86
  end
88
87
  @channels[name]
89
88
  end
@@ -102,7 +101,7 @@ module Shove
102
101
 
103
102
  def send_data data
104
103
  if @connected
105
- @socket.send_data(Yajl::Encoder.encode(data))
104
+ @socket.send_message(Yajl::Encoder.encode(data))
106
105
  else
107
106
  @queue << data
108
107
  end
@@ -157,8 +156,18 @@ module Shove
157
156
  @closing = true
158
157
  emit "disconnecting"
159
158
  when AUTHORIZE_COMPLETE
159
+ if @channels.key?(channel)
160
+ @channels[channel].process(message)
161
+ else
162
+ emit "authorize_complete"
163
+ end
164
+ when AUTHORIZE_DENIED
165
+ if @channels.key?(channel)
166
+ @channels[channel].process(message)
167
+ else
168
+ emit "authorize_denied"
169
+ end
160
170
  else
161
- #TODO: logger
162
171
  puts "Unknown opcode"
163
172
  end
164
173
 
@@ -13,7 +13,7 @@ module Shove
13
13
  # +message+ the message to publish
14
14
  # +block+ called on response
15
15
  def publish message, &block
16
- @app.request("publish?channel=direct:#{@id}").post(message, &block)
16
+ @app.request("publish?channel=direct:#{@id}").post(message.to_s, &block)
17
17
  end
18
18
 
19
19
  # grant connection to client
data/lib/shove.rb CHANGED
@@ -13,12 +13,12 @@ require "digest/sha1"
13
13
  ##
14
14
  # Shove
15
15
  #
16
- # See http://shove.io for an account and client documentation
16
+ # See https://shove.io for an account and client documentation
17
17
  # See https://github.com/shove/shove-ruby for gem documentation
18
- # See https://github.com/shove/shove for client documentation
18
+ # See https://github.com/shove/shove for js client documentation
19
19
  module Shove
20
20
 
21
- Version = "1.0.5"
21
+ Version = "1.0.7"
22
22
 
23
23
  class ShoveException < Exception; end
24
24
 
data/shove.gemspec CHANGED
@@ -12,7 +12,7 @@ spec = Gem::Specification.new do |s|
12
12
  s.has_rdoc = true
13
13
 
14
14
  s.add_dependency("em-http-request", ">= 1.0.0")
15
- s.add_dependency("em-ws-client", ">= 0.1.2")
15
+ s.add_dependency("em-ws-client", ">= 0.2.0")
16
16
  s.add_dependency("yajl-ruby", ">= 1.1.0")
17
17
  s.add_dependency("confstruct", ">= 0.2.1")
18
18
 
data/spec/helper.rb CHANGED
@@ -49,13 +49,17 @@ module EM
49
49
  @onopen = block
50
50
  end
51
51
 
52
+ def onclose &block
53
+ @onclose = block
54
+ end
55
+
52
56
  def onmessage &block
53
57
  @onmessage = block
54
58
  $backdoor = block
55
59
  @onopen.call # called
56
60
  end
57
61
 
58
- def send_data data
62
+ def send_message data
59
63
  $queue << Yajl::Parser.parse(data)
60
64
  end
61
65
 
@@ -105,8 +105,10 @@ describe Shove::Client do
105
105
  it "should subscribe to a channel" do
106
106
  @client = Shove.app.connect
107
107
  @channel = @client.channel("channel")
108
- @message = $queue.last
109
- @message["opcode"].should == Shove::Protocol::SUBSCRIBE
108
+ $queue.last["opcode"].should_not == Shove::Protocol::SUBSCRIBE
109
+ @channel.on("message") do
110
+ end
111
+ $queue.last["opcode"].should == Shove::Protocol::SUBSCRIBE
110
112
  end
111
113
 
112
114
  it "should get a subscribe granted event" do
@@ -207,6 +209,14 @@ describe Shove::Client do
207
209
  item["data"].should == "key"
208
210
  item["channel"].should == "channel"
209
211
 
212
+ @triggered = false
213
+ @channel.on("authorize_complete") do
214
+ @triggered = true
215
+ end
216
+
217
+ backdoor :opcode => Shove::Protocol::AUTHORIZE_COMPLETE, :channel => "channel"
218
+
219
+ @triggered.should == true
210
220
  end
211
221
 
212
222
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shove
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.5
4
+ version: 1.0.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2012-02-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: em-http-request
16
- requirement: &70156622099200 !ruby/object:Gem::Requirement
16
+ requirement: &21823400 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,21 +21,21 @@ dependencies:
21
21
  version: 1.0.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70156622099200
24
+ version_requirements: *21823400
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: em-ws-client
27
- requirement: &70156622110300 !ruby/object:Gem::Requirement
27
+ requirement: &21822160 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
31
31
  - !ruby/object:Gem::Version
32
- version: 0.1.2
32
+ version: 0.2.0
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70156622110300
35
+ version_requirements: *21822160
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: yajl-ruby
38
- requirement: &70156622116560 !ruby/object:Gem::Requirement
38
+ requirement: &21820560 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 1.1.0
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70156622116560
46
+ version_requirements: *21820560
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: confstruct
49
- requirement: &70156622111420 !ruby/object:Gem::Requirement
49
+ requirement: &21819840 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,7 +54,7 @@ dependencies:
54
54
  version: 0.2.1
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70156622111420
57
+ version_requirements: *21819840
58
58
  description: Client side implementation for the shove.io API. See http://shove.io/documentation
59
59
  email: dan@shove.io
60
60
  executables:
@@ -144,44 +144,4 @@ rubygems_version: 1.8.11
144
144
  signing_key:
145
145
  specification_version: 3
146
146
  summary: Ruby gem for leveraging shove.io, the web push platform
147
- test_files:
148
- - spec/app_directory_spec.rb
149
- - spec/cassettes/should_authorize_on_a_channel.yml
150
- - spec/cassettes/should_authorize_oneself.yml
151
- - spec/cassettes/should_be_able_to_authorize_with_the_server.yml
152
- - spec/cassettes/should_cancel_a_binding.yml
153
- - spec/cassettes/should_configure_the_default.yml
154
- - spec/cassettes/should_configure_the_from_the_previous_test.yml
155
- - spec/cassettes/should_create_a_channel_context.yml
156
- - spec/cassettes/should_deny_a_connection.yml
157
- - spec/cassettes/should_deny_a_control_to_a_client.yml
158
- - spec/cassettes/should_deny_a_publishing_to_a_client.yml
159
- - spec/cassettes/should_deny_a_subscriptions_to_a_client.yml
160
- - spec/cassettes/should_deny_publishing_on_a_channel_context.yml
161
- - spec/cassettes/should_deny_subscriptions_on_a_channel_context.yml
162
- - spec/cassettes/should_get_a_set_of_nodes_for_the_network.yml
163
- - spec/cassettes/should_get_a_subscribe_granted_event.yml
164
- - spec/cassettes/should_grant_a_connection.yml
165
- - spec/cassettes/should_grant_a_control_to_a_client.yml
166
- - spec/cassettes/should_grant_a_publishing_to_a_client.yml
167
- - spec/cassettes/should_grant_a_subscriptions_to_a_client.yml
168
- - spec/cassettes/should_grant_publishing_on_a_channel_context.yml
169
- - spec/cassettes/should_grant_subscriptions_on_a_channel_context.yml
170
- - spec/cassettes/should_publish.yml
171
- - spec/cassettes/should_publish_on_a_channel_context.yml
172
- - spec/cassettes/should_publish_to_a_client.yml
173
- - spec/cassettes/should_receive_an_unsubscribe_event.yml
174
- - spec/cassettes/should_receive_messages_on_a_channel.yml
175
- - spec/cassettes/should_send_a_connect_op.yml
176
- - spec/cassettes/should_send_a_connect_op_with_an_id.yml
177
- - spec/cassettes/should_spawn_a_client.yml
178
- - spec/cassettes/should_subscribe_to_a_channel.yml
179
- - spec/cassettes/should_trigger_a_connect_denied_event.yml
180
- - spec/cassettes/should_trigger_a_connect_event.yml
181
- - spec/cassettes/should_trigger_a_disconnect_event.yml
182
- - spec/cassettes/should_trigger_an_error_event.yml
183
- - spec/cassettes/should_unsubscribe_from_a_channel.yml
184
- - spec/cassettes/should_update_the_default_app.yml
185
- - spec/helper.rb
186
- - spec/shove_client_spec.rb
187
- - spec/shove_http_spec.rb
147
+ test_files: []