feat(testing): add Pest configuration, example tests, and composer scripts

- Add tests/Pest.php with TestCase binding and RefreshDatabase
- Add example feature tests: WelcomePageTest, HealthEndpointTest
- Add composer scripts: lint, test, test:coverage

Implements P2-049, P2-050, P2-051

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Snider 2026-01-29 13:37:20 +00:00
parent c3a783f547
commit 4833d922c5
9 changed files with 342 additions and 1 deletions

177
TODO.md Normal file
View file

@ -0,0 +1,177 @@
# TODO - core-template
Project template for Core PHP Framework applications. This is the starter template developers clone to create new projects.
## P1 - Critical / Security
### Security Hardening
- [ ] **Add security headers middleware** - Configure `X-Frame-Options`, `X-Content-Type-Options`, `X-XSS-Protection`, `Referrer-Policy`, and CSP headers. The template should ship with secure defaults that developers can customise.
- [ ] **Add CSRF protection documentation** - Document that Laravel's CSRF protection is enabled by default and how to handle AJAX requests with the X-CSRF-TOKEN header (already set up in `bootstrap.js` via axios).
- [ ] **Configure session security in .env.example** - Add `SESSION_SECURE_COOKIE=true` (commented for production) and document that `SESSION_ENCRYPT=true` should be enabled for sensitive applications.
- [ ] **Add rate limiting to default routes** - The welcome page has no rate limiting. Consider adding basic throttle middleware to prevent abuse during development/staging.
- [ ] **Document APP_KEY rotation** - Add a security note about key rotation and the implications for encrypted data (sessions, cookies).
### Environment Security
- [ ] **Add .env.production.example** - Provide a production-ready example with secure defaults (`APP_DEBUG=false`, `SESSION_SECURE_COOKIE=true`, etc.).
- [ ] **Add sensitive key validation** - Consider adding a boot-time check that warns if critical keys (APP_KEY, BCRYPT_ROUNDS) are using insecure defaults in production.
## P2 - High Priority
### Testing Infrastructure
- [x] **Add example tests** - Added example tests demonstrating Pest patterns. (Fixed: 2026-01-29)
- `tests/Feature/WelcomePageTest.php` - Tests welcome page (GET / returns 200)
- `tests/Feature/HealthEndpointTest.php` - Tests health endpoint (GET /up returns 200)
- `tests/Unit/ExampleTest.php` - Demonstrates Pest expectations syntax
- [x] **Add Pest configuration file** - Created `tests/Pest.php` with TestCase binding, RefreshDatabase for Feature tests, and documentation for custom expectations/helpers. (Fixed: 2026-01-29)
- [ ] **Configure parallel testing** - Add `pest.xml` or configure phpunit.xml for parallel test execution.
- [ ] **Add database refresh trait documentation** - Document when to use `RefreshDatabase` vs `DatabaseMigrations` in tests.
### Developer Experience
- [x] **Add composer scripts** - Added common scripts to composer.json: `lint`, `test`, `test:coverage`. Also added `pestphp/pest-plugin-type-coverage` for coverage support. (Fixed: 2026-01-29)
- [ ] **Add make:mod command documentation** - The README mentions `php artisan make:mod` but doesn't document all available flags (--web, --api, --admin, --all).
- [ ] **Create example module** - Add a simple example module (e.g., `app/Mod/Example/`) that developers can reference or delete. This would demonstrate the module pattern better than documentation alone.
- [ ] **Add VS Code workspace settings** - Create `.vscode/settings.json` with recommended settings for PHP, Blade, and Tailwind.
- [ ] **Add EditorConfig** - Create `.editorconfig` for consistent formatting across different editors.
### Configuration
- [ ] **Document CDN configuration** - The `config/core.php` references CDN settings but there's no documentation on how to configure BunnyCDN or other CDN providers.
- [ ] **Add Flux Pro setup script** - Consider adding a composer script or artisan command to simplify Flux Pro installation for licensed users.
- [ ] **Add database configuration examples** - The .env.example shows SQLite as default with commented MySQL. Add PostgreSQL example too.
## P3 - Medium Priority
### Code Quality
- [ ] **Add strict_types to all PHP files** - The `AppServiceProvider.php`, `TestCase.php`, `DatabaseSeeder.php`, and route files are missing `declare(strict_types=1);`. This contradicts the coding standards documented in CLAUDE.md.
- [ ] **Add return type to artisan file** - The `artisan` file should have proper typing for consistency.
- [ ] **Standardise route file structure** - The `routes/api.php` and `routes/console.php` have comments but no actual routes. Consider adding example routes or removing the unused files entirely.
- [ ] **Add PHPStan/Larastan configuration** - Consider adding static analysis to catch type errors and potential bugs.
### Frontend
- [ ] **Add Livewire to Vite config** - The vite.config.js doesn't include Livewire-specific configuration for hot reloading.
- [ ] **Configure Tailwind for module paths** - The tailwind.config.js only scans `resources/` but modules in `app/Mod/*/Views/` won't be picked up. Add:
```js
content: [
"./resources/**/*.blade.php",
"./resources/**/*.js",
"./app/Mod/**/Views/**/*.blade.php",
]
```
- [ ] **Add Flux UI styles import** - The `app.css` only imports Tailwind utilities. When using Flux, additional styles may be needed.
- [ ] **Remove welcome.blade.php inline styles** - The welcome page uses inline `<style>` tags instead of Tailwind classes. Consider converting to Tailwind or moving to a separate CSS file.
### CI/CD
- [ ] **Add missing cliff.toml** - The release.yml workflow references `cliff.toml` for changelog generation, but this file doesn't exist in the template.
- [ ] **Update actions/checkout version** - The CI workflows use `actions/checkout@v6` which may not exist yet. Verify and use the correct version (likely v4).
- [ ] **Add Codecov configuration** - Consider adding `codecov.yml` for customised coverage thresholds and ignore patterns.
- [ ] **Add branch protection documentation** - Document recommended GitHub branch protection rules for main branch.
### Documentation
- [ ] **Add CONTRIBUTING.md** - Guide for contributors including coding standards, PR process, and testing requirements.
- [ ] **Add CHANGELOG.md** - Start tracking changes in a changelog file.
- [ ] **Add LICENSE file** - The composer.json specifies EUPL-1.2 but there's no LICENSE file in the repository.
- [ ] **Improve README installation instructions** - Add troubleshooting section for common issues (permission errors, missing extensions).
## P4 - Low Priority
### Polish
- [ ] **Add favicon** - The public directory has no favicon. Add a default Core PHP Framework favicon.
- [ ] **Add meta tags to welcome.blade.php** - Missing description, Open Graph tags, and other SEO-relevant meta tags.
- [ ] **Configure error pages** - Add custom 404, 500, and 503 error pages that match the Core PHP Framework branding.
- [ ] **Add storage link documentation** - Document when and how to run `php artisan storage:link`.
- [ ] **Add Docker configuration** - Consider adding Dockerfile and docker-compose.yml for containerised development.
### Consistency
- [ ] **Unify AI instruction files** - There are three similar files: CLAUDE.md, GEMINI.md, and AGENTS.md. Consider consolidating into a single AI_INSTRUCTIONS.md or keeping them but ensuring they stay in sync.
- [ ] **Add .gitignore entries for common IDEs** - The template could benefit from more comprehensive IDE ignore patterns (JetBrains, VS Code, Sublime, etc.).
- [ ] **Remove unused .idea directory files** - These should be in .gitignore, not committed to the template.
## P5 - Nice to Have
### Features
- [ ] **Add health check route customisation** - The `/up` health endpoint is hardcoded. Consider making this configurable.
- [ ] **Add deployment documentation** - Include guides for deploying to common platforms (Forge, Vapor, DigitalOcean, etc.).
- [ ] **Add make:mod stub customisation** - Allow developers to customise the stubs used by `make:mod` command.
- [ ] **Add queue worker configuration** - Document queue setup and add example Supervisor configuration.
- [ ] **Add scheduled task documentation** - Document how to set up cron for Laravel's scheduler.
### Tooling
- [ ] **Add pre-commit hooks** - Configure Husky or similar to run Pint before commits.
- [ ] **Add GitHub issue templates** - Create templates for bug reports and feature requests.
- [ ] **Add GitHub PR template** - Create a pull request template with checklist.
- [ ] **Add Dependabot auto-merge** - Configure auto-merge for minor/patch dependency updates.
## P6 - Future / Backlog
### Long-term Improvements
- [ ] **Add multi-language support** - Consider adding lang directory structure and documentation for i18n.
- [ ] **Add API documentation generation** - Integrate OpenAPI/Swagger documentation generation.
- [ ] **Add performance monitoring integration** - Document integration with Laravel Telescope, Debugbar, or similar.
- [ ] **Add logging configuration examples** - Document centralised logging setup (Papertrail, Logstash, etc.).
- [ ] **Add backup configuration** - Document and provide examples for database backup strategies.
---
## Completed
*Move items here when done, preserving them for reference.*
- [x] **Add example tests (P2-049)** - Added `tests/Feature/WelcomePageTest.php`, `tests/Feature/HealthEndpointTest.php`, and `tests/Unit/ExampleTest.php` demonstrating Pest testing patterns. (2026-01-29)
- [x] **Add Pest configuration file (P2-050)** - Created `tests/Pest.php` with TestCase binding, RefreshDatabase for Feature tests, and placeholder documentation for custom expectations and helper functions. (2026-01-29)
- [x] **Add composer scripts (P2-051)** - Added `lint`, `test`, and `test:coverage` scripts to composer.json. Also added `pestphp/pest-plugin-type-coverage` dependency. (2026-01-29)

View file

@ -23,7 +23,8 @@
"mockery/mockery": "^1.6", "mockery/mockery": "^1.6",
"nunomaduro/collision": "^8.6", "nunomaduro/collision": "^8.6",
"pestphp/pest": "^3.0", "pestphp/pest": "^3.0",
"pestphp/pest-plugin-laravel": "^3.0" "pestphp/pest-plugin-laravel": "^3.0",
"pestphp/pest-plugin-type-coverage": "^3.0"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {
@ -44,6 +45,9 @@
} }
], ],
"scripts": { "scripts": {
"lint": "pint",
"test": "pest",
"test:coverage": "pest --coverage",
"dev:packages": "COMPOSER=composer.local.json composer update", "dev:packages": "COMPOSER=composer.local.json composer update",
"post-autoload-dump": [ "post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump", "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",

View file

View file

@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
/*
|--------------------------------------------------------------------------
| Health Endpoint Tests
|--------------------------------------------------------------------------
|
| These tests verify that the health check endpoint is accessible and
| returns the expected response. The /up endpoint is used by load
| balancers and monitoring services to check application health.
|
*/
it('returns ok status from health endpoint', function () {
$response = $this->get('/up');
$response->assertStatus(200);
});

View file

@ -0,0 +1,26 @@
<?php
declare(strict_types=1);
/*
|--------------------------------------------------------------------------
| Welcome Page Tests
|--------------------------------------------------------------------------
|
| These tests verify that the welcome page is accessible and renders
| correctly. This is an example feature test demonstrating the patterns
| used in Core PHP Framework applications.
|
*/
it('displays the welcome page', function () {
$response = $this->get('/');
$response->assertStatus(200);
});
it('returns the welcome view', function () {
$response = $this->get('/');
$response->assertViewIs('welcome');
});

72
tests/Pest.php Normal file
View file

@ -0,0 +1,72 @@
<?php
declare(strict_types=1);
/*
|--------------------------------------------------------------------------
| Pest Configuration
|--------------------------------------------------------------------------
|
| Configure Pest testing framework for the Core PHP Framework template.
| This file binds test traits to test cases and provides helper functions.
|
*/
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
/*
|--------------------------------------------------------------------------
| Test Case
|--------------------------------------------------------------------------
|
| The closure passed to the "uses()" method binds an abstract test case
| to all Feature and Unit tests. The TestCase class provides a bridge
| between Laravel's testing utilities and Pest's expressive syntax.
|
*/
uses(TestCase::class)->in('Feature', 'Unit');
/*
|--------------------------------------------------------------------------
| Database Refresh
|--------------------------------------------------------------------------
|
| Apply RefreshDatabase to Feature tests that need a clean database state.
| Unit tests typically don't require database access.
|
*/
uses(RefreshDatabase::class)->in('Feature');
/*
|--------------------------------------------------------------------------
| Expectations
|--------------------------------------------------------------------------
|
| You may extend Pest's expectations with custom methods here. These
| custom expectations can be used in any test throughout your application.
|
| For example:
| expect()->extend('toBeUkEnglish', function () {
| return $this->not->toContain('color')
| ->not->toContain('organization');
| });
|
*/
/*
|--------------------------------------------------------------------------
| Functions
|--------------------------------------------------------------------------
|
| You may define custom helper functions for your tests here. These
| functions will be available in all your test files.
|
| For example:
| function createWorkspace(array $attributes = []): Workspace {
| return Workspace::factory()->create($attributes);
| }
|
*/

View file

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types=1);
namespace Tests; namespace Tests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase; use Illuminate\Foundation\Testing\TestCase as BaseTestCase;

View file

View file

@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
/*
|--------------------------------------------------------------------------
| Example Unit Tests
|--------------------------------------------------------------------------
|
| Unit tests verify isolated functionality without database or HTTP
| requests. This file demonstrates the Pest testing syntax used in
| Core PHP Framework applications.
|
| Delete this file and add your own unit tests as needed.
|
*/
it('demonstrates basic expectations', function () {
expect(true)->toBeTrue();
expect(1 + 1)->toBe(2);
});
it('demonstrates string expectations', function () {
$greeting = 'Hello, World!';
expect($greeting)
->toBeString()
->toContain('Hello')
->toStartWith('Hello')
->toEndWith('!');
});
it('demonstrates array expectations', function () {
$items = ['apple', 'banana', 'cherry'];
expect($items)
->toBeArray()
->toHaveCount(3)
->toContain('banana');
});