88 lines
3.6 KiB
Markdown
88 lines
3.6 KiB
Markdown
# tests
|
|
|
|
BDD scenarios for the video upload feature, written in Gherkin and run by
|
|
[gobdd](https://github.com/go-bdd/gobdd).
|
|
|
|
The suite is **black box**: it speaks nothing but HTTP to a running `cms`, so
|
|
the same scenarios run against the local docker-compose stack and against a
|
|
deployed environment. It is its own Go module (`thamanyah/tests`) and imports
|
|
nothing from `cms/` — the API is the contract under test, not the code.
|
|
|
|
The upload to storage is a plain `PUT` to the presigned URL the API hands out,
|
|
with no AWS SDK involved, because that is exactly what a real client does.
|
|
|
|
```
|
|
features/video_upload.feature the scenarios, in Gherkin
|
|
suite_test.go the gobdd suite: step registration + per-scenario world
|
|
steps_test.go what each step does
|
|
client_test.go HTTP plumbing and the wire types
|
|
```
|
|
|
|
## Running
|
|
|
|
The suite needs a live `cms` with its database migrated and its buckets
|
|
provisioned. From the repo root:
|
|
|
|
```bash
|
|
docker compose up -d # localstack + infra + cms
|
|
docker exec cms ./cms migrate # see "Migrations" below
|
|
cd tests && go test ./...
|
|
```
|
|
|
|
If nothing is serving, the suite **skips** rather than fails, so `go test ./...`
|
|
in a fresh checkout stays green.
|
|
|
|
Point it at another environment with `CMS_BASE_URL` (default
|
|
`http://localhost:8081`):
|
|
|
|
```bash
|
|
CMS_BASE_URL=https://cms.example.com go test -v ./...
|
|
```
|
|
|
|
Use `-v` to see the Gherkin: gobdd nests a Go subtest per feature, scenario and
|
|
step, so the step text shows up in the test output.
|
|
|
|
### Migrations
|
|
|
|
`docker-compose.yml` starts `cms` in server mode only. The migrate container
|
|
that runs `./cms migrate` to completion before the service starts exists in the
|
|
ECS task definition (`runMigrations` in `infrastructure/main.go`), not in
|
|
compose — so a freshly created local database has no schema and every scenario
|
|
fails with `relation "categories" does not exist`. Run `docker exec cms ./cms
|
|
migrate` once after the stack first comes up.
|
|
|
|
## What the scenarios cover
|
|
|
|
Both steps of the upload flow, end to end:
|
|
|
|
- listing the categories a video can be filed under, and the shape of that list
|
|
- issuing an upload slot for MP4 and QuickTime, including that the storage key
|
|
is generated rather than taken from the client's file name
|
|
- refusing a slot for every other media type, and for a body that is not JSON
|
|
- uploading the file to the presigned URL and registering it: the record comes
|
|
back `processing`, under the key from the slot, with a transcoding job id and
|
|
the categories and metadata that were sent
|
|
- refusing to register: a file that was never uploaded, a missing title, no
|
|
category, and a storage key this API never issued
|
|
- answering 404 for a category id no category has, kept distinct from the 500
|
|
the category lookup itself failing produces
|
|
- answering 409 for a key that was already registered, rather than queueing a
|
|
second transcoding job for the same file
|
|
|
|
## Adding a scenario
|
|
|
|
Write it in `features/`. If it needs a step that does not exist yet, add the
|
|
function to `steps_test.go` and register it in `TestVideoUpload`. Two things to
|
|
know about gobdd:
|
|
|
|
- Step patterns are matched **unanchored**, and the first registered pattern
|
|
that matches wins. Anchor every pattern with `^…$`, as the existing ones do,
|
|
or a new step can silently shadow an old one.
|
|
- State moves between steps through the `*world` in the gobdd context, not
|
|
package variables — gobdd clones the context between the `Background` and the
|
|
scenario, so the world is held by pointer.
|
|
|
|
Scenarios write real rows and real objects, and nothing cleans up after them.
|
|
That is fine against LocalStack, which is disposable; think twice before
|
|
pointing the suite at anything that is not.
|