mirror of
https://github.com/codeigniter4/CodeIgniter4.git
synced 2025-02-20 11:44:28 +08:00
640 lines
14 KiB
PHP
640 lines
14 KiB
PHP
<?php namespace CodeIgniter\Database\Live;
|
|
|
|
use CodeIgniter\I18n\Time;
|
|
use CodeIgniter\Model;
|
|
use CodeIgniter\Test\CIDatabaseTestCase;
|
|
use CodeIgniter\Test\ReflectionHelper;
|
|
use Tests\Support\Models\EntityModel;
|
|
use Tests\Support\Models\EventModel;
|
|
use Tests\Support\Models\JobModel;
|
|
use Tests\Support\Models\SimpleEntity;
|
|
use Tests\Support\Models\UserModel;
|
|
use Tests\Support\Models\ValidModel;
|
|
|
|
/**
|
|
* @group DatabaseLive
|
|
*/
|
|
class ModelTest extends CIDatabaseTestCase
|
|
{
|
|
use ReflectionHelper;
|
|
|
|
protected $refresh = true;
|
|
|
|
protected $seed = 'Tests\Support\Database\Seeds\CITestSeeder';
|
|
|
|
public function setUp()
|
|
{
|
|
parent::setUp();
|
|
|
|
$this->model = new Model($this->db);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
public function testFindReturnsRow()
|
|
{
|
|
$model = new JobModel($this->db);
|
|
|
|
$job = $model->find(4);
|
|
|
|
$this->assertEquals('Musician', $job->name);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
public function testFindReturnsMultipleRows()
|
|
{
|
|
$model = new JobModel($this->db);
|
|
|
|
$job = $model->find([1,4]);
|
|
|
|
$this->assertEquals('Developer', $job[0]->name);
|
|
$this->assertEquals('Musician', $job[1]->name);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
public function testFindRespectsReturnArray()
|
|
{
|
|
$model = new JobModel($this->db);
|
|
|
|
$job = $model->asArray()->find(4);
|
|
|
|
$this->assertInternalType('array', $job);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
public function testFindRespectsReturnObject()
|
|
{
|
|
$model = new JobModel($this->db);
|
|
|
|
$job = $model->asObject()->find(4);
|
|
|
|
$this->assertInternalType('object', $job);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
public function testFindRespectsSoftDeletes()
|
|
{
|
|
$this->db->table('user')->where('id', 4)->update(['deleted' => 1]);
|
|
|
|
$model = new UserModel($this->db);
|
|
|
|
$user = $model->asObject()->find(4);
|
|
|
|
$this->assertEmpty($user);
|
|
|
|
$user = $model->withDeleted()->find(4);
|
|
|
|
// fix for PHP7.2
|
|
$count = is_array($user) ? count($user) : 1;
|
|
$this->assertEquals(1, $count);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
public function testFindWhereSimple()
|
|
{
|
|
$model = new JobModel($this->db);
|
|
|
|
$jobs = $model->asObject()->findWhere('id >', 2);
|
|
|
|
$this->assertCount(2, $jobs);
|
|
$this->assertEquals('Accountant', $jobs[0]->name);
|
|
$this->assertEquals('Musician', $jobs[1]->name);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
public function testFindWhereWithArrayWhere()
|
|
{
|
|
$model = new JobModel($this->db);
|
|
|
|
$jobs = $model->asArray()->findWhere(['id' => 1]);
|
|
|
|
$this->assertCount(1, $jobs);
|
|
$this->assertEquals('Developer', $jobs[0]['name']);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
public function testFindWhereRespectsSoftDeletes()
|
|
{
|
|
$this->db->table('user')->where('id', 4)->update(['deleted' => 1]);
|
|
|
|
$model = new UserModel($this->db);
|
|
|
|
$user = $model->findWhere('id >', '2');
|
|
|
|
$this->assertCount(1, $user);
|
|
|
|
$user = $model->withDeleted()->findWhere('id >', 2);
|
|
|
|
$this->assertCount(2, $user);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
public function testFindAllReturnsAllRecords()
|
|
{
|
|
$model = new UserModel($this->db);
|
|
|
|
$users = $model->findAll();
|
|
|
|
$this->assertCount(4, $users);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
public function testFindAllRespectsLimits()
|
|
{
|
|
$model = new UserModel($this->db);
|
|
|
|
$users = $model->findAll(2);
|
|
|
|
$this->assertCount(2, $users);
|
|
$this->assertEquals('Derek Jones', $users[0]->name);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
public function testFindAllRespectsLimitsAndOffset()
|
|
{
|
|
$model = new UserModel($this->db);
|
|
|
|
$users = $model->findAll(2, 2);
|
|
|
|
$this->assertCount(2, $users);
|
|
$this->assertEquals('Richard A Causey', $users[0]->name);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
public function testFindAllRespectsSoftDeletes()
|
|
{
|
|
$this->db->table('user')->where('id', 4)->update(['deleted' => 1]);
|
|
|
|
$model = new UserModel($this->db);
|
|
|
|
$user = $model->findAll();
|
|
|
|
$this->assertCount(3, $user);
|
|
|
|
$user = $model->withDeleted()->findAll();
|
|
|
|
$this->assertCount(4, $user);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
public function testFirst()
|
|
{
|
|
$model = new UserModel();
|
|
|
|
$user = $model->where('id >', 2)->first();
|
|
|
|
// fix for PHP7.2
|
|
$count = is_array($user) ? count($user) : 1;
|
|
$this->assertEquals(1, $count);
|
|
$this->assertEquals(3, $user->id);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
public function testFirstRespectsSoftDeletes()
|
|
{
|
|
$this->db->table('user')->where('id', 1)->update(['deleted' => 1]);
|
|
|
|
$model = new UserModel();
|
|
|
|
$user = $model->first();
|
|
|
|
// fix for PHP7.2
|
|
$count = is_array($user) ? count($user) : 1;
|
|
$this->assertEquals(1, $count);
|
|
$this->assertEquals(2, $user->id);
|
|
|
|
$user = $model->withDeleted()->first();
|
|
|
|
$this->assertEquals(1, $user->id);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
public function testSaveNewRecordObject()
|
|
{
|
|
$model = new JobModel();
|
|
|
|
$data = new \stdClass();
|
|
$data->name = 'Magician';
|
|
$data->description = 'Makes peoples things dissappear.';
|
|
|
|
$model->protect(false)->save($data);
|
|
|
|
$this->seeInDatabase('job', ['name' => 'Magician']);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
public function testSaveNewRecordArray()
|
|
{
|
|
$model = new JobModel();
|
|
|
|
$data = [
|
|
'name' => 'Apprentice',
|
|
'description' => 'That thing you do.'
|
|
];
|
|
|
|
$result = $model->protect(false)->save($data);
|
|
|
|
$this->seeInDatabase('job', ['name' => 'Apprentice']);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
public function testSaveUpdateRecordObject()
|
|
{
|
|
$model = new JobModel();
|
|
|
|
$data = [
|
|
'id' => 1,
|
|
'name' => 'Apprentice',
|
|
'description' => 'That thing you do.'
|
|
];
|
|
|
|
$result = $model->protect(false)->save($data);
|
|
|
|
$this->seeInDatabase('job', ['name' => 'Apprentice']);
|
|
$this->assertTrue($result);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
public function testSaveUpdateRecordArray()
|
|
{
|
|
$model = new JobModel();
|
|
|
|
$data = new \stdClass();
|
|
$data->id = 1;
|
|
$data->name = 'Engineer';
|
|
$data->description = 'A fancier term for Developer.';
|
|
|
|
$result = $model->protect(false)->save($data);
|
|
|
|
$this->seeInDatabase('job', ['name' => 'Engineer']);
|
|
$this->assertTrue($result);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
public function testSaveProtected()
|
|
{
|
|
$model = new JobModel();
|
|
|
|
$data = new \stdClass();
|
|
$data->id = 1;
|
|
$data->name = 'Engineer';
|
|
$data->description = 'A fancier term for Developer.';
|
|
$data->random_thing = 'Something wicked'; // If not protected, this would kill the script.
|
|
|
|
$result = $model->protect(true)->save($data);
|
|
|
|
$this->assertTrue($result);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
public function testDeleteBasics()
|
|
{
|
|
$model = new JobModel();
|
|
|
|
$this->seeInDatabase('job', ['name' =>'Developer']);
|
|
|
|
$model->delete(1);
|
|
|
|
$this->dontSeeInDatabase('job', ['name' => 'Developer']);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
public function testDeleteWithSoftDeletes()
|
|
{
|
|
$model = new UserModel();
|
|
|
|
$this->seeInDatabase('user', ['name' =>'Derek Jones', 'deleted' => 0]);
|
|
|
|
$model->delete(1);
|
|
|
|
$this->seeInDatabase('user', ['name' => 'Derek Jones', 'deleted' => 1]);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
public function testDeleteWithSoftDeletesPurge()
|
|
{
|
|
$model = new UserModel();
|
|
|
|
$this->seeInDatabase('user', ['name' =>'Derek Jones', 'deleted' => 0]);
|
|
|
|
$model->delete(1, true);
|
|
|
|
$this->dontSeeInDatabase('user', ['name' => 'Derek Jones']);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
public function testDeleteWhereWithSoftDeletes()
|
|
{
|
|
$model = new UserModel();
|
|
|
|
$this->seeInDatabase('user', ['name' =>'Derek Jones', 'deleted' => 0]);
|
|
|
|
$model->deleteWhere('name', 'Derek Jones');
|
|
|
|
$this->seeInDatabase('user', ['name' => 'Derek Jones', 'deleted' => 1]);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
public function testDeleteWhereWithSoftDeletesPurge()
|
|
{
|
|
$model = new UserModel();
|
|
|
|
$this->seeInDatabase('user', ['name' =>'Derek Jones', 'deleted' => 0]);
|
|
|
|
$model->deleteWhere('name', 'Derek Jones', true);
|
|
|
|
$this->dontSeeInDatabase('user', ['name' => 'Derek Jones']);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
public function testPurgeDeleted()
|
|
{
|
|
$model = new UserModel();
|
|
|
|
$this->db->table('user')->where('id', 1)->update(['deleted' => 1]);
|
|
|
|
$model->purgeDeleted();
|
|
|
|
$users = $model->withDeleted()->findAll();
|
|
|
|
$this->assertCount(3, $users);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
public function testOnlyDeleted()
|
|
{
|
|
$model = new UserModel($this->db);
|
|
|
|
$this->db->table('user')->where('id', 1)->update(['deleted' => 1]);
|
|
|
|
$users = $model->onlyDeleted()->findAll();
|
|
|
|
$this->assertCount(1, $users);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
public function testChunk()
|
|
{
|
|
$model = new UserModel();
|
|
|
|
$rowCount = 0;
|
|
|
|
$model->chunk(2, function($row) use (&$rowCount) {
|
|
$rowCount++;
|
|
});
|
|
|
|
$this->assertEquals(4, $rowCount);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
public function testValidationBasics()
|
|
{
|
|
$model = new ValidModel($this->db);
|
|
|
|
$data = [
|
|
'description' => 'some great marketing stuff'
|
|
];
|
|
|
|
$this->assertFalse($model->insert($data));
|
|
|
|
$errors = $model->errors();
|
|
|
|
$this->assertEquals('You forgot to name the baby.', $errors['name']);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
public function testValidationPlaceholdersSuccess()
|
|
{
|
|
$model = new ValidModel($this->db);
|
|
|
|
$data = [
|
|
'name' => 'abc',
|
|
'id' => 13,
|
|
'token' => 13
|
|
];
|
|
|
|
$this->assertTrue($model->validate($data));
|
|
}
|
|
|
|
public function testValidationPlaceholdersFail()
|
|
{
|
|
$model = new ValidModel($this->db);
|
|
|
|
$data = [
|
|
'name' => 'abc',
|
|
'id' => 13,
|
|
'token' => 12
|
|
];
|
|
|
|
$this->assertFalse($model->validate($data));
|
|
}
|
|
|
|
public function testSkipValidation()
|
|
{
|
|
$model = new ValidModel($this->db);
|
|
|
|
$data = [
|
|
'name' => '2',
|
|
'description' => 'some great marketing stuff'
|
|
];
|
|
|
|
$this->assertInternalType('numeric', $model->skipValidation(true)->insert($data));
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
public function testCanCreateAndSaveEntityClasses()
|
|
{
|
|
$model = new EntityModel($this->db);
|
|
|
|
$entity = $model->where('name', 'Developer')->first();
|
|
|
|
$this->assertInstanceOf(SimpleEntity::class, $entity);
|
|
$this->assertEquals('Developer', $entity->name);
|
|
$this->assertEquals('Awesome job, but sometimes makes you bored', $entity->description);
|
|
|
|
$entity->name = 'Senior Developer';
|
|
$entity->created_at = '2017-07-15';
|
|
|
|
$date = $this->getPrivateProperty($entity, 'created_at');
|
|
$this->assertInstanceOf(Time::class, $date);
|
|
|
|
$this->assertTrue($model->save($entity));
|
|
|
|
$this->seeInDatabase('job', ['name' => 'Senior Developer', 'created_at' => '2017-07-15 00:00:00']);
|
|
}
|
|
|
|
/**
|
|
* @see https://github.com/bcit-ci/CodeIgniter4/issues/580
|
|
*/
|
|
public function testPasswordsStoreCorrectly()
|
|
{
|
|
$model = new UserModel();
|
|
|
|
$pass = password_hash('secret123', PASSWORD_BCRYPT);
|
|
|
|
$data = [
|
|
'name' => $pass,
|
|
'email' => 'foo@example.com',
|
|
'country' => 'US',
|
|
'deleted' => 0
|
|
];
|
|
|
|
$model->insert($data);
|
|
|
|
$this->seeInDatabase('user', $data);
|
|
}
|
|
|
|
public function testInsertEvent()
|
|
{
|
|
$model = new EventModel();
|
|
|
|
$data = [
|
|
'name' => 'Foo',
|
|
'email' => 'foo@example.com',
|
|
'country' => 'US',
|
|
'deleted' => 0
|
|
];
|
|
|
|
$model->insert($data);
|
|
|
|
$this->assertTrue($model->hasToken('beforeInsert'));
|
|
$this->assertTrue($model->hasToken('afterInsert'));
|
|
}
|
|
|
|
public function testUpdateEvent()
|
|
{
|
|
$model = new EventModel();
|
|
|
|
$data = [
|
|
'name' => 'Foo',
|
|
'email' => 'foo@example.com',
|
|
'country' => 'US',
|
|
'deleted' => 0
|
|
];
|
|
|
|
$id = $model->insert($data);
|
|
$model->update($id, $data);
|
|
|
|
$this->assertTrue($model->hasToken('beforeUpdate'));
|
|
$this->assertTrue($model->hasToken('afterUpdate'));
|
|
}
|
|
|
|
public function testFindEvent()
|
|
{
|
|
$model = new EventModel();
|
|
|
|
$model->find(1);
|
|
|
|
$this->assertTrue($model->hasToken('afterFind'));
|
|
}
|
|
|
|
public function testDeleteEvent()
|
|
{
|
|
$model = new EventModel();
|
|
|
|
$model->delete(1);
|
|
|
|
$this->assertTrue($model->hasToken('afterDelete'));
|
|
}
|
|
|
|
public function testSetWorksWithInsert()
|
|
{
|
|
$model = new EventModel();
|
|
|
|
$this->dontSeeInDatabase('user', [
|
|
'email' => 'foo@example.com'
|
|
]);
|
|
|
|
$model->set([
|
|
'email' => 'foo@example.com',
|
|
'name' => 'Foo Bar',
|
|
'country' => 'US'
|
|
])->insert();
|
|
|
|
$this->seeInDatabase('user', [
|
|
'email' => 'foo@example.com'
|
|
]);
|
|
}
|
|
|
|
public function testSetWorksWithUpdate()
|
|
{
|
|
$model = new EventModel();
|
|
|
|
$this->dontSeeInDatabase('user', [
|
|
'email' => 'foo@example.com'
|
|
]);
|
|
|
|
$userId = $model->insert([
|
|
'email' => 'foo@example.com',
|
|
'name' => 'Foo Bar',
|
|
'country' => 'US'
|
|
]);
|
|
|
|
$model->set([
|
|
'name' => 'Fred Flintstone'
|
|
])->update($userId);
|
|
|
|
$this->seeInDatabase('user', [
|
|
'id' => $userId,
|
|
'email' => 'foo@example.com',
|
|
'name' => 'Fred Flintstone'
|
|
]);
|
|
}
|
|
|
|
public function testSetWorksWithUpdateNoId()
|
|
{
|
|
$model = new EventModel();
|
|
|
|
$this->dontSeeInDatabase('user', [
|
|
'email' => 'foo@example.com'
|
|
]);
|
|
|
|
$userId = $model->insert([
|
|
'email' => 'foo@example.com',
|
|
'name' => 'Foo Bar',
|
|
'country' => 'US'
|
|
]);
|
|
|
|
$model
|
|
->where('id', $userId)
|
|
->set([
|
|
'name' => 'Fred Flintstone'
|
|
])->update();
|
|
|
|
$this->seeInDatabase('user', [
|
|
'id' => $userId,
|
|
'email' => 'foo@example.com',
|
|
'name' => 'Fred Flintstone'
|
|
]);
|
|
}
|
|
}
|