# Perguntas Frequentes — Estratégia de Testes

> Não há suíte automatizada do módulo na `v6`. A v7 precisa de feature tests do portal
> (inclusive do fallback), do CMS e da busca global.

---

## 1. Estratégia

| Tipo | Objeto | Ferramenta (v7) |
|---|---|---|
| Feature | `/acesso-rapido/perguntas-frequentes` (sucesso e fallback) | Pest/PHPUnit + `RefreshDatabase` |
| Feature | CRUD do CMS (`/cms/conteudos/perguntas-frequentes`) | Pest + usuário com permissões |
| Feature | Busca global incluindo a FAQ | Pest |
| Unit | Filtro/normalização do texto pesquisado | PHPUnit |
| Regressão de dados | Migração `contents` -> `faq_questions` | Teste de migração com seed controlado |

## 2. Fixtures e seeds

| Item | Origem |
|---|---|
| Categoria `perguntas-frequentes` (id 12) | `v6/database/seeds/CategoryContentTableSeeder.php:81-86` |
| 8 perguntas de demonstração (LAI) | `v6/database/seeds/ContentsTableSeeder.php:438-487` |
| Permissões `perguntas-frequentes.*` | `v6/database/seeds/ResourcesTableSeeder.php:243-248` |
| Módulo id 25 | `v6/database/migrations/2024_11_01_150206_create_modulos_table.php:172-177` |
| Atalho "Perguntas Frequentes" do Acesso Rápido | `v6/database/seeds/AcessoRapidoSeeder.php:49-57` |

```php
// exemplo ilustrativo — v7
class FaqQuestionFactory extends Factory
{
    protected $model = FaqQuestion::class;

    public function definition(): array
    {
        return [
            'question' => fake()->unique()->sentence(4),
            'answer' => '<p>' . fake()->paragraph() . '</p>',
            'status' => true,
            'order' => 0,
        ];
    }
}
```

## 3. Casos de teste — Portal

| # | Cenário | Arrange | Act | Assert |
|---|---|---|---|---|
| T1 | Página de FAQ renderiza a lista | 3 perguntas; layout `modelo1` | `get('/acesso-rapido/perguntas-frequentes')` | status 200; HTML contém os 3 títulos e o prefixo "R." |
| T2 | Pergunta desativada **aparece** (comportamento legado) | 1 pergunta com `status = false` | `get('/acesso-rapido/perguntas-frequentes')` | v6: aparece — registrar como bug; v7: não aparece |
| T3 | Fallback para página estática | categoria vazia; `static_pages` com slug `perguntas-frequentes` | `get('/acesso-rapido/perguntas-frequentes')` | renderiza a página estática; `clicks` incrementado |
| T4 | Sem conteúdo e sem página estática | categoria e `static_pages` vazias | `get('/acesso-rapido/perguntas-frequentes')` | view `admin.errors.conteudo-nao-encontrado` |
| T5 | Resposta renderizada como HTML | resposta com `<strong>x</strong>` | `get('/acesso-rapido/perguntas-frequentes')` | HTML contém a tag (comportamento atual) |
| T6 | Filtro client-side presente | — | mesmo GET | HTML contém `id="txtBusca"` e `id="ulItens"` |
| T7 | Breadcrumb correto | — | mesmo GET | breadcrumb "Home > Perguntas Frequentes" com link `/acesso-rapido/perguntas-frequentes` |
| T8 | Layout `newsbit` responde | layout ativo `newsbit` | mesmo GET | status 200 (view existe) |
| T9 | Redirecionamento legado | — | `get('/portal/perguntas-frequentes')` | 302 para `acesso-rapido.index` |
| T10 | Atalho do Acesso Rápido aponta para a página | seed `AcessoRapidoSeeder` | consultar `links` | `link = '/acesso-rapido/perguntas-frequentes'` |

## 4. Casos de teste — CMS

| # | Cenário | Arrange | Act | Assert |
|---|---|---|---|---|
| T11 | Listagem carrega o DataTable | usuário com `perguntas-frequentes.*` | `get('/cms/conteudos/perguntas-frequentes')` | status 200; HTML contém `tabela_perguntas_frequentes` |
| T12 | DataTable responde JSON | 2 perguntas | `get('/cms/datatable/perguntas_frequentes')` | `data` com 2 linhas, cada uma com `edit`, `delete`, `active`, `inactivate` |
| T13 | Criar pergunta | usuário com `.create` | `post('/cms/conteudo', ['title' => 'Pergunta?', 'text' => '<p>Resposta</p>', 'category_contents_id' => 12])` | registro criado em `contents` |
| T14 | Criar sem título | idem | `post` sem `title` | falha de validação; nada criado |
| T15 | Título com 121 caracteres | idem | `post` | falha (`max:120`) |
| T16 | Editar resposta | pergunta existente | `put('/cms/conteudo/{id}', ['title' => 'Nova?', 'text' => '<p>Nova resposta</p>', 'category_contents_id' => 12])` | `text` atualizado |
| T17 | Excluir | pergunta existente | `delete('/cms/conteudo/{id}')` | `deleted_at` preenchido; some da view `perguntas_frequentes` |
| T18 | Exclusão em lote | 2 perguntas | `post('/cms/conteudo/deleteAll', ['toDelete' => [10, 11]])` | ambas soft-deleted |
| T19 | Sem permissão de criação | usuário sem `perguntas-frequentes.create` | `get('/cms/conteudos/cadastrar/perguntas-frequentes')` | 403/redirect |

## 5. Casos de teste — Busca global

| # | Cenário | Arrange | Act | Assert |
|---|---|---|---|---|
| T20 | Pergunta aparece na busca | pergunta "Quem pode solicitar as informações?" | `post('/buscando', ['text' => 'solicitar'])` | resultado contém a FAQ |
| T21 | Resposta é indexada | resposta com "anônimo" | mesmo POST com `text = 'anônimo'` | resultado encontrado (busca em `title` **e** `text`) |
| T22 | Filtro por categoria | — | `get('/buscar')` | a lista de categorias inclui `perguntas-frequentes` |
| T23 | Item da busca abre a view correta | layout `modelo1` | `get('/buscar/{id}')` | renderiza `perguntas-frequentes.show` |
| T24 | Item da busca no layout `default` | layout `default` | mesmo GET | v6: erro de view; v7: status 200 |

## 6. Casos de teste — Dados e view SQL

| # | Cenário | Arrange | Act | Assert |
|---|---|---|---|---|
| T25 | View reflete a categoria | 3 perguntas + 1 soft-deleted | consultar `perguntas_frequentes` | 3 linhas |
| T26 | `value` sequencial | 3 perguntas com `created_at` distintos | consultar a view | `value` 1..3 em `created_at DESC` |
| T27 | View não expõe a resposta | 1 pergunta | listar colunas da view | colunas = `value`, `titulo`, `id` |

## 7. Como rodar

```bash
# legado (v6) — verificação manual
cd /home/one/projects/maxima/v7/v6
php artisan route:list --name=acesso-rapido
php artisan serve
# portal:     http://localhost:8000/acesso-rapido/perguntas-frequentes
# cms:        http://localhost:8000/cms/conteudos/perguntas-frequentes   (requer login)
# datatable:  http://localhost:8000/cms/datatable/perguntas_frequentes

# v7 (proposto)
php artisan test --filter=Faq
php artisan test --group=faq
```

## 8. Critérios de aceite

1. T1–T27 passam na v7.
2. T2 registra a correção (ou a decisão de negócio) sobre itens desativados.
3. T4 garante que o fallback de página estática não foi quebrado.
4. O teste de migração garante que as 8 perguntas de demonstração sobreviveram.
