diff options
| author | James Lopez <james@jameslopez.es> | 2016-03-21 09:20:55 +0100 |
|---|---|---|
| committer | James Lopez <james@jameslopez.es> | 2016-03-21 09:20:55 +0100 |
| commit | 5f86912ef032845ef2a08acf70b434c0e4d58631 (patch) | |
| tree | 7b465b9d42c238c4a5978b4698a6ed71d1a7fcce /spec/lib | |
| parent | 735563329d1f86ee4d72b37cd22eed1168935e8e (diff) | |
| parent | b9fb48bc4597984710532e20f057920b0915d0c3 (diff) | |
| download | gitlab-ce-5f86912ef032845ef2a08acf70b434c0e4d58631.tar.gz | |
Merge branches 'fix/project-import_url' and 'master' of gitlab.com:gitlab-org/gitlab-ce into fix/project-import_url
# Conflicts:
# db/schema.rb
Diffstat (limited to 'spec/lib')
20 files changed, 803 insertions, 88 deletions
diff --git a/spec/lib/banzai/filter/gollum_tags_filter_spec.rb b/spec/lib/banzai/filter/gollum_tags_filter_spec.rb index 11cc290d6d0..5e23c5c319a 100644 --- a/spec/lib/banzai/filter/gollum_tags_filter_spec.rb +++ b/spec/lib/banzai/filter/gollum_tags_filter_spec.rb @@ -88,54 +88,17 @@ describe Banzai::Filter::GollumTagsFilter, lib: true do end context 'table of contents' do - let(:pipeline) { Banzai::Pipeline[:wiki] } + it 'replaces [[<em>TOC</em>]] with ToC result' do + doc = described_class.call("<p>[[<em>TOC</em>]]</p>", { project_wiki: project_wiki }, { toc: "FOO" }) - it 'replaces the tag with the TableOfContentsFilter result' do - markdown = <<-MD.strip_heredoc - [[_TOC_]] - - ## Header - - Foo - MD - - result = pipeline.call(markdown, project_wiki: project_wiki, project: project) - - aggregate_failures do - expect(result[:output].text).not_to include '[[_TOC_]]' - expect(result[:output].text).not_to include '[[' - expect(result[:output].to_html).to include(result[:toc]) - end - end - - it 'is case-sensitive' do - markdown = <<-MD.strip_heredoc - [[_toc_]] - - # Header 1 - - Foo - MD - - output = pipeline.to_html(markdown, project_wiki: project_wiki, project: project) - - expect(output).to include('[[<em>toc</em>]]') + expect(doc.to_html).to eq("FOO") end - it 'handles an empty pipeline result' do - # No Markdown headers in this doc, so `result[:toc]` will be empty - markdown = <<-MD.strip_heredoc - [[_TOC_]] - - Foo - MD - - output = pipeline.to_html(markdown, project_wiki: project_wiki, project: project) + it 'handles an empty ToC result' do + input = "<p>[[<em>TOC</em>]]</p>" + doc = described_class.call(input, project_wiki: project_wiki) - aggregate_failures do - expect(output).not_to include('<ul>') - expect(output).to include('[[<em>TOC</em>]]') - end + expect(doc.to_html).to eq '' end end end diff --git a/spec/lib/banzai/filter/label_reference_filter_spec.rb b/spec/lib/banzai/filter/label_reference_filter_spec.rb index b46ccc47605..4c1d4a2d24c 100644 --- a/spec/lib/banzai/filter/label_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/label_reference_filter_spec.rb @@ -56,7 +56,7 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do describe 'label span element' do it 'includes default classes' do doc = reference_filter("Label #{reference}") - expect(doc.css('a span').first.attr('class')).to eq 'label color-label' + expect(doc.css('a span').first.attr('class')).to eq 'label color-label has_tooltip' end it 'includes a style attribute' do @@ -111,7 +111,7 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do context 'String-based multi-word references in quotes' do let(:label) { create(:label, name: 'gfm references', project: project) } - let(:reference) { label.to_reference(:name) } + let(:reference) { label.to_reference(format: :name) } it 'links to a valid reference' do doc = reference_filter("See #{reference}") @@ -176,4 +176,29 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do expect(result[:references][:label]).to eq [label] end end + + describe 'cross project label references' do + let(:another_project) { create(:empty_project, :public) } + let(:project_name) { another_project.name_with_namespace } + let(:label) { create(:label, project: another_project, color: '#00ff00') } + let(:reference) { label.to_reference(project) } + + let!(:result) { reference_filter("See #{reference}") } + + it 'points to referenced project issues page' do + expect(result.css('a').first.attr('href')) + .to eq urls.namespace_project_issues_url(another_project.namespace, + another_project, + label_name: label.name) + end + + it 'has valid color' do + expect(result.css('a span').first.attr('style')) + .to match /background-color: #00ff00/ + end + + it 'contains cross project content' do + expect(result.css('a').first.text).to eq "#{label.name} in #{project_name}" + end + end end diff --git a/spec/lib/banzai/filter/redactor_filter_spec.rb b/spec/lib/banzai/filter/redactor_filter_spec.rb index e9bb388e361..9acf6304bcb 100644 --- a/spec/lib/banzai/filter/redactor_filter_spec.rb +++ b/spec/lib/banzai/filter/redactor_filter_spec.rb @@ -44,8 +44,78 @@ describe Banzai::Filter::RedactorFilter, lib: true do end end - context "for user references" do + context 'with data-issue' do + context 'for confidential issues' do + it 'removes references for non project members' do + non_member = create(:user) + project = create(:empty_project, :public) + issue = create(:issue, :confidential, project: project) + + link = reference_link(project: project.id, issue: issue.id, reference_filter: 'IssueReferenceFilter') + doc = filter(link, current_user: non_member) + + expect(doc.css('a').length).to eq 0 + end + + it 'allows references for author' do + author = create(:user) + project = create(:empty_project, :public) + issue = create(:issue, :confidential, project: project, author: author) + + link = reference_link(project: project.id, issue: issue.id, reference_filter: 'IssueReferenceFilter') + doc = filter(link, current_user: author) + + expect(doc.css('a').length).to eq 1 + end + + it 'allows references for assignee' do + assignee = create(:user) + project = create(:empty_project, :public) + issue = create(:issue, :confidential, project: project, assignee: assignee) + + link = reference_link(project: project.id, issue: issue.id, reference_filter: 'IssueReferenceFilter') + doc = filter(link, current_user: assignee) + expect(doc.css('a').length).to eq 1 + end + + it 'allows references for project members' do + member = create(:user) + project = create(:empty_project, :public) + project.team << [member, :developer] + issue = create(:issue, :confidential, project: project) + + link = reference_link(project: project.id, issue: issue.id, reference_filter: 'IssueReferenceFilter') + doc = filter(link, current_user: member) + + expect(doc.css('a').length).to eq 1 + end + + it 'allows references for admin' do + admin = create(:admin) + project = create(:empty_project, :public) + issue = create(:issue, :confidential, project: project) + + link = reference_link(project: project.id, issue: issue.id, reference_filter: 'IssueReferenceFilter') + doc = filter(link, current_user: admin) + + expect(doc.css('a').length).to eq 1 + end + end + + it 'allows references for non confidential issues' do + user = create(:user) + project = create(:empty_project, :public) + issue = create(:issue, project: project) + + link = reference_link(project: project.id, issue: issue.id, reference_filter: 'IssueReferenceFilter') + doc = filter(link, current_user: user) + + expect(doc.css('a').length).to eq 1 + end + end + + context "for user references" do context 'with data-group' do it 'removes unpermitted Group references' do user = create(:user) diff --git a/spec/lib/banzai/filter/sanitization_filter_spec.rb b/spec/lib/banzai/filter/sanitization_filter_spec.rb index 4a7b00c7660..27ce312b11c 100644 --- a/spec/lib/banzai/filter/sanitization_filter_spec.rb +++ b/spec/lib/banzai/filter/sanitization_filter_spec.rb @@ -149,10 +149,20 @@ describe Banzai::Filter::SanitizationFilter, lib: true do output: '<a href="java"></a>' }, + 'protocol-based JS injection: invalid URL char' => { + input: '<img src=java\script:alert("XSS")>', + output: '<img>' + }, + 'protocol-based JS injection: spaces and entities' => { input: '<a href="  javascript:alert(\'XSS\');">foo</a>', output: '<a href="">foo</a>' }, + + 'protocol whitespace' => { + input: '<a href=" http://example.com/"></a>', + output: '<a href="http://example.com/"></a>' + } } protocols.each do |name, data| @@ -177,6 +187,16 @@ describe Banzai::Filter::SanitizationFilter, lib: true do expect(output.to_html).to eq '<a>XSS</a>' end + it 'disallows invalid URIs' do + expect(Addressable::URI).to receive(:parse).with('foo://example.com'). + and_raise(Addressable::URI::InvalidURIError) + + input = '<a href="foo://example.com">Foo</a>' + output = filter(input) + + expect(output.to_html).to eq '<a>Foo</a>' + end + it 'allows non-standard anchor schemes' do exp = %q{<a href="irc://irc.freenode.net/git">IRC</a>} act = filter(exp) diff --git a/spec/lib/banzai/filter/yaml_front_matter_filter_spec.rb b/spec/lib/banzai/filter/yaml_front_matter_filter_spec.rb new file mode 100644 index 00000000000..fe70eada7eb --- /dev/null +++ b/spec/lib/banzai/filter/yaml_front_matter_filter_spec.rb @@ -0,0 +1,53 @@ +require 'rails_helper' + +describe Banzai::Filter::YamlFrontMatterFilter, lib: true do + include FilterSpecHelper + + it 'allows for `encoding:` before the frontmatter' do + content = <<-MD.strip_heredoc + # encoding: UTF-8 + --- + foo: foo + --- + + # Header + + Content + MD + + output = filter(content) + + expect(output).not_to match 'encoding' + end + + it 'converts YAML frontmatter to a fenced code block' do + content = <<-MD.strip_heredoc + --- + bar: :bar_symbol + --- + + # Header + + Content + MD + + output = filter(content) + + aggregate_failures do + expect(output).not_to include '---' + expect(output).to include "```yaml\nbar: :bar_symbol\n```" + end + end + + context 'on content without frontmatter' do + it 'returns the content unmodified' do + content = <<-MD.strip_heredoc + # This is some Markdown + + It has no YAML frontmatter to parse. + MD + + expect(filter(content)).to eq content + end + end +end diff --git a/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb b/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb new file mode 100644 index 00000000000..3e25406e498 --- /dev/null +++ b/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb @@ -0,0 +1,53 @@ +require 'rails_helper' + +describe Banzai::Pipeline::WikiPipeline do + describe 'TableOfContents' do + it 'replaces the tag with the TableOfContentsFilter result' do + markdown = <<-MD.strip_heredoc + [[_TOC_]] + + ## Header + + Foo + MD + + result = described_class.call(markdown, project: spy, project_wiki: double) + + aggregate_failures do + expect(result[:output].text).not_to include '[[' + expect(result[:output].text).not_to include 'TOC' + expect(result[:output].to_html).to include(result[:toc]) + end + end + + it 'is case-sensitive' do + markdown = <<-MD.strip_heredoc + [[_toc_]] + + # Header 1 + + Foo + MD + + output = described_class.to_html(markdown, project: spy, project_wiki: double) + + expect(output).to include('[[<em>toc</em>]]') + end + + it 'handles an empty pipeline result' do + # No Markdown headers in this doc, so `result[:toc]` will be empty + markdown = <<-MD.strip_heredoc + [[_TOC_]] + + Foo + MD + + output = described_class.to_html(markdown, project: spy, project_wiki: double) + + aggregate_failures do + expect(output).not_to include('<ul>') + expect(output).not_to include('[[<em>TOC</em>]]') + end + end + end +end diff --git a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb index f3394910c5b..fab6412d29f 100644 --- a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb +++ b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb @@ -397,7 +397,7 @@ module Ci services: ["mysql"], before_script: ["pwd"], rspec: { - artifacts: { paths: ["logs/", "binaries/"], untracked: true }, + artifacts: { paths: ["logs/", "binaries/"], untracked: true, name: "custom_name" }, script: "rspec" } }) @@ -417,6 +417,7 @@ module Ci image: "ruby:2.1", services: ["mysql"], artifacts: { + name: "custom_name", paths: ["logs/", "binaries/"], untracked: true } @@ -427,6 +428,112 @@ module Ci end end + describe "Dependencies" do + let(:config) do + { + build1: { stage: 'build', script: 'test' }, + build2: { stage: 'build', script: 'test' }, + test1: { stage: 'test', script: 'test', dependencies: dependencies }, + test2: { stage: 'test', script: 'test' }, + deploy: { stage: 'test', script: 'test' } + } + end + + subject { GitlabCiYamlProcessor.new(YAML.dump(config)) } + + context 'no dependencies' do + let(:dependencies) { } + + it { expect { subject }.to_not raise_error } + end + + context 'dependencies to builds' do + let(:dependencies) { [:build1, :build2] } + + it { expect { subject }.to_not raise_error } + end + + context 'undefined dependency' do + let(:dependencies) { [:undefined] } + + it { expect { subject }.to raise_error(GitlabCiYamlProcessor::ValidationError, 'test1 job: undefined dependency: undefined') } + end + + context 'dependencies to deploy' do + let(:dependencies) { [:deploy] } + + it { expect { subject }.to raise_error(GitlabCiYamlProcessor::ValidationError, 'test1 job: dependency deploy is not defined in prior stages') } + end + end + + describe "Hidden jobs" do + let(:config) do + YAML.dump({ + '.hidden_job' => { script: 'test' }, + 'normal_job' => { script: 'test' } + }) + end + + let(:config_processor) { GitlabCiYamlProcessor.new(config) } + + subject { config_processor.builds_for_stage_and_ref("test", "master") } + + it "doesn't create jobs that starts with dot" do + expect(subject.size).to eq(1) + expect(subject.first).to eq({ + except: nil, + stage: "test", + stage_idx: 1, + name: :normal_job, + only: nil, + commands: "\ntest", + tag_list: [], + options: {}, + when: "on_success", + allow_failure: false + }) + end + end + + describe "YAML Alias/Anchor" do + it "is correctly supported for jobs" do + config = <<EOT +job1: &JOBTMPL + script: execute-script-for-job + +job2: *JOBTMPL +EOT + + config_processor = GitlabCiYamlProcessor.new(config) + + expect(config_processor.builds_for_stage_and_ref("test", "master").size).to eq(2) + expect(config_processor.builds_for_stage_and_ref("test", "master").first).to eq({ + except: nil, + stage: "test", + stage_idx: 1, + name: :job1, + only: nil, + commands: "\nexecute-script-for-job", + tag_list: [], + options: {}, + when: "on_success", + allow_failure: false + }) + expect(config_processor.builds_for_stage_and_ref("test", "master").second).to eq({ + except: nil, + stage: "test", + stage_idx: 1, + name: :job2, + only: nil, + commands: "\nexecute-script-for-job", + tag_list: [], + options: {}, + when: "on_success", + allow_failure: false + }) + end + end + describe "Error handling" do it "fails to parse YAML" do expect{GitlabCiYamlProcessor.new("invalid: yaml: test")}.to raise_error(Psych::SyntaxError) @@ -590,6 +697,13 @@ module Ci end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: when parameter should be on_success, on_failure or always") end + it "returns errors if job artifacts:name is not an a string" do + config = YAML.dump({ types: ["build", "test"], rspec: { script: "test", artifacts: { name: 1 } } }) + expect do + GitlabCiYamlProcessor.new(config) + end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: artifacts:name parameter should be a string") + end + it "returns errors if job artifacts:untracked is not an array of strings" do config = YAML.dump({ types: ["build", "test"], rspec: { script: "test", artifacts: { untracked: "string" } } }) expect do @@ -645,6 +759,13 @@ module Ci GitlabCiYamlProcessor.new(config) end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: cache:paths parameter should be an array of strings") end + + it "returns errors if job dependencies is not an array of strings" do + config = YAML.dump({ types: ["build", "test"], rspec: { script: "test", dependencies: "string" } }) + expect do + GitlabCiYamlProcessor.new(config) + end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: dependencies parameter should be an array of strings") + end end end end diff --git a/spec/lib/ci/status_spec.rb b/spec/lib/ci/status_spec.rb index 1539720bb8d..47f3df6e3ce 100644 --- a/spec/lib/ci/status_spec.rb +++ b/spec/lib/ci/status_spec.rb @@ -48,6 +48,29 @@ describe Ci::Status do it { is_expected.to eq 'success' } end + context 'success and canceled' do + let(:statuses) do + [create(type, status: :success), create(type, status: :canceled)] + end + it { is_expected.to eq 'failed' } + end + + context 'all canceled' do + let(:statuses) do + [create(type, status: :canceled), create(type, status: :canceled)] + end + it { is_expected.to eq 'canceled' } + end + + context 'success and canceled but allowed to fail' do + let(:statuses) do + [create(type, status: :success), + create(type, status: :canceled, allow_failure: true)] + end + + it { is_expected.to eq 'success' } + end + context 'one finished and second running but allowed to fail' do let(:statuses) do [create(type, status: :success), diff --git a/spec/lib/gitlab/bitbucket_import/importer_spec.rb b/spec/lib/gitlab/bitbucket_import/importer_spec.rb new file mode 100644 index 00000000000..c413132abe5 --- /dev/null +++ b/spec/lib/gitlab/bitbucket_import/importer_spec.rb @@ -0,0 +1,88 @@ +require 'spec_helper' + +describe Gitlab::BitbucketImport::Importer, lib: true do + before do + Gitlab.config.omniauth.providers << OpenStruct.new(app_id: "asd123", app_secret: "asd123", name: "bitbucket") + end + + let(:statuses) do + [ + "open", + "resolved", + "on hold", + "invalid", + "duplicate", + "wontfix", + "closed" # undocumented status + ] + end + let(:sample_issues_statuses) do + issues = [] + + statuses.map.with_index do |status, index| + issues << { + local_id: index, + status: status, + title: "Issue #{index}", + content: "Some content to issue #{index}" + } + end + + issues + end + + let(:project_identifier) { 'namespace/repo' } + let(:data) do + { + bb_session: { + bitbucket_access_token: "123456", + bitbucket_access_token_secret: "secret" + } + } + end + let(:project) do + create( + :project, + import_source: project_identifier, + import_data: ProjectImportData.new(data: data) + ) + end + let(:importer) { Gitlab::BitbucketImport::Importer.new(project) } + let(:issues_statuses_sample_data) do + { + count: sample_issues_statuses.count, + issues: sample_issues_statuses + } + end + + context 'issues statuses' do + before do + stub_request( + :get, + "https://bitbucket.org/api/1.0/repositories/#{project_identifier}" + ).to_return(status: 200, body: { has_issues: true }.to_json) + + stub_request( + :get, + "https://bitbucket.org/api/1.0/repositories/#{project_identifier}/issues?limit=50&sort=utc_created_on&start=0" + ).to_return(status: 200, body: issues_statuses_sample_data.to_json) + + sample_issues_statuses.each_with_index do |issue, index| + stub_request( + :get, + "https://bitbucket.org/api/1.0/repositories/#{project_identifier}/issues/#{issue[:local_id]}/comments" + ).to_return( + status: 200, + body: [{ author_info: { username: "username" }, utc_created_on: index }].to_json + ) + end + end + + it 'map statuses to open or closed' do + importer.execute + + expect(project.issues.where(state: "closed").size).to eq(5) + expect(project.issues.where(state: "opened").size).to eq(2) + end + end +end diff --git a/spec/lib/gitlab/closing_issue_extractor_spec.rb b/spec/lib/gitlab/closing_issue_extractor_spec.rb index 04cf11fc6f1..844fd79c991 100644 --- a/spec/lib/gitlab/closing_issue_extractor_spec.rb +++ b/spec/lib/gitlab/closing_issue_extractor_spec.rb @@ -11,6 +11,7 @@ describe Gitlab::ClosingIssueExtractor, lib: true do subject { described_class.new(project, project.creator) } before do + project.team << [project.creator, :developer] project2.team << [project.creator, :master] end diff --git a/spec/lib/gitlab/diff/file_spec.rb b/spec/lib/gitlab/diff/file_spec.rb index 0d9694f2c13..a0cbef6e6a4 100644 --- a/spec/lib/gitlab/diff/file_spec.rb +++ b/spec/lib/gitlab/diff/file_spec.rb @@ -18,4 +18,18 @@ describe Gitlab::Diff::File, lib: true do describe :mode_changed? do it { expect(diff_file.mode_changed?).to be_falsey } end + + describe '#too_large?' do + it 'returns true for a file that is too large' do + expect(diff).to receive(:too_large?).and_return(true) + + expect(diff_file.too_large?).to eq(true) + end + + it 'returns false for a file that is small enough' do + expect(diff).to receive(:too_large?).and_return(false) + + expect(diff_file.too_large?).to eq(false) + end + end end diff --git a/spec/lib/gitlab/diff/parser_spec.rb b/spec/lib/gitlab/diff/parser_spec.rb index fe0dea77909..cdff063a9ed 100644 --- a/spec/lib/gitlab/diff/parser_spec.rb +++ b/spec/lib/gitlab/diff/parser_spec.rb @@ -47,7 +47,7 @@ eos end before do - @lines = parser.parse(diff.lines) + @lines = parser.parse(diff.lines).to_a end it { expect(@lines.size).to eq(30) } @@ -90,4 +90,9 @@ eos end end end + + context 'when lines is empty' do + it { expect(parser.parse([])).to eq([]) } + it { expect(parser.parse(nil)).to eq([]) } + end end diff --git a/spec/lib/gitlab/email/message/repository_push_spec.rb b/spec/lib/gitlab/email/message/repository_push_spec.rb index 56ae2a8d121..b2d7a799810 100644 --- a/spec/lib/gitlab/email/message/repository_push_spec.rb +++ b/spec/lib/gitlab/email/message/repository_push_spec.rb @@ -72,7 +72,7 @@ describe Gitlab::Email::Message::RepositoryPush do describe '#compare_timeout' do subject { message.compare_timeout } - it { is_expected.to eq compare.timeout } + it { is_expected.to eq compare.diffs.overflow? } end describe '#reverse_compare?' do diff --git a/spec/lib/gitlab/exclusive_lease_spec.rb b/spec/lib/gitlab/exclusive_lease_spec.rb new file mode 100644 index 00000000000..fbdb7ea34ac --- /dev/null +++ b/spec/lib/gitlab/exclusive_lease_spec.rb @@ -0,0 +1,21 @@ +require 'spec_helper' + +describe Gitlab::ExclusiveLease do + it 'cannot obtain twice before the lease has expired' do + lease = Gitlab::ExclusiveLease.new(unique_key, timeout: 3600) + expect(lease.try_obtain).to eq(true) + expect(lease.try_obtain).to eq(false) + end + + it 'can obtain after the lease has expired' do + timeout = 1 + lease = Gitlab::ExclusiveLease.new(unique_key, timeout: timeout) + lease.try_obtain # start the lease + sleep(2 * timeout) # lease should have expired now + expect(lease.try_obtain).to eq(true) + end + + def unique_key + SecureRandom.hex(10) + end +end diff --git a/spec/lib/gitlab/github_import/pull_request_formatter_spec.rb b/spec/lib/gitlab/github_import/pull_request_formatter_spec.rb index 6cebcb5009a..e49dcb42342 100644 --- a/spec/lib/gitlab/github_import/pull_request_formatter_spec.rb +++ b/spec/lib/gitlab/github_import/pull_request_formatter_spec.rb @@ -127,34 +127,6 @@ describe Gitlab::GithubImport::PullRequestFormatter, lib: true do end end - describe '#cross_project?' do - context 'when source, and target repositories are the same' do - let(:raw_data) { OpenStruct.new(base_data) } - - it 'returns false' do - expect(pull_request.cross_project?).to eq false - end - end - - context 'when source repo is a fork' do - let(:source_repo) { OpenStruct.new(id: 2, fork: true) } - let(:raw_data) { OpenStruct.new(base_data) } - - it 'returns true' do - expect(pull_request.cross_project?).to eq true - end - end - - context 'when target repo is a fork' do - let(:target_repo) { OpenStruct.new(id: 2, fork: true) } - let(:raw_data) { OpenStruct.new(base_data) } - - it 'returns true' do - expect(pull_request.cross_project?).to eq true - end - end - end - describe '#number' do let(:raw_data) { OpenStruct.new(base_data.merge(number: 1347)) } @@ -166,24 +138,44 @@ describe Gitlab::GithubImport::PullRequestFormatter, lib: true do describe '#valid?' do let(:invalid_branch) { OpenStruct.new(ref: 'invalid-branch') } - context 'when source and target branches exists' do - let(:raw_data) { OpenStruct.new(base_data.merge(head: source_branch, base: target_branch)) } + context 'when source, and target repositories are the same' do + context 'and source and target branches exists' do + let(:raw_data) { OpenStruct.new(base_data.merge(head: source_branch, base: target_branch)) } - it 'returns true' do - expect(pull_request.valid?).to eq true + it 'returns true' do + expect(pull_request.valid?).to eq true + end + end + + context 'and source branch doesn not exists' do + let(:raw_data) { OpenStruct.new(base_data.merge(head: invalid_branch, base: target_branch)) } + + it 'returns false' do + expect(pull_request.valid?).to eq false + end + end + + context 'and target branch doesn not exists' do + let(:raw_data) { OpenStruct.new(base_data.merge(head: source_branch, base: invalid_branch)) } + + it 'returns false' do + expect(pull_request.valid?).to eq false + end end end - context 'when source branch doesn not exists' do - let(:raw_data) { OpenStruct.new(base_data.merge(head: invalid_branch, base: target_branch)) } + context 'when source repo is a fork' do + let(:source_repo) { OpenStruct.new(id: 2, fork: true) } + let(:raw_data) { OpenStruct.new(base_data) } it 'returns false' do expect(pull_request.valid?).to eq false end end - context 'when target branch doesn not exists' do - let(:raw_data) { OpenStruct.new(base_data.merge(head: source_branch, base: invalid_branch)) } + context 'when target repo is a fork' do + let(:target_repo) { OpenStruct.new(id: 2, fork: true) } + let(:raw_data) { OpenStruct.new(base_data) } it 'returns false' do expect(pull_request.valid?).to eq false diff --git a/spec/lib/gitlab/middleware/go_spec.rb b/spec/lib/gitlab/middleware/go_spec.rb new file mode 100644 index 00000000000..117a15264da --- /dev/null +++ b/spec/lib/gitlab/middleware/go_spec.rb @@ -0,0 +1,30 @@ +require 'spec_helper' + +describe Gitlab::Middleware::Go, lib: true do + let(:app) { double(:app) } + let(:middleware) { described_class.new(app) } + + describe '#call' do + describe 'when go-get=0' do + it 'skips go-import generation' do + env = { 'rack.input' => '', + 'QUERY_STRING' => 'go-get=0' } + expect(app).to receive(:call).with(env).and_return('no-go') + middleware.call(env) + end + end + + describe 'when go-get=1' do + it 'returns a document' do + env = { 'rack.input' => '', + 'QUERY_STRING' => 'go-get=1', + 'PATH_INFO' => '/group/project/path' } + resp = middleware.call(env) + expect(resp[0]).to eq(200) + expect(resp[1]['Content-Type']).to eq('text/html') + expected_body = "<!DOCTYPE html><html><head><meta content='localhost/group/project git http://localhost/group/project.git' name='go-import'></head></html>\n" + expect(resp[2].body).to eq([expected_body]) + end + end + end +end diff --git a/spec/lib/gitlab/project_search_results_spec.rb b/spec/lib/gitlab/project_search_results_spec.rb index efc2e5f4ef1..db0ff95b4f5 100644 --- a/spec/lib/gitlab/project_search_results_spec.rb +++ b/spec/lib/gitlab/project_search_results_spec.rb @@ -1,11 +1,12 @@ require 'spec_helper' describe Gitlab::ProjectSearchResults, lib: true do + let(:user) { create(:user) } let(:project) { create(:project) } let(:query) { 'hello world' } describe 'initialize with empty ref' do - let(:results) { Gitlab::ProjectSearchResults.new(project.id, query, '') } + let(:results) { Gitlab::ProjectSearchResults.new(user, project, query, '') } it { expect(results.project).to eq(project) } it { expect(results.repository_ref).to be_nil } @@ -14,10 +15,74 @@ describe Gitlab::ProjectSearchResults, lib: true do describe 'initialize with ref' do let(:ref) { 'refs/heads/test' } - let(:results) { Gitlab::ProjectSearchResults.new(project.id, query, ref) } + let(:results) { Gitlab::ProjectSearchResults.new(user, project, query, ref) } it { expect(results.project).to eq(project) } it { expect(results.repository_ref).to eq(ref) } it { expect(results.query).to eq('hello world') } end + + describe 'confidential issues' do + let(:query) { 'issue' } + let(:author) { create(:user) } + let(:assignee) { create(:user) } + let(:non_member) { create(:user) } + let(:member) { create(:user) } + let(:admin) { create(:admin) } + let!(:issue) { create(:issue, project: project, title: 'Issue 1') } + let!(:security_issue_1) { create(:issue, :confidential, project: project, title: 'Security issue 1', author: author) } + let!(:security_issue_2) { create(:issue, :confidential, title: 'Security issue 2', project: project, assignee: assignee) } + + it 'should not list project confidential issues for non project members' do + results = described_class.new(non_member, project, query) + issues = results.objects('issues') + + expect(issues).to include issue + expect(issues).not_to include security_issue_1 + expect(issues).not_to include security_issue_2 + expect(results.issues_count).to eq 1 + end + + it 'should list project confidential issues for author' do + results = described_class.new(author, project, query) + issues = results.objects('issues') + + expect(issues).to include issue + expect(issues).to include security_issue_1 + expect(issues).not_to include security_issue_2 + expect(results.issues_count).to eq 2 + end + + it 'should list project confidential issues for assignee' do + results = described_class.new(assignee, project.id, query) + issues = results.objects('issues') + + expect(issues).to include issue + expect(issues).not_to include security_issue_1 + expect(issues).to include security_issue_2 + expect(results.issues_count).to eq 2 + end + + it 'should list project confidential issues for project members' do + project.team << [member, :developer] + + results = described_class.new(member, project, query) + issues = results.objects('issues') + + expect(issues).to include issue + expect(issues).to include security_issue_1 + expect(issues).to include security_issue_2 + expect(results.issues_count).to eq 3 + end + + it 'should list all project issues for admin' do + results = described_class.new(admin, project, query) + issues = results.objects('issues') + + expect(issues).to include issue + expect(issues).to include security_issue_1 + expect(issues).to include security_issue_2 + expect(results.issues_count).to eq 3 + end + end end diff --git a/spec/lib/gitlab/reference_extractor_spec.rb b/spec/lib/gitlab/reference_extractor_spec.rb index 7d963795e17..65af37e24f1 100644 --- a/spec/lib/gitlab/reference_extractor_spec.rb +++ b/spec/lib/gitlab/reference_extractor_spec.rb @@ -2,6 +2,7 @@ require 'spec_helper' describe Gitlab::ReferenceExtractor, lib: true do let(:project) { create(:project) } + subject { Gitlab::ReferenceExtractor.new(project, project.creator) } it 'accesses valid user objects' do @@ -41,6 +42,7 @@ describe Gitlab::ReferenceExtractor, lib: true do end it 'accesses valid issue objects' do + project.team << [project.creator, :developer] @i0 = create(:issue, project: project) @i1 = create(:issue, project: project) diff --git a/spec/lib/gitlab/search_results_spec.rb b/spec/lib/gitlab/search_results_spec.rb new file mode 100644 index 00000000000..f4afe597e8d --- /dev/null +++ b/spec/lib/gitlab/search_results_spec.rb @@ -0,0 +1,144 @@ +require 'spec_helper' + +describe Gitlab::SearchResults do + let(:user) { create(:user) } + let!(:project) { create(:project, name: 'foo') } + let!(:issue) { create(:issue, project: project, title: 'foo') } + + let!(:merge_request) do + create(:merge_request, source_project: project, title: 'foo') + end + + let!(:milestone) { create(:milestone, project: project, title: 'foo') } + let(:results) { described_class.new(user, Project.all, 'foo') } + + describe '#total_count' do + it 'returns the total amount of search hits' do + expect(results.total_count).to eq(4) + end + end + + describe '#projects_count' do + it 'returns the total amount of projects' do + expect(results.projects_count).to eq(1) + end + end + + describe '#issues_count' do + it 'returns the total amount of issues' do + expect(results.issues_count).to eq(1) + end + end + + describe '#merge_requests_count' do + it 'returns the total amount of merge requests' do + expect(results.merge_requests_count).to eq(1) + end + end + + describe '#milestones_count' do + it 'returns the total amount of milestones' do + expect(results.milestones_count).to eq(1) + end + end + + describe '#empty?' do + it 'returns true when there are no search results' do + allow(results).to receive(:total_count).and_return(0) + + expect(results.empty?).to eq(true) + end + + it 'returns false when there are search results' do + expect(results.empty?).to eq(false) + end + end + + describe 'confidential issues' do + let(:project_1) { create(:empty_project) } + let(:project_2) { create(:empty_project) } + let(:project_3) { create(:empty_project) } + let(:project_4) { create(:empty_project) } + let(:query) { 'issue' } + let(:limit_projects) { Project.where(id: [project_1.id, project_2.id, project_3.id]) } + let(:author) { create(:user) } + let(:assignee) { create(:user) } + let(:non_member) { create(:user) } + let(:member) { create(:user) } + let(:admin) { create(:admin) } + let!(:issue) { create(:issue, project: project_1, title: 'Issue 1') } + let!(:security_issue_1) { create(:issue, :confidential, project: project_1, title: 'Security issue 1', author: author) } + let!(:security_issue_2) { create(:issue, :confidential, title: 'Security issue 2', project: project_1, assignee: assignee) } + let!(:security_issue_3) { create(:issue, :confidential, project: project_2, title: 'Security issue 3', author: author) } + let!(:security_issue_4) { create(:issue, :confidential, project: project_3, title: 'Security issue 4', assignee: assignee) } + let!(:security_issue_5) { create(:issue, :confidential, project: project_4, title: 'Security issue 5') } + + it 'should not list confidential issues for non project members' do + results = described_class.new(non_member, limit_projects, query) + issues = results.objects('issues') + + expect(issues).to include issue + expect(issues).not_to include security_issue_1 + expect(issues).not_to include security_issue_2 + expect(issues).not_to include security_issue_3 + expect(issues).not_to include security_issue_4 + expect(issues).not_to include security_issue_5 + expect(results.issues_count).to eq 1 + end + + it 'should list confidential issues for author' do + results = described_class.new(author, limit_projects, query) + issues = results.objects('issues') + + expect(issues).to include issue + expect(issues).to include security_issue_1 + expect(issues).not_to include security_issue_2 + expect(issues).to include security_issue_3 + expect(issues).not_to include security_issue_4 + expect(issues).not_to include security_issue_5 + expect(results.issues_count).to eq 3 + end + + it 'should list confidential issues for assignee' do + results = described_class.new(assignee, limit_projects, query) + issues = results.objects('issues') + + expect(issues).to include issue + expect(issues).not_to include security_issue_1 + expect(issues).to include security_issue_2 + expect(issues).not_to include security_issue_3 + expect(issues).to include security_issue_4 + expect(issues).not_to include security_issue_5 + expect(results.issues_count).to eq 3 + end + + it 'should list confidential issues for project members' do + project_1.team << [member, :developer] + project_2.team << [member, :developer] + + results = described_class.new(member, limit_projects, query) + issues = results.objects('issues') + + expect(issues).to include issue + expect(issues).to include security_issue_1 + expect(issues).to include security_issue_2 + expect(issues).to include security_issue_3 + expect(issues).not_to include security_issue_4 + expect(issues).not_to include security_issue_5 + expect(results.issues_count).to eq 4 + end + + it 'should list all issues for admin' do + results = described_class.new(admin, limit_projects, query) + issues = results.objects('issues') + + expect(issues).to include issue + expect(issues).to include security_issue_1 + expect(issues).to include security_issue_2 + expect(issues).to include security_issue_3 + expect(issues).to include security_issue_4 + expect(issues).not_to include security_issue_5 + expect(results.issues_count).to eq 5 + end + end +end diff --git a/spec/lib/gitlab/snippet_search_results_spec.rb b/spec/lib/gitlab/snippet_search_results_spec.rb new file mode 100644 index 00000000000..e86b9ef6a63 --- /dev/null +++ b/spec/lib/gitlab/snippet_search_results_spec.rb @@ -0,0 +1,25 @@ +require 'spec_helper' + +describe Gitlab::SnippetSearchResults do + let!(:snippet) { create(:snippet, content: 'foo', file_name: 'foo') } + + let(:results) { described_class.new(Snippet.all, 'foo') } + + describe '#total_count' do + it 'returns the total amount of search hits' do + expect(results.total_count).to eq(2) + end + end + + describe '#snippet_titles_count' do + it 'returns the amount of matched snippet titles' do + expect(results.snippet_titles_count).to eq(1) + end + end + + describe '#snippet_blobs_count' do + it 'returns the amount of matched snippet blobs' do + expect(results.snippet_blobs_count).to eq(1) + end + end +end |
