Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/models/hooks/web_hook_spec.rb')
-rw-r--r--spec/models/hooks/web_hook_spec.rb91
1 files changed, 87 insertions, 4 deletions
diff --git a/spec/models/hooks/web_hook_spec.rb b/spec/models/hooks/web_hook_spec.rb
index fb4d1cee606..9faa5e1567c 100644
--- a/spec/models/hooks/web_hook_spec.rb
+++ b/spec/models/hooks/web_hook_spec.rb
@@ -78,6 +78,32 @@ RSpec.describe WebHook do
expect(hook.url).to eq('https://example.com')
end
+
+ context 'when there are URL variables' do
+ subject { hook }
+
+ before do
+ hook.url_variables = { 'one' => 'a', 'two' => 'b' }
+ end
+
+ it { is_expected.to allow_value('http://example.com').for(:url) }
+ it { is_expected.to allow_value('http://example.com/{one}/{two}').for(:url) }
+ it { is_expected.to allow_value('http://example.com/{one}').for(:url) }
+ 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.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) }
+ it { is_expected.not_to allow_value('http:{user}:{pwd}//example.com/{foo}').for(:url) }
+
+ it 'mentions all missing variable names' do
+ hook.url = 'http://example.com/{one}/{foo}/{two}/{three}'
+
+ expect(hook).to be_invalid
+ expect(hook.errors[:url].to_sentence).to eq "Invalid URL template. Missing keys: [\"foo\", \"three\"]"
+ end
+ end
end
describe 'token' do
@@ -161,8 +187,8 @@ RSpec.describe WebHook do
end
end
- describe '.executable' do
- let(:not_executable) do
+ describe '.executable/.disabled' do
+ let!(:not_executable) do
[
[0, Time.current],
[0, 1.minute.from_now],
@@ -176,7 +202,7 @@ RSpec.describe WebHook do
end
end
- let(:executables) do
+ let!(:executables) do
[
[0, nil],
[0, 1.day.ago],
@@ -191,6 +217,7 @@ RSpec.describe WebHook do
it 'finds the correct set of project hooks' do
expect(described_class.where(project_id: project.id).executable).to match_array executables
+ expect(described_class.where(project_id: project.id).disabled).to match_array not_executable
end
context 'when the feature flag is not enabled' do
@@ -198,7 +225,7 @@ RSpec.describe WebHook do
stub_feature_flags(web_hooks_disable_failed: false)
end
- it 'is the same as all' do
+ specify 'enabled is the same as all' do
expect(described_class.where(project_id: project.id).executable).to match_array(executables + not_executable)
end
end
@@ -559,4 +586,60 @@ RSpec.describe WebHook do
expect(hook.to_json(unsafe_serialization_hash: true)).not_to include('encrypted_url_variables')
end
end
+
+ describe '#interpolated_url' do
+ subject(:hook) { build(:project_hook, project: project) }
+
+ context 'when the hook URL does not contain variables' do
+ before do
+ hook.url = 'http://example.com'
+ end
+
+ it { is_expected.to have_attributes(interpolated_url: hook.url) }
+ end
+
+ it 'is not vulnerable to malicious input' do
+ hook.url = 'something%{%<foo>2147483628G}'
+ hook.url_variables = { 'foo' => '1234567890.12345678' }
+
+ expect(hook).to have_attributes(interpolated_url: hook.url)
+ end
+
+ context 'when the hook URL contains variables' do
+ before do
+ hook.url = 'http://example.com/{path}/resource?token={token}'
+ hook.url_variables = { 'path' => 'abc', 'token' => 'xyz' }
+ end
+
+ it { is_expected.to have_attributes(interpolated_url: 'http://example.com/abc/resource?token=xyz') }
+
+ context 'when a variable is missing' do
+ before do
+ hook.url_variables = { 'path' => 'present' }
+ end
+
+ it 'raises an error' do
+ # We expect validations to prevent this entirely - this is not user-error
+ expect { hook.interpolated_url }
+ .to raise_error(described_class::InterpolationError, include('Missing key token'))
+ end
+ end
+
+ context 'when the URL appears to include percent formatting' do
+ before do
+ hook.url = 'http://example.com/%{path}/resource?token=%{token}'
+ end
+
+ it 'succeeds, interpolates correctly' do
+ expect(hook.interpolated_url).to eq 'http://example.com/%abc/resource?token=%xyz'
+ end
+ end
+ end
+ end
+
+ describe '#update_last_failure' do
+ it 'is a method of this class' do
+ expect { described_class.new.update_last_failure }.not_to raise_error
+ end
+ end
end