diff options
Diffstat (limited to 'spec/lib')
17 files changed, 417 insertions, 95 deletions
diff --git a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb index ea79389e67e..ed571a2ba05 100644 --- a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb +++ b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb @@ -32,6 +32,28 @@ module Ci end end + describe 'retry entry' do + context 'when retry count is specified' do + let(:config) do + YAML.dump(rspec: { script: 'rspec', retry: 1 }) + end + + it 'includes retry count in build options attribute' do + expect(subject[:options]).to include(retry: 1) + end + end + + context 'when retry count is not specified' do + let(:config) do + YAML.dump(rspec: { script: 'rspec' }) + end + + it 'does not persist retry count in the database' do + expect(subject[:options]).not_to have_key(:retry) + end + end + end + describe 'allow failure entry' do context 'when job is a manual action' do context 'when allow_failure is defined' do diff --git a/spec/lib/gitlab/background_migration/migrate_system_uploads_to_new_folder_spec.rb b/spec/lib/gitlab/background_migration/migrate_system_uploads_to_new_folder_spec.rb new file mode 100644 index 00000000000..a910fb105a5 --- /dev/null +++ b/spec/lib/gitlab/background_migration/migrate_system_uploads_to_new_folder_spec.rb @@ -0,0 +1,19 @@ +require 'spec_helper' + +describe Gitlab::BackgroundMigration::MigrateSystemUploadsToNewFolder do + let(:migration) { described_class.new } + + before do + allow(migration).to receive(:logger).and_return(Logger.new(nil)) + end + + describe '#perform' do + it 'renames the path of system-uploads', truncate: true do + upload = create(:upload, model: create(:empty_project), path: 'uploads/system/project/avatar.jpg') + + migration.perform('uploads/system/', 'uploads/-/system/') + + expect(upload.reload.path).to eq('uploads/-/system/project/avatar.jpg') + end + end +end diff --git a/spec/lib/gitlab/background_migration_spec.rb b/spec/lib/gitlab/background_migration_spec.rb index cfa59280139..4ad69aeba43 100644 --- a/spec/lib/gitlab/background_migration_spec.rb +++ b/spec/lib/gitlab/background_migration_spec.rb @@ -25,7 +25,7 @@ describe Gitlab::BackgroundMigration do expect(queue[0]).to receive(:delete).and_return(true) expect(described_class).to receive(:perform) - .with('Foo', [10, 20], anything) + .with('Foo', [10, 20]) described_class.steal('Foo') end @@ -93,9 +93,9 @@ describe Gitlab::BackgroundMigration do it 'steals from the scheduled sets queue first' do Sidekiq::Testing.disable! do expect(described_class).to receive(:perform) - .with('Object', [1], anything).ordered + .with('Object', [1]).ordered expect(described_class).to receive(:perform) - .with('Object', [2], anything).ordered + .with('Object', [2]).ordered BackgroundMigrationWorker.perform_async('Object', [2]) BackgroundMigrationWorker.perform_in(10.minutes, 'Object', [1]) diff --git a/spec/lib/gitlab/badge/build/metadata_spec.rb b/spec/lib/gitlab/badge/pipeline/metadata_spec.rb index 9df96ea04eb..d537ce8803c 100644 --- a/spec/lib/gitlab/badge/build/metadata_spec.rb +++ b/spec/lib/gitlab/badge/pipeline/metadata_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' require 'lib/gitlab/badge/shared/metadata' -describe Gitlab::Badge::Build::Metadata do +describe Gitlab::Badge::Pipeline::Metadata do let(:badge) { double(project: create(:empty_project), ref: 'feature') } let(:metadata) { described_class.new(badge) } @@ -9,13 +9,13 @@ describe Gitlab::Badge::Build::Metadata do describe '#title' do it 'returns build status title' do - expect(metadata.title).to eq 'build status' + expect(metadata.title).to eq 'pipeline status' end end describe '#image_url' do it 'returns valid url' do - expect(metadata.image_url).to include 'badges/feature/build.svg' + expect(metadata.image_url).to include 'badges/feature/pipeline.svg' end end diff --git a/spec/lib/gitlab/badge/build/status_spec.rb b/spec/lib/gitlab/badge/pipeline/status_spec.rb index 6abf4ca46a9..dc835375c66 100644 --- a/spec/lib/gitlab/badge/build/status_spec.rb +++ b/spec/lib/gitlab/badge/pipeline/status_spec.rb @@ -1,36 +1,35 @@ require 'spec_helper' -describe Gitlab::Badge::Build::Status do +describe Gitlab::Badge::Pipeline::Status do let(:project) { create(:project, :repository) } let(:sha) { project.commit.sha } let(:branch) { 'master' } let(:badge) { described_class.new(project, branch) } describe '#entity' do - it 'always says build' do - expect(badge.entity).to eq 'build' + it 'always says pipeline' do + expect(badge.entity).to eq 'pipeline' end end describe '#template' do it 'returns badge template' do - expect(badge.template.key_text).to eq 'build' + expect(badge.template.key_text).to eq 'pipeline' end end describe '#metadata' do it 'returns badge metadata' do - expect(badge.metadata.image_url) - .to include 'badges/master/build.svg' + expect(badge.metadata.image_url).to include 'badges/master/pipeline.svg' end end - context 'build exists' do - let!(:build) { create_build(project, sha, branch) } + context 'pipeline exists' do + let!(:pipeline) { create_pipeline(project, sha, branch) } - context 'build success' do + context 'pipeline success' do before do - build.success! + pipeline.success! end describe '#status' do @@ -40,9 +39,9 @@ describe Gitlab::Badge::Build::Status do end end - context 'build failed' do + context 'pipeline failed' do before do - build.drop! + pipeline.drop! end describe '#status' do @@ -54,10 +53,10 @@ describe Gitlab::Badge::Build::Status do context 'when outdated pipeline for given ref exists' do before do - build.success! + pipeline.success! - old_build = create_build(project, '11eeffdd', branch) - old_build.drop! + old_pipeline = create_pipeline(project, '11eeffdd', branch) + old_pipeline.drop! end it 'does not take outdated pipeline into account' do @@ -67,10 +66,10 @@ describe Gitlab::Badge::Build::Status do context 'when multiple pipelines exist for given sha' do before do - build.drop! + pipeline.drop! - new_build = create_build(project, sha, branch) - new_build.success! + new_pipeline = create_pipeline(project, sha, branch) + new_pipeline.success! end it 'does not take outdated pipeline into account' do @@ -87,7 +86,7 @@ describe Gitlab::Badge::Build::Status do end end - def create_build(project, sha, branch) + def create_pipeline(project, sha, branch) pipeline = create(:ci_empty_pipeline, project: project, sha: sha, diff --git a/spec/lib/gitlab/badge/build/template_spec.rb b/spec/lib/gitlab/badge/pipeline/template_spec.rb index a7e21fb8bb1..20fa4f879c3 100644 --- a/spec/lib/gitlab/badge/build/template_spec.rb +++ b/spec/lib/gitlab/badge/pipeline/template_spec.rb @@ -1,28 +1,28 @@ require 'spec_helper' -describe Gitlab::Badge::Build::Template do - let(:badge) { double(entity: 'build', status: 'success') } +describe Gitlab::Badge::Pipeline::Template do + let(:badge) { double(entity: 'pipeline', status: 'success') } let(:template) { described_class.new(badge) } describe '#key_text' do - it 'is always says build' do - expect(template.key_text).to eq 'build' + it 'is always says pipeline' do + expect(template.key_text).to eq 'pipeline' end end describe '#value_text' do it 'is status value' do - expect(template.value_text).to eq 'success' + expect(template.value_text).to eq 'passed' end end describe 'widths and text anchors' do it 'has fixed width and text anchors' do - expect(template.width).to eq 92 - expect(template.key_width).to eq 38 + expect(template.width).to eq 116 + expect(template.key_width).to eq 62 expect(template.value_width).to eq 54 - expect(template.key_text_anchor).to eq 19 - expect(template.value_text_anchor).to eq 65 + expect(template.key_text_anchor).to eq 31 + expect(template.value_text_anchor).to eq 89 end end diff --git a/spec/lib/gitlab/ci/config/entry/job_spec.rb b/spec/lib/gitlab/ci/config/entry/job_spec.rb index c5cad887b64..6769f64f950 100644 --- a/spec/lib/gitlab/ci/config/entry/job_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/job_spec.rb @@ -80,6 +80,45 @@ describe Gitlab::Ci::Config::Entry::Job do expect(entry.errors).to include "job script can't be blank" end end + + context 'when retry value is not correct' do + context 'when it is not a numeric value' do + let(:config) { { retry: true } } + + it 'returns error about invalid type' do + expect(entry).not_to be_valid + expect(entry.errors).to include 'job retry is not a number' + end + end + + context 'when it is lower than zero' do + let(:config) { { retry: -1 } } + + it 'returns error about value too low' do + expect(entry).not_to be_valid + expect(entry.errors) + .to include 'job retry must be greater than or equal to 0' + end + end + + context 'when it is not an integer' do + let(:config) { { retry: 1.5 } } + + it 'returns error about wrong value' do + expect(entry).not_to be_valid + expect(entry.errors).to include 'job retry must be an integer' + end + end + + context 'when the value is too high' do + let(:config) { { retry: 10 } } + + it 'returns error about value too high' do + expect(entry).not_to be_valid + expect(entry.errors).to include 'job retry must be less than or equal to 2' + end + end + end end end diff --git a/spec/lib/gitlab/ci/trace/stream_spec.rb b/spec/lib/gitlab/ci/trace/stream_spec.rb index bbb3f9912a3..8b925fd4e22 100644 --- a/spec/lib/gitlab/ci/trace/stream_spec.rb +++ b/spec/lib/gitlab/ci/trace/stream_spec.rb @@ -293,5 +293,41 @@ describe Gitlab::Ci::Trace::Stream do it { is_expected.to eq("65") } end + + context 'malicious regexp' do + let(:data) { malicious_text } + let(:regex) { malicious_regexp } + + include_examples 'malicious regexp' + end + + context 'multi-line data with rooted regexp' do + let(:data) { "\n65%\n" } + let(:regex) { '^(\d+)\%$' } + + it { is_expected.to eq('65') } + end + + context 'empty regex' do + let(:data) { 'foo' } + let(:regex) { '' } + + it 'skips processing' do + expect(stream).not_to receive(:read) + + is_expected.to be_nil + end + end + + context 'nil regex' do + let(:data) { 'foo' } + let(:regex) { nil } + + it 'skips processing' do + expect(stream).not_to receive(:read) + + is_expected.to be_nil + end + end end end diff --git a/spec/lib/gitlab/data_builder/wiki_page_spec.rb b/spec/lib/gitlab/data_builder/wiki_page_spec.rb new file mode 100644 index 00000000000..a776d888c47 --- /dev/null +++ b/spec/lib/gitlab/data_builder/wiki_page_spec.rb @@ -0,0 +1,21 @@ +require 'spec_helper' + +describe Gitlab::DataBuilder::WikiPage do + let(:project) { create(:project, :repository) } + let(:wiki_page) { create(:wiki_page, wiki: project.wiki) } + let(:user) { create(:user) } + + describe '.build' do + let(:data) { described_class.build(wiki_page, user, 'create') } + + it { expect(data).to be_a(Hash) } + it { expect(data[:object_kind]).to eq('wiki_page') } + it { expect(data[:user]).to eq(user.hook_attrs) } + it { expect(data[:project]).to eq(project.hook_attrs) } + it { expect(data[:wiki]).to eq(project.wiki.hook_attrs) } + + it { expect(data[:object_attributes]).to include(wiki_page.hook_attrs) } + it { expect(data[:object_attributes]).to include(url: Gitlab::UrlBuilder.build(wiki_page)) } + it { expect(data[:object_attributes]).to include(action: 'create') } + end +end diff --git a/spec/lib/gitlab/git/commit_spec.rb b/spec/lib/gitlab/git/commit_spec.rb index 60de91324f0..730fdb112d9 100644 --- a/spec/lib/gitlab/git/commit_spec.rb +++ b/spec/lib/gitlab/git/commit_spec.rb @@ -91,7 +91,7 @@ describe Gitlab::Git::Commit, seed_helper: true do committer: committer ) end - let(:commit) { described_class.new(gitaly_commit) } + let(:commit) { described_class.new(Gitlab::GitalyClient::Commit.new(repository, gitaly_commit)) } it { expect(commit.short_id).to eq(id[0..10]) } it { expect(commit.id).to eq(id) } @@ -290,69 +290,85 @@ describe Gitlab::Git::Commit, seed_helper: true do end describe '.find_all' do - it 'should return a return a collection of commits' do - commits = described_class.find_all(repository) + shared_examples 'finding all commits' do + it 'should return a return a collection of commits' do + commits = described_class.find_all(repository) - expect(commits).not_to be_empty - expect(commits).to all( be_a_kind_of(Gitlab::Git::Commit) ) - end - - context 'while applying a sort order based on the `order` option' do - it "allows ordering topologically (no parents shown before their children)" do - expect_any_instance_of(Rugged::Walker).to receive(:sorting).with(Rugged::SORT_TOPO) - - described_class.find_all(repository, order: :topo) + expect(commits).to all( be_a_kind_of(Gitlab::Git::Commit) ) end - it "allows ordering by date" do - expect_any_instance_of(Rugged::Walker).to receive(:sorting).with(Rugged::SORT_DATE | Rugged::SORT_TOPO) - - described_class.find_all(repository, order: :date) + context 'max_count' do + subject do + commits = Gitlab::Git::Commit.find_all( + repository, + max_count: 50 + ) + + commits.map(&:id) + end + + it 'has 33 elements' do + expect(subject.size).to eq(33) + end + + it 'includes the expected commits' do + expect(subject).to include( + SeedRepo::Commit::ID, + SeedRepo::Commit::PARENT_ID, + SeedRepo::FirstCommit::ID + ) + end end - it "applies no sorting by default" do - expect_any_instance_of(Rugged::Walker).to receive(:sorting).with(Rugged::SORT_NONE) - - described_class.find_all(repository) + context 'ref + max_count + skip' do + subject do + commits = Gitlab::Git::Commit.find_all( + repository, + ref: 'master', + max_count: 50, + skip: 1 + ) + + commits.map(&:id) + end + + it 'has 24 elements' do + expect(subject.size).to eq(24) + end + + it 'includes the expected commits' do + expect(subject).to include(SeedRepo::Commit::ID, SeedRepo::FirstCommit::ID) + expect(subject).not_to include(SeedRepo::LastCommit::ID) + end end end - context 'max_count' do - subject do - commits = Gitlab::Git::Commit.find_all( - repository, - max_count: 50 - ) + context 'when Gitaly find_all_commits feature is enabled' do + it_behaves_like 'finding all commits' + end - commits.map { |c| c.id } - end + context 'when Gitaly find_all_commits feature is disabled', skip_gitaly_mock: true do + it_behaves_like 'finding all commits' - it 'has 31 elements' do - expect(subject.size).to eq(33) - end - it { is_expected.to include(SeedRepo::Commit::ID) } - it { is_expected.to include(SeedRepo::Commit::PARENT_ID) } - it { is_expected.to include(SeedRepo::FirstCommit::ID) } - end + context 'while applying a sort order based on the `order` option' do + it "allows ordering topologically (no parents shown before their children)" do + expect_any_instance_of(Rugged::Walker).to receive(:sorting).with(Rugged::SORT_TOPO) - context 'ref + max_count + skip' do - subject do - commits = Gitlab::Git::Commit.find_all( - repository, - ref: 'master', - max_count: 50, - skip: 1 - ) + described_class.find_all(repository, order: :topo) + end - commits.map { |c| c.id } - end + it "allows ordering by date" do + expect_any_instance_of(Rugged::Walker).to receive(:sorting).with(Rugged::SORT_DATE | Rugged::SORT_TOPO) + + described_class.find_all(repository, order: :date) + end + + it "applies no sorting by default" do + expect_any_instance_of(Rugged::Walker).to receive(:sorting).with(Rugged::SORT_NONE) - it 'has 23 elements' do - expect(subject.size).to eq(24) + described_class.find_all(repository) + end end - it { is_expected.to include(SeedRepo::Commit::ID) } - it { is_expected.to include(SeedRepo::FirstCommit::ID) } - it { is_expected.not_to include(SeedRepo::LastCommit::ID) } end end end diff --git a/spec/lib/gitlab/git/diff_collection_spec.rb b/spec/lib/gitlab/git/diff_collection_spec.rb index d20298fa139..0cfb210e390 100644 --- a/spec/lib/gitlab/git/diff_collection_spec.rb +++ b/spec/lib/gitlab/git/diff_collection_spec.rb @@ -484,6 +484,8 @@ describe Gitlab::Git::DiffCollection, seed_helper: true do end def each + return enum_for(:each) unless block_given? + loop do break if @count.zero? # It is critical to decrement before yielding. We may never reach the lines after 'yield'. diff --git a/spec/lib/gitlab/git/tree_spec.rb b/spec/lib/gitlab/git/tree_spec.rb index 4b76a43e6b5..98ddd3c3664 100644 --- a/spec/lib/gitlab/git/tree_spec.rb +++ b/spec/lib/gitlab/git/tree_spec.rb @@ -1,8 +1,9 @@ require "spec_helper" describe Gitlab::Git::Tree, seed_helper: true do + let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) } + context :repo do - let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) } let(:tree) { Gitlab::Git::Tree.where(repository, SeedRepo::Commit::ID) } it { expect(tree).to be_kind_of Array } @@ -74,4 +75,24 @@ describe Gitlab::Git::Tree, seed_helper: true do it { expect(submodule.name).to eq('gitlab-shell') } end end + + describe '#where' do + context 'with gitaly disabled' do + before do + allow(Gitlab::GitalyClient).to receive(:feature_enabled?).and_return(false) + end + + it 'calls #tree_entries_from_rugged' do + expect(described_class).to receive(:tree_entries_from_rugged) + + described_class.where(repository, SeedRepo::Commit::ID, '/') + end + end + + it 'gets the tree entries from GitalyClient' do + expect_any_instance_of(Gitlab::GitalyClient::CommitService).to receive(:tree_entries) + + described_class.where(repository, SeedRepo::Commit::ID, '/') + end + end end diff --git a/spec/lib/gitlab/gitaly_client/commit_service_spec.rb b/spec/lib/gitlab/gitaly_client/commit_service_spec.rb index 93affb12f2b..0868c793a33 100644 --- a/spec/lib/gitlab/gitaly_client/commit_service_spec.rb +++ b/spec/lib/gitlab/gitaly_client/commit_service_spec.rb @@ -2,9 +2,13 @@ require 'spec_helper' describe Gitlab::GitalyClient::CommitService do let(:project) { create(:project, :repository) } + let(:storage_name) { project.repository_storage } + let(:relative_path) { project.path_with_namespace + '.git' } let(:repository) { project.repository } let(:repository_message) { repository.gitaly_repository } - let(:commit) { project.commit('913c66a37b4a45b9769037c55c2d238bd0942d2e') } + let(:revision) { '913c66a37b4a45b9769037c55c2d238bd0942d2e' } + let(:commit) { project.commit(revision) } + let(:client) { described_class.new(repository) } describe '#diff_from_parent' do context 'when a commit has a parent' do @@ -12,12 +16,15 @@ describe Gitlab::GitalyClient::CommitService do request = Gitaly::CommitDiffRequest.new( repository: repository_message, left_commit_id: 'cfe32cf61b73a0d5e9f13e774abde7ff789b1660', - right_commit_id: commit.id + right_commit_id: commit.id, + collapse_diffs: true, + enforce_limits: true, + **Gitlab::Git::DiffCollection.collection_limits.to_h ) expect_any_instance_of(Gitaly::DiffService::Stub).to receive(:commit_diff).with(request, kind_of(Hash)) - described_class.new(repository).diff_from_parent(commit) + client.diff_from_parent(commit) end end @@ -27,27 +34,30 @@ describe Gitlab::GitalyClient::CommitService do request = Gitaly::CommitDiffRequest.new( repository: repository_message, left_commit_id: '4b825dc642cb6eb9a060e54bf8d69288fbee4904', - right_commit_id: initial_commit.id + right_commit_id: initial_commit.id, + collapse_diffs: true, + enforce_limits: true, + **Gitlab::Git::DiffCollection.collection_limits.to_h ) expect_any_instance_of(Gitaly::DiffService::Stub).to receive(:commit_diff).with(request, kind_of(Hash)) - described_class.new(repository).diff_from_parent(initial_commit) + client.diff_from_parent(initial_commit) end end it 'returns a Gitlab::Git::DiffCollection' do - ret = described_class.new(repository).diff_from_parent(commit) + ret = client.diff_from_parent(commit) expect(ret).to be_kind_of(Gitlab::Git::DiffCollection) end it 'passes options to Gitlab::Git::DiffCollection' do - options = { max_files: 31, max_lines: 13 } + options = { max_files: 31, max_lines: 13, from_gitaly: true } expect(Gitlab::Git::DiffCollection).to receive(:new).with(kind_of(Enumerable), options) - described_class.new(repository).diff_from_parent(commit, options) + client.diff_from_parent(commit, options) end end @@ -62,7 +72,7 @@ describe Gitlab::GitalyClient::CommitService do expect_any_instance_of(Gitaly::DiffService::Stub).to receive(:commit_delta).with(request, kind_of(Hash)).and_return([]) - described_class.new(repository).commit_deltas(commit) + client.commit_deltas(commit) end end @@ -77,7 +87,7 @@ describe Gitlab::GitalyClient::CommitService do expect_any_instance_of(Gitaly::DiffService::Stub).to receive(:commit_delta).with(request, kind_of(Hash)).and_return([]) - described_class.new(repository).commit_deltas(initial_commit) + client.commit_deltas(initial_commit) end end end @@ -85,6 +95,7 @@ describe Gitlab::GitalyClient::CommitService do describe '#between' do let(:from) { 'master' } let(:to) { '4b825dc642cb6eb9a060e54bf8d69288fbee4904' } + it 'sends an RPC request' do request = Gitaly::CommitsBetweenRequest.new( repository: repository_message, from: from, to: to @@ -96,4 +107,17 @@ describe Gitlab::GitalyClient::CommitService do described_class.new(repository).between(from, to) end end + + describe '#tree_entries' do + let(:path) { '/' } + + it 'sends a get_tree_entries message' do + expect_any_instance_of(Gitaly::CommitService::Stub) + .to receive(:get_tree_entries) + .with(gitaly_request_with_path(storage_name, relative_path), kind_of(Hash)) + .and_return([]) + + client.tree_entries(repository, revision, path) + end + end end diff --git a/spec/lib/gitlab/regex_spec.rb b/spec/lib/gitlab/regex_spec.rb index 51e2c3c38c6..251f82849bf 100644 --- a/spec/lib/gitlab/regex_spec.rb +++ b/spec/lib/gitlab/regex_spec.rb @@ -38,4 +38,15 @@ describe Gitlab::Regex, lib: true do it { is_expected.not_to match('9foo') } it { is_expected.not_to match('foo-') } end + + describe '.container_repository_name_regex' do + subject { described_class.container_repository_name_regex } + + it { is_expected.to match('image') } + it { is_expected.to match('my/image') } + it { is_expected.to match('my/awesome/image-1') } + it { is_expected.to match('my/awesome/image.test') } + it { is_expected.not_to match('.my/image') } + it { is_expected.not_to match('my/image.') } + end end diff --git a/spec/lib/gitlab/route_map_spec.rb b/spec/lib/gitlab/route_map_spec.rb index 21c00c6e5b8..e8feb21e4d7 100644 --- a/spec/lib/gitlab/route_map_spec.rb +++ b/spec/lib/gitlab/route_map_spec.rb @@ -55,6 +55,19 @@ describe Gitlab::RouteMap, lib: true do end describe '#public_path_for_source_path' do + context 'malicious regexp' do + include_examples 'malicious regexp' + + subject do + map = described_class.new(<<-"MAP".strip_heredoc) + - source: '#{malicious_regexp}' + public: '/' + MAP + + map.public_path_for_source_path(malicious_text) + end + end + subject do described_class.new(<<-'MAP'.strip_heredoc) # Team data diff --git a/spec/lib/gitlab/untrusted_regexp_spec.rb b/spec/lib/gitlab/untrusted_regexp_spec.rb new file mode 100644 index 00000000000..21d47b7897a --- /dev/null +++ b/spec/lib/gitlab/untrusted_regexp_spec.rb @@ -0,0 +1,98 @@ +require 'spec_helper' + +describe Gitlab::UntrustedRegexp do + describe '#initialize' do + subject { described_class.new(pattern) } + + context 'invalid regexp' do + let(:pattern) { '[' } + + it { expect { subject }.to raise_error(RegexpError) } + end + end + + describe '#replace_all' do + it 'replaces all instances of the match in a string' do + result = described_class.new('foo').replace_all('foo bar foo', 'oof') + + expect(result).to eq('oof bar oof') + end + end + + describe '#replace' do + it 'replaces the first instance of the match in a string' do + result = described_class.new('foo').replace('foo bar foo', 'oof') + + expect(result).to eq('oof bar foo') + end + end + + describe '#===' do + it 'returns true for a match' do + result = described_class.new('foo') === 'a foo here' + + expect(result).to be_truthy + end + + it 'returns false for no match' do + result = described_class.new('foo') === 'a bar here' + + expect(result).to be_falsy + end + end + + describe '#scan' do + subject { described_class.new(regexp).scan(text) } + context 'malicious regexp' do + let(:text) { malicious_text } + let(:regexp) { malicious_regexp } + + include_examples 'malicious regexp' + end + + context 'empty regexp' do + let(:regexp) { '' } + let(:text) { 'foo' } + + it 'returns an array of empty matches' do + is_expected.to eq(['']) + end + end + + context 'empty capture group regexp' do + let(:regexp) { '()' } + let(:text) { 'foo' } + + it 'returns an array of empty matches in an array' do + is_expected.to eq([['']]) + end + end + + context 'no capture group' do + let(:regexp) { '.+' } + let(:text) { 'foo' } + + it 'returns the whole match' do + is_expected.to eq(['foo']) + end + end + + context 'one capture group' do + let(:regexp) { '(f).+' } + let(:text) { 'foo' } + + it 'returns the captured part' do + is_expected.to eq([%w[f]]) + end + end + + context 'two capture groups' do + let(:regexp) { '(f).(o)' } + let(:text) { 'foo' } + + it 'returns the captured parts' do + is_expected.to eq([%w[f o]]) + end + end + end +end diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb index c6718827028..daf097f8d51 100644 --- a/spec/lib/gitlab/usage_data_spec.rb +++ b/spec/lib/gitlab/usage_data_spec.rb @@ -48,6 +48,7 @@ describe Gitlab::UsageData do milestones notes projects + projects_imported_from_github projects_prometheus_active pages_domains protected_branches |