@@ -15,6 +15,7 @@ class DBReset
|
||||
{
|
||||
$config = config('Database');
|
||||
$dbConfig = $config->{self::DB_GROUP} ?? [];
|
||||
self::assertSafeTestDatabase($config->default ?? [], $dbConfig);
|
||||
|
||||
try {
|
||||
$db = Database::connect(self::DB_GROUP);
|
||||
@@ -35,14 +36,38 @@ class DBReset
|
||||
|
||||
$db->disableForeignKeyChecks();
|
||||
|
||||
$tables = $db->listTables();
|
||||
$tables = $db->resetDataCache()->listTables();
|
||||
|
||||
foreach ($tables as $table) {
|
||||
if (!in_array($table, self::$excludeTables)) {
|
||||
if (!in_array($table, self::$excludeTables, true) && $db->tableExists($table, false)) {
|
||||
$db->query('TRUNCATE TABLE ' . $db->escapeIdentifiers($table));
|
||||
}
|
||||
}
|
||||
|
||||
$db->enableForeignKeyChecks();
|
||||
}
|
||||
|
||||
private static function assertSafeTestDatabase(array $defaultConfig, array $testConfig): void
|
||||
{
|
||||
$defaultDatabase = (string) ($defaultConfig['database'] ?? '');
|
||||
$testDatabase = (string) ($testConfig['database'] ?? '');
|
||||
|
||||
if ($testDatabase === '') {
|
||||
throw new \RuntimeException('Refusing to reset database: tests database name is empty.');
|
||||
}
|
||||
|
||||
if ($defaultDatabase !== '' && $testDatabase === $defaultDatabase) {
|
||||
throw new \RuntimeException(sprintf(
|
||||
'Refusing to reset database "%s": tests database matches the default application database.',
|
||||
$testDatabase
|
||||
));
|
||||
}
|
||||
|
||||
if (! preg_match('/(^test_|_test$|^tests$|^alrahma_test$)/i', $testDatabase)) {
|
||||
throw new \RuntimeException(sprintf(
|
||||
'Refusing to reset database "%s": test database names must clearly identify a test database.',
|
||||
$testDatabase
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ abstract class ModelCrudTestCase extends CIUnitTestCase
|
||||
protected function assertModelCanInsertAndRetrieve(string $modelClass): void
|
||||
{
|
||||
$model = $this->newModel($modelClass);
|
||||
$this->assertModelFieldsExist($model);
|
||||
$record = $this->fakeModelRecord($model);
|
||||
$id = $this->primaryKeyValue($record, $model->primaryKey);
|
||||
|
||||
@@ -32,6 +33,7 @@ abstract class ModelCrudTestCase extends CIUnitTestCase
|
||||
protected function assertModelCanUpdate(string $modelClass): void
|
||||
{
|
||||
$model = $this->newModel($modelClass);
|
||||
$this->assertModelFieldsExist($model);
|
||||
$record = $this->fakeModelRecord($model);
|
||||
$id = $this->primaryKeyValue($record, $model->primaryKey);
|
||||
$updateData = $this->updateData($model, $record);
|
||||
@@ -42,6 +44,7 @@ abstract class ModelCrudTestCase extends CIUnitTestCase
|
||||
protected function assertModelCanDelete(string $modelClass): void
|
||||
{
|
||||
$model = $this->newModel($modelClass);
|
||||
$this->assertModelFieldsExist($model);
|
||||
$record = $this->fakeModelRecord($model);
|
||||
$id = $this->primaryKeyValue($record, $model->primaryKey);
|
||||
|
||||
@@ -89,13 +92,34 @@ abstract class ModelCrudTestCase extends CIUnitTestCase
|
||||
|
||||
protected function fakeModelRecord(Model $model): array|object
|
||||
{
|
||||
if (! Database::connect('tests')->tableExists($model->table)) {
|
||||
$this->markTestSkipped(sprintf('Table %s is not present in the migrated test schema.', $model->table));
|
||||
}
|
||||
|
||||
return fake($model, $this->fabricatorOverrides($model));
|
||||
}
|
||||
|
||||
protected function assertModelFieldsExist(Model $model): void
|
||||
{
|
||||
$db = Database::connect('tests');
|
||||
|
||||
$this->assertTrue(
|
||||
$db->tableExists($model->table, false),
|
||||
sprintf('%s maps to table "%s", but that table is not present in the migrated test schema.', $model::class, $model->table)
|
||||
);
|
||||
|
||||
$databaseFields = $db->getFieldNames($model->table);
|
||||
|
||||
foreach ($model->allowedFields as $field) {
|
||||
$this->assertContains(
|
||||
$field,
|
||||
$databaseFields,
|
||||
sprintf(
|
||||
'%s allows field "%s", but table "%s" does not contain it.',
|
||||
$model::class,
|
||||
$field,
|
||||
$model->table
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
protected function fabricatorOverrides(Model $model): array
|
||||
{
|
||||
$overrides = [];
|
||||
@@ -184,9 +208,7 @@ abstract class ModelCrudTestCase extends CIUnitTestCase
|
||||
|
||||
private function newModel(string $modelClass): Model
|
||||
{
|
||||
if (! class_exists($modelClass)) {
|
||||
$this->markTestSkipped(sprintf('Model %s is not part of the application.', $modelClass));
|
||||
}
|
||||
$this->assertTrue(class_exists($modelClass), sprintf('Model %s is not part of the application.', $modelClass));
|
||||
|
||||
$model = new $modelClass();
|
||||
|
||||
|
||||
@@ -29,6 +29,16 @@ foreach ($requiredEnv as $name) {
|
||||
}
|
||||
}
|
||||
|
||||
$testDatabase = (string) getenv('TEST_DB_NAME');
|
||||
|
||||
if (! preg_match('/(^test_|_test$|^tests$|^alrahma_test$)/i', $testDatabase)) {
|
||||
fwrite(
|
||||
STDERR,
|
||||
"Refusing to import baseline into {$testDatabase}: TEST_DB_NAME must clearly identify a test database.\n"
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
|
||||
|
||||
$db = new mysqli(
|
||||
|
||||
Reference in New Issue
Block a user