tunnelbroker 0.1.0

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,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