summaryrefslogtreecommitdiff
path: root/spec/models/project_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/models/project_spec.rb')
-rw-r--r--spec/models/project_spec.rb348
1 files changed, 144 insertions, 204 deletions
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 51278836604..af5b0939ca2 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -54,6 +54,7 @@ describe Project do
it { is_expected.to have_one(:gitlab_issue_tracker_service) }
it { is_expected.to have_one(:external_wiki_service) }
it { is_expected.to have_one(:project_feature) }
+ it { is_expected.to have_one(:project_repository) }
it { is_expected.to have_one(:statistics).class_name('ProjectStatistics') }
it { is_expected.to have_one(:import_data).class_name('ProjectImportData') }
it { is_expected.to have_one(:last_event).class_name('Event') }
@@ -109,22 +110,6 @@ describe Project do
end
end
- context 'Site Statistics' do
- context 'when creating a new project' do
- it 'tracks project in SiteStatistic' do
- expect { create(:project) }.to change { SiteStatistic.fetch.repositories_count }.by(1)
- end
- end
-
- context 'when deleting a project' do
- it 'untracks project in SiteStatistic' do
- project = create(:project)
-
- expect { project.destroy }.to change { SiteStatistic.fetch.repositories_count }.by(-1)
- end
- end
- end
-
context 'updating cd_cd_settings' do
it 'does not raise an error' do
project = create(:project)
@@ -234,76 +219,93 @@ describe Project do
end
end
- it 'does not allow an invalid URI as import_url' do
- project = build(:project, import_url: 'invalid://')
+ describe 'import_url' do
+ it 'does not allow an invalid URI as import_url' do
+ project = build(:project, import_url: 'invalid://')
- expect(project).not_to be_valid
- end
+ expect(project).not_to be_valid
+ end
- it 'does allow a SSH URI as import_url for persisted projects' do
- project = create(:project)
- project.import_url = 'ssh://test@gitlab.com/project.git'
+ it 'does allow a SSH URI as import_url for persisted projects' do
+ project = create(:project)
+ project.import_url = 'ssh://test@gitlab.com/project.git'
- expect(project).to be_valid
- end
+ expect(project).to be_valid
+ end
- it 'does not allow a SSH URI as import_url for new projects' do
- project = build(:project, import_url: 'ssh://test@gitlab.com/project.git')
+ it 'does not allow a SSH URI as import_url for new projects' do
+ project = build(:project, import_url: 'ssh://test@gitlab.com/project.git')
- expect(project).not_to be_valid
- end
+ expect(project).not_to be_valid
+ end
- it 'does allow a valid URI as import_url' do
- project = build(:project, import_url: 'http://gitlab.com/project.git')
+ it 'does allow a valid URI as import_url' do
+ project = build(:project, import_url: 'http://gitlab.com/project.git')
- expect(project).to be_valid
- end
+ expect(project).to be_valid
+ end
- it 'allows an empty URI' do
- project = build(:project, import_url: '')
+ it 'allows an empty URI' do
+ project = build(:project, import_url: '')
- expect(project).to be_valid
- end
+ expect(project).to be_valid
+ end
- it 'does not produce import data on an empty URI' do
- project = build(:project, import_url: '')
+ it 'does not produce import data on an empty URI' do
+ project = build(:project, import_url: '')
- expect(project.import_data).to be_nil
- end
+ expect(project.import_data).to be_nil
+ end
- it 'does not produce import data on an invalid URI' do
- project = build(:project, import_url: 'test://')
+ it 'does not produce import data on an invalid URI' do
+ project = build(:project, import_url: 'test://')
- expect(project.import_data).to be_nil
- end
+ expect(project.import_data).to be_nil
+ end
- it "does not allow import_url pointing to localhost" do
- project = build(:project, import_url: 'http://localhost:9000/t.git')
+ it "does not allow import_url pointing to localhost" do
+ project = build(:project, import_url: 'http://localhost:9000/t.git')
- expect(project).to be_invalid
- expect(project.errors[:import_url].first).to include('Requests to localhost are not allowed')
- end
+ expect(project).to be_invalid
+ expect(project.errors[:import_url].first).to include('Requests to localhost are not allowed')
+ end
- it "does not allow import_url with invalid ports for new projects" do
- project = build(:project, import_url: 'http://github.com:25/t.git')
+ it "does not allow import_url with invalid ports for new projects" do
+ project = build(:project, import_url: 'http://github.com:25/t.git')
- expect(project).to be_invalid
- expect(project.errors[:import_url].first).to include('Only allowed ports are 80, 443')
- end
+ expect(project).to be_invalid
+ expect(project.errors[:import_url].first).to include('Only allowed ports are 80, 443')
+ end
- it "does not allow import_url with invalid ports for persisted projects" do
- project = create(:project)
- project.import_url = 'http://github.com:25/t.git'
+ it "does not allow import_url with invalid ports for persisted projects" do
+ project = create(:project)
+ project.import_url = 'http://github.com:25/t.git'
- expect(project).to be_invalid
- expect(project.errors[:import_url].first).to include('Only allowed ports are 22, 80, 443')
- end
+ expect(project).to be_invalid
+ expect(project.errors[:import_url].first).to include('Only allowed ports are 22, 80, 443')
+ end
+
+ it "does not allow import_url with invalid user" do
+ project = build(:project, import_url: 'http://$user:password@github.com/t.git')
+
+ expect(project).to be_invalid
+ expect(project.errors[:import_url].first).to include('Username needs to start with an alphanumeric character')
+ end
- it "does not allow import_url with invalid user" do
- project = build(:project, import_url: 'http://$user:password@github.com/t.git')
+ include_context 'invalid urls'
- expect(project).to be_invalid
- expect(project.errors[:import_url].first).to include('Username needs to start with an alphanumeric character')
+ it 'does not allow urls with CR or LF characters' do
+ project = build(:project)
+
+ aggregate_failures do
+ urls_with_CRLF.each do |url|
+ project.import_url = url
+
+ expect(project).not_to be_valid
+ expect(project.errors.full_messages.first).to match(/is blocked: URI is invalid/)
+ end
+ end
+ end
end
describe 'project pending deletion' do
@@ -1617,6 +1619,30 @@ describe Project do
end
end
+ describe '#track_project_repository' do
+ let(:project) { create(:project, :repository) }
+
+ it 'creates a project_repository' do
+ project.track_project_repository
+
+ expect(project.reload.project_repository).to be_present
+ expect(project.project_repository.disk_path).to eq(project.disk_path)
+ expect(project.project_repository.shard_name).to eq(project.repository_storage)
+ end
+
+ it 'updates the project_repository' do
+ project.track_project_repository
+
+ allow(project).to receive(:disk_path).and_return('@fancy/new/path')
+
+ expect do
+ project.track_project_repository
+ end.not_to change(ProjectRepository, :count)
+
+ expect(project.reload.project_repository.disk_path).to eq(project.disk_path)
+ end
+ end
+
describe '#create_repository' do
let(:project) { create(:project, :repository) }
let(:shell) { Gitlab::Shell.new }
@@ -1702,6 +1728,16 @@ describe Project do
end
end
+ describe 'handling import URL' do
+ it 'returns the sanitized URL' do
+ project = create(:project, :import_started, import_url: 'http://user:pass@test.com')
+
+ project.import_state.finish
+
+ expect(project.reload.import_url).to eq('http://test.com')
+ end
+ end
+
describe '#container_registry_url' do
let(:project) { create(:project) }
@@ -1815,106 +1851,6 @@ describe Project do
end
end
- describe '#human_import_status_name' do
- context 'when import_state exists' do
- it 'returns the humanized status name' do
- project = create(:project)
- create(:import_state, :started, project: project)
-
- expect(project.human_import_status_name).to eq("started")
- end
- end
-
- context 'when import_state was not created yet' do
- let(:project) { create(:project, :import_started) }
-
- it 'ensures import_state is created and returns humanized status name' do
- expect do
- project.human_import_status_name
- end.to change { ProjectImportState.count }.from(0).to(1)
- end
-
- it 'returns humanized status name' do
- expect(project.human_import_status_name).to eq("started")
- end
- end
- end
-
- describe 'Project import job' do
- let(:project) { create(:project, import_url: generate(:url)) }
-
- before do
- allow_any_instance_of(Gitlab::Shell).to receive(:import_repository)
- .with(project.repository_storage, project.disk_path, project.import_url)
- .and_return(true)
-
- # Works around https://github.com/rspec/rspec-mocks/issues/910
- allow(described_class).to receive(:find).with(project.id).and_return(project)
- expect(project.repository).to receive(:after_import)
- .and_call_original
- expect(project.wiki.repository).to receive(:after_import)
- .and_call_original
- end
-
- it 'imports a project' do
- expect_any_instance_of(RepositoryImportWorker).to receive(:perform).and_call_original
-
- expect { project.import_schedule }.to change { project.import_jid }
- expect(project.reload.import_status).to eq('finished')
- end
- end
-
- describe 'project import state transitions' do
- context 'state transition: [:started] => [:finished]' do
- let(:after_import_service) { spy(:after_import_service) }
- let(:housekeeping_service) { spy(:housekeeping_service) }
-
- before do
- allow(Projects::AfterImportService)
- .to receive(:new) { after_import_service }
-
- allow(after_import_service)
- .to receive(:execute) { housekeeping_service.execute }
-
- allow(Projects::HousekeepingService)
- .to receive(:new) { housekeeping_service }
- end
-
- it 'resets project import_error' do
- error_message = 'Some error'
- mirror = create(:project_empty_repo, :import_started)
- mirror.import_state.update(last_error: error_message)
-
- expect { mirror.import_finish }.to change { mirror.import_error }.from(error_message).to(nil)
- end
-
- it 'performs housekeeping when an import of a fresh project is completed' do
- project = create(:project_empty_repo, :import_started, import_type: :github)
-
- project.import_finish
-
- expect(after_import_service).to have_received(:execute)
- expect(housekeeping_service).to have_received(:execute)
- end
-
- it 'does not perform housekeeping when project repository does not exist' do
- project = create(:project, :import_started, import_type: :github)
-
- project.import_finish
-
- expect(housekeeping_service).not_to have_received(:execute)
- end
-
- it 'does not perform housekeeping when project does not have a valid import type' do
- project = create(:project, :import_started, import_type: nil)
-
- project.import_finish
-
- expect(housekeeping_service).not_to have_received(:execute)
- end
- end
- end
-
describe '#latest_successful_builds_for' do
def create_pipeline(status = 'success')
create(:ci_pipeline, project: project,
@@ -1994,6 +1930,42 @@ describe Project do
end
end
+ describe '#import_status' do
+ context 'with import_state' do
+ it 'returns the right status' do
+ project = create(:project, :import_started)
+
+ expect(project.import_status).to eq("started")
+ end
+ end
+
+ context 'without import_state' do
+ it 'returns none' do
+ project = create(:project)
+
+ expect(project.import_status).to eq('none')
+ end
+ end
+ end
+
+ describe '#human_import_status_name' do
+ context 'with import_state' do
+ it 'returns the right human import status' do
+ project = create(:project, :import_started)
+
+ expect(project.human_import_status_name).to eq('started')
+ end
+ end
+
+ context 'without import_state' do
+ it 'returns none' do
+ project = create(:project)
+
+ expect(project.human_import_status_name).to eq('none')
+ end
+ end
+ end
+
describe '#add_import_job' do
let(:import_jid) { '123' }
@@ -2203,12 +2175,6 @@ describe Project do
project.change_head(project.default_branch)
end
- it 'creates the new reference with rugged' do
- expect(project.repository.raw_repository).to receive(:write_ref).with('HEAD', "refs/heads/#{project.default_branch}", shell: false)
-
- project.change_head(project.default_branch)
- end
-
it 'copies the gitattributes' do
expect(project.repository).to receive(:copy_gitattributes).with(project.default_branch)
project.change_head(project.default_branch)
@@ -3436,13 +3402,14 @@ describe Project do
describe '#after_import' do
let(:project) { create(:project) }
+ let(:import_state) { create(:import_state, project: project) }
it 'runs the correct hooks' do
expect(project.repository).to receive(:after_import)
expect(project.wiki.repository).to receive(:after_import)
- expect(project).to receive(:import_finish)
+ expect(import_state).to receive(:finish)
expect(project).to receive(:update_project_counter_caches)
- expect(project).to receive(:remove_import_jid)
+ expect(import_state).to receive(:remove_jid)
expect(project).to receive(:after_create_default_branch)
expect(project).to receive(:refresh_markdown_cache!)
@@ -3452,6 +3419,10 @@ describe Project do
context 'branch protection' do
let(:project) { create(:project, :repository) }
+ before do
+ create(:import_state, :started, project: project)
+ end
+
it 'does not protect when branch protection is disabled' do
stub_application_setting(default_branch_protection: Gitlab::Access::PROTECTION_NONE)
@@ -3507,37 +3478,6 @@ describe Project do
end
end
- describe '#remove_import_jid', :clean_gitlab_redis_cache do
- let(:project) { }
-
- context 'without an import JID' do
- it 'does nothing' do
- project = create(:project)
-
- expect(Gitlab::SidekiqStatus)
- .not_to receive(:unset)
-
- project.remove_import_jid
- end
- end
-
- context 'with an import JID' do
- it 'unsets the import JID' do
- project = create(:project)
- create(:import_state, project: project, jid: '123')
-
- expect(Gitlab::SidekiqStatus)
- .to receive(:unset)
- .with('123')
- .and_call_original
-
- project.remove_import_jid
-
- expect(project.import_jid).to be_nil
- end
- end
- end
-
describe '#wiki_repository_exists?' do
it 'returns true when the wiki repository exists' do
project = create(:project, :wiki_repo)