Skip to content

Commit 537bbab

Browse files
committed
Se ha estandarizado correctamente el API Client y los tests. Se ha modificado bootstrap.php para que pueda obtener variables de entorno correctamente.
1 parent 85c461c commit 537bbab

19 files changed

Lines changed: 198 additions & 134 deletions

src/ApiClient.php

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,11 @@ class ApiClient
7373
* @param string|null $url URL base de la API de LibreDTE.
7474
* @throws ApiException si el hash de autenticación no está presente.
7575
*/
76-
public function __construct($hash = null, $url = null)
76+
public function __construct(string $hash = null, string $url = null)
7777
{
7878
$hash = $hash ?: $this->env('LIBREDTE_HASH');
7979
if (!$hash) {
80-
throw new ApiException('LIBREDTE_HASH missing');
80+
throw new ApiException(message: 'LIBREDTE_HASH missing');
8181
}
8282
$this->headers['Authorization'] = 'Basic ' . base64_encode(
8383
$hash . ':X'
@@ -94,8 +94,9 @@ public function __construct($hash = null, $url = null)
9494
*
9595
* @param string $name Nombre de la cabecera.
9696
* @param mixed $value Valor de la cabecera.
97+
* @return void
9798
*/
98-
public function setHeader(string $name, $value)
99+
public function setHeader(string $name, mixed $value): void
99100
{
100101
$this->headers[$name] = $value;
101102
}
@@ -108,8 +109,9 @@ public function setHeader(string $name, $value)
108109
*
109110
* @param boolean $sslcheck Activar o desactivar la verificación del
110111
* certificado SSL.
112+
* @return void
111113
*/
112-
public function setSSL($sslcheck = true)
114+
public function setSSL($sslcheck = true): void
113115
{
114116
$this->client->setSSL($sslcheck);
115117
}
@@ -120,18 +122,18 @@ public function setSSL($sslcheck = true)
120122
* Envia datos a un recurso específico de la API utilizando el método POST.
121123
*
122124
* @param string $resource El recurso de la API a solicitar.
123-
* @param mixed $data Los datos a enviar en la solicitud POST.
125+
* @param mixed|null $data Los datos a enviar en la solicitud POST.
124126
* @param array $headers Encabezados adicionales para la solicitud.
125127
* @return array Respuesta de la API.
126128
*/
127-
public function post($resource, $data = null, array $headers = [])
129+
public function post(string $resource, mixed $data = null, array $headers = []): array|bool
128130
{
129131
$headers = array_merge($this->headers, $headers);
130132
return $this->client->query(
131-
'POST',
132-
$this->api_url . $this->api_prefix . $resource,
133-
$data,
134-
$headers
133+
method: 'POST',
134+
url: $this->api_url . $this->api_prefix . $resource,
135+
data: $data,
136+
headers: $headers
135137
);
136138
}
137139

@@ -142,18 +144,18 @@ public function post($resource, $data = null, array $headers = [])
142144
* GET.
143145
*
144146
* @param string $resource El recurso de la API a solicitar.
145-
* @param mixed $data Los datos a enviar en la solicitud GET.
147+
* @param mixed|null $data Los datos a enviar en la solicitud GET.
146148
* @param array $headers Encabezados adicionales para la solicitud.
147149
* @return array Respuesta de la API.
148150
*/
149-
public function get($resource, $data = null, array $headers = [])
151+
public function get(string $resource, mixed $data = null, array $headers = []): array|bool
150152
{
151153
$headers = array_merge($this->headers, $headers);
152154
return $this->client->query(
153-
'GET',
154-
$this->api_url . $this->api_prefix . $resource,
155-
$data,
156-
$headers
155+
method: 'GET',
156+
url: $this->api_url . $this->api_prefix . $resource,
157+
data: $data,
158+
headers: $headers
157159
);
158160
}
159161

@@ -164,10 +166,10 @@ public function get($resource, $data = null, array $headers = [])
164166
* como el hash de autenticación o la URL base de la API.
165167
*
166168
* @param string $name Nombre de la variable de entorno.
167-
* @return string|null Valor de la variable de entorno o null si no está
169+
* @return mixed|null Valor de la variable de entorno o null si no está
168170
* definida.
169171
*/
170-
private function env($name)
172+
private function env($name): mixed
171173
{
172174
return function_exists('env') ? env($name) : getenv($name);
173175
}

src/HttpCurlClient.php

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class HttpCurlClient
5454
*
5555
* @return array Lista de errores de cURL.
5656
*/
57-
public function getErrors()
57+
public function getErrors(): array
5858
{
5959
return $this->errors;
6060
}
@@ -67,7 +67,7 @@ public function getErrors()
6767
*
6868
* @return string Descripción del último error de cURL.
6969
*/
70-
public function getLastError()
70+
public function getLastError(): string
7171
{
7272
return $this->errors[count($this->errors) - 1];
7373
}
@@ -81,7 +81,7 @@ public function getLastError()
8181
* @param boolean $sslcheck Activar o desactivar la verificación del
8282
* certificado SSL.
8383
*/
84-
public function setSSL($sslcheck = true)
84+
public function setSSL(bool $sslcheck = true): void
8585
{
8686
$this->sslcheck = $sslcheck;
8787
}
@@ -99,8 +99,12 @@ public function setSSL($sslcheck = true)
9999
* @param array $headers Cabeceras HTTP a enviar.
100100
* @return array|false Respuesta HTTP o false en caso de error.
101101
*/
102-
public function query($method, string $url, $data = [], array $headers = [])
103-
{
102+
public function query(
103+
string $method,
104+
string $url,
105+
mixed $data = [],
106+
array $headers = []
107+
): array|bool {
104108
// preparar datos
105109
if ($data && $method != 'GET') {
106110
if (isset($data['@files'])) {
@@ -148,13 +152,19 @@ public function query($method, string $url, $data = [], array $headers = [])
148152
$this->errors[] = curl_error($curl);
149153
return false;
150154
}
151-
$headers_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
155+
$headers_size = curl_getinfo(handle: $curl, option: CURLINFO_HEADER_SIZE);
152156
// cerrar conexión de curl
153157
curl_close($curl);
154158
// entregar respuesta de la solicitud
155-
$response_headers = $this->parseResponseHeaders(substr($response, 0, $headers_size));
159+
$response_headers = $this->parseResponseHeaders(
160+
substr(
161+
string: $response,
162+
offset: 0,
163+
length: $headers_size
164+
)
165+
);
156166
$body = substr($response, $headers_size);
157-
$json = json_decode($body, true);
167+
$json = json_decode(json: $body, associative: true);
158168
return [
159169
'status' => $this->parseResponseStatus($response_headers[0]),
160170
'header' => $response_headers,
@@ -173,7 +183,7 @@ public function query($method, string $url, $data = [], array $headers = [])
173183
* @param string $headers_txt Cabeceras HTTP en formato de texto plano.
174184
* @return array Arreglo asociativo con las cabeceras procesadas.
175185
*/
176-
private function parseResponseHeaders($headers_txt)
186+
private function parseResponseHeaders(string $headers_txt): array
177187
{
178188
$headers = [];
179189
$lineas = explode("\n", $headers_txt);
@@ -183,7 +193,11 @@ private function parseResponseHeaders($headers_txt)
183193
continue;
184194
}
185195
if (strpos($linea, ':')) {
186-
list($key, $value) = explode(':', $linea, 2);
196+
list($key, $value) = explode(
197+
separator: ':',
198+
string: $linea,
199+
limit: 2
200+
);
187201
} else {
188202
$key = 0;
189203
$value = $linea;
@@ -214,12 +228,12 @@ private function parseResponseHeaders($headers_txt)
214228
* @return array Arreglo con información del estado, incluyendo protocolo,
215229
* código y mensaje.
216230
*/
217-
private function parseResponseStatus($response_line)
231+
private function parseResponseStatus(array|string $response_line): array
218232
{
219233
if (is_array($response_line)) {
220234
$response_line = $response_line[count($response_line) - 1];
221235
}
222-
$parts = explode(' ', $response_line, 3);
236+
$parts = explode(separator: ' ', string: $response_line, limit: 3);
223237
return [
224238
'protocol' => $parts[0],
225239
'code' => $parts[1],

tests/bootstrap.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@
4141

4242
/**
4343
* Función que carga una variable de entorno o su valor por defecto
44-
* @param varname Variable que se desea consultar
45-
* @param default Valor por defecto de la variable
44+
* @param string varname Variable que se desea consultar
45+
* @param mixed|null default Valor por defecto de la variable
4646
*/
47-
function env($varname, $default = null)
47+
function env(string $varname, mixed $default = null)
4848
{
4949
if (isset($_ENV[$varname])) {
5050
return $_ENV[$varname];

tests/dte_facturacion/AbstractDteFacturacion.php

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@
2929

3030
abstract class AbstractDteFacturacion extends TestCase
3131
{
32-
/**
33-
* Variable para desplegar resultados.
34-
*
35-
* @var bool
36-
*/
32+
/**
33+
* Variable para desplegar resultados.
34+
*
35+
* @var bool
36+
*/
3737
protected static $verbose;
3838

3939
/**
@@ -97,10 +97,12 @@ abstract class AbstractDteFacturacion extends TestCase
9797
*/
9898
public static function setUpBeforeClass(): void
9999
{
100-
self::$verbose = (bool)env('TEST_VERBOSE', 'false');
101-
self::$emisor_rut = (explode(
102-
'-',
103-
(string)env('LIBREDTE_RUT'))[0]
100+
self::$verbose = (bool)env(varname: 'TEST_VERBOSE', default: 'false');
101+
self::$emisor_rut = (
102+
explode(
103+
'-',
104+
(string)env('LIBREDTE_RUT')
105+
)[0]
104106
);
105107
self::$datos['Encabezado']['Emisor']['RUTEmisor'] = env(
106108
'LIBREDTE_RUT'
@@ -119,7 +121,10 @@ protected function listarDteTemp(): array
119121
{
120122
// Se crea el filtro a utilizar, en este caso fechas de búsqueda.
121123
$filtros = [
122-
'fecha_desde' => date('Y-m-d', strtotime('-30 days')),
124+
'fecha_desde' => date(
125+
format: 'Y-m-d',
126+
timestamp: strtotime('-30 days')
127+
),
123128
'fecha_hasta' => date('Y-m-d'),
124129
];
125130
// Se genera el recurso a consumir.
@@ -128,13 +133,13 @@ protected function listarDteTemp(): array
128133
self::$emisor_rut
129134
);
130135
// Se envía la solicitud http y se guarda su respuesta.
131-
$response = self::$client->post($resource, $filtros);
136+
$response = self::$client->post(resource: $resource, data: $filtros);
132137

133138
// Si el código http no es '200', arroja error ApiException.
134139
if ($response['status']['code'] !== '200') {
135140
throw new ApiException(
136-
$response['body'],
137-
(int)$response['status']['code']
141+
message: $response['body'],
142+
code: (int)$response['status']['code']
138143
);
139144
}
140145

@@ -153,19 +158,19 @@ protected function emitirDteTemp(): array
153158
{
154159
// Se envía la solicitud http y se guarda su respuesta.
155160
$response = self::$client->post(
156-
'/dte/documentos/emitir',
157-
self::$datos
161+
resource: '/dte/documentos/emitir',
162+
data: self::$datos
158163
);
159164

160165
// Si el código http no es '200', arroja error ApiException.
161166
if ($response['status']['code'] !== '200') {
162167
throw new ApiException(
163-
$response['body'],
164-
(int)$response['status']['code']
168+
message: $response['body'],
169+
code: (int)$response['status']['code']
165170
);
166171
}
167172

168173
// Retorna la respuesta http.
169174
return $response;
170175
}
171-
}
176+
}

tests/dte_facturacion/BuscarDteTempTest.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,19 +50,19 @@ public function testBuscarDteTemp(): void
5050
// Se genera el recurso para buscar el DTE temporal generado.
5151
$resource = sprintf(
5252
"/dte/dte_tmps/info/%d/%d/%s/%d",
53-
$dte_temp['body']['receptor'],
54-
$dte_temp['body']['dte'],
55-
$dte_temp['body']['codigo'],
56-
self::$emisor_rut
53+
$dte_temp['body']['receptor'],
54+
$dte_temp['body']['dte'],
55+
$dte_temp['body']['codigo'],
56+
self::$emisor_rut
5757
);
5858

5959
// Se envía la solicitud http y se guarda su respuesta.
6060
$response = self::$client->get($resource);
6161
// Si el código http no es '200', arroja error ApiException.
6262
if ($response['status']['code'] !== '200') {
6363
throw new ApiException(
64-
$response['body'],
65-
(int)$response['status']['code']
64+
message: $response['body'],
65+
code: (int)$response['status']['code']
6666
);
6767
}
6868
// Se obtiene el body de la lista.
@@ -86,4 +86,4 @@ public function testBuscarDteTemp(): void
8686
));
8787
}
8888
}
89-
}
89+
}

tests/dte_facturacion/DescargarPdfDteTempTest.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class DescargarPdfDteTempTest extends AbstractDteFacturacion
4242
*
4343
* @return void
4444
*/
45-
public function testDescargarPdfTemp(): void
45+
public function testDescargarPdfDteTemp(): void
4646
{
4747
try {
4848
// Se emite un DTE temporal para ejecutar esta prueba.
@@ -63,8 +63,8 @@ public function testDescargarPdfTemp(): void
6363
// Si el código http no es '200', arroja error ApiException.
6464
if ($response['status']['code'] !== '200') {
6565
throw new ApiException(
66-
$response['body'],
67-
(int)$response['status']['code']
66+
message: $response['body'],
67+
code: (int)$response['status']['code']
6868
);
6969
}
7070
// Se compara el código con '200' Si no es 200, la prueba falla.
@@ -75,7 +75,8 @@ public function testDescargarPdfTemp(): void
7575
$currentDir = __DIR__;
7676

7777
// Nueva ruta relativa para guardar el archivo PDF en "tests/archivos"
78-
$targetDir = dirname($currentDir) . '/archivos/dte_facturacion';
78+
$targetDir = dirname($currentDir) .
79+
'/archivos/dte_facturacion';
7980

8081
// Define el nombre del archivo PDF en el nuevo directorio
8182
$filename = $targetDir . '/' . sprintf(
@@ -87,7 +88,7 @@ public function testDescargarPdfTemp(): void
8788

8889
// Verifica si el directorio existe, si no, créalo
8990
if (!is_dir($targetDir)) {
90-
mkdir($targetDir, 0777, true);
91+
mkdir(directory: $targetDir, permissions: 0777, recursive: true);
9192
}
9293

9394
// Se genera el archivo PDF.

tests/dte_facturacion/EliminarDteTempTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class EliminarDteTempTest extends AbstractDteFacturacion
4141
*
4242
* @return void
4343
*/
44-
public function testEliminarDteTemp()
44+
public function testEliminarDteTemp(): void
4545
{
4646
// Se emite un DTE temporal para ejecutar esta prueba.
4747
$dte_temp = $this->emitirDteTemp();
@@ -60,8 +60,8 @@ public function testEliminarDteTemp()
6060
// Si el código http no es '200', arroja error ApiException.
6161
if ($response['status']['code'] !== '200') {
6262
throw new ApiException(
63-
$response['body'],
64-
(int)$response['status']['code']
63+
message: $response['body'],
64+
code: (int)$response['status']['code']
6565
);
6666
}
6767
// Se compara el código con '200' Si no es 200, la prueba falla.

0 commit comments

Comments
 (0)