Validate Weather API endpoints and retries
This commit is contained in:
@@ -3,6 +3,7 @@ package weatherapi
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
@@ -15,6 +16,12 @@ import (
|
||||
"gitea.maximumdirect.net/eric/weatherreporter/internal/weatherdata"
|
||||
)
|
||||
|
||||
type roundTripperFunc func(*http.Request) (*http.Response, error)
|
||||
|
||||
func (f roundTripperFunc) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
return f(req)
|
||||
}
|
||||
|
||||
func TestFetchBundleFromFixtures(t *testing.T) {
|
||||
var requested []string
|
||||
server := fixtureServer(t, nil, &requested)
|
||||
@@ -265,6 +272,25 @@ func TestWarmupFailureStopsBeforeSourceFetches(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestWarmupDoesNotRetryPermanentStatus(t *testing.T) {
|
||||
var requested []string
|
||||
server := fixtureServer(t, map[string]handlerOverride{
|
||||
defaultWarmupEndpoint: {status: http.StatusNotFound, body: `not found`},
|
||||
}, &requested)
|
||||
client := newTestClient(t, server.URL+"/", nil)
|
||||
|
||||
_, err := client.FetchBundle(context.Background())
|
||||
if err == nil || !strings.Contains(err.Error(), "404") {
|
||||
t.Fatalf("FetchBundle() error = %v, want non-retryable warmup status", err)
|
||||
}
|
||||
if got := countPath(requested, defaultWarmupEndpoint); got != 1 {
|
||||
t.Fatalf("warmup requests = %d, want 1; all requests = %v", got, requested)
|
||||
}
|
||||
if containsPath(requested, "/observations") {
|
||||
t.Fatalf("requested paths = %v, want warmup failure before source fetches", requested)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFetchRetriesRetryableStatus(t *testing.T) {
|
||||
var hourlyCalls int
|
||||
server := fixtureServer(t, map[string]handlerOverride{
|
||||
@@ -312,6 +338,40 @@ func TestFetchDoesNotRetryNonRetryableStatus(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewValidatesWeatherAPIBaseURLSchemeWithoutRequests(t *testing.T) {
|
||||
requests := 0
|
||||
httpClient := &http.Client{Transport: roundTripperFunc(func(*http.Request) (*http.Response, error) {
|
||||
requests++
|
||||
return nil, errors.New("unexpected request")
|
||||
})}
|
||||
tests := []struct {
|
||||
name string
|
||||
baseURL string
|
||||
wantErr string
|
||||
}{
|
||||
{name: "local HTTP", baseURL: "http://127.0.0.1:8080/weather/"},
|
||||
{name: "local HTTPS", baseURL: "https://127.0.0.1:8443/weather/"},
|
||||
{name: "unsupported scheme", baseURL: "ftp://weather.example.test/", wantErr: "weather_api.base_url must use http or https"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
cfg := testConfig(tt.baseURL)
|
||||
_, err := New(cfg, WithHTTPClient(httpClient))
|
||||
if tt.wantErr == "" {
|
||||
if err != nil {
|
||||
t.Fatalf("New() error = %v", err)
|
||||
}
|
||||
} else if err == nil || !strings.Contains(err.Error(), tt.wantErr) {
|
||||
t.Fatalf("New() error = %v, want %q", err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
if requests != 0 {
|
||||
t.Fatalf("HTTP requests = %d, want none", requests)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFetchDoesNotRetryMalformedEnvelope(t *testing.T) {
|
||||
var hourlyCalls int
|
||||
server := fixtureServer(t, map[string]handlerOverride{
|
||||
|
||||
Reference in New Issue
Block a user