236 lines
8.3 KiB
Ruby
236 lines
8.3 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'spec_helper'
|
|
|
|
RSpec.describe Gitlab::Ci::Components::InstancePath, feature_category: :pipeline_composition do
|
|
let_it_be(:user) { create(:user) }
|
|
|
|
let(:path) { described_class.new(address: address) }
|
|
let(:settings) { GitlabSettings::Options.build({ 'component_fqdn' => current_host }) }
|
|
let(:current_host) { 'acme.com/' }
|
|
|
|
before do
|
|
allow(::Settings).to receive(:gitlab_ci).and_return(settings)
|
|
end
|
|
|
|
describe 'FQDN path' do
|
|
let(:version) { 'master' }
|
|
let(:project_path) { project.full_path }
|
|
let(:address) { "acme.com/#{project_path}/secret-detection@#{version}" }
|
|
|
|
context 'when the project repository contains a templates directory' do
|
|
let_it_be(:project) do
|
|
create(
|
|
:project, :custom_repo,
|
|
files: {
|
|
'templates/secret-detection.yml' => 'image: alpine_1',
|
|
'templates/dast/template.yml' => 'image: alpine_2',
|
|
'templates/dast/another-template.yml' => 'image: alpine_3',
|
|
'templates/dast/another-folder/template.yml' => 'image: alpine_4'
|
|
}
|
|
)
|
|
end
|
|
|
|
before do
|
|
project.add_developer(user)
|
|
end
|
|
|
|
context 'when user does not have permissions' do
|
|
it 'raises an error when fetching the content' do
|
|
expect { path.fetch_content!(current_user: build(:user)) }
|
|
.to raise_error(Gitlab::Access::AccessDeniedError)
|
|
end
|
|
end
|
|
|
|
context 'when the component is simple (single file template)' do
|
|
it 'fetches the component content', :aggregate_failures do
|
|
result = path.fetch_content!(current_user: user)
|
|
expect(result.content).to eq('image: alpine_1')
|
|
expect(result.path).to eq('templates/secret-detection.yml')
|
|
expect(path.host).to eq(current_host)
|
|
expect(path.project).to eq(project)
|
|
expect(path.sha).to eq(project.commit('master').id)
|
|
end
|
|
end
|
|
|
|
context 'when the component is complex (directory-based template)' do
|
|
let(:address) { "acme.com/#{project_path}/dast@#{version}" }
|
|
|
|
it 'fetches the component content', :aggregate_failures do
|
|
result = path.fetch_content!(current_user: user)
|
|
expect(result.content).to eq('image: alpine_2')
|
|
expect(result.path).to eq('templates/dast/template.yml')
|
|
expect(path.host).to eq(current_host)
|
|
expect(path.project).to eq(project)
|
|
expect(path.sha).to eq(project.commit('master').id)
|
|
end
|
|
|
|
context 'when there is an invalid nested component folder' do
|
|
let(:address) { "acme.com/#{project_path}/dast/another-folder@#{version}" }
|
|
|
|
it 'returns nil' do
|
|
result = path.fetch_content!(current_user: user)
|
|
expect(result.content).to be_nil
|
|
end
|
|
end
|
|
|
|
context 'when there is an invalid nested component path' do
|
|
let(:address) { "acme.com/#{project_path}/dast/another-template@#{version}" }
|
|
|
|
it 'returns nil' do
|
|
result = path.fetch_content!(current_user: user)
|
|
expect(result.content).to be_nil
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'when fetching the latest version of a component' do
|
|
let_it_be(:project) do
|
|
create(
|
|
:project, :custom_repo,
|
|
files: {
|
|
'templates/secret-detection.yml' => 'image: alpine_1'
|
|
}
|
|
)
|
|
end
|
|
|
|
let(:version) { '~latest' }
|
|
|
|
let(:latest_sha) do
|
|
project.repository.commit('master').id
|
|
end
|
|
|
|
before do
|
|
create(:release, project: project, sha: project.repository.root_ref_sha,
|
|
released_at: Time.zone.now - 1.day)
|
|
|
|
project.repository.update_file(
|
|
user, 'templates/secret-detection.yml', 'image: alpine_2',
|
|
message: 'Updates image', branch_name: project.default_branch
|
|
)
|
|
|
|
create(:release, project: project, sha: latest_sha,
|
|
released_at: Time.zone.now)
|
|
end
|
|
|
|
it 'fetches the component content', :aggregate_failures do
|
|
result = path.fetch_content!(current_user: user)
|
|
expect(result.content).to eq('image: alpine_2')
|
|
expect(result.path).to eq('templates/secret-detection.yml')
|
|
expect(path.host).to eq(current_host)
|
|
expect(path.project).to eq(project)
|
|
expect(path.sha).to eq(latest_sha)
|
|
end
|
|
end
|
|
|
|
context 'when version does not exist' do
|
|
let(:version) { 'non-existent' }
|
|
|
|
it 'returns nil', :aggregate_failures do
|
|
expect(path.fetch_content!(current_user: user)).to be_nil
|
|
expect(path.host).to eq(current_host)
|
|
expect(path.project).to eq(project)
|
|
expect(path.sha).to be_nil
|
|
end
|
|
end
|
|
|
|
context 'when current GitLab instance is installed on a relative URL' do
|
|
let(:address) { "acme.com/gitlab/#{project_path}/secret-detection@#{version}" }
|
|
let(:current_host) { 'acme.com/gitlab/' }
|
|
|
|
it 'fetches the component content', :aggregate_failures do
|
|
result = path.fetch_content!(current_user: user)
|
|
expect(result.content).to eq('image: alpine_1')
|
|
expect(result.path).to eq('templates/secret-detection.yml')
|
|
expect(path.host).to eq(current_host)
|
|
expect(path.project).to eq(project)
|
|
expect(path.sha).to eq(project.commit('master').id)
|
|
end
|
|
end
|
|
end
|
|
|
|
# All the following tests are for deprecated code and will be removed
|
|
# in https://gitlab.com/gitlab-org/gitlab/-/issues/415855
|
|
context 'when the project does not contain a templates directory' do
|
|
let(:project_path) { project.full_path }
|
|
let(:address) { "acme.com/#{project_path}/component@#{version}" }
|
|
|
|
let_it_be(:project) do
|
|
create(
|
|
:project, :custom_repo,
|
|
files: {
|
|
'component/template.yml' => 'image: alpine'
|
|
}
|
|
)
|
|
end
|
|
|
|
before do
|
|
project.add_developer(user)
|
|
end
|
|
|
|
it 'fetches the component content', :aggregate_failures do
|
|
result = path.fetch_content!(current_user: user)
|
|
expect(result.content).to eq('image: alpine')
|
|
expect(result.path).to eq('component/template.yml')
|
|
expect(path.host).to eq(current_host)
|
|
expect(path.project).to eq(project)
|
|
expect(path.sha).to eq(project.commit('master').id)
|
|
end
|
|
|
|
context 'when project path is nested under a subgroup' do
|
|
let_it_be(:group) { create(:group, :nested) }
|
|
let_it_be(:project) do
|
|
create(
|
|
:project, :custom_repo,
|
|
files: {
|
|
'component/template.yml' => 'image: alpine'
|
|
},
|
|
group: group
|
|
)
|
|
end
|
|
|
|
it 'fetches the component content', :aggregate_failures do
|
|
result = path.fetch_content!(current_user: user)
|
|
expect(result.content).to eq('image: alpine')
|
|
expect(result.path).to eq('component/template.yml')
|
|
expect(path.host).to eq(current_host)
|
|
expect(path.project).to eq(project)
|
|
expect(path.sha).to eq(project.commit('master').id)
|
|
end
|
|
end
|
|
|
|
context 'when current GitLab instance is installed on a relative URL' do
|
|
let(:address) { "acme.com/gitlab/#{project_path}/component@#{version}" }
|
|
let(:current_host) { 'acme.com/gitlab/' }
|
|
|
|
it 'fetches the component content', :aggregate_failures do
|
|
result = path.fetch_content!(current_user: user)
|
|
expect(result.content).to eq('image: alpine')
|
|
expect(result.path).to eq('component/template.yml')
|
|
expect(path.host).to eq(current_host)
|
|
expect(path.project).to eq(project)
|
|
expect(path.sha).to eq(project.commit('master').id)
|
|
end
|
|
end
|
|
|
|
context 'when version does not exist' do
|
|
let(:version) { 'non-existent' }
|
|
|
|
it 'returns nil', :aggregate_failures do
|
|
expect(path.fetch_content!(current_user: user)).to be_nil
|
|
expect(path.host).to eq(current_host)
|
|
expect(path.project).to eq(project)
|
|
expect(path.sha).to be_nil
|
|
end
|
|
end
|
|
|
|
context 'when user does not have permissions' do
|
|
it 'raises an error when fetching the content' do
|
|
expect { path.fetch_content!(current_user: build(:user)) }
|
|
.to raise_error(Gitlab::Access::AccessDeniedError)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|