Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: Models declared in the App namespace references the 'default' database group in Tests. #8073

Closed
sammyskills opened this issue Oct 22, 2023 · 5 comments · Fixed by #8077
Assignees
Labels
bug Verified issues on the current code behavior or pull requests that will fix them

Comments

@sammyskills
Copy link
Contributor

sammyskills commented Oct 22, 2023

PHP Version

8.2

CodeIgniter4 Version

4.4.2

CodeIgniter4 Installation Method

Composer (using codeigniter4/appstarter)

Which operating systems have you tested for this bug?

Windows

Which server did you use?

apache

Database

MariaDB 10.4.18

What happened?

When I try to run unit tests on models declared in the App namespace, the models only reference the default database and not the test database.

And when I try to comment the default database, I get the following error:

CodeIgniter\Database\Exceptions\DatabaseException: Unable to connect to the database.
Main connection [MySQLi]: Access denied for user ''@'localhost' (using password: NO)

Same thing happens even when the environment is set as TESTING, i.e. CI_ENVIRONMENT = testing in the .env file.

Steps to Reproduce

  1. Install Shield to a fresh CodeIgniter installation: composer require codeigniter4/shield. This is just to confirm that migrations run in the appropriate (test) database.

  2. Create a model (eg. SampleModel.php) via command line: php spark make:model sample --suffix --table sample_table

  3. Create a migration for the model: php spark make:migration create_sample_table and add fields for the up() method like so:

$this->forge->addField([
    'id'                    => ['type' => 'int', 'constraint' => 11, 'unsigned' => true, 'auto_increment' => true],
    'name'                  => ['type' => 'varchar', 'constraint' => 300],
    'description'           => ['type' => 'text', 'null' => true],
    'created_at'            => ['type' => 'datetime'],
    'updated_at'            => ['type' => 'datetime', 'null' => true],
    'deleted_at'            => ['type' => 'datetime', 'null' => true],
]);

$this->forge->addPrimaryKey('id');
$this->forge->createTable('sample_table');

Don't forget to drop the table in the down() method: $this->forge->dropTable('sample_table');

  1. Create a test for the model: test/app/Models/SampleModelTest.php with the following code:
declare(strict_types=1);

namespace Tests\App\Models;

use App\Models\SampleModel;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait;

final class SampleModelTest extends CIUnitTestCase
{
    use DatabaseTestTrait;

    protected $migrate = true;
    protected $migrateOnce = true;
    protected $namespace = null;
    protected $refresh = true;

    public function testSampleModelCanSaveData() : void 
    {
        $model = model(SampleModel::class);
        $result = $model->save([
            'name' => 'asample',
            'description' => 'Lorem ipsum dolor'
        ]);

        $this->assertTrue($result);

        $this->seeInDatabase('sample_table', [
            'name' => 'asample'
        ]);
    }
}
  1. Create your default and test databases and add the records in your .env file:
# database.default.hostname = localhost
# database.default.database = ci4_app
# database.default.username = root
# database.default.password = 
# database.default.DBDriver = MySQLi
# database.default.DBPrefix =
# database.default.port = 3306

database.tests.hostname = localhost
database.tests.database = ci4_test
database.tests.username = root
database.tests.password = 
database.tests.DBDriver = MySQLi
database.tests.DBPrefix =
database.tests.port = 3306
  1. Comment the default database and run the test: vendor\bin\phpunit

Expected Output

I expected that the test would run without any error, as models in the App namespace are not supposed to be limited to the default database.

Anything else?

Commenting the $DBGroup property of the model class:

// protected $DBGroup = 'default';`

seemed to resolve the issue, as pointed out by @datamweb which makes me to wonder why the 'default' table was hardcoded in the first place.

@sammyskills sammyskills added the bug Verified issues on the current code behavior or pull requests that will fix them label Oct 22, 2023
@kenjis
Copy link
Member

kenjis commented Oct 22, 2023

This is not a bug, because you specify the default group in your model.

The default group is a specific concrete database(s). If you specify it, CI always connects to the database group.
If you want to use the default group (that you set in Config\Database::$defaultGroup), you should not to specify $DBGroup.
https://codeigniter4.github.io/CodeIgniter4/models/model.html#connecting-to-the-database

@sammyskills
Copy link
Contributor Author

Running the command: php spark make:model modelname specifies the default group when the file is created, if it is not required, then I don't think it is needed.

@kenjis
Copy link
Member

kenjis commented Oct 22, 2023

Yes, it should be removed when you don't specify dbgroup.

@sammyskills
Copy link
Contributor Author

Better. I'll send a PR.

@sammyskills
Copy link
Contributor Author

PR #8077 submitted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Verified issues on the current code behavior or pull requests that will fix them
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants