tikiwiki/packages/tiki-pkg-tikimanager/gitonomy/gitlib/tests/Gitonomy/Git/Tests/HooksTest.php

206 lines
5.6 KiB
PHP
Raw Permalink Normal View History

2023-11-20 21:52:04 +01:00
<?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');
}
}
}