mirror of
https://github.com/SamyRai/tercul-backend.git
synced 2025-12-27 05:11:34 +00:00
- Core Go application with GraphQL API using gqlgen - Comprehensive data models for literary works, authors, translations - Repository pattern with caching layer - Authentication and authorization system - Linguistics analysis capabilities with multiple adapters - Vector search integration with Weaviate - Docker containerization support - Python data migration and analysis scripts - Clean architecture with proper separation of concerns - Production-ready configuration and middleware - Proper .gitignore excluding vendor/, database files, and build artifacts
156 lines
4.1 KiB
Go
156 lines
4.1 KiB
Go
package testutil
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/suite"
|
|
"gorm.io/driver/postgres"
|
|
"gorm.io/gorm"
|
|
"gorm.io/gorm/logger"
|
|
"tercul/config"
|
|
)
|
|
|
|
// TestDB holds the test database connection
|
|
var TestDB *gorm.DB
|
|
|
|
// SetupTestDB sets up a test database connection
|
|
func SetupTestDB() (*gorm.DB, error) {
|
|
// Load configuration
|
|
config.LoadConfig()
|
|
|
|
// Use test-specific environment variables if available, otherwise fall back to main config
|
|
host := getEnv("TEST_DB_HOST", config.Cfg.DBHost)
|
|
port := getEnv("TEST_DB_PORT", config.Cfg.DBPort)
|
|
user := getEnv("TEST_DB_USER", config.Cfg.DBUser)
|
|
password := getEnv("TEST_DB_PASSWORD", config.Cfg.DBPassword)
|
|
dbname := getEnv("TEST_DB_NAME", "tercul_test") // Always use test database
|
|
sslmode := getEnv("TEST_DB_SSLMODE", config.Cfg.DBSSLMode)
|
|
|
|
dsn := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=%s",
|
|
host, port, user, password, dbname, sslmode)
|
|
|
|
// Custom logger for tests
|
|
newLogger := logger.New(
|
|
log.New(os.Stdout, "\r\n", log.LstdFlags),
|
|
logger.Config{
|
|
SlowThreshold: time.Second,
|
|
LogLevel: logger.Silent, // Silent during tests
|
|
IgnoreRecordNotFoundError: true,
|
|
Colorful: false,
|
|
},
|
|
)
|
|
|
|
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
|
|
Logger: newLogger,
|
|
})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to connect to test database: %w", err)
|
|
}
|
|
|
|
// Set connection pool settings
|
|
sqlDB, err := db.DB()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get SQL DB instance: %w", err)
|
|
}
|
|
|
|
sqlDB.SetMaxOpenConns(5)
|
|
sqlDB.SetMaxIdleConns(2)
|
|
sqlDB.SetConnMaxLifetime(time.Hour)
|
|
|
|
return db, nil
|
|
}
|
|
|
|
// TruncateTables truncates all tables in the test database
|
|
func TruncateTables(db *gorm.DB, tables ...string) error {
|
|
for _, table := range tables {
|
|
if err := db.Exec(fmt.Sprintf("TRUNCATE TABLE %s CASCADE", table)).Error; err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// CloseDB closes the test database connection
|
|
func CloseDB(db *gorm.DB) error {
|
|
sqlDB, err := db.DB()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return sqlDB.Close()
|
|
}
|
|
|
|
// getEnv gets an environment variable or returns a default value
|
|
func getEnv(key, defaultValue string) string {
|
|
value, exists := os.LookupEnv(key)
|
|
if !exists {
|
|
return defaultValue
|
|
}
|
|
return value
|
|
}
|
|
|
|
// BaseSuite is a base test suite with common functionality
|
|
// For integration tests using mocks, DB is not used
|
|
// TODO: Remove DB logic for mock-based integration tests (priority: high, effort: medium)
|
|
type BaseSuite struct {
|
|
suite.Suite
|
|
// DB *gorm.DB // Removed for mock-based integration tests
|
|
}
|
|
|
|
// SetupSuite sets up the test suite
|
|
func (s *BaseSuite) SetupSuite() {
|
|
// No DB setup for mock-based integration tests
|
|
}
|
|
|
|
// TearDownSuite tears down the test suite
|
|
func (s *BaseSuite) TearDownSuite() {
|
|
// No DB teardown for mock-based integration tests
|
|
}
|
|
|
|
// SetupTest sets up each test
|
|
func (s *BaseSuite) SetupTest() {
|
|
// Can be overridden by specific test suites
|
|
}
|
|
|
|
// TearDownTest tears down each test
|
|
func (s *BaseSuite) TearDownTest() {
|
|
// Can be overridden by specific test suites
|
|
}
|
|
|
|
// RunTransactional runs a test function in a transaction
|
|
// TODO: Remove or refactor for mock-based tests (priority: low, effort: low)
|
|
func (s *BaseSuite) RunTransactional(testFunc func(tx interface{})) {
|
|
// No-op for mock-based tests
|
|
}
|
|
|
|
// MockDB creates a mock database for testing
|
|
func MockDB() (*sql.DB, error) {
|
|
// Use environment variables for test database connection
|
|
host := getEnv("TEST_DB_HOST", "localhost")
|
|
port := getEnv("TEST_DB_PORT", "5432")
|
|
user := getEnv("TEST_DB_USER", "postgres")
|
|
password := getEnv("TEST_DB_PASSWORD", "postgres")
|
|
dbname := getEnv("TEST_DB_NAME", "tercul_test")
|
|
sslmode := getEnv("TEST_DB_SSLMODE", "disable")
|
|
|
|
dsn := fmt.Sprintf("postgres://%s:%s@%s:%s/%s?sslmode=%s",
|
|
user, password, host, port, dbname, sslmode)
|
|
|
|
db, err := sql.Open("postgres", dsn)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return db, nil
|
|
}
|
|
|
|
// SkipIfShort skips a test if the -short flag is provided
|
|
func SkipIfShort(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("Skipping test in short mode")
|
|
}
|
|
}
|