Feature 10: Recipe grounding and photos (#78)
CI / ci (push) Successful in 2m0s

Co-authored-by: dev_agent <dev_agent@cubecraftlabs.com>
This commit was merged in pull request #78.
This commit is contained in:
2026-10-06 07:27:58 -04:00
committed by approver_agent
parent 67e44a506a
commit f25b28b39b
58 changed files with 7621 additions and 67 deletions
+53 -3
View File
@@ -2,6 +2,8 @@ package server
import (
"context"
"crypto/rand"
"encoding/base64"
"encoding/json"
"io"
"log/slog"
@@ -16,6 +18,8 @@ import (
"code.cubecraftlabs.com/Maniacs_Mansion/Meal-Quest/internal/household"
"code.cubecraftlabs.com/Maniacs_Mansion/Meal-Quest/internal/jobs"
"code.cubecraftlabs.com/Maniacs_Mansion/Meal-Quest/internal/recipes"
"code.cubecraftlabs.com/Maniacs_Mansion/Meal-Quest/internal/secretbox"
"code.cubecraftlabs.com/Maniacs_Mansion/Meal-Quest/internal/store"
"code.cubecraftlabs.com/Maniacs_Mansion/Meal-Quest/migrations"
)
@@ -38,7 +42,7 @@ func newTestRouterWith(t *testing.T, version string, settings *household.Setting
"index.html": {Data: []byte(fixtureIndex)},
"assets/index-AbC123.js": {Data: []byte(fixtureAsset)},
}
r, err := NewRouter(logger, version, nil, stubAuth{}, stubSessions{}, settings, runner, assets)
r, err := NewRouter(logger, version, nil, stubAuth{}, stubSessions{}, settings, newTestSearch(t), runner, newTestPhotos(t), assets)
if err != nil {
t.Fatal(err)
}
@@ -112,11 +116,57 @@ func newTestRunner(t *testing.T) *jobs.Runner {
return runner
}
// newTestPhotos returns a photo cache over a migrated temp database and an
// empty temp data directory.
func newTestPhotos(t *testing.T) *recipes.PhotoCache {
t.Helper()
photos, err := recipes.NewPhotoCache(recipes.NewFetcher(), newTestStore(t), t.TempDir())
if err != nil {
t.Fatal(err)
}
return photos
}
// newTestSearch returns a recipe search settings service, with nothing
// configured, over a migrated temp database and a random secret box.
func newTestSearch(t *testing.T) *recipes.SearchSettingsService {
t.Helper()
key := make([]byte, secretbox.KeySize)
rand.Read(key)
box, err := secretbox.New(base64.StdEncoding.EncodeToString(key))
if err != nil {
t.Fatal(err)
}
search, err := recipes.NewSearchSettingsService(newTestStore(t), box)
if err != nil {
t.Fatal(err)
}
return search
}
func TestNewRouterRequiresSearchSettings(t *testing.T) {
t.Parallel()
logger := slog.New(slog.NewTextHandler(io.Discard, nil))
if _, err := NewRouter(logger, "dev", nil, stubAuth{}, stubSessions{}, newTestSettings(t), nil, newTestRunner(t), newTestPhotos(t), fstest.MapFS{"index.html": {}}); err == nil {
t.Fatal("NewRouter accepted a nil recipe search settings service")
}
}
func TestNewRouterRequiresPhotoFiles(t *testing.T) {
t.Parallel()
logger := slog.New(slog.NewTextHandler(io.Discard, nil))
if _, err := NewRouter(logger, "dev", nil, stubAuth{}, stubSessions{}, newTestSettings(t), newTestSearch(t), newTestRunner(t), nil, fstest.MapFS{"index.html": {}}); err == nil {
t.Fatal("NewRouter accepted nil photo files")
}
}
func TestNewRouterRequiresSettings(t *testing.T) {
t.Parallel()
logger := slog.New(slog.NewTextHandler(io.Discard, nil))
if _, err := NewRouter(logger, "dev", nil, stubAuth{}, stubSessions{}, nil, newTestRunner(t), fstest.MapFS{"index.html": {}}); err == nil {
if _, err := NewRouter(logger, "dev", nil, stubAuth{}, stubSessions{}, nil, newTestSearch(t), newTestRunner(t), newTestPhotos(t), fstest.MapFS{"index.html": {}}); err == nil {
t.Fatal("NewRouter accepted a nil settings service")
}
}
@@ -125,7 +175,7 @@ func TestNewRouterRequiresJobRunner(t *testing.T) {
t.Parallel()
logger := slog.New(slog.NewTextHandler(io.Discard, nil))
if _, err := NewRouter(logger, "dev", nil, stubAuth{}, stubSessions{}, newTestSettings(t), nil, fstest.MapFS{"index.html": {}}); err == nil {
if _, err := NewRouter(logger, "dev", nil, stubAuth{}, stubSessions{}, newTestSettings(t), newTestSearch(t), nil, newTestPhotos(t), fstest.MapFS{"index.html": {}}); err == nil {
t.Fatal("NewRouter accepted a nil job runner")
}
}