package localdb import ( "path/filepath" "testing" "time" ) func TestRunLocalMigrationsBackfillsExistingConfigurations(t *testing.T) { dbPath := filepath.Join(t.TempDir(), "legacy_local.db") local, err := New(dbPath) if err != nil { t.Fatalf("open localdb: %v", err) } t.Cleanup(func() { _ = local.Close() }) cfg := &LocalConfiguration{ UUID: "legacy-cfg", Name: "Legacy", Items: LocalConfigItems{}, SyncStatus: "pending", OriginalUsername: "tester", IsActive: true, } if err := local.SaveConfiguration(cfg); err != nil { t.Fatalf("save seed config: %v", err) } if err := local.DB().Where("configuration_uuid = ?", "legacy-cfg").Delete(&LocalConfigurationVersion{}).Error; err != nil { t.Fatalf("delete seed versions: %v", err) } if err := local.DB().Model(&LocalConfiguration{}). Where("uuid = ?", "legacy-cfg"). Update("current_version_id", nil).Error; err != nil { t.Fatalf("clear current_version_id: %v", err) } if err := local.DB().Where("1=1").Delete(&LocalSchemaMigration{}).Error; err != nil { t.Fatalf("clear migration records: %v", err) } if err := runLocalMigrations(local.DB()); err != nil { t.Fatalf("run local migrations manually: %v", err) } migratedCfg, err := local.GetConfigurationByUUID("legacy-cfg") if err != nil { t.Fatalf("get migrated config: %v", err) } if migratedCfg.CurrentVersionID == nil || *migratedCfg.CurrentVersionID == "" { t.Fatalf("expected current_version_id after migration") } if !migratedCfg.IsActive { t.Fatalf("expected migrated config to be active") } var versionCount int64 if err := local.DB().Model(&LocalConfigurationVersion{}). Where("configuration_uuid = ?", "legacy-cfg"). Count(&versionCount).Error; err != nil { t.Fatalf("count versions: %v", err) } if versionCount != 1 { t.Fatalf("expected 1 backfilled version, got %d", versionCount) } var migrationCount int64 if err := local.DB().Model(&LocalSchemaMigration{}).Count(&migrationCount).Error; err != nil { t.Fatalf("count local migrations: %v", err) } if migrationCount == 0 { t.Fatalf("expected local migrations to be recorded") } } func TestRunLocalMigrationsFixesPricelistVersionUniqueIndex(t *testing.T) { dbPath := filepath.Join(t.TempDir(), "pricelist_index_fix.db") local, err := New(dbPath) if err != nil { t.Fatalf("open localdb: %v", err) } t.Cleanup(func() { _ = local.Close() }) if err := local.SaveLocalPricelist(&LocalPricelist{ ServerID: 10, Version: "2026-02-06-001", Name: "v1", CreatedAt: time.Now().Add(-time.Hour), SyncedAt: time.Now().Add(-time.Hour), }); err != nil { t.Fatalf("save first pricelist: %v", err) } if err := local.DB().Exec(` CREATE UNIQUE INDEX IF NOT EXISTS idx_local_pricelists_version_legacy ON local_pricelists(version) `).Error; err != nil { t.Fatalf("create legacy unique version index: %v", err) } if err := local.DB().Where("id = ?", "2026_02_06_pricelist_index_fix"). Delete(&LocalSchemaMigration{}).Error; err != nil { t.Fatalf("delete migration record: %v", err) } if err := runLocalMigrations(local.DB()); err != nil { t.Fatalf("rerun local migrations: %v", err) } if err := local.SaveLocalPricelist(&LocalPricelist{ ServerID: 11, Version: "2026-02-06-001", Name: "v1-duplicate-version", CreatedAt: time.Now(), SyncedAt: time.Now(), }); err != nil { t.Fatalf("save second pricelist with duplicate version: %v", err) } var count int64 if err := local.DB().Model(&LocalPricelist{}).Count(&count).Error; err != nil { t.Fatalf("count pricelists: %v", err) } if count != 2 { t.Fatalf("expected 2 pricelists, got %d", count) } }