114 lines
3.3 KiB
Go
114 lines
3.3 KiB
Go
package db
|
|
|
|
import (
|
|
"context"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.pcux.cn/xuans/Smail/config"
|
|
"git.pcux.cn/xuans/Smail/db/migration"
|
|
"xorm.io/xorm/convert"
|
|
)
|
|
|
|
func TestDatabaseEnginePreservesMigratedUTCTime(t *testing.T) {
|
|
previousLocal := time.Local
|
|
time.Local = time.FixedZone("CST", 8*3600)
|
|
t.Cleanup(func() { time.Local = previousLocal })
|
|
|
|
for _, tc := range []struct {
|
|
driver string
|
|
dsn string
|
|
}{
|
|
{"sqlite", ":memory:"},
|
|
{"mysql", "smail@tcp(127.0.0.1:3306)/smail?parseTime=true"},
|
|
{"postgres", "host=127.0.0.1 user=smail dbname=smail sslmode=require"},
|
|
} {
|
|
t.Run(tc.driver, func(t *testing.T) {
|
|
engine, err := newDatabaseEngine(tc.driver, tc.dsn)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Cleanup(func() { _ = engine.Close() })
|
|
if engine.GetTZDatabase() != time.UTC {
|
|
t.Fatalf("database timezone = %v, want UTC", engine.GetTZDatabase())
|
|
}
|
|
if engine.GetTZLocation() != time.Local {
|
|
t.Fatalf("display timezone = %v, want CST", engine.GetTZLocation())
|
|
}
|
|
want := time.Date(2026, 10, 3, 16, 56, 0, 0, time.UTC)
|
|
for _, value := range []any{want, "2026-10-03 16:56:00"} {
|
|
got, err := convert.AsTime(value, engine.GetTZDatabase(), engine.GetTZLocation())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if got == nil || !got.Equal(want) {
|
|
t.Fatalf("converted time = %v, want instant %v", got, want)
|
|
}
|
|
if display := got.Format("2006-01-02 15:04:05"); display != "2026-10-04 00:56:00" {
|
|
t.Fatalf("display time = %s, want 2026-10-04 00:56:00", display)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestInitAppliesSchemaMigration(t *testing.T) {
|
|
databasePath := filepath.Join(t.TempDir(), "init.db")
|
|
previousConfig := config.Instance
|
|
previousInstance := Instance
|
|
t.Cleanup(func() {
|
|
if Instance != nil && Instance != previousInstance {
|
|
_ = Instance.Close()
|
|
}
|
|
Instance = previousInstance
|
|
config.Instance = previousConfig
|
|
})
|
|
|
|
config.Instance = &config.Config{DbType: config.DBTypeSQLite, DbDSN: databasePath}
|
|
if err := Init("test"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
runner := migration.Runner{DB: Instance.DB().DB, Dialect: migration.DialectSQLite, Migrations: migration.DefaultMigrations()}
|
|
wantVersion := int64(len(migration.DefaultMigrations()))
|
|
version, err := runner.CurrentVersion(context.Background())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if version != wantVersion {
|
|
t.Fatalf("schema version = %d, want %d", version, wantVersion)
|
|
}
|
|
var count int
|
|
if _, err = Instance.SQL("SELECT count(*) FROM schema_migration").Get(&count); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if count != int(wantVersion) {
|
|
t.Fatalf("schema migration rows = %d, want %d", count, wantVersion)
|
|
}
|
|
}
|
|
|
|
func TestLegacySyncRequiresExplicitDevelopmentOrTestMode(t *testing.T) {
|
|
previousDevelopment := config.DevelopmentMode
|
|
t.Cleanup(func() { config.DevelopmentMode = previousDevelopment })
|
|
|
|
t.Setenv("SMAIL_ENABLE_LEGACY_SYNC2", "")
|
|
config.DevelopmentMode = true
|
|
if legacySyncEnabled("test") {
|
|
t.Fatal("legacy Sync2 was enabled without the compatibility flag")
|
|
}
|
|
|
|
t.Setenv("SMAIL_ENABLE_LEGACY_SYNC2", "1")
|
|
config.DevelopmentMode = false
|
|
if legacySyncEnabled("release") {
|
|
t.Fatal("legacy Sync2 was enabled in production")
|
|
}
|
|
if !legacySyncEnabled("test") {
|
|
t.Fatal("legacy Sync2 was not enabled for an explicit test run")
|
|
}
|
|
|
|
config.DevelopmentMode = true
|
|
if !legacySyncEnabled("release") {
|
|
t.Fatal("legacy Sync2 was not enabled in development mode")
|
|
}
|
|
}
|