package integration import ( "context" "encoding/json" integrationbiz "kra/internal/biz/integration" "testing" "kra/internal/integration/runtimeconfig" ) type integrationRuntimeTestProvider struct { *Data store *runtimeconfig.Store } func (p *integrationRuntimeTestProvider) IntegrationRuntime() *runtimeconfig.Store { return p.store } func TestIntegrationConfigSavePublishesUnmaskedRuntimeValues(t *testing.T) { db, err := openWithDriver("sqlite", "file:"+t.Name()+"?mode=memory&cache=shared") if err != nil { t.Fatal(err) } if err = db.AutoMigrate(&ConfigPO{}); err != nil { t.Fatal(err) } provider := &integrationRuntimeTestProvider{Data: &Data{gormDB: newReloadableDB(db, nil)}, store: runtimeconfig.NewStore()} repo := &integrationConfigRepo{data: provider} values := integrationbiz.DefaultIntegrationConfig(integrationbiz.IntegrationKindMQ, "rabbitmq") values["password"] = "runtime-secret" raw, _ := json.Marshal(values) if err = repo.SaveIntegrationConfig(context.Background(), &integrationbiz.IntegrationConfig{Kind: integrationbiz.IntegrationKindMQ, Provider: "rabbitmq", Enabled: true, Values: raw}); err != nil { t.Fatal(err) } values["password"] = "******" raw, _ = json.Marshal(values) if err = repo.SaveIntegrationConfig(context.Background(), &integrationbiz.IntegrationConfig{Kind: integrationbiz.IntegrationKindMQ, Provider: "rabbitmq", Enabled: true, Values: raw}); err != nil { t.Fatal(err) } active, ok := provider.store.Get(integrationbiz.IntegrationKindMQ, "rabbitmq") if !ok || !active.Enabled { t.Fatalf("runtime config = %#v, ok=%v", active, ok) } stored := map[string]any{} if err = json.Unmarshal(active.Values, &stored); err != nil { t.Fatal(err) } if stored["password"] != "runtime-secret" { t.Fatalf("runtime password = %#v", stored["password"]) } } func TestCommunicationDefaultsIncludeKafka(t *testing.T) { db, err := openWithDriver("sqlite", "file:"+t.Name()+"?mode=memory&cache=shared") if err != nil { t.Fatal(err) } if err = db.AutoMigrate(&ConfigPO{}); err != nil { t.Fatal(err) } if err = ensureCommunicationIntegrationConfigs(db); err != nil { t.Fatal(err) } var row ConfigPO if err = db.Where("kind = ? AND provider = ?", integrationbiz.IntegrationKindMQ, "kafka").First(&row).Error; err != nil { t.Fatal(err) } if row.Enabled || row.Config == "" { t.Fatalf("kafka default row = %#v", row) } } func TestKafkaDefaultMigrationDoesNotRecreateOtherProviders(t *testing.T) { db, err := openWithDriver("sqlite", "file:"+t.Name()+"?mode=memory&cache=shared") if err != nil { t.Fatal(err) } if err = db.AutoMigrate(&ConfigPO{}); err != nil { t.Fatal(err) } if err = ensureKafkaIntegrationConfig(db); err != nil { t.Fatal(err) } var kafkaRows, otherRows int64 if err = db.Model(&ConfigPO{}).Where("kind = ? AND provider = ?", integrationbiz.IntegrationKindMQ, "kafka").Count(&kafkaRows).Error; err != nil { t.Fatal(err) } if err = db.Model(&ConfigPO{}).Where("provider <> ?", "kafka").Count(&otherRows).Error; err != nil { t.Fatal(err) } if kafkaRows != 1 || otherRows != 0 { t.Fatalf("migration rows kafka=%d other=%d", kafkaRows, otherRows) } } func TestCommunicationDefaultUpgradeRepairsRequiredEmptyFields(t *testing.T) { db, err := openWithDriver("sqlite", "file:"+t.Name()+"?mode=memory&cache=shared") if err != nil { t.Fatal(err) } if err = db.AutoMigrate(&ConfigPO{}); err != nil { t.Fatal(err) } legacy := `{"enabled":false,"broker":"","client_id":"","username":"","password":"","keep_alive":30,"clean_session":true,"connect_timeout":10}` if err = db.Create(&ConfigPO{Kind: integrationbiz.IntegrationKindMQ, Provider: "emqx", Config: legacy}).Error; err != nil { t.Fatal(err) } if err = upgradeCommunicationIntegrationDefaults(db); err != nil { t.Fatal(err) } var row ConfigPO if err = db.Where("kind = ? AND provider = ?", integrationbiz.IntegrationKindMQ, "emqx").First(&row).Error; err != nil { t.Fatal(err) } values := map[string]any{} if err = json.Unmarshal([]byte(row.Config), &values); err != nil { t.Fatal(err) } if values["broker"] != "tcp://127.0.0.1:1883" || values["client_id"] != "kra" || values["reconnect_interval"] != float64(5) { t.Fatalf("upgraded emqx values = %#v", values) } if values["username"] != "" || values["password"] != "" { t.Fatalf("optional credentials were overwritten: %#v", values) } if _, exists := values["enabled"]; exists { t.Fatalf("legacy enabled field remained: %#v", values) } if err = db.Delete(&row).Error; err != nil { t.Fatal(err) } if err = upgradeCommunicationIntegrationDefaults(db); err != nil { t.Fatal(err) } var count int64 if err = db.Model(&ConfigPO{}).Where("kind = ? AND provider = ?", integrationbiz.IntegrationKindMQ, "emqx").Count(&count).Error; err != nil { t.Fatal(err) } if count != 0 { t.Fatalf("upgrade recreated deleted emqx row: %d", count) } }