init commit
This commit is contained in:
222
plugins/xframework/common/Test.php
Normal file
222
plugins/xframework/common/Test.php
Normal file
@ -0,0 +1,222 @@
|
||||
<?php
|
||||
namespace XFramework;
|
||||
|
||||
/**
|
||||
* Roundcube Plus Framework plugin.
|
||||
*
|
||||
* This class provides the basis for plugin unit testing.
|
||||
*
|
||||
* Make sure @backupGlobals is set to disabled, otherwise you'll get the error:
|
||||
* "PDOException: You cannot serialize or unserialize PDO instances"
|
||||
* https://blogs.kent.ac.uk/webdev/2011/07/14/phpunit-and-unserialized-pdo-instances/
|
||||
*
|
||||
* Copyright 2016, Tecorama LLC.
|
||||
*
|
||||
* @license Commercial. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
ini_set('error_reporting', E_ERROR);
|
||||
ini_set('display_errors', '1');
|
||||
ini_set('display_startup_errors', '1');
|
||||
|
||||
require_once(__DIR__ . "/DatabaseMysql.php");
|
||||
require_once(__DIR__ . "/Input.php");
|
||||
require_once(__DIR__ . "/Format.php");
|
||||
|
||||
class Test extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public $rcmail = false;
|
||||
protected $input = false;
|
||||
protected $db = false;
|
||||
protected $userId = false;
|
||||
protected $class = false;
|
||||
protected $assets = [];
|
||||
protected $rcVersion;
|
||||
|
||||
public function __construct($name = null, array $data = [], $dataName = '')
|
||||
{
|
||||
$this->dbProvider = $_SERVER['ROUNDCUBE_TEST_DATABASE'];
|
||||
$this->rcVersion = $_SERVER['ROUNDCUBE_TEST_VERSION'] ?? false;
|
||||
|
||||
if (empty($this->rcVersion)) {
|
||||
exit("Error: Roundcube version not specified.");
|
||||
}
|
||||
|
||||
// start the session to prevent the headers already sent error during tests
|
||||
session_start();
|
||||
$_SESSION['x_unit_testing'] = true;
|
||||
|
||||
// set the server variables and include the roundcube framework
|
||||
$_SERVER['REMOTE_ADDR'] = "127.0.0.1";
|
||||
|
||||
// create the rcmail instance that will use config-test.inc.php
|
||||
// all the calls to xrc() will use this same instance
|
||||
$this->rcmail = \rcmail::get_instance(0, "test");
|
||||
|
||||
if (strpos($this->rcmail->config->get("db_dsnw"), "roundcube_test") === false) {
|
||||
exit("Error loading test config file. Link config-test.inc.php to the roundcube $this->rcVersion config directory.");
|
||||
}
|
||||
|
||||
$this->callMethod($this->rcmail, "startup");
|
||||
$_SERVER["HTTP_X_CSRF_TOKEN"] = $this->rcmail->get_request_token();
|
||||
|
||||
$this->input = xinput();
|
||||
$this->db = xdb();
|
||||
$this->format = xformat();
|
||||
|
||||
if (!($user = $this->db->row("users", ["user_id" => 1]))) {
|
||||
exit("Error loading user (33948554).");
|
||||
}
|
||||
|
||||
// emulate a logged in user
|
||||
$user['password'] = "";
|
||||
$user['active'] = "1";
|
||||
|
||||
$this->rcmail->set_user(new \rcube_user(null, $user));
|
||||
$this->userId = $this->rcmail->get_user_id();
|
||||
|
||||
parent::__construct($name, $data, $dataName);
|
||||
|
||||
// create and initialize the plugin class
|
||||
if (strpos(get_class($this), "X") === 0) {
|
||||
// convert camelcase to underscores, so XNewsFeedTest becomes xnews_feed
|
||||
$className = "x" . strtolower(preg_replace('/(?<!^)[A-Z]/', '_$0', substr(get_class($this), 1, -4)));
|
||||
$this->class = $this->getPluginClass($className);
|
||||
}
|
||||
}
|
||||
|
||||
public function getPluginClass(string $className)
|
||||
{
|
||||
require_once(__DIR__ . "/../../$className/$className.php");
|
||||
$class = new $className(\rcube_plugin_api::get_instance());
|
||||
$this->setProperty($class, "unitTest", true);
|
||||
$class->init();
|
||||
return $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls a protected/private method of a class.
|
||||
*
|
||||
* @param object &$object Instantiated object that we will run method on.
|
||||
* @param string $methodName Method name to call
|
||||
* @param array $parameters Array of parameters to pass into method.
|
||||
*
|
||||
* @return mixed Method return.
|
||||
*/
|
||||
public function callMethod($object, string $methodName, array $parameters = [])
|
||||
{
|
||||
is_array($parameters) || $parameters = [$parameters];
|
||||
$reflection = new \ReflectionClass(get_class($object));
|
||||
try {
|
||||
$method = $reflection->getMethod($methodName);
|
||||
$method->setAccessible(true);
|
||||
return $method->invokeArgs($object, $parameters);
|
||||
} catch (\ReflectionException $e) {
|
||||
exit("Reflection exception (28849932) " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a protected class property.
|
||||
*
|
||||
* @param object $object
|
||||
* @param string $property
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function setProperty($object, $property, $value)
|
||||
{
|
||||
$reflection = new \ReflectionObject($object);
|
||||
try {
|
||||
$refProperty = $reflection->getProperty($property);
|
||||
$refProperty->setAccessible(true);
|
||||
$refProperty->setValue($object, $value);
|
||||
} catch (\ReflectionException $e) {
|
||||
exit("Reflection exception (589085324) " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of a protected class property.
|
||||
*
|
||||
* @param object $object
|
||||
* @param string $property
|
||||
* @return mixed
|
||||
*/
|
||||
public function getProperty($object, $property)
|
||||
{
|
||||
$reflection = new \ReflectionObject($object);
|
||||
try {
|
||||
$refProperty = $reflection->getProperty($property);
|
||||
$refProperty->setAccessible(true);
|
||||
return $refProperty->getValue($object);
|
||||
} catch (\ReflectionException $e) {
|
||||
exit("Reflection exception (38908523) " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
protected function hasAsset($partialAssetString): bool
|
||||
{
|
||||
$assets = $this->class->rcmail->output->get_env("xassets");
|
||||
|
||||
if (!is_array($assets) || empty($assets)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($assets as $asset) {
|
||||
if (strpos($asset, $partialAssetString) !== false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function assertIncludesArray($fullArray, $partialArray)
|
||||
{
|
||||
$this->assertTrue(is_array($fullArray));
|
||||
$this->assertTrue(is_array($partialArray));
|
||||
$this->assertTrue(!empty($fullArray));
|
||||
$this->assertTrue(!empty($partialArray));
|
||||
|
||||
foreach ($partialArray as $key => $val) {
|
||||
$this->assertTrue(isset($fullArray[$key]));
|
||||
$this->assertEquals((string)$fullArray[$key], (string)$val);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected function assertPluginFiles()
|
||||
{
|
||||
$path = realpath(__DIR__ . "/../../" . get_class($this->class));
|
||||
|
||||
$this->assertFileExists("$path/CHANGE_LOG");
|
||||
$this->assertFileExists("$path/composer.json");
|
||||
$this->assertFileExists("$path/LICENSE");
|
||||
$this->assertFileExists("$path/README");
|
||||
|
||||
if ($this->getProperty($this->class, "hasConfig")) {
|
||||
$this->assertFileExists("$path/config.inc.php.dist");
|
||||
}
|
||||
|
||||
if ($this->getProperty($this->class, "hasLocalization")) {
|
||||
$this->assertLocalizationFiles();
|
||||
}
|
||||
}
|
||||
|
||||
protected function assertLocalizationFiles()
|
||||
{
|
||||
$dir = __DIR__ . "/../localization";
|
||||
$this->assertTrue(is_array($files = scandir($dir)));
|
||||
|
||||
foreach (array_diff($files, ["..", "."]) as $file) {
|
||||
$labels = false;
|
||||
include("$dir/$file");
|
||||
$this->assertTrue(is_array($labels));
|
||||
}
|
||||
}
|
||||
|
||||
protected function has($needle, $haystack): bool
|
||||
{
|
||||
return strpos($haystack, $needle) !== false;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user