These docs are a work in progress and may not be fully up to date. Some pages may contain internal notes for our team.
Skip to Content

How to — test

Current testing posture across all three repos. Where infrastructure exists, this page shows how to run it. Where it doesn’t, it recommends what to add.


Backend (dropafinder-app-backend)

Infrastructure

PHPUnit is fully configured. phpunit.xml defines two suites:

  • Unittests/Unit/
  • Featuretests/Feature/

Both suites use an in-process bootstrap (vendor/autoload.php) and run with APP_ENV=testing, QUEUE_CONNECTION=sync, and MAIL_MAILER=array.

⚠️ Warning: The DB_CONNECTION lines in phpunit.xml are commented out. The test suite uses whatever database is configured in .env unless you override DB_CONNECTION manually. For CI or clean local runs, uncomment the SQLite in-memory block:

<env name="DB_CONNECTION" value="sqlite"/> <env name="DB_DATABASE" value=":memory:"/>

Existing tests

tests/Feature/ ├── AuditLogTest.php ├── BillingControllerTest.php ├── ExampleTest.php ├── LocationImageTest.php ├── SubscriptionEntitlementTest.php └── UserWorkspaceProvisioningTest.php tests/Unit/ └── ExampleTest.php

Feature tests are the primary test type. They test full request-response cycles through Laravel’s HTTP kernel.

How to run

cd "/Users/codydavis/Local Sites/dropafinder-app-backend" # Run all tests ./vendor/bin/phpunit # Run a single suite ./vendor/bin/phpunit --testsuite Feature ./vendor/bin/phpunit --testsuite Unit # Run a single file ./vendor/bin/phpunit tests/Feature/AuditLogTest.php # Run a single test method ./vendor/bin/phpunit --filter testAuditLogIsCreated

Adding a new feature test

php artisan make:test MyFeatureTest

Generated at tests/Feature/MyFeatureTest.php. The base class is Tests\TestCase, which extends Illuminate\Foundation\Testing\TestCase. Use RefreshDatabase or DatabaseTransactions traits to isolate database state:

use Illuminate\Foundation\Testing\RefreshDatabase; class MyFeatureTest extends TestCase { use RefreshDatabase; public function test_endpoint_returns_data(): void { $user = \App\Models\User::factory()->create(); $response = $this->actingAs($user, 'api') ->getJson('/api/my-resource'); $response->assertOk()->assertJsonStructure(['data']); } }

What to test first

If introducing coverage to an area that has none, prioritize in this order:

  1. New endpoints — assert correct HTTP status codes, response shape, and authorization (anonymous = 401, wrong workspace = 403).
  2. Subscription entitlement gatesSubscriptionEntitlementTest.php is the model here.
  3. Audit log emission — assert that mutating actions create a row in audit_logs.

Next.js dashboard (dropafinder-app-nextjs)

Infrastructure

🔴 [NEEDS CLARIFICATION: No test runner is installed and package.json has no test script. Neither Jest nor Vitest is listed in dependencies or devDependencies.]

Available scripts today:

"scripts": { "dev": "next dev", "build": "next build", "start": "next start", "lint": "eslint" }

The lint script (npm run lint) runs ESLint and is the only automated quality check currently in place.

Add Vitest with @testing-library/react:

npm install --save-dev vitest @vitejs/plugin-react @testing-library/react @testing-library/user-event jsdom

Create vitest.config.ts at the project root and configure the jsdom environment. Once Vitest is installed, the highest-value tests to write first are:

  1. Normalizer functions (src/lib/api/normalizers.ts) — pure input/output functions; easy to test, high breakage risk.
  2. Payload transformers (src/lib/api/payloads.ts) — same category.
  3. finderBuilderConfig.ts helpersbuildThemePreset, buildV2Config, etc.
  4. TanStack Query hook integration tests — use @testing-library/react with a query client wrapper.

Current quality gate

cd "/Users/codydavis/Local Sites/dropafinder-app-nextjs" npm run lint

ESLint is configured at the project root. Fix all lint errors before pushing to main.


Widget (dropafinder-app-external)

Infrastructure

🔴 [NEEDS CLARIFICATION: No test runner is configured in ext/2/source/package.json. The widget has no test script and Vitest is not installed.]

Available scripts today:

"scripts": { "dev": "vite", "build": "vite build", "build:dev": "vite build --mode development", "deploy:02": "npm run build && node scripts/deploy-r2.mjs", "serve": "vite preview" }

The widget is a Svelte + Vite project. Add @vitest/ui and @testing-library/svelte:

npm install --save-dev vitest @testing-library/svelte jsdom

Highest-value tests:

  1. Filtering logic (src/lib/filtering.js) — applyFinderFilters takes plain data in, returns plain data out. No DOM needed.
  2. Store initialization (src/lib/stores.js) — initializeFinderStores parses the payload shape and populates stores; assert that a given payload produces the expected designStore state.
  3. mapSettings.js utilitiesresolveMapSettings, normalizeMapProvider, isMapStyleVariantSupported are pure functions.
  4. localization.js — translation lookup functions.

Manual verification

Until a test suite exists, verify widget changes through the dashboard Live Preview:

cd "/Users/codydavis/Local Sites/dropafinder-app-external/ext/2/source" npm run build:dev

Then open the Finder Builder in the local dashboard at http://localhost:3000 and exercise the changed feature in the Live Preview rail.


Where to next