Files
breadcrumb-the-shire/tests/Service/Access/RoleServiceTest.php

262 lines
7.5 KiB
PHP
Raw Normal View History

<?php
namespace MintyPHP\Tests\Service\Access;
use MintyPHP\Repository\Access\RoleRepositoryInterface;
use MintyPHP\Service\Access\RoleService;
use MintyPHP\Service\Audit\SystemAuditService;
use MintyPHP\Service\Directory\DirectorySettingsGateway;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
class RoleServiceTest extends TestCase
{
private RoleRepositoryInterface&MockObject $roleRepo;
private DirectorySettingsGateway&MockObject $settingsGateway;
private SystemAuditService&MockObject $auditService;
private RoleService $service;
protected function setUp(): void
{
$this->roleRepo = $this->createMock(RoleRepositoryInterface::class);
$this->settingsGateway = $this->createMock(DirectorySettingsGateway::class);
$this->auditService = $this->createMock(SystemAuditService::class);
$this->service = new RoleService(
$this->roleRepo,
$this->settingsGateway,
$this->auditService
);
}
public function testCreateFromAdminSucceeds(): void
{
$this->roleRepo
->expects($this->once())
->method('existsByCode')
->with('EDITOR', 0)
->willReturn(false);
$this->roleRepo
->expects($this->once())
->method('create')
->willReturn(42);
$this->roleRepo
->expects($this->once())
->method('find')
->with(42)
->willReturn(['id' => 42, 'uuid' => 'uuid-42', 'description' => 'Editor']);
$this->settingsGateway
->expects($this->never())
->method('setDefaultRoleId');
$this->auditService
->expects($this->once())
->method('record')
->with('admin.roles.create', 'success', $this->anything());
$result = $this->service->createFromAdmin([
'description' => 'Editor',
'code' => 'EDITOR',
'active' => 1,
], 5);
$this->assertTrue($result['ok']);
$this->assertSame('uuid-42', $result['uuid']);
$this->assertSame(42, $result['id']);
}
public function testCreateFromAdminRejectsEmptyDescription(): void
{
$this->roleRepo
->expects($this->never())
->method('create');
$result = $this->service->createFromAdmin([
'description' => ' ',
'code' => '',
'active' => 1,
]);
$this->assertFalse($result['ok']);
$this->assertNotEmpty($result['errors']);
}
public function testCreateFromAdminSetsDefaultRoleWhenRequested(): void
{
$this->roleRepo
->method('existsByCode')
->willReturn(false);
$this->roleRepo
->method('create')
->willReturn(99);
$this->roleRepo
->expects($this->any())
->method('find')
->with(99)
->willReturn(['id' => 99, 'uuid' => 'uuid-99', 'description' => 'Default']);
$this->settingsGateway
->expects($this->once())
->method('setDefaultRoleId')
->with(99);
$this->auditService
->expects($this->once())
->method('record');
$result = $this->service->createFromAdmin([
'description' => 'Default',
'code' => '',
'active' => 1,
'is_default' => 1,
], 3);
$this->assertTrue($result['ok']);
}
public function testUpdateFromAdminSucceeds(): void
{
$this->roleRepo
->expects($this->once())
->method('existsByCode')
->with('MGR', 10)
->willReturn(false);
$this->roleRepo
->expects($this->once())
->method('find')
->with(10)
->willReturn(['id' => 10, 'uuid' => 'uuid-10', 'active' => 1]);
$this->roleRepo
->expects($this->once())
->method('update')
->with(10, $this->anything())
->willReturn(true);
$this->auditService
->expects($this->once())
->method('record')
->with('admin.roles.update', 'success', $this->anything());
$result = $this->service->updateFromAdmin(10, [
'description' => 'Manager',
'code' => 'MGR',
'active' => 1,
], 5);
$this->assertTrue($result['ok']);
}
public function testUpdateFromAdminRejectsDuplicateCode(): void
{
$this->roleRepo
->expects($this->once())
->method('existsByCode')
->with('ADMIN', 10)
->willReturn(true);
$this->roleRepo
->expects($this->never())
->method('update');
$result = $this->service->updateFromAdmin(10, [
'description' => 'Manager',
'code' => 'ADMIN',
'active' => 1,
]);
$this->assertFalse($result['ok']);
$this->assertNotEmpty($result['errors']);
}
public function testDeleteByUuidSucceeds(): void
{
$role = ['id' => 7, 'uuid' => 'uuid-7', 'description' => 'Guest'];
$this->roleRepo
->expects($this->once())
->method('findByUuid')
->with('uuid-7')
->willReturn($role);
$this->roleRepo
->expects($this->once())
->method('delete')
->with(7)
->willReturn(true);
$this->auditService
->expects($this->once())
->method('record')
->with('admin.roles.delete', 'success', $this->anything());
$result = $this->service->deleteByUuid('uuid-7');
$this->assertTrue($result['ok']);
$this->assertSame($role, $result['role']);
}
public function testDeleteByUuidProtectsAdminRole(): void
{
$this->roleRepo
->expects($this->once())
->method('findByUuid')
->with('uuid-admin')
->willReturn(['id' => 1, 'uuid' => 'uuid-admin', 'description' => 'Admin']);
$this->roleRepo
->expects($this->never())
->method('delete');
$result = $this->service->deleteByUuid('uuid-admin');
$this->assertFalse($result['ok']);
$this->assertSame(403, $result['status']);
$this->assertSame('admin_role_protected', $result['error']);
}
public function testDeleteByUuidReturnsNotFoundForEmptyUuid(): void
{
$this->roleRepo
->expects($this->never())
->method('findByUuid');
$result = $this->service->deleteByUuid(' ');
$this->assertFalse($result['ok']);
$this->assertSame(404, $result['status']);
$this->assertSame('not_found', $result['error']);
}
public function testDeleteByUuidReturnsDeleteFailedOnRepoFailure(): void
{
$this->roleRepo
->expects($this->once())
->method('findByUuid')
->with('uuid-8')
->willReturn(['id' => 8, 'uuid' => 'uuid-8', 'description' => 'Viewer']);
$this->roleRepo
->expects($this->once())
->method('delete')
->with(8)
->willReturn(false);
$this->auditService
->expects($this->never())
->method('record');
$result = $this->service->deleteByUuid('uuid-8');
$this->assertFalse($result['ok']);
$this->assertSame(500, $result['status']);
$this->assertSame('delete_failed', $result['error']);
}
}