groem 0.0.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.
@@ -0,0 +1,198 @@
1
+ require 'eventmachine'
2
+
3
+ module Groem
4
+ module Dummy
5
+ class Server < EM::Connection
6
+ include Groem::Constants
7
+
8
+ DEFAULT_HOST = 'localhost'
9
+ DEFAULT_PORT = 23052 # note one off to avoid port conflict
10
+
11
+ DEFAULT_RESPONSES = { :register => ['-OK', 0],
12
+ :notify => ['-OK', 0],
13
+ :callback => ['CLICK', 10]
14
+ }
15
+
16
+ class << self
17
+ def canned_responses
18
+ @canned_responses ||= DEFAULT_RESPONSES.dup
19
+ end
20
+
21
+ def reset_canned_responses
22
+ @canned_responses = nil
23
+ end
24
+
25
+ def respond_to_register_with(meth, err = 0)
26
+ canned_responses[:register] = [meth.to_s.upcase, err.to_i]
27
+ end
28
+
29
+ def respond_to_notify_with(meth, err = 0)
30
+ canned_responses[:notify] = [meth.to_s.upcase, err.to_i]
31
+ end
32
+
33
+ def callback_with(rslt, secs)
34
+ canned_responses[:callback] = [rslt.to_s.upcase, secs.to_i]
35
+ end
36
+
37
+ def listen(host = DEFAULT_HOST, port = DEFAULT_PORT)
38
+ svr = EM.start_server host, port, self
39
+ puts "SERVER: Dummy GNTP server listening on #{host}:#{port}"
40
+ canned_responses.each_pair do |k, v|
41
+ if k == :register || k == :notify
42
+ puts " #{k.to_s.upcase} responds #{v[0]} with status #{v[1]}"
43
+ elsif k == :callback
44
+ puts " #{k.to_s.upcase} with result #{v[0]} after #{v[1]} secs"
45
+ end
46
+ end
47
+ svr
48
+ end
49
+ end
50
+
51
+ def post_init
52
+ reset_state
53
+ end
54
+
55
+ def receive_data data
56
+ @buffer.extract(data).each do |line|
57
+ update_message_state!(line)
58
+ @lines << line
59
+ end
60
+ receive_message @lines.join("\r\n") + "\r\n" if eof?
61
+ end
62
+
63
+ protected
64
+
65
+ def reset_state
66
+ @buffer = BufferedTokenizer.new("\r\n")
67
+ @lines = []
68
+ @response = nil
69
+ @sections_left = 0
70
+ end
71
+
72
+ # Horribly kludgy but that's GNTP for you...
73
+ def update_message_state!(line)
74
+ if line[/^\s*Notifications-Count\s*:\s*(\d+)/i]
75
+ @sections_left += $1.to_i
76
+ end
77
+ if line[/^.+:\s*x-growl-resource:/i]
78
+ @sections_left += 1
79
+ end
80
+ if line.empty?
81
+ @sections_left -= 1
82
+ end
83
+ #puts line
84
+ #puts "Note: #{@sections_left} more sections"
85
+ end
86
+
87
+ def eof?
88
+ if @lines[-1].empty? && @sections_left > 0
89
+ puts "SERVER: CRLFCRLF received, but expecting #{@sections_left} more sections"
90
+ end
91
+ @lines[-1].empty? && @sections_left <= 0
92
+ end
93
+
94
+ def receive_message message
95
+ puts "SERVER: Received message"
96
+ klass = Class.new { include Groem::Marshal::Request }
97
+ raw = klass.load(message, false)
98
+ #puts "Parsed message:\n#{raw.inspect}"
99
+ prepare_responses_for(raw)
100
+ if @response
101
+ send_data @response
102
+ puts "SERVER: Sent response"
103
+ end
104
+ end
105
+
106
+ def canned_responses; self.class.canned_responses; end
107
+
108
+ def prepare_responses_for(req)
109
+ case req['environment']['request_method']
110
+ when 'REGISTER'
111
+ prepare_register_response_for(req,
112
+ canned_responses[:register][0],
113
+ canned_responses[:register][1]
114
+ )
115
+ when 'NOTIFY'
116
+ prepare_notify_response_for(req,
117
+ canned_responses[:notify][0],
118
+ canned_responses[:notify][1]
119
+ )
120
+ schedule_callback_response_for(req,
121
+ canned_responses[:callback][0],
122
+ canned_responses[:callback][1]
123
+ ) \
124
+ if req['headers']['Notification-Callback-Context']
125
+ end
126
+ end
127
+
128
+ # eventually replace with Response#dump, quick & dirty for now
129
+ def prepare_register_response_for(req, meth, err)
130
+ env, hdrs = req[ENVIRONMENT_KEY], req[HEADERS_KEY]
131
+ out = []
132
+ out << "#{env[(GNTP_PROTOCOL_KEY)]}" +
133
+ "/#{env[(GNTP_VERSION_KEY)]} "+
134
+ "#{meth} "+
135
+ "#{env[(GNTP_ENCRYPTION_ID_KEY)]}"
136
+ out << "#{GNTP_RESPONSE_ACTION_KEY}: #{GNTP_REGISTER_METHOD}"
137
+ if meth == GNTP_ERROR_RESPONSE
138
+ out << "#{GNTP_ERROR_CODE_KEY}: #{err}"
139
+ out << "Error-Description: An error occurred"
140
+ end
141
+ out << nil
142
+ out << nil
143
+ out << nil
144
+ puts "SERVER: Prepared REGISTER response: #{meth}, #{err}"
145
+ @response = out.join("\r\n")
146
+ end
147
+
148
+ def prepare_notify_response_for(req, meth, err)
149
+ env, hdrs = req[ENVIRONMENT_KEY], req[HEADERS_KEY]
150
+ out = []
151
+ out << "#{env[(GNTP_PROTOCOL_KEY)]}" +
152
+ "/#{env[(GNTP_VERSION_KEY)]} "+
153
+ "#{meth} "+
154
+ "#{env[(GNTP_ENCRYPTION_ID_KEY)]}"
155
+ out << "#{GNTP_RESPONSE_ACTION_KEY}: #{GNTP_NOTIFY_METHOD}"
156
+ out << "#{GNTP_NOTIFICATION_ID_KEY}: #{hdrs[(GNTP_NOTIFICATION_ID_KEY)]}"
157
+ if meth == GNTP_ERROR_RESPONSE
158
+ out << "#{GNTP_ERROR_CODE_KEY}: #{err}"
159
+ out << "Error-Description: An error occurred"
160
+ end
161
+ out << nil
162
+ out << nil
163
+ out << nil
164
+ puts "SERVER: Prepared NOTIFY response: #{meth}, #{err}"
165
+ @response = out.join("\r\n")
166
+ end
167
+
168
+ def schedule_callback_response_for(req, rslt, secs)
169
+ EM.add_timer(secs) do
170
+ msg = callback_response_for(req, rslt)
171
+ send_data msg
172
+ puts "SERVER: Sent CALLBACK response: #{rslt}"
173
+ end
174
+ puts "SERVER: Scheduled CALLBACK response in #{secs} secs: #{rslt}"
175
+ end
176
+
177
+ def callback_response_for(req, rslt)
178
+ env, hdrs = req[ENVIRONMENT_KEY], req[HEADERS_KEY]
179
+ out = []
180
+ out << "#{env[(GNTP_PROTOCOL_KEY)]}" +
181
+ "/#{env[(GNTP_VERSION_KEY)]} "+
182
+ "#{GNTP_CALLBACK_RESPONSE} "+
183
+ "#{env[(GNTP_ENCRYPTION_ID_KEY)]}"
184
+ out << "#{GNTP_APPLICATION_NAME_KEY}: #{hdrs[(GNTP_APPLICATION_NAME_KEY)]}"
185
+ out << "#{GNTP_NOTIFICATION_ID_KEY}: #{hdrs[(GNTP_NOTIFICATION_ID_KEY)]}"
186
+ out << "#{GNTP_NOTIFICATION_CALLBACK_RESULT_KEY}: #{rslt}"
187
+ out << "#{GNTP_NOTIFICATION_CALLBACK_TIMESTAMP_KEY}: #{Time.now.strftime('%Y-%m-%d %H:%M:%SZ')}"
188
+ out << "#{GNTP_NOTIFICATION_CALLBACK_CONTEXT_KEY}: #{hdrs[(GNTP_NOTIFICATION_CALLBACK_CONTEXT_KEY)]}"
189
+ out << "#{GNTP_NOTIFICATION_CALLBACK_CONTEXT_TYPE_KEY}: #{hdrs[(GNTP_NOTIFICATION_CALLBACK_CONTEXT_TYPE_KEY)]}"
190
+ out << nil
191
+ out << nil
192
+ out << nil
193
+ out.join("\r\n")
194
+ end
195
+
196
+ end
197
+ end
198
+ end
@@ -0,0 +1,31 @@
1
+
2
+ module DummyServerHelper
3
+
4
+ DEFAULT_PORT = Groem::Dummy::Server::DEFAULT_PORT
5
+
6
+ def self.fork_server(opts = {})
7
+ fork {
8
+ puts '-------------- server process fork ------------------'
9
+ Groem::Dummy::Server.reset_canned_responses
10
+ if opts[:register]
11
+ Groem::Dummy::Server.respond_to_register_with *opts[:register]
12
+ end
13
+ if opts[:notify]
14
+ Groem::Dummy::Server.respond_to_notify_with *opts[:notify]
15
+ end
16
+ if opts[:callback]
17
+ Groem::Dummy::Server.callback_with *opts[:callback]
18
+ end
19
+ EM.run {
20
+ Signal.trap("INT") { EM.next_tick { EM.stop } }
21
+ Groem::Dummy::Server.listen
22
+ }
23
+ puts '-------------- server process exiting -----------'
24
+ }
25
+ end
26
+
27
+ def self.kill_server(pid)
28
+ Process.kill("INT", pid)
29
+ end
30
+
31
+ end
@@ -0,0 +1,40 @@
1
+
2
+ module MarshalHelper
3
+
4
+ def self.dummy_request_class
5
+ Class.new {
6
+ include(Groem::Marshal::Request)
7
+ require 'forwardable'
8
+ extend Forwardable
9
+ def_delegators :@raw, :[], :[]=
10
+ def raw; @raw ||= {}; end
11
+ def initialize(input = {})
12
+ @raw = input
13
+ end
14
+ }
15
+ end
16
+
17
+ def self.dummy_response_class
18
+ Class.new {
19
+ include(Groem::Marshal::Response)
20
+ require 'forwardable'
21
+ extend Forwardable
22
+ def_delegators :@raw, :[], :[]=
23
+ def raw; @raw ||= []; end
24
+ def initialize(input = [])
25
+ @raw = input
26
+ end
27
+ }
28
+ end
29
+
30
+ def self.dummy_request(env = {}, hdrs = {}, notifs = {})
31
+ klass = dummy_request_class
32
+ klass.new({'environment' => env,
33
+ 'headers' => hdrs,
34
+ 'notifications' => notifs
35
+ })
36
+ end
37
+
38
+
39
+
40
+ end
@@ -0,0 +1,14 @@
1
+ $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__))
2
+ require 'rubygems'
3
+ require 'bundler'
4
+ Bundler.setup :default
5
+
6
+ require 'lib/groem'
7
+
8
+ Dir[File.expand_path(File.join(File.dirname(__FILE__), 'shared', '**', '*.rb'))].each do |f|
9
+ load f
10
+ end
11
+
12
+ Bundler.setup :development
13
+ require 'minitest/spec'
14
+ MiniTest::Unit.autorun
@@ -0,0 +1,77 @@
1
+ require File.join(File.dirname(__FILE__),'..','spec_helper')
2
+
3
+ describe 'Groem::App #[]' do
4
+
5
+ describe 'after initializing' do
6
+
7
+ it 'should set the application_name header based on input' do
8
+ @subject = Groem::App.new('thing')
9
+ @subject['headers']['Application-Name'].must_equal 'thing'
10
+ end
11
+
12
+ it 'should default the environment when no options passed' do
13
+ @subject = Groem::App.new('thing')
14
+ @subject['environment'].must_equal Groem::App::DEFAULT_ENV
15
+ end
16
+
17
+ it 'should merge keys from input environment option into default environment' do
18
+ input = {'version' => '1.2',
19
+ 'request_method' => 'HELLO',
20
+ 'encryption_id' => 'ABC'
21
+ }
22
+ @subject = Groem::App.new('thing', {:environment => input})
23
+ @subject['environment'].must_equal Groem::App::DEFAULT_ENV.merge(input)
24
+ end
25
+
26
+ it 'should set each option in headers hash besides environment, host, and port' do
27
+ opts = {:environment => {},
28
+ :host => 'foo',
29
+ :port => 12345,
30
+ :x_option_1 => '1',
31
+ :x_option_2 => '2',
32
+ :x_option_3 => '3'
33
+ }
34
+ @subject = Groem::App.new('thing', opts)
35
+ @subject['headers'].must_equal(
36
+ {'Application-Name' => 'thing',
37
+ 'X-Option-1' => '1',
38
+ 'X-Option-2' => '2',
39
+ 'X-Option-3' => '3'
40
+ }
41
+ )
42
+ end
43
+
44
+ it 'should initialize the notifications hash to empty' do
45
+ @subject = Groem::App.new('thing')
46
+ @subject['notifications'].must_equal({})
47
+ end
48
+
49
+ end
50
+
51
+ describe 'after setting header' do
52
+
53
+ it 'should add the header to the headers hash based on input' do
54
+ @subject = Groem::App.new('thing')
55
+ @subject.header('x_header', 'boo')
56
+ @subject['headers']['X-Header'].must_equal 'boo'
57
+ end
58
+
59
+ end
60
+
61
+
62
+ describe 'after setting notification' do
63
+
64
+ it 'should set the notifications hash defaulting enabled to true' do
65
+ @subject = Groem::App.new('thing')
66
+ @subject.notification 'action' do end
67
+ @subject['notifications'].keys.must_include 'action'
68
+ @subject['notifications']['action'].keys.must_include 'Notification-Enabled'
69
+ @subject['notifications']['action']['Notification-Enabled'].must_equal 'True'
70
+ end
71
+
72
+ end
73
+
74
+
75
+ end
76
+
77
+
@@ -0,0 +1,380 @@
1
+ require File.join(File.dirname(__FILE__),'..','spec_helper')
2
+
3
+ describe 'Groem::Marshal::Request.load' do
4
+
5
+ #------ REGISTER requests --------#
6
+
7
+ describe 'when valid REGISTER request with one notification and no binaries' do
8
+
9
+ before do
10
+ @input = <<-__________
11
+ GNTP/1.0 REGISTER NONE
12
+ Application-Name: SurfWriter
13
+ Application-Icon: http://www.site.org/image.jpg
14
+ X-Creator: Apple Software
15
+ X-Application-ID:08d6c05a21512a79a1dfeb9d2a8f262f
16
+ Notifications-Count: 1
17
+
18
+ Notification-Name: Download Complete
19
+ Notification-Display-Name: Download completed
20
+ Notification-Enabled:True
21
+ X-Language : English
22
+ X-Timezone: PST
23
+
24
+
25
+ __________
26
+ dummy = Class.new { include(Groem::Marshal::Request) }
27
+ @subject = dummy.load(@input, false)
28
+ end
29
+
30
+ it 'should return a hash with keys for environment, headers, and notifications' do
31
+ @subject.has_key?('environment').must_equal true
32
+ @subject.has_key?('headers').must_equal true
33
+ @subject.has_key?('notifications').must_equal true
34
+ end
35
+
36
+ it 'environment hash should have version == 1.0' do
37
+ @subject['environment']['version'].must_equal '1.0'
38
+ end
39
+
40
+ it 'environment hash should have request_method == REGISTER' do
41
+ @subject['environment']['request_method'].must_equal 'REGISTER'
42
+ end
43
+
44
+ it 'headers hash should have application_name == SurfWriter' do
45
+ @subject['headers']['Application-Name'].must_equal 'SurfWriter'
46
+ end
47
+
48
+ it 'headers hash should have notifications_count == 1' do
49
+ @subject['headers']['Notifications-Count'].must_equal '1'
50
+ end
51
+
52
+ it 'headers hash should have x_application_id == 08d6c05a21512a79a1dfeb9d2a8f262f' do
53
+ @subject['headers']['X-Application-ID'].must_equal '08d6c05a21512a79a1dfeb9d2a8f262f'
54
+ end
55
+
56
+ it 'notifications hash should have 1 key' do
57
+ @subject['notifications'].keys.size.must_equal 1
58
+ end
59
+
60
+ it 'notifications hash should have key \'Download Complete\'' do
61
+ @subject['notifications']['Download Complete'].wont_be_nil
62
+ end
63
+
64
+ it '\'Download Complete\' notification should have notification_display_name == \'Download completed\'' do
65
+ @subject['notifications']['Download Complete']['Notification-Display-Name'].must_equal 'Download completed'
66
+ end
67
+
68
+ it '\'Download Complete\' notification should have notification_enabled == \'True\'' do
69
+ @subject['notifications']['Download Complete']['Notification-Enabled'].must_equal 'True'
70
+ end
71
+
72
+ it '\'Download Complete\' notification should have x_timezone == \'PST\'' do
73
+ @subject['notifications']['Download Complete']['X-Timezone'].must_equal 'PST'
74
+ end
75
+
76
+ it '\'Download Complete\' notification should have x_language == \'English\'' do
77
+ @subject['notifications']['Download Complete']['X-Language'].must_equal 'English'
78
+ end
79
+
80
+ it 'headers hash should not have x_timezone key' do
81
+ @subject['headers'].has_key?('X-Timezone').must_equal false
82
+ end
83
+
84
+ end
85
+
86
+ describe 'when valid REGISTER request with three notifications and no binaries' do
87
+
88
+ before do
89
+ @input = <<-__________
90
+ GNTP/1.0 REGISTER NONE
91
+ Application-Name: SurfWriter
92
+ Application-Icon: http://www.site.org/image.jpg
93
+ X-Creator: Apple Software
94
+ X-Application-ID: 08d6c05a21512a79a1dfeb9d2a8f262f
95
+ Notifications-Count: 3
96
+
97
+ Notification-Name: Download Complete
98
+ Notification-Display-Name: Download completed
99
+ Notification-Enabled: True
100
+ X-Language: English
101
+ X-Timezone: PST
102
+
103
+ Notification-Name: Download Started
104
+ Notification-Display-Name: Download starting
105
+ Notification-Enabled: False
106
+ X-Timezone: GMT
107
+
108
+ Notification-Name: Download Error
109
+ Notification-Display-Name: Error downloading
110
+ Notification-Enabled: True
111
+ X-Language: Spanish
112
+
113
+ __________
114
+ dummy = Class.new { include(Groem::Marshal::Request) }
115
+ @subject = dummy.load(@input, false)
116
+ end
117
+
118
+ it 'should return a hash with keys for environment, headers, and notifications' do
119
+ @subject.has_key?('environment').must_equal true
120
+ @subject.has_key?('headers').must_equal true
121
+ @subject.has_key?('notifications').must_equal true
122
+ end
123
+
124
+ it 'notifications hash should have 3 keys' do
125
+ @subject['notifications'].keys.size.must_equal 3
126
+ end
127
+
128
+ it 'notifications hash should have key \'Download Complete\'' do
129
+ @subject['notifications']['Download Complete'].wont_be_nil
130
+ end
131
+
132
+ it 'notifications hash should have key \'Download Started\'' do
133
+ @subject['notifications']['Download Started'].wont_be_nil
134
+ end
135
+
136
+ it 'notifications hash should have key \'Download Error\'' do
137
+ @subject['notifications']['Download Error'].wont_be_nil
138
+ end
139
+
140
+ it '\'Download Complete\' notification should have notification_display_name == \'Download completed\'' do
141
+ @subject['notifications']['Download Complete']['Notification-Display-Name'].must_equal 'Download completed'
142
+ end
143
+
144
+ it '\'Download Started\' notification should have notification_enabled == \'False\'' do
145
+ @subject['notifications']['Download Started']['Notification-Enabled'].must_equal 'False'
146
+ end
147
+
148
+ it '\'Download Error\' notification should have x_language == \'Spanish\'' do
149
+ @subject['notifications']['Download Error']['X-Language'].must_equal 'Spanish'
150
+ end
151
+
152
+ it '\'Download Started\' notification should not have X-Language key' do
153
+ @subject['notifications']['Download Started'].has_key?('X-Language').must_equal false
154
+ end
155
+
156
+ it '\'Download Error\' notification should not have X-Timezone key' do
157
+ @subject['notifications']['Download Error'].has_key?('X-Timezone').must_equal false
158
+ end
159
+
160
+ end
161
+
162
+ describe 'when valid REGISTER request with one binary referenced once in headers' do
163
+
164
+ end
165
+
166
+ describe 'when valid REGISTER request with one binary referenced once in notifications' do
167
+
168
+ end
169
+
170
+ describe 'when valid REGISTER request with three binaries referenced once each in headers and notifications' do
171
+
172
+ end
173
+
174
+ describe 'when valid REGISTER request with three binaries referenced twice each in headers and notifications' do
175
+
176
+ end
177
+
178
+
179
+ #------ NOTIFY requests --------#
180
+
181
+ describe 'when valid NOTIFY request with no binaries' do
182
+
183
+ before do
184
+ @input = <<-__________
185
+ GNTP/1.0 NOTIFY NONE
186
+ Application-Name: SurfWriter
187
+ Notification-Name: Download Complete
188
+ Notification-ID: 999
189
+ Notification-Title:XYZ finished downloading
190
+ Notification-Sticky: True
191
+ Notification-Icon : http://www.whatever.com/poo.jpg
192
+
193
+ __________
194
+ dummy = Class.new { include(Groem::Marshal::Request) }
195
+ @subject = dummy.load(@input, false)
196
+ end
197
+
198
+ it 'should return a hash with keys for environment, headers, and notifications' do
199
+ @subject.has_key?('environment').must_equal true
200
+ @subject.has_key?('headers').must_equal true
201
+ @subject.has_key?('notifications').must_equal true
202
+ end
203
+
204
+ it 'environment hash should have version == 1.0' do
205
+ @subject['environment']['version'].must_equal '1.0'
206
+ end
207
+
208
+ it 'environment hash should have request_method == NOTIFY' do
209
+ @subject['environment']['request_method'].must_equal 'NOTIFY'
210
+ end
211
+
212
+ it 'headers hash should have application_name == SurfWriter' do
213
+ @subject['headers']['Application-Name'].must_equal 'SurfWriter'
214
+ end
215
+
216
+ it 'headers hash should have notification_title == \'XYZ finished downloading\'' do
217
+ @subject['headers']['Notification-Title'].must_equal 'XYZ finished downloading'
218
+ end
219
+
220
+ it 'headers hash should have notification_sticky == \'True\'' do
221
+ @subject['headers']['Notification-Sticky'].must_equal 'True'
222
+ end
223
+
224
+ it 'headers hash should have notification_icon == \'http://www.whatever.com/poo.jpg\'' do
225
+ @subject['headers']['Notification-Icon'].must_equal 'http://www.whatever.com/poo.jpg'
226
+ end
227
+
228
+ it 'notifications hash should be empty' do
229
+ @subject['notifications'].empty?.must_equal true
230
+ end
231
+
232
+ end
233
+
234
+ describe 'when valid NOTIFY request with one binary referenced once' do
235
+
236
+ end
237
+
238
+ describe 'when valid NOTIFY request with three binaries referenced once each' do
239
+
240
+ end
241
+
242
+ describe 'when valid NOTIFY request with three binaries referenced twice each' do
243
+
244
+ end
245
+
246
+ end
247
+
248
+
249
+
250
+ #---------- dump -----------#
251
+
252
+
253
+ describe 'Groem::Marshal::Request#dump' do
254
+
255
+ describe 'when valid REGISTER request with one notification, no binaries' do
256
+
257
+ before do
258
+ @input_env = { 'protocol' => 'GNTP',
259
+ 'version' => '1.0',
260
+ 'request_method' => 'REGISTER',
261
+ 'encryption_id' => 'NONE'
262
+ }
263
+ @input_hdrs = {'Application-Name' => 'SurfWriter',
264
+ 'Application-Icon' => 'http://www.site.org/image.jpg'
265
+ }
266
+ @input_notifs = { 'Download Complete' => {
267
+ 'Notification-Display-Name' => 'Download completed',
268
+ 'Notification-Enabled' => 'True',
269
+ 'X-Language' => 'English',
270
+ 'X-Timezone' => 'PST'
271
+ }
272
+ }
273
+
274
+ @subject = MarshalHelper.dummy_request(
275
+ @input_env, @input_hdrs, @input_notifs).dump
276
+ end
277
+
278
+ it 'should output a string' do
279
+ @subject.class.must_be_same_as String
280
+ puts
281
+ puts '------------Groem::Marshal::Request#dump when valid REGISTER request with one notification, no binaries ------------'
282
+ puts @subject
283
+ end
284
+
285
+ it 'should output 10 lines terminated by CRLF' do
286
+ lines = @subject.split("\r\n")
287
+ lines.size.must_equal 10
288
+ end
289
+
290
+ it 'should end with 2 CRLF' do
291
+ @subject[-4,4].must_equal "\r\n\r\n"
292
+ end
293
+
294
+ it 'should output the first line as the standard GNTP first header' do
295
+ lines = @subject.split("\r\n")
296
+ lines[0].must_match(/^#{@input_env['protocol']}\/#{@input_env['version']}\s+#{@input_env['request_method']}\s+#{@input_env['encryption_id']}\s*$/i)
297
+ end
298
+
299
+ it 'should output the notification count == count of input notifications' do
300
+ @subject.must_match(/^\s*Notifications-Count\s*:\s*#{@input_notifs.keys.count}\s*$/i)
301
+ end
302
+
303
+ it 'should have a notification-name line for each input notification' do
304
+ @input_notifs.each_pair do |name, pairs|
305
+ @subject.must_match(/^\s*Notification-Name\s*:\s*#{name}\s*$/i)
306
+ end
307
+ end
308
+
309
+ end
310
+
311
+ describe 'when valid NOTIFY request with one notification, no binaries' do
312
+
313
+ before do
314
+ @input_env = { 'protocol' => 'GNTP',
315
+ 'version' => '1.0',
316
+ 'request_method' => 'NOTIFY',
317
+ 'encryption_id' => 'NONE'
318
+ }
319
+ @input_hdrs = {'Application-Name' => 'SurfWriter',
320
+ 'Notification-Name'=> 'Download Complete',
321
+ 'Notification-Id' => '999',
322
+ 'Notification-Title' => 'XYZ finished downloading',
323
+ 'Notification-Sticky' => 'True',
324
+ 'Notification-Icon' => 'http://www.whatever.com/poo.jpg'
325
+ }
326
+ @subject = MarshalHelper.dummy_request(
327
+ @input_env, @input_hdrs, {}).dump
328
+ end
329
+
330
+ it 'should output a string' do
331
+ @subject.class.must_be_same_as String
332
+ puts
333
+ puts '------------Groem::Marshal::Request#dump when valid NOTIFY request with one notification, no binaries ------------'
334
+ puts @subject
335
+ end
336
+
337
+ it 'should output the first line as the standard GNTP first header for NOTIFY request' do
338
+ lines = @subject.split("\r\n")
339
+ lines[0].must_match(/^GNTP\/1.0\s+NOTIFY\s+NONE\s*$/i)
340
+ end
341
+
342
+ it 'should not output a notification-count line' do
343
+ @subject.wont_match(/^\s*Notifications-Count\s*:\s*\d+\s*$/i)
344
+ end
345
+
346
+ end
347
+
348
+ describe 'when no environment' do
349
+
350
+ before do
351
+ @input_hdrs = {'Application-Name' => 'SurfWriter',
352
+ 'Notification-Name'=> 'Download Complete',
353
+ 'Notification-ID' => '999',
354
+ 'Notification-Title' => 'XYZ finished downloading',
355
+ 'Notification-Sticky' => 'True',
356
+ 'Notification-Icon' => 'http://www.whatever.com/poo.jpg'
357
+ }
358
+ @subject = MarshalHelper.dummy_request(
359
+ {}, @input_hdrs, {}).dump
360
+ end
361
+
362
+ it 'should output a string' do
363
+ @subject.class.must_be_same_as String
364
+ puts
365
+ puts '------------Groem::Marshal::Request#dump when no environment ------------'
366
+ puts @subject
367
+ end
368
+
369
+ it 'should output the first line as the default GNTP first header for NOTIFY request' do
370
+ lines = @subject.split("\r\n")
371
+ lines[0].must_match(/^GNTP\/1.0\s+NOTIFY\s+NONE\s*$/i)
372
+ end
373
+
374
+ it 'should not output a notification-count line' do
375
+ @subject.wont_match(/^\s*Notifications-Count\s*:\s*\d+\s*$/i)
376
+ end
377
+
378
+ end
379
+
380
+ end