Test that a URL made on the generator page with a ttl expires (closes #199)
check / check (push) Failing after 3s
check / check (push) Failing after 3s
A new handler test makes a URL on the generator page with a ttl of one second, checks that /v1/e/ serves it at once, waits two seconds and checks that it then answers 410. The expiry is kept in whole seconds, so two seconds is the longest a one-second ttl can take to pass. Test only. Model: opus-5-5
This commit is contained in:
@@ -31,6 +31,13 @@ P2: security: referer blacklist
|
||||
|
||||
# Completed Steps
|
||||
|
||||
- 2026-10-04 a URL made on the generator page with a `ttl` is tested to
|
||||
expire (closes #199): a new test in `internal/handlers` makes a URL on the
|
||||
generator page with a `ttl` of one second, checks that `/v1/e/` serves it at
|
||||
once, waits two seconds and checks that it then answers 410. The test waits
|
||||
for real, as pixa reads the clock directly when it makes and checks a URL; it
|
||||
waits two seconds because the time a URL expires is kept in whole seconds.
|
||||
Test only.
|
||||
- 2026-10-04 fewer files in the repository root (closes #97):
|
||||
`config.example.yml` moved unchanged to `configs/config.example.yml`, and
|
||||
`README.md`, the comments in `internal/config/config.go` and the startup error
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"sneak.berlin/go/pixa/internal/imgcache"
|
||||
"sneak.berlin/go/pixa/internal/session"
|
||||
@@ -241,3 +242,51 @@ func TestGeneratePost_URLServesImage(t *testing.T) {
|
||||
|
||||
requireServedPhoto(t, imageRec)
|
||||
}
|
||||
|
||||
// TestGeneratePost_URLWithTTLExpires verifies that a URL the generator page
|
||||
// makes with a ttl of one second is served by /v1/e/ at once and answers 410
|
||||
// once the ttl has passed.
|
||||
func TestGeneratePost_URLWithTTLExpires(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, imageSrv := newSignedHostServer(t, slog.New(slog.DiscardHandler))
|
||||
|
||||
rec := generatePost(t, url.Values{
|
||||
sourceURLField: {"https://" + signedHost + photoPath},
|
||||
widthField: {"50"},
|
||||
heightField: {"50"},
|
||||
formatField: {string(imgcache.FormatJPEG)},
|
||||
ttlField: {"1"},
|
||||
})
|
||||
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Fatalf("POST /generate status = %d, want %d", rec.Code, http.StatusOK)
|
||||
}
|
||||
|
||||
match := generatedURLPattern.FindStringSubmatch(rec.Body.String())
|
||||
if match == nil {
|
||||
t.Fatalf("generator page shows no URL: %s", rec.Body.String())
|
||||
}
|
||||
|
||||
imageRec := httptest.NewRecorder()
|
||||
imageSrv.ServeHTTP(imageRec, httptest.NewRequestWithContext(
|
||||
t.Context(), http.MethodGet, match[1], nil))
|
||||
|
||||
requireServedPhoto(t, imageRec)
|
||||
|
||||
// The URL keeps the time it expires in whole seconds and is served
|
||||
// through the whole of that second, so a ttl of one second has passed
|
||||
// for certain two seconds after the URL was made.
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
imageRec = httptest.NewRecorder()
|
||||
imageSrv.ServeHTTP(imageRec, httptest.NewRequestWithContext(
|
||||
t.Context(), http.MethodGet, match[1], nil))
|
||||
|
||||
t.Logf("GET %s after the ttl: %d %s", match[1], imageRec.Code, imageRec.Body)
|
||||
|
||||
if imageRec.Code != http.StatusGone {
|
||||
t.Errorf("status after the ttl = %d, want %d",
|
||||
imageRec.Code, http.StatusGone)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user