process_commit_worker_spec.rb 6.1 KB
Newer Older
1 2 3
require 'spec_helper'

describe ProcessCommitWorker do
4 5
  include ProjectForksHelper

6 7
  let(:worker) { described_class.new }
  let(:user) { create(:user) }
8
  let(:project) { create(:project, :public, :repository) }
9 10 11 12 13 14 15
  let(:issue) { create(:issue, project: project, author: user) }
  let(:commit) { project.commit }

  describe '#perform' do
    it 'does not process the commit when the project does not exist' do
      expect(worker).not_to receive(:close_issues)

16
      worker.perform(-1, user.id, commit.to_hash)
17 18 19 20 21
    end

    it 'does not process the commit when the user does not exist' do
      expect(worker).not_to receive(:close_issues)

22
      worker.perform(project.id, -1, commit.to_hash)
23 24 25 26 27
    end

    it 'processes the commit message' do
      expect(worker).to receive(:process_commit_message).and_call_original

28
      worker.perform(project.id, user.id, commit.to_hash)
29 30 31 32 33
    end

    it 'updates the issue metrics' do
      expect(worker).to receive(:update_issue_metrics).and_call_original

34
      worker.perform(project.id, user.id, commit.to_hash)
35
    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
    context 'when the project is forked' do
      context 'when commit already exists in the upstream project' do
        it 'does not process the commit message' do
          forked = fork_project(project, user, repository: true)

          expect(worker).not_to receive(:process_commit_message)

          worker.perform(forked.id, user.id, forked.commit.to_hash)
        end
      end

      context 'when the commit does not exist in the upstream project' do
        it 'processes the commit message' do
          empty_project = create(:project, :public)
          forked = fork_project(empty_project, user, repository: true)

          TestEnv.copy_repo(forked,
                            bare_repo: TestEnv.factory_repo_path_bare,
                            refs: TestEnv::BRANCH_SHA)

          expect(worker).to receive(:process_commit_message)

          worker.perform(forked.id, user.id, forked.commit.to_hash)
        end
      end
62

63 64 65 66
      context 'when the upstream project no longer exists' do
        it 'processes the commit message' do
          forked = fork_project(project, user, repository: true)
          project.destroy!
67

68
          expect(worker).to receive(:process_commit_message)
69

70 71
          worker.perform(forked.id, user.id, forked.commit.to_hash)
        end
72 73
      end
    end
74 75 76 77
  end

  describe '#process_commit_message' do
    context 'when pushing to the default branch' do
78
      before do
M
Micaël Bergeron 已提交
79
        allow(commit).to receive(:safe_message).and_return("Closes #{issue.to_reference}")
80
      end
81

82
      it 'closes issues that should be closed per the commit message' do
M
Micaël Bergeron 已提交
83
        expect(worker).to receive(:close_issues).with(project, user, user, commit, [issue])
84 85 86

        worker.process_commit_message(project, commit, user, user, true)
      end
87 88 89 90 91 92

      it 'creates cross references' do
        expect(commit).to receive(:create_cross_references!).with(user, [issue])

        worker.process_commit_message(project, commit, user, user, true)
      end
93 94 95 96
    end

    context 'when pushing to a non-default branch' do
      it 'does not close any issues' do
M
Micaël Bergeron 已提交
97
        allow(commit).to receive(:safe_message).and_return("Closes #{issue.to_reference}")
98 99 100 101 102

        expect(worker).not_to receive(:close_issues)

        worker.process_commit_message(project, commit, user, user, false)
      end
103 104 105 106 107 108

      it 'does not create cross references' do
        expect(commit).to receive(:create_cross_references!).with(user, [])

        worker.process_commit_message(project, commit, user, user, false)
      end
109 110
    end

111 112 113 114 115 116 117 118
    context 'when commit is a merge request merge commit to the default branch' do
      let(:merge_request) do
        create(:merge_request,
               description: "Closes #{issue.to_reference}",
               source_branch: 'feature-merged',
               target_branch: 'master',
               source_project: project)
      end
119

120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
      let(:commit) do
        project.repository.create_branch('feature-merged', 'feature')

        MergeRequests::MergeService
          .new(project, merge_request.author)
          .execute(merge_request)

        merge_request.reload.merge_commit
      end

      it 'does not close any issues from the commit message' do
        expect(worker).not_to receive(:close_issues)

        worker.process_commit_message(project, commit, user, user, true)
      end

      it 'still creates cross references' do
        expect(commit).to receive(:create_cross_references!).with(user, [])

        worker.process_commit_message(project, commit, user, user, true)
      end
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
    end
  end

  describe '#close_issues' do
    context 'when the user can update the issues' do
      it 'closes the issues' do
        worker.close_issues(project, user, user, commit, [issue])

        issue.reload

        expect(issue.closed?).to eq(true)
      end
    end

    context 'when the user can not update the issues' do
      it 'does not close the issues' do
        other_user = create(:user)

        worker.close_issues(project, other_user, other_user, commit, [issue])

        issue.reload

        expect(issue.closed?).to eq(false)
      end
    end
  end

  describe '#update_issue_metrics' do
    it 'updates any existing issue metrics' do
M
Micaël Bergeron 已提交
170
      allow(commit).to receive(:safe_message).and_return("Closes #{issue.to_reference}")
171 172 173 174 175 176 177

      worker.update_issue_metrics(commit, user)

      metric = Issue::Metrics.first

      expect(metric.first_mentioned_in_commit_at).to eq(commit.committed_date)
    end
178 179

    it "doesn't execute any queries with false conditions" do
M
Micaël Bergeron 已提交
180
      allow(commit).to receive(:safe_message).and_return("Lorem Ipsum")
181

M
Micaël Bergeron 已提交
182 183
      expect { worker.update_issue_metrics(commit, user) }
        .not_to make_queries_matching(/WHERE (?:1=0|0=1)/)
184
    end
185
  end
186 187 188 189 190 191 192 193 194

  describe '#build_commit' do
    it 'returns a Commit' do
      commit = worker.build_commit(project, id: '123')

      expect(commit).to be_an_instance_of(Commit)
    end

    it 'parses date strings into Time instances' do
M
Micaël Bergeron 已提交
195 196 197
      commit = worker.build_commit(project,
                                   id: '123',
                                   authored_date: Time.now.to_s)
198 199 200 201

      expect(commit.authored_date).to be_an_instance_of(Time)
    end
  end
202
end