493 lines
20 KiB
PHP
493 lines
20 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace MintyPHP\Tests\Service\CustomField;
|
||
|
|
|
||
|
|
use MintyPHP\Repository\CustomField\TenantCustomFieldDefinitionRepositoryInterface;
|
||
|
|
use MintyPHP\Repository\CustomField\TenantCustomFieldOptionRepositoryInterface;
|
||
|
|
use MintyPHP\Repository\Tenant\TenantRepository;
|
||
|
|
use MintyPHP\Service\CustomField\TenantCustomFieldService;
|
||
|
|
use PHPUnit\Framework\TestCase;
|
||
|
|
|
||
|
|
final class TenantCustomFieldServiceTest extends TestCase
|
||
|
|
{
|
||
|
|
public function testListForTenantReturnsEmptyForInvalidTenantId(): void
|
||
|
|
{
|
||
|
|
$service = $this->makeService();
|
||
|
|
|
||
|
|
$this->assertSame([], $service->listForTenant(0));
|
||
|
|
$this->assertSame([], $service->listForTenant(-5));
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testListForTenantReturnsEmptyWhenNoDefinitions(): void
|
||
|
|
{
|
||
|
|
$definitionRepo = $this->createMock(TenantCustomFieldDefinitionRepositoryInterface::class);
|
||
|
|
$definitionRepo->expects($this->once())
|
||
|
|
->method('listByTenantId')
|
||
|
|
->with(10, false)
|
||
|
|
->willReturn([]);
|
||
|
|
|
||
|
|
$service = $this->makeService(definitionRepository: $definitionRepo);
|
||
|
|
|
||
|
|
$this->assertSame([], $service->listForTenant(10));
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testListForTenantMergesOptionsIntoDefinitions(): void
|
||
|
|
{
|
||
|
|
$definitionRepo = $this->createMock(TenantCustomFieldDefinitionRepositoryInterface::class);
|
||
|
|
$definitionRepo->method('listByTenantId')->willReturn([
|
||
|
|
['id' => 1, 'label' => 'Alpha', 'type' => 'select'],
|
||
|
|
['id' => 2, 'label' => 'Beta', 'type' => 'text'],
|
||
|
|
]);
|
||
|
|
|
||
|
|
$optionRepo = $this->createMock(TenantCustomFieldOptionRepositoryInterface::class);
|
||
|
|
$optionRepo->expects($this->once())
|
||
|
|
->method('listByDefinitionIds')
|
||
|
|
->with([1, 2], false)
|
||
|
|
->willReturn([
|
||
|
|
['definition_id' => 1, 'option_key' => 'a', 'label' => 'A'],
|
||
|
|
['definition_id' => 1, 'option_key' => 'b', 'label' => 'B'],
|
||
|
|
]);
|
||
|
|
|
||
|
|
$service = $this->makeService(
|
||
|
|
definitionRepository: $definitionRepo,
|
||
|
|
optionRepository: $optionRepo,
|
||
|
|
);
|
||
|
|
|
||
|
|
$result = $service->listForTenant(10);
|
||
|
|
|
||
|
|
$this->assertCount(2, $result);
|
||
|
|
$this->assertCount(2, $result[0]['options']);
|
||
|
|
$this->assertSame('a', $result[0]['options'][0]['option_key']);
|
||
|
|
$this->assertSame([], $result[1]['options']);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testCreateForTenantRejectsInvalidTenantId(): void
|
||
|
|
{
|
||
|
|
$service = $this->makeService();
|
||
|
|
|
||
|
|
$result = $service->createForTenant(0, ['label' => 'Foo'], 1);
|
||
|
|
|
||
|
|
$this->assertFalse($result['ok']);
|
||
|
|
$this->assertSame(['Tenant not found'], $result['errors']);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testCreateForTenantRejectsUnknownTenant(): void
|
||
|
|
{
|
||
|
|
$tenantRepo = $this->createMock(TenantRepository::class);
|
||
|
|
$tenantRepo->expects($this->once())->method('find')->with(99)->willReturn(null);
|
||
|
|
|
||
|
|
$service = $this->makeService(tenantRepository: $tenantRepo);
|
||
|
|
|
||
|
|
$result = $service->createForTenant(99, ['label' => 'Foo'], 1);
|
||
|
|
|
||
|
|
$this->assertFalse($result['ok']);
|
||
|
|
$this->assertSame(['Tenant not found'], $result['errors']);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testCreateForTenantReturnsValidationErrorsForEmptyLabel(): void
|
||
|
|
{
|
||
|
|
$tenantRepo = $this->createMock(TenantRepository::class);
|
||
|
|
$tenantRepo->method('find')->willReturn(['id' => 10]);
|
||
|
|
|
||
|
|
$definitionRepo = $this->createMock(TenantCustomFieldDefinitionRepositoryInterface::class);
|
||
|
|
$definitionRepo->method('findByTenantIdAndKey')->willReturn(null);
|
||
|
|
$definitionRepo->expects($this->never())->method('create');
|
||
|
|
|
||
|
|
$service = $this->makeService(
|
||
|
|
tenantRepository: $tenantRepo,
|
||
|
|
definitionRepository: $definitionRepo,
|
||
|
|
);
|
||
|
|
|
||
|
|
$result = $service->createForTenant(10, ['label' => '', 'type' => 'text'], 1);
|
||
|
|
|
||
|
|
$this->assertFalse($result['ok']);
|
||
|
|
$this->assertContains('Label cannot be empty', $result['errors']);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testCreateForTenantRejectsInvalidFieldType(): void
|
||
|
|
{
|
||
|
|
$tenantRepo = $this->createMock(TenantRepository::class);
|
||
|
|
$tenantRepo->method('find')->willReturn(['id' => 10]);
|
||
|
|
|
||
|
|
$definitionRepo = $this->createMock(TenantCustomFieldDefinitionRepositoryInterface::class);
|
||
|
|
$definitionRepo->method('findByTenantIdAndKey')->willReturn(null);
|
||
|
|
|
||
|
|
$service = $this->makeService(
|
||
|
|
tenantRepository: $tenantRepo,
|
||
|
|
definitionRepository: $definitionRepo,
|
||
|
|
);
|
||
|
|
|
||
|
|
$result = $service->createForTenant(10, ['label' => 'Foo', 'type' => 'rocket'], 1);
|
||
|
|
|
||
|
|
$this->assertFalse($result['ok']);
|
||
|
|
$this->assertContains('Field type is invalid', $result['errors']);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testCreateForTenantReturnsEmptyKeyErrorWhenAllCandidatesCollide(): void
|
||
|
|
{
|
||
|
|
$tenantRepo = $this->createMock(TenantRepository::class);
|
||
|
|
$tenantRepo->method('find')->willReturn(['id' => 10]);
|
||
|
|
|
||
|
|
$definitionRepo = $this->createMock(TenantCustomFieldDefinitionRepositoryInterface::class);
|
||
|
|
// Every candidate hits a different existing record, exhausting the 10000-candidate guard;
|
||
|
|
// resolveFieldKey then returns '' and validateForm flags the empty key.
|
||
|
|
$definitionRepo->method('findByTenantIdAndKey')->willReturnCallback(
|
||
|
|
static fn (int $tenantId, string $key): array => ['id' => 999, 'tenant_id' => $tenantId, 'field_key' => $key]
|
||
|
|
);
|
||
|
|
|
||
|
|
$service = $this->makeService(
|
||
|
|
tenantRepository: $tenantRepo,
|
||
|
|
definitionRepository: $definitionRepo,
|
||
|
|
);
|
||
|
|
|
||
|
|
$result = $service->createForTenant(10, ['label' => 'Foo', 'type' => 'text'], 1);
|
||
|
|
|
||
|
|
$this->assertFalse($result['ok']);
|
||
|
|
$this->assertContains('Field key cannot be empty', $result['errors']);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testUpdateByUuidRejectsDuplicateFieldKeyFromDifferentRecord(): void
|
||
|
|
{
|
||
|
|
$existing = ['id' => 5, 'tenant_id' => 10, 'field_key' => 'priority'];
|
||
|
|
|
||
|
|
$definitionRepo = $this->createMock(TenantCustomFieldDefinitionRepositoryInterface::class);
|
||
|
|
$definitionRepo->method('findByUuid')->willReturn($existing);
|
||
|
|
// resolveFieldKey sees id=5 for 'priority' (== excludeId) so returns 'priority' unchanged.
|
||
|
|
// validateForm re-queries and gets the SAME key owned by a DIFFERENT record id (7) — duplicate.
|
||
|
|
$definitionRepo->method('findByTenantIdAndKey')
|
||
|
|
->willReturnOnConsecutiveCalls(
|
||
|
|
['id' => 5, 'tenant_id' => 10, 'field_key' => 'priority'],
|
||
|
|
['id' => 7, 'tenant_id' => 10, 'field_key' => 'priority'],
|
||
|
|
);
|
||
|
|
$definitionRepo->expects($this->never())->method('update');
|
||
|
|
|
||
|
|
$service = $this->makeService(definitionRepository: $definitionRepo);
|
||
|
|
|
||
|
|
$result = $service->updateByUuid('uuid-of-5', [
|
||
|
|
'label' => 'Priority',
|
||
|
|
'type' => 'text',
|
||
|
|
'field_key' => 'priority',
|
||
|
|
], 7);
|
||
|
|
|
||
|
|
$this->assertFalse($result['ok']);
|
||
|
|
$this->assertContains('Field key already exists', $result['errors']);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testCreateForTenantRejectsSelectWithoutOptions(): void
|
||
|
|
{
|
||
|
|
$tenantRepo = $this->createMock(TenantRepository::class);
|
||
|
|
$tenantRepo->method('find')->willReturn(['id' => 10]);
|
||
|
|
|
||
|
|
$definitionRepo = $this->createMock(TenantCustomFieldDefinitionRepositoryInterface::class);
|
||
|
|
$definitionRepo->method('findByTenantIdAndKey')->willReturn(null);
|
||
|
|
|
||
|
|
$service = $this->makeService(
|
||
|
|
tenantRepository: $tenantRepo,
|
||
|
|
definitionRepository: $definitionRepo,
|
||
|
|
);
|
||
|
|
|
||
|
|
$result = $service->createForTenant(10, [
|
||
|
|
'label' => 'Prio',
|
||
|
|
'type' => 'select',
|
||
|
|
'options_text' => '',
|
||
|
|
], 1);
|
||
|
|
|
||
|
|
$this->assertFalse($result['ok']);
|
||
|
|
$this->assertContains('Options are required for this field type', $result['errors']);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testCreateForTenantInsertsTextFieldWithoutReplacingOptions(): void
|
||
|
|
{
|
||
|
|
$tenantRepo = $this->createMock(TenantRepository::class);
|
||
|
|
$tenantRepo->method('find')->willReturn(['id' => 10]);
|
||
|
|
|
||
|
|
$definitionRepo = $this->createMock(TenantCustomFieldDefinitionRepositoryInterface::class);
|
||
|
|
$definitionRepo->method('findByTenantIdAndKey')->willReturn(null);
|
||
|
|
$definitionRepo->method('listByTenantId')->willReturn([]);
|
||
|
|
$definitionRepo->expects($this->once())
|
||
|
|
->method('create')
|
||
|
|
->with($this->callback(static function (array $data): bool {
|
||
|
|
return ($data['tenant_id'] ?? null) === 10
|
||
|
|
&& ($data['label'] ?? null) === 'Nickname'
|
||
|
|
&& ($data['type'] ?? null) === 'text'
|
||
|
|
&& ($data['sort_order'] ?? null) === 100
|
||
|
|
&& ($data['created_by'] ?? null) === 7;
|
||
|
|
}))
|
||
|
|
->willReturn(42);
|
||
|
|
|
||
|
|
$optionRepo = $this->createMock(TenantCustomFieldOptionRepositoryInterface::class);
|
||
|
|
$optionRepo->expects($this->never())->method('replaceForDefinition');
|
||
|
|
|
||
|
|
$service = $this->makeService(
|
||
|
|
tenantRepository: $tenantRepo,
|
||
|
|
definitionRepository: $definitionRepo,
|
||
|
|
optionRepository: $optionRepo,
|
||
|
|
);
|
||
|
|
|
||
|
|
$result = $service->createForTenant(10, [
|
||
|
|
'label' => 'Nickname',
|
||
|
|
'type' => 'text',
|
||
|
|
], 7);
|
||
|
|
|
||
|
|
$this->assertTrue($result['ok']);
|
||
|
|
$this->assertSame(42, $result['id']);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testCreateForTenantInsertsSelectFieldAndReplacesOptions(): void
|
||
|
|
{
|
||
|
|
$tenantRepo = $this->createMock(TenantRepository::class);
|
||
|
|
$tenantRepo->method('find')->willReturn(['id' => 10]);
|
||
|
|
|
||
|
|
$definitionRepo = $this->createMock(TenantCustomFieldDefinitionRepositoryInterface::class);
|
||
|
|
$definitionRepo->method('findByTenantIdAndKey')->willReturn(null);
|
||
|
|
$definitionRepo->method('listByTenantId')->willReturn([
|
||
|
|
['id' => 1, 'sort_order' => 200],
|
||
|
|
]);
|
||
|
|
$definitionRepo->method('create')->willReturn(99);
|
||
|
|
|
||
|
|
$optionRepo = $this->createMock(TenantCustomFieldOptionRepositoryInterface::class);
|
||
|
|
$optionRepo->expects($this->once())
|
||
|
|
->method('replaceForDefinition')
|
||
|
|
->with(99, $this->callback(static function (array $options): bool {
|
||
|
|
return count($options) === 2
|
||
|
|
&& $options[0]['option_key'] === 'low'
|
||
|
|
&& $options[1]['option_key'] === 'high';
|
||
|
|
}))
|
||
|
|
->willReturn(true);
|
||
|
|
|
||
|
|
$service = $this->makeService(
|
||
|
|
tenantRepository: $tenantRepo,
|
||
|
|
definitionRepository: $definitionRepo,
|
||
|
|
optionRepository: $optionRepo,
|
||
|
|
);
|
||
|
|
|
||
|
|
$result = $service->createForTenant(10, [
|
||
|
|
'label' => 'Priority',
|
||
|
|
'type' => 'select',
|
||
|
|
'is_filterable' => 1,
|
||
|
|
'options_text' => "low|Low\nhigh|High",
|
||
|
|
], 7);
|
||
|
|
|
||
|
|
$this->assertTrue($result['ok']);
|
||
|
|
$this->assertSame(99, $result['id']);
|
||
|
|
// No explicit sort_order input → form keeps null; createForTenant fills the insert via nextSortOrder (200+10).
|
||
|
|
$this->assertNull($result['form']['sort_order']);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testCreateForTenantReturnsInsertFailureWhenRepoReturnsFalse(): void
|
||
|
|
{
|
||
|
|
$tenantRepo = $this->createMock(TenantRepository::class);
|
||
|
|
$tenantRepo->method('find')->willReturn(['id' => 10]);
|
||
|
|
|
||
|
|
$definitionRepo = $this->createMock(TenantCustomFieldDefinitionRepositoryInterface::class);
|
||
|
|
$definitionRepo->method('findByTenantIdAndKey')->willReturn(null);
|
||
|
|
$definitionRepo->method('listByTenantId')->willReturn([]);
|
||
|
|
$definitionRepo->method('create')->willReturn(false);
|
||
|
|
|
||
|
|
$service = $this->makeService(
|
||
|
|
tenantRepository: $tenantRepo,
|
||
|
|
definitionRepository: $definitionRepo,
|
||
|
|
);
|
||
|
|
|
||
|
|
$result = $service->createForTenant(10, ['label' => 'Foo', 'type' => 'text'], 1);
|
||
|
|
|
||
|
|
$this->assertFalse($result['ok']);
|
||
|
|
$this->assertContains('Custom field can not be created', $result['errors']);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testUpdateByUuidRejectsEmptyUuid(): void
|
||
|
|
{
|
||
|
|
$service = $this->makeService();
|
||
|
|
|
||
|
|
$result = $service->updateByUuid(' ', [], 1);
|
||
|
|
|
||
|
|
$this->assertFalse($result['ok']);
|
||
|
|
$this->assertSame(['Custom field not found'], $result['errors']);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testUpdateByUuidRejectsUnknownUuid(): void
|
||
|
|
{
|
||
|
|
$definitionRepo = $this->createMock(TenantCustomFieldDefinitionRepositoryInterface::class);
|
||
|
|
$definitionRepo->method('findByUuid')->willReturn(null);
|
||
|
|
|
||
|
|
$service = $this->makeService(definitionRepository: $definitionRepo);
|
||
|
|
|
||
|
|
$result = $service->updateByUuid('missing-uuid', [], 1);
|
||
|
|
|
||
|
|
$this->assertFalse($result['ok']);
|
||
|
|
$this->assertSame(['Custom field not found'], $result['errors']);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testUpdateByUuidPreservesExistingFieldKeyWhenSameRecord(): void
|
||
|
|
{
|
||
|
|
$existing = ['id' => 5, 'tenant_id' => 10, 'field_key' => 'priority', 'sort_order' => 30];
|
||
|
|
|
||
|
|
$definitionRepo = $this->createMock(TenantCustomFieldDefinitionRepositoryInterface::class);
|
||
|
|
$definitionRepo->method('findByUuid')->willReturn($existing);
|
||
|
|
$definitionRepo->method('findByTenantIdAndKey')->willReturnCallback(
|
||
|
|
static fn (int $tenantId, string $key): array => ['id' => 5, 'tenant_id' => $tenantId, 'field_key' => $key]
|
||
|
|
);
|
||
|
|
$definitionRepo->expects($this->once())
|
||
|
|
->method('update')
|
||
|
|
->with(5, $this->callback(static function (array $data): bool {
|
||
|
|
return ($data['field_key'] ?? null) === 'priority'
|
||
|
|
&& ($data['type'] ?? null) === 'text'
|
||
|
|
&& ($data['modified_by'] ?? null) === 7;
|
||
|
|
}))
|
||
|
|
->willReturn(true);
|
||
|
|
|
||
|
|
$optionRepo = $this->createMock(TenantCustomFieldOptionRepositoryInterface::class);
|
||
|
|
$optionRepo->expects($this->once())
|
||
|
|
->method('deleteByDefinitionId')
|
||
|
|
->with(5)
|
||
|
|
->willReturn(true);
|
||
|
|
|
||
|
|
$service = $this->makeService(
|
||
|
|
definitionRepository: $definitionRepo,
|
||
|
|
optionRepository: $optionRepo,
|
||
|
|
);
|
||
|
|
|
||
|
|
$result = $service->updateByUuid('uuid-of-5', [
|
||
|
|
'label' => 'Priority',
|
||
|
|
'type' => 'text',
|
||
|
|
'field_key' => 'priority',
|
||
|
|
], 7);
|
||
|
|
|
||
|
|
$this->assertTrue($result['ok']);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testUpdateByUuidReplacesOptionsWhenSelectType(): void
|
||
|
|
{
|
||
|
|
$existing = ['id' => 5, 'tenant_id' => 10, 'field_key' => 'priority', 'sort_order' => 30];
|
||
|
|
|
||
|
|
$definitionRepo = $this->createMock(TenantCustomFieldDefinitionRepositoryInterface::class);
|
||
|
|
$definitionRepo->method('findByUuid')->willReturn($existing);
|
||
|
|
$definitionRepo->method('findByTenantIdAndKey')->willReturn($existing);
|
||
|
|
$definitionRepo->method('update')->willReturn(true);
|
||
|
|
|
||
|
|
$optionRepo = $this->createMock(TenantCustomFieldOptionRepositoryInterface::class);
|
||
|
|
$optionRepo->expects($this->once())
|
||
|
|
->method('replaceForDefinition')
|
||
|
|
->with(5, $this->callback(static fn ($options): bool => is_array($options)))
|
||
|
|
->willReturn(true);
|
||
|
|
$optionRepo->expects($this->never())->method('deleteByDefinitionId');
|
||
|
|
|
||
|
|
$service = $this->makeService(
|
||
|
|
definitionRepository: $definitionRepo,
|
||
|
|
optionRepository: $optionRepo,
|
||
|
|
);
|
||
|
|
|
||
|
|
$result = $service->updateByUuid('uuid-of-5', [
|
||
|
|
'label' => 'Priority',
|
||
|
|
'type' => 'select',
|
||
|
|
'options_text' => 'low|Low',
|
||
|
|
'field_key' => 'priority',
|
||
|
|
], 7);
|
||
|
|
|
||
|
|
$this->assertTrue($result['ok']);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testUpdateByUuidReturnsUpdateFailureWhenRepoReturnsFalse(): void
|
||
|
|
{
|
||
|
|
$existing = ['id' => 5, 'tenant_id' => 10, 'field_key' => 'priority'];
|
||
|
|
|
||
|
|
$definitionRepo = $this->createMock(TenantCustomFieldDefinitionRepositoryInterface::class);
|
||
|
|
$definitionRepo->method('findByUuid')->willReturn($existing);
|
||
|
|
$definitionRepo->method('findByTenantIdAndKey')->willReturn($existing);
|
||
|
|
$definitionRepo->method('update')->willReturn(false);
|
||
|
|
|
||
|
|
$service = $this->makeService(definitionRepository: $definitionRepo);
|
||
|
|
|
||
|
|
$result = $service->updateByUuid('uuid-of-5', [
|
||
|
|
'label' => 'Priority',
|
||
|
|
'type' => 'text',
|
||
|
|
'field_key' => 'priority',
|
||
|
|
], 7);
|
||
|
|
|
||
|
|
$this->assertFalse($result['ok']);
|
||
|
|
$this->assertContains('Custom field can not be updated', $result['errors']);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testDeleteByUuidRejectsEmptyUuid(): void
|
||
|
|
{
|
||
|
|
$service = $this->makeService();
|
||
|
|
|
||
|
|
$result = $service->deleteByUuid('');
|
||
|
|
|
||
|
|
$this->assertSame(['ok' => false, 'status' => 404, 'error' => 'not_found'], $result);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testDeleteByUuidRejectsUnknownUuid(): void
|
||
|
|
{
|
||
|
|
$definitionRepo = $this->createMock(TenantCustomFieldDefinitionRepositoryInterface::class);
|
||
|
|
$definitionRepo->method('findByUuid')->willReturn(null);
|
||
|
|
|
||
|
|
$service = $this->makeService(definitionRepository: $definitionRepo);
|
||
|
|
|
||
|
|
$result = $service->deleteByUuid('unknown');
|
||
|
|
|
||
|
|
$this->assertSame(['ok' => false, 'status' => 404, 'error' => 'not_found'], $result);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testDeleteByUuidReturnsFailureWhenRepoReturnsFalse(): void
|
||
|
|
{
|
||
|
|
$definitionRepo = $this->createMock(TenantCustomFieldDefinitionRepositoryInterface::class);
|
||
|
|
$definitionRepo->method('findByUuid')->willReturn(['id' => 7]);
|
||
|
|
$definitionRepo->expects($this->once())->method('delete')->with(7)->willReturn(false);
|
||
|
|
|
||
|
|
$service = $this->makeService(definitionRepository: $definitionRepo);
|
||
|
|
|
||
|
|
$result = $service->deleteByUuid('uuid-7');
|
||
|
|
|
||
|
|
$this->assertSame(['ok' => false, 'status' => 500, 'error' => 'delete_failed'], $result);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testDeleteByUuidReturnsDefinitionOnSuccess(): void
|
||
|
|
{
|
||
|
|
$existing = ['id' => 7, 'tenant_id' => 10, 'label' => 'Gone'];
|
||
|
|
|
||
|
|
$definitionRepo = $this->createMock(TenantCustomFieldDefinitionRepositoryInterface::class);
|
||
|
|
$definitionRepo->method('findByUuid')->willReturn($existing);
|
||
|
|
$definitionRepo->expects($this->once())->method('delete')->with(7)->willReturn(true);
|
||
|
|
|
||
|
|
$service = $this->makeService(definitionRepository: $definitionRepo);
|
||
|
|
|
||
|
|
$result = $service->deleteByUuid('uuid-7');
|
||
|
|
|
||
|
|
$this->assertTrue($result['ok']);
|
||
|
|
$this->assertSame($existing, $result['definition']);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testDefinitionTenantIdByUuidReturnsZeroWhenNotFound(): void
|
||
|
|
{
|
||
|
|
$definitionRepo = $this->createMock(TenantCustomFieldDefinitionRepositoryInterface::class);
|
||
|
|
$definitionRepo->method('findByUuid')->willReturn(null);
|
||
|
|
|
||
|
|
$service = $this->makeService(definitionRepository: $definitionRepo);
|
||
|
|
|
||
|
|
$this->assertSame(0, $service->definitionTenantIdByUuid(' '));
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testDefinitionTenantIdByUuidReturnsTenantIdWhenFound(): void
|
||
|
|
{
|
||
|
|
$definitionRepo = $this->createMock(TenantCustomFieldDefinitionRepositoryInterface::class);
|
||
|
|
$definitionRepo->expects($this->once())->method('findByUuid')->with('abc')->willReturn(['tenant_id' => 42]);
|
||
|
|
|
||
|
|
$service = $this->makeService(definitionRepository: $definitionRepo);
|
||
|
|
|
||
|
|
$this->assertSame(42, $service->definitionTenantIdByUuid('abc'));
|
||
|
|
}
|
||
|
|
|
||
|
|
private function makeService(
|
||
|
|
?TenantRepository $tenantRepository = null,
|
||
|
|
?TenantCustomFieldDefinitionRepositoryInterface $definitionRepository = null,
|
||
|
|
?TenantCustomFieldOptionRepositoryInterface $optionRepository = null,
|
||
|
|
): TenantCustomFieldService {
|
||
|
|
return new TenantCustomFieldService(
|
||
|
|
$tenantRepository ?? $this->createMock(TenantRepository::class),
|
||
|
|
$definitionRepository ?? $this->createMock(TenantCustomFieldDefinitionRepositoryInterface::class),
|
||
|
|
$optionRepository ?? $this->createMock(TenantCustomFieldOptionRepositoryInterface::class),
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|