All checks were successful
CI / Coding Standards (push) Successful in 43s
CI / PHPStan (push) Successful in 52s
CI / Tests (PHP 8.1) (push) Successful in 47s
CI / Tests (PHP 8.2) (push) Successful in 49s
CI / Tests (PHP 8.3) (push) Successful in 37s
CI / No Debug Code (push) Successful in 2s
All classes are now organised by domain (Availability, Booking, Auth). Each domain package contains its value object, repository, admin controller, REST endpoint, and any shortcode pages under a matching sub-namespace. Cross-cutting wiring (Plugin, AdminMenu, RestRegistrar, ShortcodeRegistrar, Schema) lives at src/ root. Tests mirror the domain structure. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
150 lines
4.4 KiB
PHP
150 lines
4.4 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace Unsupervised\Schedular\Tests\Unit\Availability;
|
|
|
|
use Brain\Monkey\Functions;
|
|
use Mockery;
|
|
use Unsupervised\Schedular\Availability\AvailabilityRepository;
|
|
use Unsupervised\Schedular\Availability\AvailabilitySlot;
|
|
use Unsupervised\Schedular\Tests\Unit\TestCase;
|
|
|
|
class AvailabilityRepositoryTest extends TestCase
|
|
{
|
|
private \wpdb $db;
|
|
private AvailabilityRepository $repo;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
$this->db = Mockery::mock(\wpdb::class);
|
|
$this->db->prefix = 'wp_';
|
|
$this->repo = new AvailabilityRepository($this->db);
|
|
}
|
|
|
|
public function testInsertCallsWpdbInsertAndReturnsId(): void
|
|
{
|
|
Functions\expect('current_time')->with('mysql')->andReturn('2026-04-01 12:00:00');
|
|
|
|
$this->db->shouldReceive('insert')
|
|
->once()
|
|
->with(
|
|
'wp_us_availability',
|
|
Mockery::on(static function (array $data): bool {
|
|
return $data['instructor_id'] === 5
|
|
&& $data['start_dt'] === '2026-04-01 09:00:00'
|
|
&& $data['is_booked'] === 0;
|
|
}),
|
|
['%d', '%s', '%s', '%d', '%s']
|
|
);
|
|
|
|
$this->db->insert_id = 42;
|
|
|
|
$slot = new AvailabilitySlot(5, '2026-04-01 09:00:00', '2026-04-01 10:00:00');
|
|
$result = $this->repo->insert($slot);
|
|
|
|
self::assertSame(42, $result);
|
|
}
|
|
|
|
public function testFindByIdReturnsNullWhenNotFound(): void
|
|
{
|
|
$this->db->shouldReceive('prepare')
|
|
->once()
|
|
->andReturn('SELECT * FROM wp_us_availability WHERE id = 99');
|
|
|
|
$this->db->shouldReceive('get_row')
|
|
->once()
|
|
->andReturn(null);
|
|
|
|
$result = $this->repo->findById(99);
|
|
|
|
self::assertNull($result);
|
|
}
|
|
|
|
public function testFindByIdReturnsSlotWhenFound(): void
|
|
{
|
|
$row = (object) [
|
|
'id' => '10',
|
|
'instructor_id' => '5',
|
|
'start_dt' => '2026-04-01 09:00:00',
|
|
'end_dt' => '2026-04-01 10:00:00',
|
|
'is_booked' => '0',
|
|
];
|
|
|
|
$this->db->shouldReceive('prepare')->andReturn('SELECT ...');
|
|
$this->db->shouldReceive('get_row')->andReturn($row);
|
|
|
|
$slot = $this->repo->findById(10);
|
|
|
|
self::assertInstanceOf(AvailabilitySlot::class, $slot);
|
|
self::assertSame(10, $slot->id);
|
|
self::assertSame(5, $slot->instructorId);
|
|
}
|
|
|
|
public function testMarkBookedUpdatesRecord(): void
|
|
{
|
|
$this->db->shouldReceive('update')
|
|
->once()
|
|
->with('wp_us_availability', ['is_booked' => 1], ['id' => 7], ['%d'], ['%d'])
|
|
->andReturn(1);
|
|
|
|
$result = $this->repo->markBooked(7);
|
|
|
|
self::assertTrue($result);
|
|
}
|
|
|
|
public function testDeleteReturnsFalseWhenRowNotDeleted(): void
|
|
{
|
|
$this->db->shouldReceive('delete')
|
|
->once()
|
|
->with('wp_us_availability', ['id' => 1, 'is_booked' => 0], ['%d', '%d'])
|
|
->andReturn(0);
|
|
|
|
self::assertFalse($this->repo->delete(1));
|
|
}
|
|
|
|
public function testFindAvailableWithNoFiltersUsesNoParams(): void
|
|
{
|
|
$this->db->shouldReceive('get_results')
|
|
->once()
|
|
->with(Mockery::pattern('/WHERE is_booked = 0/'))
|
|
->andReturn([]);
|
|
|
|
$result = $this->repo->findAvailable();
|
|
|
|
self::assertSame([], $result);
|
|
}
|
|
|
|
public function testFindAvailableWithInstructorFilterPreparesQuery(): void
|
|
{
|
|
$this->db->shouldReceive('prepare')
|
|
->once()
|
|
->with(Mockery::pattern('/instructor_id = %d/'), Mockery::any())
|
|
->andReturn('SELECT ...');
|
|
|
|
$this->db->shouldReceive('get_results')->andReturn([]);
|
|
|
|
$this->repo->findAvailable(instructorId: 3);
|
|
}
|
|
|
|
public function testFindByInstructorReturnsSlots(): void
|
|
{
|
|
$row = (object) [
|
|
'id' => '5',
|
|
'instructor_id' => '3',
|
|
'start_dt' => '2026-04-01 09:00:00',
|
|
'end_dt' => '2026-04-01 10:00:00',
|
|
'is_booked' => '0',
|
|
];
|
|
|
|
$this->db->shouldReceive('prepare')->andReturn('SELECT ...');
|
|
$this->db->shouldReceive('get_results')->andReturn([$row]);
|
|
|
|
$slots = $this->repo->findByInstructor(3);
|
|
|
|
self::assertCount(1, $slots);
|
|
self::assertInstanceOf(AvailabilitySlot::class, $slots[0]);
|
|
}
|
|
}
|