# Manual do Sistema — Estratégia de Testes

> O módulo **não tem testes** na v6. A suíte existente
> (`v6/tests/`) cobre apenas o Dashboard e a configuração GA.

---

## 1. Precedente de harness

Reutilizar `v6/tests/DashboardTestCase.php`:
`createRole()`, `createUser()`, `setModules()`, `DatabaseTransactions`,
`withoutMiddleware(VerifyCsrfToken::class)`.

Para este módulo é essencial `setModules(['manual-do-sistema' => true])`,
porque a matriz de permissões filtra por módulo ativo
(`v6/resources/views/admin/role/form.blade.php:43`).

---

## 2. Estratégia

| Tipo | Escopo |
|---|---|
| **Feature** | CRUD de manuais, CRUD de áreas, upload, autorização, exclusão |
| **Unit** | `ManualAreaRepository::upInsert` (caminhos de arquivo), sanitização do HTML |
| **Integração** | Verificação de que o recurso `manual-usuario` existe e pode ser concedido |

---

## 3. Fixtures necessárias

### 3.1 Factories (a v6 tem factories quebradas)

```php
// database/factories/ManualFactory.php
class ManualFactory extends Factory
{
    protected $model = Manual::class;

    public function definition(): array
    {
        return [
            'titulo'     => fake()->unique()->sentence(3),
            'slug'       => fake()->unique()->slug(),
            'objetivo'   => fake()->sentence(),
            'url_portal' => null,
            'url_cms'    => null,
        ];
    }
}

// database/factories/ManualAreaFactory.php
class ManualAreaFactory extends Factory
{
    protected $model = ManualArea::class;

    public function definition(): array
    {
        return [
            'manual_id' => Manual::factory(),
            'titulo'    => fake()->sentence(3),
            'descricao' => '<p>'.fake()->paragraph().'</p>',
            'archive_id'=> null,
        ];
    }
}
```

> As factories legadas (`v6/database/factories/ManualFactory.php` e
> `ManualAreaFactory.php`) apontam para `App\Manual` / `App\ManualArea`,
> classes que **não existem**, e não definem atributos. Precisam ser
> reescritas.

### 3.2 Seeds

| Seed | Caminho | Papel |
|---|---|---|
| `ManualDoSistemaResourceSeeder` | `v6/database/seeds/ManualDoSistemaResourceSeeder.php` | cria o recurso `manual-usuario` (modulo_id 8) — **essencial** para os testes de permissão |
| `UpdateManualAreas` | `v6/database/seeds/UpdateManualAreas.php` | cria as áreas dos manuais padrão |
| `UpdateManualAreasDiarioSeeder` | `v6/database/seeds/UpdateManualAreasDiarioSeeder.php` | áreas do Diário Oficial |

---

## 4. Casos de teste

### 4.1 Autorização

| # | Arrange | Act | Assert |
|---|---|---|---|
| A1 | Perfil sem `manual-usuario.index` | `GET /cms/manual-usuario` | 302 + flash "Você não tem autorização para acessar esta funcionalidade!" |
| A2 | Perfil **com** `manual-usuario.index` (recurso criado) | `GET /cms/manual-usuario` | 200 + view `prefecture.configurations.manual-usuario.index` |
| A3 | Perfil sem `manual-usuario.index` | `GET /cms/manual-usuario/create` | 302 (bloqueado) |
| A4 | Sem autenticação | `GET /cms/manual-usuario` | 302 para `login` |
| A5 | Perfil com `manual-usuario.index` | o item de menu do AdminLTE | o HTML contém "Manual do Sistema" |
| A6 | `super-admin` | `GET /cms/manual-usuario` | 200 |

### 4.2 CRUD de manuais

| # | Arrange | Act | Assert |
|---|---|---|---|
| M1 | `super-admin` | `POST /cms/manual-usuario` com título e objetivo | 302 para `manual-usuario.edit`; linha em `manuals` |
| M2 | Idem, sem `titulo` | `POST /cms/manual-usuario` | 302 + erro "O campo Título é obrigatório." |
| M3 | Idem, sem `objetivo` | `POST /cms/manual-usuario` | 302 + erro "O campo de Objetivo é obrigatório." |
| M4 | Idem, com `url_portal` inválida | `POST /cms/manual-usuario` | na v7: 302 + erro de URL (na v6: aceito, pois não há regra) |
| M5 | Manual existente | `GET /cms/manual-usuario/{id}` | 200 + view `show` com as áreas |
| M6 | Manual existente | `GET /cms/manual-usuario/{id}/edit` | 200 + view `create` (mesma tela) |
| M7 | Manual existente | `PUT /cms/manual-usuario/{id}` sem `titulo` | **comportamento atual**: `dd($th)` derruba a página; **v7**: 302 + erro de validação |
| M8 | Manual existente | `PUT /cms/manual-usuario/{id}` com dados válidos | 302 para `manual-usuario.show`; linha atualizada |
| M9 | Manual existente | `GET /cms/manual/delete/{id}` | 302 para `manual-usuario.index`; manual com `deleted_at`; áreas continuam no banco (órfãs) |
| M10 | Idem | `GET /cms/manual-usuario` | o manual apagado **não** aparece |
| M11 | Idem | `DELETE /cms/manual-usuario/{id}` | **comportamento atual**: erro 500 (método inexistente); **v7**: exclusão funciona |
| M12 | Dois manuais | `GET /cms/manual-usuario` | o índice vem ordenado por título (a view reordena) |

### 4.3 CRUD de áreas

| # | Arrange | Act | Assert |
|---|---|---|---|
| R1 | Manual existente | `GET /cms/manual/get/{manual_id}` | JSON com as áreas do manual, ordenadas por `id` |
| R2 | Manual existente | `GET /cms/manual/get/{outro_id}` | JSON com array **vazio** |
| R3 | Idem | `POST /cms/manual-area` com `titulo`, `descricao`, `manual_id` | JSON `true`; linha em `manual_areas` |
| R4 | Idem, sem `titulo` | `POST /cms/manual-area` | JSON `false` (na v6) / 422 (na v7) |
| R5 | Idem, com arquivo de imagem | `POST /cms/manual-area` | `archive_id` preenchido; arquivo em `storage/app/public/manual-usuario/area/{id}/destaque/` |
| R6 | Área existente | `GET /cms/manual-area/{id}/edit` | JSON com `id`, `titulo`, `descricao` |
| R7 | Área existente | `PUT /cms/manual-area/{id}` | JSON `true`; linha atualizada |
| R8 | Área existente | `DELETE /cms/manual-area/{id}` | JSON `true`; linha removida; **arquivo continua no disco** (bug a corrigir) |
| R9 | Idem | `GET /cms/manual-area` | devolve **todas** as áreas do sistema (bug a corrigir — deve filtrar por manual) |
| R10 | Idem | `GET /cms/manual-area/create` | **500** (método inexistente) — v7: a rota não deve existir |
| R11 | Idem | `GET /cms/manual-area/{id}` | **500** (método inexistente) — v7: idem |

### 4.4 Segurança

| # | Arrange | Act | Assert |
|---|---|---|---|
| S1 | Área com `descricao = '<script>alert(1)</script>'` | `GET /cms/manual-usuario/{id}` | **comportamento atual**: o script é renderizado sem escape; **v7**: o HTML deve estar sanitizado |
| S2 | Descrição com `<img src=x onerror=alert(1)>` | idem | v7: atributo `onerror` removido |
| S3 | Perfil sem `manual-usuario.edit` | `PUT /cms/manual-area/{id}` | na v6 é **liberado** pelo bug do middleware; v7: 403 |
| S4 | Perfil sem `manual-usuario.edit` | `PUT /cms/manual-usuario/{id}` | idem |

### 4.5 Integridade do catálogo de permissões

| # | Arrange | Act | Assert |
|---|---|---|---|
| C1 | Base migrada | `DB::table('resources')->where('slug','manual-usuario')->exists()` | **hoje: `false`** (recurso ausente) — v7: `true` |
| C2 | Recurso criado (modulo_id 8) | `admin/role/form.blade.php` renderizado | a linha "Manual do Sistema" aparece na matriz |
| C3 | Módulo `manual-do-sistema` com `status = false` | renderizar a matriz | a linha **desaparece** (filtro por módulo ativo) |
| C4 | Todos os módulos | para cada `resources.slug`, existe uma chave na matriz | teste genérico que garante que **todo** recurso tem seu slug único |

---

## 5. Fixtures de view

| View | Variáveis |
|---|---|
| `manual-usuario.index` | `title`, `content` (Collection de `id`/`titulo`) |
| `manual-usuario.create` | `title`, `data` (opcional) |
| `manual-usuario.form` | `data` (opcional), `errors` |
| `manual-usuario.show` | `title`, `data` (Manual com `areas`) |
| `manual-usuario.area.index` | — (usa `document.querySelector('.id_data')`) |
| `manual-usuario.area.modal` | — |

> `manual-usuario.show` usa `lightgallery`, que exige o plugin JS no
> layout — o teste de view deve apenas verificar o HTML, sem executar o
> plugin.

---

## 6. Como rodar

```bash
cd v6/
composer install
./vendor/bin/phpunit --testsuite Feature
./vendor/bin/phpunit tests/Feature/Manual/ManualCrudTest.php
./vendor/bin/phpunit --filter testCriaManualComTituloEObjetivo
```

Ambiente (de `v6/phpunit.xml`): `APP_ENV=testing`,
`CACHE_DRIVER=array`, `SESSION_DRIVER=array`, `QUEUE_DRIVER=sync`.

> A suíte usa `DatabaseTransactions`; o banco de teste precisa estar
> migrado e com o recurso `manual-usuario` presente (executar
> `ManualDoSistemaResourceSeeder` no setup, ou no `DatabaseSeeder`).

---

## 7. Cobertura mínima aceitável para a v7

| Arquivo de teste | Casos |
|---|---|
| `tests/Feature/Manual/ManualAuthorizationTest.php` | A1-A6 |
| `tests/Feature/Manual/ManualCrudTest.php` | M1-M12 |
| `tests/Feature/Manual/ManualAreaCrudTest.php` | R1-R11 |
| `tests/Feature/Manual/ManualSanitizationTest.php` | S1-S4 |
| `tests/Feature/Manual/ResourceCatalogTest.php` | C1-C4 |
| `tests/Unit/ManualAreaRepositoryTest.php` | caminho do arquivo, limpeza |

Meta: 100% das actions de `ManualController` e `ManualAreaController`, com
ênfase nos testes de autorização e de sanitização.
