diff options
Diffstat (limited to 'spec/models/merge_request_spec.rb')
-rw-r--r-- | spec/models/merge_request_spec.rb | 193 |
1 files changed, 164 insertions, 29 deletions
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index 07b3e1c1758..243eeddc7a8 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -24,11 +24,6 @@ describe MergeRequest do it { is_expected.to include_module(Taskable) } end - describe "act_as_paranoid" do - it { is_expected.to have_db_column(:deleted_at) } - it { is_expected.to have_db_index(:deleted_at) } - end - describe 'validation' do it { is_expected.to validate_presence_of(:target_branch) } it { is_expected.to validate_presence_of(:source_branch) } @@ -92,6 +87,39 @@ describe MergeRequest do it { is_expected.to respond_to(:merge_when_pipeline_succeeds) } end + describe '.by_commit_sha' do + subject(:by_commit_sha) { described_class.by_commit_sha(sha) } + + let!(:merge_request) { create(:merge_request, :with_diffs) } + + context 'with sha contained in latest merge request diff' do + let(:sha) { 'b83d6e391c22777fca1ed3012fce84f633d7fed0' } + + it 'returns merge requests' do + expect(by_commit_sha).to eq([merge_request]) + end + end + + context 'with sha contained not in latest merge request diff' do + let(:sha) { 'b83d6e391c22777fca1ed3012fce84f633d7fed0' } + + it 'returns empty requests' do + latest_merge_request_diff = merge_request.merge_request_diffs.create + latest_merge_request_diff.merge_request_diff_commits.where(sha: 'b83d6e391c22777fca1ed3012fce84f633d7fed0').delete_all + + expect(by_commit_sha).to be_empty + end + end + + context 'with sha not contained in' do + let(:sha) { 'b83d6e3' } + + it 'returns empty result' do + expect(by_commit_sha).to be_empty + end + end + end + describe '.in_projects' do it 'returns the merge requests for a set of projects' do expect(described_class.in_projects(Project.all)).to eq([subject]) @@ -1035,6 +1063,103 @@ describe MergeRequest do end end + describe '#can_be_reverted?' do + context 'when there is no merge_commit for the MR' do + before do + subject.metrics.update!(merged_at: Time.now.utc) + end + + it 'returns false' do + expect(subject.can_be_reverted?(nil)).to be_falsey + end + end + + context 'when the MR has been merged' do + before do + MergeRequests::MergeService + .new(subject.target_project, subject.author) + .execute(subject) + end + + context 'when there is no revert commit' do + it 'returns true' do + expect(subject.can_be_reverted?(nil)).to be_truthy + end + end + + context 'when there is no merged_at for the MR' do + before do + subject.metrics.update!(merged_at: nil) + end + + it 'returns true' do + expect(subject.can_be_reverted?(nil)).to be_truthy + end + end + + context 'when there is a revert commit' do + let(:current_user) { subject.author } + let(:branch) { subject.target_branch } + let(:project) { subject.target_project } + + let(:revert_commit_id) do + params = { + commit: subject.merge_commit, + branch_name: branch, + start_branch: branch + } + + Commits::RevertService.new(project, current_user, params).execute[:result] + end + + before do + project.add_master(current_user) + + ProcessCommitWorker.new.perform(project.id, + current_user.id, + project.commit(revert_commit_id).to_hash, + project.default_branch == branch) + end + + context 'when the revert commit is mentioned in a note after the MR was merged' do + it 'returns false' do + expect(subject.can_be_reverted?(current_user)).to be_falsey + end + end + + context 'when there is no merged_at for the MR' do + before do + subject.metrics.update!(merged_at: nil) + end + + it 'returns false' do + expect(subject.can_be_reverted?(current_user)).to be_falsey + end + end + + context 'when the revert commit is mentioned in a note just before the MR was merged' do + before do + subject.notes.last.update!(created_at: subject.metrics.merged_at - 30.seconds) + end + + it 'returns false' do + expect(subject.can_be_reverted?(current_user)).to be_falsey + end + end + + context 'when the revert commit is mentioned in a note long before the MR was merged' do + before do + subject.notes.last.update!(created_at: subject.metrics.merged_at - 2.minutes) + end + + it 'returns true' do + expect(subject.can_be_reverted?(current_user)).to be_truthy + end + end + end + end + end + describe '#participants' do let(:project) { create(:project, :public) } @@ -1214,6 +1339,10 @@ describe MergeRequest do it 'returns false' do expect(subject.mergeable_state?).to be_falsey end + + it 'returns true when skipping discussions check' do + expect(subject.mergeable_state?(skip_discussions_check: true)).to be(true) + end end end end @@ -1414,7 +1543,7 @@ describe MergeRequest do expect { subject.reload_diff }.to change { subject.merge_request_diffs.count }.by(1) end - it "executs diff cache service" do + it "executes diff cache service" do expect_any_instance_of(MergeRequests::MergeRequestDiffCacheService).to receive(:execute).with(subject) subject.reload_diff @@ -1915,38 +2044,44 @@ describe MergeRequest do end describe '#rebase_in_progress?' do - # Create merge request and project before we stub file calls - before do - subject - end + shared_examples 'checking whether a rebase is in progress' do + let(:repo_path) { subject.source_project.repository.path } + let(:rebase_path) { File.join(repo_path, "gitlab-worktree", "rebase-#{subject.id}") } - it 'returns true when there is a current rebase directory' do - allow(File).to receive(:exist?).and_return(true) - allow(File).to receive(:mtime).and_return(Time.now) + before do + system(*%W(#{Gitlab.config.git.bin_path} -C #{repo_path} worktree add --detach #{rebase_path} master)) + end - expect(subject.rebase_in_progress?).to be_truthy - end + it 'returns true when there is a current rebase directory' do + expect(subject.rebase_in_progress?).to be_truthy + end - it 'returns false when there is no rebase directory' do - allow(File).to receive(:exist?).and_return(false) + it 'returns false when there is no rebase directory' do + FileUtils.rm_rf(rebase_path) - expect(subject.rebase_in_progress?).to be_falsey - end + expect(subject.rebase_in_progress?).to be_falsey + end - it 'returns false when the rebase directory has expired' do - allow(File).to receive(:exist?).and_return(true) - allow(File).to receive(:mtime).and_return(20.minutes.ago) + it 'returns false when the rebase directory has expired' do + time = 20.minutes.ago.to_time + File.utime(time, time, rebase_path) + + expect(subject.rebase_in_progress?).to be_falsey + end - expect(subject.rebase_in_progress?).to be_falsey + it 'returns false when the source project has been removed' do + allow(subject).to receive(:source_project).and_return(nil) + + expect(subject.rebase_in_progress?).to be_falsey + end end - it 'returns false when the source project has been removed' do - allow(subject).to receive(:source_project).and_return(nil) - allow(File).to receive(:exist?).and_return(true) - allow(File).to receive(:mtime).and_return(Time.now) + context 'when Gitaly rebase_in_progress is enabled' do + it_behaves_like 'checking whether a rebase is in progress' + end - expect(File).not_to have_received(:exist?) - expect(subject.rebase_in_progress?).to be_falsey + context 'when Gitaly rebase_in_progress is enabled', :disable_gitaly do + it_behaves_like 'checking whether a rebase is in progress' end end end |