BigW Consortium Gitlab

slack_mattermost_notifications_shared_examples.rb 11.2 KB
Newer Older
1 2
Dir[Rails.root.join("app/models/project_services/chat_message/*.rb")].each { |f| require f }

3
RSpec.shared_examples 'slack or mattermost notifications' do
4 5 6 7 8 9 10 11 12 13
  let(:chat_service) { described_class.new }
  let(:webhook_url) { 'https://example.gitlab.com/' }

  describe "Associations" do
    it { is_expected.to belong_to :project }
    it { is_expected.to have_one :service_hook }
  end

  describe 'Validations' do
    context 'when service is active' do
14 15 16
      before do
        subject.active = true
      end
17 18 19 20 21 22

      it { is_expected.to validate_presence_of(:webhook) }
      it_behaves_like 'issue tracker service URL attribute', :webhook
    end

    context 'when service is inactive' do
23 24 25
      before do
        subject.active = false
      end
26 27 28 29 30 31 32

      it { is_expected.not_to validate_presence_of(:webhook) }
    end
  end

  describe "#execute" do
    let(:user)    { create(:user) }
33
    let(:project) { create(:project, :repository) }
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
    let(:username) { 'slack_username' }
    let(:channel)  { 'slack_channel' }

    let(:push_sample_data) do
      Gitlab::DataBuilder::Push.build_sample(project, user)
    end

    before do
      allow(chat_service).to receive_messages(
        project: project,
        project_id: project.id,
        service_hook: true,
        webhook: webhook_url
      )

      WebMock.stub_request(:post, webhook_url)

      opts = {
        title: 'Awesome issue',
        description: 'please fix'
      }

      issue_service = Issues::CreateService.new(project, user, opts)
      @issue = issue_service.execute
      @issues_sample_data = issue_service.hook_data(@issue, 'open')

60
      project.add_developer(user)
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
      opts = {
        title: 'Awesome merge_request',
        description: 'please fix',
        source_branch: 'feature',
        target_branch: 'master'
      }
      merge_service = MergeRequests::CreateService.new(project,
                                                       user, opts)
      @merge_request = merge_service.execute
      @merge_sample_data = merge_service.hook_data(@merge_request,
                                                   'open')

      opts = {
        title: "Awesome wiki_page",
        content: "Some text describing some thing or another",
        format: "md",
        message: "user created page: Awesome wiki_page"
      }

80
      @wiki_page = create(:wiki_page, wiki: project.wiki, attrs: opts)
81
      @wiki_page_sample_data = Gitlab::DataBuilder::WikiPage.build(@wiki_page, user, 'create')
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
    end

    it "calls Slack/Mattermost API for push events" do
      chat_service.execute(push_sample_data)

      expect(WebMock).to have_requested(:post, webhook_url).once
    end

    it "calls Slack/Mattermost API for issue events" do
      chat_service.execute(@issues_sample_data)

      expect(WebMock).to have_requested(:post, webhook_url).once
    end

    it "calls Slack/Mattermost API for merge requests events" do
      chat_service.execute(@merge_sample_data)

      expect(WebMock).to have_requested(:post, webhook_url).once
    end

    it "calls Slack/Mattermost API for wiki page events" do
      chat_service.execute(@wiki_page_sample_data)

      expect(WebMock).to have_requested(:post, webhook_url).once
    end

    it 'uses the username as an option for slack when configured' do
      allow(chat_service).to receive(:username).and_return(username)

111 112 113
      expect(Slack::Notifier).to receive(:new)
       .with(webhook_url, username: username)
       .and_return(
114 115 116 117 118 119 120 121
         double(:slack_service).as_null_object
       )

      chat_service.execute(push_sample_data)
    end

    it 'uses the channel as an option when it is configured' do
      allow(chat_service).to receive(:channel).and_return(channel)
122 123 124
      expect(Slack::Notifier).to receive(:new)
        .with(webhook_url, channel: channel)
        .and_return(
125 126 127 128 129 130 131 132 133
          double(:slack_service).as_null_object
        )
      chat_service.execute(push_sample_data)
    end

    context "event channels" do
      it "uses the right channel for push event" do
        chat_service.update_attributes(push_channel: "random")

134 135 136
        expect(Slack::Notifier).to receive(:new)
         .with(webhook_url, channel: "random")
         .and_return(
137 138 139 140 141 142 143 144 145
           double(:slack_service).as_null_object
         )

        chat_service.execute(push_sample_data)
      end

      it "uses the right channel for merge request event" do
        chat_service.update_attributes(merge_request_channel: "random")

146 147 148
        expect(Slack::Notifier).to receive(:new)
         .with(webhook_url, channel: "random")
         .and_return(
149 150 151 152 153 154 155 156 157
           double(:slack_service).as_null_object
         )

        chat_service.execute(@merge_sample_data)
      end

      it "uses the right channel for issue event" do
        chat_service.update_attributes(issue_channel: "random")

158 159 160
        expect(Slack::Notifier).to receive(:new)
         .with(webhook_url, channel: "random")
         .and_return(
161 162 163 164 165 166 167 168 169
           double(:slack_service).as_null_object
         )

        chat_service.execute(@issues_sample_data)
      end

      it "uses the right channel for wiki event" do
        chat_service.update_attributes(wiki_page_channel: "random")

170 171 172
        expect(Slack::Notifier).to receive(:new)
         .with(webhook_url, channel: "random")
         .and_return(
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
           double(:slack_service).as_null_object
         )

        chat_service.execute(@wiki_page_sample_data)
      end

      context "note event" do
        let(:issue_note) do
          create(:note_on_issue, project: project, note: "issue note")
        end

        it "uses the right channel" do
          chat_service.update_attributes(note_channel: "random")

          note_data = Gitlab::DataBuilder::Note.build(issue_note, user)

189 190 191
          expect(Slack::Notifier).to receive(:new)
           .with(webhook_url, channel: "random")
           .and_return(
192 193 194 195 196 197 198 199 200 201 202
             double(:slack_service).as_null_object
           )

          chat_service.execute(note_data)
        end
      end
    end
  end

  describe "Note events" do
    let(:user) { create(:user) }
203
    let(:project) { create(:project, :repository, creator: user) }
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275

    before do
      allow(chat_service).to receive_messages(
        project: project,
        project_id: project.id,
        service_hook: true,
        webhook: webhook_url
      )

      WebMock.stub_request(:post, webhook_url)
    end

    context 'when commit comment event executed' do
      let(:commit_note) do
        create(:note_on_commit, author: user,
                                project: project,
                                commit_id: project.repository.commit.id,
                                note: 'a comment on a commit')
      end

      it "calls Slack/Mattermost API for commit comment events" do
        data = Gitlab::DataBuilder::Note.build(commit_note, user)
        chat_service.execute(data)

        expect(WebMock).to have_requested(:post, webhook_url).once
      end
    end

    context 'when merge request comment event executed' do
      let(:merge_request_note) do
        create(:note_on_merge_request, project: project,
                                       note: "merge request note")
      end

      it "calls Slack API for merge request comment events" do
        data = Gitlab::DataBuilder::Note.build(merge_request_note, user)
        chat_service.execute(data)

        expect(WebMock).to have_requested(:post, webhook_url).once
      end
    end

    context 'when issue comment event executed' do
      let(:issue_note) do
        create(:note_on_issue, project: project, note: "issue note")
      end

      it "calls Slack API for issue comment events" do
        data = Gitlab::DataBuilder::Note.build(issue_note, user)
        chat_service.execute(data)

        expect(WebMock).to have_requested(:post, webhook_url).once
      end
    end

    context 'when snippet comment event executed' do
      let(:snippet_note) do
        create(:note_on_project_snippet, project: project,
                                         note: "snippet note")
      end

      it "calls Slack API for snippet comment events" do
        data = Gitlab::DataBuilder::Note.build(snippet_note, user)
        chat_service.execute(data)

        expect(WebMock).to have_requested(:post, webhook_url).once
      end
    end
  end

  describe 'Pipeline events' do
    let(:user) { create(:user) }
276
    let(:project) { create(:project, :repository) }
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330

    let(:pipeline) do
      create(:ci_pipeline,
             project: project, status: status,
             sha: project.commit.sha, ref: project.default_branch)
    end

    before do
      allow(chat_service).to receive_messages(
        project: project,
        service_hook: true,
        webhook: webhook_url
      )
    end

    shared_examples 'call Slack/Mattermost API' do
      before do
        WebMock.stub_request(:post, webhook_url)
      end

      it 'calls Slack/Mattermost API for pipeline events' do
        data = Gitlab::DataBuilder::Pipeline.build(pipeline)
        chat_service.execute(data)

        expect(WebMock).to have_requested(:post, webhook_url).once
      end
    end

    context 'with failed pipeline' do
      let(:status) { 'failed' }

      it_behaves_like 'call Slack/Mattermost API'
    end

    context 'with succeeded pipeline' do
      let(:status) { 'success' }

      context 'with default to notify_only_broken_pipelines' do
        it 'does not call Slack/Mattermost API for pipeline events' do
          data = Gitlab::DataBuilder::Pipeline.build(pipeline)
          result = chat_service.execute(data)

          expect(result).to be_falsy
        end
      end

      context 'with setting notify_only_broken_pipelines to false' do
        before do
          chat_service.notify_only_broken_pipelines = false
        end

        it_behaves_like 'call Slack/Mattermost API'
      end
    end
331 332 333 334

    context 'only notify for the default branch' do
      context 'when enabled' do
        let(:pipeline) do
335
          create(:ci_pipeline, :failed, project: project, ref: 'not-the-default-branch')
336 337 338 339
        end

        before do
          chat_service.notify_only_default_branch = true
340
          WebMock.stub_request(:post, webhook_url)
341 342 343 344 345 346 347 348
        end

        it 'does not call the Slack/Mattermost API for pipeline events' do
          data = Gitlab::DataBuilder::Pipeline.build(pipeline)
          result = chat_service.execute(data)

          expect(result).to be_falsy
        end
349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365

        it 'does not notify push events if they are not for the default branch' do
          ref = "#{Gitlab::Git::BRANCH_REF_PREFIX}test"
          push_sample_data = Gitlab::DataBuilder::Push.build(project, user, nil, nil, ref, [])

          chat_service.execute(push_sample_data)

          expect(WebMock).not_to have_requested(:post, webhook_url)
        end

        it 'notifies about push events for the default branch' do
          push_sample_data = Gitlab::DataBuilder::Push.build_sample(project, user)

          chat_service.execute(push_sample_data)

          expect(WebMock).to have_requested(:post, webhook_url).once
        end
366
      end
367 368 369 370 371 372 373 374 375 376 377 378

      context 'when disabled' do
        let(:pipeline) do
          create(:ci_pipeline, :failed, project: project, ref: 'not-the-default-branch')
        end

        before do
          chat_service.notify_only_default_branch = false
        end

        it_behaves_like 'call Slack/Mattermost API'
      end
379
    end
380 381
  end
end