Files
Maven/internal/weather/openmeteo_test.go
T
kami e030466cac maven: weather module skeleton with open-meteo provider (task 5)
- New internal/weather/ package: Provider interface, Weather struct, StubProvider
- OpenMeteoProvider with geocoding + current weather (keyless, free API)
- Config: WeatherConfig in VoiceConfig (provider, default_location)
- Wire in voice.go as weatherProvider on reactiveHandler
- Handle weather queries in IntentQuery (before notes RAG)
- Helper: isWeatherQuery / extractWeatherLocation
- Tests: mocked HTTP round-trip for OpenMeteo, stub ErrNotConfigured, config tests
- No real network calls in any test

Co-Authored-By: opencode <opencode@anthropic.com>
2026-07-06 04:15:54 +04:00

86 lines
2.1 KiB
Go

package weather
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"testing"
)
func TestOpenMeteoProvider(t *testing.T) {
var geoReqCount, weatherReqCount int
mock := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/v1/search" {
geoReqCount++
json.NewEncoder(w).Encode(geoResponse{
Results: []geoResult{{
Name: "Moscow", Latitude: 55.7558, Longitude: 37.6173, Country: "Russia",
}},
})
return
}
if r.URL.Path == "/v1/forecast" {
weatherReqCount++
json.NewEncoder(w).Encode(forecastResponse{
CurrentWeather: currentWeather{
Temperature: 22.5,
WMO: 0,
WindSpeed: 3.2,
},
})
return
}
w.WriteHeader(http.StatusNotFound)
}))
defer mock.Close()
p := NewOpenMeteoProvider()
transport := &mockTransport{
geoURL: mock.URL + "/v1/search",
forecastURL: mock.URL + "/v1/forecast",
}
p.SetClient(&http.Client{Transport: transport})
w, err := p.CurrentWeather(context.Background(), "Moscow")
if err != nil {
t.Fatalf("CurrentWeather: %v", err)
}
if w.Location != "Moscow" {
t.Errorf("location = %q, want Moscow", w.Location)
}
if w.Temperature != 22.5 {
t.Errorf("temperature = %f, want 22.5", w.Temperature)
}
if w.Condition != "ясно" {
t.Errorf("condition = %q, want ясно", w.Condition)
}
}
type mockTransport struct {
geoURL string
forecastURL string
}
func (t *mockTransport) RoundTrip(r *http.Request) (*http.Response, error) {
var targetURL string
if r.URL.Host == "geocoding-api.open-meteo.com" {
targetURL = t.geoURL + "?" + r.URL.RawQuery
} else if r.URL.Host == "api.open-meteo.com" {
targetURL = t.forecastURL + "?" + r.URL.RawQuery
} else {
return nil, fmt.Errorf("unexpected host: %s", r.URL.Host)
}
req, _ := http.NewRequestWithContext(r.Context(), r.Method, targetURL, nil)
return http.DefaultTransport.RoundTrip(req)
}
func TestStubProvider(t *testing.T) {
p := NewStubProvider()
_, err := p.CurrentWeather(context.Background(), "Moscow")
if err != ErrNotConfigured {
t.Fatalf("StubProvider: want ErrNotConfigured, got %v", err)
}
}