issue_spec.rb 7.25 KB
Newer Older
gitlabhq's avatar
gitlabhq committed
1 2
require 'spec_helper'

Douwe Maan's avatar
Douwe Maan committed
3
describe Issue, models: true do
gitlabhq's avatar
gitlabhq committed
4
  describe "Associations" do
5
    it { is_expected.to belong_to(:milestone) }
gitlabhq's avatar
gitlabhq committed
6 7
  end

8
  describe 'modules' do
9 10 11
    subject { described_class }

    it { is_expected.to include_module(InternalId) }
12
    it { is_expected.to include_module(Issuable) }
13 14 15
    it { is_expected.to include_module(Referable) }
    it { is_expected.to include_module(Sortable) }
    it { is_expected.to include_module(Taskable) }
16 17
  end

18
  subject { create(:issue) }
19

20 21 22 23 24
  describe "act_as_paranoid" do
    it { is_expected.to have_db_column(:deleted_at) }
    it { is_expected.to have_db_index(:deleted_at) }
  end

25 26 27 28 29 30 31 32 33 34 35 36
  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.project.to_reference}##{subject.iid}"
    end
  end

37 38
  describe '#is_being_reassigned?' do
    it 'returns true if the issue assignee has changed' do
39
      subject.assignee = create(:user)
40
      expect(subject.is_being_reassigned?).to be_truthy
41 42
    end
    it 'returns false if the issue assignee has not changed' do
43
      expect(subject.is_being_reassigned?).to be_falsey
44 45
    end
  end
Andrew8xx8's avatar
Andrew8xx8 committed
46 47

  describe '#is_being_reassigned?' do
Johannes Schleifenbaum's avatar
Johannes Schleifenbaum committed
48
    it 'returns issues assigned to user' do
49 50
      user = create(:user)
      create_list(:issue, 2, assignee: user)
Andrew8xx8's avatar
Andrew8xx8 committed
51

52
      expect(Issue.open_for(user).count).to eq 2
Andrew8xx8's avatar
Andrew8xx8 committed
53 54
    end
  end
55

56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
  describe '#closed_by_merge_requests' do
    let(:project) { create(:project) }
    let(:issue)   { create(:issue, project: project, state: "opened")}
    let(:closed_issue) { build(:issue, project: project, state: "closed")}

    let(:mr) do
      opts = {
        title: 'Awesome merge_request',
        description: "Fixes #{issue.to_reference}",
        source_branch: 'feature',
        target_branch: 'master'
      }
      MergeRequests::CreateService.new(project, project.owner, opts).execute
    end

    let(:closed_mr) do
      opts = {
        title: 'Awesome merge_request 2',
        description: "Fixes #{issue.to_reference}",
        source_branch: 'feature',
        target_branch: 'master',
        state: 'closed'
      }
      MergeRequests::CreateService.new(project, project.owner, opts).execute
    end

    it 'returns the merge request to close this issue' do
      allow(mr).to receive(:closes_issue?).with(issue).and_return(true)

      expect(issue.closed_by_merge_requests).to eq([mr])
    end

    it "returns an empty array when the current issue is closed already" do
      expect(closed_issue.closed_by_merge_requests).to eq([])
    end
  end

93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
  describe '#referenced_merge_requests' do
    it 'returns the referenced merge requests' do
      project = create(:project, :public)

      mr1 = create(:merge_request,
                   source_project: project,
                   source_branch:  'master',
                   target_branch:  'feature')

      mr2 = create(:merge_request,
                   source_project: project,
                   source_branch:  'feature',
                   target_branch:  'master')

      issue = create(:issue, description: mr1.to_reference, project: project)

      create(:note_on_issue,
             noteable:   issue,
             note:       mr2.to_reference,
             project_id: project.id)

      expect(issue.referenced_merge_requests).to eq([mr1, mr2])
    end
  end

118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
  describe '#can_move?' do
    let(:user) { create(:user) }
    let(:issue) { create(:issue) }
    subject { issue.can_move?(user) }

    context 'user is not a member of project issue belongs to' do
      it { is_expected.to eq false}
    end

    context 'user is reporter in project issue belongs to' do
      let(:project) { create(:project) }
      let(:issue) { create(:issue, project: project) }

      before { project.team << [user, :reporter] }

      it { is_expected.to eq true }

135 136 137 138 139
      context 'issue not persisted' do
        let(:issue) { build(:issue, project: project) }
        it { is_expected.to eq false }
      end

140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
      context 'checking destination project also' do
        subject { issue.can_move?(user, to_project) }
        let(:to_project) { create(:project) }

        context 'destination project allowed' do
          before { to_project.team << [user, :reporter] }
          it { is_expected.to eq true }
        end

        context 'destination project not allowed' do
          before { to_project.team << [user, :guest] }
          it { is_expected.to eq false }
        end
      end
    end
  end

  describe '#moved?' do
    let(:issue) { create(:issue) }
    subject { issue.moved? }

    context 'issue not moved' do
      it { is_expected.to eq false }
    end

    context 'issue already moved' do
      let(:moved_to_issue) { create(:issue) }
      let(:issue) { create(:issue, moved_to: moved_to_issue) }

      it { is_expected.to eq true }
    end
  end

Zeger-Jan van de Weg's avatar
Zeger-Jan van de Weg committed
173
  describe '#related_branches' do
174
    let(:user) { build(:admin) }
175

176
    before do
Zeger-Jan van de Weg's avatar
Zeger-Jan van de Weg committed
177
      allow(subject.project.repository).to receive(:branch_names).
178
                                            and_return(["mpempe", "#{subject.iid}mepmep", subject.to_branch_name, "#{subject.iid}-branch"])
179 180 181 182 183 184 185 186

      # Without this stub, the `create(:merge_request)` above fails because it can't find
      # the source branch. This seems like a reasonable compromise, in comparison with
      # setting up a full repo here.
      allow_any_instance_of(MergeRequest).to receive(:create_merge_request_diff)
    end

    it "selects the right branches when there are no referenced merge requests" do
187
      expect(subject.related_branches(user)).to eq([subject.to_branch_name, "#{subject.iid}-branch"])
188
    end
Zeger-Jan van de Weg's avatar
Zeger-Jan van de Weg committed
189

190
    it "selects the right branches when there is a referenced merge request" do
Timothy Andrew's avatar
Timothy Andrew committed
191 192
      merge_request = create(:merge_request, { description: "Closes ##{subject.iid}",
                                               source_project: subject.project,
193
                                               source_branch: "#{subject.iid}-branch" })
194
      merge_request.create_cross_references!(user)
195
      expect(subject.referenced_merge_requests).not_to be_empty
196
      expect(subject.related_branches(user)).to eq([subject.to_branch_name])
Zeger-Jan van de Weg's avatar
Zeger-Jan van de Weg committed
197
    end
198 199 200 201 202

    it 'excludes stable branches from the related branches' do
      allow(subject.project.repository).to receive(:branch_names).
        and_return(["#{subject.iid}-0-stable"])

203
      expect(subject.related_branches(user)).to eq []
204
    end
Zeger-Jan van de Weg's avatar
Zeger-Jan van de Weg committed
205 206
  end

207
  it_behaves_like 'an editable mentionable' do
Douwe Maan's avatar
Douwe Maan committed
208
    subject { create(:issue) }
209

210
    let(:backref_text) { "issue #{subject.to_reference}" }
211 212
    let(:set_mentionable_text) { ->(txt){ subject.description = txt } }
  end
Vinnie Okada's avatar
Vinnie Okada committed
213 214 215 216

  it_behaves_like 'a Taskable' do
    let(:subject) { create :issue }
  end
Zeger-Jan van de Weg's avatar
Zeger-Jan van de Weg committed
217 218

  describe "#to_branch_name" do
219
    let(:issue) { create(:issue, title: 'testing-issue') }
Zeger-Jan van de Weg's avatar
Zeger-Jan van de Weg committed
220

221
    it 'starts with the issue iid' do
222
      expect(issue.to_branch_name).to match /\A#{issue.iid}-[A-Za-z\-]+\z/
Zeger-Jan van de Weg's avatar
Zeger-Jan van de Weg committed
223
    end
224 225

    it "contains the issue title if not confidential" do
226
      expect(issue.to_branch_name).to match /testing-issue\z/
227 228 229 230
    end

    it "does not contain the issue title if confidential" do
      issue = create(:issue, title: 'testing-issue', confidential: true)
231
      expect(issue.to_branch_name).to match /confidential-issue\z/
232
    end
Zeger-Jan van de Weg's avatar
Zeger-Jan van de Weg committed
233
  end
gitlabhq's avatar
gitlabhq committed
234
end