Skip to content

Commit d3d1d20

Browse files
committed
test(service): cover import payload validator
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
1 parent fa0ed8b commit d3d1d20

1 file changed

Lines changed: 149 additions & 0 deletions

File tree

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
<?php
2+
3+
/**
4+
* SPDX-FileCopyrightText: 2026 LibreCode coop and LibreCode contributors
5+
* SPDX-License-Identifier: AGPL-3.0-or-later
6+
*/
7+
8+
declare(strict_types=1);
9+
10+
namespace OCA\ProfileFields\Tests\Unit\Service;
11+
12+
use InvalidArgumentException;
13+
use OCA\ProfileFields\Db\FieldDefinition;
14+
use OCA\ProfileFields\Enum\FieldType;
15+
use OCA\ProfileFields\Service\FieldDefinitionService;
16+
use OCA\ProfileFields\Service\FieldDefinitionValidator;
17+
use OCA\ProfileFields\Service\ImportPayloadValidator;
18+
use OCP\IUserManager;
19+
use PHPUnit\Framework\MockObject\MockObject;
20+
use PHPUnit\Framework\TestCase;
21+
22+
class ImportPayloadValidatorTest extends TestCase {
23+
private FieldDefinitionService&MockObject $fieldDefinitionService;
24+
private IUserManager&MockObject $userManager;
25+
private ImportPayloadValidator $validator;
26+
27+
protected function setUp(): void {
28+
parent::setUp();
29+
$this->fieldDefinitionService = $this->createMock(FieldDefinitionService::class);
30+
$this->userManager = $this->createMock(IUserManager::class);
31+
$this->validator = new ImportPayloadValidator(
32+
new FieldDefinitionValidator(),
33+
$this->fieldDefinitionService,
34+
$this->userManager,
35+
);
36+
}
37+
38+
public function testValidateAcceptsVersionedPayload(): void {
39+
$this->fieldDefinitionService->expects($this->once())
40+
->method('findByFieldKey')
41+
->with('cost_center')
42+
->willReturn(null);
43+
44+
$this->userManager->expects($this->once())
45+
->method('userExists')
46+
->with('alice')
47+
->willReturn(true);
48+
49+
$validated = $this->validator->validate([
50+
'schema_version' => 1,
51+
'definitions' => [[
52+
'field_key' => 'cost_center',
53+
'label' => 'Cost center',
54+
'type' => FieldType::TEXT->value,
55+
'admin_only' => false,
56+
'user_editable' => false,
57+
'user_visible' => true,
58+
'initial_visibility' => 'users',
59+
'sort_order' => 1,
60+
'active' => true,
61+
]],
62+
'values' => [[
63+
'field_key' => 'cost_center',
64+
'user_uid' => 'alice',
65+
'value' => ['value' => 'finance'],
66+
'current_visibility' => 'users',
67+
'updated_by_uid' => 'admin',
68+
'updated_at' => '2026-03-15T12:00:00+00:00',
69+
]],
70+
]);
71+
72+
$this->assertSame(1, $validated['schema_version']);
73+
$this->assertSame('cost_center', $validated['definitions'][0]['field_key']);
74+
$this->assertSame(['value' => 'finance'], $validated['values'][0]['value']);
75+
}
76+
77+
public function testRejectUnsupportedSchemaVersion(): void {
78+
$this->expectException(InvalidArgumentException::class);
79+
$this->expectExceptionMessage('schema_version must be 1');
80+
81+
$this->validator->validate([
82+
'schema_version' => 2,
83+
'definitions' => [],
84+
'values' => [],
85+
]);
86+
}
87+
88+
public function testRejectMissingDestinationUser(): void {
89+
$this->fieldDefinitionService->expects($this->once())
90+
->method('findByFieldKey')
91+
->with('cost_center')
92+
->willReturn(null);
93+
94+
$this->userManager->expects($this->once())
95+
->method('userExists')
96+
->with('ghost')
97+
->willReturn(false);
98+
99+
$this->expectException(InvalidArgumentException::class);
100+
$this->expectExceptionMessage('values[0].user_uid does not exist in destination instance');
101+
102+
$this->validator->validate([
103+
'schema_version' => 1,
104+
'definitions' => [[
105+
'field_key' => 'cost_center',
106+
'label' => 'Cost center',
107+
'type' => FieldType::TEXT->value,
108+
]],
109+
'values' => [[
110+
'field_key' => 'cost_center',
111+
'user_uid' => 'ghost',
112+
'value' => ['value' => 'finance'],
113+
'current_visibility' => 'users',
114+
'updated_by_uid' => 'admin',
115+
'updated_at' => '2026-03-15T12:00:00+00:00',
116+
]],
117+
]);
118+
}
119+
120+
public function testRejectIncompatibleExistingDefinition(): void {
121+
$existingDefinition = new FieldDefinition();
122+
$existingDefinition->setId(7);
123+
$existingDefinition->setFieldKey('cost_center');
124+
$existingDefinition->setLabel('Cost center');
125+
$existingDefinition->setType(FieldType::NUMBER->value);
126+
$existingDefinition->setAdminOnly(false);
127+
$existingDefinition->setUserEditable(false);
128+
$existingDefinition->setUserVisible(true);
129+
$existingDefinition->setInitialVisibility('users');
130+
131+
$this->fieldDefinitionService->expects($this->once())
132+
->method('findByFieldKey')
133+
->with('cost_center')
134+
->willReturn($existingDefinition);
135+
136+
$this->expectException(InvalidArgumentException::class);
137+
$this->expectExceptionMessage('definitions[0].field_key conflicts with an incompatible existing definition');
138+
139+
$this->validator->validate([
140+
'schema_version' => 1,
141+
'definitions' => [[
142+
'field_key' => 'cost_center',
143+
'label' => 'Cost center',
144+
'type' => FieldType::TEXT->value,
145+
]],
146+
'values' => [],
147+
]);
148+
}
149+
}

0 commit comments

Comments
 (0)