diff options
Diffstat (limited to 'spec/models/commit_spec.rb')
-rw-r--r-- | spec/models/commit_spec.rb | 168 |
1 files changed, 144 insertions, 24 deletions
diff --git a/spec/models/commit_spec.rb b/spec/models/commit_spec.rb index 6056d78da4e..959383ff0b7 100644 --- a/spec/models/commit_spec.rb +++ b/spec/models/commit_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Commit, models: true do +describe Commit do let(:project) { create(:project, :public, :repository) } let(:commit) { project.commit } @@ -13,29 +13,65 @@ describe Commit, models: true do it { is_expected.to include_module(StaticModel) } end + describe '.lazy' do + set(:project) { create(:project, :repository) } + + context 'when the commits are found' do + let(:oids) do + %w( + 498214de67004b1da3d820901307bed2a68a8ef6 + c642fe9b8b9f28f9225d7ea953fe14e74748d53b + 6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9 + 048721d90c449b244b7b4c53a9186b04330174ec + 281d3a76f31c812dbf48abce82ccf6860adedd81 + ) + end + + subject { oids.map { |oid| described_class.lazy(project, oid) } } + + it 'batches requests for commits' do + expect(project.repository).to receive(:commits_by).once.and_call_original + + subject.first.title + subject.last.title + end + + it 'maintains ordering' do + subject.each_with_index do |commit, i| + expect(commit.id).to eq(oids[i]) + end + end + end + + context 'when not found' do + it 'returns nil as commit' do + commit = described_class.lazy(project, 'deadbeef').__sync + + expect(commit).to be_nil + end + end + end + describe '#author' do it 'looks up the author in a case-insensitive way' do user = create(:user, email: commit.author_email.upcase) expect(commit.author).to eq(user) end - it 'caches the author' do - allow(RequestStore).to receive(:active?).and_return(true) + it 'caches the author', :request_store do user = create(:user, email: commit.author_email) - expect_any_instance_of(Commit).to receive(:find_author_by_any_email).and_call_original + expect(User).to receive(:find_by_any_email).and_call_original expect(commit.author).to eq(user) - key = "commit_author:#{commit.author_email}" + key = "Commit:author:#{commit.author_email.downcase}" expect(RequestStore.store[key]).to eq(user) expect(commit.author).to eq(user) - RequestStore.store.clear end end describe '#to_reference' do let(:project) { create(:project, :repository, path: 'sample-project') } - let(:commit) { project.commit } it 'returns a String reference to the object' do expect(commit.to_reference).to eq commit.id @@ -49,7 +85,6 @@ describe Commit, models: true do describe '#reference_link_text' do let(:project) { create(:project, :repository, path: 'sample-project') } - let(:commit) { project.commit } it 'returns a String reference to the object' do expect(commit.reference_link_text).to eq commit.short_id @@ -146,24 +181,23 @@ eos it { is_expected.to respond_to(:parents) } it { is_expected.to respond_to(:date) } it { is_expected.to respond_to(:diffs) } - it { is_expected.to respond_to(:tree) } it { is_expected.to respond_to(:id) } it { is_expected.to respond_to(:to_patch) } end describe '#closes_issues' do let(:issue) { create :issue, project: project } - let(:other_project) { create(:empty_project, :public) } + let(:other_project) { create(:project, :public) } let(:other_issue) { create :issue, project: other_project } let(:commiter) { create :user } before do - project.team << [commiter, :developer] - other_project.team << [commiter, :developer] + project.add_developer(commiter) + other_project.add_developer(commiter) end it 'detects issues that this commit is marked as closing' do - ext_ref = "#{other_project.path_with_namespace}##{other_issue.iid}" + ext_ref = "#{other_project.full_path}##{other_issue.iid}" allow(commit).to receive_messages( safe_message: "Fixes ##{issue.iid} and #{ext_ref}", @@ -193,12 +227,68 @@ eos it { expect(data).to be_a(Hash) } it { expect(data[:message]).to include('adds bar folder and branch-test text file to check Repository merged_to_root_ref method') } - it { expect(data[:timestamp]).to eq('2016-09-27T14:37:46+00:00') } - it { expect(data[:added]).to eq(["bar/branch-test.txt"]) } + it { expect(data[:timestamp]).to eq('2016-09-27T14:37:46Z') } + it { expect(data[:added]).to contain_exactly("bar/branch-test.txt") } it { expect(data[:modified]).to eq([]) } it { expect(data[:removed]).to eq([]) } end + describe '#cherry_pick_message' do + let(:user) { create(:user) } + + context 'of a regular commit' do + let(:commit) { project.commit('video') } + + it { expect(commit.cherry_pick_message(user)).to include("\n\n(cherry picked from commit 88790590ed1337ab189bccaa355f068481c90bec)") } + end + + context 'of a merge commit' do + let(:repository) { project.repository } + + let(:merge_request) do + create(:merge_request, + source_branch: 'video', + target_branch: 'master', + source_project: project, + author: user) + end + + let(:merge_commit) do + merge_commit_id = repository.merge(user, + merge_request.diff_head_sha, + merge_request, + 'Test message') + + repository.commit(merge_commit_id) + end + + context 'that is found' do + before do + # Artificially mark as completed. + merge_request.update(merge_commit_sha: merge_commit.id) + end + + it do + expected_appended_text = <<~STR.rstrip + + (cherry picked from commit #{merge_commit.sha}) + + 467dc98f Add new 'videos' directory + 88790590 Upload new video file + STR + + expect(merge_commit.cherry_pick_message(user)).to include(expected_appended_text) + end + end + + context "that is existing but not found" do + it 'does not include details of the merged commits' do + expect(merge_commit.cherry_pick_message(user)).to end_with("(cherry picked from commit #{merge_commit.sha})") + end + end + end + end + describe '#reverts_commit?' do let(:another_commit) { double(:commit, revert_description: "This reverts commit #{commit.sha}") } let(:user) { commit.author } @@ -299,12 +389,19 @@ eos end it 'gives compound status from latest pipelines if ref is nil' do - expect(commit.status(nil)).to eq(Ci::Pipeline.latest_status) - expect(commit.status(nil)).to eq('failed') + expect(commit.status(nil)).to eq(pipeline_from_fix.status) end end end + describe '#set_status_for_ref' do + it 'sets the status for a given reference' do + commit.set_status_for_ref('master', 'failed') + + expect(commit.status('master')).to eq('failed') + end + end + describe '#participants' do let(:user1) { build(:user) } let(:user2) { build(:user) } @@ -342,15 +439,25 @@ eos end describe '#uri_type' do - it 'returns the URI type at the given path' do - expect(commit.uri_type('files/html')).to be(:tree) - expect(commit.uri_type('files/images/logo-black.png')).to be(:raw) - expect(project.commit('video').uri_type('files/videos/intro.mp4')).to be(:raw) - expect(commit.uri_type('files/js/application.js')).to be(:blob) + shared_examples 'URI type' do + it 'returns the URI type at the given path' do + expect(commit.uri_type('files/html')).to be(:tree) + expect(commit.uri_type('files/images/logo-black.png')).to be(:raw) + expect(project.commit('video').uri_type('files/videos/intro.mp4')).to be(:raw) + expect(commit.uri_type('files/js/application.js')).to be(:blob) + end + + it "returns nil if the path doesn't exists" do + expect(commit.uri_type('this/path/doesnt/exist')).to be_nil + end end - it "returns nil if the path doesn't exists" do - expect(commit.uri_type('this/path/doesnt/exist')).to be_nil + context 'when Gitaly commit_tree_entry feature is enabled' do + it_behaves_like 'URI type' + end + + context 'when Gitaly commit_tree_entry feature is disabled', :disable_gitaly do + it_behaves_like 'URI type' end end @@ -416,4 +523,17 @@ eos expect(described_class.valid_hash?('a' * 41)).to be false end end + + describe '#merge_requests' do + let!(:project) { create(:project, :repository) } + let!(:merge_request1) { create(:merge_request, source_project: project, source_branch: 'master', target_branch: 'feature') } + let!(:merge_request2) { create(:merge_request, source_project: project, source_branch: 'merged-target', target_branch: 'feature') } + let(:commit1) { merge_request1.merge_request_diff.commits.last } + let(:commit2) { merge_request1.merge_request_diff.commits.first } + + it 'returns merge_requests that introduced that commit' do + expect(commit1.merge_requests).to contain_exactly(merge_request1, merge_request2) + expect(commit2.merge_requests).to contain_exactly(merge_request1) + end + end end |