# 📚 Documentación de Pruebas Unitarias - Back-trackingpremium-api-v2

---

## 1. ¿Qué son las Pruebas Unitarias? 🔬

Las pruebas unitarias (o **unit tests**) son un método de desarrollo de software que consiste en verificar el funcionamiento correcto de las partes más pequeñas y aisladas del código (como funciones, métodos o clases) de manera independiente.

> **Ejemplo**: Probar el método `getFullName()` de `UserService`  
> — No pruebas la base de datos, no pruebas el controlador, solo ese método.

---

## 2. Estructura del Proyecto de Pruebas 📁

```
Back-trackingpremium-api-v2/
├── src/                          ← Código fuente
│   ├── Service/
│   ├── Module/
│   └── Controller/
│
├── tests/                        ← Pruebas (ESTO ES LO QUE VEREMOS)
│   ├── Unit/                     ← Pruebas de UNIDAD
│   │   ├── Module/               ← Pruebas por características
│   │   │   └── LabelOcr/Application/Parser/  ← Probando parsers de OCR
│   │   └── Service/              ← Pruebas de servicios individuales
│   │       └── Customer/
│   │
│   └── Integration/              ← Pruebas de INTEGRACIÓN (API completa)
│
└── phpunit.xml.dist              ← Configuración de PHPUnit
```

---

## 3. Tipos de Pruebas en Este Proyecto 🎯

### 3.1. Pruebas de Parsers (Lector de etiquetas OCR)

| Aspecto | Descripción |
|---------|-------------|
| **¿Qué son?** | Prueban que el sistema puede leer e interpretar etiquetas de diferentes empresas de paquetería (Amazon, UPS, FedEx, DHL, USPS). |
| **¿Dónde están?** | `tests/Unit/Module/LabelOcr/Application/Parser/` |
| **Framework** | PHPUnit |

#### Ejemplo concreto: `AmazonLabelParserTest.php`

| Método de prueba | Qué prueba |
|------------------|------------|
| `testSupportsKeywords()` | ¿El parser reconoce una etiqueta de Amazon? |
| `testParsesShipToAndTba()` | ¿Extrae correctamente el destinatario y el tracking? |

---

### 3.2. Pruebas de Servicios (Lógica de negocio)

| Aspecto | Descripción |
|---------|-------------|
| **¿Qué son?** | Prueban servicios como `ProcessLabelOcrService`, `CustomerRecipientMatcher`, etc. |
| **¿Dónde están?** | `tests/Unit/Service/` |
| **Enfoque** | Testing de lógica de negocio con diversos escenarios |

#### Ejemplo concreto: `CustomerRecipientMatcherTest.php`

> **Qué prueba**: ¿El sistema encuentra al cliente correcto cuando llega un paquete?

---

### 3.3. Pruebas de Integración (API completa)

| Aspecto | Descripción |
|---------|-------------|
| **¿Qué son?** | Prueban controladores enteros, haciendo peticiones HTTP reales. |
| **¿Dónde están?** | `tests/Integration/` |

#### Ejemplo concreto: `ReceiptFromLabelPhotoControllerTest.php`

> **Qué prueba**:
> 1. Hace una petición POST a `/api/receipt/from-label-photo`
> 2. Verifica que la respuesta sea 200
> 3. Verifica que el JSON devuelto tenga los campos esperados

---

## 4. Cómo Ejecutar las Pruebas ⚡

### Comandos básicos

```bash
# 1. Ejecutar TODAS las pruebas
php bin/phpunit

# 2. Ejecutar solo pruebas UNITARIAS (más rápidas)
php bin/phpunit --testsuite Unit

# 3. Ejecutar una prueba específica (archivo)
php bin/phpunit tests/Unit/Module/LabelOcr/Application/Parser/AmazonLabelParserTest.php

# 4. Ejecutar un método específico dentro de una prueba
php bin/phpunit --filter=testParsesShipToAndTba

# 5. Ver cobertura de código (qué % del código está probado)
php bin/phpunit --coverage-text

# 6. Generar reporte HTML de cobertura
php bin/phpunit --coverage-html coverage/
```

---

## 5. Cómo Crear una Prueba Nueva 📝

### 5.1. Identificar qué quieres probar

> **Ejemplo**: Quieres probar el método `getFullName()` de `UserService.php`

### 5.2. Crear el archivo de prueba

```bash
touch tests/Unit/Service/UserServiceTest.php
```

### 5.3. Estructura básica de una prueba

```php
<?php

namespace App\Tests\Unit\Service;

use PHPUnit\Framework\TestCase;
use App\Service\UserService;

class UserServiceTest extends TestCase
{
    // Tu prueba aquí
}
```

### 5.4. Escribir tu primera prueba

```php
public function testGetFullNameReturnsFullNameCorrectly(): void
{
    // 1. Preparar (Arrange)
    $userService = new UserService();

    // 2. Ejecutar (Act)
    $result = $userService->getFullName('Juan', 'Perez');

    // 3. Verificar (Assert)
    $this->assertSame('Juan Perez', $result);
}
```

### 5.5. Ejecutar tu prueba

```bash
php bin/phpunit tests/Unit/Service/UserServiceTest.php
```

---

## 6. Plantilla Común de Pruebas en Este Proyecto 📋

```php
class AmazonLabelParserTest extends TestCase
{
    // Helper para crear el parser
    private function parser(): AmazonLabelParser
    {
        return new AmazonLabelParser();
    }

    // Helper para crear DTOs desde texto
    private function dtoFromRaw(string $raw): ProcessOcrResult
    {
        return new ProcessOcrResult($raw);
    }

    // Prueba 1: ¿Reconoce la etiqueta?
    public function testSupportsKeywords(): void
    {
        self::assertTrue($this->parser()->supports('amazon.com'));
        self::assertFalse($this->parser()->supports('fedex.com'));
    }

    // Prueba 2: ¿Extrae los datos correctamente?
    public function testParsesShipToAndTba(): void
    {
        $raw = "Ship To: John Doe\nTBA123456789";
        $dto = $this->dtoFromRaw($raw);

        $result = $this->parser()->parse($dto);

        self::assertSame('John Doe', $result->getConsignee());
        self::assertSame('TBA123456789', $result->getTracking());
    }
}
```

---

## 7. Aserciones Comunes en PHPUnit ✅

| Aserción | Uso |
|----------|-----|
| `assertSame($expected, $actual)` | Verifica que dos valores sean idénticos |
| `assertTrue($condition)` | Verifica que una condición sea verdadera |
| `assertFalse($condition)` | Verifica que una condición sea falsa |
| `assertNull($value)` | Verifica que un valor sea nulo |
| `assertNotNull($value)` | Verifica que un valor no sea nulo |
| `assertCount($expected, $array)` | Verifica la cantidad de elementos |
| `assertContains($needle, $haystack)` | Verifica que contenga un elemento |
| `assertGreaterThanOrEqual($min, $actual)` | Verifica que sea mayor o igual |

---

## 8. Configuración del Proyecto ⚙️

| Elemento | Valor |
|----------|-------|
| **PHP Version** | >=8.2 |
| **Testing Framework** | PHPUnit 11 |
| **Symfony Version** | 7.4 |
| **Config File** | `phpunit.xml.dist` |
| **Bootstrap** | `tests/bootstrap.php` |

---

## 9. Lista de Tests Disponibles 📋

### Parsers

- `AmazonLabelParserTest.php`
- `UpsLabelParserTest.php`
- `FedexLabelParserTest.php`
- `DhlLabelParserTest.php`
- `UspsLabelParserTest.php`
- `SpeedXLabelParserTest.php`
- `GoFoLabelParserTest.php`
- `GenericLabelParserTest.php`
- `HybridLabelParserTest.php`
- `ScoringLabelParserResolverTest.php`
- `LabelParserResolverTest.php`

### Servicios

- `ProcessLabelOcrServiceTest.php`
- `CustomerRecipientMatcherTest.php`
- `RecipientNameNormalizerTest.php`
- `OcrCustomerMatcherServiceTest.php`
- `CreateReceiptFromLabelPhotoServiceTest.php`
- `OcrDocumentCreationLogServiceTest.php`
- `OcrTransportMetadataResolverTest.php`

### Módulo LabelOcr

- `LabelFieldFusionServiceTest.php`
- `LocalLabelMlExtractorTest.php`

### Integración

- `ReceiptFromLabelPhotoControllerTest.php`

---

*Documento generado para facilitar la comprensión de las pruebas unitarias del proyecto Back-trackingpremium-api-v2* 🚀