ngrok-wrapper 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,356 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe 'Ngrok::Wrapper' do
4
+ let(:log) { File.read("#{RSPEC_ROOT}/fixtures/ngrok.sample.log") }
5
+ let(:fake_pid) { rand(99_999) }
6
+
7
+ before do
8
+ allow(Ngrok::Wrapper).to receive(:ensure_binary)
9
+ allow(Ngrok::Wrapper).to receive(:raise_if_similar_ngroks)
10
+ allow(Process).to receive(:spawn).and_return(fake_pid)
11
+ allow(Process).to receive(:kill)
12
+ end
13
+
14
+ it 'has a version number' do
15
+ expect(Ngrok::Wrapper::VERSION).not_to be nil
16
+ end
17
+
18
+ describe 'Before start' do
19
+ before { allow_any_instance_of(Tempfile).to receive(:read).and_return(log) }
20
+
21
+ it 'is not running' do
22
+ expect(Ngrok::Wrapper.running?).to be false
23
+ end
24
+
25
+ it 'is stopped' do
26
+ expect(Ngrok::Wrapper.stopped?).to be true
27
+ end
28
+
29
+ it 'has :stopped status' do
30
+ expect(Ngrok::Wrapper.status).to eq :stopped
31
+ end
32
+ end
33
+
34
+ describe 'After start' do
35
+ before do
36
+ allow_any_instance_of(Tempfile).to receive(:read).and_return(log)
37
+
38
+ Ngrok::Wrapper.start
39
+ end
40
+
41
+ after { Ngrok::Wrapper.stop }
42
+
43
+ it 'is running' do
44
+ expect(Ngrok::Wrapper.running?).to be true
45
+ end
46
+
47
+ it 'is not stopped' do
48
+ expect(Ngrok::Wrapper.stopped?).to be false
49
+ end
50
+
51
+ it 'has :running status' do
52
+ expect(Ngrok::Wrapper.status).to eq :running
53
+ end
54
+
55
+ it 'has correct port property' do
56
+ expect(Ngrok::Wrapper.port).to eq(3001)
57
+ end
58
+
59
+ it 'has correct addr property' do
60
+ expect(Ngrok::Wrapper.addr).to eq(3001)
61
+ end
62
+
63
+ it 'has valid ngrok_url' do
64
+ expect(Ngrok::Wrapper.ngrok_url).to be =~ %r{http://.*ngrok\.io$}
65
+ end
66
+
67
+ it 'has valid ngrok_url_https' do
68
+ expect(Ngrok::Wrapper.ngrok_url_https).to be =~ %r{https://.*ngrok\.io$}
69
+ end
70
+
71
+ it 'has correct pid property' do
72
+ expect(Ngrok::Wrapper.pid).to be > 0
73
+ end
74
+ end
75
+
76
+ describe 'Custom log file' do
77
+ before { allow_any_instance_of(File).to receive(:read).and_return(log) }
78
+
79
+ it 'uses custom log file' do
80
+ Ngrok::Wrapper.start(log: 'test.log')
81
+ expect(Ngrok::Wrapper.running?).to eq true
82
+ expect(Ngrok::Wrapper.params[:log].path).to eq 'test.log'
83
+ Ngrok::Wrapper.stop
84
+ expect(Ngrok::Wrapper.stopped?).to eq true
85
+ end
86
+ end
87
+
88
+ describe 'Invalid or missing authtoken' do
89
+ describe 'when no authtoken is specified in ngrok config file' do
90
+ let(:no_auth_log) { File.read("#{RSPEC_ROOT}/fixtures/ngrok.no_auth_token.log") }
91
+
92
+ it 'raises Ngrok::Error exception' do
93
+ allow_any_instance_of(Tempfile).to receive(:read).and_return(no_auth_log)
94
+
95
+ expect { Ngrok::Wrapper.start }.to raise_error Ngrok::Error
96
+ end
97
+ end
98
+
99
+ describe 'when an invalid authtoken is specified in ngrok config file' do
100
+ let(:invalid_auth_log) { File.read("#{RSPEC_ROOT}/fixtures/ngrok.no_auth_token.log") }
101
+
102
+ it 'fails with incorrect authtoken' do
103
+ allow_any_instance_of(Tempfile).to receive(:read).and_return(invalid_auth_log)
104
+
105
+ expect do
106
+ Ngrok::Wrapper.start(authtoken: 'incorrect_token')
107
+ end.to raise_error Ngrok::Error
108
+ end
109
+ end
110
+ end
111
+
112
+ describe 'Custom addr' do
113
+ before { allow_any_instance_of(Tempfile).to receive(:read).and_return(log) }
114
+
115
+ it 'maps port param to addr' do
116
+ port = 10_010
117
+ Ngrok::Wrapper.start(port: port)
118
+ expect(Ngrok::Wrapper.addr).to eq port
119
+ Ngrok::Wrapper.stop
120
+ end
121
+
122
+ it 'returns just the port when the address contains a host' do
123
+ addr = '192.168.0.5:10010'
124
+ Ngrok::Wrapper.start(addr: addr)
125
+ expect(Ngrok::Wrapper.port).to eq 10_010
126
+ Ngrok::Wrapper.stop
127
+ end
128
+
129
+ it 'supports remote addresses' do
130
+ addr = '192.168.0.5:10010'
131
+ Ngrok::Wrapper.start(addr: addr)
132
+ expect(Ngrok::Wrapper.addr).to eq addr
133
+ Ngrok::Wrapper.stop
134
+ end
135
+ end
136
+
137
+ describe 'Custom region' do
138
+ before { allow_any_instance_of(Tempfile).to receive(:read).and_return(log) }
139
+
140
+ it "doesn't include the -region parameter when it is not provided" do
141
+ Ngrok::Wrapper.start
142
+ expect(Ngrok::Wrapper.__send__(:ngrok_exec_params)).not_to include('-region=')
143
+ Ngrok::Wrapper.stop
144
+ end
145
+
146
+ it 'includes the -region parameter with the correct value when it is provided' do
147
+ region = 'eu'
148
+ Ngrok::Wrapper.start(region: region)
149
+ expect(Ngrok::Wrapper.__send__(:ngrok_exec_params)).to include("-region=#{region}")
150
+ Ngrok::Wrapper.stop
151
+ end
152
+ end
153
+
154
+ describe 'Custom bind-tls' do
155
+ before { allow_any_instance_of(Tempfile).to receive(:read).and_return(log) }
156
+
157
+ it "doesn't include the -bind-tls parameter when it is not provided" do
158
+ Ngrok::Wrapper.start
159
+ expect(Ngrok::Wrapper.__send__(:ngrok_exec_params)).not_to include('-bind-tls=')
160
+ Ngrok::Wrapper.stop
161
+ end
162
+
163
+ it 'includes the -bind-tls parameter with the correct value when it is true' do
164
+ bind_tls = true
165
+ Ngrok::Wrapper.start(bind_tls: bind_tls)
166
+ expect(Ngrok::Wrapper.__send__(:ngrok_exec_params)).to include("-bind-tls=#{bind_tls}")
167
+ Ngrok::Wrapper.stop
168
+ end
169
+
170
+ it 'includes the -bind-tls parameter with the correct value when it is false' do
171
+ bind_tls = false
172
+ Ngrok::Wrapper.start(bind_tls: bind_tls)
173
+ expect(Ngrok::Wrapper.__send__(:ngrok_exec_params)).to include("-bind-tls=#{bind_tls}")
174
+ Ngrok::Wrapper.stop
175
+ end
176
+ end
177
+
178
+ describe 'Custom host header' do
179
+ after { Ngrok::Wrapper.stop }
180
+
181
+ it "doesn't include the -host-header parameter when it is not provided" do
182
+ expect(Ngrok::Wrapper).to receive(:fetch_urls)
183
+ Ngrok::Wrapper.start
184
+ expect(Ngrok::Wrapper.__send__(:ngrok_exec_params)).not_to include('-host-header=')
185
+ end
186
+
187
+ it 'includes the -host-header parameter with the correct value when it is provided' do
188
+ expect(Ngrok::Wrapper).to receive(:fetch_urls)
189
+ host_header = 'foo.bar'
190
+ Ngrok::Wrapper.start(host_header: host_header)
191
+ expect(Ngrok::Wrapper.__send__(:ngrok_exec_params)).to include("-host-header=#{host_header}")
192
+ end
193
+ end
194
+
195
+ describe 'Custom parameters provided' do
196
+ before { allow_any_instance_of(Tempfile).to receive(:read).and_return(log) }
197
+
198
+ it "doesn't include the -inspect parameter when it is not provided" do
199
+ Ngrok::Wrapper.start
200
+ expect(Ngrok::Wrapper.__send__(:ngrok_exec_params)).not_to include('-inspect=')
201
+ Ngrok::Wrapper.stop
202
+ end
203
+
204
+ it 'includes the -inspect parameter with the correct value when it is provided' do
205
+ Ngrok::Wrapper.start(inspect: true)
206
+ expect(Ngrok::Wrapper.__send__(:ngrok_exec_params)).to include('-inspect=true')
207
+ Ngrok::Wrapper.stop
208
+
209
+ Ngrok::Wrapper.start(inspect: false)
210
+ expect(Ngrok::Wrapper.__send__(:ngrok_exec_params)).to include('-inspect=false')
211
+ Ngrok::Wrapper.stop
212
+ end
213
+ end
214
+
215
+ describe '#start' do
216
+ after { Ngrok::Wrapper.stop }
217
+
218
+ describe 'when persistence param is true' do
219
+ before do
220
+ allow(File).to receive(:write)
221
+ allow(Ngrok::Wrapper).to receive(:try_params_from_running_ngrok).and_call_original
222
+ allow(Ngrok::Wrapper).to receive(:parse_persistence_file).and_return(state)
223
+ end
224
+
225
+ describe 'tries fetching params of an already running Ngrok and store Ngrok process data into a file' do
226
+ describe 'when fetching params returns nil' do
227
+ let(:state) { nil }
228
+
229
+ it "doesn't check for similar ngroks running" do
230
+ expect(Ngrok::Wrapper).to receive(:try_params_from_running_ngrok)
231
+ expect(Ngrok::Wrapper).not_to receive(:raise_if_similar_ngroks)
232
+ expect(Ngrok::Wrapper).not_to receive(:ngrok_running?)
233
+ expect(Ngrok::Wrapper).to receive(:spawn_new_ngrok).with(persistent_ngrok: true)
234
+ expect(File).to receive(:write)
235
+
236
+ Ngrok::Wrapper.start(persistence: true)
237
+ end
238
+ end
239
+
240
+ describe 'when fetching params returns a legit hash' do
241
+ let(:state) do
242
+ { 'pid' => '795',
243
+ 'ngrok_url' => 'http://b1cd-109-185-141-9.ngrok.io',
244
+ 'ngrok_url_https' => 'https://b1cd-109-185-141-9.ngrok.io' }
245
+ end
246
+
247
+ describe 'checking if a similar Ngrok is running' do
248
+ before do
249
+ allow(Ngrok::Wrapper).to receive(:raise_if_similar_ngroks).and_call_original
250
+ allow(Ngrok::Wrapper).to receive(:ngrok_process_status_lines).and_return(ngrok_ps_lines)
251
+
252
+ expect(Ngrok::Wrapper).to receive(:try_params_from_running_ngrok)
253
+ end
254
+
255
+ describe 'when Ngrok process with params from the persisted file is running' do
256
+ let(:ngrok_ps_lines) do
257
+ ['795 ?? S 0:04.81 ngrok http -log -config /Users/thunder/.ngrok2/ngrok.yml https://localhost:3001']
258
+ end
259
+
260
+ it 'set Ngrok::Wrapper pid and status attributes' do
261
+ expect(Ngrok::Wrapper).not_to receive(:spawn_new_ngrok)
262
+
263
+ Ngrok::Wrapper.start(persistence: true)
264
+
265
+ expect(Ngrok::Wrapper.pid).to eql('795')
266
+ expect(Ngrok::Wrapper.status).to eql(:running)
267
+ expect(Ngrok::Wrapper.ngrok_url).to eql('http://b1cd-109-185-141-9.ngrok.io')
268
+ expect(Ngrok::Wrapper.ngrok_url_https).to eql('https://b1cd-109-185-141-9.ngrok.io')
269
+ end
270
+ end
271
+
272
+ describe 'when a similar Ngrok with other pid is already running' do
273
+ let(:ngrok_ps_lines) do
274
+ ['71986 ?? S 0:04.81 ngrok http -log -config /Users/thunder/.ngrok2/ngrok.yml https://localhost:3001']
275
+ end
276
+
277
+ it 'raises exception' do
278
+ expect(Ngrok::Wrapper).not_to receive(:spawn_new_ngrok)
279
+
280
+ expect { Ngrok::Wrapper.start(persistence: true) }
281
+ .to raise_error(Ngrok::Error, 'ERROR: Other ngrok instances tunneling to port 3001 found')
282
+ end
283
+ end
284
+
285
+ describe 'when Ngrok with the persisted pid is already running, but on a different port' do
286
+ let(:ngrok_ps_lines) do
287
+ ['795 ?? S 0:04.81 ngrok http -log -config /Users/thunder/.ngrok2/ngrok.yml https://localhost:3000']
288
+ end
289
+
290
+ it 'raises exception' do
291
+ expect(Ngrok::Wrapper).not_to receive(:spawn_new_ngrok)
292
+
293
+ expect { Ngrok::Wrapper.start(persistence: true) }
294
+ .to raise_error(Ngrok::Error, 'ERROR: Ngrok pid #795 tunneling on other port 3000')
295
+ end
296
+ end
297
+
298
+ describe 'when no Ngrok process with params from the persisted file or similar is running' do
299
+ let(:ngrok_ps_lines) do
300
+ ['834 ?? S 0:04.81 ngrok http -log -config /Users/thunder/.ngrok2/ngrok.yml https://localhost:5001']
301
+ end
302
+
303
+ let(:new_ngrok_ps_lines) do
304
+ ['835 ?? S 0:04.81 ngrok http -log -config /Users/thunder/.ngrok2/ngrok.yml https://localhost:3001']
305
+ end
306
+
307
+ it 'sets Ngrok::Wrapper pid and status attributes' do
308
+ allow(Ngrok::Wrapper).to receive(:spawn_new_ngrok).with(persistent_ngrok: true).and_call_original
309
+ allow(Ngrok::Wrapper)
310
+ .to receive(:ngrok_process_status_lines).with(refetch: true).and_return(new_ngrok_ps_lines)
311
+ allow(Ngrok::Wrapper).to receive(:fetch_urls)
312
+
313
+ expect(Ngrok::Wrapper).to receive(:spawn_new_ngrok).with(persistent_ngrok: true)
314
+ expect(Ngrok::Wrapper)
315
+ .to receive(:ngrok_process_status_lines).with(refetch: true)
316
+ allow(Ngrok::Wrapper).to receive(:fetch_urls)
317
+
318
+ Ngrok::Wrapper.start(persistence: true)
319
+
320
+ expect(Ngrok::Wrapper.pid).to eql('835')
321
+ expect(Ngrok::Wrapper.status).to eql(:running)
322
+ end
323
+ end
324
+ end
325
+
326
+ it 'tries fetching params of an already running Ngrok and store Ngrok process data into a file' do
327
+ expect(Ngrok::Wrapper).to receive(:try_params_from_running_ngrok)
328
+ expect(Ngrok::Wrapper).to receive(:spawn_new_ngrok).with(persistent_ngrok: true)
329
+ expect(File).to receive(:write)
330
+
331
+ Ngrok::Wrapper.start(persistence: true)
332
+ end
333
+ end
334
+ end
335
+ end
336
+
337
+ describe 'when persistence param is not true' do
338
+ it "doesn't try to fetch params of an already running Ngrok" do
339
+ expect(Ngrok::Wrapper).not_to receive(:try_params_from_running_ngrok)
340
+ expect(Ngrok::Wrapper).to receive(:spawn_new_ngrok).with(persistent_ngrok: false)
341
+ expect_any_instance_of(File).not_to receive(:write)
342
+
343
+ Ngrok::Wrapper.start(persistence: false)
344
+ end
345
+ end
346
+
347
+ describe 'when Ngrok::Wrapper is already running' do
348
+ it "doesn't try to spawn a new Ngrok process" do
349
+ allow(Ngrok::Wrapper).to receive(:stopped?).and_return(false)
350
+ expect(Ngrok::Wrapper).not_to receive(:spawn_new_ngrok)
351
+
352
+ Ngrok::Wrapper.start
353
+ end
354
+ end
355
+ end
356
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'simplecov'
4
+ require 'ngrok/wrapper'
5
+
6
+ RSPEC_ROOT = File.dirname __FILE__
7
+
8
+ RSpec.configure do |config|
9
+ config.mock_with :rspec do |mocks|
10
+ mocks.verify_partial_doubles = true
11
+ end
12
+
13
+ # Enable flags like --only-failures and --next-failure
14
+ config.example_status_persistence_file_path = '.rspec_status'
15
+
16
+ # Disable RSpec exposing methods globally on `Module` and `main`
17
+ config.disable_monkey_patching!
18
+
19
+ config.expect_with :rspec do |c|
20
+ c.syntax = :expect
21
+ c.include_chain_clauses_in_custom_matcher_descriptions = true
22
+ end
23
+ end
metadata ADDED
@@ -0,0 +1,163 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ngrok-wrapper
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Anton Bogdanovich
8
+ - Aureliu Brinzeanu
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2022-01-09 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: github_changelog_generator
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rake
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rspec
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rubocop
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: rubocop-performance
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: rubocop-rspec
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ description: Ngrok-wrapper gem is a ruby wrapper for ngrok2
99
+ email:
100
+ - 27bogdanovich@gmail.com
101
+ - branzeanu.aurel@gmail.com
102
+ executables: []
103
+ extensions: []
104
+ extra_rdoc_files: []
105
+ files:
106
+ - ".codeclimate.yml"
107
+ - ".github/workflows/ci.yml"
108
+ - ".github/workflows/codeql-analysis.yml"
109
+ - ".gitignore"
110
+ - ".rspec"
111
+ - ".rubocop.yml"
112
+ - ".ruby-version"
113
+ - ".simplecov"
114
+ - ".tool-versions"
115
+ - CHANGELOG.md
116
+ - Gemfile
117
+ - LICENSE.txt
118
+ - README.md
119
+ - Rakefile
120
+ - disabled.yml
121
+ - enabled.yml
122
+ - lib/ngrok/wrapper.rb
123
+ - lib/ngrok/wrapper/version.rb
124
+ - ngrok-wrapper.gemspec
125
+ - sig/ngrok/wrapper.rbs
126
+ - spec/fixtures/ngrok.no_auth_token.log
127
+ - spec/fixtures/ngrok.sample.log
128
+ - spec/fixtures/ngrok_invalid_auth_token.log
129
+ - spec/ngrok/wrapper_spec.rb
130
+ - spec/spec_helper.rb
131
+ homepage: https://github.com/texpert/ngrok-wrapper
132
+ licenses:
133
+ - MIT
134
+ metadata:
135
+ rubygems_mfa_required: 'true'
136
+ homepage_uri: https://github.com/texpert/ngrok-wrapper
137
+ source_code_uri: https://github.com/texpert/ngrok-wrapper
138
+ changelog_uri: https://github.com/texpert/ngrok-wrapper/blob/main/CHANGELOG.md
139
+ post_install_message:
140
+ rdoc_options: []
141
+ require_paths:
142
+ - lib
143
+ required_ruby_version: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ version: 2.6.0
148
+ required_rubygems_version: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ requirements: []
154
+ rubygems_version: 3.0.3.1
155
+ signing_key:
156
+ specification_version: 4
157
+ summary: Ngrok-wrapper gem is a ruby wrapper for ngrok2
158
+ test_files:
159
+ - spec/fixtures/ngrok.no_auth_token.log
160
+ - spec/fixtures/ngrok.sample.log
161
+ - spec/fixtures/ngrok_invalid_auth_token.log
162
+ - spec/ngrok/wrapper_spec.rb
163
+ - spec/spec_helper.rb