jira_service_spec.rb 8.6 KB
Newer Older
1 2
require 'spec_helper'

D
Douwe Maan 已提交
3
describe JiraService, models: true do
4 5
  include Gitlab::Routing.url_helpers

6
  describe "Associations" do
7 8
    it { is_expected.to belong_to :project }
    it { is_expected.to have_one :service_hook }
9 10
  end

11 12 13 14
  describe 'Validations' do
    context 'when service is active' do
      before { subject.active = true }

F
Felipe Artur 已提交
15 16 17
      it { is_expected.to validate_presence_of(:url) }
      it { is_expected.to validate_presence_of(:project_key) }
      it_behaves_like 'issue tracker service URL attribute', :url
18 19 20 21 22
    end

    context 'when service is inactive' do
      before { subject.active = false }

F
Felipe Artur 已提交
23
      it { is_expected.not_to validate_presence_of(:url) }
24 25 26
    end
  end

27 28 29 30 31 32 33 34 35
  describe '#reference_pattern' do
    it_behaves_like 'allows project key on reference pattern'

    it 'does not allow # on the code' do
      expect(subject.reference_pattern.match('#123')).to be_nil
      expect(subject.reference_pattern.match('1#23#12')).to be_nil
    end
  end

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
  describe '#can_test?' do
    let(:jira_service) { described_class.new }

    it 'returns false if username is blank' do
      allow(jira_service).to receive_messages(
        url: 'http://jira.example.com',
        username: '',
        password: '12345678'
      )

      expect(jira_service.can_test?).to be_falsy
    end

    it 'returns false if password is blank' do
      allow(jira_service).to receive_messages(
        url: 'http://jira.example.com',
        username: 'tester',
        password: ''
      )

      expect(jira_service.can_test?).to be_falsy
    end

    it 'returns true if password and username are present' do
      jira_service = described_class.new
      allow(jira_service).to receive_messages(
        url: 'http://jira.example.com',
        username: 'tester',
        password: '12345678'
      )

      expect(jira_service.can_test?).to be_truthy
    end
  end

D
Drew Blessing 已提交
71 72 73 74 75 76 77 78 79 80 81
  describe "Execute" do
    let(:user)    { create(:user) }
    let(:project) { create(:project) }
    let(:merge_request) { create(:merge_request) }

    before do
      @jira_service = JiraService.new
      allow(@jira_service).to receive_messages(
        project_id: project.id,
        project: project,
        service_hook: true,
F
Felipe Artur 已提交
82
        url: 'http://jira.example.com',
D
Drew Blessing 已提交
83
        username: 'gitlab_jira_username',
84 85
        password: 'gitlab_jira_password',
        project_key: 'GitLabProject'
D
Drew Blessing 已提交
86
      )
F
Felipe Artur 已提交
87 88 89

      @jira_service.save

90 91 92 93
      project_issues_url = 'http://gitlab_jira_username:gitlab_jira_password@jira.example.com/rest/api/2/issue/JIRA-123'
      @project_url       = 'http://gitlab_jira_username:gitlab_jira_password@jira.example.com/rest/api/2/project/GitLabProject'
      @transitions_url   = 'http://gitlab_jira_username:gitlab_jira_password@jira.example.com/rest/api/2/issue/JIRA-123/transitions'
      @comment_url       = 'http://gitlab_jira_username:gitlab_jira_password@jira.example.com/rest/api/2/issue/JIRA-123/comment'
D
Drew Blessing 已提交
94

95 96
      WebMock.stub_request(:get, @project_url)
      WebMock.stub_request(:get, project_issues_url)
F
Felipe Artur 已提交
97
      WebMock.stub_request(:post, @transitions_url)
D
Drew Blessing 已提交
98 99 100
      WebMock.stub_request(:post, @comment_url)
    end

101
    it "calls JIRA API" do
F
Felipe Artur 已提交
102 103
      @jira_service.execute(merge_request, ExternalIssue.new("JIRA-123", project))

D
Drew Blessing 已提交
104 105 106 107 108
      expect(WebMock).to have_requested(:post, @comment_url).with(
        body: /Issue solved with/
      ).once
    end

109 110 111 112 113 114 115 116 117 118 119 120
    it "references the GitLab commit/merge request" do
      @jira_service.execute(merge_request, ExternalIssue.new("JIRA-123", project))

      expect(WebMock).to have_requested(:post, @comment_url).with(
        body: /#{Gitlab.config.gitlab.url}\/#{project.path_with_namespace}\/commit\/#{merge_request.diff_head_sha}/
      ).once
    end

    it "references the GitLab commit/merge request (relative URL)" do
      stub_config_setting(relative_url_root: '/gitlab')
      stub_config_setting(url: Settings.send(:build_gitlab_url))

121 122 123
      allow(JiraService).to receive(:default_url_options) do
        { script_name: '/gitlab' }
      end
124 125 126 127 128 129 130 131

      @jira_service.execute(merge_request, ExternalIssue.new("JIRA-123", project))

      expect(WebMock).to have_requested(:post, @comment_url).with(
        body: /#{Gitlab.config.gitlab.url}\/#{project.path_with_namespace}\/commit\/#{merge_request.diff_head_sha}/
      ).once
    end

D
Drew Blessing 已提交
132 133
    it "calls the api with jira_issue_transition_id" do
      @jira_service.jira_issue_transition_id = 'this-is-a-custom-id'
F
Felipe Artur 已提交
134 135 136
      @jira_service.execute(merge_request, ExternalIssue.new("JIRA-123", project))

      expect(WebMock).to have_requested(:post, @transitions_url).with(
D
Drew Blessing 已提交
137 138 139
        body: /this-is-a-custom-id/
      ).once
    end
140 141 142 143 144 145 146 147

    context "when testing" do
      it "tries to get jira project" do
        @jira_service.execute(nil)

        expect(WebMock).to have_requested(:get, @project_url)
      end
    end
D
Drew Blessing 已提交
148 149 150 151 152 153 154
  end

  describe "Stored password invalidation" do
    let(:project) { create(:project) }

    context "when a password was previously set" do
      before do
155
        @jira_service = JiraService.create!(
D
Drew Blessing 已提交
156 157
          project: create(:project),
          properties: {
F
Felipe Artur 已提交
158
            url: 'http://jira.example.com/rest/api/2',
D
Drew Blessing 已提交
159 160 161 162 163 164 165
            username: 'mic',
            password: "password"
          }
        )
      end

      it "reset password if url changed" do
F
Felipe Artur 已提交
166
        @jira_service.url = 'http://jira_edited.example.com/rest/api/2'
D
Drew Blessing 已提交
167 168 169 170 171 172 173 174 175 176 177
        @jira_service.save
        expect(@jira_service.password).to be_nil
      end

      it "does not reset password if username changed" do
        @jira_service.username = "some_name"
        @jira_service.save
        expect(@jira_service.password).to eq("password")
      end

      it "does not reset password if new url is set together with password, even if it's the same password" do
F
Felipe Artur 已提交
178
        @jira_service.url = 'http://jira_edited.example.com/rest/api/2'
D
Drew Blessing 已提交
179 180 181
        @jira_service.password = 'password'
        @jira_service.save
        expect(@jira_service.password).to eq("password")
F
Felipe Artur 已提交
182
        expect(@jira_service.url).to eq("http://jira_edited.example.com/rest/api/2")
D
Drew Blessing 已提交
183 184
      end

185
      it "resets password if url changed, even if setter called multiple times" do
F
Felipe Artur 已提交
186 187
        @jira_service.url = 'http://jira1.example.com/rest/api/2'
        @jira_service.url = 'http://jira1.example.com/rest/api/2'
D
Drew Blessing 已提交
188 189 190 191 192 193 194 195 196 197
        @jira_service.save
        expect(@jira_service.password).to be_nil
      end
    end

    context "when no password was previously set" do
      before do
        @jira_service = JiraService.create(
          project: create(:project),
          properties: {
F
Felipe Artur 已提交
198
            url: 'http://jira.example.com/rest/api/2',
D
Drew Blessing 已提交
199 200 201 202 203 204
            username: 'mic'
          }
        )
      end

      it "saves password if new url is set together with password" do
F
Felipe Artur 已提交
205
        @jira_service.url = 'http://jira_edited.example.com/rest/api/2'
D
Drew Blessing 已提交
206 207 208
        @jira_service.password = 'password'
        @jira_service.save
        expect(@jira_service.password).to eq("password")
F
Felipe Artur 已提交
209
        expect(@jira_service.url).to eq("http://jira_edited.example.com/rest/api/2")
D
Drew Blessing 已提交
210 211 212 213
      end
    end
  end

214 215 216 217 218 219
  describe "Validations" do
    context "active" do
      before do
        subject.active = true
      end

F
Felipe Artur 已提交
220
      it { is_expected.to validate_presence_of :url }
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
    end
  end

  describe 'description and title' do
    let(:project) { create(:project) }

    context 'when it is not set' do
      before do
        @service = project.create_jira_service(active: true)
      end

      after do
        @service.destroy!
      end

236
      it 'is initialized' do
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251
        expect(@service.title).to eq('JIRA')
        expect(@service.description).to eq("Jira issue tracker")
      end
    end

    context 'when it is set' do
      before do
        properties = { 'title' => 'Jira One', 'description' => 'Jira One issue tracker' }
        @service = project.create_jira_service(active: true, properties: properties)
      end

      after do
        @service.destroy!
      end

252
      it "is correct" do
253 254 255 256 257 258 259 260 261 262 263
        expect(@service.title).to eq('Jira One')
        expect(@service.description).to eq('Jira One issue tracker')
      end
    end
  end

  describe 'project and issue urls' do
    let(:project) { create(:project) }

    context 'when gitlab.yml was initialized' do
      before do
D
Drew Blessing 已提交
264 265 266
        settings = {
          "jira" => {
            "title" => "Jira",
F
Felipe Artur 已提交
267
            "url" => "http://jira.sample/projects/project_a"
268 269
          }
        }
270
        allow(Gitlab.config).to receive(:issues_tracker).and_return(settings)
271 272 273 274 275 276 277
        @service = project.create_jira_service(active: true)
      end

      after do
        @service.destroy!
      end

278
      it 'is prepopulated with the settings' do
F
Felipe Artur 已提交
279 280
        expect(@service.properties["title"]).to eq('Jira')
        expect(@service.properties["url"]).to eq('http://jira.sample/projects/project_a')
281 282 283 284
      end
    end
  end
end