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.rb185
1 files changed, 178 insertions, 7 deletions
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 53c8408633c..5a27ccbab0a 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -11,6 +11,8 @@ describe Project, models: true do
it { is_expected.to have_many(:issues).dependent(:destroy) }
it { is_expected.to have_many(:milestones).dependent(:destroy) }
it { is_expected.to have_many(:project_members).dependent(:destroy) }
+ it { is_expected.to have_many(:users).through(:project_members) }
+ it { is_expected.to have_many(:requesters).dependent(:destroy) }
it { is_expected.to have_many(:notes).dependent(:destroy) }
it { is_expected.to have_many(:snippets).class_name('ProjectSnippet').dependent(:destroy) }
it { is_expected.to have_many(:deploy_keys_projects).dependent(:destroy) }
@@ -31,6 +33,34 @@ describe Project, models: true do
it { is_expected.to have_many(:environments).dependent(:destroy) }
it { is_expected.to have_many(:deployments).dependent(:destroy) }
it { is_expected.to have_many(:todos).dependent(:destroy) }
+
+ describe '#members & #requesters' do
+ let(:project) { create(:project) }
+ let(:requester) { create(:user) }
+ let(:developer) { create(:user) }
+ before do
+ project.request_access(requester)
+ project.team << [developer, :developer]
+ end
+
+ describe '#members' do
+ it 'includes members and exclude requesters' do
+ member_user_ids = project.members.pluck(:user_id)
+
+ expect(member_user_ids).to include(developer.id)
+ expect(member_user_ids).not_to include(requester.id)
+ end
+ end
+
+ describe '#requesters' do
+ it 'does not include requesters' do
+ requester_user_ids = project.requesters.pluck(:user_id)
+
+ expect(requester_user_ids).to include(requester.id)
+ expect(requester_user_ids).not_to include(developer.id)
+ end
+ end
+ end
end
describe 'modules' do
@@ -56,6 +86,7 @@ describe Project, models: true do
it { is_expected.to validate_length_of(:description).is_within(0..2000) }
it { is_expected.to validate_presence_of(:creator) }
it { is_expected.to validate_presence_of(:namespace) }
+ it { is_expected.to validate_presence_of(:repository_storage) }
it 'should not allow new projects beyond user limits' do
project2 = build(:project)
@@ -63,6 +94,53 @@ describe Project, models: true do
expect(project2).not_to be_valid
expect(project2.errors[:limit_reached].first).to match(/Personal project creation is not allowed/)
end
+
+ describe 'wiki path conflict' do
+ context "when the new path has been used by the wiki of other Project" do
+ it 'should have an error on the name attribute' do
+ new_project = build_stubbed(:project, namespace_id: project.namespace_id, path: "#{project.path}.wiki")
+
+ expect(new_project).not_to be_valid
+ expect(new_project.errors[:name].first).to eq('has already been taken')
+ end
+ end
+
+ context "when the new wiki path has been used by the path of other Project" do
+ it 'should have an error on the name attribute' do
+ project_with_wiki_suffix = create(:project, path: 'foo.wiki')
+ new_project = build_stubbed(:project, namespace_id: project_with_wiki_suffix.namespace_id, path: 'foo')
+
+ expect(new_project).not_to be_valid
+ expect(new_project.errors[:name].first).to eq('has already been taken')
+ end
+ end
+ end
+
+ context 'repository storages inclussion' do
+ let(:project2) { build(:project, repository_storage: 'missing') }
+
+ before do
+ storages = { 'custom' => 'tmp/tests/custom_repositories' }
+ allow(Gitlab.config.repositories).to receive(:storages).and_return(storages)
+ end
+
+ it "should not allow repository storages that don't match a label in the configuration" do
+ expect(project2).not_to be_valid
+ expect(project2.errors[:repository_storage].first).to match(/is not included in the list/)
+ end
+ end
+
+ it 'should not allow an invalid URI as import_url' do
+ project2 = build(:project, import_url: 'invalid://')
+
+ expect(project2).not_to be_valid
+ end
+
+ it 'should allow a valid URI as import_url' do
+ project2 = build(:project, import_url: 'ssh://test@gitlab.com/project.git')
+
+ expect(project2).to be_valid
+ end
end
describe 'default_scope' do
@@ -110,6 +188,24 @@ describe Project, models: true do
end
end
+ describe '#repository_storage_path' do
+ let(:project) { create(:project, repository_storage: 'custom') }
+
+ before do
+ FileUtils.mkdir('tmp/tests/custom_repositories')
+ storages = { 'custom' => 'tmp/tests/custom_repositories' }
+ allow(Gitlab.config.repositories).to receive(:storages).and_return(storages)
+ end
+
+ after do
+ FileUtils.rm_rf('tmp/tests/custom_repositories')
+ end
+
+ it 'returns the repository storage path' do
+ expect(project.repository_storage_path).to eq('tmp/tests/custom_repositories')
+ end
+ end
+
it 'should return valid url to repo' do
project = Project.new(path: 'somewhere')
expect(project.url_to_repo).to eq(Gitlab.config.gitlab_shell.ssh_path_prefix + 'somewhere.git')
@@ -216,7 +312,7 @@ describe Project, models: true do
it 'should update merge request commits with new one if pushed to source branch' do
project.update_merge_requests(prev_commit_id, commit_id, "refs/heads/#{merge_request.source_branch}", key.user)
merge_request.reload
- expect(merge_request.last_commit.id).to eq(commit_id)
+ expect(merge_request.diff_head_sha).to eq(commit_id)
end
end
@@ -353,6 +449,14 @@ describe Project, models: true do
it { expect(project.open_branches.map(&:name)).to include('feature') }
it { expect(project.open_branches.map(&:name)).not_to include('master') }
+
+ it "includes branches matching a protected branch wildcard" do
+ expect(project.open_branches.map(&:name)).to include('feature')
+
+ create(:protected_branch, name: 'feat*', project: project)
+
+ expect(Project.find(project.id).open_branches.map(&:name)).to include('feature')
+ end
end
describe '#star_count' do
@@ -553,6 +657,21 @@ describe Project, models: true do
end
end
+ context 'repository storage by default' do
+ let(:project) { create(:empty_project) }
+
+ subject { project.repository_storage }
+
+ before do
+ storages = { 'alternative_storage' => '/some/path' }
+ allow(Gitlab.config.repositories).to receive(:storages).and_return(storages)
+ stub_application_setting(repository_storage: 'alternative_storage')
+ allow_any_instance_of(Project).to receive(:ensure_dir_exist).and_return(true)
+ end
+
+ it { is_expected.to eq('alternative_storage') }
+ end
+
context 'shared runners by default' do
let(:project) { create(:empty_project) }
@@ -708,12 +827,12 @@ describe Project, models: true do
expect(gitlab_shell).to receive(:mv_repository).
ordered.
- with("#{ns}/foo", "#{ns}/#{project.path}").
+ with(project.repository_storage_path, "#{ns}/foo", "#{ns}/#{project.path}").
and_return(true)
expect(gitlab_shell).to receive(:mv_repository).
ordered.
- with("#{ns}/foo.wiki", "#{ns}/#{project.path}.wiki").
+ with(project.repository_storage_path, "#{ns}/foo.wiki", "#{ns}/#{project.path}.wiki").
and_return(true)
expect_any_instance_of(SystemHooksService).
@@ -805,7 +924,7 @@ describe Project, models: true do
context 'using a regular repository' do
it 'creates the repository' do
expect(shell).to receive(:add_repository).
- with(project.path_with_namespace).
+ with(project.repository_storage_path, project.path_with_namespace).
and_return(true)
expect(project.repository).to receive(:after_create)
@@ -815,7 +934,7 @@ describe Project, models: true do
it 'adds an error if the repository could not be created' do
expect(shell).to receive(:add_repository).
- with(project.path_with_namespace).
+ with(project.repository_storage_path, project.path_with_namespace).
and_return(false)
expect(project.repository).not_to receive(:after_create)
@@ -838,15 +957,67 @@ describe Project, models: true do
describe '#protected_branch?' do
let(:project) { create(:empty_project) }
- it 'returns true when a branch is a protected branch' do
+ it 'returns true when the branch matches a protected branch via direct match' do
project.protected_branches.create!(name: 'foo')
expect(project.protected_branch?('foo')).to eq(true)
end
- it 'returns false when a branch is not a protected branch' do
+ it 'returns true when the branch matches a protected branch via wildcard match' do
+ project.protected_branches.create!(name: 'production/*')
+
+ expect(project.protected_branch?('production/some-branch')).to eq(true)
+ end
+
+ it 'returns false when the branch does not match a protected branch via direct match' do
expect(project.protected_branch?('foo')).to eq(false)
end
+
+ it 'returns false when the branch does not match a protected branch via wildcard match' do
+ project.protected_branches.create!(name: 'production/*')
+
+ expect(project.protected_branch?('staging/some-branch')).to eq(false)
+ end
+ end
+
+ describe "#developers_can_push_to_protected_branch?" do
+ let(:project) { create(:empty_project) }
+
+ context "when the branch matches a protected branch via direct match" do
+ it "returns true if 'Developers can Push' is turned on" do
+ create(:protected_branch, name: "production", project: project, developers_can_push: true)
+
+ expect(project.developers_can_push_to_protected_branch?('production')).to be true
+ end
+
+ it "returns false if 'Developers can Push' is turned off" do
+ create(:protected_branch, name: "production", project: project, developers_can_push: false)
+
+ expect(project.developers_can_push_to_protected_branch?('production')).to be false
+ end
+ end
+
+ context "when the branch matches a protected branch via wilcard match" do
+ it "returns true if 'Developers can Push' is turned on" do
+ create(:protected_branch, name: "production/*", project: project, developers_can_push: true)
+
+ expect(project.developers_can_push_to_protected_branch?('production/some-branch')).to be true
+ end
+
+ it "returns false if 'Developers can Push' is turned off" do
+ create(:protected_branch, name: "production/*", project: project, developers_can_push: false)
+
+ expect(project.developers_can_push_to_protected_branch?('production/some-branch')).to be false
+ end
+ end
+
+ context "when the branch does not match a protected branch" do
+ it "returns false" do
+ create(:protected_branch, name: "production/*", project: project, developers_can_push: true)
+
+ expect(project.developers_can_push_to_protected_branch?('staging/some-branch')).to be false
+ end
+ end
end
describe '#container_registry_path_with_namespace' do