issue_spec.rb 7.09 KB
Newer Older
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
1 2 3 4
# == Schema Information
#
# Table name: issues
#
Stan Hu's avatar
Stan Hu committed
5 6 7 8 9 10 11 12 13 14 15 16 17 18
#  id            :integer          not null, primary key
#  title         :string(255)
#  assignee_id   :integer
#  author_id     :integer
#  project_id    :integer
#  created_at    :datetime
#  updated_at    :datetime
#  position      :integer          default(0)
#  branch_name   :string(255)
#  description   :text
#  milestone_id  :integer
#  state         :string(255)
#  iid           :integer
#  updated_by_id :integer
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
19 20
#

gitlabhq's avatar
gitlabhq committed
21 22
require 'spec_helper'

Douwe Maan's avatar
Douwe Maan committed
23
describe Issue, models: true do
gitlabhq's avatar
gitlabhq committed
24
  describe "Associations" do
25
    it { is_expected.to belong_to(:milestone) }
gitlabhq's avatar
gitlabhq committed
26 27
  end

28
  describe 'modules' do
29 30 31
    subject { described_class }

    it { is_expected.to include_module(InternalId) }
32
    it { is_expected.to include_module(Issuable) }
33 34 35
    it { is_expected.to include_module(Referable) }
    it { is_expected.to include_module(Sortable) }
    it { is_expected.to include_module(Taskable) }
36 37
  end

38
  subject { create(:issue) }
39

40 41 42 43 44
  describe "act_as_paranoid" do
    it { is_expected.to have_db_column(:deleted_at) }
    it { is_expected.to have_db_index(:deleted_at) }
  end

45 46 47 48 49 50 51 52 53 54 55 56
  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

57 58
  describe '#is_being_reassigned?' do
    it 'returns true if the issue assignee has changed' do
59
      subject.assignee = create(:user)
60
      expect(subject.is_being_reassigned?).to be_truthy
61 62
    end
    it 'returns false if the issue assignee has not changed' do
63
      expect(subject.is_being_reassigned?).to be_falsey
64 65
    end
  end
Andrew8xx8's avatar
Andrew8xx8 committed
66 67

  describe '#is_being_reassigned?' do
Johannes Schleifenbaum's avatar
Johannes Schleifenbaum committed
68
    it 'returns issues assigned to user' do
69 70
      user = create(:user)
      create_list(:issue, 2, assignee: user)
Andrew8xx8's avatar
Andrew8xx8 committed
71

72
      expect(Issue.open_for(user).count).to eq 2
Andrew8xx8's avatar
Andrew8xx8 committed
73 74
    end
  end
75

76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
  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

113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
  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

138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
  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 }

155 156 157 158 159
      context 'issue not persisted' do
        let(:issue) { build(:issue, project: project) }
        it { is_expected.to eq false }
      end

160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
      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
193
  describe '#related_branches' do
194 195 196 197 198
    let(:user) { build(:user, :admin) }
    let(:merge_request) { create(:merge_request, description: "Closes ##{subject.iid}",
                                 source_project: subject.project, source_branch: "branch-#{subject.iid}") }

    before(:each) do
Zeger-Jan van de Weg's avatar
Zeger-Jan van de Weg committed
199
      allow(subject.project.repository).to receive(:branch_names).
200 201 202 203 204 205 206 207 208 209 210
                                            and_return(["mpempe", "#{subject.iid}mepmep", subject.to_branch_name, "branch-#{subject.iid}"])

      # 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
      expect(subject.related_branches(user)).to eq([subject.to_branch_name, "branch-#{subject.iid}"])
    end
Zeger-Jan van de Weg's avatar
Zeger-Jan van de Weg committed
211

212 213 214
    it "selects the right branches when there is a referenced merge request" do
      merge_request.create_cross_references!(user)
      expect(subject.referenced_merge_requests).to_not be_empty
215
      expect(subject.related_branches(user)).to eq([subject.to_branch_name])
Zeger-Jan van de Weg's avatar
Zeger-Jan van de Weg committed
216 217 218
    end
  end

219
  it_behaves_like 'an editable mentionable' do
Douwe Maan's avatar
Douwe Maan committed
220
    subject { create(:issue) }
221

222
    let(:backref_text) { "issue #{subject.to_reference}" }
223 224
    let(:set_mentionable_text) { ->(txt){ subject.description = txt } }
  end
Vinnie Okada's avatar
Vinnie Okada committed
225 226 227 228

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

  describe "#to_branch_name" do
231
    let(:issue) { create(:issue, title: 'a' * 30) }
Zeger-Jan van de Weg's avatar
Zeger-Jan van de Weg committed
232 233

    it "starts with the issue iid" do
234
      expect(issue.to_branch_name).to match /-#{issue.iid}\z/
Zeger-Jan van de Weg's avatar
Zeger-Jan van de Weg committed
235 236
    end
  end
gitlabhq's avatar
gitlabhq committed
237
end