Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/lerichardv/patolab-platform/llms.txt

Use this file to discover all available pages before exploring further.

PatoLab’s automated test suite is built on Pest PHP (sitting on top of PHPUnit), and is designed to run with zero external infrastructure. The phpunit.xml configuration points the test database at an in-memory SQLite instance, so every test run starts from a clean, isolated state without needing a running MySQL or PostgreSQL server. Code quality is enforced by Laravel Pint on the PHP side and ESLint + Prettier on the TypeScript/React side — all of which are wired into a single composer ci:check command that mirrors what runs in the CI pipeline.

Test Framework

ToolRole
Pest PHP v4Test runner and assertion API
PHPUnitUnderlying engine (Pest is a Pest-flavoured layer on top)
pest-plugin-laravelLaravel-specific helpers (actingAs, assertDatabaseHas, etc.)

Test Suites

PHPUnit is configured with two suites in phpunit.xml:
<testsuites>
    <testsuite name="Unit">
        <directory>tests/Unit</directory>
    </testsuite>
    <testsuite name="Feature">
        <directory>tests/Feature</directory>
    </testsuite>
</testsuites>

Existing test files

tests/Unit/
FileWhat it tests
ReportPaginatorTest.phpUnit behaviour of the report paginator utility
tests/Feature/
FileWhat it tests
MicroscopyCommissionTest.phpCommission calculations for microscopy specimens
MySpecimenTypeTemplateTest.phpUser-scoped specimen type template retrieval
SpecimenTypeTemplateTest.phpCRUD and access control for specimen type templates
Support files:
  • tests/Pest.php — global Pest configuration and dataset helpers
  • tests/TestCase.php — base test case (extends Laravel’s TestCase)

Test Database Configuration

All tests run against SQLite :memory: — no separate database server is required. The full environment override is declared in phpunit.xml:
<php>
    <env name="APP_ENV"                  value="testing"/>
    <env name="APP_MAINTENANCE_DRIVER"   value="file"/>
    <env name="BCRYPT_ROUNDS"            value="4"/>
    <env name="BROADCAST_CONNECTION"     value="null"/>
    <env name="CACHE_STORE"              value="array"/>
    <env name="DB_CONNECTION"            value="sqlite"/>
    <env name="DB_DATABASE"              value=":memory:"/>
    <env name="DB_URL"                   value=""/>
    <env name="MAIL_MAILER"              value="array"/>
    <env name="QUEUE_CONNECTION"         value="sync"/>
    <env name="SESSION_DRIVER"           value="array"/>
    <env name="PULSE_ENABLED"            value="false"/>
    <env name="TELESCOPE_ENABLED"        value="false"/>
    <env name="NIGHTWATCH_ENABLED"       value="false"/>
</php>
Notable overrides:
  • BCRYPT_ROUNDS=4 — dramatically speeds up any tests that create users with hashed passwords
  • QUEUE_CONNECTION=sync — queued jobs execute immediately in-process during tests
  • CACHE_STORE=array / SESSION_DRIVER=array — fully in-memory, no filesystem side-effects
  • PULSE_ENABLED=false / TELESCOPE_ENABLED=false — disables observability packages that would otherwise record test traffic

Running Tests

1

Run the full test suite with Pest

./vendor/bin/pest
2

Run via the Composer shortcut

The composer test script runs three steps in sequence: clears the config cache, performs a Pint dry-run style check (composer lint:check), and then executes the full test suite via php artisan test:
composer test
3

Run the full CI check locally

Mirrors what the CI pipeline runs end-to-end: ESLint check, Prettier check, TypeScript type check, and then composer test (which itself runs Pint lint check + the full Pest suite via php artisan test):
composer ci:check

Running individual suites

./vendor/bin/pest --testsuite=Unit

Code Style Tools

PatoLab enforces consistent style across both the PHP and TypeScript codebases. All tools are available as Composer or npm scripts.

PHP — Laravel Pint

Laravel Pint applies the default Laravel coding style using the php-cs-fixer engine.
# Fix all style violations in-place
composer lint

# Dry-run: report violations without modifying files
composer lint:check
Pint runs with --parallel for faster execution on multi-core machines.

JavaScript / TypeScript — ESLint

ESLint enforces import ordering and requires consistent type imports (separate type-only imports at the top level).
# Fix all auto-fixable violations in-place
npm run lint

# Report violations without modifying files
npm run lint:check
shadcn/ui components under resources/js/components/ui/ are excluded from ESLint rules, as they are generated/managed by the shadcn CLI and should not be manually reformatted.

JavaScript / TypeScript — Prettier

Prettier enforces consistent formatting (4-space indent, single quotes, semicolons, Tailwind CSS class sorting via prettier-plugin-tailwindcss).
# Format all files in-place
npm run format

# Dry-run: check for formatting issues without modifying files
npm run format:check

TypeScript — type checking

npm run types:check
This runs tsc --noEmit to catch type errors across the entire React/TypeScript codebase without emitting any output files.

CI Pipeline

The CI pipeline runs on PHP 8.3, 8.4, and 8.5 to ensure forward compatibility. For each PHP version it:
  1. Installs Node dependencies (npm i)
  2. Installs Composer dependencies
  3. Copies .env.example to .env and generates an application key
  4. Builds frontend assets (npm run build)
  5. Executes ./vendor/bin/pest directly
.npmrc sets ignore-scripts=true.PatoLab’s .npmrc disables npm lifecycle scripts globally. This means prepare, postinstall, and similar hooks will not run automatically after npm install or npm ci. If a package relies on a lifecycle script (e.g. to compile native bindings), you will need to run it manually. This is intentional and prevents unexpected side-effects in CI.

Development Server

During active development, use composer dev to start all four servers — Laravel, the queue worker, Pail (log viewer), and Vite — in a single terminal with colour-coded output:
composer dev
This runs concurrently:
  • php artisan serve — Laravel HTTP server
  • php artisan queue:listen --tries=1 --timeout=0 — queue worker
  • php artisan pail --timeout=0 — real-time log tail
  • npm run dev — Vite HMR dev server
Stop everything with a single Ctrl+C.

Build docs developers (and LLMs) love