style: fix golangci-lint issues for code quality improvement

- Fix error string capitalization to follow Go guidelines (ST1005)
- Fix unchecked error returns in test files (errcheck)
- Replace nil-nil return with proper error for non-TuneIn URLs (nilnil)
- Add missing comments for exported service type constants (revive)
- Rename unused parameters to underscore in test handlers (revive)
- Add t.Helper() calls to test helper functions (thelper)
- Update test expectations to match lowercase error messages

This addresses all critical linting issues while maintaining functionality.
This commit is contained in:
Tobias Gesellchen
2026-02-01 21:50:14 +01:00
parent 0cd6ed4603
commit 7f6eccee39
8 changed files with 76 additions and 61 deletions
+1 -1
View File
@@ -146,7 +146,7 @@ func searchSpotify(c *cli.Context) error {
// Check Spotify availability
checker := NewServiceAvailabilityChecker(client)
if !checker.ValidateSpotifyAvailable("search Spotify content") {
return fmt.Errorf("Spotify is not available on this device")
return fmt.Errorf("spotify is not available on this device")
}
response, err := client.SearchSpotifyContent(sourceAccount, searchTerm)
+1 -1
View File
@@ -175,7 +175,7 @@ var httpClient = &http.Client{
func fetchTuneInMetadata(url string) (*TuneInMetadata, error) {
if !strings.Contains(url, "tunein.com/radio/") {
return nil, nil
return nil, fmt.Errorf("url is not a TuneIn radio URL")
}
resp, err := httpClient.Get(url)
+1 -1
View File
@@ -7,7 +7,7 @@ import (
)
func TestFetchTuneInMetadata(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
html := `
<!doctype html>
<html>
+18 -18
View File
@@ -113,7 +113,7 @@ func TestClient_Navigate(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
if tt.serverStatus != 0 {
w.WriteHeader(tt.serverStatus)
}
@@ -241,7 +241,7 @@ func TestClient_NavigateContainer(t *testing.T) {
</items>
</navigateResponse>`
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
_, _ = w.Write([]byte(serverResponse))
}))
defer server.Close()
@@ -344,7 +344,7 @@ func TestClient_AddStation(t *testing.T) {
w.WriteHeader(tt.serverStatus)
}
if tt.serverResponse != "" {
w.Write([]byte(tt.serverResponse))
_, _ = w.Write([]byte(tt.serverResponse))
}
// Verify request format
@@ -457,7 +457,7 @@ func TestClient_RemoveStation(t *testing.T) {
w.WriteHeader(tt.serverStatus)
}
if tt.serverResponse != "" {
w.Write([]byte(tt.serverResponse))
_, _ = w.Write([]byte(tt.serverResponse))
}
// Verify request format
@@ -534,7 +534,7 @@ func TestClient_GetPandoraStations(t *testing.T) {
t.Errorf("Expected sort dateCreated, got %s", request.Sort)
}
w.Write([]byte(serverResponse))
_, _ = w.Write([]byte(serverResponse))
}))
defer server.Close()
@@ -560,7 +560,7 @@ func TestClient_GetPandoraStations(t *testing.T) {
// Test error case
_, err = client.GetPandoraStations("")
if err == nil || !contains(err.Error(), "Pandora source account cannot be empty") {
if err == nil || !contains(err.Error(), "pandora source account cannot be empty") {
t.Error("Expected error for empty source account")
}
}
@@ -580,8 +580,8 @@ func TestClient_GetTuneInStations(t *testing.T) {
</items>
</navigateResponse>`
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(serverResponse))
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
_, _ = w.Write([]byte(serverResponse))
}))
defer server.Close()
@@ -621,8 +621,8 @@ func TestClient_GetStoredMusicLibrary(t *testing.T) {
</items>
</navigateResponse>`
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(serverResponse))
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
_, _ = w.Write([]byte(serverResponse))
}))
defer server.Close()
@@ -739,7 +739,7 @@ func TestClient_SearchStation(t *testing.T) {
w.WriteHeader(tt.serverStatus)
}
if tt.serverResponse != "" {
w.Write([]byte(tt.serverResponse))
_, _ = w.Write([]byte(tt.serverResponse))
}
// Verify request format for valid requests
@@ -823,7 +823,7 @@ func TestClient_SearchPandoraStations(t *testing.T) {
t.Errorf("Expected searchTerm 'Taylor Swift', got %s", request.SearchTerm)
}
w.Write([]byte(serverResponse))
_, _ = w.Write([]byte(serverResponse))
}))
defer server.Close()
@@ -849,7 +849,7 @@ func TestClient_SearchPandoraStations(t *testing.T) {
// Test error case
_, err = client.SearchPandoraStations("", "test")
if err == nil || !contains(err.Error(), "Pandora source account cannot be empty") {
if err == nil || !contains(err.Error(), "pandora source account cannot be empty") {
t.Error("Expected error for empty source account")
}
}
@@ -866,8 +866,8 @@ func TestClient_SearchTuneInStations(t *testing.T) {
</stations>
</results>`
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(serverResponse))
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
_, _ = w.Write([]byte(serverResponse))
}))
defer server.Close()
@@ -909,8 +909,8 @@ func TestClient_SearchSpotifyContent(t *testing.T) {
</songs>
</results>`
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(serverResponse))
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
_, _ = w.Write([]byte(serverResponse))
}))
defer server.Close()
@@ -936,7 +936,7 @@ func TestClient_SearchSpotifyContent(t *testing.T) {
// Test error case
_, err = client.SearchSpotifyContent("", "test")
if err == nil || !contains(err.Error(), "Spotify source account cannot be empty") {
if err == nil || !contains(err.Error(), "spotify source account cannot be empty") {
t.Error("Expected error for empty source account")
}
}
+16 -16
View File
@@ -57,11 +57,11 @@ func TestClient_NavigateXMLValidation(t *testing.T) {
capturedEndpoint = r.URL.Path
body := make([]byte, r.ContentLength)
r.Body.Read(body)
_, _ = r.Body.Read(body)
capturedXML = string(body)
// Return valid navigate response
w.Write([]byte(`<?xml version="1.0" encoding="UTF-8"?>
_, _ = w.Write([]byte(`<?xml version="1.0" encoding="UTF-8"?>
<navigateResponse source="` + tt.source + `">
<totalItems>0</totalItems>
<items></items>
@@ -99,11 +99,11 @@ func TestClient_NavigateWithMenuXMLValidation(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body := make([]byte, r.ContentLength)
r.Body.Read(body)
_, _ = r.Body.Read(body)
capturedXML = string(body)
w.Write([]byte(`<?xml version="1.0" encoding="UTF-8"?>
<navigateResponse source="PANDORA">
_, _ = w.Write([]byte(`<?xml version="1.0" encoding="UTF-8"?>
<navigateResponse source="SPOTIFY">
<totalItems>0</totalItems>
<items></items>
</navigateResponse>`))
@@ -174,10 +174,10 @@ func TestClient_SearchStationXMLValidation(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body := make([]byte, r.ContentLength)
r.Body.Read(body)
_, _ = r.Body.Read(body)
capturedXML = string(body)
w.Write([]byte(`<?xml version="1.0" encoding="UTF-8"?>
_, _ = w.Write([]byte(`<?xml version="1.0" encoding="UTF-8"?>
<results source="` + tt.source + `">
<songs></songs>
<artists></artists>
@@ -212,10 +212,10 @@ func TestClient_AddStationXMLValidation(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body := make([]byte, r.ContentLength)
r.Body.Read(body)
_, _ = r.Body.Read(body)
capturedXML = string(body)
w.Write([]byte(`<status>/addStation</status>`))
_, _ = w.Write([]byte(`<status>/addStation</status>`))
}))
defer server.Close()
@@ -252,10 +252,10 @@ func TestClient_RemoveStationXMLValidation(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body := make([]byte, r.ContentLength)
r.Body.Read(body)
_, _ = r.Body.Read(body)
capturedXML = string(body)
w.Write([]byte(`<status>/removeStation</status>`))
_, _ = w.Write([]byte(`<status>/removeStation</status>`))
}))
defer server.Close()
@@ -353,8 +353,8 @@ func TestClient_NavigationResponseParsing(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(tt.responseXML))
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
_, _ = w.Write([]byte(tt.responseXML))
}))
defer server.Close()
@@ -465,8 +465,8 @@ func TestClient_SearchStationResponseParsing(t *testing.T) {
</stations>
</results>`
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(responseXML))
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
_, _ = w.Write([]byte(responseXML))
}))
defer server.Close()
@@ -559,7 +559,7 @@ func TestClient_NavigationHTTPHeaders(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
capturedHeaders = r.Header
w.Write([]byte(`<?xml version="1.0" encoding="UTF-8"?>
_, _ = w.Write([]byte(`<?xml version="1.0" encoding="UTF-8"?>
<navigateResponse source="TUNEIN">
<totalItems>0</totalItems>
<items></items>
+12 -12
View File
@@ -117,7 +117,7 @@ func TestClient_StorePreset(t *testing.T) {
w.WriteHeader(tt.serverStatus)
}
if tt.serverResponse != "" {
w.Write([]byte(tt.serverResponse))
_, _ = w.Write([]byte(tt.serverResponse))
}
}))
defer server.Close()
@@ -200,7 +200,7 @@ func TestClient_RemovePreset(t *testing.T) {
w.WriteHeader(tt.serverStatus)
}
if tt.serverResponse != "" {
w.Write([]byte(tt.serverResponse))
_, _ = w.Write([]byte(tt.serverResponse))
}
}))
defer server.Close()
@@ -343,7 +343,7 @@ func TestClient_StoreCurrentAsPreset(t *testing.T) {
w.WriteHeader(http.StatusOK)
}
if tt.nowPlayingResponse != "" {
w.Write([]byte(tt.nowPlayingResponse))
_, _ = w.Write([]byte(tt.nowPlayingResponse))
}
case "/storePreset":
if tt.storePresetStatus != 0 {
@@ -351,7 +351,7 @@ func TestClient_StoreCurrentAsPreset(t *testing.T) {
} else {
w.WriteHeader(http.StatusOK)
}
w.Write([]byte(`<?xml version="1.0" encoding="UTF-8"?><presets></presets>`))
_, _ = w.Write([]byte(`<?xml version="1.0" encoding="UTF-8"?><presets></presets>`))
default:
w.WriteHeader(http.StatusNotFound)
}
@@ -386,9 +386,9 @@ func TestClient_StorePreset_XMLGeneration(t *testing.T) {
var capturedXML string
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body := make([]byte, r.ContentLength)
r.Body.Read(body)
_, _ = r.Body.Read(body)
capturedXML = string(body)
w.Write([]byte(`<?xml version="1.0" encoding="UTF-8"?><presets></presets>`))
_, _ = w.Write([]byte(`<?xml version="1.0" encoding="UTF-8"?><presets></presets>`))
}))
defer server.Close()
@@ -437,9 +437,9 @@ func TestClient_RemovePreset_XMLGeneration(t *testing.T) {
var capturedXML string
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body := make([]byte, r.ContentLength)
r.Body.Read(body)
_, _ = r.Body.Read(body)
capturedXML = string(body)
w.Write([]byte(`<?xml version="1.0" encoding="UTF-8"?><presets></presets>`))
_, _ = w.Write([]byte(`<?xml version="1.0" encoding="UTF-8"?><presets></presets>`))
}))
defer server.Close()
@@ -536,9 +536,9 @@ func TestClient_StorePreset_RealWorldScenarios(t *testing.T) {
for _, scenario := range scenarios {
t.Run(scenario.name, func(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
// Just return success for these scenario tests
w.Write([]byte(`<?xml version="1.0" encoding="UTF-8"?><presets></presets>`))
_, _ = w.Write([]byte(`<?xml version="1.0" encoding="UTF-8"?><presets></presets>`))
}))
defer server.Close()
@@ -556,8 +556,8 @@ func TestClient_StorePreset_RealWorldScenarios(t *testing.T) {
}
func TestClient_PresetTimestamps(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(`<?xml version="1.0" encoding="UTF-8"?><presets></presets>`))
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
_, _ = w.Write([]byte(`<?xml version="1.0" encoding="UTF-8"?><presets></presets>`))
}))
defer server.Close()
+24 -12
View File
@@ -25,19 +25,31 @@ type ServiceType string
const (
// ServiceTypeAirPlay represents Apple AirPlay streaming service
ServiceTypeAirPlay ServiceType = "AIRPLAY"
ServiceTypeAlexa ServiceType = "ALEXA"
ServiceTypeAmazon ServiceType = "AMAZON"
ServiceTypeBluetooth ServiceType = "BLUETOOTH"
ServiceTypeBMX ServiceType = "BMX"
ServiceTypeDeezer ServiceType = "DEEZER"
ServiceTypeIHeart ServiceType = "IHEART"
ServiceTypeAirPlay ServiceType = "AIRPLAY"
// ServiceTypeAlexa represents Amazon Alexa voice assistant integration
ServiceTypeAlexa ServiceType = "ALEXA"
// ServiceTypeAmazon represents Amazon Music streaming service
ServiceTypeAmazon ServiceType = "AMAZON"
// ServiceTypeBluetooth represents Bluetooth audio connectivity
ServiceTypeBluetooth ServiceType = "BLUETOOTH"
// ServiceTypeBMX represents BMX streaming service
ServiceTypeBMX ServiceType = "BMX"
// ServiceTypeDeezer represents Deezer music streaming service
ServiceTypeDeezer ServiceType = "DEEZER"
// ServiceTypeIHeart represents iHeartRadio streaming service
ServiceTypeIHeart ServiceType = "IHEART"
// ServiceTypeLocalInternetRadio represents local internet radio stations
ServiceTypeLocalInternetRadio ServiceType = "LOCAL_INTERNET_RADIO"
ServiceTypeLocalMusic ServiceType = "LOCAL_MUSIC"
ServiceTypeNotification ServiceType = "NOTIFICATION"
ServiceTypePandora ServiceType = "PANDORA"
ServiceTypeSpotify ServiceType = "SPOTIFY"
ServiceTypeTuneIn ServiceType = "TUNEIN"
// ServiceTypeLocalMusic represents local music library
ServiceTypeLocalMusic ServiceType = "LOCAL_MUSIC"
// ServiceTypeNotification represents system notifications
ServiceTypeNotification ServiceType = "NOTIFICATION"
// ServiceTypePandora represents Pandora music streaming service
ServiceTypePandora ServiceType = "PANDORA"
// ServiceTypeSpotify represents Spotify music streaming service
ServiceTypeSpotify ServiceType = "SPOTIFY"
// ServiceTypeTuneIn represents TuneIn internet radio service
ServiceTypeTuneIn ServiceType = "TUNEIN"
)
// GetReason returns the reason why a service is unavailable (if any)
+3
View File
@@ -32,6 +32,7 @@ func TestServiceAvailability_UnmarshalXML(t *testing.T) {
</services>
</serviceAvailability>`,
validate: func(t *testing.T, sa *ServiceAvailability) {
t.Helper()
if sa.Services == nil {
t.Fatal("services should not be nil")
}
@@ -71,6 +72,7 @@ func TestServiceAvailability_UnmarshalXML(t *testing.T) {
</services>
</serviceAvailability>`,
validate: func(t *testing.T, sa *ServiceAvailability) {
t.Helper()
if sa.Services == nil {
t.Fatal("services should not be nil")
}
@@ -87,6 +89,7 @@ func TestServiceAvailability_UnmarshalXML(t *testing.T) {
</services>
</serviceAvailability>`,
validate: func(t *testing.T, sa *ServiceAvailability) {
t.Helper()
if sa.Services == nil {
t.Fatal("services should not be nil")
}