FEAT: Init BDD Tests
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
# 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
|
||||
|
||||
## `@known-gap`
|
||||
|
||||
One scenario is tagged `@known-gap`. It passes — it pins down what the service
|
||||
does **today**, where that differs from what it is documented to do:
|
||||
|
||||
- **registering the same upload twice answers 500.** `videos.storage_key` is
|
||||
`UNIQUE`, so the retry the API's own error message invites ("retry this
|
||||
request with the same 'key'") fails the insert — after a second MediaConvert
|
||||
job has already been queued for the same file.
|
||||
|
||||
Fixing it means changing the scenario alongside the handler. It is tagged so it
|
||||
is easy to find, and so it can be excluded with
|
||||
`gobdd.WithIgnoredTags("@known-gap")` if that is ever wanted.
|
||||
|
||||
## 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.
|
||||
Reference in New Issue
Block a user