package database import ( "os" "path/filepath" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gorm.io/driver/sqlite" "gorm.io/gorm" ) const widgetConversationMigrationBaseline = ` CREATE TABLE inboxes (id INTEGER PRIMARY KEY, channel_type TEXT NOT NULL); CREATE TABLE contact_inboxes (id INTEGER PRIMARY KEY, contact_id INTEGER NOT NULL, inbox_id INTEGER NOT NULL); CREATE TABLE conversations (id INTEGER PRIMARY KEY, contact_id INTEGER NOT NULL, inbox_id INTEGER NOT NULL, contact_inbox_id INTEGER); ` func TestWidgetConversationContactInboxMigrationRoundTrip(t *testing.T) { dbPath := filepath.Join(t.TempDir(), "widget-conversations.db") dbURL := "sqlite3://" + dbPath db, err := gorm.Open(sqlite.Open(dbPath), &gorm.Config{}) require.NoError(t, err) sqlDB, err := db.DB() require.NoError(t, err) sqlDB.SetMaxOpenConns(1) t.Cleanup(func() { _ = sqlDB.Close() }) require.NoError(t, db.Exec(widgetConversationMigrationBaseline).Error) require.NoError(t, db.Exec(` INSERT INTO inboxes VALUES (1, 'web_widget'), (2, 'api'); INSERT INTO contact_inboxes VALUES (1, 10, 1), (2, 20, 1), (3, 20, 1), (4, 30, 1); INSERT INTO conversations VALUES (1, 10, 1, NULL), (2, 20, 1, NULL), (3, 30, 1, 4), (4, 10, 2, NULL); `).Error) migrations := t.TempDir() for _, direction := range []string{"up", "down"} { require.NoError(t, os.WriteFile(filepath.Join(migrations, "000081_baseline."+direction+".sql"), []byte("SELECT 1;"), 0o600)) name := "000082_backfill_widget_conversation_contact_inboxes." + direction + ".sql" data, readErr := os.ReadFile(filepath.Join("..", "..", "migrations", name)) require.NoError(t, readErr) require.NoError(t, os.WriteFile(filepath.Join(migrations, name), data, 0o600)) } require.NoError(t, ForceVersion(dbURL, migrations, 81)) require.NoError(t, MigrateSteps(dbURL, migrations, 1)) var bindings []struct { ID uint ContactInboxID *uint } require.NoError(t, db.Raw("SELECT id, contact_inbox_id FROM conversations ORDER BY id").Scan(&bindings).Error) require.Len(t, bindings, 4) require.NotNil(t, bindings[0].ContactInboxID) assert.Equal(t, uint(1), *bindings[0].ContactInboxID) assert.Nil(t, bindings[1].ContactInboxID) require.NotNil(t, bindings[2].ContactInboxID) assert.Equal(t, uint(4), *bindings[2].ContactInboxID) assert.Nil(t, bindings[3].ContactInboxID) require.NoError(t, MigrateSteps(dbURL, migrations, -1)) require.NoError(t, db.Raw("SELECT id, contact_inbox_id FROM conversations ORDER BY id").Scan(&bindings).Error) assert.Nil(t, bindings[0].ContactInboxID) assert.Nil(t, bindings[1].ContactInboxID) require.NotNil(t, bindings[2].ContactInboxID) assert.Equal(t, uint(4), *bindings[2].ContactInboxID) assert.Nil(t, bindings[3].ContactInboxID) assert.False(t, db.Migrator().HasTable("widget_conversation_contact_inbox_backfills")) }