Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions docs/change-logs/missing-smoke-crud-tests.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Change Log: Missing Smoke & CRUD Tests

Implements [docs/plans/MISSING_SMOKE_CRUD_TESTS.md](../plans/MISSING_SMOKE_CRUD_TESTS.md), the follow-up to [SMOKE_TESTS.md](../plans/SMOKE_TESTS.md) and [CRUD_TESTS.md](../plans/CRUD_TESTS.md). Adds the still-feasible tests from the two original plans and fixes two vacuous tests found during the 2026-07-29 audit. Both original plans are now marked **Completed**.

## Test count

`tests/Feature/Smoke` + `tests/Feature/Crud`: 77 → 85 tests, all passing (+9 new, 1 vacuous test deleted, 1 vacuous test reworked).

## `tests/Feature/Smoke/PublicRoutesTest.php`

- New: `root path redirects to app login` — `/` now redirects to `/app` (`routes/web.php`); adapted from the original plan's "cover page loads".
- Removed unused `CoverPage`/`ResultsPage` imports.

## `tests/Feature/Smoke/AppPanelTest.php`

- No `HddsHints` smoke test added (optional item flagged in the plan): its `mount()` aborts 404 unless the team has an HDDS module version linked to a deployed xlsform. Noted with a comment in the file.

## `tests/Feature/Crud/AdminPanelCrudTest.php`

New tests:

- Dataset: `create dataset requires name`, `can edit dataset`.
- Program: `program list links to program panel` — asserts the rendered list contains the `program/{id}` record URL (the `recordUrl` override in `app/Filament/Admin/Resources/ProgramResource.php`). The plan's `getRecordUrl()` approach was swapped for `assertSeeHtml()` because `livewire()->instance()` is typed as the base Livewire component, which fails phpstan.
- XlsformModule: `can delete xlsform module` via the table's grouped `DeleteBulkAction` (the table has no row DeleteAction and no create action).

Fixes to vacuous tests in the XlsformModuleVersion describe block:

- Deleted the duplicate `can create xlsform module version` test — it filled module fields on the version create action and asserted a row that the `beforeEach` had already created; `can create default xlsform module version` covers version creation.
- Reworked `can delete xlsform module` into `can delete xlsform module version` — it asserted against the wrong table (`xlsform_modules`), passing vacuously; it now creates a version linked to the `beforeEach` module and asserts `xlsform_module_versions` after the row `DeleteAction`.

## `tests/Feature/Crud/AppPanelCrudTest.php`

New tests:

- Farm: `can bulk delete farm` — builds the LocationLevel → Location → Farm chain manually (no Farm factory) and deletes via the toolbar `DeleteBulkAction` (the table has no row DeleteAction).
- ChoiceListEntry: `can create choice list entry via table header action`, `can edit choice list entry via table action`, `can delete choice list entry via table action`. All operate on a team-owned entry (`owner_id` set) because edit/delete row actions are hidden for global entries. Teams automatically get an English locale on creation (`Team::booted()`), so the `languageStrings` repeater requires exactly one label item — the create test passes it as form data; the edit test seeds it on the entry first.

## `tests/TestCase.php`

- Added `public ChoiceList $choiceList;` to the shared test-property list, following the existing pattern for `$team`/`$xlsformTemplate` etc. (phpstan resolves `$this->…` in Pest closures against `Tests\TestCase`).

## Verification

- `./vendor/bin/pest tests/Feature/Smoke tests/Feature/Crud` — 85 passed.
- `./vendor/bin/phpstan analyse tests/Feature/Smoke tests/Feature/Crud` — no new errors (8 pre-existing errors from stub files / unmatched ignore patterns are unchanged).
- `./vendor/bin/pint` — applied to changed files.
2 changes: 1 addition & 1 deletion docs/plans/CRUD_TESTS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# CRUD Test Plan

**Status:** In Progress — first draft implemented 2026-05-12 (commit `b827ead`): 37 of ~69 planned tests exist in `tests/Feature/Crud/` (Admin 20/~49, App 12/~14, Program 4/~6), with the `withAppTenant()`/`withProgramTenant()` helpers in place. 5 Admin-panel tests were known-failing against current package behaviour — see [docs/change-logs/fix-admin-crud-test-imports.md](../change-logs/fix-admin-crud-test-imports.md). Remaining: ~29 Admin-panel resource cases.
**Status:** Completed — see [docs/change-logs/missing-smoke-crud-tests.md](../change-logs/missing-smoke-crud-tests.md). The still-feasible remaining cases were added via the follow-up plan [MISSING_SMOKE_CRUD_TESTS.md](MISSING_SMOKE_CRUD_TESTS.md). Items that became obsolete before completion: Domain/Theme/GlobalIndicator CRUD (resources removed), User create/edit (Admin UserResource is now list-only with an "invite users" action), XlsformModule create (the package's create action is disabled), and Program-panel ProgramResource CRUD (redesigned around the `ManageProgram` tenant-profile page — adapted tests exist in `ProgramPanelCrudTest.php`).

## Overview

Expand Down
114 changes: 114 additions & 0 deletions docs/plans/MISSING_SMOKE_CRUD_TESTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# Missing Smoke & CRUD Tests

**Status:** Completed — see [docs/change-logs/missing-smoke-crud-tests.md](../change-logs/missing-smoke-crud-tests.md). All planned tests implemented (85 smoke/CRUD tests passing). The optional `HddsHints` smoke test was skipped: the page 404s without an HDDS module version linked to a deployed xlsform. The Program record-URL test uses `assertSeeHtml()` instead of `getRecordUrl()` for phpstan compatibility.

Follow-up to [SMOKE_TESTS.md](SMOKE_TESTS.md) and [CRUD_TESTS.md](CRUD_TESTS.md). Audit date 2026-07-29: all 77 existing tests in `tests/Feature/Smoke/` and `tests/Feature/Crud/` pass. This plan adds the tests from the two original plans that are still missing **and still feasible against the current codebase**, and fixes two vacuous tests found during the audit.

---

## Audit summary — why most "missing" items are not in this plan

The codebase has moved on since both plans were written. Items from the original plans that are now obsolete (no test to write):

| Original plan item | Why obsolete |
|---|---|
| Smoke: `cover page loads`, `results page loads`, `temp results page loads` | `CoverPage`/`ResultsPage`/temp-results routes removed; `/` now redirects to `/app` (`routes/web.php:14`). Adapted test added below. |
| Smoke: `data-collection-index`, `lisp-index`, `lisp-indicators`, `lisp-workshop` pages | Page classes deleted; `Pages/Lisp/` now contains only `OptionalModules` (already tested). |
| Smoke: `domains`, `themes`, `global-indicators` admin lists | `DomainResource`/`ThemeResource`/`GlobalIndicatorResource` no longer exist anywhere in app or packages. |
| CRUD: Domain (7 tests), Theme (7), GlobalIndicator (7) | Same — resources removed. |
| CRUD: User create/edit (4 tests) | Package redesign: Admin `UserResource` is list-only with an "invite users" action. Adapted tests already exist in `AdminPanelCrudTest.php`. |
| CRUD: XlsformModule `can create` + `create requires name` | `getHeaderActions()` (CreateAction) is commented out in the package's `ManageXlsformModule.php` — no create action exists to test. |
| CRUD: Program panel ProgramResource CRUD (6 tests) | Program panel redesigned around the `ManageProgram` tenant-profile page; adapted tests already exist in `ProgramPanelCrudTest.php`. |

After this plan completes, update the **Status** lines of both original plan docs to **Completed**, noting the obsolete items above, and link a shared change log.

---

## File 1 — `tests/Feature/Smoke/PublicRoutesTest.php` (1 test)

| Test | Implementation |
|---|---|
| `root path redirects to app login` | `$this->get('/')->assertRedirect('app')` — adapted from the plan's "cover page loads"; `/` is now a redirect (`routes/web.php:14`). |

Optional (not in original plan, flagged during audit): the only routable App-panel page with no smoke test is `HddsHints` (`/app/{team}/hdds-hints`, navigation hidden but discovered/routed). Add `hdds hints page loads` to `AppPanelTest.php` if it mounts cleanly without survey data; skip with a comment if it requires a deployed xlsform.

---

## File 2 — `tests/Feature/Crud/AdminPanelCrudTest.php` (4 tests + 2 fixes)

Actor/setup: existing `createSuperAdmin()` + `withAdminPanel()` `beforeEach` blocks.

### Dataset (2 tests)

Form fields (package `Datasets/Schemas/DatasetForm.php`): `name` required, `description` required. The `custom_key`/`label` block noted as failing in [fix-admin-crud-test-imports.md](../change-logs/fix-admin-crud-test-imports.md) is now commented out in the package, so plain create/edit works.

| Test | Implementation |
|---|---|
| `create dataset requires name` | `livewire(CreateDataset::class)->fillForm(['name' => '', 'description' => 'x'])->call('create')->assertHasFormErrors(['name' => 'required'])` |
| `can edit dataset` | `Dataset::forceCreate(['name' => 'Editable Dataset', 'primary_key' => 'id'])` (same as existing edit-page-loads test), then `livewire(EditDataset::class, ['record' => $dataset->id])->fillForm(['name' => 'Updated Dataset', 'description' => 'x'])->call('save')->assertHasNoFormErrors()` + `assertDatabaseHas` |

### Program (1 test)

| Test | Implementation |
|---|---|
| `program list links to program panel` | Create a `Program`, then assert the table record URL: `$table = livewire(ListPrograms::class)->instance()->getTable(); expect($table->getRecordUrl($program))->toBe(url('program/'.$program->id));` — the `recordUrl` closure is at `app/Filament/Admin/Resources/ProgramResource.php:25`. |

### XlsformModule (1 test)

Table (package `XlsformModules/Tables/XlsformModuleTable.php`) exposes `EditAction` (row) and `DeleteBulkAction` (grouped bulk) — no row DeleteAction, no create.

| Test | Implementation |
|---|---|
| `can delete xlsform module` | Create module via `XlsformModule::forceCreate([...])` (template chain as in existing `beforeEach`), then `livewire(ManageXlsformModule::class)->callTableBulkAction(DeleteBulkAction::class, [$module])` + `assertDatabaseMissing('xlsform_modules', ...)` |

### Fixes — vacuous tests in the `XlsformModuleVersion` describe block

Two tests currently pass without testing anything:

1. `can create xlsform module version` (second one, [AdminPanelCrudTest.php:224](../../tests/Feature/Crud/AdminPanelCrudTest.php#L224)) — fills module fields (`xlsform_template_id`, `label`) on the **version** create action, then asserts `assertDatabaseHas('xlsform_modules', ['name' => 'test_module'])`, which passes because `beforeEach` already created that exact module. Delete it — the first `can create default xlsform module version` test already covers version creation.
2. `can delete xlsform module` ([AdminPanelCrudTest.php:236](../../tests/Feature/Crud/AdminPanelCrudTest.php#L236)) — creates an `XlsformModuleVersion` but asserts `assertDatabaseMissing('xlsform_modules', ...)`, which passes vacuously (wrong table). Rework as `can delete xlsform module version`: assert against `xlsform_module_versions`, and verify the delete action actually exists on the version table (if not, use `callTableBulkAction`).

---

## File 3 — `tests/Feature/Crud/AppPanelCrudTest.php` (4 tests)

### Farm (1 test)

`FarmResource` table has `EditAction` (row) + `DeleteBulkAction` (toolbar) — plan's row-delete adapted to bulk delete. No `Farm` factory exists; build the parent chain manually:

```php
$level = new LocationLevel(); $level->name = 'Village'; $level->owner_id = $this->team->id; $level->save();
$location = Location::create(['location_level_id' => $level->id, 'name' => 'Test Village', 'code' => 'tv1']); // verify Location columns at implementation time
$farm = Farm::create(['owner_id' => $this->team->id, 'location_id' => $location->id, 'team_code' => 'farm-001']);
```

| Test | Implementation |
|---|---|
| `can bulk delete farm` | `withAppTenant($this->team)` + `livewire(ListFarms::class)->callTableBulkAction(DeleteBulkAction::class, [$farm])` + `assertDatabaseMissing('farms', ['id' => $farm->id])` |

### ChoiceListEntry (3 tests)

Existing `beforeEach` already builds the Template → Module → ModuleVersion → `smoke_test_list` ChoiceList chain. `ListChoiceListEntries::mount()` falls back to the first localisable choice list when `choiceListName` is not passed, so plain `livewire(ListChoiceListEntries::class)` resolves to `smoke_test_list`.

Form ([ChoiceListEntryResource.php:117](../../app/Filament/App/Clusters/Localisations/Resources/ChoiceListEntryResource.php#L117)): `name` required, plus required per-locale `text` inputs generated from the survey's languages. In tests with no languages configured the repeater block should be empty — verify at implementation time; if a locale row is required, seed one `Locale` first.

Edit/Delete row actions are visible only when `!$record->is_global_entry` — create the target entry with `is_global_entry => false` (team-owned).

| Test | Implementation |
|---|---|
| `can create choice list entry via table action` | `livewire(ListChoiceListEntries::class)->callAction(CreateAction::class, data: ['name' => 'new_entry', ...])->assertHasNoActionErrors()` + `assertDatabaseHas` (create is a header action, not a row action) |
| `can edit choice list entry via table action` | Create entry, then `callTableAction(EditAction::class, $entry, data: ['name' => 'updated_entry'])` + DB check |
| `can delete choice list entry via table action` | Create entry, then `callTableAction(DeleteAction::class, $entry)` + `assertDatabaseMissing` |

---

## Out of scope

- `FarmEntityResource` (list/create/edit/import pages) — post-dates both plans; only the column-visibility test exists. Candidate for a separate smoke/CRUD plan.
- Package-level gaps (no create action on `ManageXlsformModule`, no user create/edit pages) — behaviour changes belong in the packages, not in this test plan.

## Completion checklist

1. All new/reworked tests pass: `./vendor/bin/pest tests/Feature/Smoke tests/Feature/Crud`
2. Update **Status** in `SMOKE_TESTS.md` and `CRUD_TESTS.md` to Completed, noting obsolete items.
3. Write change log in `docs/change-logs/` referencing this plan and the two originals.
2 changes: 1 addition & 1 deletion docs/plans/SMOKE_TESTS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Smoke Test Plan

**Status:** In Progress — implemented 2026-05-11 (commit `9b15333`): 40 of the 43 planned tests exist across all 5 files in `tests/Feature/Smoke/`, and the `tests/Pest.php` helpers (`createSuperAdmin()`, `createAppUser()`, panel/tenant helpers, permission-cache `beforeEach`) are all in place. Remaining gap: ~3 App-panel resource smoke tests from the File 4 "Resources" block.
**Status:** Completed — see [docs/change-logs/missing-smoke-crud-tests.md](../change-logs/missing-smoke-crud-tests.md). The remaining gaps were closed via the follow-up plan [MISSING_SMOKE_CRUD_TESTS.md](MISSING_SMOKE_CRUD_TESTS.md); the only adaptation is that the "cover page loads" item became "root path redirects to app login" (the `/` route is now a redirect). Items that became obsolete before completion: cover/results/temp-results pages (routes removed), `data-collection-index`/`lisp-index`/`lisp-indicators`/`lisp-workshop` pages (page classes deleted), and `domains`/`themes`/`global-indicators` admin lists (resources removed).

## Overview

Expand Down
Loading
Loading