# encoding: utf-8
#--
# Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
#++
require File.dirname(__FILE__) + '/../../test_helper'
class PushEventProcessorTest < ActiveSupport::TestCase
def setup
@processor = PushEventProcessor.new
end
should "update the last_pushed_at attribute on initial push" do
stub_git_show
stub_git_log_and_user
repo = repositories(:johans)
repo.update_attribute(:last_pushed_at, nil)
@processor.expects(:log_events).returns(true)
@processor.expects(:trigger_hooks)
json = {
:gitdir => repo.hashed_path,
:username => "johan",
:message => '0000000000000000000000000000000000000000 a9934c1d3a56edfa8f45e5f157869874c8dc2c34 refs/heads/master',
}.to_json
@processor.on_message(json)
assert_equal users(:johan), @processor.user
assert_equal repo, @processor.repository
assert_not_nil repo.reload.last_pushed_at
assert repo.last_pushed_at > 5.minutes.ago
end
should "not update the last_pushed_at when updating a merge request" do
stub_git_show
stub_git_log_and_user
repo = repositories(:johans)
repo.update_attribute(:last_pushed_at, nil)
@processor.expects(:log_events).returns(true)
json = {
:gitdir => repo.hashed_path,
:username => "johan",
:message => '0000000000000000000000000000000000000000 a9934c1d3a56edfa8f45e5f157869874c8dc2c34 refs/merge-requests/42',
}.to_json
@processor.on_message(json)
assert_nil repo.reload.last_pushed_at, "last_pushed_at was updated"
end
should "returns the correct type and identifier for a new tag" do
stub_git_show
@processor.process_push_from_commit_summary "0000000000000000000000000000000000000000 a9934c1d3a56edfa8f45e5f157869874c8dc2c34 refs/tags/r1.1"
assert_equal :create, @processor.action
assert @processor.tag?
assert_equal 1, @processor.events.size
assert_equal Action::CREATE_TAG, @processor.events.first.event_type
assert_equal 'r1.1', @processor.events.first.identifier
@processor.expects(:log_event).once
@processor.log_events
end
should 'identify non-standard (review) branches, and exclude these from logging' do
stub_git_show
@processor.process_push_from_commit_summary "0000000000000000000000000000000000000000 a9934c1d3a56edfa8f45e5f157869874c8dc2c34 refs/merge-requests/123"
assert_equal :create, @processor.action
assert @processor.review?
assert_equal 0, @processor.events.size
@processor.expects(:log_event).never
@processor.log_events
end
should "returns the correct type and identifier for a new branch" do
stub_git_log_and_user
@processor.process_push_from_commit_summary '0000000000000000000000000000000000000000 a9934c1d3a56edfa8f45e5f157869874c8dc2c34 refs/heads/foo_branch'
@processor.repository = Repository.first
assert_equal :create, @processor.action
assert @processor.head?
assert_equal 1, @processor.events.size
assert_equal Action::CREATE_BRANCH, @processor.events.first.event_type
assert_equal 'foo_branch', @processor.events.first.identifier
assert_equal users(:johan), @processor.events.first.user
@processor.expects(:log_event).times(1)
@processor.log_events
end
should "return the correct namespaced identifier for a new branch" do
stub_git_log_and_user
@processor.process_push_from_commit_summary '0000000000000000000000000000000000000000 a9934c1d3a56edfa8f45e5f157869874c8dc2c34 refs/heads/foo/bar_branch'
assert_equal 'foo/bar_branch', @processor.events.first.identifier
end
should 'only fetch commits for new branches when the new branch is master' do
stub_git_log_and_user
@processor.process_push_from_commit_summary '0000000000000000000000000000000000000000 a9934c1d3a56edfa8f45e5f157869874c8dc2c34 refs/heads/master'
@processor.repository = Repository.first
assert_equal :create, @processor.action
assert @processor.head?
assert_equal 4, @processor.events.size
assert_equal Action::CREATE_BRANCH, @processor.events.first.event_type
assert_equal 'master', @processor.events.first.identifier
assert_equal Action::COMMIT, @processor.events[1].event_type
@processor.expects(:log_event).times(4)
@processor.log_events
end
should "returns the correct type and a set of events for a commit" do
stub_git_log_and_user
@processor.process_push_from_commit_summary "a9934c1d3a56edfa8f45e5f157869874c8dc2c34 33f746e21ef5122511a5a69f381bfdf017f4d66c refs/heads/foo_branch"
@processor.repository = Repository.first
assert_equal :update, @processor.action
assert @processor.head?
assert_equal 1, @processor.events.size
first_event = @processor.events.first
assert_equal Action::PUSH, first_event.event_type
assert_equal users(:johan).email, first_event.email
assert_match(/foo_branch changed/, first_event.message)
assert_equal(3, first_event.commits.size)
assert_incremented_by(Event, :count, 4) do
@processor.log_events
end
end
should "set the correct user for the commit subevent, if a user exists with that email" do
emails(:johans1).update_attribute(:address, "john@nowhere.com")
stub_git_log_and_user
@processor.process_push_from_commit_summary "a9934c1d3a56edfa8f45e5f157869874c8dc2c34 33f746e21ef5122511a5a69f381bfdf017f4d66c refs/heads/foo_branch"
@processor.repository = Repository.first
first_event = @processor.events.first
assert_equal users(:johan).email, first_event.email
assert_equal(3, first_event.commits.size)
assert_nil first_event.commits.first.email
assert_equal users(:johan), first_event.commits.first.user
end
should "creates commit events even if the committer is unknown" do
stub_git_log_and_user
@processor.repository = Repository.first
@processor.process_push_from_commit_summary '0000000000000000000000000000000000000000 a9934c1d3a56edfa8f45e5f157869874c8dc2c34 refs/heads/master'
assert_equal :create, @processor.action
assert_equal 4, @processor.events.size
assert_equal users(:johan), @processor.events.first.user
@processor.events[1..4].each do |e|
assert_equal 'john@nowhere.com', e.email
end
end
should "pick the correct merge request to push to" do
@merge_request = merge_requests(:moes_to_johans)
MergeRequest.expects(:find_by_sequence_number!).with(@merge_request.to_param).returns(@merge_request)
@processor.repository = @merge_request.target_repository
@processor.expects(:action).returns(:update)
@processor.expects(:target).returns(:review)
@processor.stubs(:identifier).returns(@merge_request.to_param)
@merge_request.expects(:update_from_push!)
@processor.process_push
end
should "returns the correct type and identifier for the deletion of a tag" do
stub_git_show
@processor.process_push_from_commit_summary "a9934c1d3a56edfa8f45e5f157869874c8dc2c34 0000000000000000000000000000000000000000 refs/tags/r1.1"
assert_equal :delete, @processor.action
assert @processor.tag?
assert_equal 1, @processor.events.size
assert_equal Action::DELETE_TAG, @processor.events.first.event_type
assert_equal 'r1.1', @processor.events.first.identifier
assert_equal 'john@nowhere.com', @processor.events.first.email
assert_equal 'Deleted tag r1.1', @processor.events.first.message
@processor.expects(:log_event).once
@processor.log_events
end
should "returns the correct type and identifier for the deletion of a branch" do
stub_git_show
frozen_now = Time.now
Time.expects(:now).returns(frozen_now)
@processor.process_push_from_commit_summary 'a9934c1d3a56edfa8f45e5f157869874c8dc2c34 0000000000000000000000000000000000000000 refs/heads/foo_branch'
assert_equal :delete, @processor.action
assert @processor.head?
assert_equal 1, @processor.events.size
assert_equal Action::DELETE_BRANCH, @processor.events.first.event_type
assert_equal 'foo_branch', @processor.events.first.identifier
assert_equal frozen_now.utc, @processor.events.first.commit_time
@processor.expects(:log_event).once
@processor.log_events
end
should "parse the git output correctly in the real world" do
grit = Grit::Repo.new(grit_test_repo("dot_git"), :is_bare => true)
@processor.stubs(:git).returns(grit.git)
@processor.stubs(:user).returns(users(:johan))
@processor.process_push_from_commit_summary "2d3acf90f35989df8f262dc50beadc4ee3ae1560 ca8a30f5a7f0f163bbe3b6f0abf18a6c83b0687a refs/heads/master"
@processor.repository = Repository.first
assert_equal :update, @processor.action
assert @processor.head?
assert_equal 1, @processor.events.size
first_event = @processor.events.first
assert_equal Action::PUSH, first_event.event_type
assert_equal users(:johan).email, first_event.email
assert_equal(2, first_event.commits.size)
commit_event = first_event.commits.first
assert_equal "ca8a30f5a7f0f163bbe3b6f0abf18a6c83b0687a", commit_event.identifier
assert_equal "Scott Chacon ", commit_event.email
assert_equal Time.at(1208561228), commit_event.commit_time
exp_msg = "added a pure-ruby git library and converted the cat_file commands to use it"
assert_equal exp_msg, commit_event.message
end
def stub_git_log_and_user
git = mock
output = [
'33f746e21ef5122511a5a69f381bfdf017f4d66c',
'john@nowhere.com',
'1233842115',
'This is really nice'
].join(PushEventProcessor::PUSH_EVENT_GIT_OUTPUT_SEPARATOR_ESCAPED) + "\n"
git.stubs(:log).returns(output*3)
@processor.stubs(:git).returns(git)
@processor.stubs(:user).returns(users(:johan))
end
def stub_git_show
git = mock
output = [
"a9934c1d3a56edfa8f45e5f157869874c8dc2c34",
"john@nowhere.com",
"1233842115",
"Whoops, deleting the tag"
].join(PushEventProcessor::PUSH_EVENT_GIT_OUTPUT_SEPARATOR_ESCAPED)
git.stubs(:show).returns(output)
@processor.stubs(:git).returns(git)
end
context "Generating commit summaries for web hooks" do
setup {
@processor = PushEventProcessor.new
@processor.user = users(:moe)
@push_event = PushEventProcessor::EventForLogging.new
@commit_event = PushEventProcessor::EventForLogging.new
@commit_event.email = "marius@gitorious.org"
@commit_event.identifier = "ffac"
@commit_event.commit_time = 1.day.ago
@commit_event.event_type = Action::COMMIT
@commit_event.message = "A single commit"
@commit_event.commit_details = {}
@push_event.commits = [@commit_event]
commit_summary = "000 fff refs/heads/master"
@processor.parse_git_spec(commit_summary)
@repository = repositories(:johans)
@processor.repository = @repository
}
should "calculate the correct refs" do
assert_equal "000", @processor.oldrev
assert_equal "fff", @processor.newrev
assert_equal "refs/heads/master", @processor.revname
end
should "not trigger any hooks if repository has none" do
@processor.expects(:trigger_hook).never
@processor.trigger_hooks(Array(@push_event))
end
should "trigger hook for each event" do
@repository.hooks.create(:user => @processor.user, :url => "http://postbin.org/")
@processor.expects(:trigger_hook).once
@processor.trigger_hooks(Array(@push_event))
end
should "trigger payload generation" do
@processor.expects(:generate_hook_payload)
@processor.trigger_hook(@push_event)
end
should "generate the correct payload" do
result = @processor.generate_hook_payload(@push_event)
assert_not_nil result[:ref]
assert_not_nil result[:after]
assert_not_nil result[:before]
assert_not_nil result[:commits]
assert_not_nil result[:repository][:url]
end
end
# describe 'with stubbing towards a live repo' do
# before(:each) do
# @repo = Grit::Repo.new("/Users/marius/tmp/clone")
# @processor.stubs(:git).returns(@repo.git)
# end
#
# it 'should get decent output from git log' do
# @processor.process_push_from_commit_summary "b808ca5eb8ab40a9fdc3489f9f83f6cf6e726a61 abf17983b01f716f34ee10b3f74f14fe7f3bf4ed refs/heads/master"
# assert_equal 1, @processor.events.size
# assert_equal 'marius.mathiesen@gmail.com', @processor.events.first.email
# assert_equal 'Adding some stuff', @processor.events.first.message
# end
# end
end