diff options
Diffstat (limited to 'spec/models/repository_spec.rb')
-rw-r--r-- | spec/models/repository_spec.rb | 194 |
1 files changed, 138 insertions, 56 deletions
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index 829b69093c9..53b98ba05f8 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -15,7 +15,12 @@ describe Repository, models: true do let(:merge_commit) do merge_request = create(:merge_request, source_branch: 'feature', target_branch: 'master', source_project: project) - merge_commit_id = repository.merge(user, merge_request, commit_options) + + merge_commit_id = repository.merge(user, + merge_request.diff_head_sha, + merge_request, + commit_options) + repository.commit(merge_commit_id) end @@ -289,17 +294,39 @@ describe Repository, models: true do describe "#commit_dir" do it "commits a change that creates a new directory" do expect do - repository.commit_dir(user, 'newdir', 'Create newdir', 'master') + repository.commit_dir(user, 'newdir', + message: 'Create newdir', branch_name: 'master') end.to change { repository.commits('master').count }.by(1) newdir = repository.tree('master', 'newdir') expect(newdir.path).to eq('newdir') end + context "when committing to another project" do + let(:forked_project) { create(:project) } + + it "creates a fork and commit to the forked project" do + expect do + repository.commit_dir(user, 'newdir', + message: 'Create newdir', branch_name: 'patch', + start_branch_name: 'master', start_project: forked_project) + end.to change { repository.commits('master').count }.by(0) + + expect(repository.branch_exists?('patch')).to be_truthy + expect(forked_project.repository.branch_exists?('patch')).to be_falsy + + newdir = repository.tree('patch', 'newdir') + expect(newdir.path).to eq('newdir') + end + end + context "when an author is specified" do it "uses the given email/name to set the commit's author" do expect do - repository.commit_dir(user, "newdir", "Add newdir", 'master', author_email: author_email, author_name: author_name) + repository.commit_dir(user, 'newdir', + message: 'Add newdir', + branch_name: 'master', + author_email: author_email, author_name: author_name) end.to change { repository.commits('master').count }.by(1) last_commit = repository.commit @@ -314,8 +341,9 @@ describe Repository, models: true do it 'commits change to a file successfully' do expect do repository.commit_file(user, 'CHANGELOG', 'Changelog!', - 'Updates file content', - 'master', true) + message: 'Updates file content', + branch_name: 'master', + update: true) end.to change { repository.commits('master').count }.by(1) blob = repository.blob_at('master', 'CHANGELOG') @@ -326,8 +354,12 @@ describe Repository, models: true do context "when an author is specified" do it "uses the given email/name to set the commit's author" do expect do - repository.commit_file(user, "README", 'README!', 'Add README', - 'master', true, author_email: author_email, author_name: author_name) + repository.commit_file(user, 'README', 'README!', + message: 'Add README', + branch_name: 'master', + update: true, + author_email: author_email, + author_name: author_name) end.to change { repository.commits('master').count }.by(1) last_commit = repository.commit @@ -342,7 +374,7 @@ describe Repository, models: true do it 'updates filename successfully' do expect do repository.update_file(user, 'NEWLICENSE', 'Copyright!', - branch: 'master', + branch_name: 'master', previous_path: 'LICENSE', message: 'Changes filename') end.to change { repository.commits('master').count }.by(1) @@ -355,15 +387,16 @@ describe Repository, models: true do context "when an author is specified" do it "uses the given email/name to set the commit's author" do - repository.commit_file(user, "README", 'README!', 'Add README', 'master', true) + repository.commit_file(user, 'README', 'README!', + message: 'Add README', branch_name: 'master', update: true) expect do - repository.update_file(user, 'README', "Updated README!", - branch: 'master', - previous_path: 'README', - message: 'Update README', - author_email: author_email, - author_name: author_name) + repository.update_file(user, 'README', 'Updated README!', + branch_name: 'master', + previous_path: 'README', + message: 'Update README', + author_email: author_email, + author_name: author_name) end.to change { repository.commits('master').count }.by(1) last_commit = repository.commit @@ -376,10 +409,12 @@ describe Repository, models: true do describe "#remove_file" do it 'removes file successfully' do - repository.commit_file(user, "README", 'README!', 'Add README', 'master', true) + repository.commit_file(user, 'README', 'README!', + message: 'Add README', branch_name: 'master', update: true) expect do - repository.remove_file(user, "README", "Remove README", 'master') + repository.remove_file(user, 'README', + message: 'Remove README', branch_name: 'master') end.to change { repository.commits('master').count }.by(1) expect(repository.blob_at('master', 'README')).to be_nil @@ -387,10 +422,13 @@ describe Repository, models: true do context "when an author is specified" do it "uses the given email/name to set the commit's author" do - repository.commit_file(user, "README", 'README!', 'Add README', 'master', true) + repository.commit_file(user, 'README', 'README!', + message: 'Add README', branch_name: 'master', update: true) expect do - repository.remove_file(user, "README", "Remove README", 'master', author_email: author_email, author_name: author_name) + repository.remove_file(user, 'README', + message: 'Remove README', branch_name: 'master', + author_email: author_email, author_name: author_name) end.to change { repository.commits('master').count }.by(1) last_commit = repository.commit @@ -538,11 +576,14 @@ describe Repository, models: true do describe "#license_blob", caching: true do before do - repository.remove_file(user, 'LICENSE', 'Remove LICENSE', 'master') + repository.remove_file( + user, 'LICENSE', message: 'Remove LICENSE', branch_name: 'master') end it 'handles when HEAD points to non-existent ref' do - repository.commit_file(user, 'LICENSE', 'Copyright!', 'Add LICENSE', 'master', false) + repository.commit_file( + user, 'LICENSE', 'Copyright!', + message: 'Add LICENSE', branch_name: 'master', update: false) allow(repository).to receive(:file_on_head). and_raise(Rugged::ReferenceError) @@ -551,21 +592,27 @@ describe Repository, models: true do end it 'looks in the root_ref only' do - repository.remove_file(user, 'LICENSE', 'Remove LICENSE', 'markdown') - repository.commit_file(user, 'LICENSE', Licensee::License.new('mit').content, 'Add LICENSE', 'markdown', false) + repository.remove_file(user, 'LICENSE', + message: 'Remove LICENSE', branch_name: 'markdown') + repository.commit_file(user, 'LICENSE', + Licensee::License.new('mit').content, + message: 'Add LICENSE', branch_name: 'markdown', update: false) expect(repository.license_blob).to be_nil end it 'detects license file with no recognizable open-source license content' do - repository.commit_file(user, 'LICENSE', 'Copyright!', 'Add LICENSE', 'master', false) + repository.commit_file(user, 'LICENSE', 'Copyright!', + message: 'Add LICENSE', branch_name: 'master', update: false) expect(repository.license_blob.name).to eq('LICENSE') end %w[LICENSE LICENCE LiCensE LICENSE.md LICENSE.foo COPYING COPYING.md].each do |filename| it "detects '#{filename}'" do - repository.commit_file(user, filename, Licensee::License.new('mit').content, "Add #{filename}", 'master', false) + repository.commit_file(user, filename, + Licensee::License.new('mit').content, + message: "Add #{filename}", branch_name: 'master', update: false) expect(repository.license_blob.name).to eq(filename) end @@ -574,7 +621,8 @@ describe Repository, models: true do describe '#license_key', caching: true do before do - repository.remove_file(user, 'LICENSE', 'Remove LICENSE', 'master') + repository.remove_file(user, 'LICENSE', + message: 'Remove LICENSE', branch_name: 'master') end it 'returns nil when no license is detected' do @@ -588,13 +636,16 @@ describe Repository, models: true do end it 'detects license file with no recognizable open-source license content' do - repository.commit_file(user, 'LICENSE', 'Copyright!', 'Add LICENSE', 'master', false) + repository.commit_file(user, 'LICENSE', 'Copyright!', + message: 'Add LICENSE', branch_name: 'master', update: false) expect(repository.license_key).to be_nil end it 'returns the license key' do - repository.commit_file(user, 'LICENSE', Licensee::License.new('mit').content, 'Add LICENSE', 'master', false) + repository.commit_file(user, 'LICENSE', + Licensee::License.new('mit').content, + message: 'Add LICENSE', branch_name: 'master', update: false) expect(repository.license_key).to eq('mit') end @@ -707,7 +758,7 @@ describe Repository, models: true do allow_any_instance_of(Gitlab::Git::Hook).to receive(:trigger).and_return([false, '']) expect do - repository.rm_branch(user, 'new_feature') + repository.rm_branch(user, 'feature') end.to raise_error(GitHooksService::PreReceiveError) end @@ -728,36 +779,51 @@ describe Repository, models: true do context 'when pre hooks were successful' do before do - expect_any_instance_of(GitHooksService).to receive(:execute). - with(user, repository.path_to_repo, old_rev, new_rev, 'refs/heads/feature'). - and_yield.and_return(true) + service = GitHooksService.new + expect(GitHooksService).to receive(:new).and_return(service) + expect(service).to receive(:execute). + with( + user, + repository.path_to_repo, + old_rev, + new_rev, + 'refs/heads/feature'). + and_yield(service).and_return(true) end it 'runs without errors' do expect do - repository.update_branch_with_hooks(user, 'feature') { new_rev } + GitOperationService.new(user, repository).with_branch('feature') do + new_rev + end end.not_to raise_error end it 'ensures the autocrlf Git option is set to :input' do - expect(repository).to receive(:update_autocrlf_option) + service = GitOperationService.new(user, repository) - repository.update_branch_with_hooks(user, 'feature') { new_rev } + expect(service).to receive(:update_autocrlf_option) + + service.with_branch('feature') { new_rev } end context "when the branch wasn't empty" do it 'updates the head' do expect(repository.find_branch('feature').dereferenced_target.id).to eq(old_rev) - repository.update_branch_with_hooks(user, 'feature') { new_rev } + + GitOperationService.new(user, repository).with_branch('feature') do + new_rev + end + expect(repository.find_branch('feature').dereferenced_target.id).to eq(new_rev) end end end context 'when the update adds more than one commit' do - it 'runs without errors' do - old_rev = '33f3729a45c02fc67d00adb1b8bca394b0e761d9' + let(:old_rev) { '33f3729a45c02fc67d00adb1b8bca394b0e761d9' } + it 'runs without errors' do # old_rev is an ancestor of new_rev expect(repository.rugged.merge_base(old_rev, new_rev)).to eq(old_rev) @@ -767,22 +833,28 @@ describe Repository, models: true do branch = 'feature-ff-target' repository.add_branch(user, branch, old_rev) - expect { repository.update_branch_with_hooks(user, branch) { new_rev } }.not_to raise_error + expect do + GitOperationService.new(user, repository).with_branch(branch) do + new_rev + end + end.not_to raise_error end end context 'when the update would remove commits from the target branch' do - it 'raises an exception' do - branch = 'master' - old_rev = repository.find_branch(branch).dereferenced_target.sha + let(:branch) { 'master' } + let(:old_rev) { repository.find_branch(branch).dereferenced_target.sha } + it 'raises an exception' do # The 'master' branch is NOT an ancestor of new_rev. expect(repository.rugged.merge_base(old_rev, new_rev)).not_to eq(old_rev) # Updating 'master' to new_rev would lose the commits on 'master' that # are not contained in new_rev. This should not be allowed. expect do - repository.update_branch_with_hooks(user, branch) { new_rev } + GitOperationService.new(user, repository).with_branch(branch) do + new_rev + end end.to raise_error(Repository::CommitError) end end @@ -792,7 +864,9 @@ describe Repository, models: true do allow_any_instance_of(Gitlab::Git::Hook).to receive(:trigger).and_return([false, '']) expect do - repository.update_branch_with_hooks(user, 'feature') { new_rev } + GitOperationService.new(user, repository).with_branch('feature') do + new_rev + end end.to raise_error(GitHooksService::PreReceiveError) end end @@ -800,7 +874,6 @@ describe Repository, models: true do context 'when target branch is different from source branch' do before do allow_any_instance_of(Gitlab::Git::Hook).to receive(:trigger).and_return([true, '']) - allow(repository).to receive(:update_ref!) end it 'expires branch cache' do @@ -809,7 +882,10 @@ describe Repository, models: true do expect(repository).not_to receive(:expire_emptiness_caches) expect(repository).to receive(:expire_branches_cache) - repository.update_branch_with_hooks(user, 'new-feature') { new_rev } + GitOperationService.new(user, repository). + with_branch('new-feature') do + new_rev + end end end @@ -827,7 +903,9 @@ describe Repository, models: true do expect(empty_repository).to receive(:expire_branches_cache) empty_repository.commit_file(user, 'CHANGELOG', 'Changelog!', - 'Updates file content', 'master', false) + message: 'Updates file content', + branch_name: 'master', + update: false) end end end @@ -877,7 +955,7 @@ describe Repository, models: true do end it 'sets autocrlf to :input' do - repository.update_autocrlf_option + GitOperationService.new(nil, repository).send(:update_autocrlf_option) expect(repository.raw_repository.autocrlf).to eq(:input) end @@ -892,7 +970,7 @@ describe Repository, models: true do expect(repository.raw_repository).not_to receive(:autocrlf=). with(:input) - repository.update_autocrlf_option + GitOperationService.new(nil, repository).send(:update_autocrlf_option) end end end @@ -1009,8 +1087,11 @@ describe Repository, models: true do it 'sets the `in_progress_merge_commit_sha` flag for the given merge request' do merge_request = create(:merge_request, source_branch: 'feature', target_branch: 'master', source_project: project) - merge_commit_id = repository.merge(user, merge_request, commit_options) - repository.commit(merge_commit_id) + + merge_commit_id = repository.merge(user, + merge_request.diff_head_sha, + merge_request, + commit_options) expect(merge_request.in_progress_merge_commit_sha).to eq(merge_commit_id) end @@ -1388,9 +1469,10 @@ describe Repository, models: true do describe '#rm_tag' do it 'removes a tag' do expect(repository).to receive(:before_remove_tag) - expect(repository.rugged.tags).to receive(:delete).with('v1.1.0') - repository.rm_tag('v1.1.0') + repository.rm_tag(create(:user), 'v1.1.0') + + expect(repository.find_tag('v1.1.0')).to be_nil end end @@ -1458,16 +1540,16 @@ describe Repository, models: true do end end - describe '#update_ref!' do + describe '#update_ref' do it 'can create a ref' do - repository.update_ref!('refs/heads/foobar', 'refs/heads/master', Gitlab::Git::BLANK_SHA) + GitOperationService.new(nil, repository).send(:update_ref, 'refs/heads/foobar', 'refs/heads/master', Gitlab::Git::BLANK_SHA) expect(repository.find_branch('foobar')).not_to be_nil end it 'raises CommitError when the ref update fails' do expect do - repository.update_ref!('refs/heads/master', 'refs/heads/master', Gitlab::Git::BLANK_SHA) + GitOperationService.new(nil, repository).send(:update_ref, 'refs/heads/master', 'refs/heads/master', Gitlab::Git::BLANK_SHA) end.to raise_error(Repository::CommitError) end end |