tunnelbroker 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,11 @@
1
+ # -*- coding: UTF-8 -*-
2
+ require 'rspec'
3
+ require 'coveralls'
4
+ require 'simplecov'
5
+
6
+ SimpleCov.formatter = Coveralls::SimpleCov::Formatter
7
+ SimpleCov.start do
8
+ add_filter 'spec/'
9
+ end
10
+
11
+ require 'tunnelbroker'
@@ -0,0 +1,414 @@
1
+ # -*- coding: UTF-8 -*-
2
+ require 'spec_helper'
3
+
4
+ # Mock class for testing API responses
5
+ #
6
+ class MockResponse
7
+ attr_reader :lines
8
+
9
+ def initialize(text)
10
+ @lines = [text]
11
+ end
12
+ end
13
+
14
+ describe TunnelBroker::APIResponse do
15
+ describe '::BADAUTH' do
16
+ subject { TunnelBroker::APIResponse::BADAUTH }
17
+
18
+ it { should be_an_instance_of Regexp }
19
+
20
+ it 'should match the right string' do
21
+ s = 'badauth'
22
+ m = subject.match(s)
23
+ expect(m[1]).to eql 'badauth'
24
+ end
25
+ end
26
+
27
+ describe '::CHANGE' do
28
+ subject { TunnelBroker::APIResponse::CHANGE } # obama
29
+
30
+ it { should be_an_instance_of Regexp }
31
+
32
+ it 'should match the right string' do
33
+ s = 'good 127.0.0.1'
34
+ m = subject.match(s)
35
+ expect(m[1]).to eql 'good'
36
+ expect(m[2]).to eql '127.0.0.1'
37
+ end
38
+ end
39
+
40
+ describe '::NO_CHANGE' do
41
+ subject { TunnelBroker::APIResponse::NO_CHANGE }
42
+
43
+ it { should be_an_instance_of Regexp }
44
+
45
+ it 'should match the right string' do
46
+ s = 'nochg 127.0.0.1'
47
+ m = subject.match(s)
48
+ expect(m[1]).to eql 'nochg'
49
+ expect(m[2]).to eql '127.0.0.1'
50
+ end
51
+ end
52
+
53
+ describe '.matched_response' do
54
+ context 'when given more than one arg' do
55
+ it 'should raise ArgumentError' do
56
+ expect do
57
+ subject.send(:matched_response, nil, nil)
58
+ end.to raise_error ArgumentError
59
+ end
60
+ end
61
+
62
+ context 'when given less than one arg' do
63
+ it 'should raise ArgumentError' do
64
+ expect { subject.send(:matched_response) }.to raise_error ArgumentError
65
+ end
66
+ end
67
+
68
+ context 'when given a match' do
69
+ subject do
70
+ TunnelBroker::APIResponse.new(MockResponse.new('nochg 127.0.0.1'))
71
+ end
72
+ let(:m) { TunnelBroker::APIResponse::NO_CHANGE }
73
+ let(:thematch) { m.match('nochg 127.0.0.1') }
74
+
75
+ it 'should return a Hash for .response' do
76
+ subject.send(:matched_response, thematch)
77
+ expect(subject.response).to be_an_instance_of Hash
78
+ end
79
+
80
+ it 'should return the exepcted Hash for .response' do
81
+ subject.send(:matched_response, thematch)
82
+ expect(subject.response)
83
+ .to eql(msg: thematch[1], data: { ip: thematch[2] })
84
+ end
85
+ end
86
+ end
87
+
88
+ describe '.no_change' do
89
+ context 'when given more than two args' do
90
+ it 'should raise ArgumentError' do
91
+ expect do
92
+ subject.send(:no_change, nil, nil)
93
+ end.to raise_error ArgumentError
94
+ end
95
+ end
96
+
97
+ context 'when given less than one arg' do
98
+ it 'should raise ArgumentError' do
99
+ expect { subject.send(:no_change) }.to raise_error ArgumentError
100
+ end
101
+ end
102
+
103
+ context 'when passed a match' do
104
+ subject do
105
+ TunnelBroker::APIResponse.new(MockResponse.new('nochg 127.0.0.1'))
106
+ end
107
+ let(:m) { TunnelBroker::APIResponse::NO_CHANGE }
108
+ let(:thematch) { m.match('nochg 127.0.0.1') }
109
+
110
+ it 'should return true for .success?' do
111
+ subject.send(:no_change, thematch)
112
+ expect(subject.success?).to be_truthy
113
+ end
114
+
115
+ it 'should return false for .changed?' do
116
+ subject.send(:no_change, thematch)
117
+ expect(subject.changed?).to be_falsey
118
+ end
119
+
120
+ it 'should return a Hash for .response' do
121
+ subject.send(:no_change, thematch)
122
+ expect(subject.response).to be_an_instance_of Hash
123
+ end
124
+
125
+ it 'should return the exepcted Hash for .response' do
126
+ subject.send(:no_change, thematch)
127
+ expect(subject.response)
128
+ .to eql(msg: thematch[1], data: { ip: thematch[2] })
129
+ end
130
+ end
131
+ end
132
+
133
+ describe '.change' do
134
+ context 'when given more than two args' do
135
+ it 'should raise ArgumentError' do
136
+ expect do
137
+ subject.send(:change, nil, nil)
138
+ end.to raise_error ArgumentError
139
+ end
140
+ end
141
+
142
+ context 'when given less than one arg' do
143
+ it 'should raise ArgumentError' do
144
+ expect { subject.send(:change) }.to raise_error ArgumentError
145
+ end
146
+ end
147
+
148
+ context 'when passed a match' do
149
+ subject do
150
+ TunnelBroker::APIResponse.new(MockResponse.new('good 127.0.0.1'))
151
+ end
152
+ let(:m) { TunnelBroker::APIResponse::CHANGE }
153
+ let(:thematch) { m.match('good 127.0.0.1') }
154
+
155
+ it 'should return true for .success?' do
156
+ subject.send(:change, thematch)
157
+ expect(subject.success?).to be_truthy
158
+ end
159
+
160
+ it 'should return true for .changed?' do
161
+ subject.send(:change, thematch)
162
+ expect(subject.success?).to be_truthy
163
+ end
164
+
165
+ it 'should return a Hash for .response' do
166
+ subject.send(:change, thematch)
167
+ expect(subject.response).to be_an_instance_of Hash
168
+ end
169
+
170
+ it 'should return the expected Hash for .response' do
171
+ subject.send(:change, thematch)
172
+ expect(subject.response)
173
+ .to eql(msg: thematch[1], data: { ip: thematch[2] })
174
+ end
175
+ end
176
+ end
177
+
178
+ describe '.bad_auth' do
179
+ context 'when given more than two args' do
180
+ it 'should raise ArgumentError' do
181
+ expect do
182
+ subject.send(:bad_auth, nil, nil)
183
+ end.to raise_error ArgumentError
184
+ end
185
+ end
186
+
187
+ context 'when given less than one arg' do
188
+ it 'should raise ArgumentError' do
189
+ expect { subject.send(:bad_auth) }.to raise_error ArgumentError
190
+ end
191
+ end
192
+
193
+ context 'when passed a match' do
194
+ subject do
195
+ TunnelBroker::APIResponse.new(MockResponse.new('badauth'))
196
+ end
197
+ let(:m) { TunnelBroker::APIResponse::BADAUTH }
198
+ let(:thematch) { m.match('badauth') }
199
+
200
+ it 'should return false for .success?' do
201
+ subject.send(:bad_auth, thematch)
202
+ expect(subject.success?).to be_falsey
203
+ end
204
+
205
+ it 'should return false for .changed?' do
206
+ subject.send(:bad_auth, thematch)
207
+ expect(subject.changed?).to be_falsey
208
+ end
209
+
210
+ it 'should return a Hash for .response' do
211
+ subject.send(:bad_auth, thematch)
212
+ expect(subject.response).to be_an_instance_of Hash
213
+ end
214
+
215
+ it 'should return the expected Hash for .response' do
216
+ subject.send(:bad_auth, thematch)
217
+ expect(subject.response)
218
+ .to eql(msg: thematch[1], data: {})
219
+ end
220
+ end
221
+ end
222
+
223
+ describe '.parse_response' do
224
+ context 'when given more than one arg' do
225
+ it 'should raise ArgumentError' do
226
+ expect do
227
+ subject.send(:parse_response, nil, nil)
228
+ end.to raise_error ArgumentError
229
+ end
230
+ end
231
+
232
+ context 'when given less than one arg' do
233
+ it 'should raise ArgumentError' do
234
+ expect { subject.send(:parse_response) }.to raise_error ArgumentError
235
+ end
236
+ end
237
+
238
+ context 'when given a badauth string' do
239
+ before do
240
+ m = TunnelBroker::APIResponse::BADAUTH
241
+ @md = m.match('badauth')
242
+ allow_any_instance_of(TunnelBroker::APIResponse)
243
+ .to receive(:bad_auth).with(@md).and_return('hello')
244
+ end
245
+
246
+ subject do
247
+ TunnelBroker::APIResponse.new(
248
+ MockResponse.new('badauth')
249
+ ).send(:parse_response, 'badauth')
250
+ end
251
+
252
+ it { should be_an_instance_of String }
253
+
254
+ it { should eql 'hello' }
255
+ end
256
+
257
+ context 'when given a change string' do
258
+ before do
259
+ m = TunnelBroker::APIResponse::CHANGE
260
+ @md = m.match('good 127.0.0.1')
261
+ allow_any_instance_of(TunnelBroker::APIResponse)
262
+ .to receive(:change).with(@md).and_return('hi')
263
+ end
264
+
265
+ subject do
266
+ TunnelBroker::APIResponse.new(
267
+ MockResponse.new('good 127.0.0.1')
268
+ ).send(:parse_response, 'good 127.0.0.1')
269
+ end
270
+
271
+ it { should be_an_instance_of String }
272
+
273
+ it { should eql 'hi' }
274
+ end
275
+
276
+ context 'when given a no_change string' do
277
+ before do
278
+ m = TunnelBroker::APIResponse::NO_CHANGE
279
+ @md = m.match('nochg 127.0.0.1')
280
+ allow_any_instance_of(TunnelBroker::APIResponse)
281
+ .to receive(:no_change).with(@md).and_return('wat')
282
+ end
283
+
284
+ subject do
285
+ TunnelBroker::APIResponse.new(
286
+ MockResponse.new('nochg 127.0.0.1')
287
+ ).send(:parse_response, 'nochg 127.0.0.1')
288
+ end
289
+
290
+ it { should be_an_instance_of String }
291
+
292
+ it { should eql 'wat' }
293
+ end
294
+
295
+ context 'when given a non-matching string' do
296
+ subject do
297
+ TunnelBroker::APIResponse.new(
298
+ MockResponse.new('madness')
299
+ )
300
+ end
301
+
302
+ it 'should not set a response value' do
303
+ expect(subject.send(:parse_response, 'madness')).to be_nil
304
+ expect(subject.response).to be_nil
305
+ end
306
+ end
307
+ end
308
+
309
+ describe '.changed?' do
310
+ context 'when given more than one arg' do
311
+ it 'should raise ArgumentError' do
312
+ expect { subject.changed?(nil) }.to raise_error ArgumentError
313
+ end
314
+ end
315
+
316
+ context 'when @changed is true' do
317
+ before do
318
+ @t = TunnelBroker::APIResponse.new(MockResponse.new('good 127.0.0.1'))
319
+ end
320
+ subject { @t.changed? }
321
+
322
+ it { should be_truthy }
323
+ end
324
+
325
+ context 'when @changed is false' do
326
+ before do
327
+ @t = TunnelBroker::APIResponse.new(MockResponse.new('nochg 127.0.0.1'))
328
+ end
329
+ subject { @t.changed? }
330
+
331
+ it { should be_falsey }
332
+ end
333
+
334
+ context 'when @changed is not defined' do
335
+ before do
336
+ @t = TunnelBroker::APIResponse.new(MockResponse.new('good 127.0.0.1'))
337
+ @t.remove_instance_variable(:@changed)
338
+ end
339
+ subject { @t.changed? }
340
+
341
+ it { should be_falsey }
342
+ end
343
+ end
344
+
345
+ describe '.success?' do
346
+ context 'when given more than one arg' do
347
+ it 'should raise ArgumentError' do
348
+ expect { subject.success?(nil) }.to raise_error ArgumentError
349
+ end
350
+ end
351
+
352
+ context 'when @success is true' do
353
+ before do
354
+ @t = TunnelBroker::APIResponse.new(MockResponse.new('good 127.0.0.1'))
355
+ end
356
+ subject { @t.success? }
357
+
358
+ it { should be_truthy }
359
+ end
360
+
361
+ context 'when @success is false' do
362
+ before do
363
+ @t = TunnelBroker::APIResponse.new(MockResponse.new('badauth'))
364
+ end
365
+ subject { @t.success? }
366
+
367
+ it { should be_falsey }
368
+ end
369
+
370
+ context 'when @success is not defined' do
371
+ before do
372
+ @t = TunnelBroker::APIResponse.new(MockResponse.new('good 127.0.0.1'))
373
+ @t.remove_instance_variable(:@success)
374
+ end
375
+ subject { @t.success? }
376
+
377
+ it { should be_falsey }
378
+ end
379
+ end
380
+
381
+ describe '.new' do
382
+ context 'when given more than one arg' do
383
+ it 'should raise ArgumentError' do
384
+ expect do
385
+ TunnelBroker::APIResponse.new(nil, nil)
386
+ end.to raise_error ArgumentError
387
+ end
388
+ end
389
+
390
+ context 'when given less than one arg' do
391
+ it 'should raise ArgumentError' do
392
+ expect do
393
+ TunnelBroker::APIResponse.new
394
+ end.to raise_error ArgumentError
395
+ end
396
+ end
397
+
398
+ context 'when given a response-like object' do
399
+ subject do
400
+ TunnelBroker::APIResponse.new(
401
+ MockResponse.new('good 127.0.0.1')
402
+ )
403
+ end
404
+
405
+ it { should be_an_instance_of TunnelBroker::APIResponse }
406
+
407
+ it 'should call parse_response' do
408
+ expect(subject.success?).to be_truthy
409
+ expect(subject.changed?).to be_truthy
410
+ expect(subject.response).to be_an_instance_of Hash
411
+ end
412
+ end
413
+ end
414
+ end
@@ -0,0 +1,318 @@
1
+ # -*- coding: UTF-8 -*-
2
+ require 'uri'
3
+ require 'spec_helper'
4
+
5
+ # MockConfig class
6
+ # for .build_messenger_config
7
+ class MockConfig
8
+ @@url = nil
9
+ def self.url
10
+ @@url
11
+ end
12
+ def self.url=(url_in)
13
+ @@url = url_in
14
+ end
15
+
16
+ def self.username
17
+ 'theckman'
18
+ end
19
+ def self.update_key
20
+ 'abc123'
21
+ end
22
+ def self.tunnelid
23
+ '1234'
24
+ end
25
+ def self.ip4addr
26
+ '127.0.0.1'
27
+ end
28
+ end
29
+
30
+ # MockMessenger class
31
+ # for submit_update testing
32
+ class MockMessenger
33
+ attr_reader :x
34
+ def initialize(xa)
35
+ @x = xa
36
+ end
37
+
38
+ def call_api
39
+ x
40
+ end
41
+ end
42
+
43
+ describe TunnelBroker::Client do
44
+ describe '::ENDPOINT' do
45
+ subject { TunnelBroker::Client::ENDPOINT }
46
+
47
+ it { should be_an_instance_of String }
48
+
49
+ it 'should match the URI regexp' do
50
+ expect(URI.regexp.match(subject)).to_not be_nil
51
+ end
52
+
53
+ it 'should use HTTPS' do
54
+ u = URI(subject)
55
+ expect(u.scheme.downcase).to eql 'https'
56
+ end
57
+ end
58
+
59
+ describe '.config' do
60
+ context 'when given more than one arg' do
61
+ it 'should raise ArgumentError' do
62
+ expect do
63
+ subject.send(:config, nil)
64
+ end.to raise_error ArgumentError
65
+ end
66
+ end
67
+
68
+ context 'when @config does not exist' do
69
+ subject { TunnelBroker::Client.new.send(:config) }
70
+
71
+ it { should be_an_instance_of TunnelBroker::Configuration }
72
+ end
73
+
74
+ context 'when @config does exist' do
75
+ before do
76
+ @tbc = TunnelBroker::Client.new
77
+ @tbc.instance_variable_set(
78
+ :@config, TunnelBroker::Configuration.new
79
+ )
80
+ end
81
+ subject { @tbc.send(:config) }
82
+
83
+ it { should be_an_instance_of TunnelBroker::Configuration }
84
+ end
85
+ end
86
+
87
+ describe '.build_messenger_config' do
88
+ before do
89
+ @tbc = TunnelBroker::Client.new
90
+ allow(@tbc).to receive(:config).and_return(MockConfig)
91
+ end
92
+
93
+ context 'when given more than one arg' do
94
+ it 'should raise ArgumentError' do
95
+ expect do
96
+ subject.send(:build_messenger_config, nil)
97
+ end.to raise_error ArgumentError
98
+ end
99
+ end
100
+
101
+ context 'irrespective of what the config options are' do
102
+ it 'should try to build the config with each config item' do
103
+ TunnelBroker::Configuration::FIELDS.each do |c|
104
+ expect(@tbc).to receive(:config_hash_item).with(c).and_return({})
105
+ end
106
+ @tbc.send(:build_messenger_config)
107
+ end
108
+ end
109
+
110
+ context 'when none of the config options are set' do
111
+ before do
112
+ allow(MockConfig).to receive(:username).and_return(nil)
113
+ allow(MockConfig).to receive(:update_key).and_return(nil)
114
+ allow(MockConfig).to receive(:tunnelid).and_return(nil)
115
+ allow(MockConfig).to receive(:ip4addr).and_return(nil)
116
+ end
117
+ subject { @tbc.send(:build_messenger_config) }
118
+
119
+ it { should be_an_instance_of Hash }
120
+
121
+ it { should eql(url: TunnelBroker::Client::ENDPOINT) }
122
+ end
123
+
124
+ context 'when all of the config options are set' do
125
+ before do
126
+ @cfg = {
127
+ url: TunnelBroker::Client::ENDPOINT,
128
+ username: MockConfig.username,
129
+ update_key: MockConfig.update_key,
130
+ tunnelid: MockConfig.tunnelid,
131
+ ip4addr: MockConfig.ip4addr
132
+ }
133
+ end
134
+
135
+ subject { @tbc.send(:build_messenger_config) }
136
+
137
+ it { should be_an_instance_of Hash }
138
+
139
+ it { should eql @cfg }
140
+ end
141
+ end
142
+
143
+ describe '.config_hash_item' do
144
+ before do
145
+ @tbc = TunnelBroker::Client.new
146
+ allow(@tbc).to receive(:config).and_return(MockConfig)
147
+ end
148
+
149
+ context 'when given more than one arg' do
150
+ it 'should raise ArgumentError' do
151
+ expect do
152
+ @tbc.send(:config_hash_item)
153
+ end.to raise_error ArgumentError
154
+ end
155
+ end
156
+
157
+ context 'when given less than one arg' do
158
+ it 'should raise ArgumentError' do
159
+ expect do
160
+ @tbc.send(:config_hash_item)
161
+ end.to raise_error ArgumentError
162
+ end
163
+ end
164
+
165
+ context 'when given a key that is not valid' do
166
+ before do
167
+ @key = :fakeitem
168
+ end
169
+
170
+ it 'should not be a valid key' do
171
+ expect(TunnelBroker::Configuration::FIELDS.include?(@key))
172
+ .to be_falsey
173
+ end
174
+
175
+ it 'should raise NoMethodError' do
176
+ expect do
177
+ @tbc.send(:config_hash_item, @key)
178
+ end.to raise_error NoMethodError
179
+ end
180
+ end
181
+
182
+ context 'when given a valid key that is unset' do
183
+ before do
184
+ @key = :username
185
+ allow(MockConfig).to receive(:username).and_return(nil)
186
+ end
187
+
188
+ it 'should be a valid key' do
189
+ expect(TunnelBroker::Configuration::FIELDS.include?(@key))
190
+ .to be_truthy
191
+ end
192
+
193
+ subject { @tbc.send(:config_hash_item, @key) }
194
+
195
+ it { should be_an_instance_of Hash }
196
+
197
+ it { should eql({}) }
198
+ end
199
+
200
+ context 'when given a valid key that is set' do
201
+ before do
202
+ @key = :username
203
+ end
204
+
205
+ it 'should be a valid key' do
206
+ expect(TunnelBroker::Configuration::FIELDS.include?(@key))
207
+ .to be_truthy
208
+ end
209
+
210
+ subject { @tbc.send(:config_hash_item, @key) }
211
+
212
+ it { should be_an_instance_of Hash }
213
+
214
+ it { should eql(username: 'theckman') }
215
+ end
216
+
217
+ context 'when given :url and it being unset' do
218
+ before do
219
+ @key = :url
220
+ end
221
+
222
+ it 'should be a valid key' do
223
+ expect(TunnelBroker::Configuration::FIELDS.include?(@key))
224
+ .to be_truthy
225
+ end
226
+
227
+ subject { @tbc.send(:config_hash_item, @key) }
228
+
229
+ it { should be_an_instance_of Hash }
230
+
231
+ it { should eql(url: TunnelBroker::Client::ENDPOINT) }
232
+ end
233
+
234
+ context 'when given :url and it being unset' do
235
+ before do
236
+ @key = :url
237
+ allow(MockConfig).to receive(:url).and_return('http://tb.io/')
238
+ end
239
+
240
+ it 'should be a valid key' do
241
+ expect(TunnelBroker::Configuration::FIELDS.include?(@key))
242
+ .to be_truthy
243
+ end
244
+
245
+ subject { @tbc.send(:config_hash_item, @key) }
246
+
247
+ it { should be_an_instance_of Hash }
248
+
249
+ it { should eql(url: 'http://tb.io/') }
250
+ end
251
+ end
252
+
253
+ describe '.submit_update' do
254
+ before do
255
+ @tbc = TunnelBroker::Client.new
256
+ end
257
+
258
+ context 'when given any args' do
259
+ it 'to raise ArgumentError' do
260
+ expect do
261
+ @tbc.submit_update(nil)
262
+ end.to raise_error ArgumentError
263
+ end
264
+ end
265
+
266
+ context 'when submitted with no args' do
267
+ before do
268
+ allow(@tbc).to receive(:config).and_return(MockConfig)
269
+ allow(@tbc).to receive(:build_messenger_config).and_return(
270
+ x: 'wat'
271
+ )
272
+ allow(TunnelBroker::Messenger).to receive(:new) do |arg1|
273
+ MockMessenger.new(arg1)
274
+ end
275
+ end
276
+
277
+ subject { @tbc.submit_update }
278
+
279
+ it { should be_an_instance_of Hash }
280
+
281
+ it { should eql(x: 'wat') }
282
+ end
283
+ end
284
+
285
+ describe '.configure' do
286
+ before do
287
+ @tbc = TunnelBroker::Client.new
288
+ end
289
+
290
+ context 'when given any args' do
291
+ it 'should raise ArgumentError' do
292
+ expect do
293
+ @tbc.configure(nil)
294
+ end.to raise_error ArgumentError
295
+ end
296
+ end
297
+
298
+ context 'when called with a block' do
299
+ before do
300
+ allow(@tbc).to receive(:config).and_return('configObj')
301
+ end
302
+
303
+ it 'should yield control' do
304
+ expect { |b| @tbc.configure(&b) }.to yield_control
305
+ end
306
+
307
+ it 'should yield the object returned from .config' do
308
+ expect { |b| @tbc.configure(&b) }.to yield_with_args('configObj')
309
+ end
310
+ end
311
+
312
+ context 'when not called with a block' do
313
+ subject { @tbc.configure }
314
+
315
+ it { should be_nil }
316
+ end
317
+ end
318
+ end