feat: golem15.feedback plugin with the widget config route
- plugin golem15.feedback (requires golem15.user), its config, lang (en, pl), models and migrations
- typed settings singleton golem15_feedback_settings with the WinterCMS defaults and a widget key generated on first creation
- GET /_feedback/api/v1/{key}/config behind the constant-time key check and the fail-closed Origin allow-list, with the feedback-config and feedback-submit buckets
This commit is contained in:
99
internal/pgtest/pgtest.go
Normal file
99
internal/pgtest/pgtest.go
Normal file
@@ -0,0 +1,99 @@
|
||||
// Package pgtest starts one Postgres container per test binary for the
|
||||
// plugin's database tests and migrates golem15.user, golem15.feedback and
|
||||
// the framework tables (system_files, the job queue) into it. The test
|
||||
// binary must link the golem15.feedback plugin (its package or an
|
||||
// importer of it), which registers itself in init.
|
||||
package pgtest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"database/sql"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
_ "git.golem15.com/golem15/sm-user-plugin"
|
||||
"git.golem15.com/golem15/summercms/modules/backpack"
|
||||
"git.golem15.com/golem15/summercms/modules/compass"
|
||||
"git.golem15.com/golem15/summercms/modules/lagoon"
|
||||
"git.golem15.com/golem15/summercms/modules/party"
|
||||
"github.com/testcontainers/testcontainers-go/modules/postgres"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// PluginIDs are the plugins the database is migrated for.
|
||||
var PluginIDs = []string{"golem15.user", "golem15.feedback"}
|
||||
|
||||
var (
|
||||
once sync.Once
|
||||
gdb *gorm.DB
|
||||
sqlDB *sql.DB
|
||||
err error
|
||||
)
|
||||
|
||||
// DB returns the shared, migrated database. Tests that need an empty
|
||||
// table delete its rows first.
|
||||
func DB(t testing.TB) *gorm.DB {
|
||||
t.Helper()
|
||||
once.Do(func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Minute)
|
||||
defer cancel()
|
||||
if err = lagoon.PublishEncryptionKeys(nil, bytes.Repeat([]byte("F"), 32), nil); err != nil {
|
||||
return
|
||||
}
|
||||
var ctr *postgres.PostgresContainer
|
||||
ctr, err = postgres.Run(ctx, "postgres:16-alpine",
|
||||
postgres.WithDatabase("feedback"),
|
||||
postgres.WithUsername("feedback"),
|
||||
postgres.WithPassword("feedback"),
|
||||
postgres.BasicWaitStrategies(),
|
||||
)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var dsn string
|
||||
if dsn, err = ctr.ConnectionString(ctx, "sslmode=disable"); err != nil {
|
||||
return
|
||||
}
|
||||
if sqlDB, err = sql.Open("pgx", dsn); err != nil {
|
||||
return
|
||||
}
|
||||
if gdb, err = lagoon.Use(ctx, sqlDB); err != nil {
|
||||
return
|
||||
}
|
||||
var dir string
|
||||
if dir, err = os.MkdirTemp("", "feedback-pgtest-"); err != nil {
|
||||
return
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
if err = os.WriteFile(filepath.Join(dir, "app.yaml"), []byte("name: feedback-pgtest\n"), 0o644); err != nil {
|
||||
return
|
||||
}
|
||||
var cfg *compass.Config
|
||||
if cfg, err = compass.Open(compass.Options{Dir: dir, Environ: []string{
|
||||
"SUMMER_ENV=development",
|
||||
// A throwaway secret: golem15.user refuses to boot without one.
|
||||
"SUMMER_GOLEM15__USER__JWT__SECRET=pgtest-only-jwt-secret-0123456789abcdef",
|
||||
}}); err != nil {
|
||||
return
|
||||
}
|
||||
var plugins []party.Plugin
|
||||
if plugins, err = party.Activate(backpack.New(cfg), PluginIDs); err != nil {
|
||||
return
|
||||
}
|
||||
err = lagoon.Migrate(gdb, plugins)
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("pgtest: %v", err)
|
||||
}
|
||||
return gdb
|
||||
}
|
||||
|
||||
// SQL is the database's *sql.DB.
|
||||
func SQL(t testing.TB) *sql.DB {
|
||||
DB(t)
|
||||
return sqlDB
|
||||
}
|
||||
Reference in New Issue
Block a user