check / check (push) Failing after 2s
TestImageProxyFlow in internal/server starts the database, handlers and middleware from the constructors pixad uses, with a fresh state directory, and replaces only the upstream origin with an httptest server. For a resize with a format change and for orig it checks a 200 MISS with the right type and size, then a HIT after one upstream request, and the files and rows the cache keeps. Two optional test seams make that possible: httpfetcher.Config.DialContext and handlers.Params.Fetcher. pixad sets neither and the config file and environment cannot, and tests show production still uses the checked dialer and builds its own fetcher. Model: opus-5-5
62 lines
1.9 KiB
Go
62 lines
1.9 KiB
Go
package handlers
|
|
|
|
import (
|
|
"net/http"
|
|
"net/netip"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
"go.uber.org/fx"
|
|
"go.uber.org/fx/fxtest"
|
|
|
|
"sneak.berlin/go/pixa/internal/config"
|
|
"sneak.berlin/go/pixa/internal/database"
|
|
"sneak.berlin/go/pixa/internal/globals"
|
|
"sneak.berlin/go/pixa/internal/healthcheck"
|
|
"sneak.berlin/go/pixa/internal/logger"
|
|
)
|
|
|
|
// TestHandlersBuildTheirOwnFetcherWhenNoneIsProvided builds the handlers as
|
|
// pixad does, in an fx app that provides no fetcher, and requests an image
|
|
// from 192.0.2.10, which is on the allowlist and in blocked_networks. The URL
|
|
// check accepts that address; only the dialer that refuses internal
|
|
// addresses checks blocked_networks, so the answer is 403 only if the
|
|
// fetcher the handlers build from the config connects with that dialer. Any
|
|
// other dialer would try to connect until the upstream fetch timeout, which
|
|
// is short so that the test then fails quickly.
|
|
func TestHandlersBuildTheirOwnFetcherWhenNoneIsProvided(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
const host = "192.0.2.10"
|
|
|
|
stateDir := t.TempDir()
|
|
cfg := &config.Config{
|
|
SigningKey: testSigningKey,
|
|
StateDir: stateDir,
|
|
DBURL: "file:" + filepath.Join(stateDir, "state.sqlite3"),
|
|
AllowlistHosts: []string{host},
|
|
BlockedNetworks: []netip.Prefix{netip.MustParsePrefix("192.0.2.0/24")},
|
|
UpstreamFetchTimeout: 2 * time.Second,
|
|
// With no connection slots, the fetch would fail before dialing.
|
|
UpstreamConnections: config.DefaultUpstreamConnections,
|
|
}
|
|
|
|
var h *Handlers
|
|
|
|
app := fxtest.New(t,
|
|
fx.Supply(cfg),
|
|
fx.Provide(globals.New, logger.New, database.New, healthcheck.New, New),
|
|
fx.Populate(&h),
|
|
)
|
|
app.RequireStart()
|
|
t.Cleanup(app.RequireStop)
|
|
|
|
r := chi.NewRouter()
|
|
r.Get("/v1/image/*", h.HandleImage())
|
|
|
|
rec := sendGet(t, r, photoURL(host))
|
|
checkErrorBody(t, rec, http.StatusForbidden, "forbidden")
|
|
}
|