merge_request_spec.rb 7.5 KB
Newer Older
D
Dmitriy Zaporozhets 已提交
1 2 3 4
# == Schema Information
#
# Table name: merge_requests
#
D
Dmitriy Zaporozhets 已提交
5 6 7 8 9 10 11
#  id                :integer          not null, primary key
#  target_branch     :string(255)      not null
#  source_branch     :string(255)      not null
#  source_project_id :integer          not null
#  author_id         :integer
#  assignee_id       :integer
#  title             :string(255)
D
Dmitriy Zaporozhets 已提交
12 13
#  created_at        :datetime
#  updated_at        :datetime
D
Dmitriy Zaporozhets 已提交
14 15 16 17 18
#  milestone_id      :integer
#  state             :string(255)
#  merge_status      :string(255)
#  target_project_id :integer          not null
#  iid               :integer
D
Dmitriy Zaporozhets 已提交
19
#  description       :text
D
Dmitriy Zaporozhets 已提交
20
#  position          :integer          default(0)
D
Dmitriy Zaporozhets 已提交
21
#  locked_at         :datetime
S
Stan Hu 已提交
22
#  updated_by_id     :integer
D
Dmitriy Zaporozhets 已提交
23
#  merge_error       :string(255)
D
Dmitriy Zaporozhets 已提交
24 25
#

D
Dmitriy Zaporozhets 已提交
26 27 28
require 'spec_helper'

describe MergeRequest do
29 30
  subject { create(:merge_request) }

R
Robert Speicher 已提交
31 32 33
  describe 'associations' do
    it { is_expected.to belong_to(:target_project).with_foreign_key(:target_project_id).class_name('Project') }
    it { is_expected.to belong_to(:source_project).with_foreign_key(:source_project_id).class_name('Project') }
34
    it { is_expected.to belong_to(:merge_user).class_name("User") }
R
Robert Speicher 已提交
35 36 37
    it { is_expected.to have_one(:merge_request_diff).dependent(:destroy) }
  end

38 39 40 41 42 43 44 45 46 47 48
  describe 'modules' do
    subject { described_class }

    it { is_expected.to include_module(InternalId) }
    it { is_expected.to include_module(Issuable) }
    it { is_expected.to include_module(Referable) }
    it { is_expected.to include_module(Sortable) }
    it { is_expected.to include_module(Taskable) }
  end

  describe 'validation' do
49 50
    it { is_expected.to validate_presence_of(:target_branch) }
    it { is_expected.to validate_presence_of(:source_branch) }
D
Dmitriy Zaporozhets 已提交
51 52
  end

R
Robert Speicher 已提交
53
  describe 'respond to' do
54 55 56
    it { is_expected.to respond_to(:unchecked?) }
    it { is_expected.to respond_to(:can_be_merged?) }
    it { is_expected.to respond_to(:cannot_be_merged?) }
57 58
    it { is_expected.to respond_to(:merge_params) }
    it { is_expected.to respond_to(:merge_when_build_succeeds) }
59
  end
A
Andrey Kumanyaev 已提交
60

61 62 63 64 65 66 67 68 69
  describe '#to_reference' do
    it 'returns a String reference to the object' do
      expect(subject.to_reference).to eq "!#{subject.iid}"
    end

    it 'supports a cross-project reference' do
      cross = double('project')
      expect(subject.to_reference(cross)).to eq "#{subject.source_project.to_reference}!#{subject.iid}"
    end
70
  end
71 72

  describe "#mr_and_commit_notes" do
73
    let!(:merge_request) { create(:merge_request) }
74 75

    before do
76
      allow(merge_request).to receive(:commits) { [merge_request.source_project.repository.commit] }
D
Dmitriy Zaporozhets 已提交
77 78
      create(:note, commit_id: merge_request.commits.first.id, noteable_type: 'Commit', project: merge_request.project)
      create(:note, noteable: merge_request, project: merge_request.project)
79 80 81
    end

    it "should include notes for commits" do
82 83
      expect(merge_request.commits).not_to be_empty
      expect(merge_request.mr_and_commit_notes.count).to eq(2)
84
    end
85 86 87 88 89 90

    it "should include notes for commits from target project as well" do
      create(:note, commit_id: merge_request.commits.first.id, noteable_type: 'Commit', project: merge_request.target_project)
      expect(merge_request.commits).not_to be_empty
      expect(merge_request.mr_and_commit_notes.count).to eq(3)
    end
91
  end
92 93 94

  describe '#is_being_reassigned?' do
    it 'returns true if the merge_request assignee has changed' do
95
      subject.assignee = create(:user)
96
      expect(subject.is_being_reassigned?).to be_truthy
97 98
    end
    it 'returns false if the merge request assignee has not changed' do
99
      expect(subject.is_being_reassigned?).to be_falsey
100 101
    end
  end
I
Izaak Alpert 已提交
102 103 104

  describe '#for_fork?' do
    it 'returns true if the merge request is for a fork' do
D
Dmitriy Zaporozhets 已提交
105 106
      subject.source_project = create(:project, namespace: create(:group))
      subject.target_project = create(:project, namespace: create(:group))
I
Izaak Alpert 已提交
107

108
      expect(subject.for_fork?).to be_truthy
I
Izaak Alpert 已提交
109
    end
D
Dmitriy Zaporozhets 已提交
110

I
Izaak Alpert 已提交
111
    it 'returns false if is not for a fork' do
112
      expect(subject.for_fork?).to be_falsey
I
Izaak Alpert 已提交
113 114 115
    end
  end

116 117 118
  describe 'detection of issues to be closed' do
    let(:issue0) { create :issue, project: subject.project }
    let(:issue1) { create :issue, project: subject.project }
S
skv 已提交
119 120 121
    let(:commit0) { double('commit0', closes_issues: [issue0]) }
    let(:commit1) { double('commit1', closes_issues: [issue0]) }
    let(:commit2) { double('commit2', closes_issues: [issue1]) }
122 123

    before do
124
      allow(subject).to receive(:commits).and_return([commit0, commit1, commit2])
125 126 127
    end

    it 'accesses the set of issues that will be closed on acceptance' do
128 129
      allow(subject.project).to receive(:default_branch).
        and_return(subject.target_branch)
130

131
      expect(subject.closes_issues).to eq([issue0, issue1].sort_by(&:id))
132 133 134
    end

    it 'only lists issues as to be closed if it targets the default branch' do
135
      allow(subject.project).to receive(:default_branch).and_return('master')
136 137
      subject.target_branch = 'something-else'

138
      expect(subject.closes_issues).to be_empty
139
    end
140 141 142

    it 'detects issues mentioned in the description' do
      issue2 = create(:issue, project: subject.project)
143
      subject.description = "Closes #{issue2.to_reference}"
144 145
      allow(subject.project).to receive(:default_branch).
        and_return(subject.target_branch)
146

147
      expect(subject.closes_issues).to include(issue2)
148
    end
149 150
  end

151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
  describe "#work_in_progress?" do
    it "detects the 'WIP ' prefix" do
      subject.title = "WIP #{subject.title}"
      expect(subject).to be_work_in_progress
    end

    it "detects the 'WIP: ' prefix" do
      subject.title = "WIP: #{subject.title}"
      expect(subject).to be_work_in_progress
    end

    it "detects the '[WIP] ' prefix" do
      subject.title = "[WIP] #{subject.title}"
      expect(subject).to be_work_in_progress
    end

    it "doesn't detect WIP for words starting with WIP" do
      subject.title = "Wipwap #{subject.title}"
      expect(subject).not_to be_work_in_progress
    end

    it "doesn't detect WIP by default" do
      expect(subject).not_to be_work_in_progress
    end
  end

177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
  describe '#can_remove_source_branch' do
    let(:user) { build(:user)}

    before do
      subject.source_project.team << [user, :master]
    end

    it "cant be merged when its a a protected branch" do
      subject.source_project.protected_branches = [];

      expect(subject.can_remove_source_branch?(user)).to be_falsey
    end

    it "cant remove a root ref" do
      subject.source_branch = "master";

      expect(subject.can_remove_source_branch?(user)).to be_falsey
    end

    it "is truthy in all other cases" do
      expect(subject.can_remove_source_branch?(user))
    end
  end

201 202 203 204 205 206 207 208 209 210
  describe "#reset_merge_when_build_succeeds" do
    let(:merge_if_green) { create :merge_request, merge_when_build_succeeds: true }
    it "sets the item to false" do
      merge_if_green.reset_merge_when_build_succeeds
      merge_if_green.reload

      expect(merge_if_green.merge_when_build_succeeds).to be_falsey
    end
  end

211 212 213 214 215 216 217 218 219 220 221
  describe "#hook_attrs" do
    it "has all the required keys" do
      attrs = subject.hook_attrs
      attrs = attrs.to_h
      expect(attrs).to include(:source)
      expect(attrs).to include(:target)
      expect(attrs).to include(:last_commit)
      expect(attrs).to include(:work_in_progress)
    end
  end

222
  it_behaves_like 'an editable mentionable' do
223
    subject { create(:merge_request) }
224

225 226
    let(:backref_text) { "merge request #{subject.to_reference}" }
    let(:set_mentionable_text) { ->(txt){ subject.description = txt } }
227
  end
V
Vinnie Okada 已提交
228 229

  it_behaves_like 'a Taskable' do
230
    subject { create :merge_request, :simple }
V
Vinnie Okada 已提交
231
  end
D
Dmitriy Zaporozhets 已提交
232
end