# Banners — Estratégia de Testes

## 1. Estado atual

Não há testes específicos de banners. A suíte de `v6/tests` cobre Dashboard, Google
Analytics e Revisões (ver `v6/tests/Feature/` e `v6/tests/Unit/`), configurada por
`v6/phpunit.xml` (PHPUnit, bootstrap `vendor/autoload.php`).

Não há factories para `Content`, `CategoryContent`, `Archive` ou `Link` em
`v6/database/factories/` — o diretório contém apenas `HighlightFactory.php`,
`ManualAreaFactory.php`, `ManualFactory.php` e `UserFactory.php`.

## 2. Estratégia proposta

| Camada | Arquivo de teste | Foco |
|---|---|---|
| Unit | `tests/Unit/BannerPositionTest.php` | Rótulos de posição por layout |
| Unit | `tests/Unit/BannerViewTest.php` | Projeção das views SQL (`banners`, `super_banners`) |
| Feature | `tests/Feature/BannerControllerTest.php` | CRUD, validação, ativação exclusiva, reordenação |
| Feature | `tests/Feature/SuperBannerControllerTest.php` | `updateSuperBanner` (status, URL, imagem) |
| Feature | `tests/Feature/BannerPortalTest.php` | Renderização no portal (lateral, topo, rodapé) |
| Feature | `tests/Feature/BannerDatatableTest.php` | Endpoint do grid e colunas expostas |

## 3. Fixtures necessárias

```php
// database/factories/CategoryContentFactory.php (trecho)
'category_contents_id' => null,
'slug'      => 'banners',
'name'      => 'Banners',
'status'    => true,
'status_create' => true,
```

```php
// database/factories/ContentFactory.php (trecho)
'title'       => $faker->sentence(3),
'slug'        => $faker->unique()->slug,
'order'       => 1,
'status'      => true,
'category_contents_id' => $categoryId,
```

```php
// database/factories/ArchiveFactory.php (trecho)
'highlight' => 1,
'path'      => 'storage/content/banners/1/destaque/banner.png',
'name'      => 'banner.png',
'extension' => 'png',
'type'      => 'image/png',
'contents_id' => $contentId,
```

```php
// database/factories/LinkFactory.php (trecho)
'contents_id' => $contentId,
'link'        => 'https://exemplo.gov.br',
'isBlank'     => 1,
```

As **views SQL** são dependências do ambiente de teste: é preciso rodar as migrations
`2023_04_10_112025_create_view_to_banners.php`,
`2023_04_18_132413_update_banners_view_to_order.php` e
`2023_04_10_132524_create_view_to_super_banners.php` (ou o seed
`v6/database/seeds/UpdateSuperBannersViewFixEmBaixo.php`) no banco de testes.

## 4. Casos de teste

### 4.1 View SQL (Unit/integração)

| # | Arrange | Act | Assert |
|---|---|---|---|
| V1 | 2 banners na categoria `banners`, `order` 1 e 2 | `select * from banners` | `value` = 1 e 2 na ordem de `c.order` |
| V2 | Banner com `deleted_at` preenchido | `select * from banners` | A linha **não** aparece |
| V3 | Banner de outra categoria | `select * from banners` | Não aparece |
| V4 | Banner com `status = false` | `select * from banners` | `status_name = 'Desativado'` |
| V5 | Super banner com `order = 1`, layout = `modelo5` | `select posicao from super_banners` | `posicao = 'Esquerda'` |
| V6 | Super banner com `order = 1`, layout ≠ `modelo5` | idem | `posicao = 'Em cima'` |
| V7 | Super banner com `order = 2`, layout = `modelo5` | idem | `posicao = 'Direita'` |
| V8 | Super banner com `order = 2`, layout ≠ `modelo5` | idem | `posicao = 'Em baixo'` |
| V9 | Mudar `configurations.key = 'layout'` | `select posicao from super_banners` | O rótulo muda **sem** recriar a view |

### 4.2 CRUD (Feature)

| # | Arrange | Act | Assert |
|---|---|---|---|
| C1 | Categoria `banners` | `GET /cms/conteudos/banners` | HTTP 200 e view `prefecture.contents.banners.index` |
| C2 | Categoria `super-banners` | `GET /cms/conteudos/super-banners` | HTTP 200 |
| C3 | — | `GET /cms/conteudos/cadastrar/banners` | HTTP 200; a view recebe `$categoryContent` da categoria `banners` |
| C4 | — | `POST /cms/conteudo` sem `link` | `assertSessionHasErrors('link')` |
| C5 | — | `POST /cms/conteudo` com `title` > 120 | `assertSessionHasErrors('title')` |
| C6 | — | `POST /cms/conteudo` (rota `conteudo.store`) sem imagem | `assertSessionHasErrors('archive_highlight')` |
| C7 | Conteúdo existente | `PUT /cms/conteudo/{id}` sem imagem | Atualização **sem** erro (imagem só é obrigatória no create) |
| C8 | Conteúdo existente | `DELETE /cms/conteudo/{id}` | Soft delete; some da view `banners` |

### 4.3 Ativação exclusiva (super banner)

| # | Arrange | Act | Assert |
|---|---|---|---|
| A1 | 2 super banners com `order = 1`, ambos ativos | Criar/editar um terceiro com `order = 1` e `status = 1` | Os outros da posição 1 ficam `status = false` |
| A2 | Super banner `order = 2` ativo | Ativar um `order = 1` | O `order = 2` **permanece** ativo |
| A3 | Super banner ativo | `POST /cms/set-status` | Demais da mesma posição são desativados |

### 4.4 Reordenação (Feature)

| # | Arrange | Act | Assert |
|---|---|---|---|
| R1 | 3 banners (`order` 1,2,3) | `POST /cms/ajust-banners` com `[3,1,2]` | `order` = 1,2,3 na nova sequência |
| R2 | — | `POST /cms/ajust-banners` sem `sortable_data` | HTTP 500 (comportamento legado) ou 422 (v7) |

### 4.5 `updateSuperBanner` (Feature)

| # | Arrange | Act | Assert |
|---|---|---|---|
| U1 | 2 super banners (`order` 1 e 2) com links | `POST /cms/update/super-banner` com `check_super_banner_1=1`, `url_super_banner_1=...` | `status` e `link` atualizados |
| U2 | Mesmos banners | `POST` **sem** `check_super_banner_1` | `status` do banner 1 = `0` |
| U3 | Só 1 super banner cadastrado | `POST /cms/update/super-banner` | Erro controlado (não erro fatal) — hoje é **erro fatal** |
| U4 | Banner com imagem | `POST` com `super_banner_1` (arquivo) | Novo arquivo em `storage/content/super-banner/` e `archives.path` atualizado |

### 4.6 Portal (Feature)

| # | Arrange | Act | Assert |
|---|---|---|---|
| P1 | 2 banners laterais ativos | `GET /pagina/{slug}` | A resposta contém os `title`/`alt` dos dois |
| P2 | Banner com `isBlank = 1` | `GET /pagina/{slug}` | O HTML contém `target="_blank"` |
| P3 | Banner sem imagem | `GET /pagina/{slug}` | Usa `storage/img/exemplos/banner-sem-imagem.png` |
| P4 | Banner inativo | `GET /pagina/{slug}` | Não aparece |
| P5 | `modulos.banners` desligado | `GET /` | A faixa de banners não é renderizada |
| P6 | Super banner `order = 1` ativo | `GET /` (modelo1) | A faixa aparece acima das notícias |
| P7 | Super banner `order = 2` ativo | `GET /` (modelo1) | A faixa aparece abaixo das notícias |

### 4.7 Datatable (regressão)

| # | Arrange | Act | Assert |
|---|---|---|---|
| D1 | — | `GET /cms/datatable/banners` | HTTP 200; JSON com `titulo` e `status_name` |
| D2 | — | `GET /cms/datatable/super_banners` | HTTP 200; JSON com `posicao` |
| D3 | Usuário sem `banners.edit` | idem | `edit = false` em todas as linhas |

## 5. Cenários manuais (QA)

1. Arrastar um banner na lista → a ordem persiste após recarregar.
2. Ativar um super banner → o outro da mesma posição é desativado.
3. Trocar o layout do portal (Configurações) → os rótulos de posição mudam.
4. Abrir a home do modelo5 → conferir os blocos de super banner e o carrossel.
5. Abrir a tela "Super Banners" (edição rápida) → hoje **não** aplica as alterações.

## 6. Como rodar

```bash
cd v6

./vendor/bin/phpunit                                   # suíte completa
./vendor/bin/phpunit tests/Feature/BannerControllerTest.php
./vendor/bin/phpunit tests/Feature/BannerPortalTest.php
./vendor/bin/phpunit tests/Unit/BannerViewTest.php

./vendor/bin/phpunit --filter test_ativacao_exclusiva_de_super_banner
```

Para os testes que dependem das views SQL, garantir que as migrations de view foram
aplicadas no banco de testes (`php artisan migrate` inclui as views, pois usam
`DB::statement`).
