4.7 KB
testhelper_test.go
package controllers
import (
"embed"
"io/fs"
"net/http"
"sync"
"time"
"github.com/golang-jwt/jwt/v5"
"github.com/readysite/readysite/pkg/application"
"github.com/readysite/readysite/pkg/database"
"github.com/readysite/readysite/pkg/database/engines"
"github.com/readysite/readysite/website/internal/access"
"github.com/readysite/readysite/website/models"
)
var (
//go:embed testdata/views
testViewsRaw embed.FS
testViews, _ = fs.Sub(testViewsRaw, "testdata")
setupOnce sync.Once
testApp *application.App
testAdmin *models.User
)
// setupTestDB initializes an in-memory database for tests.
// This should be called in init() of test files to ensure the memory DB
// is used instead of the file-based DB from models/db.go.
func setupTestDB() {
setupOnce.Do(func() {
// Replace the file-based DB with an in-memory DB for tests
models.DB = engines.NewMemory()
// Reinitialize ALL collections to use the new DB with indexes
models.Users = database.Manage(models.DB, new(models.User),
database.WithUniqueIndex[models.User]("Email"),
)
models.Pages = database.Manage(models.DB, new(models.Page),
database.WithIndex[models.Page]("ParentID"),
database.WithIndex[models.Page]("Published"),
)
models.PageContents = database.Manage(models.DB, new(models.PageContent),
database.WithIndex[models.PageContent]("PageID"),
database.WithIndex[models.PageContent]("CreatedBy"),
)
models.Collections = database.Manage(models.DB, new(models.Collection))
models.Documents = database.Manage(models.DB, new(models.Document),
database.WithIndex[models.Document]("CollectionID"),
)
models.Conversations = database.Manage(models.DB, new(models.Conversation),
database.WithIndex[models.Conversation]("UserID"),
)
models.Messages = database.Manage(models.DB, new(models.Message),
database.WithIndex[models.Message]("ConversationID"),
)
models.Mutations = database.Manage(models.DB, new(models.Mutation),
database.WithIndex[models.Mutation]("MessageID"),
database.WithIndex[models.Mutation]("EntityType", "EntityID"),
)
models.ACLRules = database.Manage(models.DB, new(models.ACLRule),
database.WithIndex[models.ACLRule]("SubjectType", "SubjectID"),
database.WithIndex[models.ACLRule]("ResourceType", "ResourceID"),
)
models.SettingsStore = database.Manage(models.DB, new(models.Settings),
database.WithUniqueIndex[models.Settings]("Key"),
)
models.Files = database.Manage(models.DB, new(models.File),
database.WithIndex[models.File]("UserID"),
database.WithIndex[models.File]("MimeType"),
database.WithIndex[models.File]("Published"),
)
models.MessageFiles = database.Manage(models.DB, new(models.MessageFile),
database.WithIndex[models.MessageFile]("MessageID"),
database.WithIndex[models.MessageFile]("FileID"),
)
models.AuditLogs = database.Manage(models.DB, new(models.AuditLog),
database.WithIndex[models.AuditLog]("UserID"),
database.WithIndex[models.AuditLog]("ResourceType", "ResourceID"),
database.WithIndex[models.AuditLog]("Action"),
)
models.Partials = database.Manage(models.DB, new(models.Partial),
database.WithIndex[models.Partial]("Published"),
)
// Create test admin user
testAdmin = &models.User{
Email: "admin@test.com",
Name: "Test Admin",
Role: access.RoleAdmin,
}
testAdmin.ID = "test-admin-user"
models.Users.Insert(testAdmin)
// Create test App with embedded views for controller tests
testApp = application.New(
application.WithViews(testViews),
application.WithController(Chat()),
application.WithController(Collections()),
)
})
}
// testChatController returns a ChatController configured with the test app.
// Use this instead of Chat() in tests that call rendering methods.
func testChatController() *ChatController {
c := &ChatController{}
c.BaseController.Setup(testApp)
return c
}
// testCollectionsController returns a CollectionsController configured with the test app.
func testCollectionsController() *CollectionsController {
c := &CollectionsController{}
c.BaseController.Setup(testApp)
return c
}
// authenticateRequest adds an admin session cookie to the request.
// This allows tests to pass authentication and authorization checks.
func authenticateRequest(req *http.Request) {
// Create JWT token for test admin
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"user_id": testAdmin.ID,
"exp": time.Now().Add(24 * time.Hour).Unix(),
})
// Use the same default secret as the access package in dev mode
tokenString, _ := token.SignedString([]byte("dev-only-not-for-production"))
// Add session cookie to request
req.AddCookie(&http.Cookie{
Name: "session",
Value: tokenString,
})
}
func init() {
setupTestDB()
}