summaryrefslogtreecommitdiff
path: root/spec/lib
diff options
context:
space:
mode:
Diffstat (limited to 'spec/lib')
-rw-r--r--spec/lib/banzai/filter/external_link_filter_spec.rb14
-rw-r--r--spec/lib/gitlab/chat_commands/command_spec.rb28
-rw-r--r--spec/lib/gitlab/git/rev_list_spec.rb7
-rw-r--r--spec/lib/gitlab/github_import/client_spec.rb46
-rw-r--r--spec/lib/gitlab/github_import/importer_spec.rb370
-rw-r--r--spec/lib/gitlab/github_import/issuable_formatter_spec.rb21
-rw-r--r--spec/lib/gitlab/github_import/issue_formatter_spec.rb38
-rw-r--r--spec/lib/gitlab/github_import/milestone_formatter_spec.rb27
-rw-r--r--spec/lib/gitlab/github_import/pull_request_formatter_spec.rb34
-rw-r--r--spec/lib/gitlab/import_export/all_models.yml5
-rw-r--r--spec/lib/gitlab/import_export/project.json22
-rw-r--r--spec/lib/gitlab/import_sources_spec.rb94
-rw-r--r--spec/lib/gitlab/kubernetes_spec.rb39
-rw-r--r--spec/lib/gitlab/metrics/rack_middleware_spec.rb4
-rw-r--r--spec/lib/gitlab/middleware/multipart_spec.rb6
-rw-r--r--spec/lib/gitlab/workhorse_spec.rb36
-rw-r--r--spec/lib/mattermost/client_spec.rb24
-rw-r--r--spec/lib/mattermost/command_spec.rb61
-rw-r--r--spec/lib/mattermost/session_spec.rb24
-rw-r--r--spec/lib/mattermost/team_spec.rb66
20 files changed, 777 insertions, 189 deletions
diff --git a/spec/lib/banzai/filter/external_link_filter_spec.rb b/spec/lib/banzai/filter/external_link_filter_spec.rb
index 167397c736b..d9e4525cb28 100644
--- a/spec/lib/banzai/filter/external_link_filter_spec.rb
+++ b/spec/lib/banzai/filter/external_link_filter_spec.rb
@@ -80,4 +80,18 @@ describe Banzai::Filter::ExternalLinkFilter, lib: true do
expect(filter(act).to_html).to eq(exp)
end
end
+
+ context 'for protocol-relative links' do
+ let(:doc) { filter %q(<p><a href="//google.com/">Google</a></p>) }
+
+ it 'adds rel="nofollow" to external links' do
+ expect(doc.at_css('a')).to have_attribute('rel')
+ expect(doc.at_css('a')['rel']).to include 'nofollow'
+ end
+
+ it 'adds rel="noreferrer" to external links' do
+ expect(doc.at_css('a')).to have_attribute('rel')
+ expect(doc.at_css('a')['rel']).to include 'noreferrer'
+ end
+ end
end
diff --git a/spec/lib/gitlab/chat_commands/command_spec.rb b/spec/lib/gitlab/chat_commands/command_spec.rb
index bfc6818ac08..a0ec8884635 100644
--- a/spec/lib/gitlab/chat_commands/command_spec.rb
+++ b/spec/lib/gitlab/chat_commands/command_spec.rb
@@ -5,7 +5,9 @@ describe Gitlab::ChatCommands::Command, service: true do
let(:user) { create(:user) }
describe '#execute' do
- subject { described_class.new(project, user, params).execute }
+ subject do
+ described_class.new(project, user, params).execute
+ end
context 'when no command is available' do
let(:params) { { text: 'issue show 1' } }
@@ -74,7 +76,7 @@ describe Gitlab::ChatCommands::Command, service: true do
end
it 'returns action' do
- expect(subject[:text]).to include('Deployment from staging to production started')
+ expect(subject[:text]).to include('Deployment from staging to production started.')
expect(subject[:response_type]).to be(:in_channel)
end
@@ -91,4 +93,26 @@ describe Gitlab::ChatCommands::Command, service: true do
end
end
end
+
+ describe '#match_command' do
+ subject { described_class.new(project, user, params).match_command.first }
+
+ context 'IssueShow is triggered' do
+ let(:params) { { text: 'issue show 123' } }
+
+ it { is_expected.to eq(Gitlab::ChatCommands::IssueShow) }
+ end
+
+ context 'IssueCreate is triggered' do
+ let(:params) { { text: 'issue create my title' } }
+
+ it { is_expected.to eq(Gitlab::ChatCommands::IssueCreate) }
+ end
+
+ context 'IssueSearch is triggered' do
+ let(:params) { { text: 'issue search my query' } }
+
+ it { is_expected.to eq(Gitlab::ChatCommands::IssueSearch) }
+ end
+ end
end
diff --git a/spec/lib/gitlab/git/rev_list_spec.rb b/spec/lib/gitlab/git/rev_list_spec.rb
index 444639acbaa..1f9c987be0b 100644
--- a/spec/lib/gitlab/git/rev_list_spec.rb
+++ b/spec/lib/gitlab/git/rev_list_spec.rb
@@ -26,6 +26,13 @@ describe Gitlab::Git::RevList, lib: true do
expect(rev_list).not_to be_valid
end
+
+ it "ignores nil values" do
+ env = { var => nil }
+ rev_list = described_class.new('oldrev', 'newrev', project: project, env: env)
+
+ expect(rev_list).to be_valid
+ end
end
end
end
diff --git a/spec/lib/gitlab/github_import/client_spec.rb b/spec/lib/gitlab/github_import/client_spec.rb
index e829b936343..21f2a9e225b 100644
--- a/spec/lib/gitlab/github_import/client_spec.rb
+++ b/spec/lib/gitlab/github_import/client_spec.rb
@@ -45,20 +45,46 @@ describe Gitlab::GithubImport::Client, lib: true do
end
end
- context 'when provider does not specity an API endpoint' do
- it 'uses GitHub root API endpoint' do
- expect(client.api.api_endpoint).to eq 'https://api.github.com/'
+ describe '#api_endpoint' do
+ context 'when provider does not specity an API endpoint' do
+ it 'uses GitHub root API endpoint' do
+ expect(client.api.api_endpoint).to eq 'https://api.github.com/'
+ end
end
- end
- context 'when provider specify a custom API endpoint' do
- before do
- github_provider['args']['client_options']['site'] = 'https://github.company.com/'
+ context 'when provider specify a custom API endpoint' do
+ before do
+ github_provider['args']['client_options']['site'] = 'https://github.company.com/'
+ end
+
+ it 'uses the custom API endpoint' do
+ expect(OmniAuth::Strategies::GitHub).not_to receive(:default_options)
+ expect(client.api.api_endpoint).to eq 'https://github.company.com/'
+ end
+ end
+
+ context 'when given a host' do
+ subject(:client) { described_class.new(token, host: 'https://try.gitea.io/') }
+
+ it 'builds a endpoint with the given host and the default API version' do
+ expect(client.api.api_endpoint).to eq 'https://try.gitea.io/api/v3/'
+ end
end
- it 'uses the custom API endpoint' do
- expect(OmniAuth::Strategies::GitHub).not_to receive(:default_options)
- expect(client.api.api_endpoint).to eq 'https://github.company.com/'
+ context 'when given an API version' do
+ subject(:client) { described_class.new(token, api_version: 'v3') }
+
+ it 'does not use the API version without a host' do
+ expect(client.api.api_endpoint).to eq 'https://api.github.com/'
+ end
+ end
+
+ context 'when given a host and version' do
+ subject(:client) { described_class.new(token, host: 'https://try.gitea.io/', api_version: 'v3') }
+
+ it 'builds a endpoint with the given options' do
+ expect(client.api.api_endpoint).to eq 'https://try.gitea.io/api/v3/'
+ end
end
end
diff --git a/spec/lib/gitlab/github_import/importer_spec.rb b/spec/lib/gitlab/github_import/importer_spec.rb
index 9e027839f59..72421832ffc 100644
--- a/spec/lib/gitlab/github_import/importer_spec.rb
+++ b/spec/lib/gitlab/github_import/importer_spec.rb
@@ -1,169 +1,251 @@
require 'spec_helper'
describe Gitlab::GithubImport::Importer, lib: true do
- describe '#execute' do
+ shared_examples 'Gitlab::GithubImport::Importer#execute' do
+ let(:expected_not_called) { [] }
+
before do
- allow(Rails).to receive(:cache).and_return(ActiveSupport::Cache::MemoryStore.new)
+ allow(project).to receive(:import_data).and_return(double.as_null_object)
end
- context 'when an error occurs' do
- let(:project) { create(:project, import_url: 'https://github.com/octocat/Hello-World.git', wiki_access_level: ProjectFeature::DISABLED) }
- let(:octocat) { double(id: 123456, login: 'octocat') }
- let(:created_at) { DateTime.strptime('2011-01-26T19:01:12Z') }
- let(:updated_at) { DateTime.strptime('2011-01-27T19:01:12Z') }
- let(:repository) { double(id: 1, fork: false) }
- let(:source_sha) { create(:commit, project: project).id }
- let(:source_branch) { double(ref: 'feature', repo: repository, sha: source_sha) }
- let(:target_sha) { create(:commit, project: project, git_commit: RepoHelpers.another_sample_commit).id }
- let(:target_branch) { double(ref: 'master', repo: repository, sha: target_sha) }
-
- let(:label1) do
- double(
- name: 'Bug',
- color: 'ff0000',
- url: 'https://api.github.com/repos/octocat/Hello-World/labels/bug'
- )
- end
+ it 'calls import methods' do
+ importer = described_class.new(project)
- let(:label2) do
- double(
- name: nil,
- color: 'ff0000',
- url: 'https://api.github.com/repos/octocat/Hello-World/labels/bug'
- )
- end
+ expected_called = [
+ :import_labels, :import_milestones, :import_pull_requests, :import_issues,
+ :import_wiki, :import_releases, :handle_errors
+ ]
- let(:milestone) do
- double(
- number: 1347,
- state: 'open',
- title: '1.0',
- description: 'Version 1.0',
- due_on: nil,
- created_at: created_at,
- updated_at: updated_at,
- closed_at: nil,
- url: 'https://api.github.com/repos/octocat/Hello-World/milestones/1'
- )
- end
+ expected_called -= expected_not_called
- let(:issue1) do
- double(
- number: 1347,
- milestone: nil,
- state: 'open',
- title: 'Found a bug',
- body: "I'm having a problem with this.",
- assignee: nil,
- user: octocat,
- comments: 0,
- pull_request: nil,
- created_at: created_at,
- updated_at: updated_at,
- closed_at: nil,
- url: 'https://api.github.com/repos/octocat/Hello-World/issues/1347',
- labels: [double(name: 'Label #1')],
- )
- end
+ aggregate_failures do
+ expected_called.each do |method_name|
+ expect(importer).to receive(method_name)
+ end
- let(:issue2) do
- double(
- number: 1348,
- milestone: nil,
- state: 'open',
- title: nil,
- body: "I'm having a problem with this.",
- assignee: nil,
- user: octocat,
- comments: 0,
- pull_request: nil,
- created_at: created_at,
- updated_at: updated_at,
- closed_at: nil,
- url: 'https://api.github.com/repos/octocat/Hello-World/issues/1348',
- labels: [double(name: 'Label #2')],
- )
- end
+ expect(importer).to receive(:import_comments).with(:issues)
+ expect(importer).to receive(:import_comments).with(:pull_requests)
- let(:pull_request) do
- double(
- number: 1347,
- milestone: nil,
- state: 'open',
- title: 'New feature',
- body: 'Please pull these awesome changes',
- head: source_branch,
- base: target_branch,
- assignee: nil,
- user: octocat,
- created_at: created_at,
- updated_at: updated_at,
- closed_at: nil,
- merged_at: nil,
- url: 'https://api.github.com/repos/octocat/Hello-World/pulls/1347',
- )
+ expected_not_called.each do |method_name|
+ expect(importer).not_to receive(method_name)
+ end
end
- let(:release1) do
- double(
- tag_name: 'v1.0.0',
- name: 'First release',
- body: 'Release v1.0.0',
- draft: false,
- created_at: created_at,
- updated_at: updated_at,
- url: 'https://api.github.com/repos/octocat/Hello-World/releases/1'
- )
- end
+ importer.execute
+ end
+ end
- let(:release2) do
- double(
- tag_name: 'v2.0.0',
- name: 'Second release',
- body: nil,
- draft: false,
- created_at: created_at,
- updated_at: updated_at,
- url: 'https://api.github.com/repos/octocat/Hello-World/releases/2'
- )
- end
+ shared_examples 'Gitlab::GithubImport::Importer#execute an error occurs' do
+ before do
+ allow(project).to receive(:import_data).and_return(double.as_null_object)
- before do
- allow(project).to receive(:import_data).and_return(double.as_null_object)
- allow_any_instance_of(Octokit::Client).to receive(:rate_limit!).and_raise(Octokit::NotFound)
- allow_any_instance_of(Octokit::Client).to receive(:labels).and_return([label1, label2])
- allow_any_instance_of(Octokit::Client).to receive(:milestones).and_return([milestone, milestone])
- allow_any_instance_of(Octokit::Client).to receive(:issues).and_return([issue1, issue2])
- allow_any_instance_of(Octokit::Client).to receive(:pull_requests).and_return([pull_request, pull_request])
- allow_any_instance_of(Octokit::Client).to receive(:issues_comments).and_return([])
- allow_any_instance_of(Octokit::Client).to receive(:pull_requests_comments).and_return([])
- allow_any_instance_of(Octokit::Client).to receive(:last_response).and_return(double(rels: { next: nil }))
- allow_any_instance_of(Octokit::Client).to receive(:releases).and_return([release1, release2])
- allow_any_instance_of(Gitlab::Shell).to receive(:import_repository).and_raise(Gitlab::Shell::Error)
- end
+ allow(Rails).to receive(:cache).and_return(ActiveSupport::Cache::MemoryStore.new)
+
+ allow_any_instance_of(Octokit::Client).to receive(:rate_limit!).and_raise(Octokit::NotFound)
+ allow_any_instance_of(Gitlab::Shell).to receive(:import_repository).and_raise(Gitlab::Shell::Error)
+
+ allow_any_instance_of(Octokit::Client).to receive(:labels).and_return([label1, label2])
+ allow_any_instance_of(Octokit::Client).to receive(:milestones).and_return([milestone, milestone])
+ allow_any_instance_of(Octokit::Client).to receive(:issues).and_return([issue1, issue2])
+ allow_any_instance_of(Octokit::Client).to receive(:pull_requests).and_return([pull_request, pull_request])
+ allow_any_instance_of(Octokit::Client).to receive(:issues_comments).and_return([])
+ allow_any_instance_of(Octokit::Client).to receive(:pull_requests_comments).and_return([])
+ allow_any_instance_of(Octokit::Client).to receive(:last_response).and_return(double(rels: { next: nil }))
+ allow_any_instance_of(Octokit::Client).to receive(:releases).and_return([release1, release2])
+ end
+ let(:octocat) { double(id: 123456, login: 'octocat') }
+ let(:created_at) { DateTime.strptime('2011-01-26T19:01:12Z') }
+ let(:updated_at) { DateTime.strptime('2011-01-27T19:01:12Z') }
+ let(:label1) do
+ double(
+ name: 'Bug',
+ color: 'ff0000',
+ url: "#{api_root}/repos/octocat/Hello-World/labels/bug"
+ )
+ end
+
+ let(:label2) do
+ double(
+ name: nil,
+ color: 'ff0000',
+ url: "#{api_root}/repos/octocat/Hello-World/labels/bug"
+ )
+ end
+
+ let(:milestone) do
+ double(
+ id: 1347, # For Gitea
+ number: 1347,
+ state: 'open',
+ title: '1.0',
+ description: 'Version 1.0',
+ due_on: nil,
+ created_at: created_at,
+ updated_at: updated_at,
+ closed_at: nil,
+ url: "#{api_root}/repos/octocat/Hello-World/milestones/1"
+ )
+ end
- it 'returns true' do
- expect(described_class.new(project).execute).to eq true
+ let(:issue1) do
+ double(
+ number: 1347,
+ milestone: nil,
+ state: 'open',
+ title: 'Found a bug',
+ body: "I'm having a problem with this.",
+ assignee: nil,
+ user: octocat,
+ comments: 0,
+ pull_request: nil,
+ created_at: created_at,
+ updated_at: updated_at,
+ closed_at: nil,
+ url: "#{api_root}/repos/octocat/Hello-World/issues/1347",
+ labels: [double(name: 'Label #1')]
+ )
+ end
+
+ let(:issue2) do
+ double(
+ number: 1348,
+ milestone: nil,
+ state: 'open',
+ title: nil,
+ body: "I'm having a problem with this.",
+ assignee: nil,
+ user: octocat,
+ comments: 0,
+ pull_request: nil,
+ created_at: created_at,
+ updated_at: updated_at,
+ closed_at: nil,
+ url: "#{api_root}/repos/octocat/Hello-World/issues/1348",
+ labels: [double(name: 'Label #2')]
+ )
+ end
+
+ let(:repository) { double(id: 1, fork: false) }
+ let(:source_sha) { create(:commit, project: project).id }
+ let(:source_branch) { double(ref: 'feature', repo: repository, sha: source_sha) }
+ let(:target_sha) { create(:commit, project: project, git_commit: RepoHelpers.another_sample_commit).id }
+ let(:target_branch) { double(ref: 'master', repo: repository, sha: target_sha) }
+ let(:pull_request) do
+ double(
+ number: 1347,
+ milestone: nil,
+ state: 'open',
+ title: 'New feature',
+ body: 'Please pull these awesome changes',
+ head: source_branch,
+ base: target_branch,
+ assignee: nil,
+ user: octocat,
+ created_at: created_at,
+ updated_at: updated_at,
+ closed_at: nil,
+ merged_at: nil,
+ url: "#{api_root}/repos/octocat/Hello-World/pulls/1347",
+ labels: [double(name: 'Label #2')]
+ )
+ end
+
+ let(:release1) do
+ double(
+ tag_name: 'v1.0.0',
+ name: 'First release',
+ body: 'Release v1.0.0',
+ draft: false,
+ created_at: created_at,
+ updated_at: updated_at,
+ url: "#{api_root}/repos/octocat/Hello-World/releases/1"
+ )
+ end
+
+ let(:release2) do
+ double(
+ tag_name: 'v2.0.0',
+ name: 'Second release',
+ body: nil,
+ draft: false,
+ created_at: created_at,
+ updated_at: updated_at,
+ url: "#{api_root}/repos/octocat/Hello-World/releases/2"
+ )
+ end
+
+ it 'returns true' do
+ expect(described_class.new(project).execute).to eq true
+ end
+
+ it 'does not raise an error' do
+ expect { described_class.new(project).execute }.not_to raise_error
+ end
+
+ it 'stores error messages' do
+ error = {
+ message: 'The remote data could not be fully imported.',
+ errors: [
+ { type: :label, url: "#{api_root}/repos/octocat/Hello-World/labels/bug", errors: "Validation failed: Title can't be blank, Title is invalid" },
+ { type: :issue, url: "#{api_root}/repos/octocat/Hello-World/issues/1348", errors: "Validation failed: Title can't be blank" },
+ { type: :wiki, errors: "Gitlab::Shell::Error" }
+ ]
+ }
+
+ unless project.gitea_import?
+ error[:errors] << { type: :release, url: "#{api_root}/repos/octocat/Hello-World/releases/2", errors: "Validation failed: Description can't be blank" }
end
- it 'does not raise an error' do
- expect { described_class.new(project).execute }.not_to raise_error
+ described_class.new(project).execute
+
+ expect(project.import_error).to eq error.to_json
+ end
+ end
+
+ let(:project) { create(:project, import_url: "#{repo_root}/octocat/Hello-World.git", wiki_access_level: ProjectFeature::DISABLED) }
+ let(:credentials) { { user: 'joe' } }
+
+ context 'when importing a GitHub project' do
+ let(:api_root) { 'https://api.github.com' }
+ let(:repo_root) { 'https://github.com' }
+
+ it_behaves_like 'Gitlab::GithubImport::Importer#execute'
+ it_behaves_like 'Gitlab::GithubImport::Importer#execute an error occurs'
+
+ describe '#client' do
+ it 'instantiates a Client' do
+ allow(project).to receive(:import_data).and_return(double(credentials: credentials))
+ expect(Gitlab::GithubImport::Client).to receive(:new).with(
+ credentials[:user],
+ {}
+ )
+
+ described_class.new(project).client
end
+ end
+ end
- it 'stores error messages' do
- error = {
- message: 'The remote data could not be fully imported.',
- errors: [
- { type: :label, url: "https://api.github.com/repos/octocat/Hello-World/labels/bug", errors: "Validation failed: Title can't be blank, Title is invalid" },
- { type: :issue, url: "https://api.github.com/repos/octocat/Hello-World/issues/1348", errors: "Validation failed: Title can't be blank" },
- { type: :wiki, errors: "Gitlab::Shell::Error" },
- { type: :release, url: 'https://api.github.com/repos/octocat/Hello-World/releases/2', errors: "Validation failed: Description can't be blank" }
- ]
- }
+ context 'when importing a Gitea project' do
+ let(:api_root) { 'https://try.gitea.io/api/v1' }
+ let(:repo_root) { 'https://try.gitea.io' }
+ before do
+ project.update(import_type: 'gitea', import_url: "#{repo_root}/foo/group/project.git")
+ end
- described_class.new(project).execute
+ it_behaves_like 'Gitlab::GithubImport::Importer#execute' do
+ let(:expected_not_called) { [:import_releases] }
+ end
+ it_behaves_like 'Gitlab::GithubImport::Importer#execute an error occurs'
+
+ describe '#client' do
+ it 'instantiates a Client' do
+ allow(project).to receive(:import_data).and_return(double(credentials: credentials))
+ expect(Gitlab::GithubImport::Client).to receive(:new).with(
+ credentials[:user],
+ { host: "#{repo_root}:443/foo", api_version: 'v1' }
+ )
- expect(project.import_error).to eq error.to_json
+ described_class.new(project).client
end
end
end
diff --git a/spec/lib/gitlab/github_import/issuable_formatter_spec.rb b/spec/lib/gitlab/github_import/issuable_formatter_spec.rb
new file mode 100644
index 00000000000..6bc5f98ed2c
--- /dev/null
+++ b/spec/lib/gitlab/github_import/issuable_formatter_spec.rb
@@ -0,0 +1,21 @@
+require 'spec_helper'
+
+describe Gitlab::GithubImport::IssuableFormatter, lib: true do
+ let(:raw_data) do
+ double(number: 42)
+ end
+ let(:project) { double(import_type: 'github') }
+ let(:issuable_formatter) { described_class.new(project, raw_data) }
+
+ describe '#project_association' do
+ it { expect { issuable_formatter.project_association }.to raise_error(NotImplementedError) }
+ end
+
+ describe '#number' do
+ it { expect(issuable_formatter.number).to eq(42) }
+ end
+
+ describe '#find_condition' do
+ it { expect(issuable_formatter.find_condition).to eq({ iid: 42 }) }
+ end
+end
diff --git a/spec/lib/gitlab/github_import/issue_formatter_spec.rb b/spec/lib/gitlab/github_import/issue_formatter_spec.rb
index 95339e2f128..e31ed9c1fa0 100644
--- a/spec/lib/gitlab/github_import/issue_formatter_spec.rb
+++ b/spec/lib/gitlab/github_import/issue_formatter_spec.rb
@@ -23,9 +23,9 @@ describe Gitlab::GithubImport::IssueFormatter, lib: true do
}
end
- subject(:issue) { described_class.new(project, raw_data)}
+ subject(:issue) { described_class.new(project, raw_data) }
- describe '#attributes' do
+ shared_examples 'Gitlab::GithubImport::IssueFormatter#attributes' do
context 'when issue is open' do
let(:raw_data) { double(base_data.merge(state: 'open')) }
@@ -83,7 +83,7 @@ describe Gitlab::GithubImport::IssueFormatter, lib: true do
end
context 'when it has a milestone' do
- let(:milestone) { double(number: 45) }
+ let(:milestone) { double(id: 42, number: 42) }
let(:raw_data) { double(base_data.merge(milestone: milestone)) }
it 'returns nil when milestone does not exist' do
@@ -91,7 +91,7 @@ describe Gitlab::GithubImport::IssueFormatter, lib: true do
end
it 'returns milestone when it exists' do
- milestone = create(:milestone, project: project, iid: 45)
+ milestone = create(:milestone, project: project, iid: 42)
expect(issue.attributes.fetch(:milestone)).to eq milestone
end
@@ -118,6 +118,28 @@ describe Gitlab::GithubImport::IssueFormatter, lib: true do
end
end
+ shared_examples 'Gitlab::GithubImport::IssueFormatter#number' do
+ let(:raw_data) { double(base_data.merge(number: 1347)) }
+
+ it 'returns issue number' do
+ expect(issue.number).to eq 1347
+ end
+ end
+
+ context 'when importing a GitHub project' do
+ it_behaves_like 'Gitlab::GithubImport::IssueFormatter#attributes'
+ it_behaves_like 'Gitlab::GithubImport::IssueFormatter#number'
+ end
+
+ context 'when importing a Gitea project' do
+ before do
+ project.update(import_type: 'gitea')
+ end
+
+ it_behaves_like 'Gitlab::GithubImport::IssueFormatter#attributes'
+ it_behaves_like 'Gitlab::GithubImport::IssueFormatter#number'
+ end
+
describe '#has_comments?' do
context 'when number of comments is greater than zero' do
let(:raw_data) { double(base_data.merge(comments: 1)) }
@@ -136,14 +158,6 @@ describe Gitlab::GithubImport::IssueFormatter, lib: true do
end
end
- describe '#number' do
- let(:raw_data) { double(base_data.merge(number: 1347)) }
-
- it 'returns pull request number' do
- expect(issue.number).to eq 1347
- end
- end
-
describe '#pull_request?' do
context 'when mention a pull request' do
let(:raw_data) { double(base_data.merge(pull_request: double)) }
diff --git a/spec/lib/gitlab/github_import/milestone_formatter_spec.rb b/spec/lib/gitlab/github_import/milestone_formatter_spec.rb
index 09337c99a07..6d38041c468 100644
--- a/spec/lib/gitlab/github_import/milestone_formatter_spec.rb
+++ b/spec/lib/gitlab/github_import/milestone_formatter_spec.rb
@@ -6,7 +6,6 @@ describe Gitlab::GithubImport::MilestoneFormatter, lib: true do
let(:updated_at) { DateTime.strptime('2011-01-27T19:01:12Z') }
let(:base_data) do
{
- number: 1347,
state: 'open',
title: '1.0',
description: 'Version 1.0',
@@ -16,12 +15,15 @@ describe Gitlab::GithubImport::MilestoneFormatter, lib: true do
closed_at: nil
}
end
+ let(:iid_attr) { :number }
- subject(:formatter) { described_class.new(project, raw_data)}
+ subject(:formatter) { described_class.new(project, raw_data) }
+
+ shared_examples 'Gitlab::GithubImport::MilestoneFormatter#attributes' do
+ let(:data) { base_data.merge(iid_attr => 1347) }
- describe '#attributes' do
context 'when milestone is open' do
- let(:raw_data) { double(base_data.merge(state: 'open')) }
+ let(:raw_data) { double(data.merge(state: 'open')) }
it 'returns formatted attributes' do
expected = {
@@ -40,7 +42,7 @@ describe Gitlab::GithubImport::MilestoneFormatter, lib: true do
end
context 'when milestone is closed' do
- let(:raw_data) { double(base_data.merge(state: 'closed')) }
+ let(:raw_data) { double(data.merge(state: 'closed')) }
it 'returns formatted attributes' do
expected = {
@@ -60,7 +62,7 @@ describe Gitlab::GithubImport::MilestoneFormatter, lib: true do
context 'when milestone has a due date' do
let(:due_date) { DateTime.strptime('2011-01-28T19:01:12Z') }
- let(:raw_data) { double(base_data.merge(due_on: due_date)) }
+ let(:raw_data) { double(data.merge(due_on: due_date)) }
it 'returns formatted attributes' do
expected = {
@@ -78,4 +80,17 @@ describe Gitlab::GithubImport::MilestoneFormatter, lib: true do
end
end
end
+
+ context 'when importing a GitHub project' do
+ it_behaves_like 'Gitlab::GithubImport::MilestoneFormatter#attributes'
+ end
+
+ context 'when importing a Gitea project' do
+ let(:iid_attr) { :id }
+ before do
+ project.update(import_type: 'gitea')
+ end
+
+ it_behaves_like 'Gitlab::GithubImport::MilestoneFormatter#attributes'
+ 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 302f0fc0623..2b3256edcb2 100644
--- a/spec/lib/gitlab/github_import/pull_request_formatter_spec.rb
+++ b/spec/lib/gitlab/github_import/pull_request_formatter_spec.rb
@@ -32,9 +32,9 @@ describe Gitlab::GithubImport::PullRequestFormatter, lib: true do
}
end
- subject(:pull_request) { described_class.new(project, raw_data)}
+ subject(:pull_request) { described_class.new(project, raw_data) }
- describe '#attributes' do
+ shared_examples 'Gitlab::GithubImport::PullRequestFormatter#attributes' do
context 'when pull request is open' do
let(:raw_data) { double(base_data.merge(state: 'open')) }
@@ -149,7 +149,7 @@ describe Gitlab::GithubImport::PullRequestFormatter, lib: true do
end
context 'when it has a milestone' do
- let(:milestone) { double(number: 45) }
+ let(:milestone) { double(id: 42, number: 42) }
let(:raw_data) { double(base_data.merge(milestone: milestone)) }
it 'returns nil when milestone does not exist' do
@@ -157,22 +157,22 @@ describe Gitlab::GithubImport::PullRequestFormatter, lib: true do
end
it 'returns milestone when it exists' do
- milestone = create(:milestone, project: project, iid: 45)
+ milestone = create(:milestone, project: project, iid: 42)
expect(pull_request.attributes.fetch(:milestone)).to eq milestone
end
end
end
- describe '#number' do
- let(:raw_data) { double(base_data.merge(number: 1347)) }
+ shared_examples 'Gitlab::GithubImport::PullRequestFormatter#number' do
+ let(:raw_data) { double(base_data) }
it 'returns pull request number' do
expect(pull_request.number).to eq 1347
end
end
- describe '#source_branch_name' do
+ shared_examples 'Gitlab::GithubImport::PullRequestFormatter#source_branch_name' do
context 'when source branch exists' do
let(:raw_data) { double(base_data) }
@@ -190,7 +190,7 @@ describe Gitlab::GithubImport::PullRequestFormatter, lib: true do
end
end
- describe '#target_branch_name' do
+ shared_examples 'Gitlab::GithubImport::PullRequestFormatter#target_branch_name' do
context 'when source branch exists' do
let(:raw_data) { double(base_data) }
@@ -208,6 +208,24 @@ describe Gitlab::GithubImport::PullRequestFormatter, lib: true do
end
end
+ context 'when importing a GitHub project' do
+ it_behaves_like 'Gitlab::GithubImport::PullRequestFormatter#attributes'
+ it_behaves_like 'Gitlab::GithubImport::PullRequestFormatter#number'
+ it_behaves_like 'Gitlab::GithubImport::PullRequestFormatter#source_branch_name'
+ it_behaves_like 'Gitlab::GithubImport::PullRequestFormatter#target_branch_name'
+ end
+
+ context 'when importing a Gitea project' do
+ before do
+ project.update(import_type: 'gitea')
+ end
+
+ it_behaves_like 'Gitlab::GithubImport::PullRequestFormatter#attributes'
+ it_behaves_like 'Gitlab::GithubImport::PullRequestFormatter#number'
+ it_behaves_like 'Gitlab::GithubImport::PullRequestFormatter#source_branch_name'
+ it_behaves_like 'Gitlab::GithubImport::PullRequestFormatter#target_branch_name'
+ end
+
describe '#valid?' do
context 'when source, and target repos are not a fork' do
let(:raw_data) { double(base_data) }
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml
index 9b49d6837c3..f420d71dee2 100644
--- a/spec/lib/gitlab/import_export/all_models.yml
+++ b/spec/lib/gitlab/import_export/all_models.yml
@@ -129,6 +129,7 @@ project:
- builds_email_service
- pipelines_email_service
- mattermost_slash_commands_service
+- slack_slash_commands_service
- irker_service
- pivotaltracker_service
- hipchat_service
@@ -136,8 +137,8 @@ project:
- assembla_service
- asana_service
- gemnasium_service
-- slack_notification_service
-- mattermost_notification_service
+- slack_service
+- mattermost_service
- buildkite_service
- bamboo_service
- teamcity_service
diff --git a/spec/lib/gitlab/import_export/project.json b/spec/lib/gitlab/import_export/project.json
index 931d426c87f..2c0750c3377 100644
--- a/spec/lib/gitlab/import_export/project.json
+++ b/spec/lib/gitlab/import_export/project.json
@@ -15,6 +15,28 @@
"type": "ProjectLabel",
"priorities": [
]
+ },
+ {
+ "id": 3,
+ "title": "test3",
+ "color": "#428bca",
+ "group_id": 8,
+ "created_at": "2016-07-22T08:55:44.161Z",
+ "updated_at": "2016-07-22T08:55:44.161Z",
+ "template": false,
+ "description": "",
+ "project_id": null,
+ "type": "GroupLabel",
+ "priorities": [
+ {
+ "id": 1,
+ "project_id": 5,
+ "label_id": 1,
+ "priority": 1,
+ "created_at": "2016-10-18T09:35:43.338Z",
+ "updated_at": "2016-10-18T09:35:43.338Z"
+ }
+ ]
}
],
"issues": [
diff --git a/spec/lib/gitlab/import_sources_spec.rb b/spec/lib/gitlab/import_sources_spec.rb
new file mode 100644
index 00000000000..8cea38e9ff8
--- /dev/null
+++ b/spec/lib/gitlab/import_sources_spec.rb
@@ -0,0 +1,94 @@
+require 'spec_helper'
+
+describe Gitlab::ImportSources do
+ describe '.options' do
+ it 'returns a hash' do
+ expected =
+ {
+ 'GitHub' => 'github',
+ 'Bitbucket' => 'bitbucket',
+ 'GitLab.com' => 'gitlab',
+ 'Google Code' => 'google_code',
+ 'FogBugz' => 'fogbugz',
+ 'Repo by URL' => 'git',
+ 'GitLab export' => 'gitlab_project',
+ 'Gitea' => 'gitea'
+ }
+
+ expect(described_class.options).to eq(expected)
+ end
+ end
+
+ describe '.values' do
+ it 'returns an array' do
+ expected =
+ [
+ 'github',
+ 'bitbucket',
+ 'gitlab',
+ 'google_code',
+ 'fogbugz',
+ 'git',
+ 'gitlab_project',
+ 'gitea'
+ ]
+
+ expect(described_class.values).to eq(expected)
+ end
+ end
+
+ describe '.importer_names' do
+ it 'returns an array of importer names' do
+ expected =
+ [
+ 'github',
+ 'bitbucket',
+ 'gitlab',
+ 'google_code',
+ 'fogbugz',
+ 'gitlab_project',
+ 'gitea'
+ ]
+
+ expect(described_class.importer_names).to eq(expected)
+ end
+ end
+
+ describe '.importer' do
+ import_sources = {
+ 'github' => Gitlab::GithubImport::Importer,
+ 'bitbucket' => Gitlab::BitbucketImport::Importer,
+ 'gitlab' => Gitlab::GitlabImport::Importer,
+ 'google_code' => Gitlab::GoogleCodeImport::Importer,
+ 'fogbugz' => Gitlab::FogbugzImport::Importer,
+ 'git' => nil,
+ 'gitlab_project' => Gitlab::ImportExport::Importer,
+ 'gitea' => Gitlab::GithubImport::Importer
+ }
+
+ import_sources.each do |name, klass|
+ it "returns #{klass} when given #{name}" do
+ expect(described_class.importer(name)).to eq(klass)
+ end
+ end
+ end
+
+ describe '.title' do
+ import_sources = {
+ 'github' => 'GitHub',
+ 'bitbucket' => 'Bitbucket',
+ 'gitlab' => 'GitLab.com',
+ 'google_code' => 'Google Code',
+ 'fogbugz' => 'FogBugz',
+ 'git' => 'Repo by URL',
+ 'gitlab_project' => 'GitLab export',
+ 'gitea' => 'Gitea'
+ }
+
+ import_sources.each do |name, title|
+ it "returns #{title} when given #{name}" do
+ expect(described_class.title(name)).to eq(title)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/kubernetes_spec.rb b/spec/lib/gitlab/kubernetes_spec.rb
new file mode 100644
index 00000000000..c9bd52a3b8f
--- /dev/null
+++ b/spec/lib/gitlab/kubernetes_spec.rb
@@ -0,0 +1,39 @@
+require 'spec_helper'
+
+describe Gitlab::Kubernetes do
+ include described_class
+
+ describe '#container_exec_url' do
+ let(:api_url) { 'https://example.com' }
+ let(:namespace) { 'default' }
+ let(:pod_name) { 'pod1' }
+ let(:container_name) { 'container1' }
+
+ subject(:result) { URI::parse(container_exec_url(api_url, namespace, pod_name, container_name)) }
+
+ it { expect(result.scheme).to eq('wss') }
+ it { expect(result.host).to eq('example.com') }
+ it { expect(result.path).to eq('/api/v1/namespaces/default/pods/pod1/exec') }
+ it { expect(result.query).to eq('container=container1&stderr=true&stdin=true&stdout=true&tty=true&command=sh&command=-c&command=bash+%7C%7C+sh') }
+
+ context 'with a HTTP API URL' do
+ let(:api_url) { 'http://example.com' }
+
+ it { expect(result.scheme).to eq('ws') }
+ end
+
+ context 'with a path prefix in the API URL' do
+ let(:api_url) { 'https://example.com/prefix/' }
+ it { expect(result.path).to eq('/prefix/api/v1/namespaces/default/pods/pod1/exec') }
+ end
+
+ context 'with arguments that need urlencoding' do
+ let(:namespace) { 'default namespace' }
+ let(:pod_name) { 'pod 1' }
+ let(:container_name) { 'container 1' }
+
+ it { expect(result.path).to eq('/api/v1/namespaces/default%20namespace/pods/pod%201/exec') }
+ it { expect(result.query).to match(/\Acontainer=container\+1&/) }
+ end
+ end
+end
diff --git a/spec/lib/gitlab/metrics/rack_middleware_spec.rb b/spec/lib/gitlab/metrics/rack_middleware_spec.rb
index bcaffd27909..7371b578a48 100644
--- a/spec/lib/gitlab/metrics/rack_middleware_spec.rb
+++ b/spec/lib/gitlab/metrics/rack_middleware_spec.rb
@@ -33,7 +33,7 @@ describe Gitlab::Metrics::RackMiddleware do
end
it 'tags a transaction with the method and path of the route in the grape endpoint' do
- route = double(:route, route_method: "GET", route_path: "/:version/projects/:id/archive(.:format)")
+ route = double(:route, request_method: "GET", path: "/:version/projects/:id/archive(.:format)")
endpoint = double(:endpoint, route: route)
env['api.endpoint'] = endpoint
@@ -117,7 +117,7 @@ describe Gitlab::Metrics::RackMiddleware do
let(:transaction) { middleware.transaction_from_env(env) }
it 'tags a transaction with the method and path of the route in the grape endpount' do
- route = double(:route, route_method: "GET", route_path: "/:version/projects/:id/archive(.:format)")
+ route = double(:route, request_method: "GET", path: "/:version/projects/:id/archive(.:format)")
endpoint = double(:endpoint, route: route)
env['api.endpoint'] = endpoint
diff --git a/spec/lib/gitlab/middleware/multipart_spec.rb b/spec/lib/gitlab/middleware/multipart_spec.rb
index ab1ab22795c..8d925460f01 100644
--- a/spec/lib/gitlab/middleware/multipart_spec.rb
+++ b/spec/lib/gitlab/middleware/multipart_spec.rb
@@ -12,7 +12,7 @@ describe Gitlab::Middleware::Multipart do
expect(app).to receive(:call) do |env|
file = Rack::Request.new(env).params['file']
- expect(file).to be_a(File)
+ expect(file).to be_a(::UploadedFile)
expect(file.path).to eq(tempfile.path)
end
@@ -39,7 +39,7 @@ describe Gitlab::Middleware::Multipart do
expect(app).to receive(:call) do |env|
file = Rack::Request.new(env).params['user']['avatar']
- expect(file).to be_a(File)
+ expect(file).to be_a(::UploadedFile)
expect(file.path).to eq(tempfile.path)
end
@@ -54,7 +54,7 @@ describe Gitlab::Middleware::Multipart do
expect(app).to receive(:call) do |env|
file = Rack::Request.new(env).params['project']['milestone']['themesong']
- expect(file).to be_a(File)
+ expect(file).to be_a(::UploadedFile)
expect(file.path).to eq(tempfile.path)
end
diff --git a/spec/lib/gitlab/workhorse_spec.rb b/spec/lib/gitlab/workhorse_spec.rb
index b5b685da904..61da91dcbd3 100644
--- a/spec/lib/gitlab/workhorse_spec.rb
+++ b/spec/lib/gitlab/workhorse_spec.rb
@@ -37,6 +37,42 @@ describe Gitlab::Workhorse, lib: true do
end
end
+ describe '.terminal_websocket' do
+ def terminal(ca_pem: nil)
+ out = {
+ subprotocols: ['foo'],
+ url: 'wss://example.com/terminal.ws',
+ headers: { 'Authorization' => ['Token x'] }
+ }
+ out[:ca_pem] = ca_pem if ca_pem
+ out
+ end
+
+ def workhorse(ca_pem: nil)
+ out = {
+ 'Terminal' => {
+ 'Subprotocols' => ['foo'],
+ 'Url' => 'wss://example.com/terminal.ws',
+ 'Header' => { 'Authorization' => ['Token x'] }
+ }
+ }
+ out['Terminal']['CAPem'] = ca_pem if ca_pem
+ out
+ end
+
+ context 'without ca_pem' do
+ subject { Gitlab::Workhorse.terminal_websocket(terminal) }
+
+ it { is_expected.to eq(workhorse) }
+ end
+
+ context 'with ca_pem' do
+ subject { Gitlab::Workhorse.terminal_websocket(terminal(ca_pem: "foo")) }
+
+ it { is_expected.to eq(workhorse(ca_pem: "foo")) }
+ end
+ end
+
describe '.send_git_diff' do
let(:diff_refs) { double(base_sha: "base", head_sha: "head") }
subject { described_class.send_git_patch(repository, diff_refs) }
diff --git a/spec/lib/mattermost/client_spec.rb b/spec/lib/mattermost/client_spec.rb
new file mode 100644
index 00000000000..dc11a414717
--- /dev/null
+++ b/spec/lib/mattermost/client_spec.rb
@@ -0,0 +1,24 @@
+require 'spec_helper'
+
+describe Mattermost::Client do
+ let(:user) { build(:user) }
+
+ subject { described_class.new(user) }
+
+ context 'JSON parse error' do
+ before do
+ Struct.new("Request", :body, :success?)
+ end
+
+ it 'yields an error on malformed JSON' do
+ bad_json = Struct::Request.new("I'm not json", true)
+ expect { subject.send(:json_response, bad_json) }.to raise_error(Mattermost::ClientError)
+ end
+
+ it 'shows a client error if the request was unsuccessful' do
+ bad_request = Struct::Request.new("true", false)
+
+ expect { subject.send(:json_response, bad_request) }.to raise_error(Mattermost::ClientError)
+ end
+ end
+end
diff --git a/spec/lib/mattermost/command_spec.rb b/spec/lib/mattermost/command_spec.rb
new file mode 100644
index 00000000000..5ccf1100898
--- /dev/null
+++ b/spec/lib/mattermost/command_spec.rb
@@ -0,0 +1,61 @@
+require 'spec_helper'
+
+describe Mattermost::Command do
+ let(:params) { { 'token' => 'token', team_id: 'abc' } }
+
+ before do
+ Mattermost::Session.base_uri('http://mattermost.example.com')
+
+ allow_any_instance_of(Mattermost::Client).to receive(:with_session).
+ and_yield(Mattermost::Session.new(nil))
+ end
+
+ describe '#create' do
+ let(:params) do
+ { team_id: 'abc',
+ trigger: 'gitlab'
+ }
+ end
+
+ subject { described_class.new(nil).create(params) }
+
+ context 'for valid trigger word' do
+ before do
+ stub_request(:post, 'http://mattermost.example.com/api/v3/teams/abc/commands/create').
+ with(body: {
+ team_id: 'abc',
+ trigger: 'gitlab' }.to_json).
+ to_return(
+ status: 200,
+ headers: { 'Content-Type' => 'application/json' },
+ body: { token: 'token' }.to_json
+ )
+ end
+
+ it 'returns a token' do
+ is_expected.to eq('token')
+ end
+ end
+
+ context 'for error message' do
+ before do
+ stub_request(:post, 'http://mattermost.example.com/api/v3/teams/abc/commands/create').
+ to_return(
+ status: 500,
+ headers: { 'Content-Type' => 'application/json' },
+ body: {
+ id: 'api.command.duplicate_trigger.app_error',
+ message: 'This trigger word is already in use. Please choose another word.',
+ detailed_error: '',
+ request_id: 'obc374man7bx5r3dbc1q5qhf3r',
+ status_code: 500
+ }.to_json
+ )
+ end
+
+ it 'raises an error with message' do
+ expect { subject }.to raise_error(Mattermost::Error, 'This trigger word is already in use. Please choose another word.')
+ end
+ end
+ end
+end
diff --git a/spec/lib/mattermost/session_spec.rb b/spec/lib/mattermost/session_spec.rb
index 3c2eddbd221..74d12e37181 100644
--- a/spec/lib/mattermost/session_spec.rb
+++ b/spec/lib/mattermost/session_spec.rb
@@ -95,5 +95,29 @@ describe Mattermost::Session, type: :request do
end
end
end
+
+ context 'with lease' do
+ before do
+ allow(subject).to receive(:lease_try_obtain).and_return('aldkfjsldfk')
+ end
+
+ it 'tries to obtain a lease' do
+ expect(subject).to receive(:lease_try_obtain)
+ expect(Gitlab::ExclusiveLease).to receive(:cancel)
+
+ # Cannot setup a session, but we should still cancel the lease
+ expect { subject.with_session }.to raise_error(Mattermost::NoSessionError)
+ end
+ end
+
+ context 'without lease' do
+ before do
+ allow(subject).to receive(:lease_try_obtain).and_return(nil)
+ end
+
+ it 'returns a NoSessionError error' do
+ expect { subject.with_session }.to raise_error(Mattermost::NoSessionError)
+ end
+ end
end
end
diff --git a/spec/lib/mattermost/team_spec.rb b/spec/lib/mattermost/team_spec.rb
new file mode 100644
index 00000000000..2d14be6bcc2
--- /dev/null
+++ b/spec/lib/mattermost/team_spec.rb
@@ -0,0 +1,66 @@
+require 'spec_helper'
+
+describe Mattermost::Team do
+ before do
+ Mattermost::Session.base_uri('http://mattermost.example.com')
+
+ allow_any_instance_of(Mattermost::Client).to receive(:with_session).
+ and_yield(Mattermost::Session.new(nil))
+ end
+
+ describe '#all' do
+ subject { described_class.new(nil).all }
+
+ context 'for valid request' do
+ let(:response) do
+ [{
+ "id" => "xiyro8huptfhdndadpz8r3wnbo",
+ "create_at" => 1482174222155,
+ "update_at" => 1482174222155,
+ "delete_at" => 0,
+ "display_name" => "chatops",
+ "name" => "chatops",
+ "email" => "admin@example.com",
+ "type" => "O",
+ "company_name" => "",
+ "allowed_domains" => "",
+ "invite_id" => "o4utakb9jtb7imctdfzbf9r5ro",
+ "allow_open_invite" => false }]
+ end
+
+ before do
+ stub_request(:get, 'http://mattermost.example.com/api/v3/teams/all').
+ to_return(
+ status: 200,
+ headers: { 'Content-Type' => 'application/json' },
+ body: response.to_json
+ )
+ end
+
+ it 'returns a token' do
+ is_expected.to eq(response)
+ end
+ end
+
+ context 'for error message' do
+ before do
+ stub_request(:get, 'http://mattermost.example.com/api/v3/teams/all').
+ to_return(
+ status: 500,
+ headers: { 'Content-Type' => 'application/json' },
+ body: {
+ id: 'api.team.list.app_error',
+ message: 'Cannot list teams.',
+ detailed_error: '',
+ request_id: 'obc374man7bx5r3dbc1q5qhf3r',
+ status_code: 500
+ }.to_json
+ )
+ end
+
+ it 'raises an error with message' do
+ expect { subject }.to raise_error(Mattermost::Error, 'Cannot list teams.')
+ end
+ end
+ end
+end