From 7021455bd1ed7b125c55eb1b33c5a01f2bc55ee0 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Thu, 17 Nov 2022 11:33:21 +0000 Subject: Add latest changes from gitlab-org/gitlab@15-6-stable-ee --- spec/models/hooks/web_hook_spec.rb | 142 ++++++++++++++++++++++++++++++++----- 1 file changed, 125 insertions(+), 17 deletions(-) (limited to 'spec/models/hooks/web_hook_spec.rb') diff --git a/spec/models/hooks/web_hook_spec.rb b/spec/models/hooks/web_hook_spec.rb index da8c10b67a6..db854670cc3 100644 --- a/spec/models/hooks/web_hook_spec.rb +++ b/spec/models/hooks/web_hook_spec.rb @@ -34,6 +34,11 @@ RSpec.describe WebHook do it { is_expected.to allow_value({ 'x' => ('a' * 100) }).for(:url_variables) } it { is_expected.to allow_value({ 'foo' => 'bar', 'bar' => 'baz' }).for(:url_variables) } it { is_expected.to allow_value((1..20).to_h { ["k#{_1}", 'value'] }).for(:url_variables) } + it { is_expected.to allow_value({ 'MY-TOKEN' => 'bar' }).for(:url_variables) } + it { is_expected.to allow_value({ 'my_secr3t-token' => 'bar' }).for(:url_variables) } + it { is_expected.to allow_value({ 'x-y-z' => 'bar' }).for(:url_variables) } + it { is_expected.to allow_value({ 'x_y_z' => 'bar' }).for(:url_variables) } + it { is_expected.to allow_value({ 'f.o.o' => 'bar' }).for(:url_variables) } it { is_expected.not_to allow_value([]).for(:url_variables) } it { is_expected.not_to allow_value({ 'foo' => 1 }).for(:url_variables) } @@ -45,6 +50,10 @@ RSpec.describe WebHook do it { is_expected.not_to allow_value({ '' => 'foo' }).for(:url_variables) } it { is_expected.not_to allow_value({ '1foo' => 'foo' }).for(:url_variables) } it { is_expected.not_to allow_value((1..21).to_h { ["k#{_1}", 'value'] }).for(:url_variables) } + it { is_expected.not_to allow_value({ 'MY--TOKEN' => 'foo' }).for(:url_variables) } + it { is_expected.not_to allow_value({ 'MY__SECRET' => 'foo' }).for(:url_variables) } + it { is_expected.not_to allow_value({ 'x-_y' => 'foo' }).for(:url_variables) } + it { is_expected.not_to allow_value({ 'x..y' => 'foo' }).for(:url_variables) } end describe 'url' do @@ -83,7 +92,7 @@ RSpec.describe WebHook do subject { hook } before do - hook.url_variables = { 'one' => 'a', 'two' => 'b' } + hook.url_variables = { 'one' => 'a', 'two' => 'b', 'url' => 'http://example.com' } end it { is_expected.to allow_value('http://example.com').for(:url) } @@ -92,6 +101,8 @@ RSpec.describe WebHook do it { is_expected.to allow_value('http://example.com/{two}').for(:url) } it { is_expected.to allow_value('http://user:s3cret@example.com/{two}').for(:url) } it { is_expected.to allow_value('http://{one}:{two}@example.com').for(:url) } + it { is_expected.to allow_value('http://{one}').for(:url) } + it { is_expected.to allow_value('{url}').for(:url) } it { is_expected.not_to allow_value('http://example.com/{one}/{two}/{three}').for(:url) } it { is_expected.not_to allow_value('http://example.com/{foo}').for(:url) } @@ -113,24 +124,81 @@ RSpec.describe WebHook do end describe 'push_events_branch_filter' do - it { is_expected.to allow_values("good_branch_name", "another/good-branch_name").for(:push_events_branch_filter) } - it { is_expected.to allow_values("").for(:push_events_branch_filter) } - it { is_expected.not_to allow_values("bad branch name", "bad~branchname").for(:push_events_branch_filter) } - - it 'gets rid of whitespace' do - hook.push_events_branch_filter = ' branch ' - hook.save! + before do + subject.branch_filter_strategy = strategy + end + + context 'with "all branches" strategy' do + let(:strategy) { 'all_branches' } + + it { + is_expected.to allow_values( + "good_branch_name", + "another/good-branch_name", + "good branch name", + "good~branchname", + "good_branchname(", + "good_branchname[", + "" + ).for(:push_events_branch_filter) + } + end + + context 'with "wildcard" strategy' do + let(:strategy) { 'wildcard' } + + it { + is_expected.to allow_values( + "good_branch_name", + "another/good-branch_name", + "good_branch_name(", + "" + ).for(:push_events_branch_filter) + } + + it { + is_expected.not_to allow_values( + "bad branch name", + "bad~branchname", + "bad_branch_name[" + ).for(:push_events_branch_filter) + } + + it 'gets rid of whitespace' do + hook.push_events_branch_filter = ' branch ' + hook.save! + + expect(hook.push_events_branch_filter).to eq('branch') + end - expect(hook.push_events_branch_filter).to eq('branch') + it 'stores whitespace only as empty' do + hook.push_events_branch_filter = ' ' + hook.save! + expect(hook.push_events_branch_filter).to eq('') + end end - it 'stores whitespace only as empty' do - hook.push_events_branch_filter = ' ' - hook.save! + context 'with "regex" strategy' do + let(:strategy) { 'regex' } - expect(hook.push_events_branch_filter).to eq('') + it { + is_expected.to allow_values( + "good_branch_name", + "another/good-branch_name", + "good branch name", + "good~branch~name", + "" + ).for(:push_events_branch_filter) + } + + it { is_expected.not_to allow_values("bad_branch_name(", "bad_branch_name[").for(:push_events_branch_filter) } end end + + it "only consider these branch filter strategies are valid" do + expected_valid_types = %w[all_branches regex wildcard] + expect(described_class.branch_filter_strategies.keys).to contain_exactly(*expected_valid_types) + end end describe 'encrypted attributes' do @@ -141,7 +209,7 @@ RSpec.describe WebHook do describe '.web_hooks_disable_failed?' do it 'returns true when feature is enabled for parent' do - second_hook = build(:project_hook, project: create(:project)) + second_hook = build(:project_hook) stub_feature_flags(web_hooks_disable_failed: [false, second_hook.project]) expect(described_class.web_hooks_disable_failed?(hook)).to eq(false) @@ -242,7 +310,7 @@ RSpec.describe WebHook do end describe '#executable?' do - let(:web_hook) { create(:project_hook, project: project) } + let_it_be_with_reload(:web_hook) { create(:project_hook, project: project) } where(:recent_failures, :not_until, :executable) do [ @@ -389,7 +457,7 @@ RSpec.describe WebHook do end end - describe 'backoff!' do + describe '#backoff!' do context 'when we have not backed off before' do it 'does not disable the hook' do expect { hook.backoff! }.not_to change(hook, :executable?).from(true) @@ -400,6 +468,26 @@ RSpec.describe WebHook do end end + context 'when the recent failure value is the max value of a smallint' do + before do + hook.update!(recent_failures: 32767, disabled_until: 1.hour.ago) + end + + it 'reduces to MAX_FAILURES' do + expect { hook.backoff! }.to change(hook, :recent_failures).to(described_class::MAX_FAILURES) + end + end + + context 'when the recent failure value is MAX_FAILURES' do + before do + hook.update!(recent_failures: described_class::MAX_FAILURES, disabled_until: 1.hour.ago) + end + + it 'does not change recent_failures' do + expect { hook.backoff! }.not_to change(hook, :recent_failures) + end + end + context 'when we have exhausted the grace period' do before do hook.update!(recent_failures: described_class::FAILURE_THRESHOLD) @@ -459,11 +547,21 @@ RSpec.describe WebHook do end end - describe 'failed!' do + describe '#failed!' do it 'increments the failure count' do expect { hook.failed! }.to change(hook, :recent_failures).by(1) end + context 'when the recent failure value is the max value of a smallint' do + before do + hook.update!(recent_failures: 32767) + end + + it 'does not change recent_failures' do + expect { hook.failed! }.not_to change(hook, :recent_failures) + end + end + it 'does not update the hook if the the failure count exceeds the maximum value' do hook.recent_failures = described_class::MAX_FAILURES @@ -670,4 +768,14 @@ RSpec.describe WebHook do expect { described_class.new.update_last_failure }.not_to raise_error end end + + describe '#masked_token' do + it { expect(hook.masked_token).to be_nil } + + context 'with a token' do + let(:hook) { build(:project_hook, :token, project: project) } + + it { expect(hook.masked_token).to eq described_class::SECRET_MASK } + end + end end -- cgit v1.2.3