diff options
author | Kamil Trzciński <ayufan@ayufan.eu> | 2018-12-01 14:39:13 +0300 |
---|---|---|
committer | Kamil Trzciński <ayufan@ayufan.eu> | 2019-01-07 11:38:05 +0300 |
commit | c4d615c9dcba6815d0e9d1b7b7de5b7528ac7c72 (patch) | |
tree | d5358e8d4dad18f7b92b2dea54b1b1b768e37313 /spec/lib/gitlab/ci/config | |
parent | b97b85c37e77e5d37705cb2d3a60161896585420 (diff) |
Allow to include files from another projects
This adds `project:, file:, ref:` specification support.
Diffstat (limited to 'spec/lib/gitlab/ci/config')
6 files changed, 162 insertions, 5 deletions
diff --git a/spec/lib/gitlab/ci/config/external/file/base_spec.rb b/spec/lib/gitlab/ci/config/external/file/base_spec.rb index ada8775c489..1a6b3587599 100644 --- a/spec/lib/gitlab/ci/config/external/file/base_spec.rb +++ b/spec/lib/gitlab/ci/config/external/file/base_spec.rb @@ -3,7 +3,7 @@ require 'fast_spec_helper' describe Gitlab::Ci::Config::External::File::Base do - let(:context) { described_class::Context.new(nil, 'HEAD') } + let(:context) { described_class::Context.new(nil, 'HEAD', nil) } let(:test_class) do Class.new(described_class) do diff --git a/spec/lib/gitlab/ci/config/external/file/local_spec.rb b/spec/lib/gitlab/ci/config/external/file/local_spec.rb index 83be43e240b..ff67a765da0 100644 --- a/spec/lib/gitlab/ci/config/external/file/local_spec.rb +++ b/spec/lib/gitlab/ci/config/external/file/local_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' describe Gitlab::Ci::Config::External::File::Local do set(:project) { create(:project, :repository) } - let(:context) { described_class::Context.new(project, '12345') } + let(:context) { described_class::Context.new(project, '12345', nil) } let(:params) { { local: location } } let(:local_file) { described_class.new(params, context) } diff --git a/spec/lib/gitlab/ci/config/external/file/project_spec.rb b/spec/lib/gitlab/ci/config/external/file/project_spec.rb new file mode 100644 index 00000000000..11809adcaf6 --- /dev/null +++ b/spec/lib/gitlab/ci/config/external/file/project_spec.rb @@ -0,0 +1,151 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Ci::Config::External::File::Project do + set(:project) { create(:project, :repository) } + set(:user) { create(:user) } + + let(:context_user) { user } + let(:context) { described_class::Context.new(nil, '12345', context_user) } + let(:subject) { described_class.new(params, context) } + + before do + project.add_developer(user) + end + + describe '#matching?' do + context 'when a file and project is specified' do + let(:params) { { file: 'file.yml', project: 'project' } } + + it 'should return true' do + expect(subject).to be_matching + end + end + + context 'with only file is specified' do + let(:params) { { file: 'file.yml' } } + + it 'should return false' do + expect(subject).not_to be_matching + end + end + + context 'with only project is specified' do + let(:params) { { project: 'project' } } + + it 'should return false' do + expect(subject).not_to be_matching + end + end + + context 'with a missing local key' do + let(:params) { {} } + + it 'should return false' do + expect(subject).not_to be_matching + end + end + end + + describe '#valid?' do + context 'when a valid path is used' do + let(:params) do + { project: project.full_path, file: '/file.yml' } + end + + let(:root_ref_sha) { project.repository.root_ref_sha } + + before do + stub_project_blob(root_ref_sha, '/file.yml') { 'image: ruby:2.1' } + end + + it 'should return true' do + expect(subject).to be_valid + end + + context 'when user does not have permission to access file' do + let(:context_user) { create(:user) } + + it 'should return false' do + expect(subject).not_to be_valid + expect(subject.error_message).to include("Project `#{project.full_path}` not found or access denied!") + end + end + end + + context 'when a valid path with custom ref is used' do + let(:params) do + { project: project.full_path, ref: 'master', file: '/file.yml' } + end + + let(:ref_sha) { project.commit('master').sha } + + before do + stub_project_blob(ref_sha, '/file.yml') { 'image: ruby:2.1' } + end + + it 'should return true' do + expect(subject).to be_valid + end + end + + context 'when an empty file is used' do + let(:params) do + { project: project.full_path, file: '/file.yml' } + end + + let(:root_ref_sha) { project.repository.root_ref_sha } + + before do + stub_project_blob(root_ref_sha, '/file.yml') { '' } + end + + it 'should return false' do + expect(subject).not_to be_valid + expect(subject.error_message).to include("Project `#{project.full_path}` file `/file.yml` is empty!") + end + end + + context 'when non-existing ref is used' do + let(:params) do + { project: project.full_path, ref: 'I-Do-Not-Exist', file: '/file.yml' } + end + + it 'should return false' do + expect(subject).not_to be_valid + expect(subject.error_message).to include("Project `#{project.full_path}` reference `I-Do-Not-Exist` does not exist!") + end + end + + context 'when non-existing file is requested' do + let(:params) do + { project: project.full_path, file: '/invalid-file.yml' } + end + + it 'should return false' do + expect(subject).not_to be_valid + expect(subject.error_message).to include("Project `#{project.full_path}` file `/invalid-file.yml` does not exist!") + end + end + + context 'when file is not a yaml file' do + let(:params) do + { project: project.full_path, file: '/invalid-file' } + end + + it 'should return false' do + expect(subject).not_to be_valid + expect(subject.error_message).to include('Included file `/invalid-file` does not have YAML extension!') + end + end + end + + private + + def stub_project_blob(ref, path) + allow_any_instance_of(Repository) + .to receive(:blob_data_at) + .with(ref, path) { yield } + end +end diff --git a/spec/lib/gitlab/ci/config/external/file/remote_spec.rb b/spec/lib/gitlab/ci/config/external/file/remote_spec.rb index 319e7137f9f..3e0fda9c308 100644 --- a/spec/lib/gitlab/ci/config/external/file/remote_spec.rb +++ b/spec/lib/gitlab/ci/config/external/file/remote_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe Gitlab::Ci::Config::External::File::Remote do - let(:context) { described_class::Context.new(nil, '12345') } + let(:context) { described_class::Context.new(nil, '12345', nil) } let(:params) { { remote: location } } let(:remote_file) { described_class.new(params, context) } let(:location) { 'https://gitlab.com/gitlab-org/gitlab-ce/blob/1234/.gitlab-ci-1.yml' } diff --git a/spec/lib/gitlab/ci/config/external/mapper_spec.rb b/spec/lib/gitlab/ci/config/external/mapper_spec.rb index e27d2cd9422..4cab4961b0f 100644 --- a/spec/lib/gitlab/ci/config/external/mapper_spec.rb +++ b/spec/lib/gitlab/ci/config/external/mapper_spec.rb @@ -4,6 +4,7 @@ require 'spec_helper' describe Gitlab::Ci::Config::External::Mapper do set(:project) { create(:project, :repository) } + set(:user) { create(:user) } let(:local_file) { '/lib/gitlab/ci/templates/non-existent-file.yml' } let(:remote_url) { 'https://gitlab.com/gitlab-org/gitlab-ce/blob/1234/.gitlab-ci-1.yml' } @@ -20,7 +21,7 @@ describe Gitlab::Ci::Config::External::Mapper do end describe '#process' do - subject { described_class.new(values, project: project, sha: '123456').process } + subject { described_class.new(values, project: project, sha: '123456', user: user).process } context "when single 'include' keyword is defined" do context 'when the string is a local file' do diff --git a/spec/lib/gitlab/ci/config/external/processor_spec.rb b/spec/lib/gitlab/ci/config/external/processor_spec.rb index d2d4fbc5115..1ac58139b25 100644 --- a/spec/lib/gitlab/ci/config/external/processor_spec.rb +++ b/spec/lib/gitlab/ci/config/external/processor_spec.rb @@ -4,8 +4,13 @@ require 'spec_helper' describe Gitlab::Ci::Config::External::Processor do set(:project) { create(:project, :repository) } + set(:user) { create(:user) } - let(:processor) { described_class.new(values, project: project, sha: '12345') } + let(:processor) { described_class.new(values, project: project, sha: '12345', user: user) } + + before do + project.add_developer(user) + end describe "#perform" do context 'when no external files defined' do |