package marge import ( "encoding/xml" "os" "testing" "github.com/gesellix/bose-soundtouch/pkg/models" "github.com/gesellix/bose-soundtouch/pkg/service/datastore" ) func TestSyncFromAccountFull(t *testing.T) { // Setup a temporary datastore tmpDir, err := os.MkdirTemp("", "datastore_test") if err != nil { t.Fatalf("Failed to create temp dir: %v", err) } defer os.RemoveAll(tmpDir) ds := datastore.NewDataStore(tmpDir) // Mock AccountFullResponse xmlData := ` ACTIVE Living Room 192.0.2.10 ABC123XYZ 27.0.6 ABC123XYZ My Station tunein://station/s123 station TuneIn TuneIn Last Song spotify:track:abc track Spotify Spotify TuneIn TuneIn ` var resp models.AccountFullResponse if err := xml.Unmarshal([]byte(xmlData), &resp); err != nil { t.Fatalf("Failed to unmarshal mock data: %v", err) } // Run Sync if err := SyncFromAccountFull(ds, &resp); err != nil { t.Fatalf("SyncFromAccountFull failed: %v", err) } // Verify Device Info info, err := ds.GetDeviceInfo("USER_123", "DEVICE_ABC") if err != nil { t.Errorf("Failed to get device info: %v", err) } if info.Name != "Living Room" { t.Errorf("Expected name 'Living Room', got '%s'", info.Name) } // Note: ProductCode might be concatenated with a space in some implementations or models if info.ProductCode != "ST10" && info.ProductCode != "ST10 " { t.Errorf("Expected product code 'ST10', got '%s'", info.ProductCode) } // Verify Presets presets, err := ds.GetPresets("USER_123", "DEVICE_ABC") if err != nil { t.Errorf("Failed to get presets: %v", err) } if len(presets) != 1 { t.Errorf("Expected 1 preset, got %d", len(presets)) } else { // Datastore's ServicePreset might not use ButtonNumber field in its XML structure, // but rather relies on order or an 'id' attribute. // Let's check the name which we know was set. if presets[0].Name != "My Station" { t.Errorf("Expected preset name 'My Station', got '%s'", presets[0].Name) } } // Verify Recents recents, err := ds.GetRecents("USER_123", "DEVICE_ABC") if err != nil { t.Errorf("Failed to get recents: %v", err) } if len(recents) != 1 { t.Errorf("Expected 1 recent, got %d", len(recents)) } // Verify Sources sources, err := ds.GetConfiguredSources("USER_123", "DEVICE_ABC") if err != nil { t.Errorf("Failed to get sources: %v", err) } // Now we aggregate sources from Account + Preset + Recent. // Account has TUNEIN. // Preset has TUNEIN (same ID, so deduplicated). // Recent has SPOTIFY (new ID, so added). // Total expected: 2 if len(sources) != 2 { t.Errorf("Expected 2 sources (aggregated), got %d", len(sources)) } }