merge_request_spec.rb 7.1 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 34 35 36 37
  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') }

    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
  end
A
Andrey Kumanyaev 已提交
58

59 60 61 62 63 64 65 66 67
  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
68
  end
69 70

  describe "#mr_and_commit_notes" do
71
    let!(:merge_request) { create(:merge_request) }
72 73

    before do
74
      allow(merge_request).to receive(:commits) { [merge_request.source_project.repository.commit] }
D
Dmitriy Zaporozhets 已提交
75 76
      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)
77 78 79
    end

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

    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
89
  end
90 91 92

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

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

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

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

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

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

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

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

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

136
      expect(subject.closes_issues).to be_empty
137
    end
138 139 140

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

145
      expect(subject.closes_issues).to include(issue2)
146
    end
147 148
  end

149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
  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

175 176 177 178 179 180 181 182 183 184 185
  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

186
  it_behaves_like 'an editable mentionable' do
187
    subject { create(:merge_request) }
188

189 190
    let(:backref_text) { "merge request #{subject.to_reference}" }
    let(:set_mentionable_text) { ->(txt){ subject.description = txt } }
191
  end
V
Vinnie Okada 已提交
192 193

  it_behaves_like 'a Taskable' do
194
    subject { create :merge_request, :simple }
V
Vinnie Okada 已提交
195
  end
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220

  describe '#ci_commit' do
    describe 'when the source project exists' do
      it 'returns the latest commit' do
        commit    = double(:commit, id: '123abc')
        ci_commit = double(:ci_commit)

        allow(subject).to receive(:last_commit).and_return(commit)

        expect(subject.source_project).to receive(:ci_commit).
          with('123abc').
          and_return(ci_commit)

        expect(subject.ci_commit).to eq(ci_commit)
      end
    end

    describe 'when the source project does not exist' do
      it 'returns nil' do
        allow(subject).to receive(:source_project).and_return(nil)

        expect(subject.ci_commit).to be_nil
      end
    end
  end
D
Dmitriy Zaporozhets 已提交
221
end