Test enhancements

This commit is contained in:
Philipp Holzer 2018-11-01 13:44:47 +01:00
parent 70f9d3c596
commit 83ead5ec48
No known key found for this signature in database
GPG key ID: 517BE60E2CE5C8A5
12 changed files with 154 additions and 71 deletions

View file

@ -34,7 +34,7 @@ class BaseObject
/** /**
* Set the app * Set the app
* *
* @param object $app App * @param App $app App
* *
* @return void * @return void
*/ */

View file

@ -5,13 +5,9 @@
namespace Friendica\Test; namespace Friendica\Test;
use Friendica\App;
use Friendica\BaseObject;
use Friendica\Core\Config;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use PHPUnit\DbUnit\DataSet\YamlDataSet; use PHPUnit\DbUnit\DataSet\YamlDataSet;
use PHPUnit\DbUnit\TestCaseTrait; use PHPUnit\DbUnit\TestCaseTrait;
use PHPUnit\Framework\TestCase;
use PHPUnit_Extensions_Database_DB_IDatabaseConnection; use PHPUnit_Extensions_Database_DB_IDatabaseConnection;
require_once __DIR__ . '/../boot.php'; require_once __DIR__ . '/../boot.php';
@ -19,7 +15,7 @@ require_once __DIR__ . '/../boot.php';
/** /**
* Abstract class used by tests that need a database. * Abstract class used by tests that need a database.
*/ */
abstract class DatabaseTest extends TestCase abstract class DatabaseTest extends MockedTest
{ {
use TestCaseTrait; use TestCaseTrait;

18
tests/MockedTest.php Normal file
View file

@ -0,0 +1,18 @@
<?php
namespace Friendica\Test;
use PHPUnit\Framework\TestCase;
/**
* This class verifies each mock after each call
*/
abstract class MockedTest extends TestCase
{
protected function tearDown()
{
\Mockery::close();
parent::tearDown();
}
}

View file

@ -27,11 +27,6 @@ trait AppMockTrait
*/ */
public function mockApp($root) public function mockApp($root)
{ {
// simply returning the input when using L10n::t()
$l10nMock = \Mockery::mock('alias:Friendica\Core\L10n');
$l10nMock->shouldReceive('t')
->andReturnUsing(function ($arg) { return $arg; });
$this->mockConfigGet('system', 'theme', 'testtheme'); $this->mockConfigGet('system', 'theme', 'testtheme');
// Mocking App and most used functions // Mocking App and most used functions

View file

@ -49,4 +49,24 @@ trait DBAMockTrait
->times($times) ->times($times)
->andReturn($return); ->andReturn($return);
} }
/**
* Mocking DBA::fetchFirst()
*
* @param string $arg The argument of fetchFirst
* @param bool $return True, if the DB is connected, otherwise false
* @param null|int $times How often the method will get used
*/
public function mockFetchFirst($arg, $return = true, $times = null)
{
if (!isset($this->dbaMock)) {
$this->dbaMock = \Mockery::mock('alias:Friendica\Database\DBA');
}
$this->dbaMock
->shouldReceive('fetchFirst')
->with($arg)
->times($times)
->andReturn($return);
}
} }

View file

@ -0,0 +1,45 @@
<?php
namespace Friendica\Test\Util;
use Mockery\MockInterface;
trait L10nMockTrait
{
/**
* @var MockInterface The interface for L10n mocks
*/
private $l10nMock;
/**
* Mocking the 'L10n::t()' method
*
* @param null|string $input Either an input (string) or null for EVERY input is possible
* @param null|int $times How often will it get called
* @param null|string $return Either an return (string) or null for return the input
*/
public function mockL10nT($input = null, $times = null, $return = null)
{
if (!isset($this->l10nMock)) {
$this->l10nMock = \Mockery::mock('alias:Friendica\Core\L10n');
}
$with = isset($input) ? $input : \Mockery::any();
$return = isset($return) ? $return : $with;
if ($return instanceof \Mockery\Matcher\Any) {
$this->l10nMock
->shouldReceive('t')
->with($with)
->times($times)
->andReturnUsing(function($arg) { return $arg; });
} else {
$this->l10nMock
->shouldReceive('t')
->with($with)
->times($times)
->andReturn($return);
}
}
}

View file

@ -3,16 +3,20 @@
namespace Friendica\Test\src\App; namespace Friendica\Test\src\App;
use Friendica\App\Mode; use Friendica\App\Mode;
use Friendica\Test\MockedTest;
use Friendica\Test\Util\ConfigMockTrait;
use Friendica\Test\Util\DBAMockTrait;
use Friendica\Test\Util\VFSTrait; use Friendica\Test\Util\VFSTrait;
use PHPUnit\Framework\TestCase;
/** /**
* @runTestsInSeparateProcesses * @runTestsInSeparateProcesses
* @preserveGlobalState disabled * @preserveGlobalState disabled
*/ */
class ModeTest extends TestCase class ModeTest extends MockedTest
{ {
use VFSTrait; use VFSTrait;
use DBAMockTrait;
use ConfigMockTrait;
public function setUp() public function setUp()
{ {
@ -48,10 +52,7 @@ class ModeTest extends TestCase
public function testWithoutDatabase() public function testWithoutDatabase()
{ {
$dba = \Mockery::mock('alias:Friendica\Database\DBA'); $this->mockConnected(false, 1);
$dba
->shouldReceive('connected')
->andReturn(false);
$mode = new Mode($this->root->url()); $mode = new Mode($this->root->url());
$mode->determine(); $mode->determine();
@ -65,14 +66,8 @@ class ModeTest extends TestCase
public function testWithoutDatabaseSetup() public function testWithoutDatabaseSetup()
{ {
$dba = \Mockery::mock('alias:Friendica\Database\DBA'); $this->mockConnected(true, 1);
$dba $this->mockFetchFirst('SHOW TABLES LIKE \'config\'', false, 1);
->shouldReceive('connected')
->andReturn(true);
$dba
->shouldReceive('fetchFirst')
->with('SHOW TABLES LIKE \'config\'')
->andReturn(false);
$mode = new Mode($this->root->url()); $mode = new Mode($this->root->url());
$mode->determine(); $mode->determine();
@ -85,20 +80,9 @@ class ModeTest extends TestCase
public function testWithMaintenanceMode() public function testWithMaintenanceMode()
{ {
$dba = \Mockery::mock('alias:Friendica\Database\DBA'); $this->mockConnected(true, 1);
$dba $this->mockFetchFirst('SHOW TABLES LIKE \'config\'', true, 1);
->shouldReceive('connected') $this->mockConfigGet('system', 'maintenance', true, 1);
->andReturn(true);
$dba
->shouldReceive('fetchFirst')
->with('SHOW TABLES LIKE \'config\'')
->andReturn(true);
$conf = \Mockery::mock('alias:Friendica\Core\Config');
$conf
->shouldReceive('get')
->with('system', 'maintenance')
->andReturn(true);
$mode = new Mode($this->root->url()); $mode = new Mode($this->root->url());
$mode->determine(); $mode->determine();
@ -112,20 +96,9 @@ class ModeTest extends TestCase
public function testNormalMode() public function testNormalMode()
{ {
$dba = \Mockery::mock('alias:Friendica\Database\DBA'); $this->mockConnected(true, 1);
$dba $this->mockFetchFirst('SHOW TABLES LIKE \'config\'', true, 1);
->shouldReceive('connected') $this->mockConfigGet('system', 'maintenance', false, 1);
->andReturn(true);
$dba
->shouldReceive('fetchFirst')
->with('SHOW TABLES LIKE \'config\'')
->andReturn(true);
$conf = \Mockery::mock('alias:Friendica\Core\Config');
$conf
->shouldReceive('get')
->with('system', 'maintenance')
->andReturn(false);
$mode = new Mode($this->root->url()); $mode = new Mode($this->root->url());
$mode->determine(); $mode->determine();

View file

@ -38,7 +38,7 @@ class BaseObjectTest extends TestCase
*/ */
public function testSetApp() public function testSetApp()
{ {
$app = new App(__DIR__.'/../'); $app = new App(__DIR__ . '/../../');
$this->assertNull($this->baseObject->setApp($app)); $this->assertNull($this->baseObject->setApp($app));
$this->assertEquals($app, $this->baseObject->getApp()); $this->assertEquals($app, $this->baseObject->getApp());
} }

View file

@ -5,6 +5,7 @@ namespace Friendica\Test\src\Core\Console;
use Friendica\Core\Console\AutomaticInstallation; use Friendica\Core\Console\AutomaticInstallation;
use Friendica\Test\Util\DBAMockTrait; use Friendica\Test\Util\DBAMockTrait;
use Friendica\Test\Util\DBStructureMockTrait; use Friendica\Test\Util\DBStructureMockTrait;
use Friendica\Test\Util\L10nMockTrait;
use Friendica\Test\Util\RendererMockTrait; use Friendica\Test\Util\RendererMockTrait;
use org\bovigo\vfs\vfsStream; use org\bovigo\vfs\vfsStream;
use org\bovigo\vfs\vfsStreamFile; use org\bovigo\vfs\vfsStreamFile;
@ -16,6 +17,7 @@ use org\bovigo\vfs\vfsStreamFile;
*/ */
class AutomaticInstallationConsoleTest extends ConsoleTest class AutomaticInstallationConsoleTest extends ConsoleTest
{ {
use L10nMockTrait;
use DBAMockTrait; use DBAMockTrait;
use DBStructureMockTrait; use DBStructureMockTrait;
use RendererMockTrait; use RendererMockTrait;
@ -51,6 +53,8 @@ class AutomaticInstallationConsoleTest extends ConsoleTest
$this->db_pass = getenv('MYSQL_PASSWORD'); $this->db_pass = getenv('MYSQL_PASSWORD');
$this->mockConfigGet('config', 'php_path', false); $this->mockConfigGet('config', 'php_path', false);
$this->mockL10nT();
} }
/** /**

View file

@ -3,24 +3,48 @@
// this is in the same namespace as Install for mocking 'function_exists' // this is in the same namespace as Install for mocking 'function_exists'
namespace Friendica\Core; namespace Friendica\Core;
use Friendica\Test\MockedTest;
use Friendica\Test\Util\L10nMockTrait;
use Friendica\Test\Util\VFSTrait; use Friendica\Test\Util\VFSTrait;
use PHPUnit\Framework\TestCase;
/** /**
* @runTestsInSeparateProcesses * @runTestsInSeparateProcesses
* @preserveGlobalState disabled * @preserveGlobalState disabled
*/ */
class InstallerTest extends TestCase class InstallerTest extends MockedTest
{ {
use VFSTrait; use VFSTrait;
use L10nMockTrait;
public function setUp() public function setUp()
{ {
parent::setUp(); // TODO: Change the autogenerated stub parent::setUp();
$this->setUpVfsDir(); $this->setUpVfsDir();
} }
/**
* Mocking the L10n::t() calls for the function checks
*/
private function mockFunctionL10TCalls()
{
$this->mockL10nT('Apache mod_rewrite module', 1);
$this->mockL10nT('PDO or MySQLi PHP module', 1);
$this->mockL10nT('libCurl PHP module', 1);
$this->mockL10nT('Error: libCURL PHP module required but not installed.', 1);
$this->mockL10nT('XML PHP module', 1);
$this->mockL10nT('GD graphics PHP module', 1);
$this->mockL10nT('Error: GD graphics PHP module with JPEG support required but not installed.', 1);
$this->mockL10nT('OpenSSL PHP module', 1);
$this->mockL10nT('Error: openssl PHP module required but not installed.', 1);
$this->mockL10nT('mb_string PHP module', 1);
$this->mockL10nT('Error: mb_string PHP module required but not installed.', 1);
$this->mockL10nT('iconv PHP module', 1);
$this->mockL10nT('Error: iconv PHP module required but not installed.', 1);
$this->mockL10nT('POSIX PHP module', 1);
$this->mockL10nT('Error: POSIX PHP module required but not installed.', 1);
}
private function assertCheckExist($position, $title, $help, $status, $required, $assertionArray) private function assertCheckExist($position, $title, $help, $status, $required, $assertionArray)
{ {
$this->assertArraySubset([$position => [ $this->assertArraySubset([$position => [
@ -87,66 +111,73 @@ class InstallerTest extends TestCase
*/ */
public function testCheckFunctions() public function testCheckFunctions()
{ {
$this->setFunctions(['curl_init' => false]); $this->mockFunctionL10TCalls();
$this->setFunctions(['curl_init' => false, 'imagecreatefromjpeg' => true]);
$install = new Installer(); $install = new Installer();
$this->assertFalse($install->checkFunctions()); $this->assertFalse($install->checkFunctions());
$this->assertCheckExist(3, $this->assertCheckExist(3,
L10n::t('libCurl PHP module'), 'libCurl PHP module',
L10n::t('Error: libCURL PHP module required but not installed.'), 'Error: libCURL PHP module required but not installed.',
false, false,
true, true,
$install->getChecks()); $install->getChecks());
$this->mockFunctionL10TCalls();
$this->setFunctions(['imagecreatefromjpeg' => false]); $this->setFunctions(['imagecreatefromjpeg' => false]);
$install = new Installer(); $install = new Installer();
$this->assertFalse($install->checkFunctions()); $this->assertFalse($install->checkFunctions());
$this->assertCheckExist(4, $this->assertCheckExist(4,
L10n::t('GD graphics PHP module'), 'GD graphics PHP module',
L10n::t('Error: GD graphics PHP module with JPEG support required but not installed.'), 'Error: GD graphics PHP module with JPEG support required but not installed.',
false, false,
true, true,
$install->getChecks()); $install->getChecks());
$this->mockFunctionL10TCalls();
$this->setFunctions(['openssl_public_encrypt' => false]); $this->setFunctions(['openssl_public_encrypt' => false]);
$install = new Installer(); $install = new Installer();
$this->assertFalse($install->checkFunctions()); $this->assertFalse($install->checkFunctions());
$this->assertCheckExist(5, $this->assertCheckExist(5,
L10n::t('OpenSSL PHP module'), 'OpenSSL PHP module',
L10n::t('Error: openssl PHP module required but not installed.'), 'Error: openssl PHP module required but not installed.',
false, false,
true, true,
$install->getChecks()); $install->getChecks());
$this->mockFunctionL10TCalls();
$this->setFunctions(['mb_strlen' => false]); $this->setFunctions(['mb_strlen' => false]);
$install = new Installer(); $install = new Installer();
$this->assertFalse($install->checkFunctions()); $this->assertFalse($install->checkFunctions());
$this->assertCheckExist(6, $this->assertCheckExist(6,
L10n::t('mb_string PHP module'), 'mb_string PHP module',
L10n::t('Error: mb_string PHP module required but not installed.'), 'Error: mb_string PHP module required but not installed.',
false, false,
true, true,
$install->getChecks()); $install->getChecks());
$this->mockFunctionL10TCalls();
$this->setFunctions(['iconv_strlen' => false]); $this->setFunctions(['iconv_strlen' => false]);
$install = new Installer(); $install = new Installer();
$this->assertFalse($install->checkFunctions()); $this->assertFalse($install->checkFunctions());
$this->assertCheckExist(7, $this->assertCheckExist(7,
L10n::t('iconv PHP module'), 'iconv PHP module',
L10n::t('Error: iconv PHP module required but not installed.'), 'Error: iconv PHP module required but not installed.',
false, false,
true, true,
$install->getChecks()); $install->getChecks());
$this->mockFunctionL10TCalls();
$this->setFunctions(['posix_kill' => false]); $this->setFunctions(['posix_kill' => false]);
$install = new Installer(); $install = new Installer();
$this->assertFalse($install->checkFunctions()); $this->assertFalse($install->checkFunctions());
$this->assertCheckExist(8, $this->assertCheckExist(8,
L10n::t('POSIX PHP module'), 'POSIX PHP module',
L10n::t('Error: POSIX PHP module required but not installed.'), 'Error: POSIX PHP module required but not installed.',
false, false,
true, true,
$install->getChecks()); $install->getChecks());
$this->mockFunctionL10TCalls();
$this->setFunctions([ $this->setFunctions([
'curl_init' => true, 'curl_init' => true,
'imagecreatefromjpeg' => true, 'imagecreatefromjpeg' => true,
@ -308,13 +339,14 @@ class InstallerTest extends TestCase
public function testImagickNotInstalled() public function testImagickNotInstalled()
{ {
$this->setClasses(['Imagick' => false]); $this->setClasses(['Imagick' => false]);
$this->mockL10nT('ImageMagick PHP extension is not installed');
$install = new Installer(); $install = new Installer();
// even there is no supported type, Imagick should return true (because it is not required) // even there is no supported type, Imagick should return true (because it is not required)
$this->assertTrue($install->checkImagick()); $this->assertTrue($install->checkImagick());
$this->assertCheckExist(0, $this->assertCheckExist(0,
L10n::t('ImageMagick PHP extension is not installed'), 'ImageMagick PHP extension is not installed',
'', '',
false, false,
false, false,