add route to search instances by field value

This commit is contained in:
2026-07-21 20:43:36 +02:00
parent dc5a8897e0
commit 9c5e089573
8 changed files with 632 additions and 12 deletions
+157
View File
@@ -0,0 +1,157 @@
<?php
namespace Tests\Unit;
use Api\Core\HttpClient;
use ElixForms\Auth\ElixFormsApiClient;
use ElixForms\Auth\ElixFormsRequestStatus;
use PHPUnit\Framework\TestCase;
final class ElixFormsApiClientTest extends TestCase
{
public function testLookupByStatusOmitsStatusWhenItIsNull(): void
{
$httpClient = new class extends HttpClient {
public string $url = '';
public array $headers = [];
public function get(string $url, array $headers = [])
{
$this->url = $url;
$this->headers = $headers;
return [
'status' => 200,
'json' => [
'value' => [
'globalStatus' => 'OK',
'requests' => [['requestId' => 123]],
],
],
];
}
};
$client = new ElixFormsApiClient('https://example.test', $httpClient);
$requests = $client->lookupByStatus('MODULO TEST', 'token', 'user');
self::assertSame([['requestId' => 123]], $requests);
self::assertStringNotContainsString('requestStatus=', $httpClient->url);
self::assertStringContainsString('moduleTag=MODULO%20TEST', $httpClient->url);
self::assertSame('Bearer token', $httpClient->headers['Authorization']);
self::assertSame('user', $httpClient->headers['x-api-username']);
}
public function testLookupByStatusExpandsCombinedFlags(): void
{
$httpClient = new class extends HttpClient {
public string $url = '';
public function get(string $url, array $headers = [])
{
$this->url = $url;
return [
'status' => 200,
'json' => [
'value' => [
'globalStatus' => 'OK',
'requests' => [],
],
],
];
}
};
$client = new ElixFormsApiClient('https://example.test', $httpClient);
$client->lookupByStatus(
'MODULO',
'token',
'user',
ElixFormsRequestStatus::IN_PROGRESS | ElixFormsRequestStatus::PROCESSED
);
self::assertStringContainsString('requestStatus=IN_PROGRESS', $httpClient->url);
self::assertStringNotContainsString('requestStatus=SUBMITTED', $httpClient->url);
self::assertStringContainsString('requestStatus=PROCESSED', $httpClient->url);
}
public function testRequestStatusRejectsUnknownFlags(): void
{
$this->expectException(\InvalidArgumentException::class);
ElixFormsRequestStatus::toApiValues(8);
}
public function testGetExportTagsSupportsVendorJsonContentTypeResponses(): void
{
$httpClient = new class extends HttpClient {
public string $url = '';
public function get(string $url, array $headers = [])
{
$this->url = $url;
return [
'status' => 200,
'body' => json_encode([
'value' => [
'globalStatus' => 'OK',
'exportTags' => [
['name' => 'contratto.id', 'value' => 'ABC-123'],
],
],
]),
'json' => null,
];
}
};
$client = new ElixFormsApiClient('https://example.test/', $httpClient);
$tags = $client->getExportTags(42, 'MODULO', 'token', 'user');
self::assertSame(
[['name' => 'contratto.id', 'value' => 'ABC-123']],
$tags
);
self::assertSame(
'https://example.test/eF/services/api/request/42/view/_DEFAULT/exportTags/get/v1?moduleTag=MODULO&exportGroup=API',
$httpClient->url
);
}
public function testGetExportTagsUsesTheProvidedExportGroup(): void
{
$httpClient = new class extends HttpClient {
public string $url = '';
public function get(string $url, array $headers = [])
{
$this->url = $url;
return [
'status' => 200,
'json' => [
'value' => [
'globalStatus' => 'OK',
'exportTags' => [],
],
],
];
}
};
$client = new ElixFormsApiClient('https://example.test', $httpClient);
$client->getExportTags(42, 'MODULO', 'token', 'user', 'REPORT ORE');
self::assertStringContainsString('exportGroup=REPORT%20ORE', $httpClient->url);
}
public function testGetExportTagsRejectsAnEmptyExportGroup(): void
{
$this->expectException(\InvalidArgumentException::class);
$httpClient = new HttpClient();
$client = new ElixFormsApiClient('https://example.test', $httpClient);
$client->getExportTags(42, 'MODULO', 'token', 'user', ' ');
}
}
+147
View File
@@ -0,0 +1,147 @@
<?php
namespace Tests\Unit;
use Api\Controllers\V1\ElixFormsController;
use Api\Core\Config;
use Api\Core\Request;
use Api\Core\Response;
use ElixForms\Auth\ElixFormsApiClient;
use ElixForms\Auth\ElixFormsAuthenticationClient;
use PHPUnit\Framework\TestCase;
final class ElixFormsControllerTest extends TestCase
{
public function testSearchInstancesReturnsOnlyMatchingInstances(): void
{
$authenticationClient = new class extends ElixFormsAuthenticationClient {
public function __construct()
{
}
public function login(string $username, string $password): string
{
return 'token';
}
};
$apiClient = new class extends ElixFormsApiClient {
public function __construct()
{
}
public function lookupByStatus(
string $moduleTag,
string $authToken,
string $username,
?int $status = null
): array
{
return [
['idDomanda' => 10],
['requestId' => 20],
['idRequest' => 30],
];
}
public function getExportTags(
$requestId,
string $moduleTag,
string $authToken,
string $username,
string $exportGroup = 'API'
): array
{
if ($exportGroup !== 'CUSTOM') {
throw new \RuntimeException('exportGroup non inoltrato al client.');
}
$values = [
10 => 'Nessuna corrispondenza',
20 => 'Il contratto ABC-123 è presente',
30 => 'Altro valore',
];
return [[
'name' => 'contratto.id',
'value' => $values[$requestId],
]];
}
};
$config = new class extends Config {
public function secret($key, $default = null)
{
return $key === 'elixforms_api_username' ? 'user' : 'password';
}
};
$request = new class extends Request {
public function query()
{
return [
'moduleTag' => 'MODULO',
'fieldName' => 'contratto.id',
'fieldValue' => 'abc-123',
'exportGroup' => ' CUSTOM ',
];
}
};
$response = new CapturingResponse();
$controller = new ElixFormsController($authenticationClient, $apiClient, $config);
try {
$controller->searchInstances($request, $response);
self::fail('La risposta avrebbe dovuto interrompere il flusso del test.');
} catch (CapturedResponseException $exception) {
self::assertSame(200, $exception->status);
self::assertSame([['requestId' => 20]], $exception->payload);
}
}
public function testSearchInstancesRejectsMissingParameters(): void
{
$authenticationClient = new class extends ElixFormsAuthenticationClient {
public function __construct()
{
}
};
$apiClient = new class extends ElixFormsApiClient {
public function __construct()
{
}
};
$config = new Config();
$request = new class extends Request {
public function query()
{
return ['moduleTag' => 'MODULO'];
}
};
$controller = new ElixFormsController($authenticationClient, $apiClient, $config);
try {
$controller->searchInstances($request, new CapturingResponse());
self::fail('La risposta avrebbe dovuto interrompere il flusso del test.');
} catch (CapturedResponseException $exception) {
self::assertSame(400, $exception->status);
}
}
}
final class CapturingResponse extends Response
{
public function json($data, $status = 200)
{
throw new CapturedResponseException($data, $status);
}
}
final class CapturedResponseException extends \RuntimeException
{
public $payload;
public int $status;
public function __construct($payload, int $status)
{
parent::__construct('Response captured');
$this->payload = $payload;
$this->status = $status;
}
}