mirror of
https://github.com/gesellix/Bose-SoundTouch.git
synced 2026-08-19 09:06:14 +00:00
Add `soundtouch-cli setup` subcommand group covering the full reset →
re-provision → pair lifecycle as a scriptable alternative to the web UI:
inspect, verify, plan, factory-reset, wait-ap, wifi-push, wait-online,
ssh-check, install-ca, migrate, reboot, pair (bare | full state machine)
Supporting library code lives in pkg/service/setup: factory_reset.go,
wifi_provision.go, inspect.go, init_plan.go, setup_session.go.
Confirmed against ST10 firmware 27.0.6 that bare setMargeAccount over
WebSocket — no SETUP_START/SETUP_ENTER/SETUP_LEAVE bracket — is
sufficient to pair a factory-reset speaker; the firmware materializes
SystemConfigurationDB.xml and Sources.xml itself and the pairing
survives reboot. Result and field-by-field SystemConfigurationDB
comparison documented in docs/analysis/SETUP-WEBSOCKET-EXPERIMENT.md.
Captures the device's pre-reset DELETE-to-marge plus its LAN peer
notification flow in docs/analysis/FACTORY-RESET-PROTOCOL.md.
Perf: batch GetMigrationSummary's SSH probes into one Run() call via
ssh_probe.go / ssh_probe_apply.go — was ~8 sequential dials at
500-1000 ms each on FW 27 crypto, now one round-trip. Same data shape,
same MigrationSummary fields populated.
Fixes /clockTime and /clockDisplay wire formats — firmware 27 rejects
the legacy flat XML ("Error parsing request"). ClockTimeRequest now
uses utcTime attribute; ClockDisplayRequest emits the nested
<clockConfig> envelope with timezoneInfo/timeFormat/brightnessLevel.
Removes cmd/example-init-speaker (superseded by setup pair).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
69 lines
1.6 KiB
Go
69 lines
1.6 KiB
Go
package setup
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestBuildServerHTTPSURL_PortResolution(t *testing.T) {
|
|
// HTTPS_PORT must be unset for the env-var path tests to be
|
|
// meaningful. t.Setenv("HTTPS_PORT", "") clears it for the duration
|
|
// of each subtest.
|
|
|
|
tests := []struct {
|
|
name string
|
|
targetURL string
|
|
envHTTPSPort string
|
|
want string
|
|
}{
|
|
{
|
|
name: "https with explicit port wins over HTTPS_PORT env",
|
|
targetURL: "https://soundtouch.fritz.box:443",
|
|
envHTTPSPort: "8443",
|
|
want: "https://soundtouch.fritz.box:443/health",
|
|
},
|
|
{
|
|
name: "https without explicit port uses 443",
|
|
targetURL: "https://soundtouch.fritz.box",
|
|
want: "https://soundtouch.fritz.box:443/health",
|
|
},
|
|
{
|
|
name: "http URL falls back to HTTPS_PORT env var",
|
|
targetURL: "http://aftertouch.local:8000",
|
|
envHTTPSPort: "9443",
|
|
want: "https://aftertouch.local:9443/health",
|
|
},
|
|
{
|
|
name: "http URL with no env var defaults to 8443",
|
|
targetURL: "http://aftertouch.local:8000",
|
|
want: "https://aftertouch.local:8443/health",
|
|
},
|
|
{
|
|
name: "invalid URL returns empty",
|
|
targetURL: "::not-a-url",
|
|
want: "",
|
|
},
|
|
{
|
|
name: "URL with no hostname returns empty",
|
|
targetURL: "http://",
|
|
want: "",
|
|
},
|
|
}
|
|
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
if tc.envHTTPSPort != "" {
|
|
t.Setenv("HTTPS_PORT", tc.envHTTPSPort)
|
|
} else {
|
|
t.Setenv("HTTPS_PORT", "")
|
|
}
|
|
|
|
m := &Manager{}
|
|
|
|
got := m.buildServerHTTPSURL(tc.targetURL)
|
|
if got != tc.want {
|
|
t.Errorf("buildServerHTTPSURL(%q) = %q, want %q", tc.targetURL, got, tc.want)
|
|
}
|
|
})
|
|
}
|
|
}
|