application_setting_spec.rb 18.4 KB
Newer Older
1
2
require 'spec_helper'

3
describe ApplicationSetting do
4
  let(:setting) { described_class.create_from_defaults }
5

Kamil Trzcinski's avatar
Kamil Trzcinski committed
6
  it { expect(setting).to be_valid }
7
  it { expect(setting.uuid).to be_present }
8
  it { expect(setting).to have_db_column(:auto_devops_enabled) }
9

Robert Speicher's avatar
Robert Speicher committed
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  describe 'validations' do
    let(:http)  { 'http://example.com' }
    let(:https) { 'https://example.com' }
    let(:ftp)   { 'ftp://example.com' }

    it { is_expected.to allow_value(nil).for(:home_page_url) }
    it { is_expected.to allow_value(http).for(:home_page_url) }
    it { is_expected.to allow_value(https).for(:home_page_url) }
    it { is_expected.not_to allow_value(ftp).for(:home_page_url) }

    it { is_expected.to allow_value(nil).for(:after_sign_out_path) }
    it { is_expected.to allow_value(http).for(:after_sign_out_path) }
    it { is_expected.to allow_value(https).for(:after_sign_out_path) }
    it { is_expected.not_to allow_value(ftp).for(:after_sign_out_path) }
24

25
26
27
28
29
30
31
32
    describe 'disabled_oauth_sign_in_sources validations' do
      before do
        allow(Devise).to receive(:omniauth_providers).and_return([:github])
      end

      it { is_expected.to allow_value(['github']).for(:disabled_oauth_sign_in_sources) }
      it { is_expected.not_to allow_value(['test']).for(:disabled_oauth_sign_in_sources) }
    end
33

34
    describe 'default_artifacts_expire_in' do
35
      it 'sets an error if it cannot parse' do
36
37
        setting.update(default_artifacts_expire_in: 'a')

38
        expect_invalid
39
40
      end

41
42
      it 'sets an error if it is blank' do
        setting.update(default_artifacts_expire_in: ' ')
43

44
        expect_invalid
45
46
      end

47
48
49
50
51
52
53
      it 'sets the value if it is valid' do
        setting.update(default_artifacts_expire_in: '30 days')

        expect(setting).to be_valid
        expect(setting.default_artifacts_expire_in).to eq('30 days')
      end

54
55
      it 'sets the value if it is 0' do
        setting.update(default_artifacts_expire_in: '0')
56
57

        expect(setting).to be_valid
58
59
60
61
62
63
        expect(setting.default_artifacts_expire_in).to eq('0')
      end

      def expect_invalid
        expect(setting).to be_invalid
        expect(setting.errors.messages)
64
          .to have_key(:default_artifacts_expire_in)
65
66
67
      end
    end

68
69
70
71
72
73
74
    it { is_expected.to validate_presence_of(:max_attachment_size) }

    it do
      is_expected.to validate_numericality_of(:max_attachment_size)
        .only_integer
        .is_greater_than(0)
    end
75

76
77
78
79
    context 'key restrictions' do
      it 'supports all key types' do
        expect(described_class::SUPPORTED_KEY_TYPES).to contain_exactly(:rsa, :dsa, :ecdsa, :ed25519)
      end
80

Nick Thomas's avatar
Nick Thomas committed
81
82
83
84
85
86
87
88
89
      it 'does not allow all key types to be disabled' do
        described_class::SUPPORTED_KEY_TYPES.each do |type|
          setting["#{type}_key_restriction"] = described_class::FORBIDDEN_KEY_VALUE
        end

        expect(setting).not_to be_valid
        expect(setting.errors.messages).to have_key(:allowed_key_types)
      end

90
91
92
      where(:type) do
        described_class::SUPPORTED_KEY_TYPES
      end
93

94
95
      with_them do
        let(:field) { :"#{type}_key_restriction" }
96

97
        it { is_expected.to validate_presence_of(field) }
98
        it { is_expected.to allow_value(*KeyRestrictionValidator.supported_key_restrictions(type)).for(field) }
99
100
        it { is_expected.not_to allow_value(128).for(field) }
      end
101
102
    end

103
104
105
    it_behaves_like 'an object with email-formated attributes', :admin_notification_email do
      subject { setting }
    end
106

107
108
    # Upgraded databases will have this sort of content
    context 'repository_storages is a String, not an Array' do
109
110
111
      before do
        setting.__send__(:raw_write_attribute, :repository_storages, 'default')
      end
112
113
114
115
116

      it { expect(setting.repository_storages_before_type_cast).to eq('default') }
      it { expect(setting.repository_storages).to eq(['default']) }
    end

117
118
119
120
121
122
123
124
125
126
127
128
129
    context 'circuitbreaker settings' do
      [:circuitbreaker_failure_count_threshold,
       :circuitbreaker_failure_wait_time,
       :circuitbreaker_failure_reset_time,
       :circuitbreaker_storage_timeout].each do |field|
        it "Validates #{field} as number" do
          is_expected.to validate_numericality_of(field)
                           .only_integer
                           .is_greater_than_or_equal_to(0)
        end
      end
    end

130
    context 'repository storages' do
131
      before do
132
133
134
        storages = {
          'custom1' => 'tmp/tests/custom_repositories_1',
          'custom2' => 'tmp/tests/custom_repositories_2',
135
          'custom3' => 'tmp/tests/custom_repositories_3'
136
137

        }
138
139
140
        allow(Gitlab.config.repositories).to receive(:storages).and_return(storages)
      end

141
142
      describe 'inclusion' do
        it { is_expected.to allow_value('custom1').for(:repository_storages) }
Douwe Maan's avatar
Douwe Maan committed
143
        it { is_expected.to allow_value(%w(custom2 custom3)).for(:repository_storages) }
144
        it { is_expected.not_to allow_value('alternative').for(:repository_storages) }
Douwe Maan's avatar
Douwe Maan committed
145
        it { is_expected.not_to allow_value(%w(alternative custom1)).for(:repository_storages) }
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
      end

      describe 'presence' do
        it { is_expected.not_to allow_value([]).for(:repository_storages) }
        it { is_expected.not_to allow_value("").for(:repository_storages) }
        it { is_expected.not_to allow_value(nil).for(:repository_storages) }
      end

      describe '.pick_repository_storage' do
        it 'uses Array#sample to pick a random storage' do
          array = double('array', sample: 'random')
          expect(setting).to receive(:repository_storages).and_return(array)

          expect(setting.pick_repository_storage).to eq('random')
        end

        describe '#repository_storage' do
          it 'returns the first storage' do
Douwe Maan's avatar
Douwe Maan committed
164
            setting.repository_storages = %w(good bad)
165
166
167
168
169
170
171
172
173
174
175
176
177

            expect(setting.repository_storage).to eq('good')
          end
        end

        describe '#repository_storage=' do
          it 'overwrites repository_storages' do
            setting.repository_storage = 'overwritten'

            expect(setting.repository_storages).to eq(['overwritten'])
          end
        end
      end
178
    end
Jacob Vosmaer's avatar
Jacob Vosmaer committed
179
180
181
182

    context 'housekeeping settings' do
      it { is_expected.not_to allow_value(0).for(:housekeeping_incremental_repack_period) }

183
      it 'wants the full repack period to be at least the incremental repack period' do
Jacob Vosmaer's avatar
Jacob Vosmaer committed
184
185
186
187
188
189
        subject.housekeeping_incremental_repack_period = 2
        subject.housekeeping_full_repack_period = 1

        expect(subject).not_to be_valid
      end

190
191
192
      it 'wants the gc period to be at least the full repack period' do
        subject.housekeeping_full_repack_period = 100
        subject.housekeeping_gc_period = 90
Jacob Vosmaer's avatar
Jacob Vosmaer committed
193
194
195

        expect(subject).not_to be_valid
      end
196
197
198
199
200
201
202
203
204
205
206
207
208
209

      it 'allows the same period for incremental repack and full repack, effectively skipping incremental repack' do
        subject.housekeeping_incremental_repack_period = 2
        subject.housekeeping_full_repack_period = 2

        expect(subject).to be_valid
      end

      it 'allows the same period for full repack and gc, effectively skipping full repack' do
        subject.housekeeping_full_repack_period = 100
        subject.housekeeping_gc_period = 100

        expect(subject).to be_valid
      end
210
211
212
213
214
215
216
    end
  end

  describe '.current' do
    context 'redis unavailable' do
      it 'returns an ApplicationSetting' do
        allow(Rails.cache).to receive(:fetch).and_call_original
217
        allow(described_class).to receive(:last).and_return(:last)
218
219
        expect(Rails.cache).to receive(:fetch).with(ApplicationSetting::CACHE_KEY).and_raise(ArgumentError)

220
        expect(described_class.current).to eq(:last)
221
      end
Jacob Vosmaer's avatar
Jacob Vosmaer committed
222
    end
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237

    context 'when an ApplicationSetting is not yet present' do
      it 'does not cache nil object' do
        # when missing settings a nil object is returned, but not cached
        allow(described_class).to receive(:last).and_return(nil).twice
        expect(described_class.current).to be_nil

        # when the settings are set the method returns a valid object
        allow(described_class).to receive(:last).and_return(:last)
        expect(described_class.current).to eq(:last)

        # subsequent calls get everything from cache
        expect(described_class.current).to eq(:last)
      end
    end
Robert Speicher's avatar
Robert Speicher committed
238
239
  end

240
241
242
243
244
245
246
247
248
249
  context 'restrict creating duplicates' do
    before do
      described_class.create_from_defaults
    end

    it 'raises an record creation violation if already created' do
      expect { described_class.create_from_defaults }.to raise_error(ActiveRecord::RecordNotUnique)
    end
  end

Kamil Trzcinski's avatar
Kamil Trzcinski committed
250
  context 'restricted signup domains' do
251
    it 'sets single domain' do
252
253
      setting.domain_whitelist_raw = 'example.com'
      expect(setting.domain_whitelist).to eq(['example.com'])
254
255
    end

256
    it 'sets multiple domains with spaces' do
257
258
      setting.domain_whitelist_raw = 'example.com *.example.com'
      expect(setting.domain_whitelist).to eq(['example.com', '*.example.com'])
259
260
    end

261
    it 'sets multiple domains with newlines and a space' do
262
263
      setting.domain_whitelist_raw = "example.com\n *.example.com"
      expect(setting.domain_whitelist).to eq(['example.com', '*.example.com'])
264
265
    end

266
    it 'sets multiple domains with commas' do
267
268
      setting.domain_whitelist_raw = "example.com, *.example.com"
      expect(setting.domain_whitelist).to eq(['example.com', '*.example.com'])
269
270
    end
  end
271
272

  context 'blacklisted signup domains' do
273
    it 'sets single domain' do
274
      setting.domain_blacklist_raw = 'example.com'
275
      expect(setting.domain_blacklist).to contain_exactly('example.com')
276
277
    end

278
    it 'sets multiple domains with spaces' do
279
      setting.domain_blacklist_raw = 'example.com *.example.com'
280
      expect(setting.domain_blacklist).to contain_exactly('example.com', '*.example.com')
281
282
    end

283
    it 'sets multiple domains with newlines and a space' do
284
      setting.domain_blacklist_raw = "example.com\n *.example.com"
285
      expect(setting.domain_blacklist).to contain_exactly('example.com', '*.example.com')
286
287
    end

288
    it 'sets multiple domains with commas' do
289
      setting.domain_blacklist_raw = "example.com, *.example.com"
290
      expect(setting.domain_blacklist).to contain_exactly('example.com', '*.example.com')
291
292
    end

293
    it 'sets multiple domains with semicolon' do
294
295
296
297
      setting.domain_blacklist_raw = "example.com; *.example.com"
      expect(setting.domain_blacklist).to contain_exactly('example.com', '*.example.com')
    end

298
    it 'sets multiple domains with mixture of everything' do
299
300
301
302
      setting.domain_blacklist_raw = "example.com; *.example.com\n test.com\sblock.com   yes.com"
      expect(setting.domain_blacklist).to contain_exactly('example.com', '*.example.com', 'test.com', 'block.com', 'yes.com')
    end

303
    it 'sets multiple domain with file' do
304
      setting.domain_blacklist_file = File.open(Rails.root.join('spec/fixtures/', 'domain_blacklist.txt'))
305
      expect(setting.domain_blacklist).to contain_exactly('example.com', 'test.com', 'foo.bar')
306
307
    end
  end
308

309
  describe 'performance bar settings' do
310
311
312
313
314
    describe 'performance_bar_allowed_group_id=' do
      context 'with a blank path' do
        before do
          setting.performance_bar_allowed_group_id = create(:group).full_path
        end
315

316
317
        it 'persists nil for a "" path and clears allowed user IDs cache' do
          expect(Gitlab::PerformanceBar).to receive(:expire_allowed_user_ids_cache)
318

319
320
321
322
323
324
325
326
327
          setting.performance_bar_allowed_group_id = ''

          expect(setting.performance_bar_allowed_group_id).to be_nil
        end
      end

      context 'with an invalid path' do
        it 'does not persist an invalid group path' do
          setting.performance_bar_allowed_group_id = 'foo'
328

329
330
          expect(setting.performance_bar_allowed_group_id).to be_nil
        end
331
332
333
334
335
336
337
338
339
340
341
342
343
344
      end

      context 'with a path to an existing group' do
        let(:group) { create(:group) }

        it 'persists a valid group path and clears allowed user IDs cache' do
          expect(Gitlab::PerformanceBar).to receive(:expire_allowed_user_ids_cache)

          setting.performance_bar_allowed_group_id = group.full_path

          expect(setting.performance_bar_allowed_group_id).to eq(group.id)
        end

        context 'when the given path is the same' do
345
346
347
348
349
350
351
352
353
354
          context 'with a blank path' do
            before do
              setting.performance_bar_allowed_group_id = nil
            end

            it 'clears the cached allowed user IDs' do
              expect(Gitlab::PerformanceBar).not_to receive(:expire_allowed_user_ids_cache)

              setting.performance_bar_allowed_group_id = ''
            end
355
356
          end

357
358
359
360
361
362
363
          context 'with a valid path' do
            before do
              setting.performance_bar_allowed_group_id = group.full_path
            end

            it 'clears the cached allowed user IDs' do
              expect(Gitlab::PerformanceBar).not_to receive(:expire_allowed_user_ids_cache)
364

365
366
              setting.performance_bar_allowed_group_id = group.full_path
            end
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
          end
        end
      end
    end

    describe 'performance_bar_allowed_group' do
      context 'with no performance_bar_allowed_group_id saved' do
        it 'returns nil' do
          expect(setting.performance_bar_allowed_group).to be_nil
        end
      end

      context 'with a performance_bar_allowed_group_id saved' do
        let(:group) { create(:group) }

        before do
          setting.performance_bar_allowed_group_id = group.full_path
        end

        it 'returns the group' do
          expect(setting.performance_bar_allowed_group).to eq(group)
        end
      end
    end

392
393
394
    describe 'performance_bar_enabled' do
      context 'with the Performance Bar is enabled' do
        let(:group) { create(:group) }
395
396

        before do
397
          setting.performance_bar_allowed_group_id = group.full_path
398
399
400
        end

        it 'returns true' do
401
          expect(setting.performance_bar_enabled).to be_truthy
402
403
404
405
406
407
        end
      end
    end

    describe 'performance_bar_enabled=' do
      context 'when the performance bar is enabled' do
408
409
        let(:group) { create(:group) }

410
        before do
411
          setting.performance_bar_allowed_group_id = group.full_path
412
413
414
415
416
        end

        context 'when passing true' do
          it 'does not clear allowed user IDs cache' do
            expect(Gitlab::PerformanceBar).not_to receive(:expire_allowed_user_ids_cache)
417

418
419
            setting.performance_bar_enabled = true

420
421
            expect(setting.performance_bar_allowed_group_id).to eq(group.id)
            expect(setting.performance_bar_enabled).to be_truthy
422
423
424
425
426
427
          end
        end

        context 'when passing false' do
          it 'disables the performance bar and clears allowed user IDs cache' do
            expect(Gitlab::PerformanceBar).to receive(:expire_allowed_user_ids_cache)
428

429
430
            setting.performance_bar_enabled = false

431
432
            expect(setting.performance_bar_allowed_group_id).to be_nil
            expect(setting.performance_bar_enabled).to be_falsey
433
434
435
436
437
438
          end
        end
      end

      context 'when the performance bar is disabled' do
        context 'when passing true' do
439
440
441
          it 'does nothing and does not clear allowed user IDs cache' do
            expect(Gitlab::PerformanceBar).not_to receive(:expire_allowed_user_ids_cache)

442
443
            setting.performance_bar_enabled = true

444
445
            expect(setting.performance_bar_allowed_group_id).to be_nil
            expect(setting.performance_bar_enabled).to be_falsey
446
447
448
449
          end
        end

        context 'when passing false' do
450
          it 'does nothing and does not clear allowed user IDs cache' do
451
            expect(Gitlab::PerformanceBar).not_to receive(:expire_allowed_user_ids_cache)
452

453
454
            setting.performance_bar_enabled = false

455
456
            expect(setting.performance_bar_allowed_group_id).to be_nil
            expect(setting.performance_bar_enabled).to be_falsey
457
458
459
460
461
462
          end
        end
      end
    end
  end

463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
  describe 'usage ping settings' do
    context 'when the usage ping is disabled in gitlab.yml' do
      before do
        allow(Settings.gitlab).to receive(:usage_ping_enabled).and_return(false)
      end

      it 'does not allow the usage ping to be configured' do
        expect(setting.usage_ping_can_be_configured?).to be_falsey
      end

      context 'when the usage ping is disabled in the DB' do
        before do
          setting.usage_ping_enabled = false
        end

        it 'returns false for usage_ping_enabled' do
          expect(setting.usage_ping_enabled).to be_falsey
        end
      end

      context 'when the usage ping is enabled in the DB' do
        before do
          setting.usage_ping_enabled = true
        end

        it 'returns false for usage_ping_enabled' do
          expect(setting.usage_ping_enabled).to be_falsey
        end
      end
    end

    context 'when the usage ping is enabled in gitlab.yml' do
      before do
        allow(Settings.gitlab).to receive(:usage_ping_enabled).and_return(true)
      end

      it 'allows the usage ping to be configured' do
        expect(setting.usage_ping_can_be_configured?).to be_truthy
      end

      context 'when the usage ping is disabled in the DB' do
        before do
          setting.usage_ping_enabled = false
        end

        it 'returns false for usage_ping_enabled' do
          expect(setting.usage_ping_enabled).to be_falsey
        end
      end

      context 'when the usage ping is enabled in the DB' do
        before do
          setting.usage_ping_enabled = true
        end

        it 'returns true for usage_ping_enabled' do
          expect(setting.usage_ping_enabled).to be_truthy
        end
      end
    end
  end
524

525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
  describe '#allowed_key_types' do
    it 'includes all key types by default' do
      expect(setting.allowed_key_types).to contain_exactly(*described_class::SUPPORTED_KEY_TYPES)
    end

    it 'excludes disabled key types' do
      expect(setting.allowed_key_types).to include(:ed25519)

      setting.ed25519_key_restriction = described_class::FORBIDDEN_KEY_VALUE

      expect(setting.allowed_key_types).not_to include(:ed25519)
    end
  end

  describe '#key_restriction_for' do
    it 'returns the restriction value for recognised types' do
      setting.rsa_key_restriction = 1024

      expect(setting.key_restriction_for(:rsa)).to eq(1024)
    end

    it 'allows types to be passed as a string' do
      setting.rsa_key_restriction = 1024

      expect(setting.key_restriction_for('rsa')).to eq(1024)
550
551
    end

552
553
    it 'returns forbidden for unrecognised type' do
      expect(setting.key_restriction_for(:foo)).to eq(described_class::FORBIDDEN_KEY_VALUE)
554
555
    end
  end
556
end