This commit is contained in:
Markus
2022-04-28 09:40:10 +02:00
commit 795794f992
9586 changed files with 1146991 additions and 0 deletions

View File

@@ -0,0 +1,42 @@
<?php
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\Test\Mock;
use Config\App;
class MockAppConfig extends App
{
public $baseURL = 'http://example.com/';
public $uriProtocol = 'REQUEST_URI';
public $cookiePrefix = '';
public $cookieDomain = '';
public $cookiePath = '/';
public $cookieSecure = false;
public $cookieHTTPOnly = false;
public $cookieSameSite = 'Lax';
public $proxyIPs = '';
public $CSRFTokenName = 'csrf_test_name';
public $CSRFHeaderName = 'X-CSRF-TOKEN';
public $CSRFCookieName = 'csrf_cookie_name';
public $CSRFExpire = 7200;
public $CSRFRegenerate = true;
public $CSRFExcludeURIs = ['http://example.com'];
public $CSRFRedirect = false;
public $CSRFSameSite = 'Lax';
public $CSPEnabled = false;
public $defaultLocale = 'en';
public $negotiateLocale = false;
public $supportedLocales = [
'en',
'es',
];
}

View File

@@ -0,0 +1,26 @@
<?php
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\Test\Mock;
use Config\Autoload;
class MockAutoload extends Autoload
{
public $psr4 = [];
public $classmap = [];
public function __construct()
{
// Don't call the parent since we don't want the default mappings.
// parent::__construct();
}
}

View File

@@ -0,0 +1,18 @@
<?php
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\Test\Mock;
use CodeIgniter\Database\BaseBuilder;
class MockBuilder extends BaseBuilder
{
}

View File

@@ -0,0 +1,40 @@
<?php
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\Test\Mock;
use Config\App;
class MockCLIConfig extends App
{
public $baseURL = 'http://example.com/';
public $uriProtocol = 'REQUEST_URI';
public $cookiePrefix = '';
public $cookieDomain = '';
public $cookiePath = '/';
public $cookieSecure = false;
public $cookieHTTPOnly = false;
public $cookieSameSite = 'Lax';
public $proxyIPs = '';
public $CSRFTokenName = 'csrf_test_name';
public $CSRFCookieName = 'csrf_cookie_name';
public $CSRFExpire = 7200;
public $CSRFRegenerate = true;
public $CSRFExcludeURIs = ['http://example.com'];
public $CSRFSameSite = 'Lax';
public $CSPEnabled = false;
public $defaultLocale = 'en';
public $negotiateLocale = false;
public $supportedLocales = [
'en',
'es',
];
}

View File

@@ -0,0 +1,54 @@
<?php
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\Test\Mock;
use CodeIgniter\HTTP\CURLRequest;
/**
* Class MockCURLRequest
*
* Simply allows us to not actually call cURL during the
* test runs. Instead, we can set the desired output
* and get back the set options.
*/
class MockCURLRequest extends CURLRequest
{
public $curl_options;
protected $output = '';
public function setOutput($output)
{
$this->output = $output;
return $this;
}
protected function sendRequest(array $curlOptions = []): string
{
// Save so we can access later.
$this->curl_options = $curlOptions;
return $this->output;
}
// for testing purposes only
public function getBaseURI()
{
return $this->baseURI;
}
// for testing purposes only
public function getDelay()
{
return $this->delay;
}
}

View File

@@ -0,0 +1,297 @@
<?php
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\Test\Mock;
use Closure;
use CodeIgniter\Cache\CacheInterface;
use CodeIgniter\Cache\Handlers\BaseHandler;
use PHPUnit\Framework\Assert;
class MockCache extends BaseHandler implements CacheInterface
{
/**
* Mock cache storage.
*
* @var array
*/
protected $cache = [];
/**
* Expiration times.
*
* @var ?int[]
*/
protected $expirations = [];
/**
* If true, will not cache any data.
*
* @var bool
*/
protected $bypass = false;
/**
* Takes care of any handler-specific setup that must be done.
*/
public function initialize()
{
}
/**
* Attempts to fetch an item from the cache store.
*
* @param string $key Cache item name
*
* @return mixed
*/
public function get(string $key)
{
$key = static::validateKey($key, $this->prefix);
return array_key_exists($key, $this->cache) ? $this->cache[$key] : null;
}
/**
* Get an item from the cache, or execute the given Closure and store the result.
*
* @return mixed
*/
public function remember(string $key, int $ttl, Closure $callback)
{
$value = $this->get($key);
if ($value !== null) {
return $value;
}
$this->save($key, $value = $callback(), $ttl);
return $value;
}
/**
* Saves an item to the cache store.
*
* The $raw parameter is only utilized by Mamcache in order to
* allow usage of increment() and decrement().
*
* @param string $key Cache item name
* @param mixed $value the data to save
* @param int $ttl Time To Live, in seconds (default 60)
* @param bool $raw Whether to store the raw value.
*
* @return bool
*/
public function save(string $key, $value, int $ttl = 60, bool $raw = false)
{
if ($this->bypass) {
return false;
}
$key = static::validateKey($key, $this->prefix);
$this->cache[$key] = $value;
$this->expirations[$key] = $ttl > 0 ? time() + $ttl : null;
return true;
}
/**
* Deletes a specific item from the cache store.
*
* @return bool
*/
public function delete(string $key)
{
$key = static::validateKey($key, $this->prefix);
if (! isset($this->cache[$key])) {
return false;
}
unset($this->cache[$key], $this->expirations[$key]);
return true;
}
/**
* Deletes items from the cache store matching a given pattern.
*
* @return int
*/
public function deleteMatching(string $pattern)
{
$count = 0;
foreach (array_keys($this->cache) as $key) {
if (fnmatch($pattern, $key)) {
$count++;
unset($this->cache[$key], $this->expirations[$key]);
}
}
return $count;
}
/**
* Performs atomic incrementation of a raw stored value.
*
* @return bool
*/
public function increment(string $key, int $offset = 1)
{
$key = static::validateKey($key, $this->prefix);
$data = $this->cache[$key] ?: null;
if (empty($data)) {
$data = 0;
} elseif (! is_int($data)) {
return false;
}
return $this->save($key, $data + $offset);
}
/**
* Performs atomic decrementation of a raw stored value.
*
* @return bool
*/
public function decrement(string $key, int $offset = 1)
{
$key = static::validateKey($key, $this->prefix);
$data = $this->cache[$key] ?: null;
if (empty($data)) {
$data = 0;
} elseif (! is_int($data)) {
return false;
}
return $this->save($key, $data - $offset);
}
/**
* Will delete all items in the entire cache.
*
* @return bool
*/
public function clean()
{
$this->cache = [];
$this->expirations = [];
return true;
}
/**
* Returns information on the entire cache.
*
* The information returned and the structure of the data
* varies depending on the handler.
*
* @return string[] Keys currently present in the store
*/
public function getCacheInfo()
{
return array_keys($this->cache);
}
/**
* Returns detailed information about the specific item in the cache.
*
* @return array|null Returns null if the item does not exist, otherwise array<string, mixed>
* with at least the 'expire' key for absolute epoch expiry (or null).
*/
public function getMetaData(string $key)
{
// Misses return null
if (! array_key_exists($key, $this->expirations)) {
return null;
}
// Count expired items as a miss
if (is_int($this->expirations[$key]) && $this->expirations[$key] > time()) {
return null;
}
return ['expire' => $this->expirations[$key]];
}
/**
* Determine if the driver is supported on this system.
*/
public function isSupported(): bool
{
return true;
}
//--------------------------------------------------------------------
// Test Helpers
//--------------------------------------------------------------------
/**
* Instructs the class to ignore all
* requests to cache an item, and always "miss"
* when checked for existing data.
*
* @return $this
*/
public function bypass(bool $bypass = true)
{
$this->clean();
$this->bypass = $bypass;
return $this;
}
//--------------------------------------------------------------------
// Additional Assertions
//--------------------------------------------------------------------
/**
* Asserts that the cache has an item named $key.
* The value is not checked since storing false or null
* values is valid.
*/
public function assertHas(string $key)
{
Assert::assertNotNull($this->get($key), "The cache does not have an item named: `{$key}`");
}
/**
* Asserts that the cache has an item named $key with a value matching $value.
*
* @param mixed $value
*/
public function assertHasValue(string $key, $value = null)
{
$item = $this->get($key);
// Let assertHas handle throwing the error for consistency
// if the key is not found
if (empty($item)) {
$this->assertHas($key);
}
Assert::assertSame($value, $this->get($key), "The cached item `{$key}` does not equal match expectation. Found: " . print_r($value, true));
}
/**
* Asserts that the cache does NOT have an item named $key.
*/
public function assertMissing(string $key)
{
Assert::assertArrayNotHasKey($key, $this->cache, "The cached item named `{$key}` exists.");
}
}

View File

@@ -0,0 +1,22 @@
<?php
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\Test\Mock;
use CodeIgniter\CodeIgniter;
class MockCodeIgniter extends CodeIgniter
{
protected function callExit($code)
{
// Do not call exit() in testing.
}
}

View File

@@ -0,0 +1,32 @@
<?php
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
if (! function_exists('is_cli')) {
/**
* Is CLI?
*
* Test to see if a request was made from the command line.
* You can set the return value for testing.
*
* @param bool $newReturn return value to set
*/
function is_cli(?bool $newReturn = null): bool
{
// PHPUnit always runs via CLI.
static $returnValue = true;
if ($newReturn !== null) {
$returnValue = $newReturn;
}
return $returnValue;
}
}

View File

@@ -0,0 +1,233 @@
<?php
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\Test\Mock;
use CodeIgniter\CodeIgniter;
use CodeIgniter\Database\BaseConnection;
use CodeIgniter\Database\BaseResult;
use CodeIgniter\Database\Query;
class MockConnection extends BaseConnection
{
protected $returnValues = [];
public $database;
public $lastQuery;
public function shouldReturn(string $method, $return)
{
$this->returnValues[$method] = $return;
return $this;
}
/**
* Orchestrates a query against the database. Queries must use
* Database\Statement objects to store the query and build it.
* This method works with the cache.
*
* Should automatically handle different connections for read/write
* queries if needed.
*
* @param mixed ...$binds
*
* @return BaseResult|bool|Query
*
* @todo BC set $queryClass default as null in 4.1
*/
public function query(string $sql, $binds = null, bool $setEscapeFlags = true, string $queryClass = '')
{
$queryClass = str_replace('Connection', 'Query', static::class);
$query = new $queryClass($this);
$query->setQuery($sql, $binds, $setEscapeFlags);
if (! empty($this->swapPre) && ! empty($this->DBPrefix)) {
$query->swapPrefix($this->DBPrefix, $this->swapPre);
}
$startTime = microtime(true);
$this->lastQuery = $query;
// Run the query
if (false === ($this->resultID = $this->simpleQuery($query->getQuery()))) {
$query->setDuration($startTime, $startTime);
// @todo deal with errors
return false;
}
$query->setDuration($startTime);
// resultID is not false, so it must be successful
if ($query->isWriteType()) {
return true;
}
// query is not write-type, so it must be read-type query; return QueryResult
$resultClass = str_replace('Connection', 'Result', static::class);
return new $resultClass($this->connID, $this->resultID);
}
/**
* Connect to the database.
*
* @return mixed
*/
public function connect(bool $persistent = false)
{
$return = $this->returnValues['connect'] ?? true;
if (is_array($return)) {
// By removing the top item here, we can
// get a different value for, say, testing failover connections.
$return = array_shift($this->returnValues['connect']);
}
return $return;
}
/**
* Keep or establish the connection if no queries have been sent for
* a length of time exceeding the server's idle timeout.
*/
public function reconnect(): bool
{
return true;
}
/**
* Select a specific database table to use.
*
* @return mixed
*/
public function setDatabase(string $databaseName)
{
$this->database = $databaseName;
return $this;
}
/**
* Returns a string containing the version of the database being used.
*/
public function getVersion(): string
{
return CodeIgniter::CI_VERSION;
}
/**
* Executes the query against the database.
*
* @return mixed
*/
protected function execute(string $sql)
{
return $this->returnValues['execute'];
}
/**
* Returns the total number of rows affected by this query.
*/
public function affectedRows(): int
{
return 1;
}
/**
* Returns the last error code and message.
*
* Must return an array with keys 'code' and 'message':
*
* return ['code' => null, 'message' => null);
*/
public function error(): array
{
return [
'code' => 0,
'message' => '',
];
}
/**
* Insert ID
*/
public function insertID(): int
{
return $this->connID->insert_id;
}
/**
* Generates the SQL for listing tables in a platform-dependent manner.
*/
protected function _listTables(bool $constrainByPrefix = false): string
{
return '';
}
/**
* Generates a platform-specific query string so that the column names can be fetched.
*/
protected function _listColumns(string $table = ''): string
{
return '';
}
protected function _fieldData(string $table): array
{
return [];
}
protected function _indexData(string $table): array
{
return [];
}
protected function _foreignKeyData(string $table): array
{
return [];
}
/**
* Close the connection.
*/
protected function _close()
{
}
/**
* Begin Transaction
*/
protected function _transBegin(): bool
{
return true;
}
/**
* Commit Transaction
*/
protected function _transCommit(): bool
{
return true;
}
/**
* Rollback Transaction
*/
protected function _transRollback(): bool
{
return true;
}
}

View File

@@ -0,0 +1,40 @@
<?php
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\Test\Mock;
use CodeIgniter\Email\Email;
use CodeIgniter\Events\Events;
class MockEmail extends Email
{
/**
* Value to return from mocked send().
*
* @var bool
*/
public $returnValue = true;
public function send($autoClear = true)
{
if ($this->returnValue) {
$this->setArchiveValues();
if ($autoClear) {
$this->clear();
}
Events::trigger('email', $this->archive);
}
return $this->returnValue;
}
}

View File

@@ -0,0 +1,40 @@
<?php
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\Test\Mock;
use CodeIgniter\Events\Events;
/**
* Events
*/
class MockEvents extends Events
{
public function getListeners()
{
return self::$listeners;
}
public function getEventsFile()
{
return self::$files;
}
public function getSimulate()
{
return self::$simulate;
}
public function unInitialize()
{
static::$initialized = false;
}
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\Test\Mock;
use CodeIgniter\Log\Handlers\FileHandler;
/**
* Class MockFileLogger
*
* Extends FileHandler, exposing some inner workings
*/
class MockFileLogger extends FileHandler
{
/**
* Where would the log be written?
*/
public $destination;
public function __construct(array $config)
{
parent::__construct($config);
$this->handles = $config['handles'] ?? [];
$this->destination = $this->path . 'log-' . date('Y-m-d') . '.' . $this->fileExtension;
}
}

View File

@@ -0,0 +1,22 @@
<?php
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\Test\Mock;
use CodeIgniter\HTTP\IncomingRequest;
class MockIncomingRequest extends IncomingRequest
{
protected function detectURI($protocol, $baseURL)
{
// Do nothing...
}
}

View File

@@ -0,0 +1,56 @@
<?php
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\Test\Mock;
use CodeIgniter\Language\Language;
class MockLanguage extends Language
{
/**
* Stores the data that should be
* returned by the 'requireFile()' method.
*
* @var mixed
*/
protected $data;
/**
* Sets the data that should be returned by the
* 'requireFile()' method to allow easy overrides
* during testing.
*
* @return $this
*/
public function setData(string $file, array $data, ?string $locale = null)
{
$this->language[$locale ?? $this->locale][$file] = $data;
return $this;
}
/**
* Provides an override that allows us to set custom
* data to be returned easily during testing.
*/
protected function requireFile(string $path): array
{
return $this->data ?? [];
}
/**
* Arbitrarily turnoff internationalization support for testing
*/
public function disableIntlSupport()
{
$this->intlSupport = false;
}
}

View File

@@ -0,0 +1,101 @@
<?php
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\Test\Mock;
class MockLogger
{
/*
|--------------------------------------------------------------------------
| Error Logging Threshold
|--------------------------------------------------------------------------
|
| You can enable error logging by setting a threshold over zero. The
| threshold determines what gets logged. Any values below or equal to the
| threshold will be logged. Threshold options are:
|
| 0 = Disables logging, Error logging TURNED OFF
| 1 = Emergency Messages - System is unusable
| 2 = Alert Messages - Action Must Be Taken Immediately
| 3 = Critical Messages - Application component unavailable, unexpected exception.
| 4 = Runtime Errors - Don't need immediate action, but should be monitored.
| 5 = Warnings - Exceptional occurrences that are not errors.
| 6 = Notices - Normal but significant events.
| 7 = Info - Interesting events, like user logging in, etc.
| 8 = Debug - Detailed debug information.
| 9 = All Messages
|
| You can also pass an array with threshold levels to show individual error types
|
| array(1, 2, 3, 8) = Emergency, Alert, Critical, and Debug messages
|
| For a live site you'll usually enable Critical or higher (3) to be logged otherwise
| your log files will fill up very fast.
|
*/
public $threshold = 9;
/*
|--------------------------------------------------------------------------
| Date Format for Logs
|--------------------------------------------------------------------------
|
| Each item that is logged has an associated date. You can use PHP date
| codes to set your own date formatting
|
*/
public $dateFormat = 'Y-m-d';
/*
|--------------------------------------------------------------------------
| Log Handlers
|--------------------------------------------------------------------------
|
| The logging system supports multiple actions to be taken when something
| is logged. This is done by allowing for multiple Handlers, special classes
| designed to write the log to their chosen destinations, whether that is
| a file on the getServer, a cloud-based service, or even taking actions such
| as emailing the dev team.
|
| Each handler is defined by the class name used for that handler, and it
| MUST implement the CodeIgniter\Log\Handlers\HandlerInterface interface.
|
| The value of each key is an array of configuration items that are sent
| to the constructor of each handler. The only required configuration item
| is the 'handles' element, which must be an array of integer log levels.
| This is most easily handled by using the constants defined in the
| Psr\Log\LogLevel class.
|
| Handlers are executed in the order defined in this array, starting with
| the handler on top and continuing down.
|
*/
public $handlers = [
// File Handler
'Tests\Support\Log\Handlers\TestHandler' => [
// The log levels that this handler will handle.
'handles' => [
'critical',
'alert',
'emergency',
'debug',
'error',
'info',
'notice',
'warning',
],
// Logging Directory Path
'path' => '',
],
];
}

View File

@@ -0,0 +1,18 @@
<?php
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\Test\Mock;
use CodeIgniter\Database\Query;
class MockQuery extends Query
{
}

View File

@@ -0,0 +1,32 @@
<?php
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\Test\Mock;
use CodeIgniter\RESTful\ResourceController;
class MockResourceController extends ResourceController
{
public function getModel()
{
return $this->model;
}
public function getModelName()
{
return $this->modelName;
}
public function getFormat()
{
return $this->format;
}
}

View File

@@ -0,0 +1,35 @@
<?php
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\Test\Mock;
use CodeIgniter\API\ResponseTrait;
use CodeIgniter\RESTful\ResourcePresenter;
class MockResourcePresenter extends ResourcePresenter
{
use ResponseTrait;
public function getModel()
{
return $this->model;
}
public function getModelName()
{
return $this->modelName;
}
public function getFormat()
{
return $this->format;
}
}

View File

@@ -0,0 +1,39 @@
<?php
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\Test\Mock;
use CodeIgniter\HTTP\Response;
/**
* Class MockResponse
*/
class MockResponse extends Response
{
/**
* If true, will not write output. Useful during testing.
*
* @var bool
*/
protected $pretend = true;
// for testing
public function getPretend()
{
return $this->pretend;
}
// artificial error for testing
public function misbehave()
{
$this->statusCode = 0;
}
}

View File

@@ -0,0 +1,96 @@
<?php
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\Test\Mock;
use CodeIgniter\Database\BaseResult;
class MockResult extends BaseResult
{
/**
* Gets the number of fields in the result set.
*/
public function getFieldCount(): int
{
return 0;
}
/**
* Generates an array of column names in the result set.
*/
public function getFieldNames(): array
{
return [];
}
/**
* Generates an array of objects representing field meta-data.
*/
public function getFieldData(): array
{
return [];
}
/**
* Frees the current result.
*
* @return mixed
*/
public function freeResult()
{
}
/**
* Moves the internal pointer to the desired offset. This is called
* internally before fetching results to make sure the result set
* starts at zero.
*
* @param int $n
*
* @return mixed
*/
public function dataSeek($n = 0)
{
}
/**
* Returns the result set as an array.
*
* Overridden by driver classes.
*
* @return mixed
*/
protected function fetchAssoc()
{
}
/**
* Returns the result set as an object.
*
* Overridden by child classes.
*
* @param string $className
*
* @return object
*/
protected function fetchObject($className = 'stdClass')
{
return new $className();
}
/**
* Gets the number of fields in the result set.
*/
public function getNumRows(): int
{
return 0;
}
}

View File

@@ -0,0 +1,30 @@
<?php
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\Test\Mock;
use CodeIgniter\Security\Security;
class MockSecurity extends Security
{
protected function doSendCookie(): void
{
$_COOKIE['csrf_cookie_name'] = $this->hash;
}
protected function randomize(string $hash): string
{
$keyBinary = hex2bin('005513c290126d34d41bf41c5265e0f1');
$hashBinary = hex2bin($hash);
return bin2hex(($hashBinary ^ $keyBinary) . $keyBinary);
}
}

View File

@@ -0,0 +1,31 @@
<?php
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\Test\Mock;
use Config\Security as Security;
/**
* @deprecated
*
* @codeCoverageIgnore
*/
class MockSecurityConfig extends Security
{
public $tokenName = 'csrf_test_name';
public $headerName = 'X-CSRF-TOKEN';
public $cookieName = 'csrf_cookie_name';
public $expires = 7200;
public $regenerate = true;
public $redirect = false;
public $samesite = 'Lax';
public $excludeURIs = ['http://example.com'];
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\Test\Mock;
use CodeIgniter\Autoloader\FileLocator;
use CodeIgniter\Config\BaseService;
class MockServices extends BaseService
{
public $psr4 = [
'Tests/Support' => TESTPATH . '_support/',
];
public $classmap = [];
public function __construct()
{
// Don't call the parent since we don't want the default mappings.
// parent::__construct();
}
public static function locator(bool $getShared = true)
{
return new FileLocator(static::autoloader());
}
}

View File

@@ -0,0 +1,70 @@
<?php
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\Test\Mock;
use CodeIgniter\Cookie\Cookie;
use CodeIgniter\Session\Session;
/**
* Class MockSession
*
* Provides a safe way to test the Session class itself,
* that doesn't interact with the session or cookies at all.
*/
class MockSession extends Session
{
/**
* Holds our "cookie" data.
*
* @var Cookie[]
*/
public $cookies = [];
public $didRegenerate = false;
/**
* Sets the driver as the session handler in PHP.
* Extracted for easier testing.
*/
protected function setSaveHandler()
{
// session_set_save_handler($this->driver, true);
}
/**
* Starts the session.
* Extracted for testing reasons.
*/
protected function startSession()
{
// session_start();
$this->setCookie();
}
/**
* Takes care of setting the cookie on the client side.
* Extracted for testing reasons.
*/
protected function setCookie()
{
$expiration = $this->sessionExpiration === 0 ? 0 : time() + $this->sessionExpiration;
$this->cookie = $this->cookie->withValue(session_id())->withExpires($expiration);
$this->cookies[] = $this->cookie;
}
public function regenerate(bool $destroy = false)
{
$this->didRegenerate = true;
$_SESSION['__ci_last_regenerate'] = time();
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\Test\Mock;
use BadMethodCallException;
use CodeIgniter\View\Table;
class MockTable extends Table
{
// Override inaccessible protected method
public function __call($method, $params)
{
if (is_callable([$this, '_' . $method])) {
return call_user_func_array([$this, '_' . $method], $params);
}
throw new BadMethodCallException('Method ' . $method . ' was not found');
}
}