206 lines
5.6 KiB
PHP
206 lines
5.6 KiB
PHP
|
<?php
|
||
|
|
||
|
/**
|
||
|
* This file is part of Gitonomy.
|
||
|
*
|
||
|
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
|
||
|
* (c) Julien DIDIER <genzo.wm@gmail.com>
|
||
|
*
|
||
|
* This source file is subject to the MIT license that is bundled
|
||
|
* with this source code in the file LICENSE.
|
||
|
*/
|
||
|
|
||
|
namespace Gitonomy\Git\Tests;
|
||
|
|
||
|
use Gitonomy\Git\Exception\InvalidArgumentException;
|
||
|
use Gitonomy\Git\Exception\LogicException;
|
||
|
|
||
|
class HooksTest extends AbstractTest
|
||
|
{
|
||
|
private static $symlinkOnWindows = null;
|
||
|
|
||
|
/**
|
||
|
* @beforeClass
|
||
|
*/
|
||
|
public static function setUpWindows()
|
||
|
{
|
||
|
if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
|
||
|
self::$symlinkOnWindows = true;
|
||
|
$originDir = tempnam(sys_get_temp_dir(), 'sl');
|
||
|
$targetDir = tempnam(sys_get_temp_dir(), 'sl');
|
||
|
if (true !== @symlink($originDir, $targetDir)) {
|
||
|
$report = error_get_last();
|
||
|
if (is_array($report) && false !== strpos($report['message'], 'error code(1314)')) {
|
||
|
self::$symlinkOnWindows = false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public function hookPath($repository, $hook)
|
||
|
{
|
||
|
return $repository->getGitDir().'/hooks/'.$hook;
|
||
|
}
|
||
|
|
||
|
public function touchHook($repository, $hook, $content = '')
|
||
|
{
|
||
|
$path = $this->hookPath($repository, $hook);
|
||
|
file_put_contents($path, $content);
|
||
|
|
||
|
return $path;
|
||
|
}
|
||
|
|
||
|
public function assertHasHook($repository, $hook)
|
||
|
{
|
||
|
$file = $this->hookPath($repository, $hook);
|
||
|
|
||
|
$this->assertTrue($repository->getHooks()->has($hook), "hook $hook in repository");
|
||
|
|
||
|
$this->assertFileExists($file, "Hook $hook is present");
|
||
|
}
|
||
|
|
||
|
public function assertNoHook($repository, $hook)
|
||
|
{
|
||
|
$file = $this->hookPath($repository, $hook);
|
||
|
|
||
|
$this->assertFalse($repository->getHooks()->has($hook), "No hook $hook in repository");
|
||
|
|
||
|
if (method_exists($this, 'assertFileDoesNotExist')) {
|
||
|
$this->assertFileDoesNotExist($file, "Hook $hook is not present");
|
||
|
} else {
|
||
|
$this->assertFileNotExists($file, "Hook $hook is not present");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @dataProvider provideFoobar
|
||
|
*/
|
||
|
public function testHas($repository)
|
||
|
{
|
||
|
$this->assertNoHook($repository, 'foo');
|
||
|
$this->touchHook($repository, 'foo');
|
||
|
$this->assertHasHook($repository, 'foo');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @dataProvider provideFoobar
|
||
|
*/
|
||
|
public function testGet_InvalidName_ThrowsException($repository)
|
||
|
{
|
||
|
$this->expectException(InvalidArgumentException::class);
|
||
|
|
||
|
$repository->getHooks()->get('foo');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @dataProvider provideFoobar
|
||
|
*/
|
||
|
public function testGet($repository)
|
||
|
{
|
||
|
$this->touchHook($repository, 'foo', 'foobar');
|
||
|
|
||
|
$this->assertEquals('foobar', $repository->getHooks()->get('foo'));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @dataProvider provideFoobar
|
||
|
*/
|
||
|
public function testSymlink($repository)
|
||
|
{
|
||
|
$this->markAsSkippedIfSymlinkIsMissing();
|
||
|
|
||
|
$file = $this->touchHook($repository, 'bar', 'barbarbar');
|
||
|
$repository->getHooks()->setSymlink('foo', $file);
|
||
|
|
||
|
$this->assertTrue(is_link($this->hookPath($repository, 'foo')), 'foo hook is a symlink');
|
||
|
|
||
|
$this->assertEquals(
|
||
|
str_replace('\\', '/', $file),
|
||
|
str_replace('\\', '/', readlink($this->hookPath($repository, 'foo'))),
|
||
|
'target of symlink is correct'
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @dataProvider provideFoobar
|
||
|
*/
|
||
|
public function testSymlink_WithExisting_ThrowsLogicException($repository)
|
||
|
{
|
||
|
$this->expectException(LogicException::class);
|
||
|
|
||
|
$this->markAsSkippedIfSymlinkIsMissing();
|
||
|
|
||
|
$file = $this->hookPath($repository, 'target-symlink');
|
||
|
$fooFile = $this->hookPath($repository, 'foo');
|
||
|
|
||
|
file_put_contents($file, 'foobar');
|
||
|
touch($fooFile);
|
||
|
|
||
|
$repository->getHooks()->setSymlink('foo', $file);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @dataProvider provideFoobar
|
||
|
*/
|
||
|
public function testSet($repository)
|
||
|
{
|
||
|
$file = $this->hookPath($repository, 'foo');
|
||
|
$repository->getHooks()->set('foo', 'bar');
|
||
|
|
||
|
$this->assertEquals('bar', file_get_contents($file), 'Hook content is correct');
|
||
|
|
||
|
$perms = fileperms($file);
|
||
|
$this->assertEquals(defined('PHP_WINDOWS_VERSION_BUILD') ? 0666 : 0777, $perms & 0777, 'Hook permissions are correct');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @dataProvider provideFoobar
|
||
|
*/
|
||
|
public function testSet_Existing_ThrowsLogicException($repository)
|
||
|
{
|
||
|
$repository->getHooks()->set('foo', 'bar');
|
||
|
|
||
|
$this->expectException(LogicException::class);
|
||
|
|
||
|
$repository->getHooks()->set('foo', 'bar');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @dataProvider provideFoobar
|
||
|
*/
|
||
|
public function testRemove($repository)
|
||
|
{
|
||
|
$file = $this->hookPath($repository, 'foo');
|
||
|
touch($file);
|
||
|
|
||
|
$repository->getHooks()->remove('foo');
|
||
|
|
||
|
if (method_exists($this, 'assertFileDoesNotExist')) {
|
||
|
$this->assertFileDoesNotExist($file);
|
||
|
} else {
|
||
|
$this->assertFileNotExists($file);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @dataProvider provideFoobar
|
||
|
*/
|
||
|
public function testRemove_NotExisting_ThrowsLogicException($repository)
|
||
|
{
|
||
|
$this->expectException(LogicException::class);
|
||
|
|
||
|
$repository->getHooks()->remove('foo');
|
||
|
}
|
||
|
|
||
|
private function markAsSkippedIfSymlinkIsMissing()
|
||
|
{
|
||
|
if (!function_exists('symlink')) {
|
||
|
$this->markTestSkipped('symlink is not supported');
|
||
|
}
|
||
|
|
||
|
if (defined('PHP_WINDOWS_VERSION_MAJOR') && false === self::$symlinkOnWindows) {
|
||
|
$this->markTestSkipped('symlink requires "Create symbolic links" privilege on windows');
|
||
|
}
|
||
|
}
|
||
|
}
|