Files
software-station/internal/api/handlers_test.go
Sudo-Ivan 2f0af4c988 Refactor API and background updater functionality
- Updated the StartBackgroundUpdater function to accept a callback for software list updates, improving flexibility.
- Refactored the API handlers to utilize a proxied software list, enhancing data handling and response efficiency.
- Introduced a new method for refreshing the proxied software list, ensuring accurate data representation.
- Added unit tests for API handlers to validate functionality and response correctness.
2025-12-27 03:30:18 -06:00

111 lines
2.8 KiB
Go

package api
import (
"encoding/json"
"net/http"
"net/http/httptest"
"os"
"software-station/internal/models"
"software-station/internal/stats"
"strings"
"testing"
)
func TestHandlers(t *testing.T) {
os.Setenv("ALLOW_LOOPBACK", "true")
defer os.Unsetenv("ALLOW_LOOPBACK")
tempHashes := "test_handlers_hashes.json"
defer os.Remove(tempHashes)
os.RemoveAll(".cache")
statsService := stats.NewService(tempHashes)
initialSoftware := []models.Software{
{
Name: "test-app",
Releases: []models.Release{
{
TagName: "v1.0.0",
Assets: []models.Asset{
{Name: "test.exe", URL: "http://example.com/test.exe"},
},
},
},
AvatarURL: "http://example.com/logo.png",
},
}
server := NewServer("token", initialSoftware, statsService)
t.Run("APISoftwareHandler", func(t *testing.T) {
req := httptest.NewRequest("GET", "/api/software", nil)
rr := httptest.NewRecorder()
server.APISoftwareHandler(rr, req)
if rr.Code != http.StatusOK {
t.Errorf("expected 200, got %d", rr.Code)
}
var sw []models.Software
if err := json.Unmarshal(rr.Body.Bytes(), &sw); err != nil {
t.Fatal(err)
}
if len(sw) != 1 || sw[0].Name != "test-app" {
t.Errorf("unexpected response: %v", sw)
}
if !strings.Contains(sw[0].AvatarURL, "/api/avatar?id=") {
t.Errorf("AvatarURL not proxied: %s", sw[0].AvatarURL)
}
})
t.Run("AvatarHandler", func(t *testing.T) {
// Mock upstream
upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "image/png")
w.Write([]byte("fake-image"))
}))
defer upstream.Close()
hash := server.RegisterURL(upstream.URL)
req := httptest.NewRequest("GET", "/api/avatar?id="+hash, nil)
rr := httptest.NewRecorder()
server.AvatarHandler(rr, req)
if rr.Code != http.StatusOK {
t.Errorf("expected 200, got %d", rr.Code)
}
if rr.Header().Get("Content-Type") != "image/png" {
t.Errorf("expected image/png, got %s", rr.Header().Get("Content-Type"))
}
})
t.Run("DownloadProxyHandler", func(t *testing.T) {
upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("fake-binary"))
}))
defer upstream.Close()
hash := server.RegisterURL(upstream.URL)
req := httptest.NewRequest("GET", "/api/download?id="+hash, nil)
rr := httptest.NewRecorder()
server.DownloadProxyHandler(rr, req)
if rr.Code != http.StatusOK {
t.Errorf("expected 200, got %d", rr.Code)
}
})
t.Run("RSSHandler", func(t *testing.T) {
req := httptest.NewRequest("GET", "/api/rss", nil)
rr := httptest.NewRecorder()
server.RSSHandler(rr, req)
if rr.Code != http.StatusOK {
t.Errorf("expected 200, got %d", rr.Code)
}
if !strings.Contains(rr.Body.String(), "<rss") {
t.Error("missing rss tag")
}
})
}