process_commit_worker_spec.rb 5.22 KB
Newer Older
1 2 3 4 5
require 'spec_helper'

describe ProcessCommitWorker do
  let(:worker) { described_class.new }
  let(:user) { create(:user) }
6
  let(:project) { create(:project, :public, :repository) }
7 8 9 10 11 12 13
  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)

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

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

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

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

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

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

32
      worker.perform(project.id, user.id, commit.to_hash)
33
    end
34 35

    context 'when commit already exists in upstream project' do
36
      let(:forked) { create(:project, :public, :repository) }
37 38 39 40 41 42 43 44 45

      it 'does not process commit message' do
        create(:forked_project_link, forked_to_project: forked, forked_from_project: project)

        expect(worker).not_to receive(:process_commit_message)

        worker.perform(forked.id, user.id, forked.commit.to_hash)
      end
    end
46 47 48 49
  end

  describe '#process_commit_message' do
    context 'when pushing to the default branch' do
50
      before do
Micaël Bergeron's avatar
Micaël Bergeron committed
51
        allow(commit).to receive(:safe_message).and_return("Closes #{issue.to_reference}")
52
      end
53

54
      it 'closes issues that should be closed per the commit message' do
Micaël Bergeron's avatar
Micaël Bergeron committed
55
        expect(worker).to receive(:close_issues).with(project, user, user, commit, [issue])
56 57 58

        worker.process_commit_message(project, commit, user, user, true)
      end
59 60 61 62 63 64

      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
65 66 67 68
    end

    context 'when pushing to a non-default branch' do
      it 'does not close any issues' do
Micaël Bergeron's avatar
Micaël Bergeron committed
69
        allow(commit).to receive(:safe_message).and_return("Closes #{issue.to_reference}")
70 71 72 73 74

        expect(worker).not_to receive(:close_issues)

        worker.process_commit_message(project, commit, user, user, false)
      end
75 76 77 78 79 80

      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
81 82
    end

83 84 85 86 87 88 89 90
    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
91

92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
      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
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
    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
Micaël Bergeron's avatar
Micaël Bergeron committed
142
      allow(commit).to receive(:safe_message).and_return("Closes #{issue.to_reference}")
143 144 145 146 147 148 149

      worker.update_issue_metrics(commit, user)

      metric = Issue::Metrics.first

      expect(metric.first_mentioned_in_commit_at).to eq(commit.committed_date)
    end
150 151

    it "doesn't execute any queries with false conditions" do
Micaël Bergeron's avatar
Micaël Bergeron committed
152
      allow(commit).to receive(:safe_message).and_return("Lorem Ipsum")
153

Micaël Bergeron's avatar
Micaël Bergeron committed
154 155
      expect { worker.update_issue_metrics(commit, user) }
        .not_to make_queries_matching(/WHERE (?:1=0|0=1)/)
156
    end
157
  end
158 159 160 161 162 163 164 165 166

  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
Micaël Bergeron's avatar
Micaël Bergeron committed
167 168 169
      commit = worker.build_commit(project,
                                   id: '123',
                                   authored_date: Time.now.to_s)
170 171 172 173

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