Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions backend/migration/migrations/20251013_080000_core_models_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package migrations_test

import (
"testing"

"socialpredict/models"
"socialpredict/models/modelstesting"
)

func TestCoreModelsMigration_CreatesTablesAndColumns(t *testing.T) {
db := modelstesting.NewFakeDB(t) // runs global migrations incl. this file's init-registered one

m := db.Migrator()

// Tables
for _, tbl := range []any{&models.User{}, &models.Market{}, &models.Bet{}, &models.HomepageContent{}} {
if !m.HasTable(tbl) {
t.Fatalf("expected table for %T to exist", tbl)
}
}

// Critical market columns (v2 change)
if !m.HasColumn(&models.Market{}, "YesLabel") {
t.Fatalf("expected markets.yes_label column to exist")
}
if !m.HasColumn(&models.Market{}, "NoLabel") {
t.Fatalf("expected markets.no_label column to exist")
}
}
46 changes: 46 additions & 0 deletions backend/migration/migrations/20251020_140500_add_market_labels.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package migrations

import (
"socialpredict/migration"
"socialpredict/models"

"gorm.io/gorm"
)

// migrateAddMarketLabels contains the core logic so we can unit test it directly.
func MigrateAddMarketLabels(db *gorm.DB) error {
m := db.Migrator()

// 1) Add columns if missing (snake_cased by GORM -> yes_label / no_label)
if !m.HasColumn(&models.Market{}, "YesLabel") {
if err := m.AddColumn(&models.Market{}, "YesLabel"); err != nil {
return err
}
}
if !m.HasColumn(&models.Market{}, "NoLabel") {
if err := m.AddColumn(&models.Market{}, "NoLabel"); err != nil {
return err
}
}

// 2) Backfill defaults for existing rows (empty or NULL -> "YES"/"NO")
if err := db.Model(&models.Market{}).
Where("yes_label IS NULL OR yes_label = ''").
Update("yes_label", "YES").Error; err != nil {
return err
}
if err := db.Model(&models.Market{}).
Where("no_label IS NULL OR no_label = ''").
Update("no_label", "NO").Error; err != nil {
return err
}

return nil
}

// Register the migration with a timestamp. Adjust the timestamp if you need strict ordering vs. other migrations.
func init() {
migration.Register("20251020140500", func(db *gorm.DB) error {
return MigrateAddMarketLabels(db)
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package migrations_test

import (
"testing"
"time"

"socialpredict/migration/migrations"
"socialpredict/models"
"socialpredict/models/modelstesting"

"gorm.io/gorm"
)

// MarketV1 mirrors the old schema (no label fields) but uses same table name.
type MarketV1 struct {
ID int64 `gorm:"primaryKey"`
QuestionTitle string
Description string
OutcomeType string
ResolutionDateTime time.Time
FinalResolutionDateTime time.Time
UTCOffset int
IsResolved bool
ResolutionResult string
InitialProbability float64
CreatorUsername string
}

func (MarketV1) TableName() string { return "markets" }

func seedPreMigrationMarket(t *testing.T, db *gorm.DB) int64 {
t.Helper()
m := MarketV1{
ID: 1,
QuestionTitle: "Test Market",
Description: "Test Description",
OutcomeType: "BINARY",
ResolutionDateTime: time.Now().Add(24 * time.Hour),
CreatorUsername: "alice",
}
if err := db.Create(&m).Error; err != nil {
t.Fatalf("failed to seed v1 market: %v", err)
}
return m.ID
}

func TestMigrateAddMarketLabels_AddsColumnsAndBackfills(t *testing.T) {
db := modelstesting.NewFakeDB(t)

// Simulate v1: drop the new columns if present.
_ = db.Migrator().DropColumn(&models.Market{}, "YesLabel")
_ = db.Migrator().DropColumn(&models.Market{}, "NoLabel")

id := seedPreMigrationMarket(t, db)

// Run the migration under test.
if err := migrations.MigrateAddMarketLabels(db); err != nil {
t.Fatalf("migration failed: %v", err)
}

// Assert columns exist.
mig := db.Migrator()
if !mig.HasColumn(&models.Market{}, "YesLabel") {
t.Fatalf("expected yes_label column after migration")
}
if !mig.HasColumn(&models.Market{}, "NoLabel") {
t.Fatalf("expected no_label column after migration")
}

// Assert backfill applied.
var out models.Market
if err := db.First(&out, id).Error; err != nil {
t.Fatalf("load market failed: %v", err)
}
if out.YesLabel != "YES" {
t.Fatalf("expected YesLabel 'YES', got %q", out.YesLabel)
}
if out.NoLabel != "NO" {
t.Fatalf("expected NoLabel 'NO', got %q", out.NoLabel)
}
}
Loading