first commit

This commit is contained in:
CHIEFSOFT\ameye
2025-01-18 18:33:45 -05:00
commit e8d16deefd
684 changed files with 120708 additions and 0 deletions
+30
View File
@@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
/**
* 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 string $baseURL = 'http://example.com/';
public string $uriProtocol = 'REQUEST_URI';
public array $proxyIPs = [];
public bool $CSPEnabled = false;
public string $defaultLocale = 'en';
public bool $negotiateLocale = false;
public array $supportedLocales = [
'en',
'es',
];
}
+28
View File
@@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
/**
* 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();
}
}
+25
View File
@@ -0,0 +1,25 @@
<?php
declare(strict_types=1);
/**
* 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
{
protected $supportedIgnoreStatements = [
'update' => 'IGNORE',
'insert' => 'IGNORE',
'delete' => 'IGNORE',
];
}
+36
View File
@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
/**
* 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 string $baseURL = 'http://example.com/';
public string $uriProtocol = 'REQUEST_URI';
public array $proxyIPs = [];
public string $CSRFTokenName = 'csrf_test_name';
public string $CSRFCookieName = 'csrf_cookie_name';
public int $CSRFExpire = 7200;
public bool $CSRFRegenerate = true;
public $CSRFExcludeURIs = ['http://example.com'];
public string $CSRFSameSite = 'Lax';
public bool $CSPEnabled = false;
public string $defaultLocale = 'en';
public bool $negotiateLocale = false;
public array $supportedLocales = [
'en',
'es',
];
}
+58
View File
@@ -0,0 +1,58 @@
<?php
declare(strict_types=1);
/**
* 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
{
$this->response = clone $this->responseOrig;
// 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;
}
}
+307
View File
@@ -0,0 +1,307 @@
<?php
declare(strict_types=1);
/**
* 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 CodeIgniter\I18n\Time;
use PHPUnit\Framework\Assert;
class MockCache extends BaseHandler implements CacheInterface
{
/**
* Mock cache storage.
*
* @var array<string, mixed>
*/
protected $cache = [];
/**
* Expiration times.
*
* @var ?list<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.
*
* @return void
*/
public function initialize()
{
}
/**
* Attempts to fetch an item from the cache store.
*
* @param string $key Cache item name
*
* @return bool|null
*/
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 bool|null
*/
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)
*
* @return bool
*/
public function save(string $key, $value, int $ttl = 60)
{
if ($this->bypass) {
return false;
}
$key = static::validateKey($key, $this->prefix);
$this->cache[$key] = $value;
$this->expirations[$key] = $ttl > 0 ? Time::now()->getTimestamp() + $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 ($data === null) {
$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 ($data === null) {
$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 list<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::now()->getTimestamp()) {
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.
*
* @return void
*/
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
*
* @return void
*/
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 ($item === null) {
$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.
*
* @return void
*/
public function assertMissing(string $key)
{
Assert::assertArrayNotHasKey($key, $this->cache, "The cached item named `{$key}` exists.");
}
}
+31
View File
@@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
/**
* 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 ?string $context = 'web';
/**
* @param int $code
*
* @deprecated 4.4.0 No longer Used. Moved to index.php.
*/
protected function callExit($code)
{
// Do not call exit() in testing.
}
}
+34
View File
@@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
/**
* 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;
}
}
+258
View File
@@ -0,0 +1,258 @@
<?php
declare(strict_types=1);
/**
* 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;
/**
* @extends BaseConnection<object|resource, object|resource>
*/
class MockConnection extends BaseConnection
{
/**
* @var array{connect?: mixed, execute?: bool|object}
*/
protected $returnValues = [];
/**
* Database schema for Postgre and SQLSRV
*
* @var string
*/
protected $schema;
public $database;
public $lastQuery;
/**
* @param mixed $return
*
* @return $this
*/
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 ($this->swapPre !== '' && $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($sql)) {
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 bool
*/
public function setDatabase(string $databaseName)
{
$this->database = $databaseName;
return true;
}
/**
* 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 bool|object
*/
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.
*
* @param string|null $tableName If $tableName is provided will return only this table if exists.
*/
protected function _listTables(bool $constrainByPrefix = false, ?string $tableName = null): 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.
*
* @return void
*/
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;
}
}
+42
View File
@@ -0,0 +1,42 @@
<?php
declare(strict_types=1);
/**
* 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;
}
}
+42
View File
@@ -0,0 +1,42 @@
<?php
declare(strict_types=1);
/**
* 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;
}
}
+36
View File
@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
/**
* 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;
}
}
+20
View File
@@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
/**
* 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
{
}
+140
View File
@@ -0,0 +1,140 @@
<?php
declare(strict_types=1);
/**
* 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\CLI\InputOutput;
use CodeIgniter\Test\Filters\CITestStreamFilter;
use CodeIgniter\Test\PhpStreamWrapper;
use InvalidArgumentException;
use LogicException;
final class MockInputOutput extends InputOutput
{
/**
* String to be entered by the user.
*
* @var list<string>
*/
private array $inputs = [];
/**
* Output lines.
*
* @var array<int, string>
* @phpstan-var list<string>
*/
private array $outputs = [];
/**
* Sets user inputs.
*
* @param array<int, string> $inputs
* @phpstan-param list<string> $inputs
*/
public function setInputs(array $inputs): void
{
$this->inputs = $inputs;
}
/**
* Gets the item from the output array.
*
* @param int|null $index The output array index. If null, returns all output
* string. If negative int, returns the last $index-th
* item.
*/
public function getOutput(?int $index = null): string
{
if ($index === null) {
return implode('', $this->outputs);
}
if (array_key_exists($index, $this->outputs)) {
return $this->outputs[$index];
}
if ($index < 0) {
$i = count($this->outputs) + $index;
if (array_key_exists($i, $this->outputs)) {
return $this->outputs[$i];
}
}
throw new InvalidArgumentException(
'No such index in output: ' . $index . ', the last index is: '
. (count($this->outputs) - 1)
);
}
/**
* Returns the outputs array.
*/
public function getOutputs(): array
{
return $this->outputs;
}
private function addStreamFilters(): void
{
CITestStreamFilter::registration();
CITestStreamFilter::addOutputFilter();
CITestStreamFilter::addErrorFilter();
}
private function removeStreamFilters(): void
{
CITestStreamFilter::removeOutputFilter();
CITestStreamFilter::removeErrorFilter();
}
public function input(?string $prefix = null): string
{
if ($this->inputs === []) {
throw new LogicException(
'No input data. Specifiy input data with `MockInputOutput::setInputs()`.'
);
}
$input = array_shift($this->inputs);
$this->addStreamFilters();
PhpStreamWrapper::register();
PhpStreamWrapper::setContent($input);
$userInput = parent::input($prefix);
$this->outputs[] = CITestStreamFilter::$buffer . $input . PHP_EOL;
PhpStreamWrapper::restore();
$this->removeStreamFilters();
if ($input !== $userInput) {
throw new LogicException($input . '!==' . $userInput);
}
return $input;
}
public function fwrite($handle, string $string): void
{
$this->addStreamFilters();
parent::fwrite($handle, $string);
$this->outputs[] = CITestStreamFilter::$buffer;
$this->removeStreamFilters();
}
}
+58
View File
@@ -0,0 +1,58 @@
<?php
declare(strict_types=1);
/**
* 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;
}
}
+105
View File
@@ -0,0 +1,105 @@
<?php
declare(strict_types=1);
/**
* 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 Tests\Support\Log\Handlers\TestHandler;
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 server, 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
TestHandler::class => [
// The log levels that this handler will handle.
'handles' => [
'critical',
'alert',
'emergency',
'debug',
'error',
'info',
'notice',
'warning',
],
// Logging Directory Path
'path' => '',
],
];
}
+20
View File
@@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
/**
* 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
{
}
@@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
/**
* 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;
}
}
@@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
/**
* 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;
}
}
+41
View File
@@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
/**
* 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;
}
}
+103
View File
@@ -0,0 +1,103 @@
<?php
declare(strict_types=1);
/**
* 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;
use stdClass;
/**
* @extends BaseResult<object|resource, object|resource>
*/
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 void
*/
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 bool
*/
public function dataSeek($n = 0)
{
return true;
}
/**
* 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|stdClass
*/
protected function fetchObject($className = 'stdClass')
{
return new $className();
}
/**
* Gets the number of fields in the result set.
*/
public function getNumRows(): int
{
return 0;
}
}
+32
View File
@@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
/**
* 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);
}
}
+36
View File
@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
/**
* 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());
}
}
+73
View File
@@ -0,0 +1,73 @@
<?php
declare(strict_types=1);
/**
* 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\I18n\Time;
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 list<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->config->expiration === 0 ? 0 : Time::now()->getTimestamp() + $this->config->expiration;
$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::now()->getTimestamp();
}
}
+30
View File
@@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
/**
* 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');
}
}