Cover active alert text rendering
This commit is contained in:
@@ -79,6 +79,46 @@ func (s *fakeService) CurrentConditions(context.Context) (*app.CurrentConditions
|
||||
return s.conditions, s.err
|
||||
}
|
||||
|
||||
type alertRepository struct {
|
||||
alerts *model.WeatherAlertRun
|
||||
}
|
||||
|
||||
func (r *alertRepository) LatestObservation(context.Context) (*model.WeatherObservation, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (r *alertRepository) LatestHourlyForecast(context.Context) (*model.WeatherForecastRun, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (r *alertRepository) LatestNarrativeForecast(context.Context) (*model.WeatherForecastRun, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (r *alertRepository) LatestForecastDiscussion(context.Context) (*model.WeatherForecastDiscussion, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (r *alertRepository) LatestWeatherStoryRun(context.Context) (*model.WeatherStoryRun, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (r *alertRepository) LatestWeatherStory(context.Context) (*model.WeatherStory, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (r *alertRepository) LatestAlertRun(context.Context) (*model.WeatherAlertRun, error) {
|
||||
return r.alerts, nil
|
||||
}
|
||||
|
||||
func (r *alertRepository) LatestConvectiveOutlookRun(context.Context) (*model.WeatherOutlookRun, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (r *alertRepository) CurrentConditions(context.Context, int) (*app.CurrentConditions, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func TestObservationsRejectUnknownQueryParameter(t *testing.T) {
|
||||
h := newHandler(t, &fakeService{}, "/observations")
|
||||
|
||||
@@ -377,6 +417,21 @@ func TestAlertsNoDataReturnsNullEnvelopeData(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAlertsTextRendersNoData(t *testing.T) {
|
||||
h := newHandler(t, &fakeService{}, "/alerts/active")
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req := httptest.NewRequest(http.MethodGet, "/alerts/active?format=text", nil)
|
||||
h.ServeHTTP(w, req)
|
||||
|
||||
if w.Code != http.StatusOK {
|
||||
t.Fatalf("expected 200, got %d", w.Code)
|
||||
}
|
||||
if !strings.Contains(w.Body.String(), "No active alerts data available.") {
|
||||
t.Fatalf("expected no-data alert text, got %q", w.Body.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestAlertsTextRendersEmptyActiveSet(t *testing.T) {
|
||||
h := newHandler(t, &fakeService{
|
||||
alerts: &model.WeatherAlertRun{
|
||||
@@ -397,6 +452,62 @@ func TestAlertsTextRendersEmptyActiveSet(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAlertsTextOmitsInactiveAlertsAfterServiceFiltering(t *testing.T) {
|
||||
activeAt := time.Date(2026, 6, 11, 12, 0, 0, 0, time.UTC)
|
||||
setAlertNowForTest(t, activeAt)
|
||||
effective := activeAt.Add(-1 * time.Hour)
|
||||
activeExpires := activeAt.Add(1 * time.Hour)
|
||||
expiredAtBoundary := activeAt
|
||||
repo := &alertRepository{
|
||||
alerts: &model.WeatherAlertRun{
|
||||
AsOf: activeAt,
|
||||
Alerts: []model.WeatherAlert{
|
||||
{
|
||||
ID: "active-alert",
|
||||
Headline: "Active warning",
|
||||
MessageType: "Alert",
|
||||
Effective: &effective,
|
||||
Expires: &activeExpires,
|
||||
},
|
||||
{
|
||||
ID: "expired-alert",
|
||||
Headline: "Expired warning",
|
||||
MessageType: "Alert",
|
||||
Effective: &effective,
|
||||
Expires: &expiredAtBoundary,
|
||||
},
|
||||
{
|
||||
ID: "canceled-alert",
|
||||
Headline: "Canceled warning",
|
||||
MessageType: " cancel ",
|
||||
Effective: &effective,
|
||||
Expires: &activeExpires,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
h := newHandler(t, app.NewService(repo), "/alerts/active")
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req := httptest.NewRequest(http.MethodGet, "/alerts/active?format=text", nil)
|
||||
h.ServeHTTP(w, req)
|
||||
|
||||
if w.Code != http.StatusOK {
|
||||
t.Fatalf("expected 200, got %d", w.Code)
|
||||
}
|
||||
body := w.Body.String()
|
||||
for _, want := range []string{"Alerts: 1", "active-alert", "Active warning"} {
|
||||
if !strings.Contains(body, want) {
|
||||
t.Fatalf("expected %q in text body, got %q", want, body)
|
||||
}
|
||||
}
|
||||
for _, notWant := range []string{"expired-alert", "Expired warning", "canceled-alert", "Canceled warning"} {
|
||||
if strings.Contains(body, notWant) {
|
||||
t.Fatalf("did not expect %q in text body, got %q", notWant, body)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestObservationUSUnitsWithXMLFormat(t *testing.T) {
|
||||
h := newHandler(t, &fakeService{
|
||||
observation: &model.WeatherObservation{
|
||||
@@ -2352,7 +2463,7 @@ func testRenderers(t *testing.T) *render.Registry {
|
||||
"outlooks_convective.txt.tmpl": "Convective Outlook\n{{if .Data}}Outlooks: {{len .Data.Outlooks}}\nDiscussions: {{len .Data.Discussions}}{{range .Data.Discussions}}\nDiscussion: {{.Discussion}}{{end}}{{else}}No convective outlook data available.{{end}}",
|
||||
"weatherstories.txt.tmpl": "Weather Stories",
|
||||
"weatherstories_latest.txt.tmpl": "Latest Weather Story",
|
||||
"alerts_active.txt.tmpl": "{{if .Data}}Active Alerts\nAlerts: {{len .Data.Alerts}}{{else}}No active alerts data available.{{end}}",
|
||||
"alerts_active.txt.tmpl": "{{if .Data}}Active Alerts\nAlerts: {{len .Data.Alerts}}{{range .Data.Alerts}}\n{{.ID}}{{if .Headline}}\nHeadline: {{.Headline}}{{end}}{{end}}{{else}}No active alerts data available.{{end}}",
|
||||
"conditions_current.txt.tmpl": "Conditions text",
|
||||
} {
|
||||
tmpl, err := template.New(name).Parse(body)
|
||||
|
||||
@@ -337,6 +337,22 @@ func TestMetricCopyAndNilHandling(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAlertsPayloadPassThrough(t *testing.T) {
|
||||
run := &model.WeatherAlertRun{
|
||||
LocationID: "stl",
|
||||
AsOf: time.Date(2026, 6, 11, 12, 0, 0, 0, time.UTC),
|
||||
Alerts: []model.WeatherAlert{{
|
||||
ID: "alert-1",
|
||||
Headline: "Storm warning",
|
||||
}},
|
||||
}
|
||||
|
||||
payload := AlertsPayload(run, UnitsUS)
|
||||
if payload != run {
|
||||
t.Fatalf("expected alerts payload to pass through input run")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCurrentConditionsPayloadMetricAndUS(t *testing.T) {
|
||||
conditions := &app.CurrentConditions{
|
||||
TemperatureC: float64Ptr(20),
|
||||
|
||||
Reference in New Issue
Block a user