diff --git a/cmd/soundtouch-cli/cmd_group_test.go b/cmd/soundtouch-cli/cmd_group_test.go index 5477e39..8eb5c96 100644 --- a/cmd/soundtouch-cli/cmd_group_test.go +++ b/cmd/soundtouch-cli/cmd_group_test.go @@ -76,9 +76,9 @@ func TestPropagateAddGroup_BothSucceed(t *testing.T) { leftClient := newTestGroupClient(leftSrv.URL) rightClient := newTestGroupClient(rightSrv.URL) - req := sampleGroupRequest("192.168.1.131", "192.168.1.134") + req := sampleGroupRequest("192.0.2.131", "192.0.2.134") - leftOut, rightOut := propagateAddGroup(leftClient, rightClient, "192.168.1.131", "192.168.1.134", req) + leftOut, rightOut := propagateAddGroup(leftClient, rightClient, "192.0.2.131", "192.0.2.134", req) if leftOut.err != nil { t.Errorf("LEFT err = %v, want nil", leftOut.err) @@ -117,8 +117,8 @@ func TestPropagateAddGroup_BothSucceed(t *testing.T) { } rightBody := (*rightBodies)[0] - if !strings.Contains(rightBody, "192.168.1.131") { - t.Errorf("RIGHT (slave) body must carry 192.168.1.131\nbody:\n%s", rightBody) + if !strings.Contains(rightBody, "192.0.2.131") { + t.Errorf("RIGHT (slave) body must carry 192.0.2.131\nbody:\n%s", rightBody) } } @@ -134,9 +134,9 @@ func TestPropagateAddGroup_RightFails(t *testing.T) { leftClient := newTestGroupClient(leftSrv.URL) rightClient := newTestGroupClient(rightSrv.URL) - req := sampleGroupRequest("192.168.1.131", "192.168.1.134") + req := sampleGroupRequest("192.0.2.131", "192.0.2.134") - leftOut, rightOut := propagateAddGroup(leftClient, rightClient, "192.168.1.131", "192.168.1.134", req) + leftOut, rightOut := propagateAddGroup(leftClient, rightClient, "192.0.2.131", "192.0.2.134", req) if leftOut.err != nil { t.Errorf("LEFT err = %v, want nil", leftOut.err) diff --git a/cmd/soundtouch-cli/cmd_introspect_test.go b/cmd/soundtouch-cli/cmd_introspect_test.go index f7cc96c..0b30325 100644 --- a/cmd/soundtouch-cli/cmd_introspect_test.go +++ b/cmd/soundtouch-cli/cmd_introspect_test.go @@ -17,7 +17,7 @@ func TestIntrospectCommands(t *testing.T) { }{ { name: "introspect service with source flag", - args: []string{"soundtouch-cli", "--host", "192.168.1.100", "source", "introspect", "--source", "SPOTIFY"}, + args: []string{"soundtouch-cli", "--host", "192.0.2.100", "source", "introspect", "--source", "SPOTIFY"}, expectedOutput: []string{ "Getting introspect data for SPOTIFY", "=== SPOTIFY Service Introspect Data ===", @@ -47,7 +47,7 @@ func TestIntrospectCommands(t *testing.T) { }, { name: "introspect spotify convenience command", - args: []string{"soundtouch-cli", "--host", "192.168.1.100", "source", "introspect-spotify"}, + args: []string{"soundtouch-cli", "--host", "192.0.2.100", "source", "introspect-spotify"}, expectedOutput: []string{ "Getting Spotify introspect data", "=== Spotify Service Introspect Data ===", @@ -60,7 +60,7 @@ func TestIntrospectCommands(t *testing.T) { }, { name: "introspect with account parameter", - args: []string{"soundtouch-cli", "--host", "192.168.1.100", "source", "introspect", "--source", "SPOTIFY", "--account", "my_spotify_account"}, + args: []string{"soundtouch-cli", "--host", "192.0.2.100", "source", "introspect", "--source", "SPOTIFY", "--account", "my_spotify_account"}, expectedOutput: []string{ "Getting introspect data for SPOTIFY", "Source Account: my_spotify_account", @@ -68,7 +68,7 @@ func TestIntrospectCommands(t *testing.T) { }, { name: "introspect missing source flag", - args: []string{"soundtouch-cli", "--host", "192.168.1.100", "source", "introspect"}, + args: []string{"soundtouch-cli", "--host", "192.0.2.100", "source", "introspect"}, expectError: true, }, { diff --git a/cmd/soundtouch-cli/cmd_recents_test.go b/cmd/soundtouch-cli/cmd_recents_test.go index 7f7ce65..958d004 100644 --- a/cmd/soundtouch-cli/cmd_recents_test.go +++ b/cmd/soundtouch-cli/cmd_recents_test.go @@ -17,7 +17,7 @@ func TestRecentsCommands(t *testing.T) { }{ { name: "recents list command", - args: []string{"soundtouch-cli", "--host", "192.168.1.100", "recents", "list"}, + args: []string{"soundtouch-cli", "--host", "192.0.2.100", "recents", "list"}, expectedOutput: []string{ "Getting recently played content", "Recent Items Summary:", @@ -26,7 +26,7 @@ func TestRecentsCommands(t *testing.T) { }, { name: "recents filter by source", - args: []string{"soundtouch-cli", "--host", "192.168.1.100", "recents", "filter", "--source", "SPOTIFY"}, + args: []string{"soundtouch-cli", "--host", "192.0.2.100", "recents", "filter", "--source", "SPOTIFY"}, expectedOutput: []string{ "Getting filtered recent content", "filtered by source: SPOTIFY", @@ -34,7 +34,7 @@ func TestRecentsCommands(t *testing.T) { }, { name: "recents latest command", - args: []string{"soundtouch-cli", "--host", "192.168.1.100", "recents", "latest"}, + args: []string{"soundtouch-cli", "--host", "192.0.2.100", "recents", "latest"}, expectedOutput: []string{ "Getting most recent item", "Most Recent Item:", @@ -42,7 +42,7 @@ func TestRecentsCommands(t *testing.T) { }, { name: "recents stats command", - args: []string{"soundtouch-cli", "--host", "192.168.1.100", "recents", "stats"}, + args: []string{"soundtouch-cli", "--host", "192.0.2.100", "recents", "stats"}, expectedOutput: []string{ "Getting recent items statistics", "Recent Items Statistics", diff --git a/cmd/soundtouch-cli/cmd_setup_test.go b/cmd/soundtouch-cli/cmd_setup_test.go index 40a20d8..28f57dc 100644 --- a/cmd/soundtouch-cli/cmd_setup_test.go +++ b/cmd/soundtouch-cli/cmd_setup_test.go @@ -169,7 +169,7 @@ func TestBuildPlanSteps_NoOpWhenAlreadyMigratedAndPaired(t *testing.T) { summary := &setup.MigrationSummary{IsMigrated: true, IsPaired: true, TelnetMigrated: true} inspect := &setup.InspectReport{Info: &setup.DeviceInfoXML{DeviceID: "AABBCCDDEEFF"}} - steps := buildPlanSteps("192.168.1.42", "http://aftertouch.local:8000", "", true, false, inspect, summary) + steps := buildPlanSteps("192.0.2.42", "http://aftertouch.local:8000", "", true, false, inspect, summary) if len(steps) != 0 { t.Errorf("expected no steps for fully-set-up device, got %d:\n%v", len(steps), steps) @@ -180,7 +180,7 @@ func TestBuildPlanSteps_RecommendsPairWhenMigratedButUnpaired(t *testing.T) { summary := &setup.MigrationSummary{IsMigrated: true, IsPaired: false, TelnetMigrated: true, TelnetReachable: true} inspect := &setup.InspectReport{Info: &setup.DeviceInfoXML{DeviceID: "AABBCCDDEEFF"}} - steps := buildPlanSteps("192.168.1.42", "http://aftertouch.local:8000", "", true, false, inspect, summary) + steps := buildPlanSteps("192.0.2.42", "http://aftertouch.local:8000", "", true, false, inspect, summary) if len(steps) != 1 { t.Fatalf("expected exactly the pair step, got %d:\n%v", len(steps), steps) @@ -195,7 +195,7 @@ func TestBuildPlanSteps_MigrateRebootThenPairWhenFresh(t *testing.T) { summary := &setup.MigrationSummary{TelnetReachable: true, SSHSuccess: false, IsPaired: false} inspect := &setup.InspectReport{Info: &setup.DeviceInfoXML{DeviceID: "AABBCCDDEEFF"}} - steps := buildPlanSteps("192.168.1.42", "http://aftertouch.local:8000", "", true, false, inspect, summary) + steps := buildPlanSteps("192.0.2.42", "http://aftertouch.local:8000", "", true, false, inspect, summary) // migrate → reboot → pair. The reboot step exists because envswitch's // parallel-persistence layer only fully wins on the next boot, and we @@ -228,7 +228,7 @@ func TestBuildPlanSteps_DNSMethodPrependsCAInstall(t *testing.T) { } inspect := &setup.InspectReport{Info: &setup.DeviceInfoXML{DeviceID: "X"}} - steps := buildPlanSteps("192.168.1.42", "http://aftertouch.local:8000", "", false, false, inspect, summary) + steps := buildPlanSteps("192.0.2.42", "http://aftertouch.local:8000", "", false, false, inspect, summary) if len(steps) < 2 { t.Fatalf("expected at least install-ca + migrate, got %d steps:\n%v", len(steps), steps) @@ -256,7 +256,7 @@ func TestBuildPlanSteps_ResetModeIncludesManualNetworkSwitches(t *testing.T) { } summary := &setup.MigrationSummary{IsMigrated: true, IsPaired: true} // doesn't matter in reset mode - steps := buildPlanSteps("192.168.1.42", "http://aftertouch.local:8000", "", true, true, inspect, summary) + steps := buildPlanSteps("192.0.2.42", "http://aftertouch.local:8000", "", true, true, inspect, summary) // Expected sequence in --reset mode: // factory-reset, manual AP switch, wait-ap, wifi-push, manual home switch, diff --git a/cmd/soundtouch-cli/main_test.go b/cmd/soundtouch-cli/main_test.go index a4e4f3e..e195549 100644 --- a/cmd/soundtouch-cli/main_test.go +++ b/cmd/soundtouch-cli/main_test.go @@ -14,16 +14,16 @@ func TestParseHostPort(t *testing.T) { }{ { name: "IPv4 with port", - input: "192.168.1.10:8090", + input: "192.0.2.10:8090", defaultPort: 8080, - wantHost: "192.168.1.10", + wantHost: "192.0.2.10", wantPort: 8090, }, { name: "IPv4 without port", - input: "192.168.1.10", + input: "192.0.2.10", defaultPort: 8080, - wantHost: "192.168.1.10", + wantHost: "192.0.2.10", wantPort: 8080, }, { @@ -63,30 +63,30 @@ func TestParseHostPort(t *testing.T) { }, { name: "invalid port - non-numeric", - input: "192.168.1.10:abc", + input: "192.0.2.10:abc", defaultPort: 8080, - wantHost: "192.168.1.10", + wantHost: "192.0.2.10", wantPort: 8080, }, { name: "invalid port - too high", - input: "192.168.1.10:99999", + input: "192.0.2.10:99999", defaultPort: 8080, - wantHost: "192.168.1.10", + wantHost: "192.0.2.10", wantPort: 8080, }, { name: "invalid port - zero", - input: "192.168.1.10:0", + input: "192.0.2.10:0", defaultPort: 8080, - wantHost: "192.168.1.10", + wantHost: "192.0.2.10", wantPort: 8080, }, { name: "invalid port - negative", - input: "192.168.1.10:-123", + input: "192.0.2.10:-123", defaultPort: 8080, - wantHost: "192.168.1.10", + wantHost: "192.0.2.10", wantPort: 8080, }, { @@ -105,37 +105,37 @@ func TestParseHostPort(t *testing.T) { }, { name: "multiple colons - malformed", - input: "192.168.1.100:8090:extra", + input: "192.0.2.100:8090:extra", defaultPort: 8080, - wantHost: "192.168.1.100:8090:extra", + wantHost: "192.0.2.100:8090:extra", wantPort: 8080, }, { name: "standard SoundTouch default", - input: "192.168.1.10", + input: "192.0.2.10", defaultPort: 8090, - wantHost: "192.168.1.10", + wantHost: "192.0.2.10", wantPort: 8090, }, { name: "valid high port", - input: "192.168.1.100:65535", + input: "192.0.2.100:65535", defaultPort: 8080, - wantHost: "192.168.1.100", + wantHost: "192.0.2.100", wantPort: 65535, }, { name: "valid low port", - input: "192.168.1.100:1", + input: "192.0.2.100:1", defaultPort: 8080, - wantHost: "192.168.1.100", + wantHost: "192.0.2.100", wantPort: 1, }, { name: "real SoundTouch device example", - input: "192.168.1.10:8090", + input: "192.0.2.10:8090", defaultPort: 8080, - wantHost: "192.168.1.10", + wantHost: "192.0.2.10", wantPort: 8090, }, { @@ -166,8 +166,8 @@ func BenchmarkParseHostPort(b *testing.B) { name string input string }{ - {"with_port", "192.168.1.100:8090"}, - {"without_port", "192.168.1.100"}, + {"with_port", "192.0.2.100:8090"}, + {"without_port", "192.0.2.100"}, {"hostname_with_port", "soundtouch.local:8090"}, {"ipv6_with_port", "[::1]:8090"}, } @@ -193,26 +193,26 @@ func TestParseHostPortSoundTouchScenarios(t *testing.T) { }{ { name: "typical_cli_usage", - input: "192.168.1.10:8091", + input: "192.0.2.10:8091", defaultPort: 8090, description: "User specifies full host:port", - wantHost: "192.168.1.10", + wantHost: "192.0.2.10", wantPort: 8091, }, { name: "discovery_result_host_only", - input: "192.168.1.10", + input: "192.0.2.10", defaultPort: 8090, description: "Discovery returns IP, CLI uses default port", - wantHost: "192.168.1.10", + wantHost: "192.0.2.10", wantPort: 8090, }, { name: "custom_port_override", - input: "192.168.1.100:9000", + input: "192.0.2.100:9000", defaultPort: 8090, description: "User overrides default SoundTouch port", - wantHost: "192.168.1.100", + wantHost: "192.0.2.100", wantPort: 9000, }, { @@ -225,10 +225,10 @@ func TestParseHostPortSoundTouchScenarios(t *testing.T) { }, { name: "invalid_port_fallback", - input: "192.168.1.10:invalid", + input: "192.0.2.10:invalid", defaultPort: 8090, description: "Malformed port should fallback to default", - wantHost: "192.168.1.10", + wantHost: "192.0.2.10", wantPort: 8090, }, } diff --git a/cmd/soundtouch-service/router_test.go b/cmd/soundtouch-service/router_test.go index f3dd73d..9f5abe4 100644 --- a/cmd/soundtouch-service/router_test.go +++ b/cmd/soundtouch-service/router_test.go @@ -132,10 +132,10 @@ func TestPUTRenameRoutesToLocalHandler(t *testing.T) { ts := httptest.NewServer(r) defer ts.Close() - body := `Sound MachinechenA81B6A536A98` + body := `Living Room SoundTouchAABBCCDDEEFF` req, err := http.NewRequest(http.MethodPut, - ts.URL+"/streaming/account/1111111/device/A81B6A536A98", + ts.URL+"/streaming/account/1111111/device/AABBCCDDEEFF", strings.NewReader(body)) if err != nil { t.Fatalf("build request: %v", err) diff --git a/cmd/soundtouch-web/handlers/handlers_test.go b/cmd/soundtouch-web/handlers/handlers_test.go index 5945ae2..4b06af7 100644 --- a/cmd/soundtouch-web/handlers/handlers_test.go +++ b/cmd/soundtouch-web/handlers/handlers_test.go @@ -24,7 +24,7 @@ func createTestApp() *WebApp { Name: "Test Speaker", Type: "SoundTouch 30", NetworkInfo: []models.NetworkInfo{ - {MacAddress: "TEST123", IPAddress: "192.168.1.100"}, + {MacAddress: "TEST123", IPAddress: "192.0.2.100"}, }, } diff --git a/cmd/soundtouch-web/resolve_bind_addr_test.go b/cmd/soundtouch-web/resolve_bind_addr_test.go index db54ae6..26915e9 100644 --- a/cmd/soundtouch-web/resolve_bind_addr_test.go +++ b/cmd/soundtouch-web/resolve_bind_addr_test.go @@ -14,7 +14,7 @@ func TestResolveBindAddr_PassThrough(t *testing.T) { "", "localhost", "127.0.0.1", - "192.168.1.5", + "192.0.2.5", "::1", "definitely-not-an-iface-xyz", } @@ -102,21 +102,21 @@ func TestDefaultDiscoveryInterface(t *testing.T) { name: "explicit interface wins over bind-derived default", rawInterface: "eth1", rawBind: "eth0", - resolvedBind: "192.168.1.5", + resolvedBind: "192.0.2.5", want: "eth1", }, { name: "derive from --bind when --bind was an interface name", rawInterface: "", rawBind: "eth0", - resolvedBind: "192.168.1.5", + resolvedBind: "192.0.2.5", want: "eth0", }, { name: "no derivation when --bind was an IP literal", rawInterface: "", - rawBind: "192.168.1.5", - resolvedBind: "192.168.1.5", + rawBind: "192.0.2.5", + resolvedBind: "192.0.2.5", want: "", }, { diff --git a/cmd/soundtouch-web/webtypes/types_test.go b/cmd/soundtouch-web/webtypes/types_test.go index e93c3a1..a194d80 100644 --- a/cmd/soundtouch-web/webtypes/types_test.go +++ b/cmd/soundtouch-web/webtypes/types_test.go @@ -128,7 +128,7 @@ func TestDeviceConnection(t *testing.T) { Name: "Test Speaker", Type: "SoundTouch 30", NetworkInfo: []models.NetworkInfo{ - {MacAddress: "TEST123", IPAddress: "192.168.1.100"}, + {MacAddress: "TEST123", IPAddress: "192.0.2.100"}, }, } diff --git a/pkg/client/additional_endpoints_test.go b/pkg/client/additional_endpoints_test.go index 07dcd11..e656d3f 100644 --- a/pkg/client/additional_endpoints_test.go +++ b/pkg/client/additional_endpoints_test.go @@ -121,7 +121,7 @@ func TestClient_GetBassCapabilities(t *testing.T) { { name: "bass supported device", responseStatus: http.StatusOK, - responseBody: ` + responseBody: ` true -9 9 @@ -129,7 +129,7 @@ func TestClient_GetBassCapabilities(t *testing.T) { `, expectError: false, expectedCaps: &models.BassCapabilities{ - DeviceID: "A81B6A536A98", + DeviceID: "AABBCCDDEEFF", BassAvailable: true, BassMin: -9, BassMax: 9, @@ -139,7 +139,7 @@ func TestClient_GetBassCapabilities(t *testing.T) { { name: "bass not supported device", responseStatus: http.StatusOK, - responseBody: ` + responseBody: ` false 0 0 @@ -147,7 +147,7 @@ func TestClient_GetBassCapabilities(t *testing.T) { `, expectError: false, expectedCaps: &models.BassCapabilities{ - DeviceID: "A81B6A536A98", + DeviceID: "AABBCCDDEEFF", BassAvailable: false, BassMin: 0, BassMax: 0, @@ -306,7 +306,7 @@ func TestClient_GetTrackInfo(t *testing.T) { { name: "track info with full details", responseStatus: http.StatusOK, - responseBody: ` + responseBody: ` Test Track @@ -317,7 +317,7 @@ func TestClient_GetTrackInfo(t *testing.T) { `, expectError: false, expectedInfo: &models.NowPlaying{ - DeviceID: "A81B6A536A98", + DeviceID: "AABBCCDDEEFF", Source: "SPOTIFY", Track: "Test Track", Artist: "Test Artist", @@ -328,7 +328,7 @@ func TestClient_GetTrackInfo(t *testing.T) { { name: "radio station info", responseStatus: http.StatusOK, - responseBody: ` + responseBody: ` Jazz FM @@ -337,7 +337,7 @@ func TestClient_GetTrackInfo(t *testing.T) { `, expectError: false, expectedInfo: &models.NowPlaying{ - DeviceID: "A81B6A536A98", + DeviceID: "AABBCCDDEEFF", Source: "TUNEIN", StationName: "Jazz FM", PlayStatus: "PLAY_STATE", @@ -346,7 +346,7 @@ func TestClient_GetTrackInfo(t *testing.T) { { name: "standby state", responseStatus: http.StatusOK, - responseBody: ` + responseBody: ` STANDBY @@ -354,7 +354,7 @@ func TestClient_GetTrackInfo(t *testing.T) { `, expectError: false, expectedInfo: &models.NowPlaying{ - DeviceID: "A81B6A536A98", + DeviceID: "AABBCCDDEEFF", Source: "STANDBY", PlayStatus: "STOP_STATE", }, @@ -462,7 +462,7 @@ func TestClient_GetTrackInfo(t *testing.T) { func TestClient_NewEndpoints_NetworkError(t *testing.T) { // Create client pointing to non-existent server config := &Config{ - Host: "192.168.1.999", // Invalid IP + Host: "192.0.2.999", // Invalid IP Port: 8090, } client := NewClient(config) diff --git a/pkg/client/client_test.go b/pkg/client/client_test.go index 4d829d4..0138e6d 100644 --- a/pkg/client/client_test.go +++ b/pkg/client/client_test.go @@ -15,15 +15,15 @@ import ( func TestNewClient(t *testing.T) { config := &Config{ - Host: "192.168.1.100", + Host: "192.0.2.100", Port: 8090, Timeout: 15 * time.Second, } client := NewClient(config) - if client.baseURL != "http://192.168.1.100:8090" { - t.Errorf("Expected baseURL 'http://192.168.1.100:8090', got '%s'", client.baseURL) + if client.baseURL != "http://192.0.2.100:8090" { + t.Errorf("Expected baseURL 'http://192.0.2.100:8090', got '%s'", client.baseURL) } if client.timeout != 15*time.Second { @@ -37,12 +37,12 @@ func TestNewClient(t *testing.T) { func TestNewClientWithDefaults(t *testing.T) { config := &Config{ - Host: "192.168.1.100", + Host: "192.0.2.100", } client := NewClient(config) - if client.baseURL != "http://192.168.1.100:8090" { + if client.baseURL != "http://192.0.2.100:8090" { t.Errorf("Expected default port 8090 in baseURL, got '%s'", client.baseURL) } @@ -56,9 +56,9 @@ func TestNewClientWithDefaults(t *testing.T) { } func TestNewClientFromHost(t *testing.T) { - client := NewClientFromHost("192.168.1.200") + client := NewClientFromHost("192.0.2.200") - expected := "http://192.168.1.200:8090" + expected := "http://192.0.2.200:8090" if client.baseURL != expected { t.Errorf("Expected baseURL '%s', got '%s'", expected, client.baseURL) } @@ -152,8 +152,8 @@ func TestGetDeviceInfo_Success(t *testing.T) { t.Errorf("Expected first network type 'SCM', got '%s'", net.Type) } - if net.IPAddress != "192.168.1.10" { - t.Errorf("Expected IP address '192.168.1.10', got '%s'", net.IPAddress) + if net.IPAddress != "192.0.2.10" { + t.Errorf("Expected IP address '192.0.2.10', got '%s'", net.IPAddress) } } } @@ -259,8 +259,8 @@ func TestPing_Failure(t *testing.T) { } func TestBaseURL(t *testing.T) { - client := NewClientFromHost("192.168.1.100") - expected := "http://192.168.1.100:8090" + client := NewClientFromHost("192.0.2.100") + expected := "http://192.0.2.100:8090" if client.BaseURL() != expected { t.Errorf("Expected BaseURL '%s', got '%s'", expected, client.BaseURL()) diff --git a/pkg/client/example_test.go b/pkg/client/example_test.go index 9b5ef6f..da9fd71 100644 --- a/pkg/client/example_test.go +++ b/pkg/client/example_test.go @@ -13,7 +13,7 @@ import ( func Example() { // Create a client for your SoundTouch device config := &client.Config{ - Host: "192.168.1.100", + Host: "192.0.2.100", Port: 8090, Timeout: 10 * time.Second, } @@ -45,7 +45,7 @@ func Example() { // ExampleClient_GetNowPlaying demonstrates how to get current playback information. func ExampleClient_GetNowPlaying() { - config := &client.Config{Host: "192.168.1.100"} + config := &client.Config{Host: "192.0.2.100"} c := client.NewClient(config) nowPlaying, err := c.GetNowPlaying() @@ -67,7 +67,7 @@ func ExampleClient_GetNowPlaying() { // ExampleClient_SetVolume demonstrates volume control with validation. func ExampleClient_SetVolume() { - config := &client.Config{Host: "192.168.1.100"} + config := &client.Config{Host: "192.0.2.100"} c := client.NewClient(config) // Set volume to 75% @@ -92,7 +92,7 @@ func ExampleClient_SetVolume() { // ExampleClient_SelectSource demonstrates how to change audio sources. func ExampleClient_SelectSource() { - config := &client.Config{Host: "192.168.1.100"} + config := &client.Config{Host: "192.0.2.100"} c := client.NewClient(config) // Switch to Spotify @@ -121,7 +121,7 @@ func ExampleClient_SelectSource() { // ExampleClient_SetBass demonstrates bass control. func ExampleClient_SetBass() { - config := &client.Config{Host: "192.168.1.100"} + config := &client.Config{Host: "192.0.2.100"} c := client.NewClient(config) // Set bass to +3 (range: -9 to +9) @@ -144,7 +144,7 @@ func ExampleClient_SetBass() { // ExampleClient_SetBalance demonstrates balance control. func ExampleClient_SetBalance() { - config := &client.Config{Host: "192.168.1.100"} + config := &client.Config{Host: "192.0.2.100"} c := client.NewClient(config) // Set balance slightly to the right (range: -50 to +50) @@ -167,15 +167,15 @@ func ExampleClient_SetBalance() { // ExampleClient_SetZone demonstrates multiroom zone management. func ExampleClient_SetZone() { - config := &client.Config{Host: "192.168.1.100"} + config := &client.Config{Host: "192.0.2.100"} c := client.NewClient(config) // Create a zone with multiple speakers zone := &models.ZoneRequest{ - Master: "192.168.1.100", + Master: "192.0.2.100", Members: []models.MemberEntry{ - {IP: "192.168.1.101"}, - {IP: "192.168.1.102"}, + {IP: "192.0.2.101"}, + {IP: "192.0.2.102"}, }, } @@ -192,7 +192,7 @@ func ExampleClient_SetZone() { // ExampleClient_GetPresets demonstrates how to retrieve configured presets. func ExampleClient_GetPresets() { - config := &client.Config{Host: "192.168.1.100"} + config := &client.Config{Host: "192.0.2.100"} c := client.NewClient(config) presets, err := c.GetPresets() @@ -212,7 +212,7 @@ func ExampleClient_GetPresets() { // ExampleClient_NewWebSocketClient demonstrates WebSocket client creation. func ExampleClient_NewWebSocketClient() { - config := &client.Config{Host: "192.168.1.100"} + config := &client.Config{Host: "192.0.2.100"} c := client.NewClient(config) // Create WebSocket client for real-time events @@ -236,7 +236,7 @@ func ExampleClient_NewWebSocketClient() { // ExampleClient_SendKey demonstrates sending key commands. func ExampleClient_SendKey() { - config := &client.Config{Host: "192.168.1.100"} + config := &client.Config{Host: "192.0.2.100"} c := client.NewClient(config) // Send various key commands @@ -262,7 +262,7 @@ func ExampleClient_SendKey() { // ExampleClient_GetCapabilities demonstrates how to check device capabilities. func ExampleClient_GetCapabilities() { - config := &client.Config{Host: "192.168.1.100"} + config := &client.Config{Host: "192.0.2.100"} c := client.NewClient(config) capabilities, err := c.GetCapabilities() @@ -288,7 +288,7 @@ func ExampleClient_GetCapabilities() { func ExampleClient_GetSupportedURLs_concept() { // Example of how to use GetSupportedURLs() method // Note: This example shows the concept but doesn't execute to avoid requiring a real device - config := &client.Config{Host: "192.168.1.100"} + config := &client.Config{Host: "192.0.2.100"} c := client.NewClient(config) supportedURLs, err := c.GetSupportedURLs() diff --git a/pkg/client/group_test.go b/pkg/client/group_test.go index 021b9ea..ac02ca8 100644 --- a/pkg/client/group_test.go +++ b/pkg/client/group_test.go @@ -20,15 +20,15 @@ func TestClient_GetGroup_Configured(t *testing.T) { 9070658C9D4A LEFT - 192.168.1.131 + 192.0.2.131 F45EAB3115DA RIGHT - 192.168.1.134 + 192.0.2.134 - 192.168.1.131 + 192.0.2.131 GROUP_OK ` @@ -121,7 +121,7 @@ func TestClient_AddGroup(t *testing.T) { got.ID = "9999999" got.Status = "GROUP_OK" - got.SenderIPAddress = "192.168.1.131" + got.SenderIPAddress = "192.0.2.131" w.Header().Set("Content-Type", "application/xml") @@ -135,8 +135,8 @@ func TestClient_AddGroup(t *testing.T) { MasterDeviceID: "9070658C9D4A", Roles: models.GroupRoles{ Roles: []models.GroupRole{ - {DeviceID: "9070658C9D4A", Role: "LEFT", IPAddress: "192.168.1.131"}, - {DeviceID: "F45EAB3115DA", Role: "RIGHT", IPAddress: "192.168.1.134"}, + {DeviceID: "9070658C9D4A", Role: "LEFT", IPAddress: "192.0.2.131"}, + {DeviceID: "F45EAB3115DA", Role: "RIGHT", IPAddress: "192.0.2.134"}, }, }, } diff --git a/pkg/client/introspect_integration_test.go b/pkg/client/introspect_integration_test.go index 4b24746..5d34b49 100644 --- a/pkg/client/introspect_integration_test.go +++ b/pkg/client/introspect_integration_test.go @@ -181,7 +181,7 @@ func TestClient_Introspect_ErrorCases_Integration(t *testing.T) { // ExampleClient_Introspect demonstrates how to use the Introspect method func ExampleClient_Introspect() { config := &Config{ - Host: "192.168.1.100", + Host: "192.0.2.100", Port: 8090, } client := NewClient(config) @@ -216,7 +216,7 @@ func ExampleClient_Introspect() { // ExampleClient_IntrospectSpotify demonstrates the Spotify convenience method func ExampleClient_IntrospectSpotify() { config := &Config{ - Host: "192.168.1.100", + Host: "192.0.2.100", Port: 8090, } client := NewClient(config) diff --git a/pkg/client/navigation_examples_test.go b/pkg/client/navigation_examples_test.go index 998ed09..3162bca 100644 --- a/pkg/client/navigation_examples_test.go +++ b/pkg/client/navigation_examples_test.go @@ -7,7 +7,7 @@ import ( // ExampleClient_Navigate demonstrates basic navigation of content sources func ExampleClient_Navigate() { - config := &Config{Host: "192.168.1.100", Port: 8090} + config := &Config{Host: "192.0.2.100", Port: 8090} client := NewClient(config) // Navigate TuneIn content @@ -25,7 +25,7 @@ func ExampleClient_Navigate() { // ExampleClient_SearchStation demonstrates searching for radio stations func ExampleClient_SearchStation() { - config := &Config{Host: "192.168.1.100", Port: 8090} + config := &Config{Host: "192.0.2.100", Port: 8090} client := NewClient(config) // Search for jazz stations on TuneIn @@ -49,7 +49,7 @@ func ExampleClient_SearchStation() { // ExampleClient_AddStation demonstrates adding a station and playing it func ExampleClient_AddStation() { - config := &Config{Host: "192.168.1.100", Port: 8090} + config := &Config{Host: "192.0.2.100", Port: 8090} client := NewClient(config) // First, search for content to get a token @@ -79,7 +79,7 @@ func ExampleClient_AddStation() { // Example_navigationWorkflow demonstrates a complete workflow func Example_navigationWorkflow() { - config := &Config{Host: "192.168.1.100", Port: 8090} + config := &Config{Host: "192.0.2.100", Port: 8090} client := NewClient(config) // 1. Search for content @@ -134,7 +134,7 @@ func Example_navigationWorkflow() { // ExampleClient_NavigateContainer demonstrates browsing into directories func ExampleClient_NavigateContainer() { - config := &Config{Host: "192.168.1.100", Port: 8090} + config := &Config{Host: "192.0.2.100", Port: 8090} client := NewClient(config) // First, get the stored music library root @@ -187,7 +187,7 @@ func ExampleClient_NavigateContainer() { // Example_searchAndPlayWorkflow demonstrates search -> add -> play workflow func Example_searchAndPlayWorkflow() { - config := &Config{Host: "192.168.1.100", Port: 8090} + config := &Config{Host: "192.0.2.100", Port: 8090} client := NewClient(config) searchTerm := "classic rock" diff --git a/pkg/client/recents_integration_test.go b/pkg/client/recents_integration_test.go index d1e8c9e..aa5488d 100644 --- a/pkg/client/recents_integration_test.go +++ b/pkg/client/recents_integration_test.go @@ -254,7 +254,7 @@ func TestClient_GetRecents_ErrorConditions(t *testing.T) { // ExampleClient_GetRecents demonstrates how to use the GetRecents method func ExampleClient_GetRecents() { config := &Config{ - Host: "192.168.1.100", + Host: "192.0.2.100", Port: 8090, } client := NewClient(config) @@ -299,7 +299,7 @@ func ExampleClient_GetRecents() { // ExampleRecentsResponse_filtering demonstrates filtering recent items func ExampleRecentsResponse_filtering() { config := &Config{ - Host: "192.168.1.100", + Host: "192.0.2.100", Port: 8090, } client := NewClient(config) diff --git a/pkg/client/serviceavailability_integration_test.go b/pkg/client/serviceavailability_integration_test.go index e1cc3b2..455ac98 100644 --- a/pkg/client/serviceavailability_integration_test.go +++ b/pkg/client/serviceavailability_integration_test.go @@ -14,7 +14,7 @@ func TestGetServiceAvailability_Integration(t *testing.T) { // This test requires a real SoundTouch device // Set the SOUNDTOUCH_HOST environment variable to run this test - // Example: SOUNDTOUCH_HOST=192.168.1.100 go test -v -run TestGetServiceAvailability_Integration + // Example: SOUNDTOUCH_HOST=192.0.2.100 go test -v -run TestGetServiceAvailability_Integration host := os.Getenv("SOUNDTOUCH_TEST_HOST") if host == "" { t.Skip("SOUNDTOUCH_TEST_HOST environment variable not set - skipping integration tests") diff --git a/pkg/client/source_selection_test.go b/pkg/client/source_selection_test.go index 3f9a9e4..cc3004f 100644 --- a/pkg/client/source_selection_test.go +++ b/pkg/client/source_selection_test.go @@ -594,7 +594,7 @@ func TestClient_SelectContentItem(t *testing.T) { SourceAccount: "3f205110-4a57-4e91-810a-123456789012", IsPresetable: true, ItemName: "Welcome to the New", - ContainerArt: "http://192.168.1.14:8085/v1/albums/983/image", + ContainerArt: "http://192.0.2.14:8085/v1/albums/983/image", }, wantError: false, }, @@ -761,7 +761,7 @@ func TestClient_SelectLocalMusic(t *testing.T) { location: "album:983", sourceAccount: "3f205110-4a57-4e91-810a-123456789012", itemName: "Welcome to the New", - containerArt: "http://192.168.1.14:8085/v1/albums/983/image", + containerArt: "http://192.0.2.14:8085/v1/albums/983/image", wantError: false, }, { diff --git a/pkg/client/system_test.go b/pkg/client/system_test.go index f229054..143e7d7 100644 --- a/pkg/client/system_test.go +++ b/pkg/client/system_test.go @@ -464,7 +464,7 @@ func TestClient_GetNetworkInfo(t *testing.T) { name: "Successful network info retrieval - WiFi device", serverResponse: ` - + `, @@ -477,7 +477,7 @@ func TestClient_GetNetworkInfo(t *testing.T) { name: "Ethernet device", serverResponse: ` - + `, statusCode: http.StatusOK, @@ -557,7 +557,7 @@ func TestClient_SystemEndpoints_Integration(t *testing.T) { case "/networkInfo": _, _ = w.Write([]byte(` - + `)) default: diff --git a/pkg/client/testdata/info_response_st10.xml b/pkg/client/testdata/info_response_st10.xml index a3723e7..f0af8c8 100644 --- a/pkg/client/testdata/info_response_st10.xml +++ b/pkg/client/testdata/info_response_st10.xml @@ -18,11 +18,11 @@ https://streaming.bose.com AA:BB:CC:DD:EE:FF - 192.168.1.10 + 192.0.2.10 AA:BB:CC:DD:EE:FF - 192.168.1.10 + 192.0.2.10 sm2 rhino diff --git a/pkg/client/testdata/info_response_st20.xml b/pkg/client/testdata/info_response_st20.xml index e0b8136..971c69e 100644 --- a/pkg/client/testdata/info_response_st20.xml +++ b/pkg/client/testdata/info_response_st20.xml @@ -26,11 +26,11 @@ https://streaming.bose.com AA:BB:CC:DD:EE:FF - 192.168.1.10 + 192.0.2.10 AA:BB:CC:DD:EE:01 - 192.168.1.10 + 192.0.2.10 scm spotty diff --git a/pkg/client/testdata/networkinfo_ethernet_response.xml b/pkg/client/testdata/networkinfo_ethernet_response.xml index 72ec1eb..4c800e3 100644 --- a/pkg/client/testdata/networkinfo_ethernet_response.xml +++ b/pkg/client/testdata/networkinfo_ethernet_response.xml @@ -1,6 +1,6 @@ - + diff --git a/pkg/client/testdata/networkinfo_response.xml b/pkg/client/testdata/networkinfo_response.xml index 8f0779a..2573dab 100644 --- a/pkg/client/testdata/networkinfo_response.xml +++ b/pkg/client/testdata/networkinfo_response.xml @@ -1,7 +1,7 @@ - + diff --git a/pkg/client/testdata/nowplaying_radio.xml b/pkg/client/testdata/nowplaying_radio.xml index 69e2c2c..1b54915 100644 --- a/pkg/client/testdata/nowplaying_radio.xml +++ b/pkg/client/testdata/nowplaying_radio.xml @@ -1,5 +1,5 @@ - + Classic Rock 101.5 https://cdn-radiotime-logos.tunein.com/s123456q.png diff --git a/pkg/client/testdata/nowplaying_response.xml b/pkg/client/testdata/nowplaying_response.xml index 54765ed..e0b49c9 100644 --- a/pkg/client/testdata/nowplaying_response.xml +++ b/pkg/client/testdata/nowplaying_response.xml @@ -1,5 +1,5 @@ - + SYML https://i.scdn.co/image/ab67616d0000b273ca6f00df62ef197fdc8af79c diff --git a/pkg/client/testdata/sources_response.xml b/pkg/client/testdata/sources_response.xml index d35bf4d..0e98694 100644 --- a/pkg/client/testdata/sources_response.xml +++ b/pkg/client/testdata/sources_response.xml @@ -1,5 +1,5 @@ - + AUX IN AirPlayUserName QPlay1UserName diff --git a/pkg/client/websocket_test.go b/pkg/client/websocket_test.go index bdb732d..29d149c 100644 --- a/pkg/client/websocket_test.go +++ b/pkg/client/websocket_test.go @@ -120,7 +120,7 @@ func TestDefaultWebSocketConfig(t *testing.T) { } func TestNewWebSocketClient(t *testing.T) { - client := NewClientFromHost("192.168.1.10") + client := NewClientFromHost("192.0.2.10") wsClient := client.NewWebSocketClient(nil) if wsClient == nil { @@ -145,7 +145,7 @@ func TestNewWebSocketClient(t *testing.T) { } func TestWebSocketClient_SetHandlers(t *testing.T) { - client := NewClientFromHost("192.168.1.10") + client := NewClientFromHost("192.0.2.10") wsClient := client.NewWebSocketClient(nil) handlers := &models.WebSocketEventHandlers{ @@ -170,7 +170,7 @@ func TestWebSocketClient_SetHandlers(t *testing.T) { } func TestWebSocketClient_IndividualHandlers(t *testing.T) { - client := NewClientFromHost("192.168.1.10") + client := NewClientFromHost("192.0.2.10") wsClient := client.NewWebSocketClient(nil) wsClient.OnNowPlaying(func(_ *models.NowPlayingUpdatedEvent) { @@ -204,7 +204,7 @@ func TestWebSocketClient_IndividualHandlers(t *testing.T) { } func TestWebSocketClient_IsConnected(t *testing.T) { - client := NewClientFromHost("192.168.1.10") + client := NewClientFromHost("192.0.2.10") wsClient := client.NewWebSocketClient(nil) // Initially should not be connected @@ -245,7 +245,7 @@ func TestWebSocketClient_ConnectToMockServer(t *testing.T) { } func TestWebSocketClient_Disconnect(t *testing.T) { - client := NewClientFromHost("192.168.1.10") + client := NewClientFromHost("192.0.2.10") wsClient := client.NewWebSocketClient(nil) // Test disconnect when not connected @@ -270,7 +270,7 @@ func TestWebSocketClient_Disconnect(t *testing.T) { } func TestWebSocketClient_HandleMessage(t *testing.T) { - client := NewClientFromHost("192.168.1.10") + client := NewClientFromHost("192.0.2.10") wsClient := client.NewWebSocketClient(&WebSocketConfig{ Logger: &mockLogger{}, }) @@ -358,7 +358,7 @@ func TestWebSocketClient_HandleMessage(t *testing.T) { } func TestWebSocketClient_HandleUnknownEvent(t *testing.T) { - client := NewClientFromHost("192.168.1.10") + client := NewClientFromHost("192.0.2.10") logger := &mockLogger{} wsClient := client.NewWebSocketClient(&WebSocketConfig{ Logger: logger, @@ -389,7 +389,7 @@ func TestWebSocketClient_HandleUnknownEvent(t *testing.T) { } func TestWebSocketClient_SendMessage(t *testing.T) { - client := NewClientFromHost("192.168.1.10") + client := NewClientFromHost("192.0.2.10") wsClient := client.NewWebSocketClient(nil) // Test send when not connected @@ -400,7 +400,7 @@ func TestWebSocketClient_SendMessage(t *testing.T) { } func TestWebSocketClient_ConfigValidation(t *testing.T) { - client := NewClientFromHost("192.168.1.10") + client := NewClientFromHost("192.0.2.10") t.Run("NilConfig", func(t *testing.T) { wsClient := client.NewWebSocketClient(nil) @@ -428,7 +428,7 @@ func TestWebSocketClient_ConfigValidation(t *testing.T) { } func TestWebSocketClient_ConcurrentAccess(_ *testing.T) { - client := NewClientFromHost("192.168.1.10") + client := NewClientFromHost("192.0.2.10") wsClient := client.NewWebSocketClient(nil) // Test concurrent access to handlers @@ -460,7 +460,7 @@ func TestWebSocketClient_ConcurrentAccess(_ *testing.T) { // Benchmark tests func BenchmarkWebSocketClient_HandleMessage(b *testing.B) { - client := NewClientFromHost("192.168.1.10") + client := NewClientFromHost("192.0.2.10") wsClient := client.NewWebSocketClient(&WebSocketConfig{ Logger: &mockLogger{}, }) @@ -489,7 +489,7 @@ func BenchmarkWebSocketClient_HandleMessage(b *testing.B) { } func BenchmarkWebSocketClient_SetHandlers(b *testing.B) { - client := NewClientFromHost("192.168.1.10") + client := NewClientFromHost("192.0.2.10") wsClient := client.NewWebSocketClient(nil) handlers := &models.WebSocketEventHandlers{ diff --git a/pkg/client/zone_slave_test.go b/pkg/client/zone_slave_test.go index 912a8d0..25c3809 100644 --- a/pkg/client/zone_slave_test.go +++ b/pkg/client/zone_slave_test.go @@ -24,7 +24,7 @@ func TestClient_AddZoneSlave(t *testing.T) { name: "successful add zone slave with IP", masterID: "MASTER123", slaveID: "SLAVE456", - slaveIP: "192.168.1.101", + slaveIP: "192.0.2.101", responseStatus: http.StatusOK, responseBody: `OK`, expectError: false, @@ -44,7 +44,7 @@ func TestClient_AddZoneSlave(t *testing.T) { name: "server error response", masterID: "MASTER123", slaveID: "SLAVE456", - slaveIP: "192.168.1.101", + slaveIP: "192.0.2.101", responseStatus: http.StatusInternalServerError, responseBody: `Internal Server Error`, expectError: true, @@ -54,7 +54,7 @@ func TestClient_AddZoneSlave(t *testing.T) { name: "empty master device ID", masterID: "", slaveID: "SLAVE456", - slaveIP: "192.168.1.101", + slaveIP: "192.0.2.101", responseStatus: http.StatusOK, responseBody: `OK`, expectError: true, @@ -64,7 +64,7 @@ func TestClient_AddZoneSlave(t *testing.T) { name: "empty slave device ID", masterID: "MASTER123", slaveID: "", - slaveIP: "192.168.1.101", + slaveIP: "192.0.2.101", responseStatus: http.StatusOK, responseBody: `OK`, expectError: true, @@ -84,7 +84,7 @@ func TestClient_AddZoneSlave(t *testing.T) { name: "same master and slave device ID", masterID: "MASTER123", slaveID: "MASTER123", - slaveIP: "192.168.1.101", + slaveIP: "192.0.2.101", responseStatus: http.StatusOK, responseBody: `OK`, expectError: true, @@ -218,7 +218,7 @@ func TestClient_RemoveZoneSlave(t *testing.T) { name: "successful remove zone slave with IP", masterID: "MASTER123", slaveID: "SLAVE456", - slaveIP: "192.168.1.101", + slaveIP: "192.0.2.101", responseStatus: http.StatusOK, responseBody: `OK`, expectError: false, @@ -238,7 +238,7 @@ func TestClient_RemoveZoneSlave(t *testing.T) { name: "server error response", masterID: "MASTER123", slaveID: "SLAVE456", - slaveIP: "192.168.1.101", + slaveIP: "192.0.2.101", responseStatus: http.StatusBadRequest, responseBody: `Bad Request`, expectError: true, @@ -248,7 +248,7 @@ func TestClient_RemoveZoneSlave(t *testing.T) { name: "device not found", masterID: "MASTER123", slaveID: "NONEXISTENT", - slaveIP: "192.168.1.101", + slaveIP: "192.0.2.101", responseStatus: http.StatusNotFound, responseBody: `Device not found`, expectError: true, @@ -374,7 +374,7 @@ func TestZoneSlaveRequest_Validation(t *testing.T) { request: &models.ZoneSlaveRequest{ Master: "MASTER123", Members: []models.ZoneSlaveEntry{ - {DeviceID: "SLAVE456", IP: "192.168.1.101"}, + {DeviceID: "SLAVE456", IP: "192.0.2.101"}, }, }, expectError: false, @@ -394,7 +394,7 @@ func TestZoneSlaveRequest_Validation(t *testing.T) { request: &models.ZoneSlaveRequest{ Master: "", Members: []models.ZoneSlaveEntry{ - {DeviceID: "SLAVE456", IP: "192.168.1.101"}, + {DeviceID: "SLAVE456", IP: "192.0.2.101"}, }, }, expectError: true, @@ -414,8 +414,8 @@ func TestZoneSlaveRequest_Validation(t *testing.T) { request: &models.ZoneSlaveRequest{ Master: "MASTER123", Members: []models.ZoneSlaveEntry{ - {DeviceID: "SLAVE456", IP: "192.168.1.101"}, - {DeviceID: "SLAVE789", IP: "192.168.1.102"}, + {DeviceID: "SLAVE456", IP: "192.0.2.101"}, + {DeviceID: "SLAVE789", IP: "192.0.2.102"}, }, }, expectError: true, @@ -426,7 +426,7 @@ func TestZoneSlaveRequest_Validation(t *testing.T) { request: &models.ZoneSlaveRequest{ Master: "MASTER123", Members: []models.ZoneSlaveEntry{ - {DeviceID: "", IP: "192.168.1.101"}, + {DeviceID: "", IP: "192.0.2.101"}, }, }, expectError: true, @@ -437,7 +437,7 @@ func TestZoneSlaveRequest_Validation(t *testing.T) { request: &models.ZoneSlaveRequest{ Master: "MASTER123", Members: []models.ZoneSlaveEntry{ - {DeviceID: "MASTER123", IP: "192.168.1.101"}, + {DeviceID: "MASTER123", IP: "192.0.2.101"}, }, }, expectError: true, @@ -481,7 +481,7 @@ func TestZoneSlaveRequest_Validation(t *testing.T) { func TestZoneSlaveRequest_HelperMethods(t *testing.T) { t.Run("GetSlaveDeviceID", func(t *testing.T) { request := models.NewZoneSlaveRequest("MASTER123") - request.AddSlave("SLAVE456", "192.168.1.101") + request.AddSlave("SLAVE456", "192.0.2.101") deviceID := request.GetSlaveDeviceID() if deviceID != "SLAVE456" { @@ -491,11 +491,11 @@ func TestZoneSlaveRequest_HelperMethods(t *testing.T) { t.Run("GetSlaveIP", func(t *testing.T) { request := models.NewZoneSlaveRequest("MASTER123") - request.AddSlave("SLAVE456", "192.168.1.101") + request.AddSlave("SLAVE456", "192.0.2.101") ip := request.GetSlaveIP() - if ip != "192.168.1.101" { - t.Errorf("Expected IP '192.168.1.101', got '%s'", ip) + if ip != "192.0.2.101" { + t.Errorf("Expected IP '192.0.2.101', got '%s'", ip) } }) @@ -510,11 +510,11 @@ func TestZoneSlaveRequest_HelperMethods(t *testing.T) { t.Run("String representation", func(t *testing.T) { request := models.NewZoneSlaveRequest("MASTER123") - request.AddSlave("SLAVE456", "192.168.1.101") + request.AddSlave("SLAVE456", "192.0.2.101") str := request.String() - expected := "Zone slave operation: master=MASTER123, slave=SLAVE456 (192.168.1.101)" + expected := "Zone slave operation: master=MASTER123, slave=SLAVE456 (192.0.2.101)" if str != expected { t.Errorf("Expected string '%s', got '%s'", expected, str) } @@ -541,13 +541,13 @@ func TestClient_ZoneSlaveOperations_NetworkError(t *testing.T) { client := NewClient(config) // Test AddZoneSlave with network error - err := client.AddZoneSlave("MASTER123", "SLAVE456", "192.168.1.101") + err := client.AddZoneSlave("MASTER123", "SLAVE456", "192.0.2.101") if err == nil { t.Errorf("Expected network error for AddZoneSlave but got none") } // Test RemoveZoneSlave with network error - err = client.RemoveZoneSlave("MASTER123", "SLAVE456", "192.168.1.101") + err = client.RemoveZoneSlave("MASTER123", "SLAVE456", "192.0.2.101") if err == nil { t.Errorf("Expected network error for RemoveZoneSlave but got none") } diff --git a/pkg/client/zone_test.go b/pkg/client/zone_test.go index 0ee1f5d..4806fb9 100644 --- a/pkg/client/zone_test.go +++ b/pkg/client/zone_test.go @@ -32,8 +32,8 @@ func TestClient_GetZone(t *testing.T) { name: "Zone with members", responseXML: ` - EFGH5678IJKL - IJKL9012MNOP + EFGH5678IJKL + IJKL9012MNOP `, responseStatus: http.StatusOK, expectError: false, @@ -117,7 +117,7 @@ func TestClient_SetZone(t *testing.T) { name: "Valid zone request", zoneRequest: func() *models.ZoneRequest { zr := models.NewZoneRequest("ABCD1234EFGH") - zr.AddMember("EFGH5678IJKL", "192.168.1.11") + zr.AddMember("EFGH5678IJKL", "192.0.2.11") return zr }(), @@ -140,7 +140,7 @@ func TestClient_SetZone(t *testing.T) { name: "Invalid zone request - duplicate device", zoneRequest: func() *models.ZoneRequest { zr := models.NewZoneRequest("ABCD1234EFGH") - zr.AddMember("ABCD1234EFGH", "192.168.1.10") // Same as master + zr.AddMember("ABCD1234EFGH", "192.0.2.10") // Same as master return zr }(), @@ -238,8 +238,8 @@ func TestClient_CreateZoneWithIPs(t *testing.T) { masterDeviceID := "ABCD1234EFGH" members := map[string]string{ - "EFGH5678IJKL": "192.168.1.11", - "IJKL9012MNOP": "192.168.1.12", + "EFGH5678IJKL": "192.0.2.11", + "IJKL9012MNOP": "192.0.2.12", } err := client.CreateZoneWithIPs(masterDeviceID, members) @@ -260,7 +260,7 @@ func TestClient_AddToZone(t *testing.T) { // Return existing zone response := ` - EFGH5678IJKL + EFGH5678IJKL ` w.WriteHeader(http.StatusOK) @@ -277,7 +277,7 @@ func TestClient_AddToZone(t *testing.T) { client := createTestClient(server.URL) - err := client.AddToZone("IJKL9012MNOP", "192.168.1.12") + err := client.AddToZone("IJKL9012MNOP", "192.0.2.12") if err != nil { t.Errorf("Expected no error, but got: %v", err) } @@ -303,8 +303,8 @@ func TestClient_RemoveFromZone(t *testing.T) { // Return existing zone with members response := ` - EFGH5678IJKL - IJKL9012MNOP + EFGH5678IJKL + IJKL9012MNOP ` w.WriteHeader(http.StatusOK) @@ -347,8 +347,8 @@ func TestClient_DissolveZone(t *testing.T) { // Return existing zone with members response := ` - EFGH5678IJKL - IJKL9012MNOP + EFGH5678IJKL + IJKL9012MNOP ` w.WriteHeader(http.StatusOK) @@ -397,7 +397,7 @@ func TestClient_IsInZone(t *testing.T) { name: "Device in zone", responseXML: ` - EFGH5678IJKL + EFGH5678IJKL `, expectedResult: true, expectError: false, @@ -469,7 +469,7 @@ func TestClient_GetZoneStatus(t *testing.T) { `, zoneXML: ` - EFGH5678IJKL + EFGH5678IJKL `, expectedStatus: models.ZoneStatusMaster, expectError: false, @@ -483,7 +483,7 @@ func TestClient_GetZoneStatus(t *testing.T) { `, zoneXML: ` - EFGH5678IJKL + EFGH5678IJKL `, expectedStatus: models.ZoneStatusSlave, expectError: false, @@ -548,8 +548,8 @@ func TestClient_GetZoneMembers(t *testing.T) { name: "Zone with members", responseXML: ` - EFGH5678IJKL - IJKL9012MNOP + EFGH5678IJKL + IJKL9012MNOP `, expectedMembers: []string{"ABCD1234EFGH", "EFGH5678IJKL", "IJKL9012MNOP"}, expectError: false, @@ -633,7 +633,7 @@ func TestClient_Zone_ErrorHandling(t *testing.T) { client := createTestClient(server.URL) - err := client.AddToZone("DEVICE456", "192.168.1.10") + err := client.AddToZone("DEVICE456", "192.0.2.10") if err == nil { t.Error("Expected error when GetZone fails, but got none") } @@ -650,8 +650,8 @@ func BenchmarkClient_GetZone(b *testing.B) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { response := ` - EFGH5678IJKL - IJKL9012MNOP + EFGH5678IJKL + IJKL9012MNOP ` w.Header().Set("Content-Type", "application/xml") @@ -681,7 +681,7 @@ func BenchmarkClient_SetZone(b *testing.B) { client := createTestClient(server.URL) zoneRequest := models.NewZoneRequest("ABCD1234EFGH") - zoneRequest.AddMember("EFGH5678IJKL", "192.168.1.11") + zoneRequest.AddMember("EFGH5678IJKL", "192.0.2.11") b.ResetTimer() diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index 839b0c4..1f9f09a 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -110,51 +110,51 @@ func TestLoadFromEnv_WithEnvVars(t *testing.T) { } func TestParseDeviceString_HostOnly(t *testing.T) { - device, err := parseDeviceString("192.168.1.100") + device, err := parseDeviceString("192.0.2.100") if err != nil { t.Fatalf("Expected no error, got %v", err) } - if device.Host != "192.168.1.100" { - t.Errorf("Expected host '192.168.1.100', got '%s'", device.Host) + if device.Host != "192.0.2.100" { + t.Errorf("Expected host '192.0.2.100', got '%s'", device.Host) } if device.Port != 8090 { t.Errorf("Expected default port 8090, got %d", device.Port) } - if device.Name != "SoundTouch-192.168.1.100" { - t.Errorf("Expected default name 'SoundTouch-192.168.1.100', got '%s'", device.Name) + if device.Name != "SoundTouch-192.0.2.100" { + t.Errorf("Expected default name 'SoundTouch-192.0.2.100', got '%s'", device.Name) } } func TestParseDeviceString_HostPort(t *testing.T) { - device, err := parseDeviceString("192.168.1.100:8091") + device, err := parseDeviceString("192.0.2.100:8091") if err != nil { t.Fatalf("Expected no error, got %v", err) } - if device.Host != "192.168.1.100" { - t.Errorf("Expected host '192.168.1.100', got '%s'", device.Host) + if device.Host != "192.0.2.100" { + t.Errorf("Expected host '192.0.2.100', got '%s'", device.Host) } if device.Port != 8091 { t.Errorf("Expected port 8091, got %d", device.Port) } - if device.Name != "SoundTouch-192.168.1.100" { - t.Errorf("Expected default name 'SoundTouch-192.168.1.100', got '%s'", device.Name) + if device.Name != "SoundTouch-192.0.2.100" { + t.Errorf("Expected default name 'SoundTouch-192.0.2.100', got '%s'", device.Name) } } func TestParseDeviceString_NameHostPort(t *testing.T) { - device, err := parseDeviceString("Living Room@192.168.1.100:8090") + device, err := parseDeviceString("Living Room@192.0.2.100:8090") if err != nil { t.Fatalf("Expected no error, got %v", err) } - if device.Host != "192.168.1.100" { - t.Errorf("Expected host '192.168.1.100', got '%s'", device.Host) + if device.Host != "192.0.2.100" { + t.Errorf("Expected host '192.0.2.100', got '%s'", device.Host) } if device.Port != 8090 { @@ -167,13 +167,13 @@ func TestParseDeviceString_NameHostPort(t *testing.T) { } func TestParseDeviceString_NameHost(t *testing.T) { - device, err := parseDeviceString("Kitchen Speaker@192.168.1.101") + device, err := parseDeviceString("Kitchen Speaker@192.0.2.101") if err != nil { t.Fatalf("Expected no error, got %v", err) } - if device.Host != "192.168.1.101" { - t.Errorf("Expected host '192.168.1.101', got '%s'", device.Host) + if device.Host != "192.0.2.101" { + t.Errorf("Expected host '192.0.2.101', got '%s'", device.Host) } if device.Port != 8090 { @@ -186,17 +186,17 @@ func TestParseDeviceString_NameHost(t *testing.T) { } func TestParseDeviceString_InvalidPort(t *testing.T) { - _, err := parseDeviceString("192.168.1.100:invalid") + _, err := parseDeviceString("192.0.2.100:invalid") if err == nil { t.Error("Expected error for invalid port, got nil") } - _, err = parseDeviceString("192.168.1.100:0") + _, err = parseDeviceString("192.0.2.100:0") if err == nil { t.Error("Expected error for port 0, got nil") } - _, err = parseDeviceString("192.168.1.100:70000") + _, err = parseDeviceString("192.0.2.100:70000") if err == nil { t.Error("Expected error for port > 65535, got nil") } @@ -217,7 +217,7 @@ func TestParseDeviceString_EmptyHost(t *testing.T) { func TestParsePreferredDevices_SingleDevice(t *testing.T) { clearTestEnvVars() - _ = os.Setenv("PREFERRED_DEVICES", "192.168.1.100") + _ = os.Setenv("PREFERRED_DEVICES", "192.0.2.100") defer clearTestEnvVars() @@ -230,15 +230,15 @@ func TestParsePreferredDevices_SingleDevice(t *testing.T) { t.Errorf("Expected 1 device, got %d", len(devices)) } - if devices[0].Host != "192.168.1.100" { - t.Errorf("Expected host '192.168.1.100', got '%s'", devices[0].Host) + if devices[0].Host != "192.0.2.100" { + t.Errorf("Expected host '192.0.2.100', got '%s'", devices[0].Host) } } func TestParsePreferredDevices_MultipleDevices(t *testing.T) { clearTestEnvVars() - _ = os.Setenv("PREFERRED_DEVICES", "Living Room@192.168.1.100:8090;Kitchen@192.168.1.101;192.168.1.102:8091") + _ = os.Setenv("PREFERRED_DEVICES", "Living Room@192.0.2.100:8090;Kitchen@192.0.2.101;192.0.2.102:8091") defer clearTestEnvVars() @@ -256,8 +256,8 @@ func TestParsePreferredDevices_MultipleDevices(t *testing.T) { t.Errorf("Expected first device name 'Living Room', got '%s'", devices[0].Name) } - if devices[0].Host != "192.168.1.100" { - t.Errorf("Expected first device host '192.168.1.100', got '%s'", devices[0].Host) + if devices[0].Host != "192.0.2.100" { + t.Errorf("Expected first device host '192.0.2.100', got '%s'", devices[0].Host) } if devices[0].Port != 8090 { @@ -269,8 +269,8 @@ func TestParsePreferredDevices_MultipleDevices(t *testing.T) { t.Errorf("Expected second device name 'Kitchen', got '%s'", devices[1].Name) } - if devices[1].Host != "192.168.1.101" { - t.Errorf("Expected second device host '192.168.1.101', got '%s'", devices[1].Host) + if devices[1].Host != "192.0.2.101" { + t.Errorf("Expected second device host '192.0.2.101', got '%s'", devices[1].Host) } if devices[1].Port != 8090 { @@ -278,12 +278,12 @@ func TestParsePreferredDevices_MultipleDevices(t *testing.T) { } // Check third device - if devices[2].Name != "SoundTouch-192.168.1.102" { + if devices[2].Name != "SoundTouch-192.0.2.102" { t.Errorf("Expected third device default name, got '%s'", devices[2].Name) } - if devices[2].Host != "192.168.1.102" { - t.Errorf("Expected third device host '192.168.1.102', got '%s'", devices[2].Host) + if devices[2].Host != "192.0.2.102" { + t.Errorf("Expected third device host '192.0.2.102', got '%s'", devices[2].Host) } if devices[2].Port != 8091 { @@ -311,7 +311,7 @@ func TestParsePreferredDevices_EmptyString(t *testing.T) { func TestParsePreferredDevices_InvalidDevice(t *testing.T) { clearTestEnvVars() - _ = os.Setenv("PREFERRED_DEVICES", "192.168.1.100:invalid") + _ = os.Setenv("PREFERRED_DEVICES", "192.0.2.100:invalid") defer clearTestEnvVars() @@ -324,8 +324,8 @@ func TestParsePreferredDevices_InvalidDevice(t *testing.T) { func TestGetPreferredDevicesAsDiscovered(t *testing.T) { config := &Config{ PreferredDevices: []DeviceConfig{ - {Name: "Living Room", Host: "192.168.1.100", Port: 8090}, - {Name: "Kitchen", Host: "192.168.1.101", Port: 8091}, + {Name: "Living Room", Host: "192.0.2.100", Port: 8090}, + {Name: "Kitchen", Host: "192.0.2.101", Port: 8091}, }, } @@ -340,15 +340,15 @@ func TestGetPreferredDevicesAsDiscovered(t *testing.T) { t.Errorf("Expected name 'Living Room', got '%s'", devices[0].Name) } - if devices[0].Host != "192.168.1.100" { - t.Errorf("Expected host '192.168.1.100', got '%s'", devices[0].Host) + if devices[0].Host != "192.0.2.100" { + t.Errorf("Expected host '192.0.2.100', got '%s'", devices[0].Host) } if devices[0].Port != 8090 { t.Errorf("Expected port 8090, got %d", devices[0].Port) } - expectedInfoURL := "http://192.168.1.100:8090/info" + expectedInfoURL := "http://192.0.2.100:8090/info" if devices[0].InfoURL != expectedInfoURL { t.Errorf("Expected info URL '%s', got '%s'", expectedInfoURL, devices[0].InfoURL) } @@ -360,7 +360,7 @@ func TestValidate_ValidConfig(t *testing.T) { HTTPTimeout: 10 * time.Second, CacheTTL: 30 * time.Second, PreferredDevices: []DeviceConfig{ - {Name: "Test", Host: "192.168.1.100", Port: 8090}, + {Name: "Test", Host: "192.0.2.100", Port: 8090}, }, } @@ -414,7 +414,7 @@ func TestValidate_InvalidDevices(t *testing.T) { t.Error("Expected error for empty host, got nil") } - config.PreferredDevices[0].Host = "192.168.1.100" + config.PreferredDevices[0].Host = "192.0.2.100" config.PreferredDevices[0].Port = 0 // Invalid port err = config.Validate() diff --git a/pkg/discovery/dns_test.go b/pkg/discovery/dns_test.go index 579beaf..e625d4b 100644 --- a/pkg/discovery/dns_test.go +++ b/pkg/discovery/dns_test.go @@ -11,7 +11,7 @@ import ( ) func TestDNSDiscovery_Interception(t *testing.T) { - serviceIP := "192.168.1.100" + serviceIP := "192.0.2.100" upstreamDNS := []string{"8.8.8.8"} d := NewDNSDiscovery(upstreamDNS, serviceIP) @@ -65,7 +65,7 @@ func TestDNSDiscovery_Interception(t *testing.T) { func TestDNSDiscovery_Forwarding(t *testing.T) { // This test is harder because it needs a real upstream or a mock. // For now, let's just test that it calls forward and record. - serviceIP := "192.168.1.100" + serviceIP := "192.0.2.100" upstreamDNS := []string{"127.0.0.1:5353"} // Use a port that is likely closed or we can mock d := NewDNSDiscovery(upstreamDNS, serviceIP) @@ -106,7 +106,7 @@ func TestDNSDiscovery_Forwarding(t *testing.T) { } func TestDNSDiscovery_StartTCP(t *testing.T) { - serviceIP := "192.168.1.100" + serviceIP := "192.0.2.100" upstreamDNS := []string{"8.8.8.8"} d := NewDNSDiscovery(upstreamDNS, serviceIP) @@ -164,7 +164,7 @@ func TestDNSDiscovery_SelfForwarding(t *testing.T) { mux.HandleFunc("soundtouch.local.", func(w dns.ResponseWriter, r *dns.Msg) { m := new(dns.Msg) m.SetReply(r) - rr, _ := dns.NewRR("soundtouch.local. 60 IN A 192.168.178.10") + rr, _ := dns.NewRR("soundtouch.local. 60 IN A 192.0.2.10") m.Answer = append(m.Answer, rr) _ = w.WriteMsg(m) }) @@ -194,8 +194,8 @@ func TestDNSDiscovery_SelfForwarding(t *testing.T) { } if a, ok := rw.msg.Answer[0].(*dns.A); ok { - if a.A.String() != "192.168.178.10" { - t.Errorf("Expected IP 192.168.178.10, got %s", a.A.String()) + if a.A.String() != "192.0.2.10" { + t.Errorf("Expected IP 192.0.2.10, got %s", a.A.String()) } } @@ -214,7 +214,7 @@ func TestDNSDiscovery_SelfForwarding(t *testing.T) { } func TestDNSDiscovery_ForwardLocal(t *testing.T) { - serviceIP := "192.168.1.100" + serviceIP := "192.0.2.100" upstreamDNS := []string{"127.0.0.1:5356"} d := NewDNSDiscovery(upstreamDNS, serviceIP) @@ -227,7 +227,7 @@ func TestDNSDiscovery_ForwardLocal(t *testing.T) { mux.HandleFunc("someone-else.local.", func(w dns.ResponseWriter, r *dns.Msg) { m := new(dns.Msg) m.SetReply(r) - rr, _ := dns.NewRR("someone-else.local. 60 IN A 192.168.1.50") + rr, _ := dns.NewRR("someone-else.local. 60 IN A 192.0.2.50") m.Answer = append(m.Answer, rr) _ = w.WriteMsg(m) }) @@ -255,7 +255,7 @@ func TestDNSDiscovery_ForwardLocal(t *testing.T) { } func TestDNSDiscovery_IsRunning(t *testing.T) { - serviceIP := "192.168.1.100" + serviceIP := "192.0.2.100" upstreamDNS := []string{"8.8.8.8"} d := NewDNSDiscovery(upstreamDNS, serviceIP) @@ -301,7 +301,7 @@ func (m *mockResponseWriter) TsigTimersOnly(bool) {} func (m *mockResponseWriter) Hijack() {} func TestDNSDiscovery_LogThrottling(t *testing.T) { - d := NewDNSDiscovery([]string{"8.8.8.8"}, "192.168.1.100") + d := NewDNSDiscovery([]string{"8.8.8.8"}, "192.0.2.100") // Capture log output var logBuf strings.Builder @@ -332,7 +332,7 @@ func TestDNSDiscovery_LogThrottling(t *testing.T) { } func TestDNSDiscovery_LoopPrevention(t *testing.T) { - serviceIP := "192.168.1.100" + serviceIP := "192.0.2.100" bindAddr := "127.0.0.1:53" upstreamDNS := []string{"127.0.0.1:53"} d := NewDNSDiscovery(upstreamDNS, serviceIP) @@ -360,7 +360,7 @@ func TestDNSDiscovery_LoopPrevention(t *testing.T) { } func TestDNSDiscovery_EmptyUpstream(t *testing.T) { - serviceIP := "192.168.1.100" + serviceIP := "192.0.2.100" var upstreamDNS []string // Empty upstream d := NewDNSDiscovery(upstreamDNS, serviceIP) d.bindAddr = ":53" @@ -383,7 +383,7 @@ func TestDNSDiscovery_EmptyUpstream(t *testing.T) { } func TestDNSDiscovery_ForwardTimeout(t *testing.T) { - serviceIP := "192.168.1.100" + serviceIP := "192.0.2.100" // Mock server that deliberately delays its response mux := dns.NewServeMux() @@ -426,7 +426,7 @@ func TestDNSDiscovery_ForwardTimeout(t *testing.T) { } func TestDNSDiscovery_MultipleUpstreams(t *testing.T) { - serviceIP := "192.168.1.100" + serviceIP := "192.0.2.100" // Mock server 1: returns NXDOMAIN mux1 := dns.NewServeMux() diff --git a/pkg/discovery/example_test.go b/pkg/discovery/example_test.go index eea73a1..79daf94 100644 --- a/pkg/discovery/example_test.go +++ b/pkg/discovery/example_test.go @@ -29,8 +29,8 @@ func Example() { // Example output: // Found 2 devices: - // - Living Room at 192.168.1.100:8090 - // - Kitchen at 192.168.1.101:8090 + // - Living Room at 192.0.2.100:8090 + // - Kitchen at 192.0.2.101:8090 } // ExampleService_DiscoverDevices demonstrates discovering devices with timeout. @@ -61,16 +61,16 @@ func ExampleService_DiscoverDevices() { // Example output: // Device: Living Room - // Address: 192.168.1.100:8090 + // Address: 192.0.2.100:8090 // Serial: AA123456789 // Location: /device.xml - // Host: 192.168.1.100:8090 + // Host: 192.0.2.100:8090 // // Device: Kitchen - // Address: 192.168.1.101:8090 + // Address: 192.0.2.101:8090 // Serial: BB123456789 // Location: /device.xml - // Host: 192.168.1.101:8090 + // Host: 192.0.2.101:8090 } // ExampleUnifiedDiscoveryService_DiscoverDevices demonstrates caching functionality. @@ -130,7 +130,7 @@ func Example_upnpOnlyDiscovery() { // Example output: // UPnP discovered 1 devices: - // - Living Room at 192.168.1.100:8090 + // - Living Room at 192.0.2.100:8090 } // ExampleMDNSDiscoveryService_DiscoverDevices demonstrates mDNS-only discovery. @@ -152,7 +152,7 @@ func ExampleMDNSDiscoveryService_DiscoverDevices() { // Example output: // mDNS discovered 1 devices: - // - Kitchen at 192.168.1.101:8090 + // - Kitchen at 192.0.2.101:8090 } // Example_errorHandling demonstrates proper error handling in discovery. diff --git a/pkg/discovery/upnp_enrich_test.go b/pkg/discovery/upnp_enrich_test.go index 1c3c1b6..b09c957 100644 --- a/pkg/discovery/upnp_enrich_test.go +++ b/pkg/discovery/upnp_enrich_test.go @@ -18,7 +18,7 @@ func TestEnrichDeviceInfo(t *testing.T) { Sound Machinery SoundTouch 10 - A81B6A536A09 + AABBCCDDEE04 ` @@ -49,8 +49,8 @@ func TestEnrichDeviceInfo(t *testing.T) { t.Errorf("expected ModelID 'SoundTouch 10', got '%s'", device.ModelID) } - if device.UPnPSerial != "A81B6A536A09" { - t.Errorf("expected UPnPSerial 'A81B6A536A09', got '%s'", device.UPnPSerial) + if device.UPnPSerial != "AABBCCDDEE04" { + t.Errorf("expected UPnPSerial 'AABBCCDDEE04', got '%s'", device.UPnPSerial) } } @@ -60,7 +60,7 @@ func TestUPnP_Unmarshal(t *testing.T) { Sound Machinery SoundTouch 10 - A81B6A536A09 + AABBCCDDEE04 ` @@ -84,7 +84,7 @@ func TestUPnP_Unmarshal(t *testing.T) { if upnpRoot.Device.ModelName != "SoundTouch 10" { t.Errorf("expected ModelName 'SoundTouch 10', got '%s'", upnpRoot.Device.ModelName) } - if upnpRoot.Device.SerialNumber != "A81B6A536A09" { - t.Errorf("expected SerialNumber 'A81B6A536A09', got '%s'", upnpRoot.Device.SerialNumber) + if upnpRoot.Device.SerialNumber != "AABBCCDDEE04" { + t.Errorf("expected SerialNumber 'AABBCCDDEE04', got '%s'", upnpRoot.Device.SerialNumber) } } diff --git a/pkg/discovery/upnp_mac_test.go b/pkg/discovery/upnp_mac_test.go index aad7851..688615c 100644 --- a/pkg/discovery/upnp_mac_test.go +++ b/pkg/discovery/upnp_mac_test.go @@ -20,7 +20,7 @@ func TestUPnP_EnrichDeviceInfo_RealDeviceXML(t *testing.T) { urn:schemas-upnp-org:device:MediaRenderer:1 - Sound Machinechen + Living Room SoundTouch QPlay:2 Bose Corporation http://www.bose.com @@ -28,8 +28,8 @@ func TestUPnP_EnrichDeviceInfo_RealDeviceXML(t *testing.T) { Bose SoundTouch Wireless Streaming Audio Device http://www.bose.com - A81B6A536A98 - uuid:BO5EBO5E-F00D-F00D-FEED-A81B6A536A98 + AABBCCDDEEFF + uuid:BO5EBO5E-F00D-F00D-FEED-AABBCCDDEEFF urn:schemas-upnp-org:service:AVTransport:1 @@ -72,7 +72,7 @@ func TestUPnP_EnrichDeviceInfo_RealDeviceXML(t *testing.T) { // Create a discovered device to enrich device := &models.DiscoveredDevice{ - Host: "192.168.1.100", + Host: "192.0.2.100", Port: 8091, Name: "Initial Device Name", } @@ -86,13 +86,13 @@ func TestUPnP_EnrichDeviceInfo_RealDeviceXML(t *testing.T) { } // Verify that the MAC address was extracted correctly from serialNumber - expectedMAC := "A81B6A536A98" + expectedMAC := "AABBCCDDEEFF" if device.UPnPSerial != expectedMAC { t.Errorf("Expected UPnPSerial '%s', got '%s'", expectedMAC, device.UPnPSerial) } // Verify other enriched fields - expectedName := "Sound Machinechen" + expectedName := "Living Room SoundTouch" if device.Name != expectedName { t.Errorf("Expected Name '%s', got '%s'", expectedName, device.Name) } @@ -117,32 +117,32 @@ func TestUPnP_MACAddressDiscovery_Integration(t *testing.T) { }{ { name: "StandardMAC", - serialNumberInXML: "A81B6A536A98", - expectedUPnPSerial: "A81B6A536A98", + serialNumberInXML: "AABBCCDDEEFF", + expectedUPnPSerial: "AABBCCDDEEFF", description: "Standard MAC address format without separators", }, { name: "MACWithColons", - serialNumberInXML: "A8:1B:6A:53:6A:98", - expectedUPnPSerial: "A8:1B:6A:53:6A:98", + serialNumberInXML: "AA:BB:CC:DD:EE:FF", + expectedUPnPSerial: "AA:BB:CC:DD:EE:FF", description: "MAC address with colon separators", }, { name: "MACWithDashes", - serialNumberInXML: "A8-1B-6A-53-6A-98", - expectedUPnPSerial: "A8-1B-6A-53-6A-98", + serialNumberInXML: "AA-BB-CC-DD-EE-FF", + expectedUPnPSerial: "AA-BB-CC-DD-EE-FF", description: "MAC address with dash separators", }, { name: "LowercaseMAC", - serialNumberInXML: "a81b6a536a98", - expectedUPnPSerial: "a81b6a536a98", + serialNumberInXML: "aabbccddeeff", + expectedUPnPSerial: "aabbccddeeff", description: "Lowercase MAC address", }, { name: "MixedCaseMAC", - serialNumberInXML: "a81B6a536A98", - expectedUPnPSerial: "a81B6a536A98", + serialNumberInXML: "aaBBccddEEff", + expectedUPnPSerial: "aaBBccddEEff", description: "Mixed case MAC address", }, } @@ -173,7 +173,7 @@ func TestUPnP_MACAddressDiscovery_Integration(t *testing.T) { // Create and enrich device device := &models.DiscoveredDevice{ - Host: "192.168.1.100", + Host: "192.0.2.100", Port: 8090, } @@ -197,23 +197,23 @@ func TestUPnP_MACAddressDiscovery_Integration(t *testing.T) { func TestUPnP_URLPattern_Realistic(t *testing.T) { // Test the exact URL pattern mentioned: - // http://192.168.1.100:8091/XD/BO5EBO5E-F00D-F00D-FEED-A81B6A536A98.xml + // http://192.0.2.100:8091/XD/BO5EBO5E-F00D-F00D-FEED-AABBCCDDEEFF.xml realDeviceXML := ` urn:schemas-upnp-org:device:MediaRenderer:1 - Sound Machinechen + Living Room SoundTouch Bose Corporation SoundTouch 10 - A81B6A536A98 - uuid:BO5EBO5E-F00D-F00D-FEED-A81B6A536A98 + AABBCCDDEEFF + uuid:BO5EBO5E-F00D-F00D-FEED-AABBCCDDEEFF ` // Create server that responds to the specific path server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.URL.Path == "/XD/BO5EBO5E-F00D-F00D-FEED-A81B6A536A98.xml" { + if r.URL.Path == "/XD/BO5EBO5E-F00D-F00D-FEED-AABBCCDDEEFF.xml" { w.Header().Set("Content-Type", "text/xml") fmt.Fprint(w, realDeviceXML) } else { @@ -224,13 +224,13 @@ func TestUPnP_URLPattern_Realistic(t *testing.T) { // Test enrichment using the realistic URL path device := &models.DiscoveredDevice{ - Host: "192.168.1.100", + Host: "192.0.2.100", Port: 8091, Name: "Initial Name", } service := NewService(5 * time.Second) - locationURL := server.URL + "/XD/BO5EBO5E-F00D-F00D-FEED-A81B6A536A98.xml" + locationURL := server.URL + "/XD/BO5EBO5E-F00D-F00D-FEED-AABBCCDDEEFF.xml" err := service.EnrichDeviceInfo(device, locationURL) if err != nil { @@ -238,7 +238,7 @@ func TestUPnP_URLPattern_Realistic(t *testing.T) { } // Verify MAC address extraction - expectedMAC := "A81B6A536A98" + expectedMAC := "AABBCCDDEEFF" if device.UPnPSerial != expectedMAC { t.Errorf("Expected MAC '%s', got '%s'", expectedMAC, device.UPnPSerial) } @@ -254,7 +254,7 @@ func TestUPnP_URLPattern_Realistic(t *testing.T) { func TestUPnP_ErrorHandling(t *testing.T) { service := NewService(5 * time.Second) device := &models.DiscoveredDevice{ - Host: "192.168.1.100", + Host: "192.0.2.100", Name: "Test Device", } diff --git a/pkg/discovery/upnp_test.go b/pkg/discovery/upnp_test.go index 0c28088..724251b 100644 --- a/pkg/discovery/upnp_test.go +++ b/pkg/discovery/upnp_test.go @@ -85,15 +85,15 @@ func TestBuildMSearchRequest(t *testing.T) { func TestParseLocationURL_Valid(t *testing.T) { service := NewService(1 * time.Second) - location := "http://192.168.1.100:8090/device.xml" + location := "http://192.0.2.100:8090/device.xml" device, err := service.parseLocationURL(location, "") if err != nil { t.Fatalf("Expected no error, got: %v", err) } - if device.Host != "192.168.1.100" { - t.Errorf("Expected host '192.168.1.100', got '%s'", device.Host) + if device.Host != "192.0.2.100" { + t.Errorf("Expected host '192.0.2.100', got '%s'", device.Host) } if device.Port != 8090 { @@ -108,7 +108,7 @@ func TestParseLocationURL_Valid(t *testing.T) { t.Error("Expected device name to be set") } - expectedName := "SoundTouch-192.168.1.100" + expectedName := "SoundTouch-192.0.2.100" if device.Name != expectedName { t.Errorf("Expected name '%s', got '%s'", expectedName, device.Name) } @@ -119,7 +119,7 @@ func TestParseLocationURL_Invalid(t *testing.T) { invalidURLs := []string{ "not-a-url", - "ftp://192.168.1.100/device.xml", + "ftp://192.0.2.100/device.xml", "http://invalid-format", "", } @@ -179,7 +179,7 @@ func TestParseResponse_NotMediaRenderer(t *testing.T) { Cache-Control: max-age=1800 Date: Mon, 22 Jun 1998 09:55:21 GMT EXT: -Location: http://192.168.1.100:8090/device.xml +Location: http://192.0.2.100:8090/device.xml Server: Linux/3.14.0 UPnP/1.0 SomeDevice/1.0 ST: urn:schemas-upnp-org:device:SomeOtherDevice:1 USN: uuid:12345678-1234-5678-9012-123456789012::urn:schemas-upnp-org:device:SomeOtherDevice:1 @@ -260,13 +260,13 @@ func TestCacheOperations(t *testing.T) { // Add devices to cache testDevices := []*models.DiscoveredDevice{ { - Host: "192.168.1.100", + Host: "192.0.2.100", Port: 8090, Name: "Device 1", LastSeen: time.Now(), }, { - Host: "192.168.1.101", + Host: "192.0.2.101", Port: 8090, Name: "Device 2", LastSeen: time.Now(), @@ -296,7 +296,7 @@ func TestCacheExpiration(t *testing.T) { // Add device with old timestamp expiredDevice := &models.DiscoveredDevice{ - Host: "192.168.1.100", + Host: "192.0.2.100", Port: 8090, Name: "Expired Device", LastSeen: time.Now().Add(-200 * time.Millisecond), // Expired @@ -304,7 +304,7 @@ func TestCacheExpiration(t *testing.T) { // Add device with recent timestamp freshDevice := &models.DiscoveredDevice{ - Host: "192.168.1.101", + Host: "192.0.2.101", Port: 8090, Name: "Fresh Device", LastSeen: time.Now(), // Fresh @@ -321,7 +321,7 @@ func TestCacheExpiration(t *testing.T) { t.Errorf("Expected 1 non-expired device, got %d", len(devices)) } - if len(devices) > 0 && devices[0].Host != "192.168.1.101" { + if len(devices) > 0 && devices[0].Host != "192.0.2.101" { t.Errorf("Expected fresh device, got %s", devices[0].Host) } } @@ -331,7 +331,7 @@ func TestDiscoverDevices_UseCache(t *testing.T) { // Add fresh device to cache freshDevice := &models.DiscoveredDevice{ - Host: "192.168.1.100", + Host: "192.0.2.100", Port: 8090, Name: "Cached Device", LastSeen: time.Now(), @@ -352,7 +352,7 @@ func TestDiscoverDevices_UseCache(t *testing.T) { t.Errorf("Expected 1 cached device, got %d", len(devices)) } - if len(devices) > 0 && devices[0].Host != "192.168.1.100" { + if len(devices) > 0 && devices[0].Host != "192.0.2.100" { t.Errorf("Expected cached device host, got %s", devices[0].Host) } } @@ -362,7 +362,7 @@ func TestDiscoverDevice_FromCache(t *testing.T) { // Add device to cache device := &models.DiscoveredDevice{ - Host: "192.168.1.100", + Host: "192.0.2.100", Port: 8090, Name: "Test Device", LastSeen: time.Now(), @@ -374,13 +374,13 @@ func TestDiscoverDevice_FromCache(t *testing.T) { defer cancel() // Discover specific device from cache - foundDevice, err := service.DiscoverDevice(ctx, "192.168.1.100") + foundDevice, err := service.DiscoverDevice(ctx, "192.0.2.100") if err != nil { t.Fatalf("Expected no error, got: %v", err) } - if foundDevice.Host != "192.168.1.100" { - t.Errorf("Expected host '192.168.1.100', got '%s'", foundDevice.Host) + if foundDevice.Host != "192.0.2.100" { + t.Errorf("Expected host '192.0.2.100', got '%s'", foundDevice.Host) } if foundDevice.Name != "Test Device" { @@ -395,12 +395,12 @@ func TestDiscoverDevice_NotFound(t *testing.T) { defer cancel() // Try to discover non-existent device - _, err := service.DiscoverDevice(ctx, "192.168.1.999") + _, err := service.DiscoverDevice(ctx, "192.0.2.999") if err == nil { t.Error("Expected error for non-existent device, got nil") } - expectedError := "device with host 192.168.1.999 not found" + expectedError := "device with host 192.0.2.999 not found" if !contains(err.Error(), expectedError) { t.Errorf("Expected error to contain '%s', got '%s'", expectedError, err.Error()) } @@ -412,7 +412,7 @@ func TestNewDiscoveryServiceWithConfig(t *testing.T) { CacheTTL: 60 * time.Second, UPnPEnabled: false, PreferredDevices: []config.DeviceConfig{ - {Name: "Test Device", Host: "192.168.1.100", Port: 8090}, + {Name: "Test Device", Host: "192.0.2.100", Port: 8090}, }, } @@ -434,8 +434,8 @@ func TestNewDiscoveryServiceWithConfig(t *testing.T) { func TestGetConfiguredDevices(t *testing.T) { cfg := &config.Config{ PreferredDevices: []config.DeviceConfig{ - {Name: "Living Room", Host: "192.168.1.100", Port: 8090}, - {Name: "Kitchen", Host: "192.168.1.101", Port: 8091}, + {Name: "Living Room", Host: "192.0.2.100", Port: 8090}, + {Name: "Kitchen", Host: "192.0.2.101", Port: 8091}, }, } @@ -450,8 +450,8 @@ func TestGetConfiguredDevices(t *testing.T) { t.Errorf("Expected first device name 'Living Room', got '%s'", devices[0].Name) } - if devices[0].Host != "192.168.1.100" { - t.Errorf("Expected first device host '192.168.1.100', got '%s'", devices[0].Host) + if devices[0].Host != "192.0.2.100" { + t.Errorf("Expected first device host '192.0.2.100', got '%s'", devices[0].Host) } if devices[1].Port != 8091 { @@ -463,13 +463,13 @@ func TestMergeDevices(t *testing.T) { service := NewService(5 * time.Second) existing := []*models.DiscoveredDevice{ - {Host: "192.168.1.100", Name: "Device 1", Port: 8090}, - {Host: "192.168.1.101", Name: "Device 2", Port: 8090}, + {Host: "192.0.2.100", Name: "Device 1", Port: 8090}, + {Host: "192.0.2.101", Name: "Device 2", Port: 8090}, } newDevices := []*models.DiscoveredDevice{ - {Host: "192.168.1.101", Name: "Duplicate", Port: 8090}, // Duplicate - {Host: "192.168.1.102", Name: "Device 3", Port: 8090}, // New + {Host: "192.0.2.101", Name: "Duplicate", Port: 8090}, // Duplicate + {Host: "192.0.2.102", Name: "Device 3", Port: 8090}, // New } merged := service.mergeDevices(existing, newDevices) @@ -491,7 +491,7 @@ func TestMergeDevices(t *testing.T) { } // Check that all unique hosts are present - expectedHosts := []string{"192.168.1.100", "192.168.1.101", "192.168.1.102"} + expectedHosts := []string{"192.0.2.100", "192.0.2.101", "192.0.2.102"} for _, expectedHost := range expectedHosts { if _, exists := hosts[expectedHost]; !exists { t.Errorf("Expected host %s not found in merged devices", expectedHost) @@ -503,7 +503,7 @@ func TestDiscoverDevices_ConfiguredOnly(t *testing.T) { cfg := &config.Config{ UPnPEnabled: false, // Disable UPnP PreferredDevices: []config.DeviceConfig{ - {Name: "Test Device", Host: "192.168.1.100", Port: 8090}, + {Name: "Test Device", Host: "192.0.2.100", Port: 8090}, }, } @@ -523,8 +523,8 @@ func TestDiscoverDevices_ConfiguredOnly(t *testing.T) { t.Errorf("Expected device name 'Test Device', got '%s'", devices[0].Name) } - if devices[0].Host != "192.168.1.100" { - t.Errorf("Expected device host '192.168.1.100', got '%s'", devices[0].Host) + if devices[0].Host != "192.0.2.100" { + t.Errorf("Expected device host '192.0.2.100', got '%s'", devices[0].Host) } } diff --git a/pkg/models/clockdisplay_test.go b/pkg/models/clockdisplay_test.go index d9ea0a2..9be1f26 100644 --- a/pkg/models/clockdisplay_test.go +++ b/pkg/models/clockdisplay_test.go @@ -13,9 +13,9 @@ func TestClockDisplay_UnmarshalXML(t *testing.T) { }{ { name: "Full clock display configuration", - xmlData: `Clock Display`, + xmlData: `Clock Display`, expected: ClockDisplay{ - DeviceID: "A81B6A536A98", + DeviceID: "AABBCCDDEEFF", Enabled: true, Format: "24", Brightness: 75, @@ -677,15 +677,15 @@ func TestClockDisplayRequest_MarshalXML_TimezoneOnly(t *testing.T) { func TestClockDisplay_UnmarshalXML_NestedClockConfig(t *testing.T) { // The real wire format — what firmware-27 devices emit and accept. - xmlData := `` + xmlData := `` var got ClockDisplay if err := xml.Unmarshal([]byte(xmlData), &got); err != nil { t.Fatalf("Failed to unmarshal: %v", err) } - if got.DeviceID != "A81B6A536A98" { - t.Errorf("DeviceID = %q, want A81B6A536A98", got.DeviceID) + if got.DeviceID != "AABBCCDDEEFF" { + t.Errorf("DeviceID = %q, want AABBCCDDEEFF", got.DeviceID) } if got.TimeZone != "Europe/Berlin" { diff --git a/pkg/models/device_info_test.go b/pkg/models/device_info_test.go index 298388f..debbf6e 100644 --- a/pkg/models/device_info_test.go +++ b/pkg/models/device_info_test.go @@ -7,7 +7,7 @@ import ( ) func TestName_UnmarshalXML(t *testing.T) { - xmlData := `Sound Machinechen` + xmlData := `Living Room SoundTouch` var name Name @@ -16,16 +16,16 @@ func TestName_UnmarshalXML(t *testing.T) { t.Fatalf("Failed to unmarshal XML: %v", err) } - if name.Value != "Sound Machinechen" { - t.Errorf("Expected name 'Sound Machinechen', got '%s'", name.Value) + if name.Value != "Living Room SoundTouch" { + t.Errorf("Expected name 'Living Room SoundTouch', got '%s'", name.Value) } - if name.GetName() != "Sound Machinechen" { - t.Errorf("Expected GetName() 'Sound Machinechen', got '%s'", name.GetName()) + if name.GetName() != "Living Room SoundTouch" { + t.Errorf("Expected GetName() 'Living Room SoundTouch', got '%s'", name.GetName()) } - if name.String() != "Sound Machinechen" { - t.Errorf("Expected String() 'Sound Machinechen', got '%s'", name.String()) + if name.String() != "Living Room SoundTouch" { + t.Errorf("Expected String() 'Living Room SoundTouch', got '%s'", name.String()) } if name.IsEmpty() { @@ -54,7 +54,7 @@ func TestName_EmptyName(t *testing.T) { func TestCapabilities_UnmarshalXML(t *testing.T) { xmlData := ` - + true true @@ -82,8 +82,8 @@ func TestCapabilities_UnmarshalXML(t *testing.T) { } // Test basic fields - if capabilities.DeviceID != "A81B6A536A98" { - t.Errorf("Expected DeviceID 'A81B6A536A98', got '%s'", capabilities.DeviceID) + if capabilities.DeviceID != "AABBCCDDEEFF" { + t.Errorf("Expected DeviceID 'AABBCCDDEEFF', got '%s'", capabilities.DeviceID) } // Test boolean capabilities diff --git a/pkg/models/networkinfo_test.go b/pkg/models/networkinfo_test.go index e7179ba..faff6de 100644 --- a/pkg/models/networkinfo_test.go +++ b/pkg/models/networkinfo_test.go @@ -15,7 +15,7 @@ func TestNetworkInformation_UnmarshalXML(t *testing.T) { name: "WiFi device with connected and disconnected interfaces", xmlData: ` - + `, @@ -27,7 +27,7 @@ func TestNetworkInformation_UnmarshalXML(t *testing.T) { Type: "WIFI_INTERFACE", Name: "wlan0", MacAddress: "AA:BB:CC:DD:EE:FF", - IPAddress: "192.168.1.10", + IPAddress: "192.0.2.10", SSID: "MyHomeNetwork", FrequencyKHz: 5500000, State: "NETWORK_WIFI_CONNECTED", @@ -48,7 +48,7 @@ func TestNetworkInformation_UnmarshalXML(t *testing.T) { name: "Ethernet device", xmlData: ` - + `, expected: NetworkInformation{ @@ -59,7 +59,7 @@ func TestNetworkInformation_UnmarshalXML(t *testing.T) { Type: "ETHERNET_INTERFACE", Name: "eth0", MacAddress: "AA:BB:CC:DD:EE:FF", - IPAddress: "192.168.1.10", + IPAddress: "192.0.2.10", State: "NETWORK_ETHERNET_CONNECTED", }, }, @@ -83,7 +83,7 @@ func TestNetworkInformation_UnmarshalXML(t *testing.T) { name: "Multiple WiFi interfaces with different signals", xmlData: ` - + `, @@ -95,7 +95,7 @@ func TestNetworkInformation_UnmarshalXML(t *testing.T) { Type: "WIFI_INTERFACE", Name: "wlan0", MacAddress: "AA:BB:CC:DD:EE:FF", - IPAddress: "192.168.1.10", + IPAddress: "192.0.2.10", SSID: "StrongNetwork", FrequencyKHz: 2400000, State: "NETWORK_WIFI_CONNECTED", @@ -594,7 +594,7 @@ func TestNetworkInterface_ValidateAddresses(t *testing.T) { { name: "Valid IPv4 and MAC", iface: NetworkInterface{ - IPAddress: "192.168.1.10", + IPAddress: "192.0.2.10", MacAddress: "AA:BB:CC:DD:EE:FF", }, validIP: true, @@ -650,7 +650,7 @@ func TestNetworkInformation_GetConnectedInterfaces(t *testing.T) { Type: InterfaceTypeWiFi, State: StateWiFiConnected, SSID: "WiFiNetwork", - IPAddress: "192.168.1.10", + IPAddress: "192.0.2.10", MacAddress: "AA:BB:CC:DD:EE:FF", }, { @@ -661,7 +661,7 @@ func TestNetworkInformation_GetConnectedInterfaces(t *testing.T) { { Type: InterfaceTypeEthernet, State: StateEthernetConnected, - IPAddress: "192.168.1.11", + IPAddress: "192.0.2.11", MacAddress: "11:22:33:44:55:66", }, }, @@ -680,8 +680,8 @@ func TestNetworkInformation_GetConnectedInterfaces(t *testing.T) { ethIface := networkInfo.GetConnectedEthernetInterface() if ethIface == nil { t.Error("Expected to find connected Ethernet interface") - } else if ethIface.IPAddress != "192.168.1.11" { - t.Errorf("Expected Ethernet IP '192.168.1.11', got %q", ethIface.IPAddress) + } else if ethIface.IPAddress != "192.0.2.11" { + t.Errorf("Expected Ethernet IP '192.0.2.11', got %q", ethIface.IPAddress) } // Test with no connected interfaces diff --git a/pkg/models/nowplaying_test.go b/pkg/models/nowplaying_test.go index 25f077f..d6a2593 100644 --- a/pkg/models/nowplaying_test.go +++ b/pkg/models/nowplaying_test.go @@ -182,7 +182,7 @@ func TestRepeatSetting_UnmarshalXML(t *testing.T) { func TestNowPlaying_UnmarshalXML(t *testing.T) { xmlData := ` - + SYML https://i.scdn.co/image/ab67616d0000b273ca6f00df62ef197fdc8af79c @@ -211,8 +211,8 @@ func TestNowPlaying_UnmarshalXML(t *testing.T) { } // Test basic fields - if nowPlaying.DeviceID != "A81B6A536A98" { - t.Errorf("Expected DeviceID 'A81B6A536A98', got '%s'", nowPlaying.DeviceID) + if nowPlaying.DeviceID != "AABBCCDDEEFF" { + t.Errorf("Expected DeviceID 'AABBCCDDEEFF', got '%s'", nowPlaying.DeviceID) } if nowPlaying.Source != "SPOTIFY" { @@ -309,7 +309,7 @@ func TestNowPlaying_UnmarshalXML(t *testing.T) { func TestNowPlaying_RadioStation(t *testing.T) { xmlData := ` - + Classic Rock 101.5 The Best Classic Rock Hits New York, NY @@ -343,7 +343,7 @@ func TestNowPlaying_RadioStation(t *testing.T) { func TestNowPlaying_EmptyState(t *testing.T) { xmlData := ` - + STOP_STATE ` diff --git a/pkg/models/sources_test.go b/pkg/models/sources_test.go index 0b98165..45f0853 100644 --- a/pkg/models/sources_test.go +++ b/pkg/models/sources_test.go @@ -201,7 +201,7 @@ func TestSourceItem_Methods(t *testing.T) { func TestSources_UnmarshalXML(t *testing.T) { xmlData := ` - + AUX IN user+spotify@example.com @@ -216,8 +216,8 @@ func TestSources_UnmarshalXML(t *testing.T) { } // Test basic fields - if sources.DeviceID != "A81B6A536A98" { - t.Errorf("Expected DeviceID 'A81B6A536A98', got '%s'", sources.DeviceID) + if sources.DeviceID != "AABBCCDDEEFF" { + t.Errorf("Expected DeviceID 'AABBCCDDEEFF', got '%s'", sources.DeviceID) } if len(sources.SourceItem) != 4 { diff --git a/pkg/models/websocket_test.go b/pkg/models/websocket_test.go index 5678366..8535880 100644 --- a/pkg/models/websocket_test.go +++ b/pkg/models/websocket_test.go @@ -202,12 +202,12 @@ func TestParseWebSocketEvent(t *testing.T) { 9070658C9D4A LEFT - 192.168.1.131 + 192.0.2.131 F45EAB3115DA RIGHT - 192.168.1.134 + 192.0.2.134 GROUP_OK diff --git a/pkg/models/zone_slave_test.go b/pkg/models/zone_slave_test.go index 2b13b2d..e9b464c 100644 --- a/pkg/models/zone_slave_test.go +++ b/pkg/models/zone_slave_test.go @@ -22,7 +22,7 @@ func TestZoneSlaveRequest_Creation(t *testing.T) { t.Run("AddSlave", func(t *testing.T) { request := NewZoneSlaveRequest("MASTER123") - request.AddSlave("SLAVE456", "192.168.1.101") + request.AddSlave("SLAVE456", "192.0.2.101") if len(request.Members) != 1 { t.Errorf("Expected 1 member, got %d", len(request.Members)) @@ -34,8 +34,8 @@ func TestZoneSlaveRequest_Creation(t *testing.T) { t.Errorf("Expected device ID 'SLAVE456', got '%s'", member.DeviceID) } - if member.IP != "192.168.1.101" { - t.Errorf("Expected IP '192.168.1.101', got '%s'", member.IP) + if member.IP != "192.0.2.101" { + t.Errorf("Expected IP '192.0.2.101', got '%s'", member.IP) } }) } @@ -52,7 +52,7 @@ func TestZoneSlaveRequest_Validation(t *testing.T) { name: "valid request with IP", masterID: "MASTER123", members: []ZoneSlaveEntry{ - {DeviceID: "SLAVE456", IP: "192.168.1.101"}, + {DeviceID: "SLAVE456", IP: "192.0.2.101"}, }, expectError: false, }, @@ -67,7 +67,7 @@ func TestZoneSlaveRequest_Validation(t *testing.T) { { name: "empty master ID", masterID: "", - members: []ZoneSlaveEntry{{DeviceID: "SLAVE456", IP: "192.168.1.101"}}, + members: []ZoneSlaveEntry{{DeviceID: "SLAVE456", IP: "192.0.2.101"}}, expectError: true, errorMsg: "master device ID is required", }, @@ -82,8 +82,8 @@ func TestZoneSlaveRequest_Validation(t *testing.T) { name: "multiple members", masterID: "MASTER123", members: []ZoneSlaveEntry{ - {DeviceID: "SLAVE456", IP: "192.168.1.101"}, - {DeviceID: "SLAVE789", IP: "192.168.1.102"}, + {DeviceID: "SLAVE456", IP: "192.0.2.101"}, + {DeviceID: "SLAVE789", IP: "192.0.2.102"}, }, expectError: true, errorMsg: "zone slave operations require exactly one member", @@ -91,14 +91,14 @@ func TestZoneSlaveRequest_Validation(t *testing.T) { { name: "empty slave device ID", masterID: "MASTER123", - members: []ZoneSlaveEntry{{DeviceID: "", IP: "192.168.1.101"}}, + members: []ZoneSlaveEntry{{DeviceID: "", IP: "192.0.2.101"}}, expectError: true, errorMsg: "slave device ID cannot be empty", }, { name: "same master and slave ID", masterID: "MASTER123", - members: []ZoneSlaveEntry{{DeviceID: "MASTER123", IP: "192.168.1.101"}}, + members: []ZoneSlaveEntry{{DeviceID: "MASTER123", IP: "192.0.2.101"}}, expectError: true, errorMsg: "slave device ID cannot be the same as master", }, @@ -148,7 +148,7 @@ func TestZoneSlaveRequest_Validation(t *testing.T) { func TestZoneSlaveRequest_HelperMethods(t *testing.T) { t.Run("GetSlaveDeviceID with member", func(t *testing.T) { request := NewZoneSlaveRequest("MASTER123") - request.AddSlave("SLAVE456", "192.168.1.101") + request.AddSlave("SLAVE456", "192.0.2.101") deviceID := request.GetSlaveDeviceID() @@ -169,11 +169,11 @@ func TestZoneSlaveRequest_HelperMethods(t *testing.T) { t.Run("GetSlaveIP with member", func(t *testing.T) { request := NewZoneSlaveRequest("MASTER123") - request.AddSlave("SLAVE456", "192.168.1.101") + request.AddSlave("SLAVE456", "192.0.2.101") ip := request.GetSlaveIP() - expected := "192.168.1.101" + expected := "192.0.2.101" if ip != expected { t.Errorf("Expected IP '%s', got '%s'", expected, ip) } @@ -209,11 +209,11 @@ func TestZoneSlaveRequest_String(t *testing.T) { name: "with IP address", setup: func() *ZoneSlaveRequest { req := NewZoneSlaveRequest("MASTER123") - req.AddSlave("SLAVE456", "192.168.1.101") + req.AddSlave("SLAVE456", "192.0.2.101") return req }, - expected: "Zone slave operation: master=MASTER123, slave=SLAVE456 (192.168.1.101)", + expected: "Zone slave operation: master=MASTER123, slave=SLAVE456 (192.0.2.101)", }, { name: "without IP address", @@ -249,7 +249,7 @@ func TestZoneSlaveRequest_String(t *testing.T) { func TestZoneSlaveRequest_XMLMarshaling(t *testing.T) { t.Run("marshal with IP", func(t *testing.T) { request := NewZoneSlaveRequest("MASTER123") - request.AddSlave("SLAVE456", "192.168.1.101") + request.AddSlave("SLAVE456", "192.0.2.101") xmlData, err := xml.Marshal(request) if err != nil { @@ -263,7 +263,7 @@ func TestZoneSlaveRequest_XMLMarshaling(t *testing.T) { t.Error("Expected XML to contain zone element with master attribute") } - if !strings.Contains(xmlStr, `SLAVE456`) { + if !strings.Contains(xmlStr, `SLAVE456`) { t.Error("Expected XML to contain member with IP address") } }) @@ -304,11 +304,11 @@ func TestZoneSlaveRequest_XMLUnmarshaling(t *testing.T) { }{ { name: "valid XML with IP", - xmlData: `SLAVE456`, + xmlData: `SLAVE456`, expectedReq: &ZoneSlaveRequest{ Master: "MASTER123", Members: []ZoneSlaveEntry{ - {DeviceID: "SLAVE456", IP: "192.168.1.101"}, + {DeviceID: "SLAVE456", IP: "192.0.2.101"}, }, }, expectError: false, @@ -378,7 +378,7 @@ func TestZoneSlaveEntry_XMLMarshaling(t *testing.T) { t.Run("entry with IP", func(t *testing.T) { entry := ZoneSlaveEntry{ DeviceID: "SLAVE456", - IP: "192.168.1.101", + IP: "192.0.2.101", } xmlData, err := xml.Marshal(entry) @@ -388,7 +388,7 @@ func TestZoneSlaveEntry_XMLMarshaling(t *testing.T) { xmlStr := string(xmlData) - expected := `SLAVE456` + expected := `SLAVE456` if xmlStr != expected { t.Errorf("Expected XML '%s', got '%s'", expected, xmlStr) } @@ -417,8 +417,8 @@ func TestZoneSlaveEntry_XMLMarshaling(t *testing.T) { func TestZoneSlaveRequest_EdgeCases(t *testing.T) { t.Run("multiple AddSlave calls", func(t *testing.T) { request := NewZoneSlaveRequest("MASTER123") - request.AddSlave("SLAVE456", "192.168.1.101") - request.AddSlave("SLAVE789", "192.168.1.102") + request.AddSlave("SLAVE456", "192.0.2.101") + request.AddSlave("SLAVE789", "192.0.2.102") if len(request.Members) != 2 { t.Errorf("Expected 2 members, got %d", len(request.Members)) diff --git a/pkg/models/zone_test.go b/pkg/models/zone_test.go index fec3c05..cab17a5 100644 --- a/pkg/models/zone_test.go +++ b/pkg/models/zone_test.go @@ -22,8 +22,8 @@ func TestNewZoneRequest(t *testing.T) { func TestZoneRequest_AddMember(t *testing.T) { zr := NewZoneRequest("MASTER123") - zr.AddMember("DEVICE456", "192.168.1.10") - zr.AddMember("DEVICE789", "192.168.1.11") + zr.AddMember("DEVICE456", "192.0.2.10") + zr.AddMember("DEVICE789", "192.0.2.11") if len(zr.Members) != 2 { t.Errorf("Expected 2 members, got %d", len(zr.Members)) @@ -33,8 +33,8 @@ func TestZoneRequest_AddMember(t *testing.T) { t.Errorf("Expected first member DEVICE456, got %s", zr.Members[0].DeviceID) } - if zr.Members[0].IP != "192.168.1.10" { - t.Errorf("Expected first member IP 192.168.1.10, got %s", zr.Members[0].IP) + if zr.Members[0].IP != "192.0.2.10" { + t.Errorf("Expected first member IP 192.0.2.10, got %s", zr.Members[0].IP) } } @@ -58,9 +58,9 @@ func TestZoneRequest_AddMemberByDeviceID(t *testing.T) { func TestZoneRequest_RemoveMember(t *testing.T) { zr := NewZoneRequest("MASTER123") - zr.AddMember("DEVICE456", "192.168.1.10") - zr.AddMember("DEVICE789", "192.168.1.11") - zr.AddMember("DEVICEABC", "192.168.1.12") + zr.AddMember("DEVICE456", "192.0.2.10") + zr.AddMember("DEVICE789", "192.0.2.11") + zr.AddMember("DEVICEABC", "192.0.2.12") // Remove middle member zr.RemoveMember("DEVICE789") @@ -86,8 +86,8 @@ func TestZoneRequest_RemoveMember(t *testing.T) { func TestZoneRequest_ClearMembers(t *testing.T) { zr := NewZoneRequest("MASTER123") - zr.AddMember("DEVICE456", "192.168.1.10") - zr.AddMember("DEVICE789", "192.168.1.11") + zr.AddMember("DEVICE456", "192.0.2.10") + zr.AddMember("DEVICE789", "192.0.2.11") zr.ClearMembers() @@ -98,7 +98,7 @@ func TestZoneRequest_ClearMembers(t *testing.T) { func TestZoneRequest_HasMember(t *testing.T) { zr := NewZoneRequest("MASTER123") - zr.AddMember("DEVICE456", "192.168.1.10") + zr.AddMember("DEVICE456", "192.0.2.10") if !zr.HasMember("DEVICE456") { t.Error("Expected HasMember to return true for DEVICE456") @@ -120,13 +120,13 @@ func TestZoneRequest_GetMemberCount(t *testing.T) { t.Errorf("Expected 0 members initially, got %d", zr.GetMemberCount()) } - zr.AddMember("DEVICE456", "192.168.1.10") + zr.AddMember("DEVICE456", "192.0.2.10") if zr.GetMemberCount() != 1 { t.Errorf("Expected 1 member, got %d", zr.GetMemberCount()) } - zr.AddMember("DEVICE789", "192.168.1.11") + zr.AddMember("DEVICE789", "192.0.2.11") if zr.GetMemberCount() != 2 { t.Errorf("Expected 2 members, got %d", zr.GetMemberCount()) @@ -144,7 +144,7 @@ func TestZoneRequest_Validate(t *testing.T) { name: "Valid zone request", setupFunc: func() *ZoneRequest { zr := NewZoneRequest("MASTER123") - zr.AddMember("DEVICE456", "192.168.1.10") + zr.AddMember("DEVICE456", "192.0.2.10") return zr }, @@ -184,8 +184,8 @@ func TestZoneRequest_Validate(t *testing.T) { name: "Duplicate member device ID", setupFunc: func() *ZoneRequest { zr := NewZoneRequest("MASTER123") - zr.AddMember("DEVICE456", "192.168.1.10") - zr.AddMember("DEVICE456", "192.168.1.11") + zr.AddMember("DEVICE456", "192.0.2.10") + zr.AddMember("DEVICE456", "192.0.2.11") return zr }, @@ -196,7 +196,7 @@ func TestZoneRequest_Validate(t *testing.T) { name: "Master device ID as member", setupFunc: func() *ZoneRequest { zr := NewZoneRequest("MASTER123") - zr.AddMember("MASTER123", "192.168.1.10") + zr.AddMember("MASTER123", "192.0.2.10") return zr }, @@ -320,8 +320,8 @@ func TestZoneInfo_GetMemberByDeviceID(t *testing.T) { zi := &ZoneInfo{ Master: "MASTER123", Members: []Member{ - {DeviceID: "DEVICE456", IP: "192.168.1.10"}, - {DeviceID: "DEVICE789", IP: "192.168.1.11"}, + {DeviceID: "DEVICE456", IP: "192.0.2.10"}, + {DeviceID: "DEVICE789", IP: "192.0.2.11"}, }, } @@ -330,8 +330,8 @@ func TestZoneInfo_GetMemberByDeviceID(t *testing.T) { t.Error("Expected to find member DEVICE456") } - if member.IP != "192.168.1.10" { - t.Errorf("Expected IP 192.168.1.10, got %s", member.IP) + if member.IP != "192.0.2.10" { + t.Errorf("Expected IP 192.0.2.10, got %s", member.IP) } _, found = zi.GetMemberByDeviceID("NONEXISTENT") @@ -344,21 +344,21 @@ func TestZoneInfo_GetMemberByIP(t *testing.T) { zi := &ZoneInfo{ Master: "MASTER123", Members: []Member{ - {DeviceID: "DEVICE456", IP: "192.168.1.10"}, - {DeviceID: "DEVICE789", IP: "192.168.1.11"}, + {DeviceID: "DEVICE456", IP: "192.0.2.10"}, + {DeviceID: "DEVICE789", IP: "192.0.2.11"}, }, } - member, found := zi.GetMemberByIP("192.168.1.10") + member, found := zi.GetMemberByIP("192.0.2.10") if !found { - t.Error("Expected to find member by IP 192.168.1.10") + t.Error("Expected to find member by IP 192.0.2.10") } if member.DeviceID != "DEVICE456" { t.Errorf("Expected device ID DEVICE456, got %s", member.DeviceID) } - _, found = zi.GetMemberByIP("192.168.1.99") + _, found = zi.GetMemberByIP("192.0.2.99") if found { t.Error("Expected not to find member with non-existent IP") } @@ -496,8 +496,8 @@ func TestZoneInfo_ToZoneRequest(t *testing.T) { zi := &ZoneInfo{ Master: "MASTER123", Members: []Member{ - {DeviceID: "DEVICE456", IP: "192.168.1.10"}, - {DeviceID: "DEVICE789", IP: "192.168.1.11"}, + {DeviceID: "DEVICE456", IP: "192.0.2.10"}, + {DeviceID: "DEVICE789", IP: "192.0.2.11"}, }, } @@ -526,7 +526,7 @@ func TestZoneBuilder(t *testing.T) { zb := NewZoneBuilder("MASTER123") zr, err := zb. - WithMember("DEVICE456", "192.168.1.10"). + WithMember("DEVICE456", "192.0.2.10"). WithMemberByDeviceID("DEVICE789"). Build() if err != nil { @@ -545,8 +545,8 @@ func TestZoneBuilder(t *testing.T) { t.Errorf("Expected first member DEVICE456, got %s", zr.Members[0].DeviceID) } - if zr.Members[0].IP != "192.168.1.10" { - t.Errorf("Expected first member IP 192.168.1.10, got %s", zr.Members[0].IP) + if zr.Members[0].IP != "192.0.2.10" { + t.Errorf("Expected first member IP 192.0.2.10, got %s", zr.Members[0].IP) } if zr.Members[1].DeviceID != "DEVICE789" { @@ -672,8 +672,8 @@ func TestZoneCapabilities(t *testing.T) { func TestZoneXMLMarshaling(t *testing.T) { t.Run("ZoneInfo XML Unmarshaling", func(t *testing.T) { xmlData := ` - DEVICE456 - DEVICE789 + DEVICE456 + DEVICE789 ` var zi ZoneInfo @@ -695,15 +695,15 @@ func TestZoneXMLMarshaling(t *testing.T) { t.Errorf("Expected first member DEVICE456, got %s", zi.Members[0].DeviceID) } - if zi.Members[0].IP != "192.168.1.10" { - t.Errorf("Expected first member IP 192.168.1.10, got %s", zi.Members[0].IP) + if zi.Members[0].IP != "192.0.2.10" { + t.Errorf("Expected first member IP 192.0.2.10, got %s", zi.Members[0].IP) } }) t.Run("ZoneRequest XML Marshaling", func(t *testing.T) { zr := NewZoneRequest("MASTER123") - zr.AddMember("DEVICE456", "192.168.1.10") - zr.AddMember("DEVICE789", "192.168.1.11") + zr.AddMember("DEVICE456", "192.0.2.10") + zr.AddMember("DEVICE789", "192.0.2.11") data, err := xml.MarshalIndent(zr, "", " ") if err != nil { @@ -711,8 +711,8 @@ func TestZoneXMLMarshaling(t *testing.T) { } expected := ` - DEVICE456 - DEVICE789 + DEVICE456 + DEVICE789 ` if string(data) != expected { @@ -768,7 +768,7 @@ func TestZoneEdgeCases(t *testing.T) { for i := 1; i <= 10; i++ { deviceID := fmt.Sprintf("DEVICE%03d", i) - ip := fmt.Sprintf("192.168.1.%d", i+10) + ip := fmt.Sprintf("192.0.2.%d", i+10) zr.AddMember(deviceID, ip) } @@ -833,7 +833,7 @@ func BenchmarkZoneRequest_Validate(b *testing.B) { for i := 0; i < 5; i++ { deviceID := fmt.Sprintf("DEVICE%d", i) - ip := fmt.Sprintf("192.168.1.%d", i+10) + ip := fmt.Sprintf("192.0.2.%d", i+10) zr.AddMember(deviceID, ip) } diff --git a/pkg/service/certmanager/certmanager_test.go b/pkg/service/certmanager/certmanager_test.go index 7c282b0..1b01ecb 100644 --- a/pkg/service/certmanager/certmanager_test.go +++ b/pkg/service/certmanager/certmanager_test.go @@ -138,7 +138,7 @@ func TestCertificateManagerIPAddress(t *testing.T) { cm := NewCertificateManager(filepath.Join(tempDir, "certs")) // Test certificate generation with an IP address - domains := []string{"192.168.1.100", "localhost"} + domains := []string{"192.0.2.100", "localhost"} certPEM, _, err := cm.GenerateCertificate(domains) if err != nil { t.Fatalf("Failed to generate certificate: %v", err) @@ -154,20 +154,20 @@ func TestCertificateManagerIPAddress(t *testing.T) { // Check IP addresses foundIP := false for _, ip := range cert.IPAddresses { - if ip.String() == "192.168.1.100" { + if ip.String() == "192.0.2.100" { foundIP = true break } } if !foundIP { - t.Errorf("Expected IP address 192.168.1.100 in IPAddresses, but it was not found") + t.Errorf("Expected IP address 192.0.2.100 in IPAddresses, but it was not found") } // Check if it was mistakenly added to DNSNames for _, dns := range cert.DNSNames { - if dns == "192.168.1.100" { - t.Errorf("IP address 192.168.1.100 should NOT be in DNSNames") + if dns == "192.0.2.100" { + t.Errorf("IP address 192.0.2.100 should NOT be in DNSNames") } } } diff --git a/pkg/service/datastore/case_sensitivity_test.go b/pkg/service/datastore/case_sensitivity_test.go index 89d7531..db0bf7b 100644 --- a/pkg/service/datastore/case_sensitivity_test.go +++ b/pkg/service/datastore/case_sensitivity_test.go @@ -17,7 +17,7 @@ func TestMacAddressCaseSensitivity(t *testing.T) { } defer os.RemoveAll(tmpDir) - accountID := "3230304" + accountID := "1000001" serialNumber := "I6332527703739342000020" // Test scenarios that could occur in production @@ -30,43 +30,43 @@ func TestMacAddressCaseSensitivity(t *testing.T) { }{ { name: "ExactMatch", - macInDeviceInfo: "A81B6A536A98", - macInRequest: "A81B6A536A98", + macInDeviceInfo: "AABBCCDDEEFF", + macInRequest: "AABBCCDDEEFF", expectedToWork: true, description: "Exact case match should work", }, { name: "DeviceInfoUpperRequestLower", - macInDeviceInfo: "A81B6A536A98", - macInRequest: "a81b6a536a98", + macInDeviceInfo: "AABBCCDDEEFF", + macInRequest: "aabbccddeeff", expectedToWork: true, description: "DeviceInfo has uppercase, request has lowercase (should work with normalization)", }, { name: "DeviceInfoLowerRequestUpper", - macInDeviceInfo: "a81b6a536a98", - macInRequest: "A81B6A536A98", + macInDeviceInfo: "aabbccddeeff", + macInRequest: "AABBCCDDEEFF", expectedToWork: true, description: "DeviceInfo has lowercase, request has uppercase (should work with normalization)", }, { name: "MixedCaseInDeviceInfo", - macInDeviceInfo: "a81B6a536A98", - macInRequest: "A81B6A536A98", + macInDeviceInfo: "aaBBccddEEff", + macInRequest: "AABBCCDDEEFF", expectedToWork: true, description: "Mixed case in DeviceInfo vs uppercase request (should work with normalization)", }, { name: "WithColonsInDeviceInfo", - macInDeviceInfo: "A8:1B:6A:53:6A:98", - macInRequest: "A81B6A536A98", + macInDeviceInfo: "AA:BB:CC:DD:EE:FF", + macInRequest: "AABBCCDDEEFF", expectedToWork: true, description: "DeviceInfo has colons, request without (should work with normalization)", }, { name: "WithDashesInDeviceInfo", - macInDeviceInfo: "A8-1B-6A-53-6A-98", - macInRequest: "A81B6A536A98", + macInDeviceInfo: "AA-BB-CC-DD-EE-FF", + macInRequest: "AABBCCDDEEFF", expectedToWork: true, description: "DeviceInfo has dashes, request without (should work with normalization)", }, @@ -94,7 +94,7 @@ func TestMacAddressCaseSensitivity(t *testing.T) { ` + tc.macInDeviceInfo + ` - 192.168.1.100 + 192.0.2.100 ` if err := os.WriteFile(filepath.Join(deviceDir, constants.DeviceInfoFile), []byte(deviceInfoXML), 0644); err != nil { @@ -152,8 +152,8 @@ func TestMacAddressCaseSensitivity(t *testing.T) { // TestProductionScenarioSimulation simulates the exact issue described func TestProductionScenarioSimulation(t *testing.T) { // This test specifically simulates the production scenario where: - // Request: GET /streaming/account/3230304/device/A81B6A536A98/presets - // File exists at: /var/lib/soundtouch-service/accounts/3230304/devices/I6332527703739342000020/Presets.xml + // Request: GET /streaming/account/1000001/device/AABBCCDDEEFF/presets + // File exists at: /var/lib/soundtouch-service/accounts/1000001/devices/I6332527703739342000020/Presets.xml tmpDir, err := os.MkdirTemp("", "production-scenario") if err != nil { @@ -161,19 +161,19 @@ func TestProductionScenarioSimulation(t *testing.T) { } defer os.RemoveAll(tmpDir) - accountID := "3230304" + accountID := "1000001" serialNumber := "I6332527703739342000020" - requestMAC := "A81B6A536A98" + requestMAC := "AABBCCDDEEFF" // Test different MAC address formats that could be in DeviceInfo.xml possibleMACFormats := []string{ - "A81B6A536A98", // Exact match - "a81b6a536a98", // All lowercase - "A81b6a536A98", // Mixed case - "A8:1B:6A:53:6A:98", // With colons - "A8-1B-6A-53-6A-98", // With dashes - "a8:1b:6a:53:6a:98", // Lowercase with colons - "a8-1b-6a-53-6a-98", // Lowercase with dashes + "AABBCCDDEEFF", // Exact match + "aabbccddeeff", // All lowercase + "AAbbccddEEff", // Mixed case + "AA:BB:CC:DD:EE:FF", // With colons + "AA-BB-CC-DD-EE-FF", // With dashes + "aa:bb:cc:dd:ee:ff", // Lowercase with colons + "aa-bb-cc-dd-ee-ff", // Lowercase with dashes } t.Logf("Production scenario simulation:") @@ -203,7 +203,7 @@ func TestProductionScenarioSimulation(t *testing.T) { ` + macFormat + ` - 192.168.1.100 + 192.0.2.100 ` if err := os.WriteFile(filepath.Join(deviceDir, constants.DeviceInfoFile), []byte(deviceInfoXML), 0644); err != nil { @@ -259,13 +259,13 @@ func TestNormalizationSuggestion(t *testing.T) { original string normalized string }{ - {"A81B6A536A98", "A81B6A536A98"}, - {"a81b6a536a98", "A81B6A536A98"}, - {"A8:1B:6A:53:6A:98", "A81B6A536A98"}, - {"a8:1b:6a:53:6a:98", "A81B6A536A98"}, - {"A8-1B-6A-53-6A-98", "A81B6A536A98"}, - {"a8-1b-6a-53-6a-98", "A81B6A536A98"}, - {"a81B6a536A98", "A81B6A536A98"}, + {"AABBCCDDEEFF", "AABBCCDDEEFF"}, + {"aabbccddeeff", "AABBCCDDEEFF"}, + {"AA:BB:CC:DD:EE:FF", "AABBCCDDEEFF"}, + {"aa:bb:cc:dd:ee:ff", "AABBCCDDEEFF"}, + {"AA-BB-CC-DD-EE-FF", "AABBCCDDEEFF"}, + {"aa-bb-cc-dd-ee-ff", "AABBCCDDEEFF"}, + {"aaBBccddEEff", "AABBCCDDEEFF"}, } t.Log("MAC Address Normalization Test:") @@ -273,7 +273,7 @@ func TestNormalizationSuggestion(t *testing.T) { t.Log("") allNormalizedSame := true - expectedNormalized := "A81B6A536A98" + expectedNormalized := "AABBCCDDEEFF" for _, tc := range testCases { normalized := normalizeMAC(tc.original) diff --git a/pkg/service/datastore/datastore_test.go b/pkg/service/datastore/datastore_test.go index e1ce64e..0b0d7cf 100644 --- a/pkg/service/datastore/datastore_test.go +++ b/pkg/service/datastore/datastore_test.go @@ -180,7 +180,7 @@ func TestListAllDevices(t *testing.T) { info := &models.ServiceDeviceInfo{ DeviceID: deviceID, Name: "Test Speaker", - IPAddress: "192.168.1.100", + IPAddress: "192.0.2.100", DeviceSerialNumber: deviceID, ProductCode: "SoundTouch 10", FirmwareVersion: "1.2.3", @@ -264,13 +264,13 @@ func TestListAllDevices_MultipleEmptyIDs(t *testing.T) { info1 := &models.ServiceDeviceInfo{ DeviceID: "", Name: "Speaker 1", - IPAddress: "192.168.1.1", + IPAddress: "192.0.2.1", AccountID: account, } info2 := &models.ServiceDeviceInfo{ DeviceID: "", Name: "Speaker 2", - IPAddress: "192.168.1.2", + IPAddress: "192.0.2.2", AccountID: account, } diff --git a/pkg/service/datastore/device_info_test.go b/pkg/service/datastore/device_info_test.go index 3747e6c..cd6dc8b 100644 --- a/pkg/service/datastore/device_info_test.go +++ b/pkg/service/datastore/device_info_test.go @@ -44,7 +44,7 @@ func TestSaveDeviceInfo_MergesName(t *testing.T) { AccountID: account, Name: "", ProductCode: "SoundTouch 20", - IPAddress: "192.168.1.100", + IPAddress: "192.0.2.100", } if err := ds.SaveDeviceInfo(account, device, info2); err != nil { t.Fatalf("Second SaveDeviceInfo failed: %v", err) @@ -58,7 +58,7 @@ func TestSaveDeviceInfo_MergesName(t *testing.T) { if saved2.Name != "Living Room" { t.Errorf("Expected name 'Living Room' to be preserved, but got '%s'", saved2.Name) } - if saved2.IPAddress != "192.168.1.100" { - t.Errorf("Expected IPAddress '192.168.1.100', got '%s'", saved2.IPAddress) + if saved2.IPAddress != "192.0.2.100" { + t.Errorf("Expected IPAddress '192.0.2.100', got '%s'", saved2.IPAddress) } } diff --git a/pkg/service/datastore/dns_persistence_test.go b/pkg/service/datastore/dns_persistence_test.go index 5686d7b..d7d85af 100644 --- a/pkg/service/datastore/dns_persistence_test.go +++ b/pkg/service/datastore/dns_persistence_test.go @@ -24,7 +24,7 @@ func TestDNSDiscoveryPersistence(t *testing.T) { QueryCount: 10, IsBoseService: true, IsIntercepted: true, - RemoteAddr: "192.168.1.100", + RemoteAddr: "192.0.2.100", }, { Hostname: "google.com", @@ -33,7 +33,7 @@ func TestDNSDiscoveryPersistence(t *testing.T) { QueryCount: 5, IsBoseService: false, IsIntercepted: false, - RemoteAddr: "192.168.1.101", + RemoteAddr: "192.0.2.101", }, } diff --git a/pkg/service/datastore/mac_address_serialization_test.go b/pkg/service/datastore/mac_address_serialization_test.go index d85b9aa..ba26c59 100644 --- a/pkg/service/datastore/mac_address_serialization_test.go +++ b/pkg/service/datastore/mac_address_serialization_test.go @@ -16,16 +16,16 @@ func TestMacAddressSerialization(t *testing.T) { defer os.RemoveAll(tempDir) ds := NewDataStore(tempDir) - account := "3230304" + account := "1000001" device := "I6332527703739342000020" - macAddress := "A81B6A536A98" + macAddress := "AABBCCDDEEFF" // Create device info with MAC address info := &models.ServiceDeviceInfo{ DeviceID: device, Name: "Test SoundTouch", ProductCode: "SoundTouch 10", - IPAddress: "192.168.1.100", + IPAddress: "192.0.2.100", MacAddress: macAddress, DeviceSerialNumber: device, ProductSerialNumber: "PROD123456", @@ -61,8 +61,8 @@ func TestMacAddressSerialization(t *testing.T) { t.Errorf("DeviceID mismatch. Expected: %s, Got: %s", device, loadedInfo.DeviceID) } - if loadedInfo.IPAddress != "192.168.1.100" { - t.Errorf("IPAddress mismatch. Expected: 192.168.1.100, Got: %s", loadedInfo.IPAddress) + if loadedInfo.IPAddress != "192.0.2.100" { + t.Errorf("IPAddress mismatch. Expected: 192.0.2.100, Got: %s", loadedInfo.IPAddress) } // Initialize datastore to populate MAC mappings @@ -112,10 +112,10 @@ func TestMacAddressSerializationEdgeCases(t *testing.T) { macAddress string expected string }{ - {"uppercase", "A81B6A536A98", "A81B6A536A98"}, - {"lowercase", "a81b6a536a98", "a81b6a536a98"}, - {"with_colons", "A8:1B:6A:53:6A:98", "A8:1B:6A:53:6A:98"}, - {"with_dashes", "A8-1B-6A-53-6A-98", "A8-1B-6A-53-6A-98"}, + {"uppercase", "AABBCCDDEEFF", "AABBCCDDEEFF"}, + {"lowercase", "aabbccddeeff", "aabbccddeeff"}, + {"with_colons", "AA:BB:CC:DD:EE:FF", "AA:BB:CC:DD:EE:FF"}, + {"with_dashes", "AA-BB-CC-DD-EE-FF", "AA-BB-CC-DD-EE-FF"}, {"empty", "", ""}, } @@ -127,7 +127,7 @@ func TestMacAddressSerializationEdgeCases(t *testing.T) { DeviceID: deviceID, Name: "Test Device " + tc.name, ProductCode: "SoundTouch 10", - IPAddress: "192.168.1.100", + IPAddress: "192.0.2.100", MacAddress: tc.macAddress, DeviceSerialNumber: deviceID, } @@ -159,7 +159,7 @@ func TestExistingDeviceInfoUpdate(t *testing.T) { defer os.RemoveAll(tempDir) ds := NewDataStore(tempDir) - account := "3230304" + account := "1000001" device := "I6332527703739342000020" // First save without MAC address (simulating old DeviceInfo.xml) @@ -167,7 +167,7 @@ func TestExistingDeviceInfoUpdate(t *testing.T) { DeviceID: device, Name: "Test SoundTouch", ProductCode: "SoundTouch 10", - IPAddress: "192.168.1.100", + IPAddress: "192.0.2.100", MacAddress: "", // No MAC address initially DeviceSerialNumber: device, } @@ -188,12 +188,12 @@ func TestExistingDeviceInfoUpdate(t *testing.T) { } // Now update with MAC address (simulating discovery update) - macAddress := "A81B6A536A98" + macAddress := "AABBCCDDEEFF" infoWithMAC := &models.ServiceDeviceInfo{ DeviceID: device, Name: "Test SoundTouch", ProductCode: "SoundTouch 10", - IPAddress: "192.168.1.100", + IPAddress: "192.0.2.100", MacAddress: macAddress, DeviceSerialNumber: device, } diff --git a/pkg/service/datastore/mac_first_resolution_test.go b/pkg/service/datastore/mac_first_resolution_test.go index 11527b4..6ac11b1 100644 --- a/pkg/service/datastore/mac_first_resolution_test.go +++ b/pkg/service/datastore/mac_first_resolution_test.go @@ -17,7 +17,7 @@ func TestAccountDeviceDir_MACFirstResolution(t *testing.T) { ds := NewDataStore(tempDir) accountID := "testaccount" - macAddress := "A81B6A536A98" + macAddress := "AABBCCDDEEFF" serialNumber := "I6332527703739342000020" t.Run("NewMACBasedDevice", func(t *testing.T) { @@ -26,7 +26,7 @@ func TestAccountDeviceDir_MACFirstResolution(t *testing.T) { DeviceID: macAddress, AccountID: accountID, Name: "New MAC Device", - IPAddress: "192.168.1.100", + IPAddress: "192.0.2.100", MacAddress: macAddress, DeviceSerialNumber: serialNumber, ProductCode: "SoundTouch 10 sm2", @@ -59,7 +59,7 @@ func TestAccountDeviceDir_MACFirstResolution(t *testing.T) { DeviceID: serialNumber, AccountID: accountID, Name: "Legacy Serial Device", - IPAddress: "192.168.1.101", + IPAddress: "192.0.2.101", MacAddress: macAddress, DeviceSerialNumber: serialNumber, ProductCode: "SoundTouch 10", @@ -153,11 +153,11 @@ func TestAccountDeviceDir_MACFirstResolution(t *testing.T) { t.Run("MACNormalization", func(t *testing.T) { // Test different MAC address formats macFormats := []string{ - "A81B6A536A98", // No separators - "A8:1B:6A:53:6A:98", // Colons - "A8-1B-6A-53-6A-98", // Dashes - "a81b6a536a98", // Lowercase - "a8:1b:6a:53:6a:98", // Lowercase with colons + "AABBCCDDEEFF", // No separators + "AA:BB:CC:DD:EE:FF", // Colons + "AA-BB-CC-DD-EE-FF", // Dashes + "aabbccddeeff", // Lowercase + "aa:bb:cc:dd:ee:ff", // Lowercase with colons } for _, macFormat := range macFormats { @@ -275,17 +275,17 @@ func TestMACAddressFormatDetection(t *testing.T) { expected bool name string }{ - {"A81B6A536A98", true, "12-char hex"}, - {"a81b6a536a98", true, "12-char hex lowercase"}, - {"A8:1B:6A:53:6A:98", true, "colon-separated"}, - {"A8-1B-6A-53-6A-98", true, "dash-separated"}, - {"a8:1b:6a:53:6a:98", true, "colon-separated lowercase"}, - {"a8-1b-6a-53-6a-98", true, "dash-separated lowercase"}, + {"AABBCCDDEEFF", true, "12-char hex"}, + {"aabbccddeeff", true, "12-char hex lowercase"}, + {"AA:BB:CC:DD:EE:FF", true, "colon-separated"}, + {"AA-BB-CC-DD-EE-FF", true, "dash-separated"}, + {"aa:bb:cc:dd:ee:ff", true, "colon-separated lowercase"}, + {"aa-bb-cc-dd-ee-ff", true, "dash-separated lowercase"}, {"I6332527703739342000020", false, "device serial"}, - {"192.168.1.100", false, "IP address"}, + {"192.0.2.100", false, "IP address"}, {"ABCDEFGHIJKL", false, "12-char non-hex"}, - {"A8:1B:6A:53:6A", false, "incomplete MAC"}, - {"A8:1B:6A:53:6A:98:01", false, "too long MAC"}, + {"AA:BB:CC:DD:EE", false, "incomplete MAC"}, + {"AA:BB:CC:DD:EE:FF:01", false, "too long MAC"}, {"", false, "empty string"}, } @@ -308,7 +308,7 @@ func TestAccountDeviceDir_PriorityOrder(t *testing.T) { ds := NewDataStore(tempDir) accountID := "prioritytest" - macAddress := "A8:1B:6A:53:6A:98" + macAddress := "AA:BB:CC:DD:EE:FF" serialNumber := "PRIORITY123456789" // Create both MAC-based and serial-based devices for the same physical device diff --git a/pkg/service/datastore/mac_mapping_diagnostic_test.go b/pkg/service/datastore/mac_mapping_diagnostic_test.go index f07dcb6..c26a948 100644 --- a/pkg/service/datastore/mac_mapping_diagnostic_test.go +++ b/pkg/service/datastore/mac_mapping_diagnostic_test.go @@ -16,9 +16,9 @@ func TestMacMappingDiagnostic(t *testing.T) { } defer os.RemoveAll(tmpDir) - accountID := "3230304" + accountID := "1000001" serialNumber := "I6332527703739342000020" - macAddress := "A81B6A536A98" + macAddress := "AABBCCDDEEFF" // Create the directory structure as it exists in production deviceDir := filepath.Join(tmpDir, "accounts", accountID, "devices", serialNumber) @@ -39,7 +39,7 @@ func TestMacMappingDiagnostic(t *testing.T) { ` + macAddress + ` - 192.168.1.100 + 192.0.2.100 ` if err := os.WriteFile(filepath.Join(deviceDir, constants.DeviceInfoFile), []byte(deviceInfoXML), 0644); err != nil { @@ -127,8 +127,8 @@ func TestMacMappingDiagnostic(t *testing.T) { // Test 5: Check case sensitivity t.Run("CheckCaseSensitivity", func(t *testing.T) { - lowercaseMAC := "a81b6a536a98" - uppercaseMAC := "A81B6A536A98" + lowercaseMAC := "aabbccddeeff" + uppercaseMAC := "AABBCCDDEEFF" ds.idMutex.RLock() _, lowercaseOk := ds.deviceMappings[lowercaseMAC] @@ -191,11 +191,11 @@ func TestMacMappingWithDifferentFormats(t *testing.T) { macInRequest string shouldWork bool }{ - {"ExactMatch", "A81B6A536A98", "A81B6A536A98", true}, - {"LowerCase", "A81B6A536A98", "a81b6a536a98", true}, // Should work with normalization - {"UpperCase", "a81b6a536a98", "A81B6A536A98", true}, // Should work with normalization - {"WithColons", "A8:1B:6A:53:6A:98", "A81B6A536A98", true}, // Should work with normalization - {"WithDashes", "A8-1B-6A-53-6A-98", "A81B6A536A98", true}, // Should work with normalization + {"ExactMatch", "AABBCCDDEEFF", "AABBCCDDEEFF", true}, + {"LowerCase", "AABBCCDDEEFF", "aabbccddeeff", true}, // Should work with normalization + {"UpperCase", "aabbccddeeff", "AABBCCDDEEFF", true}, // Should work with normalization + {"WithColons", "AA:BB:CC:DD:EE:FF", "AABBCCDDEEFF", true}, // Should work with normalization + {"WithDashes", "AA-BB-CC-DD-EE-FF", "AABBCCDDEEFF", true}, // Should work with normalization } for _, tc := range testCases { @@ -223,7 +223,7 @@ func TestMacMappingWithDifferentFormats(t *testing.T) { ` + tc.macInXML + ` - 192.168.1.100 + 192.0.2.100 ` if err := os.WriteFile(filepath.Join(deviceDir, constants.DeviceInfoFile), []byte(deviceInfoXML), 0644); err != nil { diff --git a/pkg/service/datastore/mapping_test.go b/pkg/service/datastore/mapping_test.go index f1600ab..1d530ec 100644 --- a/pkg/service/datastore/mapping_test.go +++ b/pkg/service/datastore/mapping_test.go @@ -37,7 +37,7 @@ func TestDataStore_MacAddressMapping(t *testing.T) { ` + macAddress + ` - 192.168.1.10 + 192.0.2.10 ` if err := os.WriteFile(filepath.Join(deviceDir, constants.DeviceInfoFile), []byte(deviceInfoXML), 0644); err != nil { diff --git a/pkg/service/datastore/upnp_integration_test.go b/pkg/service/datastore/upnp_integration_test.go index 975318d..fc559c8 100644 --- a/pkg/service/datastore/upnp_integration_test.go +++ b/pkg/service/datastore/upnp_integration_test.go @@ -28,10 +28,10 @@ func TestUPnPDiscoveryToDatastoreMapping_FullFlow(t *testing.T) { defer os.RemoveAll(tmpDir) // Test data matching the user's scenario - accountID := "3230304" + accountID := "1000001" deviceSerial := "I6332527703739342000020" - deviceMAC := "A81B6A536A98" - deviceName := "Sound Machinechen" + deviceMAC := "AABBCCDDEEFF" + deviceName := "Living Room SoundTouch" t.Logf("Test scenario:") t.Logf(" Account: %s", accountID) @@ -60,7 +60,7 @@ func TestUPnPDiscoveryToDatastoreMapping_FullFlow(t *testing.T) { ` + deviceMAC + ` - 192.168.1.100 + 192.0.2.100 ` if err := os.WriteFile(filepath.Join(deviceDir, constants.DeviceInfoFile), []byte(deviceInfoXML), 0644); err != nil { @@ -128,7 +128,7 @@ func TestUPnPDiscoveryToDatastoreMapping_FullFlow(t *testing.T) { // Simulate UPnP discovery discoveryService := discovery.NewService(5 * time.Second) device := &models.DiscoveredDevice{ - Host: "192.168.1.100", + Host: "192.0.2.100", Port: 8091, Name: "Initial Name", } @@ -195,25 +195,25 @@ func TestUPnPDiscoveryToDatastoreMapping_FullFlow(t *testing.T) { }{ { name: "ExactMatch", - requestMAC: "A81B6A536A98", + requestMAC: "AABBCCDDEEFF", shouldWork: true, description: "Exact MAC match", }, { name: "LowercaseMAC", - requestMAC: "a81b6a536a98", + requestMAC: "aabbccddeeff", shouldWork: true, description: "Lowercase MAC (should work with normalization)", }, { name: "MACWithColons", - requestMAC: "A8:1B:6A:53:6A:98", + requestMAC: "AA:BB:CC:DD:EE:FF", shouldWork: true, description: "MAC with colons (should work with normalization)", }, { name: "MACWithDashes", - requestMAC: "A8-1B-6A-53-6A-98", + requestMAC: "AA-BB-CC-DD-EE-FF", shouldWork: true, description: "MAC with dashes (should work with normalization)", }, @@ -315,16 +315,16 @@ func TestNormalizationEdgeCases(t *testing.T) { {"", "", "empty string"}, {"a", "A", "single character"}, {"ab", "AB", "two characters"}, - {"A81B6A536A98", "A81B6A536A98", "standard MAC"}, - {"a81b6a536a98", "A81B6A536A98", "lowercase MAC"}, - {"A8:1B:6A:53:6A:98", "A81B6A536A98", "MAC with colons"}, - {"A8-1B-6A-53-6A-98", "A81B6A536A98", "MAC with dashes"}, - {"a8:1b:6a:53:6a:98", "A81B6A536A98", "lowercase MAC with colons"}, - {"a8-1b-6a-53-6a-98", "A81B6A536A98", "lowercase MAC with dashes"}, - {"A8::1B::6A", "A81B6A", "multiple consecutive colons"}, - {"A8--1B--6A", "A81B6A", "multiple consecutive dashes"}, - {"A8:-1B-:6A", "A81B6A", "mixed separators"}, - {" A81B6A536A98 ", "A81B6A536A98", "MAC with spaces (handled by normalization)"}, + {"AABBCCDDEEFF", "AABBCCDDEEFF", "standard MAC"}, + {"aabbccddeeff", "AABBCCDDEEFF", "lowercase MAC"}, + {"AA:BB:CC:DD:EE:FF", "AABBCCDDEEFF", "MAC with colons"}, + {"AA-BB-CC-DD-EE-FF", "AABBCCDDEEFF", "MAC with dashes"}, + {"aa:bb:cc:dd:ee:ff", "AABBCCDDEEFF", "lowercase MAC with colons"}, + {"aa-bb-cc-dd-ee-ff", "AABBCCDDEEFF", "lowercase MAC with dashes"}, + {"AA::BB::CC", "AABBCC", "multiple consecutive colons"}, + {"AA--BB--CC", "AABBCC", "multiple consecutive dashes"}, + {"AA:-BB-:CC", "AABBCC", "mixed separators"}, + {" AABBCCDDEEFF ", "AABBCCDDEEFF", "MAC with spaces (handled by normalization)"}, } for _, tc := range testCases { diff --git a/pkg/service/handlers/handlers_marge_test.go b/pkg/service/handlers/handlers_marge_test.go index b809ac0..5e4104a 100644 --- a/pkg/service/handlers/handlers_marge_test.go +++ b/pkg/service/handlers/handlers_marge_test.go @@ -253,7 +253,7 @@ func TestMargeAccountFull(t *testing.T) { - 192.168.1.100 + 192.0.2.100 `), 0644); err != nil { @@ -283,7 +283,7 @@ func TestMargeAccountFull(t *testing.T) { } // TestMargeAccountFullExcludesEmptyAmazonSource is a regression test for the two-device scenario -// observed in production: device A81B6A536A98 (alphabetically last, used as lastDeviceID) +// observed in production: device AABBCCDDEEFF (alphabetically last, used as lastDeviceID) // has Sources.xml with 6 sources but no Amazon. The first device has Amazon with empty // credentials (written before OAuth was implemented). Amazon must NOT appear in /full — // an empty-credential Amazon causes the speaker's AmazonController to fail JSON parsing. @@ -296,7 +296,7 @@ func TestMargeAccountFullExcludesEmptyAmazonSource(t *testing.T) { ds := datastore.NewDataStore(tempDir) - account := "3230304" + account := "1000001" // First device (alphabetically): has Amazon in Sources.xml firstDeviceID := "08DF1F0BA325" @@ -306,7 +306,7 @@ func TestMargeAccountFullExcludesEmptyAmazonSource(t *testing.T) { } if err := os.WriteFile(filepath.Join(firstDir, "DeviceInfo.xml"), []byte(` - A Sound Machine + Kitchen SoundTouch SoundTouch 20 scm `), 0644); err != nil { @@ -322,13 +322,13 @@ func TestMargeAccountFullExcludesEmptyAmazonSource(t *testing.T) { // Second device (alphabetically last = lastDeviceID): 6 sources but NO Amazon. // This reproduces the real full.xml returned by the live service. - lastDeviceID := "A81B6A536A98" + lastDeviceID := "AABBCCDDEEFF" lastDir := filepath.Join(tempDir, "accounts", account, "devices", lastDeviceID) if err := os.MkdirAll(lastDir, 0755); err != nil { t.Fatalf("Failed to create last device dir: %v", err) } if err := os.WriteFile(filepath.Join(lastDir, "DeviceInfo.xml"), []byte(` - + Another Speaker SoundTouch 300 @@ -565,7 +565,7 @@ func TestMargeAccountDevices(t *testing.T) { deviceInfo := models.ServiceDeviceInfo{ DeviceID: deviceID, Name: "Test Device", - IPAddress: "192.168.1.100", + IPAddress: "192.0.2.100", DeviceSerialNumber: "ABCDE12345", ProductCode: "SoundTouch 20", ProductSerialNumber: "066802942560222AE", @@ -599,7 +599,7 @@ func TestMargeAccountDevices(t *testing.T) { "", "", "Test Device", - "192.168.1.100", + "192.0.2.100", "", "ELIGIBLE_FOR_TRIAL", } @@ -1296,7 +1296,7 @@ func TestMargeAddRemoveDevice(t *testing.T) { - 192.168.1.101 + 192.0.2.101 ` @@ -1358,7 +1358,7 @@ func TestMargePowerOn(t *testing.T) { }) t.Run("FullBody", func(t *testing.T) { - payload := `I633252770373934200002027.0.6.46330069231P63364828AEExcellent192.168.1.1001122334455192.168.1.100Wireless` + payload := `I633252770373934200002027.0.6.46330069231P63364828AEExcellent192.0.2.1001122334455192.0.2.100Wireless` res, err := http.Post(ts.URL+"/marge/streaming/support/power_on", "application/vnd.bose.streaming-v1.2+xml", strings.NewReader(payload)) if err != nil { t.Fatal(err) @@ -1386,7 +1386,7 @@ func TestMargePowerOn(t *testing.T) { firmware := "27.0.6.46330" productCode := "SoundTouch 10 sm2" productSerial := "069231P63364828AE" - ipAddress := "192.168.1.100" + ipAddress := "192.0.2.100" macAddress := "001122334455" payload := fmt.Sprintf(` @@ -1401,7 +1401,7 @@ func TestMargePowerOn(t *testing.T) { Excellent - 192.168.1.1 + 192.0.2.1 %s @@ -1528,7 +1528,7 @@ func TestMargeAdvancedFeatures(t *testing.T) { account := "A123" deviceId := "587A628A4042" macAddress := "AABBCCDDEEFF" - ipAddress := "192.168.1.100" + ipAddress := "192.0.2.100" firmware := "27.0.6" // Pre-register device @@ -1722,10 +1722,10 @@ func TestMargeGroupCRUD(t *testing.T) { Living Room Stereo ` + device1 + ` - ` + device1 + `LEFT192.168.1.10 - ` + device2 + `RIGHT192.168.1.11 + ` + device1 + `LEFT192.0.2.10 + ` + device2 + `RIGHT192.0.2.11 - 192.168.1.10 + 192.0.2.10 ` var groupID string diff --git a/pkg/service/handlers/handlers_setup_test.go b/pkg/service/handlers/handlers_setup_test.go index 138c909..c40e983 100644 --- a/pkg/service/handlers/handlers_setup_test.go +++ b/pkg/service/handlers/handlers_setup_test.go @@ -183,7 +183,7 @@ func TestMigrationAndCA(t *testing.T) { // Mock HTTPGet to avoid real network timeouts sm.HTTPGet = func(url string) (*http.Response, error) { if strings.HasSuffix(url, "/info") { - xml := `Test SpeakerSoundTouch 10default` + xml := `Test SpeakerSoundTouch 10default` return &http.Response{ StatusCode: http.StatusOK, Body: io.NopCloser(strings.NewReader(xml)), @@ -202,9 +202,9 @@ func TestMigrationAndCA(t *testing.T) { defer ts.Close() // Add device to datastore for resolution - _ = ds.SaveDeviceInfo("default", "192.168.1.10", &models.ServiceDeviceInfo{ - DeviceID: "192.168.1.10", - IPAddress: "192.168.1.10", + _ = ds.SaveDeviceInfo("default", "192.0.2.10", &models.ServiceDeviceInfo{ + DeviceID: "192.0.2.10", + IPAddress: "192.0.2.10", AccountID: "default", }) @@ -223,7 +223,7 @@ func TestMigrationAndCA(t *testing.T) { } // 2. Test POST /setup/migrate/{deviceIP}?method=hosts - res, err = http.Post(ts.URL+"/setup/migrate/192.168.1.10?method=hosts&target_url=http://192.168.1.100:8000", "application/json", nil) + res, err = http.Post(ts.URL+"/setup/migrate/192.0.2.10?method=hosts&target_url=http://192.0.2.100:8000", "application/json", nil) if err != nil { t.Fatal(err) } @@ -245,7 +245,7 @@ func TestMigrationAndCA(t *testing.T) { } // 3. Test POST /setup/trust-ca/{deviceIP} - res, err = http.Post(ts.URL+"/setup/trust-ca/192.168.1.10", "application/json", nil) + res, err = http.Post(ts.URL+"/setup/trust-ca/192.0.2.10", "application/json", nil) if err != nil { t.Fatal(err) } @@ -266,7 +266,7 @@ func TestMigrationAndCA(t *testing.T) { } // 4. Test POST /setup/reboot/{deviceIP} - res, err = http.Post(ts.URL+"/setup/reboot/192.168.1.10", "application/json", nil) + res, err = http.Post(ts.URL+"/setup/reboot/192.0.2.10", "application/json", nil) if err != nil { t.Fatal(err) } @@ -287,7 +287,7 @@ func TestMigrationAndCA(t *testing.T) { } // 5. Test POST /setup/remove-remote-services/{deviceIP} - res, err = http.Post(ts.URL+"/setup/remove-remote-services/192.168.1.10", "application/json", nil) + res, err = http.Post(ts.URL+"/setup/remove-remote-services/192.0.2.10", "application/json", nil) if err != nil { t.Fatal(err) } @@ -412,7 +412,7 @@ func (m *mockSSH) Run(command string) (string, error) { m.runCount++ if m.runCount > 1 { // Return updated hosts for verification - return "127.0.0.1 localhost\n192.168.1.100\tstreaming.bose.com\n192.168.1.100\tupdates.bose.com\n192.168.1.100\tstats.bose.com\n192.168.1.100\tbmx.bose.com\n192.168.1.100\tcontent.api.bose.io\n192.168.1.100\tevents.api.bosecm.com\n192.168.1.100\tbose-prod.apigee.net\n192.168.1.100\tworldwide.bose.com\n192.168.1.100\tmedia.bose.io\n192.168.1.100\tdownloads.bose.com\n192.168.1.100\tvoice.api.bose.io", nil + return "127.0.0.1 localhost\n192.0.2.100\tstreaming.bose.com\n192.0.2.100\tupdates.bose.com\n192.0.2.100\tstats.bose.com\n192.0.2.100\tbmx.bose.com\n192.0.2.100\tcontent.api.bose.io\n192.0.2.100\tevents.api.bosecm.com\n192.0.2.100\tbose-prod.apigee.net\n192.0.2.100\tworldwide.bose.com\n192.0.2.100\tmedia.bose.io\n192.0.2.100\tdownloads.bose.com\n192.0.2.100\tvoice.api.bose.io", nil } return "127.0.0.1 localhost", nil } diff --git a/pkg/service/handlers/issue285_regression_test.go b/pkg/service/handlers/issue285_regression_test.go index 4e63d5f..383804e 100644 --- a/pkg/service/handlers/issue285_regression_test.go +++ b/pkg/service/handlers/issue285_regression_test.go @@ -34,7 +34,7 @@ import ( // and the Bose App showed the rename spinning indefinitely. // // The fixture at testdata/issue285/rename_request.xml is the exact -// payload from the log (line 36) — `deviceid="884AEAEEBD27"`, +// payload from the log (line 36) — `deviceid="AABBCCDDEE02"`, // `Wohnzimmer SB`. The test: // // 1. Pre-seeds the datastore with a device record under the @@ -66,7 +66,7 @@ func TestIssue285_RenamePutAcceptedAndPersisted(t *testing.T) { const ( accountID = "3981561" - deviceID = "884AEAEEBD27" + deviceID = "AABBCCDDEE02" oldName = "Wohnzimmer" newName = "Wohnzimmer SB" preExistingIP = "192.168.0.109" @@ -78,7 +78,7 @@ func TestIssue285_RenamePutAcceptedAndPersisted(t *testing.T) { // data models a long-paired device the user is now renaming — // CreatedOn must survive the PUT (real Bose preserves it // across renames; see parity capture at - // data/parity_mismatches/1771797308__streaming_account_3230304_device_A81B6A536A98.json). + // data/parity_mismatches/1771797308__streaming_account_1000001_device_AABBCCDDEEFF.json). if err := ds.SaveDeviceInfo(accountID, deviceID, &models.ServiceDeviceInfo{ DeviceID: deviceID, AccountID: accountID, @@ -228,8 +228,8 @@ func TestIssue285_NewDeviceGetsRemoteAddrAndFreshTimestamps(t *testing.T) { const ( accountID = "1111111" - deviceID = "A81B6A536A98" - newName = "Sound Machinechen" + deviceID = "AABBCCDDEEFF" + newName = "Living Room SoundTouch" ) r, _ := setupRouter("http://localhost:8001", ds) @@ -314,7 +314,7 @@ func TestIssue285_RenamePutRejectsMismatchedDeviceID(t *testing.T) { t.Cleanup(ts.Close) - const urlDeviceID = "884AEAEEBD27" + const urlDeviceID = "AABBCCDDEE02" // Body claims a different deviceID than the URL. body := []byte(`` + diff --git a/pkg/service/handlers/mac_discovery_integration_test.go b/pkg/service/handlers/mac_discovery_integration_test.go index 38581d7..9f0445f 100644 --- a/pkg/service/handlers/mac_discovery_integration_test.go +++ b/pkg/service/handlers/mac_discovery_integration_test.go @@ -24,7 +24,7 @@ func TestMACBasedDeviceDiscovery_Integration(t *testing.T) { // Mock device info response (real-world example) deviceInfoXML := ` -Sound Machinechen +Living Room SoundTouch SoundTouch 10 1234567 @@ -42,11 +42,11 @@ func TestMACBasedDeviceDiscovery_Integration(t *testing.T) { https://streaming.bose.com 001122334455 -192.168.1.100 +192.0.2.100 -A81B6A849D99 -192.168.1.100 +AABBCCDDEE01 +192.0.2.100 sm2 rhino @@ -127,8 +127,8 @@ func TestMACBasedDeviceDiscovery_Integration(t *testing.T) { t.Errorf("Expected accountID '%s', got '%s'", expectedAccountID, deviceInfo.AccountID) } - if deviceInfo.Name != "Sound Machinechen" { - t.Errorf("Expected name 'Sound Machinechen' (from /info), got '%s'", deviceInfo.Name) + if deviceInfo.Name != "Living Room SoundTouch" { + t.Errorf("Expected name 'Living Room SoundTouch' (from /info), got '%s'", deviceInfo.Name) } if deviceInfo.ProductCode != "SoundTouch 10 sm2" { @@ -244,7 +244,7 @@ func TestMACBasedDeviceDiscovery_MigrationScenario(t *testing.T) { accountID := "1234567" // 1. Create an existing device entry using IP address (old style) - oldDeviceID := "192.168.1.100" + oldDeviceID := "192.0.2.100" oldInfo := &models.ServiceDeviceInfo{ DeviceID: oldDeviceID, AccountID: accountID, @@ -282,7 +282,7 @@ func TestMACBasedDeviceDiscovery_MigrationScenario(t *testing.T) { // 2. Mock the same device now providing proper /info response deviceInfoXML := ` -Sound Machinechen +Living Room SoundTouch SoundTouch 10 1234567 @@ -294,7 +294,7 @@ func TestMACBasedDeviceDiscovery_MigrationScenario(t *testing.T) { 001122334455 -192.168.1.100 +192.0.2.100 sm2 ` @@ -336,8 +336,8 @@ func TestMACBasedDeviceDiscovery_MigrationScenario(t *testing.T) { t.Errorf("Expected new deviceID '%s', got '%s'", newDeviceID, newInfo.DeviceID) } - if newInfo.Name != "Sound Machinechen" { - t.Errorf("Expected name from /info 'Sound Machinechen', got '%s'", newInfo.Name) + if newInfo.Name != "Living Room SoundTouch" { + t.Errorf("Expected name from /info 'Living Room SoundTouch', got '%s'", newInfo.Name) } t.Logf("\nMigration completed:") diff --git a/pkg/service/handlers/mac_mapping_integration_test.go b/pkg/service/handlers/mac_mapping_integration_test.go index 8801475..5993284 100644 --- a/pkg/service/handlers/mac_mapping_integration_test.go +++ b/pkg/service/handlers/mac_mapping_integration_test.go @@ -46,7 +46,7 @@ func TestMacMappingIntegration_HTTPHandler(t *testing.T) { ` + macAddress + ` - 192.168.1.100 + 192.0.2.100 ` if err := os.WriteFile(filepath.Join(deviceDir, constants.DeviceInfoFile), []byte(deviceInfoXML), 0644); err != nil { @@ -184,7 +184,7 @@ func TestMacMappingIntegration_HTTPHandler(t *testing.T) { // Test 4: Case sensitivity test t.Run("RequestWithLowercaseMAC", func(t *testing.T) { - lowercaseMAC := "a81b6a536a98" + lowercaseMAC := "aabbccddeeff" requestURL := "/streaming/account/" + accountID + "/device/" + lowercaseMAC + "/presets" req, err := http.NewRequest("GET", requestURL, nil) if err != nil { @@ -287,7 +287,7 @@ func TestMacMappingDebug(t *testing.T) { ` + device.mac + ` - 192.168.1.100 + 192.0.2.100 ` if err := os.WriteFile(filepath.Join(deviceDir, constants.DeviceInfoFile), []byte(deviceInfoXML), 0644); err != nil { diff --git a/pkg/service/handlers/middleware_realip_test.go b/pkg/service/handlers/middleware_realip_test.go index b322094..41f206b 100644 --- a/pkg/service/handlers/middleware_realip_test.go +++ b/pkg/service/handlers/middleware_realip_test.go @@ -28,14 +28,14 @@ func TestTrustedRealIP(t *testing.T) { { name: "trusted peer with X-Real-IP is honoured", remoteAddr: "127.0.0.1:54321", - xRealIP: "192.168.1.10", - wantRemoteAddr: "192.168.1.10", + xRealIP: "192.0.2.10", + wantRemoteAddr: "192.0.2.10", }, { name: "trusted peer with X-Forwarded-For is honoured", remoteAddr: "127.0.0.1:54321", - xForwardedFor: "192.168.1.20, 10.0.0.1", - wantRemoteAddr: "192.168.1.20", + xForwardedFor: "192.0.2.20, 10.0.0.1", + wantRemoteAddr: "192.0.2.20", }, { name: "trusted peer with no headers leaves RemoteAddr alone", @@ -44,15 +44,15 @@ func TestTrustedRealIP(t *testing.T) { }, { name: "untrusted peer's X-Real-IP is ignored", - remoteAddr: "192.168.1.99:54321", + remoteAddr: "192.0.2.99:54321", xRealIP: "1.2.3.4", - wantRemoteAddr: "192.168.1.99:54321", + wantRemoteAddr: "192.0.2.99:54321", }, { name: "untrusted peer's X-Forwarded-For is ignored", - remoteAddr: "192.168.1.99:54321", + remoteAddr: "192.0.2.99:54321", xForwardedFor: "1.2.3.4", - wantRemoteAddr: "192.168.1.99:54321", + wantRemoteAddr: "192.0.2.99:54321", }, { name: "trusted peer with garbage X-Real-IP leaves RemoteAddr alone", diff --git a/pkg/service/handlers/peer_observer_test.go b/pkg/service/handlers/peer_observer_test.go index 8b394ab..5470ddd 100644 --- a/pkg/service/handlers/peer_observer_test.go +++ b/pkg/service/handlers/peer_observer_test.go @@ -10,19 +10,19 @@ import ( func TestPeerObserver_RegisterSignalForget(t *testing.T) { o := newPeerObserver() - ch := o.Register("192.168.1.42") + ch := o.Register("192.0.2.42") if ch == nil { t.Fatal("Register returned nil channel") } first := setup.PeerHit{Path: "/updates/soundtouch", At: time.Now()} - if !o.Signal("192.168.1.42", first) { + if !o.Signal("192.0.2.42", first) { t.Error("Signal returned false for registered IP") } // Second signal while the buffer is still full (no reader yet) drops // silently and returns false — only the first hit per window matters. - if o.Signal("192.168.1.42", setup.PeerHit{Path: "/streaming/x"}) { + if o.Signal("192.0.2.42", setup.PeerHit{Path: "/streaming/x"}) { t.Error("second Signal returned true; expected false (buffer full, undrained)") } @@ -35,10 +35,10 @@ func TestPeerObserver_RegisterSignalForget(t *testing.T) { t.Error("Signal did not deliver hit to channel") } - o.Forget("192.168.1.42") + o.Forget("192.0.2.42") // After Forget, Signal returns false. - if o.Signal("192.168.1.42", first) { + if o.Signal("192.0.2.42", first) { t.Error("Signal returned true after Forget") } } @@ -52,12 +52,12 @@ func TestPeerObserver_UnknownIP(t *testing.T) { func TestPeerObserver_SignalIsNonBlocking(t *testing.T) { o := newPeerObserver() - o.Register("192.168.1.42") // never drain + o.Register("192.0.2.42") // never drain done := make(chan struct{}) go func() { for i := 0; i < 100; i++ { - o.Signal("192.168.1.42", setup.PeerHit{Path: "/x"}) + o.Signal("192.0.2.42", setup.PeerHit{Path: "/x"}) } close(done) }() diff --git a/pkg/service/handlers/preflight_test.go b/pkg/service/handlers/preflight_test.go index eeed379..aedc9a3 100644 --- a/pkg/service/handlers/preflight_test.go +++ b/pkg/service/handlers/preflight_test.go @@ -104,7 +104,7 @@ func TestFormatPreflightGuidance_BothFailMentionsRedirectPort(t *testing.T) { res := Probe443Result{ Localhost: ProbeOutcome{Error: "connection refused"}, LAN: ProbeOutcome{Error: "connection refused"}, - LANHost: "192.168.1.151", + LANHost: "192.0.2.151", } out := FormatPreflightGuidance(8443, res) @@ -112,7 +112,7 @@ func TestFormatPreflightGuidance_BothFailMentionsRedirectPort(t *testing.T) { t.Errorf("guidance must reference configured listener port for iptables, got: %s", out) } - if !strings.Contains(out, "192.168.1.151:443") { + if !strings.Contains(out, "192.0.2.151:443") { t.Errorf("guidance must mention probed LAN host, got: %s", out) } diff --git a/pkg/service/handlers/server_merge_test.go b/pkg/service/handlers/server_merge_test.go index abd92dd..745dcef 100644 --- a/pkg/service/handlers/server_merge_test.go +++ b/pkg/service/handlers/server_merge_test.go @@ -19,7 +19,7 @@ func TestMergeOverlappingDevices(t *testing.T) { s := NewServer(ds, nil, "http://localhost", false, false, false) // Case 1: IP-only entry and Serial-based entry for the same IP - ip := "192.168.1.100" + ip := "192.0.2.100" serial := "SERIAL123" // 1. Save IP-based entry @@ -76,7 +76,7 @@ func TestFindExistingDeviceID(t *testing.T) { ds := datastore.NewDataStore(tempDir) s := NewServer(ds, nil, "http://localhost", false, false, false) - ip := "192.168.1.101" + ip := "192.0.2.101" serial := "SERIAL456" // Save IP-based diff --git a/pkg/service/handlers/testdata/issue285/rename_request.xml b/pkg/service/handlers/testdata/issue285/rename_request.xml index 19a720e..50e5be6 100644 --- a/pkg/service/handlers/testdata/issue285/rename_request.xml +++ b/pkg/service/handlers/testdata/issue285/rename_request.xml @@ -1 +1 @@ -Wohnzimmer SB884AEAEEBD27 +Wohnzimmer SBAABBCCDDEE02 diff --git a/pkg/service/marge/marge_test.go b/pkg/service/marge/marge_test.go index 661dd1f..9bc2fe3 100644 --- a/pkg/service/marge/marge_test.go +++ b/pkg/service/marge/marge_test.go @@ -94,12 +94,12 @@ func TestAccountFullToXML_Structure(t *testing.T) { // 1. Setup Device Info with Components info := &models.ServiceDeviceInfo{ DeviceID: device, - Name: "A Sound Machine", + Name: "Kitchen SoundTouch", ProductCode: "SoundTouch 20", DeviceSerialNumber: device, ProductSerialNumber: "066802942560222AE", FirmwareVersion: "27.0.6.46330.5043500", - IPAddress: "192.168.178.28", + IPAddress: "192.0.2.28", Components: []models.ServiceComponent{ { Category: "SMSC", @@ -186,8 +186,8 @@ func TestAccountFullToXML_Structure(t *testing.T) { if !strings.Contains(xmlStr, ``) { t.Errorf("Expected device attribute deviceid, got %s", xmlStr) } - if !strings.Contains(xmlStr, `A Sound Machine`) { - t.Errorf("Expected A Sound Machine under device, got %s", xmlStr) + if !strings.Contains(xmlStr, `Kitchen SoundTouch`) { + t.Errorf("Expected Kitchen SoundTouch under device, got %s", xmlStr) } if !strings.Contains(xmlStr, `08DF1F0BA325`) { t.Errorf("Expected 08DF1F0BA325 under device, got %s", xmlStr) @@ -715,7 +715,7 @@ func TestAccountFullToXML_WithBackupStructure(t *testing.T) { deviceInfoXML := ` - Sound Machinechen + Living Room SoundTouch SoundTouch 10 sm2 @@ -726,7 +726,7 @@ func TestAccountFullToXML_WithBackupStructure(t *testing.T) { - 192.168.178.35 + 192.0.2.35 001122334455 sync_full @@ -744,8 +744,8 @@ func TestAccountFullToXML_WithBackupStructure(t *testing.T) { xmlStr := string(fullXML) // Verify Name is present - if !strings.Contains(xmlStr, `Sound Machinechen`) { - t.Errorf("Expected Sound Machinechen under device, got %s", xmlStr) + if !strings.Contains(xmlStr, `Living Room SoundTouch`) { + t.Errorf("Expected Living Room SoundTouch under device, got %s", xmlStr) } // 2. Verify ButtonNumber and ContentItemType mapping diff --git a/pkg/service/marge/repro_test.go b/pkg/service/marge/repro_test.go index a5acbb4..07b8cd1 100644 --- a/pkg/service/marge/repro_test.go +++ b/pkg/service/marge/repro_test.go @@ -103,7 +103,7 @@ func TestReproduceMissingName(t *testing.T) { t.Fatal(err) } dev1Info := ` - A Sound Machine + Kitchen SoundTouch SoundTouch 20 @@ -128,7 +128,7 @@ func TestReproduceMissingName(t *testing.T) { } dev2Info := ` - Sound Machinechen + Living Room SoundTouch SoundTouch 10 sm2 @@ -143,7 +143,7 @@ func TestReproduceMissingName(t *testing.T) { - 192.168.178.35 + 192.0.2.35 001122334455 sync_full @@ -190,7 +190,7 @@ func TestReproduceMissingName(t *testing.T) { globalDevDir := filepath.Join("st-go", "data", "accounts", "default", "devices", "001122334455") os.MkdirAll(globalDevDir, 0755) defer os.RemoveAll("st-go") - globalDevInfo := `Sound MachinechenSoundTouch10 sm2` + globalDevInfo := `Living Room SoundTouchSoundTouch10 sm2` os.WriteFile(filepath.Join(globalDevDir, "DeviceInfo.xml"), []byte(globalDevInfo), 0644) // Create a directory in 'default' with EMPTY name (the one that GetDeviceInfo will pick up) @@ -210,8 +210,8 @@ func TestReproduceMissingName(t *testing.T) { t.Fatal(err) } - if info.Name != "Sound Machinechen" { - t.Errorf("Expected name 'Sound Machinechen' to be preserved, got '%s'", info.Name) + if info.Name != "Living Room SoundTouch" { + t.Errorf("Expected name 'Living Room SoundTouch' to be preserved, got '%s'", info.Name) } // Re-generate XML to see if it now uses the preserved name diff --git a/pkg/service/marge/sync_test.go b/pkg/service/marge/sync_test.go index de8237b..4cf64b5 100644 --- a/pkg/service/marge/sync_test.go +++ b/pkg/service/marge/sync_test.go @@ -26,7 +26,7 @@ func TestSyncFromAccountFull(t *testing.T) { Living Room - 192.168.1.10 + 192.0.2.10 ABC123XYZ 27.0.6 diff --git a/pkg/service/proxy/patterns_test.go b/pkg/service/proxy/patterns_test.go index 91c43bb..9d9b899 100644 --- a/pkg/service/proxy/patterns_test.go +++ b/pkg/service/proxy/patterns_test.go @@ -34,7 +34,7 @@ func TestPathPatterns_Sanitize(t *testing.T) { segment string wantRepl string }{ - {"192.168.1.100", "{ip}"}, + {"192.0.2.100", "{ip}"}, {"1234567", "{accountId}"}, {"12345", "{accountId}"}, {"12345678-1234-5678-9012-123456789012", "{uuid}"}, diff --git a/pkg/service/proxy/recorder_test.go b/pkg/service/proxy/recorder_test.go index 2ea3368..8be55e1 100644 --- a/pkg/service/proxy/recorder_test.go +++ b/pkg/service/proxy/recorder_test.go @@ -52,7 +52,7 @@ func TestRecorder_Record_Structure(t *testing.T) { { name: "path_with_ip", category: "self", - path: "/setup/info/192.168.1.100", + path: "/setup/info/192.0.2.100", expected: "setup/info/{ip}", }, { @@ -131,11 +131,11 @@ func TestRecorder_Record_Sanitization(t *testing.T) { req := &http.Request{ Method: "GET", URL: &url.URL{ - Path: "/info/192.168.1.100/A81B6A536A98", + Path: "/info/192.0.2.100/AABBCCDDEEFF", }, Header: make(http.Header), } - req.Header.Set("X-Device", "A81B6A536A98") + req.Header.Set("X-Device", "AABBCCDDEEFF") err = r.Record("self", req, nil) if err != nil { @@ -331,7 +331,7 @@ func TestRecorder_EnvFile(t *testing.T) { req := &http.Request{ Method: "GET", URL: &url.URL{ - Path: "/info/192.168.1.100", + Path: "/info/192.0.2.100", }, Header: make(http.Header), } @@ -352,8 +352,8 @@ func TestRecorder_EnvFile(t *testing.T) { t.Fatalf("Failed to unmarshal env file: %v", err) } - if content["session"]["ip"] != "192.168.1.100" { - t.Errorf("Expected ip to be 192.168.1.100, got %s", content["session"]["ip"]) + if content["session"]["ip"] != "192.0.2.100" { + t.Errorf("Expected ip to be 192.0.2.100, got %s", content["session"]["ip"]) } } diff --git a/pkg/service/setup/device_info_parsing_test.go b/pkg/service/setup/device_info_parsing_test.go index 2b67c08..d3918dd 100644 --- a/pkg/service/setup/device_info_parsing_test.go +++ b/pkg/service/setup/device_info_parsing_test.go @@ -7,10 +7,10 @@ import ( func TestDeviceInfoXML_RealWorldParsing(t *testing.T) { // Real XML response from a SoundTouch device's /info endpoint - xmlData := ` -Sound Machinechen + xmlData := ` +Living Room SoundTouch SoundTouch 10 -3230304 +1000001 SCM @@ -25,12 +25,12 @@ func TestDeviceInfoXML_RealWorldParsing(t *testing.T) { https://streaming.bose.com -A81B6A536A98 -192.168.1.100 +AABBCCDDEEFF +192.0.2.100 -A81B6A849D99 -192.168.1.100 +AABBCCDDEE01 +192.0.2.100 sm2 rhino @@ -48,12 +48,12 @@ func TestDeviceInfoXML_RealWorldParsing(t *testing.T) { } // Verify basic fields - if infoXML.DeviceID != "A81B6A536A98" { - t.Errorf("Expected deviceID 'A81B6A536A98', got '%s'", infoXML.DeviceID) + if infoXML.DeviceID != "AABBCCDDEEFF" { + t.Errorf("Expected deviceID 'AABBCCDDEEFF', got '%s'", infoXML.DeviceID) } - if infoXML.Name != "Sound Machinechen" { - t.Errorf("Expected name 'Sound Machinechen', got '%s'", infoXML.Name) + if infoXML.Name != "Living Room SoundTouch" { + t.Errorf("Expected name 'Living Room SoundTouch', got '%s'", infoXML.Name) } if infoXML.Type != "SoundTouch 10" { @@ -64,8 +64,8 @@ func TestDeviceInfoXML_RealWorldParsing(t *testing.T) { t.Errorf("Expected moduleType 'sm2', got '%s'", infoXML.ModuleType) } - if infoXML.MargeAccountUUID != "3230304" { - t.Errorf("Expected margeAccountUUID '3230304', got '%s'", infoXML.MargeAccountUUID) + if infoXML.MargeAccountUUID != "1000001" { + t.Errorf("Expected margeAccountUUID '1000001', got '%s'", infoXML.MargeAccountUUID) } if infoXML.MargeURL != "https://streaming.bose.com" { @@ -132,19 +132,19 @@ func TestDeviceInfoXML_RealWorldParsing(t *testing.T) { switch net.Type { case "SCM": scmNetworkFound = true - if net.MacAddress != "A81B6A536A98" { - t.Errorf("Expected SCM MAC 'A81B6A536A98', got '%s'", net.MacAddress) + if net.MacAddress != "AABBCCDDEEFF" { + t.Errorf("Expected SCM MAC 'AABBCCDDEEFF', got '%s'", net.MacAddress) } - if net.IPAddress != "192.168.1.100" { - t.Errorf("Expected SCM IP '192.168.1.100', got '%s'", net.IPAddress) + if net.IPAddress != "192.0.2.100" { + t.Errorf("Expected SCM IP '192.0.2.100', got '%s'", net.IPAddress) } case "SMSC": smscNetworkFound = true - if net.MacAddress != "A81B6A849D99" { - t.Errorf("Expected SMSC MAC 'A81B6A849D99', got '%s'", net.MacAddress) + if net.MacAddress != "AABBCCDDEE01" { + t.Errorf("Expected SMSC MAC 'AABBCCDDEE01', got '%s'", net.MacAddress) } - if net.IPAddress != "192.168.1.100" { - t.Errorf("Expected SMSC IP '192.168.1.100', got '%s'", net.IPAddress) + if net.IPAddress != "192.0.2.100" { + t.Errorf("Expected SMSC IP '192.0.2.100', got '%s'", net.IPAddress) } } } @@ -158,8 +158,8 @@ func TestDeviceInfoXML_RealWorldParsing(t *testing.T) { // Test the GetPrimaryMacAddress method primaryMAC := infoXML.GetPrimaryMacAddress() - if primaryMAC != "A81B6A536A98" { - t.Errorf("Expected primary MAC 'A81B6A536A98', got '%s'", primaryMAC) + if primaryMAC != "AABBCCDDEEFF" { + t.Errorf("Expected primary MAC 'AABBCCDDEEFF', got '%s'", primaryMAC) } t.Logf("✅ Successfully parsed real device info XML") @@ -194,10 +194,10 @@ func TestDeviceInfoXML_GetPrimaryMacAddress_EdgeCases(t *testing.T) { MacAddress string IPAddress string }{ - {"SCM", "A81B6A536A98", "192.168.1.1"}, - {"SMSC", "A81B6A849D99", "192.168.1.1"}, + {"SCM", "AABBCCDDEEFF", "192.0.2.1"}, + {"SMSC", "AABBCCDDEE01", "192.0.2.1"}, }, - expected: "A81B6A536A98", + expected: "AABBCCDDEEFF", }, { name: "scm_second", @@ -206,10 +206,10 @@ func TestDeviceInfoXML_GetPrimaryMacAddress_EdgeCases(t *testing.T) { MacAddress string IPAddress string }{ - {"SMSC", "A81B6A849D99", "192.168.1.1"}, - {"SCM", "A81B6A536A98", "192.168.1.1"}, + {"SMSC", "AABBCCDDEE01", "192.0.2.1"}, + {"SCM", "AABBCCDDEEFF", "192.0.2.1"}, }, - expected: "A81B6A536A98", + expected: "AABBCCDDEEFF", }, { name: "no_scm", @@ -218,8 +218,8 @@ func TestDeviceInfoXML_GetPrimaryMacAddress_EdgeCases(t *testing.T) { MacAddress string IPAddress string }{ - {"SMSC", "A81B6A849D99", "192.168.1.1"}, - {"OTHER", "A81B6A849D88", "192.168.1.1"}, + {"SMSC", "AABBCCDDEE01", "192.0.2.1"}, + {"OTHER", "AABBCCDDEE03", "192.0.2.1"}, }, expected: "", }, @@ -230,8 +230,8 @@ func TestDeviceInfoXML_GetPrimaryMacAddress_EdgeCases(t *testing.T) { MacAddress string IPAddress string }{ - {"SCM", "", "192.168.1.1"}, - {"SMSC", "A81B6A849D99", "192.168.1.1"}, + {"SCM", "", "192.0.2.1"}, + {"SMSC", "AABBCCDDEE01", "192.0.2.1"}, }, expected: "", }, @@ -261,7 +261,7 @@ func TestDeviceInfoXML_GetPrimaryMacAddress_EdgeCases(t *testing.T) { } func TestDeviceInfoXML_ComponentParsing(t *testing.T) { - xmlData := ` + xmlData := ` Test Device SoundTouch 10 diff --git a/pkg/service/setup/inspect_test.go b/pkg/service/setup/inspect_test.go index 326cadc..686e666 100644 --- a/pkg/service/setup/inspect_test.go +++ b/pkg/service/setup/inspect_test.go @@ -56,7 +56,7 @@ func TestInspect_HappyPath(t *testing.T) { `, "/networkInfo": ` - + `, "/sources": ``, @@ -66,7 +66,7 @@ func TestInspect_HappyPath(t *testing.T) { m := &Manager{HTTPGet: f.get} - r := m.Inspect("192.168.1.42", InspectOptions{}) + r := m.Inspect("192.0.2.42", InspectOptions{}) if r.InfoErr != nil { t.Errorf("InfoErr = %v, want nil", r.InfoErr) @@ -119,7 +119,7 @@ func TestInspect_PartialFailureRecordsPerSectionErrors(t *testing.T) { m := &Manager{HTTPGet: f.get} - r := m.Inspect("192.168.1.42", InspectOptions{}) + r := m.Inspect("192.0.2.42", InspectOptions{}) if r.InfoErr != nil { t.Errorf("InfoErr = %v, want nil", r.InfoErr) @@ -152,7 +152,7 @@ func TestInspect_TelnetRuntimeURLs(t *testing.T) { NewTelnet: func(string) TelnetClient { return tn }, } - r := m.Inspect("192.168.1.42", InspectOptions{IncludeTelnet: true}) + r := m.Inspect("192.0.2.42", InspectOptions{IncludeTelnet: true}) if r.RuntimeErr != nil { t.Errorf("RuntimeErr = %v, want nil", r.RuntimeErr) @@ -172,7 +172,7 @@ func TestInspect_TelnetSkippedWhenOptionDisabled(t *testing.T) { m := &Manager{HTTPGet: f.get} - r := m.Inspect("192.168.1.42", InspectOptions{IncludeTelnet: false}) + r := m.Inspect("192.0.2.42", InspectOptions{IncludeTelnet: false}) if r.RuntimeURLs != "" || r.RuntimeErr != nil { t.Errorf("telnet runtime fields should be zero when IncludeTelnet=false, got %q / %v", diff --git a/pkg/service/setup/migration_summary_telnet_test.go b/pkg/service/setup/migration_summary_telnet_test.go index 454baff..6aa8b8a 100644 --- a/pkg/service/setup/migration_summary_telnet_test.go +++ b/pkg/service/setup/migration_summary_telnet_test.go @@ -108,7 +108,7 @@ func TestGetMigrationSummary_IsPairedFromLiveInfo(t *testing.T) { t.Run("with margeAccountUUID", func(t *testing.T) { m, host, cleanup := telnetSummaryEnvWithInfo(t, nil, ft, - `Test3230304`, + `Test1000001`, ) defer cleanup() @@ -121,8 +121,8 @@ func TestGetMigrationSummary_IsPairedFromLiveInfo(t *testing.T) { t.Errorf("IsPaired = false, want true (margeAccountUUID present in :8090/info)") } - if summary.AccountID != "3230304" { - t.Errorf("AccountID = %q, want 3230304 (live info should populate)", summary.AccountID) + if summary.AccountID != "1000001" { + t.Errorf("AccountID = %q, want 1000001 (live info should populate)", summary.AccountID) } }) diff --git a/pkg/service/setup/peer_probe_test.go b/pkg/service/setup/peer_probe_test.go index 4ceb54f..450edb3 100644 --- a/pkg/service/setup/peer_probe_test.go +++ b/pkg/service/setup/peer_probe_test.go @@ -68,10 +68,10 @@ func TestRunPeerReachabilityProbe_HappyPath(t *testing.T) { // On nudge, simulate the device fanning out to /updates/soundtouch // which the middleware would signal as a hit on this IP. m := peerProbeManager(func() { - obs.signal("192.168.1.42", PeerHit{Path: "/updates/soundtouch", At: time.Now()}) + obs.signal("192.0.2.42", PeerHit{Path: "/updates/soundtouch", At: time.Now()}) }) - result, err := m.RunPeerReachabilityProbe("192.168.1.42", obs, 2*time.Second) + result, err := m.RunPeerReachabilityProbe("192.0.2.42", obs, 2*time.Second) if err != nil { t.Fatalf("RunPeerReachabilityProbe error: %v", err) } @@ -81,7 +81,7 @@ func TestRunPeerReachabilityProbe_HappyPath(t *testing.T) { if result.ObservedPath != "/updates/soundtouch" { t.Errorf("ObservedPath = %q, want %q", result.ObservedPath, "/updates/soundtouch") } - if len(obs.forgotten) != 1 || obs.forgotten[0] != "192.168.1.42" { + if len(obs.forgotten) != 1 || obs.forgotten[0] != "192.0.2.42" { t.Errorf("Forget not called for IP: forgotten = %v", obs.forgotten) } } @@ -91,7 +91,7 @@ func TestRunPeerReachabilityProbe_Timeout(t *testing.T) { m := peerProbeManager(nil) // nudge fires but device never responds start := time.Now() - result, err := m.RunPeerReachabilityProbe("192.168.1.42", obs, 200*time.Millisecond) + result, err := m.RunPeerReachabilityProbe("192.0.2.42", obs, 200*time.Millisecond) elapsed := time.Since(start) if err != nil { @@ -110,7 +110,7 @@ func TestRunPeerReachabilityProbe_Timeout(t *testing.T) { func TestRunPeerReachabilityProbe_NilObserver(t *testing.T) { m := peerProbeManager(nil) - _, err := m.RunPeerReachabilityProbe("192.168.1.42", nil, time.Second) + _, err := m.RunPeerReachabilityProbe("192.0.2.42", nil, time.Second) if err == nil { t.Error("expected error for nil observer, got nil") } @@ -132,7 +132,7 @@ func TestRunPeerReachabilityProbe_NilHTTPGetTimesOut(t *testing.T) { m := &Manager{} // HTTPGet nil obs := newFakePeerObserver() - result, err := m.RunPeerReachabilityProbe("192.168.1.42", obs, 100*time.Millisecond) + result, err := m.RunPeerReachabilityProbe("192.0.2.42", obs, 100*time.Millisecond) if err != nil { t.Fatalf("error: %v", err) } diff --git a/pkg/service/setup/setup_test.go b/pkg/service/setup/setup_test.go index c1a0142..054de86 100644 --- a/pkg/service/setup/setup_test.go +++ b/pkg/service/setup/setup_test.go @@ -144,7 +144,7 @@ func TestMigrateViaHosts(t *testing.T) { t.Fatalf("Failed to ensure CA: %v", err) } - m := NewManager("http://192.168.1.100:8000", nil, cm) + m := NewManager("http://192.0.2.100:8000", nil, cm) runCalls := []string{} m.NewSSH = func(host string) SSHClient { @@ -154,7 +154,7 @@ func TestMigrateViaHosts(t *testing.T) { if command == "cat /etc/hosts" { // Handle both initial read and verification read if len(runCalls) > 2 { // Rough heuristic: verification happens after upload - return "192.168.1.100\tstreaming.bose.com\n192.168.1.100\tupdates.bose.com\n192.168.1.100\tstats.bose.com\n192.168.1.100\tbmx.bose.com\n192.168.1.100\tcontent.api.bose.io\n192.168.1.100\tevents.api.bosecm.com\n192.168.1.100\tbose-prod.apigee.net\n192.168.1.100\tworldwide.bose.com\n192.168.1.100\tmedia.bose.io\n192.168.1.100\tdownloads.bose.com\n192.168.1.100\tvoice.api.bose.io", nil + return "192.0.2.100\tstreaming.bose.com\n192.0.2.100\tupdates.bose.com\n192.0.2.100\tstats.bose.com\n192.0.2.100\tbmx.bose.com\n192.0.2.100\tcontent.api.bose.io\n192.0.2.100\tevents.api.bosecm.com\n192.0.2.100\tbose-prod.apigee.net\n192.0.2.100\tworldwide.bose.com\n192.0.2.100\tmedia.bose.io\n192.0.2.100\tdownloads.bose.com\n192.0.2.100\tvoice.api.bose.io", nil } return "127.0.0.1 localhost", nil } @@ -168,7 +168,7 @@ func TestMigrateViaHosts(t *testing.T) { }, uploadContentFunc: func(content []byte, remotePath string) error { if remotePath == "/etc/hosts" { - if !strings.Contains(string(content), "192.168.1.100\tstreaming.bose.com") { + if !strings.Contains(string(content), "192.0.2.100\tstreaming.bose.com") { t.Errorf("Expected hosts content to contain redirect, got %s", string(content)) } } @@ -177,7 +177,7 @@ func TestMigrateViaHosts(t *testing.T) { } } - _, err = m.migrateViaHosts("192.168.1.10", "http://192.168.1.100:8000") + _, err = m.migrateViaHosts("192.0.2.10", "http://192.0.2.100:8000") if err != nil { t.Fatalf("migrateViaHosts failed: %v", err) } @@ -223,7 +223,7 @@ func TestMigrateViaHosts_UpdateExisting(t *testing.T) { cm := certmanager.NewCertificateManager(filepath.Join(tempDir, "certs")) _ = cm.EnsureCA() - m := NewManager("http://192.168.1.100:8000", nil, cm) + m := NewManager("http://192.0.2.100:8000", nil, cm) m.NewSSH = func(host string) SSHClient { runCount := 0 @@ -232,7 +232,7 @@ func TestMigrateViaHosts_UpdateExisting(t *testing.T) { runCount++ if command == "cat /etc/hosts" { if runCount > 1 { - return "127.0.0.1 localhost\n192.168.1.100\tstreaming.bose.com\n192.168.1.100\tupdates.bose.com\n192.168.1.100\tstats.bose.com\n192.168.1.100\tbmx.bose.com\n192.168.1.100\tcontent.api.bose.io\n192.168.1.100\tevents.api.bosecm.com\n192.168.1.100\tbose-prod.apigee.net\n192.168.1.100\tworldwide.bose.com\n192.168.1.100\tmedia.bose.io\n192.168.1.100\tdownloads.bose.com\n192.168.1.100\tvoice.api.bose.io", nil + return "127.0.0.1 localhost\n192.0.2.100\tstreaming.bose.com\n192.0.2.100\tupdates.bose.com\n192.0.2.100\tstats.bose.com\n192.0.2.100\tbmx.bose.com\n192.0.2.100\tcontent.api.bose.io\n192.0.2.100\tevents.api.bosecm.com\n192.0.2.100\tbose-prod.apigee.net\n192.0.2.100\tworldwide.bose.com\n192.0.2.100\tmedia.bose.io\n192.0.2.100\tdownloads.bose.com\n192.0.2.100\tvoice.api.bose.io", nil } return "127.0.0.1 localhost\n1.2.3.4\tstreaming.bose.com\n1.2.3.4\tupdates.bose.com", nil } @@ -247,13 +247,13 @@ func TestMigrateViaHosts_UpdateExisting(t *testing.T) { uploadContentFunc: func(content []byte, remotePath string) error { if remotePath == "/etc/hosts" { c := string(content) - if !strings.Contains(c, "192.168.1.100\tstreaming.bose.com") { + if !strings.Contains(c, "192.0.2.100\tstreaming.bose.com") { t.Errorf("Expected updated IP for streaming.bose.com, got:\n%s", c) } - if !strings.Contains(c, "192.168.1.100\tupdates.bose.com") { + if !strings.Contains(c, "192.0.2.100\tupdates.bose.com") { t.Errorf("Expected updated IP for updates.bose.com, got:\n%s", c) } - if !strings.Contains(c, "192.168.1.100\tevents.api.bosecm.com") { + if !strings.Contains(c, "192.0.2.100\tevents.api.bosecm.com") { t.Errorf("Expected new domain events.api.bosecm.com, got:\n%s", c) } // Ensure no duplicates @@ -266,7 +266,7 @@ func TestMigrateViaHosts_UpdateExisting(t *testing.T) { } } - _, err = m.migrateViaHosts("192.168.1.10", "http://192.168.1.100:8000") + _, err = m.migrateViaHosts("192.0.2.10", "http://192.0.2.100:8000") if err != nil { t.Fatalf("migrateViaHosts failed: %v", err) } @@ -407,7 +407,7 @@ func TestCheckCACertTrusted(t *testing.T) { } summary := &MigrationSummary{} - m.checkCACertTrusted(summary, "192.168.1.10") + m.checkCACertTrusted(summary, "192.0.2.10") if !summary.CACertTrusted { t.Errorf("Expected CACertTrusted to be true when label is found") } @@ -429,7 +429,7 @@ func TestCheckCACertTrusted(t *testing.T) { } summary = &MigrationSummary{} - m.checkCACertTrusted(summary, "192.168.1.10") + m.checkCACertTrusted(summary, "192.0.2.10") if !summary.CACertTrusted { t.Errorf("Expected CACertTrusted to be true when cert data is found") } @@ -447,7 +447,7 @@ func TestCheckCACertTrusted(t *testing.T) { } summary = &MigrationSummary{} - m.checkCACertTrusted(summary, "192.168.1.10") + m.checkCACertTrusted(summary, "192.0.2.10") if summary.CACertTrusted { t.Errorf("Expected CACertTrusted to be false when nothing is found") } @@ -486,7 +486,7 @@ func TestTestConnection(t *testing.T) { } // Test 1: Shared trust store (no explicit CA) - output, err := m.TestConnection("192.168.1.10", "https://localhost:8443/health", false) + output, err := m.TestConnection("192.0.2.10", "https://localhost:8443/health", false) if err != nil { t.Fatalf("TestConnection failed: %v", err) } @@ -498,7 +498,7 @@ func TestTestConnection(t *testing.T) { } // Test 2: Explicit CA - output, err = m.TestConnection("192.168.1.10", "https://localhost:8443/health", true) + output, err = m.TestConnection("192.0.2.10", "https://localhost:8443/health", true) if err != nil { t.Fatalf("TestConnection failed: %v", err) } @@ -585,7 +585,7 @@ func TestTestHostsRedirection(t *testing.T) { return mock } - output, err := m.TestHostsRedirection("192.168.1.10", "http://1.2.3.4:8000") + output, err := m.TestHostsRedirection("192.0.2.10", "http://1.2.3.4:8000") if err != nil { t.Fatalf("TestHostsRedirection failed: %v", err) } @@ -761,7 +761,7 @@ func TestMigrateViaHosts_SkipCAIfTrusted(t *testing.T) { t.Fatalf("Failed to ensure CA: %v", err) } - m := NewManager("http://192.168.1.100:8000", nil, cm) + m := NewManager("http://192.0.2.100:8000", nil, cm) runCalls := []string{} m.NewSSH = func(host string) SSHClient { @@ -771,7 +771,7 @@ func TestMigrateViaHosts_SkipCAIfTrusted(t *testing.T) { if command == "cat /etc/hosts" { // Handle both initial read and verification read if len(runCalls) > 2 { // Rough heuristic: verification happens after upload - return "192.168.1.100\tstreaming.bose.com\n192.168.1.100\tupdates.bose.com\n192.168.1.100\tstats.bose.com\n192.168.1.100\tbmx.bose.com\n192.168.1.100\tcontent.api.bose.io\n192.168.1.100\tevents.api.bosecm.com\n192.168.1.100\tbose-prod.apigee.net\n192.168.1.100\tworldwide.bose.com\n192.168.1.100\tmedia.bose.io\n192.168.1.100\tdownloads.bose.com\n192.168.1.100\tvoice.api.bose.io", nil + return "192.0.2.100\tstreaming.bose.com\n192.0.2.100\tupdates.bose.com\n192.0.2.100\tstats.bose.com\n192.0.2.100\tbmx.bose.com\n192.0.2.100\tcontent.api.bose.io\n192.0.2.100\tevents.api.bosecm.com\n192.0.2.100\tbose-prod.apigee.net\n192.0.2.100\tworldwide.bose.com\n192.0.2.100\tmedia.bose.io\n192.0.2.100\tdownloads.bose.com\n192.0.2.100\tvoice.api.bose.io", nil } return "127.0.0.1 localhost", nil } @@ -784,7 +784,7 @@ func TestMigrateViaHosts_SkipCAIfTrusted(t *testing.T) { } } - _, err = m.migrateViaHosts("192.168.1.10", "http://192.168.1.100:8000") + _, err = m.migrateViaHosts("192.0.2.10", "http://192.0.2.100:8000") if err != nil { t.Fatalf("migrateViaHosts failed: %v", err) } @@ -838,7 +838,7 @@ func TestTrustCACert(t *testing.T) { } } - _, err = m.TrustCACert("192.168.1.10") + _, err = m.TrustCACert("192.0.2.10") if err != nil { t.Fatalf("TrustCACert failed: %v", err) } @@ -967,7 +967,7 @@ func TestTrustCACert_StripsMultipleStaleEntriesSilently(t *testing.T) { return sshMock } - logs, err := m.TrustCACert("192.168.1.10") + logs, err := m.TrustCACert("192.0.2.10") if err != nil { t.Fatalf("TrustCACert failed: %v", err) } @@ -1084,7 +1084,7 @@ func TestTrustCACert_PostUploadVerificationFailureCleansUpTmp(t *testing.T) { return sshMock } - _, err = m.TrustCACert("192.168.1.10") + _, err = m.TrustCACert("192.0.2.10") if err == nil { t.Fatalf("TrustCACert succeeded, want a verification failure") } @@ -1149,7 +1149,7 @@ func TestRevertMigration(t *testing.T) { } } - _, err := m.RevertMigration("192.168.1.10") + _, err := m.RevertMigration("192.0.2.10") if err != nil { t.Fatalf("RevertMigration failed: %v", err) } @@ -1262,7 +1262,7 @@ func TestRevertMigration_CorruptedRcLocal(t *testing.T) { } } - _, err := m.RevertMigration("192.168.1.10") + _, err := m.RevertMigration("192.0.2.10") if err != nil { t.Fatalf("RevertMigration failed: %v", err) } @@ -1293,7 +1293,7 @@ func TestRevertMigration_NoBackup(t *testing.T) { } } - _, err := m.RevertMigration("192.168.1.10") + _, err := m.RevertMigration("192.0.2.10") if err == nil { t.Errorf("Expected error when backup is missing, got nil") } else if !strings.Contains(err.Error(), "backup") { @@ -1314,7 +1314,7 @@ func TestReboot(t *testing.T) { } } - _, err := m.Reboot("192.168.1.10", "") + _, err := m.Reboot("192.0.2.10", "") if err != nil { t.Fatalf("Reboot failed: %v", err) } @@ -1332,7 +1332,7 @@ func TestReboot(t *testing.T) { } func TestTestDNSRedirection(t *testing.T) { - m := NewManager("http://192.168.1.100:8000", nil, nil) + m := NewManager("http://192.0.2.100:8000", nil, nil) runCalls := []string{} m.NewSSH = func(host string) SSHClient { @@ -1344,29 +1344,29 @@ func TestTestDNSRedirection(t *testing.T) { if !strings.Contains(command, "\\x00\\x21") { return "", fmt.Errorf("missing TCP length prefix in nc command") } - // Mock od output: " 192 168 1 100" - return " 192 168 1 100", nil + // Mock od output: " 192 0 2 100" + return " 192 0 2 100", nil } - if strings.HasPrefix(command, "nslookup aftertouch.test 192.168.1.100") { - return "Server: 192.168.1.100\nAddress 1: 192.168.1.100\n\nName: aftertouch.test\nAddress 1: 192.168.1.100", nil + if strings.HasPrefix(command, "nslookup aftertouch.test 192.0.2.100") { + return "Server: 192.0.2.100\nAddress 1: 192.0.2.100\n\nName: aftertouch.test\nAddress 1: 192.0.2.100", nil } return "", nil }, } } - output, err := m.TestDNSRedirection("192.168.1.10", "http://192.168.1.100:8000") + output, err := m.TestDNSRedirection("192.0.2.10", "http://192.0.2.100:8000") if err != nil { t.Fatalf("TestDNSRedirection failed: %v", err) } - if !strings.Contains(output, "192.168.1.100") { + if !strings.Contains(output, "192.0.2.100") { t.Errorf("Expected output to contain service IP, got %s", output) } foundNc := false for _, call := range runCalls { - if strings.Contains(call, "nc") && !strings.Contains(call, "-u") && strings.Contains(call, "192.168.1.100 53") { + if strings.Contains(call, "nc") && !strings.Contains(call, "-u") && strings.Contains(call, "192.0.2.100 53") { foundNc = true break } @@ -1389,7 +1389,7 @@ func TestTestDNSRedirection_CustomPort(t *testing.T) { DNSBindAddr: ":1053", }) - m := NewManager("http://192.168.1.100:8000", ds, nil) + m := NewManager("http://192.0.2.100:8000", ds, nil) runCalls := []string{} m.NewSSH = func(host string) SSHClient { @@ -1401,25 +1401,25 @@ func TestTestDNSRedirection_CustomPort(t *testing.T) { if !strings.Contains(command, "\\x00\\x21") { return "", fmt.Errorf("missing TCP length prefix in nc command") } - return " 192 168 1 100", nil + return " 192 0 2 100", nil } return "", nil }, } } - output, err := m.TestDNSRedirection("192.168.1.10", "http://192.168.1.100:8000") + output, err := m.TestDNSRedirection("192.0.2.10", "http://192.0.2.100:8000") if err != nil { t.Fatalf("TestDNSRedirection failed: %v", err) } - if !strings.Contains(output, "192.168.1.100") { + if !strings.Contains(output, "192.0.2.100") { t.Errorf("Expected output to contain service IP, got %s", output) } foundNc := false for _, call := range runCalls { - if strings.Contains(call, "nc") && !strings.Contains(call, "-u") && strings.Contains(call, "192.168.1.100 1053") { + if strings.Contains(call, "nc") && !strings.Contains(call, "-u") && strings.Contains(call, "192.0.2.100 1053") { foundNc = true break } @@ -1442,7 +1442,7 @@ func TestBackupConfigOffDevice(t *testing.T) { m := NewManager("http://localhost:8000", ds, nil) serial := "08DF1F0BA325" - accountID := "3230304" + accountID := "1000001" // Mock info server infoServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -1462,7 +1462,7 @@ func TestBackupConfigOffDevice(t *testing.T) { return "http://original", nil } if strings.Contains(command, "/etc/hosts") { - return "127.0.0.1 localhost\n192.168.1.1 bmx.bose.com", nil + return "127.0.0.1 localhost\n192.0.2.1 bmx.bose.com", nil } return "", nil }, @@ -1512,7 +1512,7 @@ func TestMigrateSpeaker_PreFlightFailure(t *testing.T) { } } - _, err := m.MigrateSpeaker("192.168.1.10", "", "", nil, MigrationMethodXML) + _, err := m.MigrateSpeaker("192.0.2.10", "", "", nil, MigrationMethodXML) if err == nil { t.Errorf("Expected error during pre-flight write check, got nil") } @@ -1533,7 +1533,7 @@ func TestMigrateViaResolvConf(t *testing.T) { t.Fatalf("Failed to ensure CA: %v", err) } - m := NewManager("http://192.168.1.100:8000", nil, cm) + m := NewManager("http://192.0.2.100:8000", nil, cm) runCalls := []string{} uploads := make(map[string]string) @@ -1560,13 +1560,13 @@ func TestMigrateViaResolvConf(t *testing.T) { } } - _, err = m.migrateViaResolvConf("192.168.1.10", "http://192.168.1.100:8000") + _, err = m.migrateViaResolvConf("192.0.2.10", "http://192.0.2.100:8000") if err != nil { t.Fatalf("migrateViaResolvConf failed: %v", err) } // Verify uploads - if !strings.Contains(uploads["/mnt/nv/soundtouch-service/aftertouch.resolv.conf"], "nameserver 192.168.1.100") { + if !strings.Contains(uploads["/mnt/nv/soundtouch-service/aftertouch.resolv.conf"], "nameserver 192.0.2.100") { t.Errorf("aftertouch.resolv.conf missing nameserver") } @@ -1599,7 +1599,7 @@ func TestMigrateViaResolvConf_CorruptedRcLocal(t *testing.T) { t.Fatalf("Failed to ensure CA: %v", err) } - m := NewManager("http://192.168.1.100:8000", nil, cm) + m := NewManager("http://192.0.2.100:8000", nil, cm) uploads := make(map[string]string) @@ -1625,7 +1625,7 @@ func TestMigrateViaResolvConf_CorruptedRcLocal(t *testing.T) { } } - _, err = m.migrateViaResolvConf("192.168.1.10", "http://192.168.1.100:8000") + _, err = m.migrateViaResolvConf("192.0.2.10", "http://192.0.2.100:8000") if err != nil { t.Fatalf("migrateViaResolvConf failed: %v", err) } @@ -1655,7 +1655,7 @@ func TestMigrateViaResolvConf_UdhcpcScript(t *testing.T) { t.Fatalf("Failed to ensure CA: %v", err) } - m := NewManager("http://192.168.1.100:8000", nil, cm) + m := NewManager("http://192.0.2.100:8000", nil, cm) runCalls := []string{} uploads := make(map[string]string) @@ -1687,7 +1687,7 @@ func TestMigrateViaResolvConf_UdhcpcScript(t *testing.T) { } } - _, err = m.migrateViaResolvConf("192.168.1.10", "http://192.168.1.100:8000") + _, err = m.migrateViaResolvConf("192.0.2.10", "http://192.0.2.100:8000") if err != nil { t.Fatalf("migrateViaResolvConf failed: %v", err) } @@ -1725,7 +1725,7 @@ func TestRevertMigration_ResolvConf(t *testing.T) { } defer os.RemoveAll(tempDir) - m := NewManager("http://192.168.1.100:8000", nil, nil) + m := NewManager("http://192.0.2.100:8000", nil, nil) runCalls := []string{} uploads := make(map[string]string) @@ -1754,7 +1754,7 @@ func TestRevertMigration_ResolvConf(t *testing.T) { } } - _, err = m.RevertMigration("192.168.1.10") + _, err = m.RevertMigration("192.0.2.10") if err != nil { t.Fatalf("RevertMigration failed: %v", err) } @@ -1843,7 +1843,7 @@ func TestCheckIsMigrated(t *testing.T) { summary := &MigrationSummary{ SSHSuccess: true, CACertTrusted: true, - CurrentResolvConf: "# Priority nameserver for Bose service redirection\nnameserver 192.168.1.1\n", + CurrentResolvConf: "# Priority nameserver for Bose service redirection\nnameserver 192.0.2.1\n", } m.checkIsMigrated(summary, "127.0.0.1") if !summary.IsMigrated { @@ -1946,7 +1946,7 @@ func TestMigrateSpeaker_ResolvBlocking(t *testing.T) { ds := datastore.NewDataStore(tempDir) cm := certmanager.NewCertificateManager(filepath.Join(tempDir, "certs")) - m := NewManager("http://192.168.1.100:8000", ds, cm) + m := NewManager("http://192.0.2.100:8000", ds, cm) m.NewSSH = func(host string) SSHClient { return &mockSSH{ diff --git a/pkg/service/setup/sync_deviceid_test.go b/pkg/service/setup/sync_deviceid_test.go index 29f6834..9ec7d2a 100644 --- a/pkg/service/setup/sync_deviceid_test.go +++ b/pkg/service/setup/sync_deviceid_test.go @@ -24,7 +24,7 @@ func TestSyncDeviceData_UsesDeviceID(t *testing.T) { // Return device info with MAC address as deviceID w.Header().Set("Content-Type", "application/xml") fmt.Fprint(w, ` - + Test Device SoundTouch 30 test-account-123 @@ -36,20 +36,20 @@ func TestSyncDeviceData_UsesDeviceID(t *testing.T) { - A81B6A536A98 - 192.168.1.100 + AABBCCDDEEFF + 192.0.2.100 `) case "/presets": // Return empty presets for simplicity w.Header().Set("Content-Type", "application/xml") fmt.Fprint(w, ` -`) +`) case "/recents": // Return empty recents for simplicity w.Header().Set("Content-Type", "application/xml") fmt.Fprint(w, ` -`) +`) default: http.NotFound(w, r) } @@ -70,7 +70,7 @@ func TestSyncDeviceData_UsesDeviceID(t *testing.T) { } // Verify that data was synced to the correct directory using MAC address (deviceID) - expectedDeviceID := "A81B6A536A98" + expectedDeviceID := "AABBCCDDEEFF" expectedAccountID := "test-account-123" // Check that the device directory is resolved correctly using MAC address @@ -151,7 +151,7 @@ func TestSyncDeviceData_FallbackToExistingDeviceMapping(t *testing.T) { // Pre-populate device data using serial number (legacy scenario) accountID := "test-account-123" serialNumber := "I6332527703739342000020" - macAddress := "A81B6A536A98" + macAddress := "AABBCCDDEEFF" // Save device info under serial number (simulating legacy behavior) legacyDeviceInfo := &models.ServiceDeviceInfo{ @@ -207,11 +207,11 @@ func TestSyncDeviceData_FallbackToExistingDeviceMapping(t *testing.T) { case "/presets": w.Header().Set("Content-Type", "application/xml") fmt.Fprint(w, ` -`) +`) case "/recents": w.Header().Set("Content-Type", "application/xml") fmt.Fprint(w, ` -`) +`) } })) defer server.Close() diff --git a/pkg/service/setup/wifi_provision_test.go b/pkg/service/setup/wifi_provision_test.go index 4dbe66e..3b16b46 100644 --- a/pkg/service/setup/wifi_provision_test.go +++ b/pkg/service/setup/wifi_provision_test.go @@ -211,8 +211,8 @@ func TestWaitForOnline_MatchesSubstringInNameOrSerial(t *testing.T) { results: [][]*models.DiscoveredDevice{ nil, // first poll: nothing yet { - {Name: "Other Bose Speaker", SerialNo: "AAAAAAAAAAAA", Host: "192.168.1.50"}, - {Name: "Bose SoundTouch DE4803", SerialNo: "506583DE4803", Host: "192.168.1.42"}, + {Name: "Other Bose Speaker", SerialNo: "AAAAAAAAAAAA", Host: "192.0.2.50"}, + {Name: "Bose SoundTouch DE4803", SerialNo: "506583DE4803", Host: "192.0.2.42"}, }, }, } @@ -224,8 +224,8 @@ func TestWaitForOnline_MatchesSubstringInNameOrSerial(t *testing.T) { t.Fatalf("WaitForOnline: %v", err) } - if d.Host != "192.168.1.42" { - t.Errorf("Host = %q, want 192.168.1.42", d.Host) + if d.Host != "192.0.2.42" { + t.Errorf("Host = %q, want 192.0.2.42", d.Host) } } @@ -233,7 +233,7 @@ func TestWaitForOnline_EmptyMatcherReturnsFirst(t *testing.T) { stub := &stubMDNS{ results: [][]*models.DiscoveredDevice{ { - {Name: "Bose SoundTouch DE4803", Host: "192.168.1.42"}, + {Name: "Bose SoundTouch DE4803", Host: "192.0.2.42"}, }, }, } @@ -245,17 +245,17 @@ func TestWaitForOnline_EmptyMatcherReturnsFirst(t *testing.T) { t.Fatalf("WaitForOnline: %v", err) } - if d.Host != "192.168.1.42" { - t.Errorf("Host = %q, want 192.168.1.42", d.Host) + if d.Host != "192.0.2.42" { + t.Errorf("Host = %q, want 192.0.2.42", d.Host) } } func TestWaitForOnline_TimesOutWhenNoMatch(t *testing.T) { stub := &stubMDNS{ results: [][]*models.DiscoveredDevice{ - {{Name: "Wrong One", SerialNo: "X", Host: "192.168.1.99"}}, - {{Name: "Wrong One", SerialNo: "X", Host: "192.168.1.99"}}, - {{Name: "Wrong One", SerialNo: "X", Host: "192.168.1.99"}}, + {{Name: "Wrong One", SerialNo: "X", Host: "192.0.2.99"}}, + {{Name: "Wrong One", SerialNo: "X", Host: "192.0.2.99"}}, + {{Name: "Wrong One", SerialNo: "X", Host: "192.0.2.99"}}, }, } diff --git a/pkg/service/stockholm/bridge_test.go b/pkg/service/stockholm/bridge_test.go index c2e6932..50bf8d3 100644 --- a/pkg/service/stockholm/bridge_test.go +++ b/pkg/service/stockholm/bridge_test.go @@ -125,8 +125,8 @@ func TestBridge_DeviceDiscovery_CumulativeList(t *testing.T) { // Simulate what runDeviceDiscovery now does: build a cumulative slice and // enqueue it with every new device. - d1 := RendererDevice{UID: "AABBCC112233", IP: "192.168.1.10"} - d2 := RendererDevice{UID: "DDEEFF445566", IP: "192.168.1.11"} + d1 := RendererDevice{UID: "AABBCC112233", IP: "192.0.2.10"} + d2 := RendererDevice{UID: "DDEEFF445566", IP: "192.0.2.11"} var seen []RendererDevice for _, d := range []RendererDevice{d1, d2} { diff --git a/pkg/service/zeroconf/zeroconf_test.go b/pkg/service/zeroconf/zeroconf_test.go index cec4834..44772a4 100644 --- a/pkg/service/zeroconf/zeroconf_test.go +++ b/pkg/service/zeroconf/zeroconf_test.go @@ -324,19 +324,24 @@ func TestValidateZcBaseURL(t *testing.T) { }{ {"loopback", "http://127.0.0.1:8200/zc", true, "127.0.0.1:8200", "/zc"}, {"loopback no port", "http://127.0.0.1/zc", true, "127.0.0.1", "/zc"}, - {"private 192", "http://192.168.1.10:8200/zc", true, "192.168.1.10:8200", "/zc"}, + // The "private 192" and "strips query" cases must use an + // RFC-1918 192.168/16 value — validateZcBaseURL only accepts + // loopback, RFC-1918, and link-local. RFC-5737 doc IPs + // (which we use as placeholders elsewhere) would be rejected + // here, so the test uses a generic-but-real 192.168 value. + {"private 192", "http://192.168.10.10:8200/zc", true, "192.168.10.10:8200", "/zc"}, {"private 10", "http://10.0.0.5/zc", true, "10.0.0.5", "/zc"}, {"private 172", "http://172.16.0.1/zc", true, "172.16.0.1", "/zc"}, {"link-local v4", "http://169.254.10.20/zc", true, "169.254.10.20", "/zc"}, {"ipv6 loopback", "http://[::1]:8200/zc", true, "[::1]:8200", "/zc"}, {"ipv6 link-local", "http://[fe80::1]:8200/zc", true, "[fe80::1]:8200", "/zc"}, - {"strips query", "http://192.168.1.10:8200/zc?foo=bar", true, "192.168.1.10:8200", "/zc"}, + {"strips query", "http://192.168.10.10:8200/zc?foo=bar", true, "192.168.10.10:8200", "/zc"}, {"public IP rejected", "http://1.1.1.1/zc", false, "", ""}, {"public ipv6 rejected", "http://[2001:db8::1]/zc", false, "", ""}, {"hostname rejected", "http://myspeaker.local/zc", false, "", ""}, {"plain hostname rejected", "http://speaker/zc", false, "", ""}, - {"ftp scheme rejected", "ftp://192.168.1.10/zc", false, "", ""}, + {"ftp scheme rejected", "ftp://192.0.2.10/zc", false, "", ""}, {"file scheme rejected", "file:///etc/passwd", false, "", ""}, {"empty host rejected", "http:///zc", false, "", ""}, {"unparseable rejected", "::not a url::", false, "", ""}, diff --git a/pkg/ssh/ssh_test.go b/pkg/ssh/ssh_test.go index 49a1e51..d315e82 100644 --- a/pkg/ssh/ssh_test.go +++ b/pkg/ssh/ssh_test.go @@ -6,7 +6,7 @@ import ( ) func TestNewClient(t *testing.T) { - host := "192.168.1.10" + host := "192.0.2.10" client := NewClient(host) if client.Host != host { diff --git a/pkg/telnet/telnet_test.go b/pkg/telnet/telnet_test.go index 7985d98..ff7efaf 100644 --- a/pkg/telnet/telnet_test.go +++ b/pkg/telnet/telnet_test.go @@ -158,9 +158,9 @@ func newClientFor(t *testing.T, s *scriptedServer) *Client { } func TestNewClient_Defaults(t *testing.T) { - c := NewClient("192.168.1.10") - if c.Host != "192.168.1.10" { - t.Errorf("Host = %q, want 192.168.1.10", c.Host) + c := NewClient("192.0.2.10") + if c.Host != "192.0.2.10" { + t.Errorf("Host = %q, want 192.0.2.10", c.Host) } if c.Port != DefaultPort { diff --git a/tests/integration/http-client/get_account_devices.http b/tests/integration/http-client/get_account_devices.http index 920d677..925d403 100644 --- a/tests/integration/http-client/get_account_devices.http +++ b/tests/integration/http-client/get_account_devices.http @@ -22,7 +22,7 @@ Authorization: Bearer dummy-token const expectedDeviceId = "B05ECAFE"; const expectedName = "SoundTouch-11"; - const expectedIp = "192.168.1.100"; + const expectedIp = "192.0.2.100"; const device = deviceList.item(0); client.assert(device.getAttribute("deviceid") === expectedDeviceId, "Wrong device ID"); diff --git a/tests/integration/http-client/rename_device.http b/tests/integration/http-client/rename_device.http index 051b2ad..8f5223c 100644 --- a/tests/integration/http-client/rename_device.http +++ b/tests/integration/http-client/rename_device.http @@ -7,7 +7,7 @@ ### in a loop and the Bose App showed the rename spinning forever. ### This test runs after register_device.http (which creates the ### initial record) and after power_on.http (which seeds the IP at -### 192.168.1.100). The rename PUT must: +### 192.0.2.100). The rename PUT must: ### ### - return 200 OK ### - echo the new name @@ -54,7 +54,7 @@ Authorization: Bearer {{token}} // register_device.http captured on the initial POST. If it // doesn't, the rename PUT regressed the "first-paired in // 2017" semantics — the exact bug behind the parity capture - // at data/parity_mismatches/1771797308__streaming_account_3230304_device_A81B6A536A98.json. + // at data/parity_mismatches/1771797308__streaming_account_1000001_device_AABBCCDDEEFF.json. const initial = client.global.get("initialCreatedOn"); client.assert(initial !== undefined && initial.length > 0, "initialCreatedOn was not captured by register_device.http — test ordering issue");