# Licitações Antigas — Estratégia de Testes

---

## 1. Estado atual

| Item | Situação |
|---|---|
| Testes do módulo legado em `v5` | **Nenhum** — `v5/tests/Feature/` contém apenas `ExampleTest.php` (nenhum caso de licitações legadas). |
| Testes do módulo legado em `v6` | **Nenhum** — `v6/tests/Feature/` contém apenas casos do Dashboard (ex.: `v6/tests/Feature/DashboardLicitacoesWidgetTest.php`, que testa o widget de licitações **novas**). |
| Cobertura de rotas do portal em geral | Não há suíte de rotas do portal. |

Consequência: toda a funcionalidade do módulo legado (listagem, filtros,
detalhe, anexos) está **não testada** no legado. A v7 precisa cobrir 100%
dela.

## 2. Estratégia v7

| Camada | Tipo | Ferramenta |
|---|---|---|
| Listagem e filtros | Feature (HTTP) | PHPUnit + `RefreshDatabase` + factories |
| Detalhe e 404 | Feature (HTTP) | idem |
| Busca textual (acentos, case) | Feature | idem |
| Sanitização de HTML | Unit | idem |
| Model (casts, relações) | Unit | idem |
| Importação do acervo | Feature (job) | idem |

Comandos (Laravel 11/12):

```bash
php artisan test --filter=LegacyBidding
php artisan test --testsuite=Feature --filter=LegacyBiddingIndexTest
php artisan test --filter=LegacyBiddingSanitizerTest
```

Fixtures de banco: `Database\Factories\LegacyBiddingFactory`,
`LegacyBiddingArchiveFactory`, `LegacyModalityFactory`,
`LegacyJurisdictionFactory`. As tabelas de dados legados devem ser populadas
por seeder de testes (`LegacyBiddingSeeder`) para garantir ao menos:

- 1 registro sem anexos;
- 1 registro com 2 anexos;
- registros em 2 anos distintos (para validar o filtro de ano e a lista de anos);
- 1 registro com `body_html` contendo acento e maiúsculas (para a busca).

## 3. Casos de teste — listagem

| # | Arrange | Act | Assert |
|---|---|---|---|
| L1 | 12 licitações legadas | `GET /licitacoes-ate-2018` | HTTP 200;(view renderizada; 10 itens na página 1) |
| L2 | 12 licitações | `GET /licitacoes-ate-2018?page=2` | 2 itens; paginação preserva filtros quando informados |
| L3 | 3 licitações, uma de 2015, duas de 2016 | `GET ...?ano=2016` | somente as de 2016 na resposta |
| L4 | modalidades 1 e 2 | `GET ...?tipo_modalidade=2` | só as de modalidade 2 |
| L5 | secretarias 1 e 2 | `GET ...?ids_secretarias=1` | só as da secretaria 1 |
| L6 | registro com "Edital de Pregão Presencial" e outro com "TOMADA DE PREÇOS" | `GET ...?informacoes=pregao` | apenas o primeiro (case-insensitive) |
| L7 | registro com "TOMADA DE PREÇOS" | `GET ...?informacoes=tomada de precos` | o registro é encontrado (acento e espaço ignorados) |
| L8 | nenhum registro | `GET /licitacoes-ate-2018` | HTTP 200 e mensagem "Nenhuma informação encontrada!" |
| L9 | 3 registros em 2015/2016/2017 | `GET /licitacoes-ate-2018` | o filtro de ano lista 2017, 2016, 2015 em ordem decrescente |
| L10 | 2 registros com datas 2020-01-01 e 2021-01-01 | `GET /licitacoes-ate-2018` | o mais recente aparece primeiro (ordenação por `published_at` desc) |
| L11 | — | `GET /licitacoes-ate-2018?tipo_modalidade=abc` | HTTP 422 (Form Request) |
| L12 | — | `GET /licitacoes-ate-2018?ano=99999` | HTTP 422 |

## 4. Casos de teste — detalhe

| # | Arrange | Act | Assert |
|---|---|---|---|
| D1 | licença existente | `GET /licitacoes-ate-2018/{id}` | HTTP 200; título, data por extenso e corpo HTML presentes |
| D2 | licença com 2 anexos existentes no storage | `GET /licitacoes-ate-2018/{id}` | 2 links de download com o caminho `legacy-biddings/{id}/{arquivo}` |
| D3 | licença cujo anexo não existe no storage | `GET /licitacoes-ate-2018/{id}` | não há link de download para o anexo ausente (sem erro) |
| D4 | — | `GET /licitacoes-ate-2018/999999` | HTTP 404 |
| D5 | — | `GET /licitacoes-ate-2018/abc` | HTTP 404 (não 500) |
| D6 | `body_html` com `<script>alert(1)</script>` | `GET /licitacoes-ate-2018/{id}` | o `<script>` é removido/sanitizado na resposta |
| D7 | licença existente | `GET /licitacoes-ate-2018/{id}` | a resposta contém link de retorno para `licitacoes.old.index` |

## 5. Casos de teste — unidade

| # | Alvo | Assert |
|---|---|---|
| U1 | `LegacyBidding` cast | `published_at` é instância de `Carbon` e formata `d/m/Y` |
| U2 | relação `archives` | retorna os anexos da licitação |
| U3 | relação `modality` / `jurisdiction` | retorna o registro do catálogo correto |
| U4 | sanitizador de HTML | remove `<script>` e `onclick`, preserva `<p>`, `<strong>`, `<table>` |
| U5 | anos distintos | a lista de anos não tem duplicatas e está em ordem decrescente |
| U6 | `LegacyBiddingIndexRequest` | rejeita `ano` fora de faixa, `tipo_modalidade` inexistente e `informacoes` > 255 |

## 6. Testes de regressão "equivalência funcional"

Objetivo: garantir que a v7 reproduz o comportamento observável do legado.

| Cenário legado | Expectativa na v7 |
|---|---|
| `GET /licitacoes-ate-2018` sem filtros | mesma quantidade de itens por página (10) e mesma ordenação por data decrescente |
| `GET /licitacoes-ate-2018?ano=2016` | mesmo conjunto de resultados que o legado para a mesma base |
| `GET /licitacoes-ate-2018?informacoes=licitacao` | mesmo conjunto de resultados (ignorando acentos e maiúsculas) |
| `GET /licitacoes-ate-2018/{id}` | mesmas informações exibidas (título, data, corpo, anexos) |

A comparação pode ser automatizada com um *harness* que executa as duas
versões contra o mesmo dump de dados e compara os conjuntos de IDs retornados.

## 7. Fixtures de view / seed

- `configurations` precisa ter `layout = 'modelo1'` (ou o template escolhido)
  para o teste de renderização; no Laravel moderno a resolução de layout deve
  ser testada com um stub, sem depender do banco.
- Seed de dados legados é obrigatório para qualquer teste de feature — usar
  factories, não o banco de produção.
- Teste de sanidade do acervo: um comando Artisan
  (`php artisan legacy:report`) que informa contagem e faixa de anos, útil
  como verificação pré-migração e como smoke test de ambiente.

## 8. Não testado (e por quê)

| Item | Motivo |
|---|---|
| Integração com o CMS de módulos (`modulos.status`) | O status do módulo não afeta as rotas do legado; na v7 o comportamento deve ser definido explicitamente antes de testar. |
| Upload de anexos pelo CMS | Não existe no legado (módulo somente leitura). |
| Exportação | Não existe no legado. |
