gorynich 1.1.0.142046

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +19 -0
  3. data/README.md +414 -0
  4. data/Rakefile +20 -0
  5. data/config/locales/en.yml +6 -0
  6. data/lib/generators/gorynich/gorynich_generator.rb +9 -0
  7. data/lib/generators/gorynich/install_generator.rb +17 -0
  8. data/lib/generators/templates/gorynich.rb +32 -0
  9. data/lib/gorynich/config.rb +241 -0
  10. data/lib/gorynich/configuration.rb +17 -0
  11. data/lib/gorynich/current.rb +13 -0
  12. data/lib/gorynich/engine.rb +11 -0
  13. data/lib/gorynich/fetcher.rb +54 -0
  14. data/lib/gorynich/fetchers/consul.rb +19 -0
  15. data/lib/gorynich/fetchers/file.rb +22 -0
  16. data/lib/gorynich/head/action_cable.rb +44 -0
  17. data/lib/gorynich/head/active_job.rb +36 -0
  18. data/lib/gorynich/head/active_record.rb +46 -0
  19. data/lib/gorynich/head/delayed_job.rb +22 -0
  20. data/lib/gorynich/head/rack_middleware.rb +34 -0
  21. data/lib/gorynich/head.rb +9 -0
  22. data/lib/gorynich/switcher.rb +48 -0
  23. data/lib/gorynich/version.rb +3 -0
  24. data/lib/gorynich.rb +137 -0
  25. data/lib/tasks/gorynich_tasks.rake +27 -0
  26. data/spec/dummy/Rakefile +6 -0
  27. data/spec/dummy/app/assets/config/manifest.js +3 -0
  28. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  29. data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
  30. data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
  31. data/spec/dummy/app/controllers/application_controller.rb +2 -0
  32. data/spec/dummy/app/controllers/users_controller.rb +10 -0
  33. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  34. data/spec/dummy/app/javascript/packs/application.js +15 -0
  35. data/spec/dummy/app/jobs/application_job.rb +7 -0
  36. data/spec/dummy/app/jobs/test_job.rb +6 -0
  37. data/spec/dummy/app/mailers/application_mailer.rb +4 -0
  38. data/spec/dummy/app/models/application_record.rb +3 -0
  39. data/spec/dummy/app/models/user.rb +2 -0
  40. data/spec/dummy/app/views/layouts/application.html.erb +13 -0
  41. data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
  42. data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
  43. data/spec/dummy/app/views/users/index.html.erb +9 -0
  44. data/spec/dummy/bin/rails +4 -0
  45. data/spec/dummy/bin/rake +4 -0
  46. data/spec/dummy/bin/setup +33 -0
  47. data/spec/dummy/config/application.rb +34 -0
  48. data/spec/dummy/config/boot.rb +5 -0
  49. data/spec/dummy/config/cable.yml +10 -0
  50. data/spec/dummy/config/database.yml +3 -0
  51. data/spec/dummy/config/environment.rb +5 -0
  52. data/spec/dummy/config/environments/development.rb +46 -0
  53. data/spec/dummy/config/environments/production.rb +112 -0
  54. data/spec/dummy/config/environments/test.rb +49 -0
  55. data/spec/dummy/config/gorynich_config.yml +49 -0
  56. data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
  57. data/spec/dummy/config/initializers/assets.rb +12 -0
  58. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  59. data/spec/dummy/config/initializers/content_security_policy.rb +28 -0
  60. data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
  61. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  62. data/spec/dummy/config/initializers/gorynich.rb +34 -0
  63. data/spec/dummy/config/initializers/inflections.rb +16 -0
  64. data/spec/dummy/config/initializers/middleware.rb +0 -0
  65. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  66. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  67. data/spec/dummy/config/locales/en.yml +33 -0
  68. data/spec/dummy/config/puma.rb +38 -0
  69. data/spec/dummy/config/routes.rb +5 -0
  70. data/spec/dummy/config/spring.rb +6 -0
  71. data/spec/dummy/config/storage.yml +34 -0
  72. data/spec/dummy/config.ru +5 -0
  73. data/spec/dummy/db/migrate/20220907101031_create_users.rb +8 -0
  74. data/spec/dummy/public/404.html +67 -0
  75. data/spec/dummy/public/422.html +67 -0
  76. data/spec/dummy/public/500.html +66 -0
  77. data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
  78. data/spec/dummy/public/apple-touch-icon.png +0 -0
  79. data/spec/dummy/public/favicon.ico +0 -0
  80. data/spec/dummy/tmp/development_secret.txt +1 -0
  81. data/spec/fixtures/env_test_database.yml +7 -0
  82. data/spec/fixtures/fetchers/consul_config.yml +1 -0
  83. data/spec/fixtures/fetchers/file_config.yml +46 -0
  84. data/spec/fixtures/fetchers/wrong_file_config.yml +44 -0
  85. data/spec/fixtures/test_database.yml +1 -0
  86. data/spec/lib/gorynich/config_spec.rb +428 -0
  87. data/spec/lib/gorynich/fetcher_spec.rb +112 -0
  88. data/spec/lib/gorynich/fetchers/consul_spec.rb +58 -0
  89. data/spec/lib/gorynich/fetchers/file_spec.rb +29 -0
  90. data/spec/lib/gorynich/version_spec.rb +6 -0
  91. data/spec/lib/gorynich_spec.rb +99 -0
  92. data/spec/rails_helper.rb +8 -0
  93. data/spec/spec_helper.rb +48 -0
  94. metadata +458 -0
@@ -0,0 +1,428 @@
1
+ RSpec.describe Gorynich::Config do
2
+ before(:all) do
3
+ file_path = "#{RSPEC_ROOT}/fixtures/fetchers/file_config.yml"
4
+
5
+ Gorynich.configure do |config|
6
+ config.fetcher = Gorynich::Fetchers::File.new(file_path: file_path)
7
+ end
8
+ end
9
+
10
+ after(:all) do
11
+ Gorynich.reset
12
+ end
13
+
14
+ subject { described_class.new }
15
+
16
+ context '#default' do
17
+ it { expect(subject.default).to eq('default') }
18
+ end
19
+
20
+ context '#fetcher' do
21
+ it do
22
+ expect(subject.fetcher.class).to eq(Gorynich::Fetcher)
23
+ end
24
+ end
25
+
26
+ context '#databases' do
27
+ it do
28
+ expect(subject.databases).to eq(
29
+ {
30
+ 'default' => {
31
+ 'adapter' => 'postgresql',
32
+ 'encoding' => 'unicode',
33
+ 'host' => 'localhost',
34
+ 'pool' => 10,
35
+ 'port' => 5432,
36
+ 'username' => 'xxx',
37
+ 'password' => 'xxx',
38
+ 'database' => 'gorynich_test_default'
39
+ },
40
+ 'local' => {
41
+ 'adapter' => 'postgresql',
42
+ 'encoding' => 'unicode',
43
+ 'host' => 'localhost',
44
+ 'pool' => 10,
45
+ 'port' => 5432,
46
+ 'username' => 'xxx',
47
+ 'password' => 'xxx',
48
+ 'database' => 'gorynich_test_local'
49
+ },
50
+ 'local1' => {
51
+ 'adapter' => 'postgresql',
52
+ 'encoding' => 'unicode',
53
+ 'host' => 'localhost',
54
+ 'pool' => 10,
55
+ 'port' => 5432,
56
+ 'username' => 'xxx',
57
+ 'password' => 'xxx',
58
+ 'database' => 'gorynich_test_local1'
59
+ }
60
+ }
61
+ )
62
+ end
63
+ end
64
+
65
+ context '#database' do
66
+ describe 'when found tenant' do
67
+ it do
68
+ expect(subject.database('default')).to eq(
69
+ {
70
+ 'adapter' => 'postgresql',
71
+ 'encoding' => 'unicode',
72
+ 'host' => 'localhost',
73
+ 'pool' => 10,
74
+ 'port' => 5432,
75
+ 'username' => 'xxx',
76
+ 'password' => 'xxx',
77
+ 'database' => 'gorynich_test_default'
78
+ }
79
+ )
80
+
81
+ expect(subject.database(:default)).to eq(
82
+ {
83
+ 'adapter' => 'postgresql',
84
+ 'encoding' => 'unicode',
85
+ 'host' => 'localhost',
86
+ 'pool' => 10,
87
+ 'port' => 5432,
88
+ 'username' => 'xxx',
89
+ 'password' => 'xxx',
90
+ 'database' => 'gorynich_test_default'
91
+ }
92
+ )
93
+ end
94
+ end
95
+
96
+ describe 'when tenant not found' do
97
+ it do
98
+ expect { subject.database("default#{Faker::Lorem.word}") }.to raise_error(Gorynich::TenantNotFound)
99
+ end
100
+ end
101
+ end
102
+
103
+ context '#uris' do
104
+ describe 'when tenant found' do
105
+ it do
106
+ expect(subject.uris('local')).to eq(
107
+ ['http://localhost:3000']
108
+ )
109
+
110
+ expect(subject.uris(:local)).to eq(
111
+ ['http://localhost:3000']
112
+ )
113
+ end
114
+ end
115
+
116
+ describe 'when tenant not found' do
117
+ it do
118
+ expect { subject.uris("default#{Faker::Lorem.word}") }.to raise_error(Gorynich::TenantNotFound)
119
+ end
120
+ end
121
+
122
+ describe 'when parsing wrong config' do
123
+ let(:file_path) { "#{RSPEC_ROOT}/fixtures/fetchers/wrong_file_config.yml" }
124
+
125
+ it do
126
+ expect { described_class.new(fetcher: Gorynich::Fetchers::File.new(file_path: file_path)) }.to raise_error(
127
+ Gorynich::ConfigError
128
+ )
129
+ end
130
+ end
131
+ end
132
+
133
+ context '#hosts' do
134
+ describe 'when tenant found' do
135
+ it do
136
+ expect(subject.hosts('local')).to eq(
137
+ ['localhost']
138
+ )
139
+
140
+ expect(subject.hosts(:local)).to eq(
141
+ ['localhost']
142
+ )
143
+ end
144
+ end
145
+
146
+ describe 'when tenant not found' do
147
+ it do
148
+ expect { subject.hosts("default#{Faker::Lorem.word}") }.to raise_error(Gorynich::TenantNotFound)
149
+ end
150
+ end
151
+ end
152
+
153
+ context '#secrets' do
154
+ describe 'when tenant found' do
155
+ it do
156
+ expect(subject.secrets('local')).to eq(
157
+ {
158
+ 'uris' => ['http://localhost:3000']
159
+ }
160
+ )
161
+
162
+ expect(subject.secrets(:local)).to eq(
163
+ {
164
+ 'uris' => ['http://localhost:3000']
165
+ }
166
+ )
167
+ end
168
+ end
169
+
170
+ describe 'when tenant not found' do
171
+ it do
172
+ expect { subject.secrets("default#{Faker::Lorem.word}") }.to raise_error(Gorynich::TenantNotFound)
173
+ end
174
+ end
175
+ end
176
+
177
+ context 'tenant_by_uri' do
178
+ describe 'when uri found' do
179
+ it do
180
+ expect(subject.tenant_by_uri('http://localhost:3000')).to eq('local')
181
+ end
182
+ end
183
+
184
+ describe 'when uri not found' do
185
+ let(:uri) { Faker::Internet.url }
186
+
187
+ it do
188
+ expect { subject.tenant_by_uri(uri) }.to raise_error(Gorynich::UriNotFound)
189
+ end
190
+ end
191
+ end
192
+
193
+ context 'tenant_by_host' do
194
+ describe 'when host found' do
195
+ it do
196
+ expect(subject.tenant_by_host('localhost')).to eq('local')
197
+ end
198
+ end
199
+
200
+ describe 'when host not found' do
201
+ let(:host) { Faker::Internet.domain_name }
202
+
203
+ it do
204
+ expect { subject.tenant_by_host(host) }.to raise_error(Gorynich::HostNotFound)
205
+ end
206
+ end
207
+ end
208
+
209
+ context '#config' do
210
+ describe 'when tenant found' do
211
+ it do
212
+ expect(subject.config('local')).to eq(
213
+ tenant: 'local',
214
+ database: {
215
+ 'adapter' => 'postgresql',
216
+ 'encoding' => 'unicode',
217
+ 'host' => 'localhost',
218
+ 'pool' => 10,
219
+ 'port' => 5432,
220
+ 'username' => 'xxx',
221
+ 'password' => 'xxx',
222
+ 'database' => 'gorynich_test_local'
223
+ },
224
+ secrets: {
225
+ 'uris' => ['http://localhost:3000']
226
+ }
227
+ )
228
+
229
+ expect(subject.config(:local)).to eq(
230
+ tenant: 'local',
231
+ database: {
232
+ 'adapter' => 'postgresql',
233
+ 'encoding' => 'unicode',
234
+ 'host' => 'localhost',
235
+ 'pool' => 10,
236
+ 'port' => 5432,
237
+ 'username' => 'xxx',
238
+ 'password' => 'xxx',
239
+ 'database' => 'gorynich_test_local'
240
+ },
241
+ secrets: {
242
+ 'uris' => ['http://localhost:3000']
243
+ }
244
+ )
245
+ end
246
+ end
247
+ end
248
+
249
+ context '#database_config' do
250
+ describe 'when without env' do
251
+ it do
252
+ expect(subject.database_config).to include('development', 'test')
253
+ end
254
+ end
255
+
256
+ describe 'when with end' do
257
+ it do
258
+ dev_res = subject.database_config('development')
259
+ expect(dev_res).to include('gorynich_local')
260
+ expect(dev_res).not_to include('gorynich_test_local')
261
+
262
+ test_res = subject.database_config('test')
263
+ expect(test_res).to include('gorynich_test_local')
264
+ expect(test_res).not_to include('gorynich_local')
265
+ end
266
+ end
267
+
268
+ describe 'when use in file just tenants' do
269
+ let(:database_yml) { File.read("#{RSPEC_ROOT}/fixtures/test_database.yml") }
270
+
271
+ subject { ::YAML.load(::ERB.new(database_yml).result) }
272
+
273
+ it do
274
+ expect(subject).to eq(
275
+ {
276
+ 'development' => {
277
+ 'default' => {
278
+ 'adapter' => 'postgresql',
279
+ 'encoding' => 'unicode',
280
+ 'host' => 'localhost',
281
+ 'pool' => 10,
282
+ 'port' => 5432,
283
+ 'username' => 'xxx',
284
+ 'password' => 'xxx',
285
+ 'database' => 'gorynich_default'
286
+ },
287
+ 'local' => {
288
+ 'adapter' => 'postgresql',
289
+ 'encoding' => 'unicode',
290
+ 'host' => 'localhost',
291
+ 'pool' => 10,
292
+ 'port' => 5432,
293
+ 'username' => 'xxx',
294
+ 'password' => 'xxx',
295
+ 'database' => 'gorynich_local'
296
+ },
297
+ 'local1' => {
298
+ 'adapter' => 'postgresql',
299
+ 'encoding' => 'unicode',
300
+ 'host' => 'localhost',
301
+ 'pool' => 10,
302
+ 'port' => 5432,
303
+ 'username' => 'xxx',
304
+ 'password' => 'xxx',
305
+ 'database' => 'gorynich_local1'
306
+ }
307
+ },
308
+ 'test' => {
309
+ 'default' => {
310
+ 'adapter' => 'postgresql',
311
+ 'encoding' => 'unicode',
312
+ 'host' => 'localhost',
313
+ 'pool' => 10,
314
+ 'port' => 5432,
315
+ 'username' => 'xxx',
316
+ 'password' => 'xxx',
317
+ 'database' => 'gorynich_test_default'
318
+ },
319
+ 'local' => {
320
+ 'adapter' => 'postgresql',
321
+ 'encoding' => 'unicode',
322
+ 'host' => 'localhost',
323
+ 'pool' => 10,
324
+ 'port' => 5432,
325
+ 'username' => 'xxx',
326
+ 'password' => 'xxx',
327
+ 'database' => 'gorynich_test_local'
328
+ },
329
+ 'local1' => {
330
+ 'adapter' => 'postgresql',
331
+ 'encoding' => 'unicode',
332
+ 'host' => 'localhost',
333
+ 'pool' => 10,
334
+ 'port' => 5432,
335
+ 'username' => 'xxx',
336
+ 'password' => 'xxx',
337
+ 'database' => 'gorynich_test_local1'
338
+ }
339
+ }
340
+ }
341
+ )
342
+ end
343
+ end
344
+
345
+ describe 'when use in file with tenants and customs configs' do
346
+ let(:database_yml) { File.read("#{RSPEC_ROOT}/fixtures/env_test_database.yml") }
347
+
348
+ subject { ::YAML.load(::ERB.new(database_yml).result) }
349
+
350
+ it do
351
+ expect(subject).to eq(
352
+ {
353
+ 'development' => {
354
+ 'default' => {
355
+ 'adapter' => 'postgresql',
356
+ 'encoding' => 'unicode',
357
+ 'host' => 'localhost',
358
+ 'pool' => 10,
359
+ 'port' => 5432,
360
+ 'username' => 'xxx',
361
+ 'password' => 'xxx',
362
+ 'database' => 'gorynich_default'
363
+ },
364
+ 'local' => {
365
+ 'adapter' => 'postgresql',
366
+ 'encoding' => 'unicode',
367
+ 'host' => 'localhost',
368
+ 'pool' => 10,
369
+ 'port' => 5432,
370
+ 'username' => 'xxx',
371
+ 'password' => 'xxx',
372
+ 'database' => 'gorynich_local'
373
+ },
374
+ 'local1' => {
375
+ 'adapter' => 'postgresql',
376
+ 'encoding' => 'unicode',
377
+ 'host' => 'localhost',
378
+ 'pool' => 10,
379
+ 'port' => 5432,
380
+ 'username' => 'xxx',
381
+ 'password' => 'xxx',
382
+ 'database' => 'gorynich_local1'
383
+ },
384
+ 'shared' => {
385
+ 'host' => 'dev'
386
+ }
387
+ },
388
+ 'test' => {
389
+ 'default' => {
390
+ 'adapter' => 'postgresql',
391
+ 'encoding' => 'unicode',
392
+ 'host' => 'localhost',
393
+ 'pool' => 10,
394
+ 'port' => 5432,
395
+ 'username' => 'xxx',
396
+ 'password' => 'xxx',
397
+ 'database' => 'gorynich_test_default'
398
+ },
399
+ 'local' => {
400
+ 'adapter' => 'postgresql',
401
+ 'encoding' => 'unicode',
402
+ 'host' => 'localhost',
403
+ 'pool' => 10,
404
+ 'port' => 5432,
405
+ 'username' => 'xxx',
406
+ 'password' => 'xxx',
407
+ 'database' => 'gorynich_test_local'
408
+ },
409
+ 'local1' => {
410
+ 'adapter' => 'postgresql',
411
+ 'encoding' => 'unicode',
412
+ 'host' => 'localhost',
413
+ 'pool' => 10,
414
+ 'port' => 5432,
415
+ 'username' => 'xxx',
416
+ 'password' => 'xxx',
417
+ 'database' => 'gorynich_test_local1'
418
+ },
419
+ 'shared' => {
420
+ 'host' => 'test'
421
+ }
422
+ }
423
+ }
424
+ )
425
+ end
426
+ end
427
+ end
428
+ end
@@ -0,0 +1,112 @@
1
+ RSpec.describe Gorynich::Fetcher do
2
+ let(:file_path) { "#{RSPEC_ROOT}/fixtures/fetchers/file_config.yml" }
3
+ let(:consul_storage) { Faker::Lorem.word }
4
+ let(:consul_host) { Faker::Internet.url }
5
+ let(:consul_opts) { { http_addr: consul_host } }
6
+ let(:consul_response) { [{ 'Key' => "#{consul_storage}/test_key", 'Value' => Base64.encode64('test') }].to_json }
7
+
8
+ def consul_request(response, code = 200)
9
+ stub_request(:get, "#{consul_host}/v1/kv/#{consul_storage}?recurse=true")
10
+ .to_return(
11
+ status: code,
12
+ body: response
13
+ )
14
+ end
15
+
16
+ context '#new' do
17
+ let(:fetcher) { Gorynich::Fetchers::File.new(file_path: file_path) }
18
+ let(:namespace) { Faker::Lorem.word }
19
+ let(:cache_expiration) { Faker::Number.between(from: 1, to: 10).minutes }
20
+
21
+ describe 'when from config' do
22
+ before(:each) do
23
+ Gorynich.configure do |config|
24
+ config.fetcher = fetcher
25
+ config.namespace = namespace
26
+ config.cache_expiration = cache_expiration
27
+ end
28
+ end
29
+
30
+ subject { described_class.new }
31
+
32
+ it do
33
+ expect(subject.fetcher).to eq(fetcher)
34
+ expect(subject.namespace).to eq(namespace)
35
+ expect(subject.cache_expiration).to eq(cache_expiration)
36
+ end
37
+ end
38
+
39
+ describe 'when from initialize' do
40
+ before(:each) { Gorynich.reset }
41
+
42
+ subject { described_class.new(fetcher: fetcher, namespace: namespace, cache_expiration: cache_expiration) }
43
+
44
+ it do
45
+ expect(subject.fetcher).to eq(fetcher)
46
+ expect(subject.namespace).to eq(namespace)
47
+ expect(subject.cache_expiration).to eq(cache_expiration)
48
+ end
49
+ end
50
+ end
51
+
52
+ context '#fetch' do
53
+ before(:each) { Gorynich.configuration.cache.clear }
54
+
55
+ describe 'when no fetcher' do
56
+ subject { described_class.new }
57
+
58
+ it do
59
+ expect { subject.fetch }.to raise_error(Gorynich::Error)
60
+ end
61
+ end
62
+
63
+ describe 'when one fetcher' do
64
+ let(:fetcher) { Gorynich::Fetchers::File.new(file_path: file_path) }
65
+
66
+ subject { described_class.new(fetcher: fetcher) }
67
+
68
+ it do
69
+ result = subject.fetch
70
+ expect(result.class).to eq(Hash)
71
+ expect(result).to include('development', 'test')
72
+ end
73
+ end
74
+
75
+ describe 'when some fetchers' do
76
+ let(:file_fetcher) { Gorynich::Fetchers::File.new(file_path: file_path) }
77
+ let(:consul_fetcher) { Gorynich::Fetchers::Consul.new(storage: consul_storage, **consul_opts) }
78
+
79
+ subject { described_class.new(fetcher: [consul_fetcher, file_fetcher]) }
80
+
81
+ describe 'when consul fetch success' do
82
+ before(:each) { consul_request(consul_response) }
83
+
84
+ it do
85
+ expect(subject.fetch).to eq({ 'test_key' => 'test' })
86
+ end
87
+ end
88
+
89
+ describe 'when consul fetch failed' do
90
+ before(:each) do
91
+ Gorynich.configuration.cache = ActiveSupport::Cache::MemoryStore.new
92
+ consul_request(consul_response, 500)
93
+ end
94
+
95
+ it do
96
+ expect(subject.fetch).to include('development', 'test')
97
+ end
98
+ end
99
+ end
100
+ end
101
+
102
+ context 'fetch with cache' do
103
+ let(:fetcher) { Gorynich::Fetchers::File.new(file_path: file_path) }
104
+
105
+ subject { described_class.new(fetcher: fetcher) }
106
+
107
+ it do
108
+ expect(subject.fetch).to include('development', 'test')
109
+ expect(Gorynich.configuration.cache.exist?(%i[gorynich fetcher fetch])).to be(true)
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,58 @@
1
+ RSpec.describe Gorynich::Fetchers::Consul do
2
+ let(:storage) { Faker::Lorem.word }
3
+
4
+ context '#storage' do
5
+ subject { described_class.new(storage: storage) }
6
+
7
+ it do
8
+ expect(subject.storage).to eq(storage)
9
+ end
10
+ end
11
+
12
+ context '#consul_opts' do
13
+ let(:consul_opts) { { Faker::Lorem.word.to_sym => Faker::Lorem.word } }
14
+
15
+ subject { described_class.new(storage: storage, **consul_opts) }
16
+
17
+ it do
18
+ expect(subject.consul_opts).to eq(consul_opts)
19
+ end
20
+ end
21
+
22
+ context '#fetch' do
23
+ let(:consul_host) { Faker::Internet.url }
24
+ let(:consul_opts) { { http_addr: consul_host } }
25
+
26
+ def consul_request(response, code = 200)
27
+ stub_request(:get, "#{consul_host}/v1/kv/#{storage}?recurse=true")
28
+ .to_return(
29
+ status: code,
30
+ body: response
31
+ )
32
+ end
33
+
34
+ subject { described_class.new(storage: storage, **consul_opts) }
35
+
36
+ describe 'when consul return data' do
37
+ let(:response) { [{ 'Key' => "#{storage}/test_key", 'Value' => Base64.encode64('test') }].to_json }
38
+
39
+ before(:each) do
40
+ consul_request(response)
41
+ end
42
+
43
+ it do
44
+ expect(subject.fetch).to eq({ 'test_key' => 'test' })
45
+ end
46
+ end
47
+
48
+ describe 'when http error' do
49
+ before(:each) do
50
+ consul_request([], 500)
51
+ end
52
+
53
+ it do
54
+ expect { subject.fetch }.to raise_error(Diplomat::UnknownStatus)
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,29 @@
1
+ RSpec.describe Gorynich::Fetchers::File do
2
+ let(:file_path) { "#{RSPEC_ROOT}/fixtures/fetchers/file_config.yml" }
3
+
4
+ subject { described_class.new(file_path: file_path) }
5
+
6
+ context '#file_path' do
7
+ it do
8
+ expect(subject.file_path).to eq(file_path)
9
+ end
10
+ end
11
+
12
+ context '#fetch' do
13
+ describe 'when file not exists' do
14
+ let(:file_path) { Faker::Lorem.word }
15
+
16
+ it do
17
+ expect { subject.fetch }.to raise_error(Errno::ENOENT)
18
+ end
19
+ end
20
+
21
+ describe 'when file exists' do
22
+ it do
23
+ result = subject.fetch
24
+ expect(result.class).to eq(Hash)
25
+ expect(result).to include('development', 'test')
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,6 @@
1
+ RSpec.describe Gorynich do
2
+ it 'has a version number' do
3
+ expect(Gorynich::VERSION).not_to be nil
4
+ end
5
+ end
6
+