feat(11.1-03): add the Architecture and Plugins docs sections

- architecture: introduction, Go modules and workspaces, application
  lifecycle, request lifecycle
- plugins: registration, scheduling, extending, testing
- verified Examples for backpack services, towel request context,
  pact schedules and festival events
- TestDocsRequiredPages lists the eight new pages
This commit is contained in:
Jakub Zych
2026-09-30 22:12:08 +02:00
parent d6003cd84b
commit 1f8f5e1b51
14 changed files with 749 additions and 0 deletions

48
docs/plugins/testing.md Normal file
View File

@@ -0,0 +1,48 @@
---
title: Testing plugins
description: Test plugins with go test, run database tests against real PostgreSQL containers, replay API parity fixtures and keep documentation examples running.
section: plugins
order: 40
---
# Testing plugins
SummerCMS uses the standard Go test tooling. There is no separate test runner and no PHPUnit bootstrap: a plugin's tests are `_test.go` files next to its code, and `go test` runs them.
## Running tests
Run every test in the module from its root:
```sh
go vet ./...
go test ./...
```
Tests that need Docker, such as database tests, skip themselves in short mode. Use it for a fast loop:
```sh
go test -short ./...
```
In an application with local plugins in a `go.work` workspace, run the tests of one plugin by its directory, for example `go test ./plugins/blog/...`.
## Unit tests without a database
Most plugin code runs without a database. Build a container with `backpack.New`, call your plugin's Register and Boot, and assert on what it published. Drive HTTP handlers with `net/http/httptest`: `surf.Assemble` builds the same handler `serve` uses, so a test can send requests to your routes without listening on a port. Call console commands in-process with `bonfire.Call`.
## Database tests
SummerCMS supports PostgreSQL only, so database tests run against real PostgreSQL rather than an SQLite stand-in. The framework's own tests start a `postgres:16-alpine` container through testcontainers-go and create the database with the ICU `pl-PL` locale that lagoon checks for when it connects. Follow the same pattern in plugin tests:
- skip the test when `testing.Short` reports true;
- create the database with `LOCALE_PROVIDER icu ICU_LOCALE 'pl-PL'`, or lagoon refuses the connection;
- migrate a fresh database per test with `lagoon.Migrate`, so tests do not depend on each other.
Docker must be running for these tests.
## API parity tests
When you port an existing backend, its real responses are the acceptance test. [tide](../../modules/tide/README.md) records request and response fixtures from the reference backend and replays them against your port, reporting differences after masking IDs and timestamps. The `summer parity:record`, `summer parity:replay`, `summer parity:proxy` and `summer parity:broadcasts` commands wrap it.
## Examples in the documentation
Every Go code block in these docs is a copy of an `Example` function or a marked region of a test that `go test ./...` runs. If you change a framework API and forget an example, `go test` fails. Write your plugin's examples the same way: an `Example` function with an `// Output:` comment is compiled, run and compared by `go test`, so it cannot go stale.