mock_gcm 0.1.1

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 ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ .ruby-version
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mock_gcm.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Anders Carling
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,56 @@
1
+ # MockGcm
2
+
3
+ Fake GCM server for your integration testing needs.
4
+
5
+
6
+ Please be aware that this does not test everything as specific tests for errors like InvalidTtl, DataTooBig, InvalidRegistration are not made - but their results can be mocked.
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ gem 'mock_gcm'
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install mock_gcm
21
+
22
+ ## Usage
23
+ require 'mock_gcm'
24
+
25
+ mock_gcm = MockGCM.new("my key", 8282)
26
+ mock_gcm.start
27
+
28
+ require 'gcm_client' # some gcm client library
29
+ client = GcmClient.new(:url => "http://localhost:8282/", :api_key => "my key")
30
+ client.send("registration_id1", {:some => :data})
31
+ client.send("registration_id2", {:some => :data})
32
+
33
+ mock_gcm.received_messages =>
34
+ # => [
35
+ # {
36
+ # "collapse_key" => nil,
37
+ # "time_to_live" => nil,
38
+ # "delay_while_idle" => nil,
39
+ # "data" => {"some" => "data"},
40
+ # "registration_id" => "registration_id1"
41
+ # }, {
42
+ # "collapse_key" => nil,
43
+ # "time_to_live" => nil,
44
+ # "delay_while_idle" => nil,
45
+ # "data" => {"some" => "data"},
46
+ # "registration_id" => "registration_id2"
47
+ # }
48
+ # ]
49
+
50
+ ## Contributing
51
+
52
+ 1. Fork it
53
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
54
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
55
+ 4. Push to the branch (`git push origin my-new-feature`)
56
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,188 @@
1
+ require 'xmlrpc/httpserver'
2
+ require 'json'
3
+ require 'thread'
4
+ require 'forwardable'
5
+
6
+ module MockGCM
7
+ class Server
8
+ extend Forwardable
9
+
10
+ DEFAULT_HOST = 'localhost'
11
+
12
+ def initialize(api_key, port)
13
+ @api_key = api_key
14
+
15
+ @received_messages = []
16
+ @mutex = Mutex.new
17
+
18
+ @server = HttpServer.new(self, port, DEFAULT_HOST, 1, File.open("/dev/null"), false, false)
19
+
20
+ # Configurable error behaviour
21
+ @next_request_errno = nil
22
+ @canonicals = {}
23
+ @errors = {}
24
+ end
25
+
26
+ # Manage server state
27
+
28
+ def_delegators :@server, :start, :stop, :stopped?
29
+
30
+ def mock_next_request_failure(errno)
31
+ @mutex.synchronize { @next_request_errno = Integer(errno) }
32
+ end
33
+
34
+ def mock_canonical_id(reg_id, canonical_reg_id)
35
+ @mutex.synchronize { @canonicals[reg_id] = canonical_reg_id }
36
+ end
37
+
38
+ def mock_error(reg_id, error, options = {})
39
+ @mutex.synchronize { @errors[reg_id] = { :error => error, :times => options[:times] || -1 } }
40
+ end
41
+
42
+ # Check server state from request thread
43
+
44
+ def error_for(reg_id)
45
+ @mutex.synchronize {
46
+ return unless hsh = @errors[reg_id]
47
+ return unless hsh[:times] != 0
48
+
49
+ hsh[:times] -= 1 if hsh[:times] >= 1
50
+ hsh[:error]
51
+ }
52
+ end
53
+
54
+ def canonical_id_for(reg_id)
55
+ @mutex.synchronize { @canonicals[reg_id] }
56
+ end
57
+
58
+ # Message log
59
+
60
+ def received_messages
61
+ @mutex.synchronize { @received_messages.dup }
62
+ end
63
+
64
+ def add_received(reg_id, collapse_key, time_to_live, delay_while_idle, data)
65
+ hsh = {
66
+ 'registration_id' => reg_id.freeze,
67
+ 'collapse_key' => collapse_key.freeze,
68
+ 'time_to_live' => time_to_live.freeze,
69
+ 'delay_while_idle' => delay_while_idle.freeze,
70
+ 'data' => data.freeze,
71
+ }.freeze
72
+ @mutex.synchronize { @received_messages << hsh }
73
+ end
74
+
75
+ # Check stuff
76
+
77
+ def check_fail_next_request(request, response, req_data)
78
+ next_request_errno = @mutex.synchronize do
79
+ @next_request_errno.tap { @next_request_errno = nil }
80
+ end
81
+
82
+ if next_request_errno
83
+ response.status = next_request_errno
84
+ false
85
+ else
86
+ true
87
+ end
88
+ end
89
+
90
+ def check_authorization_header(request, response, req_data)
91
+ if request.header['Authorization'] == "key=#{@api_key}"
92
+ true
93
+ else
94
+ response.status = 401
95
+ false
96
+ end
97
+ end
98
+
99
+ def check_content_type(request, response, req_data)
100
+ if request.header['Content-Type'] == "application/json"
101
+ true
102
+ else
103
+ response.status = 400
104
+ false
105
+ end
106
+ end
107
+
108
+ def check_data_format(request, response, req_data)
109
+ fail = Proc.new do
110
+ response.status = 400
111
+ return false
112
+ end
113
+ json = JSON.parse(req_data) rescue fail.call
114
+
115
+ # Required
116
+ fail.call unless json["data"].is_a?(Hash)
117
+ fail.call unless json["registration_ids"].is_a?(Array) && json["registration_ids"].all? { |reg_id| reg_id.is_a?(String) } && json["registration_ids"].size <= 1000
118
+ # Optional
119
+ fail.call unless json.fetch("collapse_key", "").is_a?(String)
120
+ fail.call unless json.fetch("time_to_live", 1).is_a?(Integer)
121
+ fail.call unless [true,false].include?(json.fetch("delay_while_idle", false))
122
+
123
+ valid_fields = ["data", "registration_ids", "collapse_key", "time_to_live", "delay_while_idle"]
124
+ json.keys.each do |key|
125
+ fail.call unless valid_fields.include?(key)
126
+ end
127
+
128
+ true
129
+ end
130
+
131
+ def handle_req_data(req_data)
132
+ req_json = JSON.parse(req_data)
133
+
134
+ success, failure, canonical_ids, results = 0, 0, 0, []
135
+
136
+ reg_ids = req_json['registration_ids']
137
+ reg_ids.each do |reg_id|
138
+ results << {}.tap do |result|
139
+ if error = error_for(reg_id)
140
+ result['error'] = error
141
+ failure += 1
142
+ next
143
+ end
144
+
145
+ if canonical_id = canonical_id_for(reg_id)
146
+ result['registration_id'] = canonical_id
147
+ canonical_ids += 1
148
+ end
149
+
150
+ result['message_id'] = rand(100_000_000)
151
+ success += 1
152
+
153
+ add_received(reg_id, req_json['collapse_key'], req_json['time_to_live'],
154
+ req_json['delay_while_idle'], req_json.fetch('data'))
155
+ end
156
+ end
157
+
158
+ return success, failure, canonical_ids, results
159
+ end
160
+
161
+ # HttpServer handlers
162
+
163
+ def ip_auth_handler(io)
164
+ true
165
+ end
166
+
167
+ def request_handler(request, response)
168
+ req_data = request.data.read(request.content_length)
169
+
170
+ return unless check_fail_next_request(request, response, req_data)
171
+ return unless check_authorization_header(request, response, req_data)
172
+ return unless check_content_type(request, response, req_data)
173
+ return unless check_data_format(request, response, req_data)
174
+
175
+ success, failure, canonical_ids, results = handle_req_data(req_data)
176
+
177
+ response.header['Content-Type'] = 'application/json'
178
+ response.body = {
179
+ 'multicast_id' => rand(100_000_000),
180
+ 'success' => success,
181
+ 'failure' => failure,
182
+ 'canonical_ids' => canonical_ids,
183
+ 'results' => results
184
+ }.to_json
185
+ end
186
+
187
+ end
188
+ end
@@ -0,0 +1,3 @@
1
+ module MockGCM
2
+ VERSION = "0.1.1"
3
+ end
data/lib/mock_gcm.rb ADDED
@@ -0,0 +1,10 @@
1
+ require "mock_gcm/version"
2
+ require "mock_gcm/server"
3
+
4
+ module MockGCM
5
+ extend self
6
+
7
+ def new(*attrs)
8
+ Server.new(*attrs)
9
+ end
10
+ end
data/mock_gcm.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'mock_gcm/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "mock_gcm"
8
+ spec.version = MockGCM::VERSION
9
+ spec.authors = ["Anders Carling"]
10
+ spec.email = ["anders.carling@d05.se"]
11
+ spec.description = %q{Fake GCM server for your integration testing needs}
12
+ spec.summary = %q{Fake GCM server for your integration testing needs}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+ spec.add_development_dependency "httpclient"
25
+ end
@@ -0,0 +1,329 @@
1
+ require 'spec_helper'
2
+ require 'json'
3
+ require 'httpclient'
4
+
5
+ describe MockGCM do
6
+ let(:api_key) { "secrets" }
7
+ let(:mock_gcm_port) { 8282 }
8
+ let(:mock_gcm) { MockGCM.new(api_key, mock_gcm_port) }
9
+ let(:mock_gcm_url) { "http://localhost:#{mock_gcm_port}" }
10
+ let(:http_client) { HTTPClient.new }
11
+ let(:headers) {
12
+ { "Content-Type" => "application/json",
13
+ "Authorization" => "key=#{api_key}" }
14
+ }
15
+ let(:valid_data) {
16
+ {
17
+ "collapse_key" => "score_update",
18
+ "time_to_live" => 108,
19
+ "delay_while_idle" => true,
20
+ "data" => {
21
+ "score" => "4x8",
22
+ "time" => "15:16.2342"
23
+ },
24
+ "registration_ids" => ["4", "8", "15", "16", "23", "42"]
25
+ }
26
+ }
27
+
28
+ before { mock_gcm.start }
29
+ after { mock_gcm.stop; sleep(0.01) until mock_gcm.stopped? }
30
+
31
+ context 'correct data' do
32
+ optional_keys = ["collapse_key", "time_to_live", "delay_while_idle"]
33
+ ([:all, :no] + optional_keys).each do |included_key|
34
+ it "should accept and report messages including #{included_key} optional key(s)" do
35
+ unless included_key == :all
36
+ optional_keys.each { |key| valid_data.delete(key) unless key == included_key }
37
+ end
38
+
39
+ resp = http_client.post(mock_gcm_url, valid_data.to_json, headers)
40
+ resp.should be_ok
41
+ resp.headers.fetch('Content-type').should == 'application/json'
42
+
43
+ json = JSON.parse(resp.body)
44
+
45
+ json.should include('multicast_id')
46
+ json.fetch('success').should == 6
47
+ json.fetch('failure').should == 0
48
+ json.fetch('canonical_ids').should == 0
49
+
50
+ results = json.fetch('results')
51
+ results.size.should == 6
52
+ results.each do |res|
53
+ res.should include('message_id')
54
+ res.should_not include('registration_id')
55
+ res.should_not include('error')
56
+ end
57
+
58
+ expected_report = valid_data['registration_ids'].map do |registration_id|
59
+ { "collapse_key" => valid_data["collapse_key"],
60
+ "time_to_live" => valid_data["time_to_live"],
61
+ "delay_while_idle" => valid_data['delay_while_idle'],
62
+ "data" => valid_data["data"],
63
+ "registration_id" => registration_id }
64
+ end
65
+ mock_gcm.received_messages.should == expected_report
66
+ end
67
+ end
68
+
69
+ describe "#mock_error" do
70
+ it "should fail sends to specified registration_id in subsequent requests" do
71
+ cnt = 1+rand(100)
72
+
73
+ errors = %w{
74
+ MissingRegistration InvalidRegistration MismatchSenderId NotRegistered MessageTooBig
75
+ InvalidDataKey InvalidTtl Unavailable InternalServerError InvalidPackageName
76
+ }
77
+ fails = {
78
+ "42" => errors.sample,
79
+ "16" => errors.sample
80
+ }
81
+ fails.each_pair do |reg_id, error|
82
+ mock_gcm.mock_error(reg_id, error)
83
+ end
84
+
85
+ cnt.times do
86
+ resp = http_client.post(mock_gcm_url, valid_data.to_json, headers)
87
+ resp.should be_ok
88
+
89
+ json = JSON.parse(resp.body)
90
+ json.fetch('success').should == 4
91
+ json.fetch('failure').should == 2
92
+ json.fetch('canonical_ids').should == 0
93
+
94
+ result_for = lambda do |reg_id|
95
+ json.fetch('results').at(valid_data['registration_ids'].index(reg_id))
96
+ end
97
+
98
+ fails.each_pair do |reg_id, error|
99
+ result = result_for.(reg_id)
100
+ result.should_not include('message_id')
101
+ result.fetch('error').should == error
102
+ result.should_not include('registration_id')
103
+ end
104
+
105
+ (valid_data['registration_ids'] - fails.keys).each do |reg_id|
106
+ result = result_for.(reg_id)
107
+ result.should include('message_id')
108
+ result.should_not include('error')
109
+ result.should_not include('registration_id')
110
+ end
111
+ end
112
+
113
+ mock_gcm.received_messages.size.should == cnt * 4
114
+ end
115
+
116
+ it "should limit error reporting to :times times if specified" do
117
+ cnt = 1 + rand(100)
118
+
119
+ errors = %w{
120
+ MissingRegistration InvalidRegistration MismatchSenderId NotRegistered MessageTooBig
121
+ InvalidDataKey InvalidTtl Unavailable InternalServerError InvalidPackageName
122
+ }
123
+ fails = {
124
+ "42" => errors.sample,
125
+ "16" => errors.sample
126
+ }
127
+ fails.each_pair do |reg_id, error|
128
+ mock_gcm.mock_error(reg_id, error, :times => cnt)
129
+ end
130
+
131
+ cnt.times do
132
+ resp = http_client.post(mock_gcm_url, valid_data.to_json, headers)
133
+ resp.should be_ok
134
+
135
+ json = JSON.parse(resp.body)
136
+ json.fetch('success').should == 4
137
+ json.fetch('failure').should == 2
138
+ json.fetch('canonical_ids').should == 0
139
+
140
+ result_for = lambda do |reg_id|
141
+ json.fetch('results').at(valid_data['registration_ids'].index(reg_id))
142
+ end
143
+
144
+ fails.each_pair do |reg_id, error|
145
+ result = result_for.(reg_id)
146
+ result.should_not include('message_id')
147
+ result.fetch('error').should == error
148
+ result.should_not include('registration_id')
149
+ end
150
+
151
+ (valid_data['registration_ids'] - fails.keys).each do |reg_id|
152
+ result = result_for.(reg_id)
153
+ result.should include('message_id')
154
+ result.should_not include('error')
155
+ result.should_not include('registration_id')
156
+ end
157
+ end
158
+
159
+ resp = http_client.post(mock_gcm_url, valid_data.to_json, headers)
160
+ resp.should be_ok
161
+
162
+ json = JSON.parse(resp.body)
163
+ json.fetch('success').should == 6
164
+ json.fetch('failure').should == 0
165
+
166
+ mock_gcm.received_messages.size.should == 6 + cnt * 4
167
+ end
168
+
169
+ it "should not affect unrelated requests" do
170
+ mock_gcm.mock_error("not in valid data", "Unavailable")
171
+
172
+ resp = http_client.post(mock_gcm_url, valid_data.to_json, headers)
173
+ resp.should be_ok
174
+
175
+ json = JSON.parse(resp.body)
176
+ json.fetch('failure').should == 0
177
+ json.fetch('results').each { |hash| hash.should_not include('error') }
178
+
179
+ mock_gcm.received_messages.size.should == 6
180
+ end
181
+
182
+ end
183
+
184
+ describe "#mock_canonical_id" do
185
+
186
+ it "should return canonical registration_id for specified registration_ids in subsequent requests" do
187
+ cnt = 1 + rand(100)
188
+
189
+ canonicals = { "8" => "27", "42" => "19" }
190
+ canonicals.each_pair do |reg_id, can_id|
191
+ mock_gcm.mock_canonical_id(reg_id, can_id)
192
+ end
193
+
194
+ cnt.times do
195
+ resp = http_client.post(mock_gcm_url, valid_data.to_json, headers)
196
+ resp.should be_ok
197
+
198
+ json = JSON.parse(resp.body)
199
+ json.fetch('success').should == 6
200
+ json.fetch('failure').should == 0
201
+ json.fetch('canonical_ids').should == 2
202
+
203
+ result_for = lambda do |reg_id|
204
+ json.fetch('results').at(valid_data['registration_ids'].index(reg_id))
205
+ end
206
+
207
+ canonicals.each do |reg_id, can_id|
208
+ result = result_for.(reg_id)
209
+ result.should include('message_id')
210
+ result.should_not include('error')
211
+ result.fetch('registration_id').should == can_id
212
+ end
213
+
214
+ (valid_data['registration_ids'] - canonicals.keys).each do |reg_id|
215
+ result = result_for.(reg_id)
216
+ result.should include('message_id')
217
+ result.should_not include('error')
218
+ result.should_not include('registration_id')
219
+ end
220
+ end
221
+
222
+ mock_gcm.received_messages.size.should == cnt * 6
223
+ end
224
+
225
+ it "should not affect unrelated requests" do
226
+ mock_gcm.mock_canonical_id("not in valid data", "1")
227
+
228
+ resp = http_client.post(mock_gcm_url, valid_data.to_json, headers)
229
+ resp.should be_ok
230
+
231
+ json = JSON.parse(resp.body)
232
+ json.fetch('canonical_ids').should == 0
233
+ json.fetch('results').each { |hash| hash.should_not include('registration_id') }
234
+
235
+ mock_gcm.received_messages.size.should == 6
236
+ end
237
+
238
+ end
239
+
240
+ describe "#mock_next_request_failure" do
241
+
242
+ 5.times do
243
+ errno = 500 + rand(100)
244
+ it "should fail (#{errno}) if requested" do
245
+ mock_gcm.mock_next_request_failure(errno)
246
+ resp = http_client.post(mock_gcm_url, valid_data.to_json, headers)
247
+ resp.status.should == errno
248
+ mock_gcm.received_messages.should be_empty
249
+ end
250
+ end
251
+
252
+ it "should clear after one failure" do
253
+ mock_gcm.mock_next_request_failure(500)
254
+ resp = http_client.post(mock_gcm_url, valid_data.to_json, headers)
255
+ resp.status.should == 500
256
+ mock_gcm.received_messages.should be_empty
257
+
258
+ resp = http_client.post(mock_gcm_url, valid_data.to_json, headers)
259
+ resp.should be_ok
260
+ end
261
+
262
+ end
263
+ end
264
+
265
+ context 'missing api key' do
266
+
267
+ it "should fail (401)" do
268
+ resp = http_client.post(mock_gcm_url, valid_data.to_json, headers.reject { |k,v| k == 'Authorization' })
269
+ resp.status.should == 401
270
+ mock_gcm.received_messages.should be_empty
271
+ end
272
+
273
+ end
274
+
275
+ context "incorrect data" do
276
+
277
+ it "should fail (400) given more than 1000 registration_ids" do
278
+ resp = http_client.post(mock_gcm_url, valid_data.tap { |d| d['registration_ids'] = 1.upto(1001).map(&:to_s) }.to_json, headers)
279
+ resp.status.should == 400
280
+ mock_gcm.received_messages.should be_empty
281
+ end
282
+
283
+ ['data', 'registration_ids'].each do |key|
284
+ it "should fail (400) when #{key} (required) is missing" do
285
+ resp = http_client.post(mock_gcm_url, valid_data.tap { |d| d.delete(key) }.to_json, headers)
286
+ resp.status.should == 400
287
+ mock_gcm.received_messages.should be_empty
288
+ end
289
+ end
290
+
291
+ [ ['data', 1],
292
+ ['registration_ids', 1],
293
+ ['registration_ids', [1]],
294
+ ['time_to_live', "123"],
295
+ ['collapse_key', 1],
296
+ ['delay_while_idle', "1"]
297
+ ].each do |key, value|
298
+ it "should fail (400) when #{key} = #{value.inspect} (incorrect type)" do
299
+ resp = http_client.post(mock_gcm_url, valid_data.tap { |d| d[key] = value }.to_json, headers)
300
+ resp.status.should == 400
301
+ mock_gcm.received_messages.should be_empty
302
+ end
303
+ end
304
+
305
+ it "should fail(400) when extra keys are present" do
306
+ resp = http_client.post(mock_gcm_url, valid_data.tap { |d| d['extra'] = 1 }.to_json, headers)
307
+ resp.status.should == 400
308
+ mock_gcm.received_messages.should be_empty
309
+ end
310
+
311
+ it "should fail (400) if non-valid-json data is sent" do
312
+ resp = http_client.post(mock_gcm_url, "garbage%s" % valid_data.to_json, headers)
313
+ resp.status.should == 400
314
+ mock_gcm.received_messages.should be_empty
315
+ end
316
+
317
+ end
318
+
319
+ context "incorrect content-type header" do
320
+
321
+ it "should fail (400)" do
322
+ resp = http_client.post(mock_gcm_url, valid_data.to_json, headers.tap { |h| h['Content-Type'] = 'text/plain' })
323
+ resp.status.should == 400
324
+ mock_gcm.received_messages.should be_empty
325
+ end
326
+
327
+ end
328
+
329
+ end
@@ -0,0 +1,22 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'mock_gcm'
5
+
6
+ # This file was generated by the `rspec --init` command. Conventionally, all
7
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
8
+ # Require this file using `require "spec_helper"` to ensure that it is only
9
+ # loaded once.
10
+ #
11
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
12
+ RSpec.configure do |config|
13
+ config.treat_symbols_as_metadata_keys_with_true_values = true
14
+ config.run_all_when_everything_filtered = true
15
+ config.filter_run :focus
16
+
17
+ # Run specs in random order to surface order dependencies. If you find an
18
+ # order dependency and want to debug it, you can fix the order by providing
19
+ # the seed, which is printed after each run.
20
+ # --seed 1234
21
+ config.order = 'random'
22
+ end
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mock_gcm
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.1
6
+ platform: ruby
7
+ authors:
8
+ - Anders Carling
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-10-18 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ version_requirements: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ none: false
21
+ name: bundler
22
+ type: :development
23
+ prerelease: false
24
+ requirement: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ version: '1.3'
29
+ none: false
30
+ - !ruby/object:Gem::Dependency
31
+ version_requirements: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ! '>='
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ none: false
37
+ name: rake
38
+ type: :development
39
+ prerelease: false
40
+ requirement: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ none: false
46
+ - !ruby/object:Gem::Dependency
47
+ version_requirements: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ! '>='
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ none: false
53
+ name: rspec
54
+ type: :development
55
+ prerelease: false
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ! '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ none: false
62
+ - !ruby/object:Gem::Dependency
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ! '>='
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ none: false
69
+ name: httpclient
70
+ type: :development
71
+ prerelease: false
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ none: false
78
+ description: Fake GCM server for your integration testing needs
79
+ email:
80
+ - anders.carling@d05.se
81
+ executables: []
82
+ extensions: []
83
+ extra_rdoc_files: []
84
+ files:
85
+ - .gitignore
86
+ - Gemfile
87
+ - LICENSE.txt
88
+ - README.md
89
+ - Rakefile
90
+ - lib/mock_gcm.rb
91
+ - lib/mock_gcm/server.rb
92
+ - lib/mock_gcm/version.rb
93
+ - mock_gcm.gemspec
94
+ - spec/mock_gcm_spec.rb
95
+ - spec/spec_helper.rb
96
+ homepage: ''
97
+ licenses:
98
+ - MIT
99
+ post_install_message:
100
+ rdoc_options: []
101
+ require_paths:
102
+ - lib
103
+ required_ruby_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ! '>='
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ none: false
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ! '>='
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ none: false
115
+ requirements: []
116
+ rubyforge_project:
117
+ rubygems_version: 1.8.23
118
+ signing_key:
119
+ specification_version: 3
120
+ summary: Fake GCM server for your integration testing needs
121
+ test_files:
122
+ - spec/mock_gcm_spec.rb
123
+ - spec/spec_helper.rb
124
+ has_rdoc: