Revert "Merge remote-tracking branch 'OpensourcePOS/master' into fix-unit-test-failures" and test-standardization commit (#4770)

These landed on master by accident via a local branch that was
mistakenly created tracking OpensourcePOS/master directly, rather than
pushed as its own branch. Reverting to restore master to its prior
state; the reverted work will come back through a proper PR instead.

This reverts commit 00bf4cb8af.
This reverts commit 37cc1b15e7.

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
objecttothisandClaude Sonnet 5 authored and GitHub committed 2026-10-22 16:43:32 +04:00
1 parent 00bf4cb8af
commit 0015b7575c
55 files changed
+201 -278

No files matched your search

-46
View File
@@ -28,52 +28,6 @@ This document provides guidance for AI agents working on the Open Source Point o
- Tests must pass before submitting changes
- **One test file per class under test.** A controller, model, library, or helper gets exactly one test file covering all of its behavior — `Item_kits.php` → `tests/Controllers/Item_kitsTest.php` (or `Item_kitsControllerTest.php`, matching this codebase's existing `*ControllerTest.php` suffix for controllers), `Sale_lib.php` → `tests/Libraries/Sale_libTest.php`, etc. Do not create feature- or endpoint-scoped test files alongside a class's main test file (e.g. no `Item_kitsBarcodeTest.php` next to `Item_kitsControllerTest.php`) — add the new test methods to the existing file for that class instead. If no test file exists yet for the class, create the one canonical file rather than a narrowly-scoped one.
- **Name test methods as `test{MethodUnderTest}_{Behavior}`.** `PascalCase` the method under test, then an underscore, then a short behavior phrase — `testPostSave_RejectsNegativeTaxPercent`, `testSaveLocale_AcceptsValidReferenceCodeMinMax`. Start the behavior with a verb: `Accepts`/`Requires` for valid or boundary cases, `Rejects` for invalid ones. The name should read as a self-documenting sentence and needs no docblock.
- **Resetting the test database (full migration reset, not just `$refresh`).** When a test class needs the `ospos_tests` schema fully dropped and re-migrated from scratch (e.g. so `ospos_permissions`/`app_config` get freshly seeded), `use Tests\Support\DatabaseBootstrapTrait;` and call `$this->resetDatabaseOnce()` as the first line of `setUp()`, before `parent::setUp()`:
```php
use Tests\Support\DatabaseBootstrapTrait;
class FooTest extends CIUnitTestCase
{
use DatabaseTestTrait;
use DatabaseBootstrapTrait;
protected $migrate = true;
protected $migrateOnce = true;
protected $seedOnce = true;
protected $refresh = false;
protected $namespace = null;
protected function setUp(): void
{
$this->resetDatabaseOnce();
parent::setUp();
// ...
}
}
```
`DatabaseBootstrapTrait` (`tests/Support/DatabaseBootstrapTrait.php`) wraps `TestDatabaseBootstrapSeeder::reset()` with a per-class static guard so it only runs once per test class. Do **not** reinvent this with a local `private static bool $doneBootstrap` flag, `setUpBeforeClass()`, or `Config::seeder($this->DBGroup)->call('App\Database\Seeds\TestDatabaseBootstrapSeeder')` followed by a manual `Config::connect($this->DBGroup)->close()`/`resetDataCache()` in the test file — those are the old patterns the trait replaces, and the manual version reintroduces the exact stale-connection bug `TestDatabaseBootstrapSeeder::reset()` already fixes internally. Only add this trait to test classes that actually touch the real test database (`DatabaseTestTrait` users) — pure unit tests that mock everything don't need it.
If a test class reads `config(OSPOS::class)->settings` for real (not mocking it out), also call `config(OSPOS::class)->update_settings();` right after `parent::setUp();` to force a fresh settings read post-reset. See `tests/Controllers/ReportsControllerTest.php` for that shape.
- **Mocking OSPOS config settings.** When a test needs `config(OSPOS::class)->settings` to return fixed values instead of reading from the database, `use Tests\Support\OsposConfigFixtureTrait;` and call `$this->injectOsposSettings([...])` instead of manually constructing `new OSPOS()` + `Factories::injectMock('config', OSPOS::class, $ospos)`:
```php
use Tests\Support\OsposConfigFixtureTrait;
class FooTest extends CIUnitTestCase
{
use OsposConfigFixtureTrait;
protected function setUp(): void
{
parent::setUp();
$this->injectOsposSettings([
'number_locale' => 'en_US',
'currency_decimals' => 2,
]);
}
}
```
`OSPOS::getDefaultSettings()` is `private` and only covers a handful of keys, so it is not a usable base to merge onto — each test must supply the exact settings it depends on. Use this trait regardless of whether the test also uses `DatabaseBootstrapTrait`.
## Build
@@ -25,7 +25,7 @@ class Migration_Initial_Schema extends Migration
public function up(): void
{
helper('migration');
executeScript(APPPATH . 'Database/Migrations/sqlscripts/initial_schema.sql', false, $this->db);
executeScript(APPPATH . 'Database/Migrations/sqlscripts/initial_schema.sql');
}
/**
@@ -42,7 +42,7 @@ class Migration_Upgrade_To_3_1_1 extends Migration
}
}
if (!executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.0.2_to_3.1.1.sql', false, $this->db)) {
if (!executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.0.2_to_3.1.1.sql')) {
throw new DatabaseException('Migration script 3.0.2_to_3.1.1.sql failed. Check logs for details.');
}
@@ -12,7 +12,7 @@ class Migration_Upgrade_To_3_2_0 extends Migration
public function up(): void
{
helper('migration');
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.1.1_to_3.2.0.sql', false, $this->db);
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.1.1_to_3.2.0.sql');
}
/**
@@ -12,7 +12,7 @@ class Migration_Upgrade_To_3_2_1 extends Migration
public function up(): void
{
helper('migration');
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.2.0_to_3.2.1.sql', false, $this->db);
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.2.0_to_3.2.1.sql');
}
/**
@@ -12,7 +12,7 @@ class Migration_Attributes extends Migration
public function up(): void
{
helper('migration');
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_attributes.sql', false, $this->db);
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_attributes.sql');
}
/**
@@ -12,7 +12,7 @@ class Migration_Upgrade_To_3_3_0 extends Migration
public function up(): void
{
helper('migration');
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.2.1_to_3.3.0.sql', false, $this->db);
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.2.1_to_3.3.0.sql');
}
/**
@@ -17,7 +17,7 @@ class Migration_IndiaGST extends Migration
// If number of entries is greater than zero then the tax data needs to be migrated
helper('migration');
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_indiagst.sql', false, $this->db);
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_indiagst.sql');
$count_of_tax_codes = $this->get_count_of_tax_code_entries();
@@ -12,7 +12,7 @@ class Migration_IndiaGST1 extends Migration
public function up(): void
{
helper('migration');
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_indiagst1.sql', false, $this->db);
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_indiagst1.sql');
}
/**
@@ -12,7 +12,7 @@ class Migration_IndiaGST2 extends Migration
public function up(): void
{
helper('migration');
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_indiagst2.sql', false, $this->db);
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_indiagst2.sql');
}
/**
@@ -12,7 +12,7 @@ class Migration_decimal_attribute_type extends Migration
public function up(): void
{
helper('migration');
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_decimal_attribute_type.sql', false, $this->db);
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_decimal_attribute_type.sql');
}
/**
@@ -12,7 +12,7 @@ class Migration_add_iso_4217 extends Migration
public function up(): void
{
helper('migration');
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_add_iso_4217.sql', false, $this->db);
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_add_iso_4217.sql');
}
/**
@@ -12,7 +12,7 @@ class Migration_PaymentTracking extends Migration
public function up(): void
{
helper('migration');
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_paymenttracking.sql', false, $this->db);
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_paymenttracking.sql');
}
/**
@@ -12,7 +12,7 @@ class Migration_RefundTracking extends Migration
public function up(): void
{
helper(['migration', 'locale']);
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_refundtracking.sql', false, $this->db);
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_refundtracking.sql');
// Add missing cash_refund amounts to payments table
$decimals = totals_decimals();
@@ -12,7 +12,7 @@ class Migration_DBFix extends Migration
public function up(): void
{
helper('migration');
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_dbfix.sql', false, $this->db);
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_dbfix.sql');
}
/**
@@ -12,7 +12,7 @@ class Migration_fix_attribute_datetime extends Migration
public function up(): void
{
helper('migration');
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_fix_attribute_datetime.sql', false, $this->db);
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_fix_attribute_datetime.sql');
}
/**
@@ -12,7 +12,7 @@ class Migration_PaymentDateFix extends Migration
public function up(): void
{
helper('migration');
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.3.2_paymentdatefix.sql', false, $this->db);
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.3.2_paymentdatefix.sql');
}
/**
@@ -12,7 +12,7 @@ class Migration_SalesChangePrice extends Migration
public function up(): void
{
helper('migration');
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.3.2_saleschangeprice.sql', false, $this->db);
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.3.2_saleschangeprice.sql');
}
/**
@@ -12,7 +12,7 @@ class Migration_modify_attr_links_constraint extends Migration
public function up(): void
{
helper('migration');
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.3.2_modify_attr_links_constraint.sql', false, $this->db);
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.3.2_modify_attr_links_constraint.sql');
}
/**
@@ -12,7 +12,7 @@ class Migration_add_item_kit_number extends Migration
public function up(): void
{
helper('migration');
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.3.3_add_kits_item_number.sql', false, $this->db);
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.3.3_add_kits_item_number.sql');
}
/**
@@ -12,7 +12,7 @@ class Migration_modify_session_datatype extends Migration
public function up(): void
{
helper('migration');
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.3.4_modify_session_datatype.sql', false, $this->db);
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.3.4_modify_session_datatype.sql');
}
/**
@@ -113,7 +113,7 @@ class Migration_database_optimizations extends Migration
}
$this->db->transComplete();
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.4.0_database_optimizations.sql', false, $this->db);
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.4.0_database_optimizations.sql');
log_message('info', 'Finished migrating database optimizations.');
}
@@ -27,7 +27,7 @@ class ConvertToCI4 extends Migration
{
helper('migration');
if (!executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.4.0_CI4Conversion.sql', false, $this->db)) {
if (!executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.4.0_CI4Conversion.sql')) {
throw new DatabaseException('Migration script 3.4.0_CI4Conversion.sql failed. Check logs for details.');
}
@@ -28,7 +28,7 @@ class fix_duplicate_attributes extends Migration
dropForeignKeyConstraints($foreignKeys, 'attribute_links');
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.4.0_attribute_links_unique_constraint.sql', false, $this->db);
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.4.0_attribute_links_unique_constraint.sql');
}
/**
@@ -12,7 +12,7 @@ class Migration_sessions_migration extends Migration
public function up(): void
{
helper('migration');
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.4.1_migrate_sessions_table.sql', false, $this->db);
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.4.1_migrate_sessions_table.sql');
}
/**
@@ -21,7 +21,7 @@ class AttributeLinksUniqueConstraint extends Migration
dropForeignKeyConstraints($foreignKeys, 'attribute_links');
dropColumnIfExists('ospos_attribute_links', 'generated_unique_column');
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.4.1_attribute_links_unique_constraint.sql', false, $this->db);
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.4.1_attribute_links_unique_constraint.sql');
}
/**
@@ -12,7 +12,7 @@ class Migration_MissingConfigKeys extends Migration
public function up(): void
{
helper('migration');
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.4.2_missing_config_keys.sql', true, $this->db);
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.4.2_missing_config_keys.sql', true);
}
/**
@@ -12,7 +12,7 @@ class Migration_NullableTaxCategoryId extends Migration
public function up(): void
{
helper('migration');
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.4.2_nullable_tax_category_id.sql', false, $this->db);
executeScript(APPPATH . 'Database/Migrations/sqlscripts/3.4.2_nullable_tax_category_id.sql');
}
/**
@@ -21,7 +21,7 @@ class Migration_Mysql84Utf8mb4Conversion extends Migration
}
$script = APPPATH . 'Database/Migrations/sqlscripts/3.4.3_mysql84_utf8mb4_conversion.sql';
if (!executeScript($script, false, $this->db)) {
if (!executeScript($script)) {
throw new RuntimeException('Failed to execute utf8mb4 conversion migration: ' . $script);
}
@@ -36,7 +36,7 @@ class TestDatabaseBootstrapSeeder extends Seeder
$serverConn->close();
// The application's shared 'tests' connection caches listTables()
// results in dataCache['table_names']. Because we dropped and
// results in dataCache['table_names'']. Because we dropped and
// recreated the schema on a SEPARATE server connection above, that
// cache is now stale. Reset it so subsequent listTables()/tableExists()
// calls re-query the server instead of trusting a dropped schema's table
+2 -3
View File
@@ -8,10 +8,9 @@ use Config\Database;
* Executes a SQL migration script.
* @param string $path Path to migration script.
* @param bool $withTransaction Whether to wrap execution in a transaction.
* @param BaseConnection|null $db Connection to use (defaults to the default connection).
* @return bool Whether the migration executed successfully.
*/
function executeScript(string $path, bool $withTransaction = false, ?BaseConnection $db = null): bool
function executeScript(string $path, bool $withTransaction = false): bool
{
$version = explode('_', basename($path, '.sql'), 2)[0];
log_message('info', "Migrating to $version (file: $path)");
@@ -19,7 +18,7 @@ function executeScript(string $path, bool $withTransaction = false, ?BaseConnect
$sqls = explode(';', file_get_contents($path));
array_pop($sqls);
$db ??= Database::connect();
$db = Database::connect();
if ($withTransaction) {
$db->transStart();
+4 -4
View File
@@ -7,9 +7,9 @@ use App\Models\Employee;
use CodeIgniter\Config\Factories;
use CodeIgniter\HTTP\IncomingRequest;
use CodeIgniter\Test\CIUnitTestCase;
use Config\OSPOS;
use Config\Services;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\Support\OsposConfigFixtureTrait;
/**
* Regression tests for the login validation flow in OSPOSRules::login_check().
@@ -19,8 +19,6 @@ use Tests\Support\OsposConfigFixtureTrait;
*/
class OSPOSRulesTest extends CIUnitTestCase
{
use OsposConfigFixtureTrait;
protected function tearDown(): void
{
Factories::reset();
@@ -140,7 +138,9 @@ class OSPOSRulesTest extends CIUnitTestCase
private function injectSettings(array $settings): void
{
$this->injectOsposSettings($settings);
$ospos = new OSPOS();
$ospos->settings = $settings;
Factories::injectMock('config', OSPOS::class, $ospos);
}
private function injectRequest(): void
+16 -7
View File
@@ -3,20 +3,19 @@
namespace Tests\Controllers;
use App\Models\Cashup;
use CodeIgniter\Config\Factories;
use CodeIgniter\Database\Config;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait;
use CodeIgniter\Test\FeatureTestTrait;
use Tests\Support\DatabaseBootstrapTrait;
use Config\OSPOS;
use Tests\Support\EmployeeFixtureTrait;
use Tests\Support\OsposConfigFixtureTrait;
class CashupControllerTest extends CIUnitTestCase
{
use DatabaseTestTrait;
use DatabaseBootstrapTrait;
use FeatureTestTrait;
use EmployeeFixtureTrait;
use OsposConfigFixtureTrait;
protected $migrate = true;
protected $migrateOnce = true;
@@ -24,24 +23,34 @@ class CashupControllerTest extends CIUnitTestCase
protected $refresh = false;
protected $namespace = null;
private static bool $doneBootstrap = false;
protected function setUp(): void
{
$this->resetDatabaseOnce();
if (self::$doneBootstrap === false) {
Config::seeder($this->DBGroup)->call('App\Database\Seeds\TestDatabaseBootstrapSeeder');
Config::connect($this->DBGroup)->close();
self::$doneBootstrap = true;
}
parent::setUp();
$this->injectOsposSettings([
$ospos = new OSPOS();
$ospos->settings = [
'company' => 'Test Co',
'dateformat' => 'Y-m-d',
'timeformat' => 'H:i:s',
'number_locale' => 'en_US',
'currency_decimals' => 2,
'thousands_separator' => ',',
]);
];
Factories::injectMock('config', OSPOS::class, $ospos);
}
protected function tearDown(): void
{
Factories::reset();
parent::tearDown();
}
+9 -3
View File
@@ -2,17 +2,16 @@
namespace Tests\Controllers;
use CodeIgniter\Database\Config;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait;
use CodeIgniter\Test\FeatureTestTrait;
use App\Models\Customer;
use App\Models\Employee;
use Tests\Support\DatabaseBootstrapTrait;
class CustomersCsvImportTest extends CIUnitTestCase
{
use DatabaseTestTrait;
use DatabaseBootstrapTrait;
use FeatureTestTrait;
protected $migrate = true;
@@ -23,12 +22,19 @@ class CustomersCsvImportTest extends CIUnitTestCase
protected Customer $customer;
protected Employee $employee;
private static bool $doneBootstrap = false;
protected function setUp(): void
{
// Reset the test database to a clean schema on the first test in this
// class so leftover customers with the same emails from prior runs
// cannot be rejected as duplicates by the import (check_email_exists).
$this->resetDatabaseOnce();
if (self::$doneBootstrap === false) {
Config::seeder($this->DBGroup)->call('App\Database\Seeds\TestDatabaseBootstrapSeeder');
Config::connect($this->DBGroup)->close();
self::$doneBootstrap = true;
}
parent::setUp();
// Reset any stale transaction state left on the shared in-process DB
@@ -2,19 +2,18 @@
namespace Tests\Controllers;
use CodeIgniter\Database\Config;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait;
use CodeIgniter\Test\FeatureTestTrait;
use CodeIgniter\Config\Services;
use App\Models\Employee;
use App\Models\Module;
use Tests\Support\DatabaseBootstrapTrait;
use Tests\Support\EmployeeFixtureTrait;
class EmployeesControllerTest extends CIUnitTestCase
{
use DatabaseTestTrait;
use DatabaseBootstrapTrait;
use FeatureTestTrait;
use EmployeeFixtureTrait;
@@ -25,13 +24,20 @@ class EmployeesControllerTest extends CIUnitTestCase
protected $priorDisallowGrantChange;
private static bool $doneBootstrap = false;
protected function setUp(): void
{
// Reset the test database to a known clean schema on the first test in
// this class so stale employees from prior runs (whose usernames are
// unique-key bound and whose grant sets leak into these assertions)
// cannot contaminate the assertions below.
$this->resetDatabaseOnce();
if (self::$doneBootstrap === false) {
Config::seeder($this->DBGroup)->call('App\Database\Seeds\TestDatabaseBootstrapSeeder');
Config::connect($this->DBGroup)->close();
self::$doneBootstrap = true;
}
parent::setUp();
// Reset any stale transaction state left on the shared in-process DB
+9 -3
View File
@@ -2,12 +2,12 @@
namespace Tests\Controllers;
use CodeIgniter\Database\Config;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait;
use CodeIgniter\Test\FeatureTestTrait;
use App\Models\Employee;
use RuntimeException;
use Tests\Support\DatabaseBootstrapTrait;
/**
* Test suite for Home controller password validation
@@ -19,7 +19,6 @@ use Tests\Support\DatabaseBootstrapTrait;
class HomeTest extends CIUnitTestCase
{
use DatabaseTestTrait;
use DatabaseBootstrapTrait;
use FeatureTestTrait;
protected $migrate = true;
@@ -27,9 +26,16 @@ class HomeTest extends CIUnitTestCase
protected $refresh = false;
protected $namespace = null;
private static bool $doneBootstrap = false;
protected function setUp(): void
{
$this->resetDatabaseOnce();
if (self::$doneBootstrap === false) {
Config::seeder($this->DBGroup)->call('App\Database\Seeds\TestDatabaseBootstrapSeeder');
Config::connect($this->DBGroup)->close();
self::$doneBootstrap = true;
}
parent::setUp();
}
+16 -7
View File
@@ -2,21 +2,20 @@
namespace Tests\Controllers;
use CodeIgniter\Config\Factories;
use CodeIgniter\Database\Config;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait;
use CodeIgniter\Test\FeatureTestTrait;
use App\Models\Item;
use App\Models\Item_kit;
use Config\OSPOS;
use Exception;
use Tests\Support\DatabaseBootstrapTrait;
use Tests\Support\OsposConfigFixtureTrait;
class ItemKitsControllerTest extends CIUnitTestCase
{
use DatabaseTestTrait;
use DatabaseBootstrapTrait;
use FeatureTestTrait;
use OsposConfigFixtureTrait;
protected $migrate = true;
protected $migrateOnce = true;
@@ -24,16 +23,24 @@ class ItemKitsControllerTest extends CIUnitTestCase
protected $refresh = false;
protected $namespace = null;
private static bool $doneBootstrap = false;
protected Item $item;
protected Item_kit $itemKit;
protected function setUp(): void
{
$this->resetDatabaseOnce();
if (self::$doneBootstrap === false) {
Config::seeder($this->DBGroup)->call('App\Database\Seeds\TestDatabaseBootstrapSeeder');
Config::connect($this->DBGroup)->close();
self::$doneBootstrap = true;
}
parent::setUp();
$this->injectOsposSettings([
$ospos = new OSPOS();
$ospos->settings = [
'company' => 'Test Co',
'barcode_content' => 'id',
'barcode_type' => 'C128',
@@ -49,7 +56,8 @@ class ItemKitsControllerTest extends CIUnitTestCase
'barcode_page_cellspacing' => 1,
'barcode_generate_if_empty' => 0,
'barcode_formats' => 'null',
]);
];
Factories::injectMock('config', OSPOS::class, $ospos);
$this->item = model(Item::class);
$this->itemKit = model(Item_kit::class);
@@ -57,6 +65,7 @@ class ItemKitsControllerTest extends CIUnitTestCase
protected function tearDown(): void
{
Factories::reset();
parent::tearDown();
}
+8 -3
View File
@@ -5,9 +5,9 @@ namespace Tests\Controllers;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait;
use CodeIgniter\Test\FeatureTestTrait;
use App\Database\Seeds\TestDatabaseBootstrapSeeder;
use App\Models\Employee;
use Config\OSPOS;
use Tests\Support\DatabaseBootstrapTrait;
/**
* Regression tests for the reports permission bypass
@@ -23,7 +23,6 @@ use Tests\Support\DatabaseBootstrapTrait;
class ReportsControllerTest extends CIUnitTestCase
{
use DatabaseTestTrait;
use DatabaseBootstrapTrait;
use FeatureTestTrait;
protected $migrate = true;
@@ -31,12 +30,18 @@ class ReportsControllerTest extends CIUnitTestCase
protected $refresh = false;
protected $namespace = null;
private static bool $doneBootstrap = false;
/**
* Set up test environment
*/
protected function setUp(): void
{
$this->resetDatabaseOnce();
if (self::$doneBootstrap === false) {
TestDatabaseBootstrapSeeder::reset();
self::$doneBootstrap = true;
}
parent::setUp();
+9 -3
View File
@@ -2,13 +2,13 @@
namespace Tests\Controllers;
use CodeIgniter\Database\Config;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait;
use CodeIgniter\Test\FeatureTestTrait;
use CodeIgniter\Config\Services;
use App\Models\Employee;
use Config\Database;
use Tests\Support\DatabaseBootstrapTrait;
use Tests\Support\ItemFixtureTrait;
use Tests\Support\EmployeeFixtureTrait;
use Tests\Support\SaleFixtureTrait;
@@ -28,7 +28,6 @@ use Tests\Support\SaleFixtureTrait;
class SalesControllerTest extends CIUnitTestCase
{
use DatabaseTestTrait;
use DatabaseBootstrapTrait;
use FeatureTestTrait;
use ItemFixtureTrait;
use EmployeeFixtureTrait;
@@ -40,9 +39,16 @@ class SalesControllerTest extends CIUnitTestCase
protected $refresh = false;
protected $namespace = null;
private static bool $doneBootstrap = false;
protected function setUp(): void
{
$this->resetDatabaseOnce();
if (self::$doneBootstrap === false) {
Config::seeder($this->DBGroup)->call('App\Database\Seeds\TestDatabaseBootstrapSeeder');
Config::connect($this->DBGroup)->close();
self::$doneBootstrap = true;
}
parent::setUp();
}
+9 -3
View File
@@ -2,16 +2,15 @@
namespace Tests\Controllers;
use CodeIgniter\Database\Config;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait;
use CodeIgniter\Test\FeatureTestTrait;
use Tests\Support\DatabaseBootstrapTrait;
use Tests\Support\EmployeeFixtureTrait;
class TaxesControllerTest extends CIUnitTestCase
{
use DatabaseTestTrait;
use DatabaseBootstrapTrait;
use FeatureTestTrait;
use EmployeeFixtureTrait;
@@ -21,9 +20,16 @@ class TaxesControllerTest extends CIUnitTestCase
protected $refresh = false;
protected $namespace = null;
private static $doneBootstrap = false;
protected function setUp(): void
{
$this->resetDatabaseOnce();
if (self::$doneBootstrap === false) {
Config::seeder($this->DBGroup)->call('App\Database\Seeds\TestDatabaseBootstrapSeeder');
Config::connect($this->DBGroup)->close();
self::$doneBootstrap = true;
}
parent::setUp();
}
+7 -5
View File
@@ -2,14 +2,13 @@
namespace Tests\Helpers;
use CodeIgniter\Config\Factories;
use CodeIgniter\Test\CIUnitTestCase;
use Config\OSPOS;
use stdClass;
use Tests\Support\OsposConfigFixtureTrait;
class GetItemDataRowTest extends CIUnitTestCase
{
use OsposConfigFixtureTrait;
protected function setUp(): void
{
parent::setUp();
@@ -21,7 +20,8 @@ class GetItemDataRowTest extends CIUnitTestCase
protected function injectSettings(array $overrides = []): void
{
$this->injectOsposSettings(array_merge([
$config = new OSPOS();
$config->settings = array_merge([
'multi_pack_enabled' => 0,
'use_destination_based_tax' => 0,
'number_locale' => 'en_US',
@@ -29,7 +29,9 @@ class GetItemDataRowTest extends CIUnitTestCase
'quantity_decimals' => 0,
'thousands_separator' => 1,
'currency_symbol' => '$',
], $overrides));
], $overrides);
Factories::injectMock('config', OSPOS::class, $config);
}
protected function makeItem(array $overrides = []): stdClass
+11 -4
View File
@@ -2,19 +2,26 @@
namespace Tests\Helpers;
use CodeIgniter\Config\Factories;
use CodeIgniter\Test\CIUnitTestCase;
use Tests\Support\OsposConfigFixtureTrait;
use Config\OSPOS;
class LocaleHelperTest extends CIUnitTestCase
{
use OsposConfigFixtureTrait;
protected function setUp(): void
{
parent::setUp();
require_once __DIR__ . '/../../app/Helpers/locale_helper.php';
$this->injectOsposSettings(['dateformat' => 'Y-m-d']);
$config = new OSPOS();
$config->settings = ['dateformat' => 'Y-m-d'];
Factories::injectMock('config', OSPOS::class, $config);
}
protected function tearDown(): void
{
Factories::reset();
parent::tearDown();
}
public function testValidDateReturnsTrue(): void
+5 -5
View File
@@ -14,12 +14,10 @@ use App\Models\Sale;
use App\Models\Stock_location;
use CodeIgniter\Config\Factories;
use CodeIgniter\Test\CIUnitTestCase;
use Tests\Support\OsposConfigFixtureTrait;
use Config\OSPOS;
class Sale_libPaymentTest extends CIUnitTestCase
{
use OsposConfigFixtureTrait;
private Sale_lib $saleLib;
protected int $priorBcscale;
@@ -37,13 +35,15 @@ class Sale_libPaymentTest extends CIUnitTestCase
bcscale(0);
// Inject mock OSPOS config so Sale_lib constructor and helpers don't need real settings
$this->injectOsposSettings([
$ospos = new OSPOS();
$ospos->settings = [
'cash_rounding_code' => '',
'cash_decimals' => 2,
'currency_decimals' => 2,
'tax_decimals' => 2,
'quantity_decimals' => 2,
]);
];
Factories::injectMock('config', OSPOS::class, $ospos);
// Inject stub models so model() calls in Sale_lib::__construct() skip DB
$stubMethods = ['__construct'];
+4 -6
View File
@@ -5,13 +5,12 @@ namespace Tests\Models;
use App\Models\Appconfig;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait;
use Config\Database;
use Config\OSPOS;
use Tests\Support\DatabaseBootstrapTrait;
class AppconfigTest extends CIUnitTestCase
{
use DatabaseTestTrait;
use DatabaseBootstrapTrait;
protected $migrate = true;
protected $migrateOnce = true;
@@ -20,11 +19,10 @@ class AppconfigTest extends CIUnitTestCase
protected $refresh = true;
protected $namespace = null;
protected function setUp(): void
public static function setUpBeforeClass(): void
{
$this->resetDatabaseOnce();
parent::setUp();
$seeder = Database::seeder('tests');
$seeder->call('TestDatabaseBootstrapSeeder');
}
private function appconfig(): Appconfig
+7 -4
View File
@@ -5,8 +5,8 @@ namespace Tests\Models;
use App\Models\Customer;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait;
use Config\Database;
use Tests\Support\ConcurrentDbRaceTrait;
use Tests\Support\DatabaseBootstrapTrait;
/**
* Regression tests: adjustRewardPoints() must apply
@@ -17,7 +17,6 @@ use Tests\Support\DatabaseBootstrapTrait;
class CustomerRewardPointsTest extends CIUnitTestCase
{
use DatabaseTestTrait;
use DatabaseBootstrapTrait;
use ConcurrentDbRaceTrait;
protected $migrate = true;
@@ -25,10 +24,14 @@ class CustomerRewardPointsTest extends CIUnitTestCase
protected $refresh = false;
protected $namespace = null;
public static function setUpBeforeClass(): void
{
$seeder = Database::seeder('tests');
$seeder->call('TestDatabaseBootstrapSeeder');
}
protected function setUp(): void
{
$this->resetDatabaseOnce();
parent::setUp();
}
-5
View File
@@ -5,25 +5,20 @@ namespace Tests\Models;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait;
use App\Models\Employee;
use Tests\Support\DatabaseBootstrapTrait;
use Tests\Support\EmployeeFixtureTrait;
class EmployeeTest extends CIUnitTestCase
{
use DatabaseTestTrait;
use DatabaseBootstrapTrait;
use EmployeeFixtureTrait;
protected $migrate = true;
protected $migrateOnce = true;
protected $seedOnce = true;
protected $refresh = false;
protected $namespace = null;
protected function setUp(): void
{
$this->resetDatabaseOnce();
parent::setUp();
}
+7 -4
View File
@@ -5,8 +5,8 @@ namespace Tests\Models;
use App\Models\Giftcard;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait;
use Config\Database;
use Tests\Support\ConcurrentDbRaceTrait;
use Tests\Support\DatabaseBootstrapTrait;
/**
* Regression tests: decrementGiftcardValue() must
@@ -17,7 +17,6 @@ use Tests\Support\DatabaseBootstrapTrait;
class GiftcardTest extends CIUnitTestCase
{
use DatabaseTestTrait;
use DatabaseBootstrapTrait;
use ConcurrentDbRaceTrait;
protected $migrate = true;
@@ -25,10 +24,14 @@ class GiftcardTest extends CIUnitTestCase
protected $refresh = false;
protected $namespace = null;
public static function setUpBeforeClass(): void
{
$seeder = Database::seeder('tests');
$seeder->call('TestDatabaseBootstrapSeeder');
}
protected function setUp(): void
{
$this->resetDatabaseOnce();
parent::setUp();
}
+8 -9
View File
@@ -5,7 +5,6 @@ namespace Tests\Models;
use App\Models\Item;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait;
use Tests\Support\DatabaseBootstrapTrait;
/**
* Regression coverage for mass assignment in bulk edit.
@@ -16,13 +15,15 @@ use Tests\Support\DatabaseBootstrapTrait;
class ItemBulkUpdateTest extends CIUnitTestCase
{
use DatabaseTestTrait;
use DatabaseBootstrapTrait;
protected $migrate = true;
protected $migrateOnce = true;
protected $seedOnce = true;
protected $refresh = false;
protected $namespace = null;
/**
* The schema is taken as it stands rather than migrated, so these tests run
* against an existing test database without dropping it. Every row created
* here is rolled back in tearDown().
*/
protected $migrate = false;
protected $refresh = false;
protected $namespace = null;
protected Item $item;
@@ -34,8 +35,6 @@ class ItemBulkUpdateTest extends CIUnitTestCase
protected function setUp(): void
{
$this->resetDatabaseOnce();
parent::setUp();
$this->item = model(Item::class);
+7 -4
View File
@@ -5,8 +5,8 @@ namespace Tests\Models;
use App\Models\Item_quantity;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait;
use Config\Database;
use Tests\Support\ConcurrentDbRaceTrait;
use Tests\Support\DatabaseBootstrapTrait;
use Tests\Support\ItemFixtureTrait;
/**
@@ -20,7 +20,6 @@ use Tests\Support\ItemFixtureTrait;
class ItemQuantityTest extends CIUnitTestCase
{
use DatabaseTestTrait;
use DatabaseBootstrapTrait;
use ConcurrentDbRaceTrait;
use ItemFixtureTrait;
@@ -31,10 +30,14 @@ class ItemQuantityTest extends CIUnitTestCase
private const LOCATION_ID = 1;
public static function setUpBeforeClass(): void
{
$seeder = Database::seeder('tests');
$seeder->call('TestDatabaseBootstrapSeeder');
}
protected function setUp(): void
{
$this->resetDatabaseOnce();
parent::setUp();
}
+8 -5
View File
@@ -5,29 +5,32 @@ namespace Tests\Models;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait;
use App\Models\Item;
use Config\Database;
use Config\OSPOS;
use Tests\Support\DatabaseBootstrapTrait;
use Tests\Support\ItemSearchFixtureTrait;
class ItemSearchTest extends CIUnitTestCase
{
use DatabaseTestTrait;
use DatabaseBootstrapTrait;
use ItemSearchFixtureTrait;
protected $migrate = true;
protected $migrateOnce = true;
protected $seed = '';
protected $seedOnce = true;
protected $refresh = false;
protected $refresh = true;
protected $namespace = null;
protected $item;
public static function setUpBeforeClass(): void
{
$seeder = Database::seeder('tests');
$seeder->call('TestDatabaseBootstrapSeeder');
}
protected function setUp(): void
{
$this->resetDatabaseOnce();
parent::setUp();
$this->item = model(Item::class);
+8 -5
View File
@@ -5,28 +5,31 @@ namespace Tests\Models;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait;
use App\Models\Item_taxes;
use Tests\Support\DatabaseBootstrapTrait;
use Config\Database;
use Tests\Support\ItemSearchFixtureTrait;
class ItemTaxesMultipleTest extends CIUnitTestCase
{
use DatabaseTestTrait;
use DatabaseBootstrapTrait;
use ItemSearchFixtureTrait;
protected $migrate = true;
protected $migrateOnce = true;
protected $seed = '';
protected $seedOnce = true;
protected $refresh = false;
protected $refresh = true;
protected $namespace = null;
protected $item_taxes;
public static function setUpBeforeClass(): void
{
$seeder = Database::seeder('tests');
$seeder->call('TestDatabaseBootstrapSeeder');
}
protected function setUp(): void
{
$this->resetDatabaseOnce();
parent::setUp();
$this->item_taxes = model(Item_taxes::class);
@@ -7,16 +7,13 @@ namespace Tests\Models\Reports;
use App\Models\Reports\Summary_taxes;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait;
use Tests\Support\DatabaseBootstrapTrait;
class Summary_taxes_test extends CIUnitTestCase
{
use DatabaseTestTrait;
use DatabaseBootstrapTrait;
protected $migrate = true;
protected $migrateOnce = true;
protected $seedOnce = true;
protected $refresh = false;
protected $namespace = null;
@@ -25,8 +22,6 @@ class Summary_taxes_test extends CIUnitTestCase
protected function setUp(): void
{
$this->resetDatabaseOnce();
parent::setUp();
$this->seedTestData();
}
+9 -3
View File
@@ -3,9 +3,9 @@
namespace Tests\Models;
use App\Models\Sale;
use CodeIgniter\Database\Config;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait;
use Tests\Support\DatabaseBootstrapTrait;
use Tests\Support\EmployeeFixtureTrait;
use Tests\Support\FailedQueryConnectionTrait;
use Tests\Support\ItemFixtureTrait;
@@ -18,7 +18,6 @@ use Tests\Support\ItemFixtureTrait;
class SaleTest extends CIUnitTestCase
{
use DatabaseTestTrait;
use DatabaseBootstrapTrait;
use EmployeeFixtureTrait;
use FailedQueryConnectionTrait;
use ItemFixtureTrait;
@@ -29,11 +28,18 @@ class SaleTest extends CIUnitTestCase
protected $refresh = false;
protected $namespace = null;
private static bool $doneBootstrap = false;
private const LOCATION_ID = 1;
protected function setUp(): void
{
$this->resetDatabaseOnce();
if (self::$doneBootstrap === false) {
Config::seeder($this->DBGroup)->call('App\Database\Seeds\TestDatabaseBootstrapSeeder');
Config::connect($this->DBGroup)->close();
self::$doneBootstrap = true;
}
parent::setUp();
}
-50
View File
@@ -1,50 +0,0 @@
<?php
namespace Tests\Support;
use App\Database\Seeds\TestDatabaseBootstrapSeeder;
use CodeIgniter\Database\Config;
/**
* Standard one-time-per-class database reset for DatabaseTestTrait tests.
*
* Call {@see self::resetDatabaseOnce()} as the first line of setUp(), before
* parent::setUp(). It drops and re-migrates the `tests` schema exactly once
* per test class (guarded by a per-class static, since PHP trait statics are
* independent per using-class) and closes the shared connection afterward so
* the migration run that follows reconnects against the freshly reset schema
* instead of reusing a connection whose state predates the reset.
*
* Usage:
*
* use Tests\Support\DatabaseBootstrapTrait;
*
* class FooTest extends CIUnitTestCase
* {
* use DatabaseTestTrait;
* use DatabaseBootstrapTrait;
*
* protected function setUp(): void
* {
* $this->resetDatabaseOnce();
*
* parent::setUp();
* }
* }
*/
trait DatabaseBootstrapTrait
{
private static bool $doneBootstrap = false;
protected function resetDatabaseOnce(): void
{
if (self::$doneBootstrap === true) {
return;
}
TestDatabaseBootstrapSeeder::reset();
Config::connect($this->DBGroup)->close();
self::$doneBootstrap = true;
}
}
-50
View File
@@ -1,50 +0,0 @@
<?php
namespace Tests\Support;
use CodeIgniter\Config\Factories;
use Config\OSPOS;
/**
* Shared helper for injecting a mocked OSPOS config into a test.
*
* Replaces the old per-file `$ospos = new OSPOS(); $ospos->settings = [...];
* Factories::injectMock(...)` block that was duplicated with slightly
* different settings arrays across many test files. Each test supplies the
* exact settings it depends on - OSPOS::getDefaultSettings() is private and
* only has a handful of keys, so it is not a usable base to merge onto.
*
* Usage:
*
* use Tests\Support\OsposConfigFixtureTrait;
*
* class FooTest extends CIUnitTestCase
* {
* use OsposConfigFixtureTrait;
*
* protected function setUp(): void
* {
* parent::setUp();
*
* $this->injectOsposSettings([
* 'invoice_enable' => false,
* 'number_locale' => 'en_US',
* ]);
* }
* }
*/
trait OsposConfigFixtureTrait
{
/**
* @param array<string, mixed> $settings
*/
protected function injectOsposSettings(array $settings): OSPOS
{
$ospos = new OSPOS();
$ospos->settings = $settings;
Factories::injectMock('config', OSPOS::class, $ospos);
return $ospos;
}
}