summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/models/ci/pipeline.rb2
-rw-r--r--app/models/project.rb6
-rw-r--r--app/models/repository.rb4
-rw-r--r--lib/gitlab/route_map.rb2
-rw-r--r--spec/features/projects/blobs/view_on_env_spec.rb7
-rw-r--r--spec/features/projects/commit/cherry_pick_spec.rb (renamed from spec/features/projects/commits/cherry_pick_spec.rb)0
-rw-r--r--spec/features/projects/commit/view_on_env_spec.rb9
-rw-r--r--spec/features/projects/compare/view_on_env_spec.rb9
-rw-r--r--spec/features/projects/compare_spec.rb (renamed from spec/features/compare_spec.rb)0
-rw-r--r--spec/features/projects/merge_requests/view_on_env_spec.rb9
-rw-r--r--spec/helpers/commits_helper_spec.rb19
-rw-r--r--spec/lib/gitlab/route_map_spec.rb89
-rw-r--r--spec/models/environment_spec.rb48
-rw-r--r--spec/models/merge_request_spec.rb24
-rw-r--r--spec/models/project_spec.rb123
-rw-r--r--spec/models/repository_spec.rb36
16 files changed, 381 insertions, 6 deletions
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index 8db53ea56dd..70bb4a224a1 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -283,7 +283,7 @@ module Ci
def ci_yaml_file
return @ci_yaml_file if defined?(@ci_yaml_file)
- @ci_yaml_file ||= project.repository.ci_yaml_file(sha)
+ @ci_yaml_file ||= project.repository.gitlab_ci_yml_for(sha)
end
def has_yaml_errors?
diff --git a/app/models/project.rb b/app/models/project.rb
index 42a79557136..15c6e25e73f 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -1342,10 +1342,10 @@ class Project < ActiveRecord::Base
end
end
- def route_map_for_commit(commit_sha)
+ def route_map_for(commit_sha)
@route_maps_by_commit ||= Hash.new do |h, sha|
h[sha] = begin
- data = repository.route_map_file(sha)
+ data = repository.route_map_for(sha)
next unless data
Gitlab::RouteMap.new(data)
@@ -1358,7 +1358,7 @@ class Project < ActiveRecord::Base
end
def public_path_for_source_path(path, commit_sha)
- map = route_map_for_commit(commit_sha)
+ map = route_map_for(commit_sha)
return unless map
map.public_path_for_source_path(path)
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 9aa0cc250f0..ba9c038b66d 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -1187,14 +1187,14 @@ class Repository
end
end
- def route_map_file(sha)
+ def route_map_for(sha)
blob = blob_at(sha, ROUTE_MAP_PATH)
return unless blob
blob.load_all_data!(self)
blob.data
end
- def ci_yaml_file(sha)
+ def gitlab_ci_yml_for(sha)
blob = blob_at(sha, GITLAB_CI_YML_PATH)
return unless blob
blob.load_all_data!(self)
diff --git a/lib/gitlab/route_map.rb b/lib/gitlab/route_map.rb
index 89985d90c10..b1a93d44a45 100644
--- a/lib/gitlab/route_map.rb
+++ b/lib/gitlab/route_map.rb
@@ -2,6 +2,8 @@ module Gitlab
class RouteMap
class FormatError < StandardError; end
+ attr_reader :map
+
def initialize(data)
begin
entries = YAML.safe_load(data)
diff --git a/spec/features/projects/blobs/view_on_env_spec.rb b/spec/features/projects/blobs/view_on_env_spec.rb
new file mode 100644
index 00000000000..360f9d66609
--- /dev/null
+++ b/spec/features/projects/blobs/view_on_env_spec.rb
@@ -0,0 +1,7 @@
+require 'spec_helper'
+
+feature 'Blob' do
+ describe 'View on environment' do
+ # TODO: Test
+ end
+end
diff --git a/spec/features/projects/commits/cherry_pick_spec.rb b/spec/features/projects/commit/cherry_pick_spec.rb
index 7baf7913424..7baf7913424 100644
--- a/spec/features/projects/commits/cherry_pick_spec.rb
+++ b/spec/features/projects/commit/cherry_pick_spec.rb
diff --git a/spec/features/projects/commit/view_on_env_spec.rb b/spec/features/projects/commit/view_on_env_spec.rb
new file mode 100644
index 00000000000..eee2814089a
--- /dev/null
+++ b/spec/features/projects/commit/view_on_env_spec.rb
@@ -0,0 +1,9 @@
+require 'spec_helper'
+
+feature 'Commit' do
+ describe 'Diff' do
+ describe 'View on environment' do
+ # TODO: Test
+ end
+ end
+end
diff --git a/spec/features/projects/compare/view_on_env_spec.rb b/spec/features/projects/compare/view_on_env_spec.rb
new file mode 100644
index 00000000000..0a4ec03b17f
--- /dev/null
+++ b/spec/features/projects/compare/view_on_env_spec.rb
@@ -0,0 +1,9 @@
+require 'spec_helper'
+
+feature 'Compare' do
+ describe 'Diff' do
+ describe 'View on environment' do
+ # TODO: Test
+ end
+ end
+end
diff --git a/spec/features/compare_spec.rb b/spec/features/projects/compare_spec.rb
index 43eb4000e58..43eb4000e58 100644
--- a/spec/features/compare_spec.rb
+++ b/spec/features/projects/compare_spec.rb
diff --git a/spec/features/projects/merge_requests/view_on_env_spec.rb b/spec/features/projects/merge_requests/view_on_env_spec.rb
new file mode 100644
index 00000000000..b25e499acd6
--- /dev/null
+++ b/spec/features/projects/merge_requests/view_on_env_spec.rb
@@ -0,0 +1,9 @@
+require 'spec_helper'
+
+feature 'Merge Request' do
+ describe 'Diff' do
+ describe 'View on environment' do
+ # TODO: Test
+ end
+ end
+end
diff --git a/spec/helpers/commits_helper_spec.rb b/spec/helpers/commits_helper_spec.rb
index 727c25ff529..85c663030d8 100644
--- a/spec/helpers/commits_helper_spec.rb
+++ b/spec/helpers/commits_helper_spec.rb
@@ -26,4 +26,23 @@ describe CommitsHelper do
not_to include('onmouseover="alert(1)"')
end
end
+
+ describe '#view_on_environment_btn' do
+ let(:project) { create(:empty_project) }
+ let(:environment) { create(:environment, external_url: 'http://example.com') }
+ let(:path) { 'source/file.html' }
+ let(:sha) { RepoHelpers.sample_commit.id }
+
+ before do
+ allow(environment).to receive(:external_url_for).with(path, sha).and_return('http://example.com/file.html')
+ end
+
+ it 'returns a link tag linking to the file in the environment' do
+ html = helper.view_on_environment_btn(sha, path, environment)
+ node = Nokogiri::HTML.parse(html).at_css('a')
+
+ expect(node[:title]).to eq('View on example.com')
+ expect(node[:href]).to eq('http://example.com/file.html')
+ end
+ end
end
diff --git a/spec/lib/gitlab/route_map_spec.rb b/spec/lib/gitlab/route_map_spec.rb
new file mode 100644
index 00000000000..d56380bec50
--- /dev/null
+++ b/spec/lib/gitlab/route_map_spec.rb
@@ -0,0 +1,89 @@
+require 'spec_helper'
+
+describe Gitlab::RouteMap, lib: true do
+ describe '#initialize' do
+ context 'when the data is not YAML' do
+ it 'raises an error' do
+ expect { described_class.new('"') }.
+ to raise_error(Gitlab::RouteMap::FormatError, /valid YAML/)
+ end
+ end
+
+ context 'when the data is not a YAML array' do
+ it 'raises an error' do
+ expect { described_class.new(YAML.dump('foo')) }.
+ to raise_error(Gitlab::RouteMap::FormatError, /an array/)
+ end
+ end
+
+ context 'when an entry is not a hash' do
+ it 'raises an error' do
+ expect { described_class.new(YAML.dump(['foo'])) }.
+ to raise_error(Gitlab::RouteMap::FormatError, /a hash/)
+ end
+ end
+
+ context 'when an entry does not have a source key' do
+ it 'raises an error' do
+ expect { described_class.new(YAML.dump([{ 'public' => 'index.html' }])) }.
+ to raise_error(Gitlab::RouteMap::FormatError, /source key/)
+ end
+ end
+
+ context 'when an entry does not have a public key' do
+ it 'raises an error' do
+ expect { described_class.new(YAML.dump([{ 'source' => '/index\.html/' }])) }.
+ to raise_error(Gitlab::RouteMap::FormatError, /public key/)
+ end
+ end
+
+ context 'when an entry source does not start and end with a slash' do
+ it 'raises an error' do
+ expect { described_class.new(YAML.dump([{ 'source' => 'index.html', 'public' => 'index.html' }])) }.
+ to raise_error(Gitlab::RouteMap::FormatError, /a slash/)
+ end
+ end
+
+ context 'when an entry source is not a valid regex' do
+ it 'raises an error' do
+ expect { described_class.new(YAML.dump([{ 'source' => '/[/', 'public' => 'index.html' }])) }.
+ to raise_error(Gitlab::RouteMap::FormatError, /regular expression/)
+ end
+ end
+
+ context 'when all is good' do
+ it 'returns a route map' do
+ route_map = described_class.new(YAML.dump([{ 'source' => '/index\.html/', 'public' => 'index.html' }]))
+ expect(route_map.map).to eq([{ source: /^index\.html$/, public: 'index.html' }])
+ end
+ end
+ end
+
+ describe '#public_path_for_source_path' do
+ subject do
+ described_class.new(<<-'MAP'.strip_heredoc)
+ # Blogposts
+ - source: /source/posts/([0-9]{4})-([0-9]{2})-([0-9]{2})-(.+?)\..*/ # source/posts/2017-01-30-around-the-world-in-6-releases.html.md.erb
+ public: '\1/\2/\3/\4/' # 2017/01/30/around-the-world-in-6-releases/
+
+ # HTML files
+ - source: /source/(.+?\.html).*/ # source/index.html.haml
+ public: '\1' # index.html
+
+ # Other files
+ - source: /source/(.*)/ # source/images/blogimages/around-the-world-in-6-releases-cover.png
+ public: '\1' # images/blogimages/around-the-world-in-6-releases-cover.png
+ MAP
+ end
+
+ it 'returns the public path for a provided source path' do
+ expect(subject.public_path_for_source_path('source/posts/2017-01-30-around-the-world-in-6-releases.html.md.erb')).to eq('2017/01/30/around-the-world-in-6-releases/')
+
+ expect(subject.public_path_for_source_path('source/index.html.haml')).to eq('index.html')
+
+ expect(subject.public_path_for_source_path('source/images/blogimages/around-the-world-in-6-releases-cover.png')).to eq('images/blogimages/around-the-world-in-6-releases-cover.png')
+
+ expect(subject.public_path_for_source_path('.gitlab/route-map.yml')).to be_nil
+ end
+ end
+end
diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb
index eba392044bf..e40a9bf4fbe 100644
--- a/spec/models/environment_spec.rb
+++ b/spec/models/environment_spec.rb
@@ -22,6 +22,25 @@ describe Environment, models: true do
it { is_expected.to validate_length_of(:external_url).is_at_most(255) }
it { is_expected.to validate_uniqueness_of(:external_url).scoped_to(:project_id) }
+ describe '.latest_for_commit' do
+ let!(:environment1) { create(:environment, project: project) }
+ let!(:environment2) { create(:environment, project: project) }
+ let!(:environment3) { create(:environment, project: project) }
+ let!(:deployment1) { create(:deployment, environment: environment1) }
+ let!(:deployment2) { create(:deployment, environment: environment2) }
+ let(:commit) { RepoHelpers.sample_commit }
+
+ before do
+ allow(environment1).to receive(:first_deployment_for).with(commit).and_return(deployment1)
+ allow(environment2).to receive(:first_deployment_for).with(commit).and_return(deployment2)
+ allow(environment3).to receive(:first_deployment_for).with(commit).and_return(nil)
+ end
+
+ it 'returns the environment that the commit was last deployed to' do
+ expect(Environment.latest_for_commit([environment1, environment2, environment3], commit)).to be(environment2)
+ end
+ end
+
describe '#nullify_external_url' do
it 'replaces a blank url with nil' do
env = build(:environment, external_url: "")
@@ -301,4 +320,33 @@ describe Environment, models: true do
end
end
end
+
+ describe '#external_url_for' do
+ let(:source_path) { 'source/file.html' }
+ let(:sha) { RepoHelpers.sample_commit.id }
+
+ before do
+ environment.external_url = 'http://example.com'
+ end
+
+ context 'when the public path is not known' do
+ before do
+ allow(project).to receive(:public_path_for_source_path).with(source_path, sha).and_return(nil)
+ end
+
+ it 'returns nil' do
+ expect(environment.external_url_for(source_path, sha)).to be_nil
+ end
+ end
+
+ context 'when the public path is known' do
+ before do
+ allow(project).to receive(:public_path_for_source_path).with(source_path, sha).and_return('file.html')
+ end
+
+ it 'returns the full external URL' do
+ expect(environment.external_url_for(source_path, sha)).to eq('http://example.com/file.html')
+ end
+ end
+ end
end
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index 32ed1e96749..91a8f2d77ab 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -1069,6 +1069,30 @@ describe MergeRequest, models: true do
end
end
+ describe '#latest_environment' do
+ let(:project) { subject.project }
+ let!(:environment1) { create(:environment, project: project) }
+ let!(:environment2) { create(:environment, project: project) }
+ let!(:environment3) { create(:environment, project: project) }
+ let!(:deployment1) { create(:deployment, environment: environment1, ref: 'master', sha: commit.id) }
+ let!(:deployment2) { create(:deployment, environment: environment2, ref: 'feature', sha: commit.id) }
+ let(:commit) { subject.diff_head_commit }
+
+ before do
+ allow(environment1).to receive(:first_deployment_for).with(commit).and_return(deployment1)
+ allow(environment2).to receive(:first_deployment_for).with(commit).and_return(deployment2)
+ allow(environment3).to receive(:first_deployment_for).with(commit).and_return(nil)
+ end
+
+ before do
+ allow(subject).to receive(:environments).and_return([environment1, environment2, environment3])
+ end
+
+ it 'returns the environment that the commit was last deployed to' do
+ expect(subject.latest_environment).to eq(environment2)
+ end
+ end
+
describe "#reload_diff" do
let(:note) { create(:diff_note_on_merge_request, project: subject.project, noteable: subject) }
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index d7e6da02261..1072b324b22 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -1766,6 +1766,53 @@ describe Project, models: true do
.to contain_exactly(environment)
end
end
+
+ context 'commit deployment' do
+ before do
+ create(:deployment, environment: environment, ref: 'master', sha: project.commit.id)
+ end
+
+ it 'returns environment' do
+ expect(project.environments_for(nil, commit: project.commit))
+ .to contain_exactly(environment)
+ end
+ end
+ end
+
+ describe '#latest_environment_for' do
+ let(:project) { create(:project) }
+ let!(:environment1) { create(:environment, project: project) }
+ let!(:environment2) { create(:environment, project: project) }
+ let!(:environment3) { create(:environment, project: project) }
+ let!(:deployment1) { create(:deployment, environment: environment1, ref: 'master', sha: commit.id) }
+ let!(:deployment2) { create(:deployment, environment: environment2, ref: 'feature', sha: commit.id) }
+ let(:commit) { project.commit }
+
+ before do
+ allow(environment1).to receive(:first_deployment_for).with(commit).and_return(deployment1)
+ allow(environment2).to receive(:first_deployment_for).with(commit).and_return(deployment2)
+ allow(environment3).to receive(:first_deployment_for).with(commit).and_return(nil)
+ end
+
+ context 'when specifying a ref' do
+ before do
+ allow(project).to receive(:environments_for).with('master', commit: commit).and_return([environment1])
+ end
+
+ it 'returns the environment that the commit was last deployed to from that ref' do
+ expect(project.latest_environment_for(commit, ref: 'master')).to eq(environment1)
+ end
+ end
+
+ context 'when not specifying a ref' do
+ before do
+ allow(project).to receive(:environments_for).with(nil, commit: commit).and_return([environment1, environment2])
+ end
+
+ it 'returns the environment that the commit was last deployed to' do
+ expect(project.latest_environment_for(commit)).to eq(environment2)
+ end
+ end
end
describe '#environments_recently_updated_on_branch' do
@@ -1858,6 +1905,82 @@ describe Project, models: true do
it { expect(Project.inside_path(path)).to eq([project1]) }
end
+ describe '#route_map_for' do
+ let(:project) { create(:project) }
+ let(:route_map) do
+ <<-MAP.strip_heredoc
+ - source: /source/(.*)/
+ public: '\\1'
+ MAP
+ end
+
+ before do
+ project.repository.commit_file(User.last, '.gitlab/route-map.yml', route_map, 'Add .gitlab/route-map.yml', 'master', false)
+ end
+
+ context 'when there is a .gitlab/route-map.yml at the commit' do
+ context 'when the route map is valid' do
+ it 'returns a route map' do
+ map = project.route_map_for(project.commit.sha)
+ expect(map).to be_a_kind_of(Gitlab::RouteMap)
+ end
+ end
+
+ context 'when the route map is invalid' do
+ let(:route_map) { 'INVALID' }
+
+ it 'returns nil' do
+ expect(project.route_map_for(project.commit.sha)).to be_nil
+ end
+ end
+ end
+
+ context 'when there is no .gitlab/route-map.yml at the commit' do
+ it 'returns nil' do
+ expect(project.route_map_for(project.commit.parent.sha)).to be_nil
+ end
+ end
+ end
+
+ describe '#public_path_for_source_path' do
+ let(:project) { create(:project) }
+ let(:route_map) do
+ Gitlab::RouteMap.new(<<-MAP.strip_heredoc)
+ - source: /source/(.*)/
+ public: '\\1'
+ MAP
+ end
+ let(:sha) { project.commit.id }
+
+ context 'when there is a route map' do
+ before do
+ allow(project).to receive(:route_map_for).with(sha).and_return(route_map)
+ end
+
+ context 'when the source path is mapped' do
+ it 'returns the public path' do
+ expect(project.public_path_for_source_path('source/file.html', sha)).to eq('file.html')
+ end
+ end
+
+ context 'when the source path is not mapped' do
+ it 'returns nil' do
+ expect(project.public_path_for_source_path('file.html', sha)).to be_nil
+ end
+ end
+ end
+
+ context 'when there is no route map' do
+ before do
+ allow(project).to receive(:route_map_for).with(sha).and_return(nil)
+ end
+
+ it 'returns nil' do
+ expect(project.public_path_for_source_path('source/file.html', sha)).to be_nil
+ end
+ end
+ end
+
def enable_lfs
allow(Gitlab.config.lfs).to receive(:enabled).and_return(true)
end
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
index 53b98ba05f8..7f97319aa2f 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -1782,4 +1782,40 @@ describe Repository, models: true do
repository.refresh_method_caches(%i(readme license))
end
end
+
+ describe '#gitlab_ci_yml_for' do
+ before do
+ repository.commit_file(User.last, '.gitlab-ci.yml', 'CONTENT', 'Add .gitlab-ci.yml', 'master', false)
+ end
+
+ context 'when there is a .gitlab-ci.yml at the commit' do
+ it 'returns the content' do
+ expect(repository.gitlab_ci_yml_for(repository.commit.sha)).to eq('CONTENT')
+ end
+ end
+
+ context 'when there is no .gitlab-ci.yml at the commit' do
+ it 'returns nil' do
+ expect(repository.gitlab_ci_yml_for(repository.commit.parent.sha)).to be_nil
+ end
+ end
+ end
+
+ describe '#route_map_for' do
+ before do
+ repository.commit_file(User.last, '.gitlab/route-map.yml', 'CONTENT', 'Add .gitlab/route-map.yml', 'master', false)
+ end
+
+ context 'when there is a .gitlab/route-map.yml at the commit' do
+ it 'returns the content' do
+ expect(repository.route_map_for(repository.commit.sha)).to eq('CONTENT')
+ end
+ end
+
+ context 'when there is no .gitlab/route-map.yml at the commit' do
+ it 'returns nil' do
+ expect(repository.route_map_for(repository.commit.parent.sha)).to be_nil
+ end
+ end
+ end
end