summaryrefslogtreecommitdiff
path: root/spec/services/merge_requests/create_from_issue_service_spec.rb
blob: 20bf1cbb8b6780ca8e38de6b982da3b805d64376 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
require 'spec_helper'

describe MergeRequests::CreateFromIssueService do
  let(:project) { create(:project, :repository) }
  let(:user) { create(:user) }
  let(:label_ids) { create_pair(:label, project: project).map(&:id) }
  let(:milestone_id) { create(:milestone, project: project).id }
  let(:issue) { create(:issue, project: project, milestone_id: milestone_id) }
  let(:custom_source_branch) { 'custom-source-branch' }

  subject(:service) { described_class.new(project, user, issue_iid: issue.iid) }
  subject(:service_with_custom_source_branch) { described_class.new(project, user, issue_iid: issue.iid, branch_name: custom_source_branch) }

  before do
    project.add_developer(user)
  end

  describe '#execute' do
    it 'returns an error with invalid issue iid' do
      result = described_class.new(project, user, issue_iid: -1).execute

      expect(result[:status]).to eq(:error)
      expect(result[:message]).to eq('Invalid issue iid')
    end

    it 'delegates issue search to IssuesFinder' do
      expect_any_instance_of(IssuesFinder).to receive(:find_by).once.and_call_original

      described_class.new(project, user, issue_iid: -1).execute
    end

    it "inherits labels" do
      issue.assign_attributes(label_ids: label_ids)

      result = service.execute

      expect(result[:merge_request].label_ids).to eq(label_ids)
    end

    it "inherits milestones" do
      result = service.execute

      expect(result[:merge_request].milestone_id).to eq(milestone_id)
    end

    it 'delegates the branch creation to CreateBranchService' do
      expect_any_instance_of(CreateBranchService).to receive(:execute).once.and_call_original

      service.execute
    end

    it 'creates a branch based on issue title' do
      service.execute

      expect(project.repository.branch_exists?(issue.to_branch_name)).to be_truthy
    end

    it 'creates a branch using passed name' do
      service_with_custom_source_branch.execute

      expect(project.repository.branch_exists?(custom_source_branch)).to be_truthy
    end

    it 'creates the new_merge_request system note' do
      expect(SystemNoteService).to receive(:new_merge_request).with(issue, project, user, instance_of(MergeRequest))

      service.execute
    end

    it 'creates the new_issue_branch system note when the branch could be created but the merge_request cannot be created' do
      project.project_feature.update!(merge_requests_access_level: ProjectFeature::DISABLED)

      expect(SystemNoteService).to receive(:new_issue_branch).with(issue, project, user, issue.to_branch_name)

      service.execute
    end

    it 'creates a merge request' do
      expect { service.execute }.to change(project.merge_requests, :count).by(1)
    end

    it 'sets the merge request title to: "WIP: Resolves "$issue-title"' do
      result = service.execute

      expect(result[:merge_request].title).to eq("WIP: Resolve \"#{issue.title}\"")
    end

    it 'sets the merge request author to current user' do
      result = service.execute

      expect(result[:merge_request].author).to eq(user)
    end

    it 'sets the merge request source branch to the new issue branch' do
      result = service.execute

      expect(result[:merge_request].source_branch).to eq(issue.to_branch_name)
    end

    it 'sets the merge request source branch to the passed branch name' do
      result = service_with_custom_source_branch.execute

      expect(result[:merge_request].source_branch).to eq(custom_source_branch)
    end

    it 'sets the merge request target branch to the project default branch' do
      result = service.execute

      expect(result[:merge_request].target_branch).to eq(project.default_branch)
    end

    it 'executes quick actions if the build service sets them in the description' do
      allow(service).to receive(:merge_request).and_wrap_original do |m, *args|
        m.call(*args).tap do |merge_request|
          merge_request.description = "/assign #{user.to_reference}"
        end
      end

      result = service.execute

      expect(result[:merge_request].assignees).to eq([user])
    end

    context 'when ref branch is set' do
      subject { described_class.new(project, user, issue_iid: issue.iid, ref: 'feature').execute }

      it 'sets the merge request source branch to the new issue branch' do
        expect(subject[:merge_request].source_branch).to eq(issue.to_branch_name)
      end

      it 'sets the merge request target branch to the ref branch' do
        expect(subject[:merge_request].target_branch).to eq('feature')
      end

      context 'when ref branch does not exist' do
        subject { described_class.new(project, user, issue_iid: issue.iid, ref: 'no-such-branch').execute }

        it 'creates a merge request' do
          expect { subject }.to change(project.merge_requests, :count).by(1)
        end

        it 'sets the merge request target branch to the project default branch' do
          expect(subject[:merge_request].target_branch).to eq(project.default_branch)
        end
      end
    end
  end
end