Adds a new endpoint GET /api/tasks/templates/by-region/?zip= that resolves ZIP codes to IECC climate regions and returns relevant home maintenance task templates. Includes climate region model, region lookup service with tests, seed data for all 8 climate zones with 50+ templates, and OpenAPI spec. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
82 lines
2.2 KiB
Go
82 lines
2.2 KiB
Go
package services
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestGetClimateRegionIDByState(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
state string
|
|
expected uint
|
|
}{
|
|
{"Massachusetts → Cold (5)", "MA", 5},
|
|
{"Florida → Hot-Humid (1)", "FL", 1},
|
|
{"Arizona → Hot-Dry (2)", "AZ", 2},
|
|
{"Alaska → Arctic (8)", "AK", 8},
|
|
{"Minnesota → Very Cold (6)", "MN", 6},
|
|
{"Tennessee → Mixed-Humid (3)", "TN", 3},
|
|
{"Missouri → Mixed (4)", "MO", 4},
|
|
{"Unknown state → 0", "XX", 0},
|
|
{"Empty string → 0", "", 0},
|
|
{"Lowercase input", "ma", 5},
|
|
{"Whitespace trimmed", " TX ", 2},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := GetClimateRegionIDByState(tt.state)
|
|
assert.Equal(t, tt.expected, result)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestZipToState(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
zip string
|
|
expected string
|
|
}{
|
|
{"Boston MA", "02101", "MA"},
|
|
{"Miami FL", "33101", "FL"},
|
|
{"Phoenix AZ", "85001", "AZ"},
|
|
{"Anchorage AK", "99501", "AK"},
|
|
{"New York NY", "10001", "NY"},
|
|
{"Chicago IL", "60601", "IL"},
|
|
{"Houston TX", "77001", "TX"},
|
|
{"Denver CO", "80201", "CO"},
|
|
{"DC", "20001", "DC"},
|
|
{"Too short", "12", ""},
|
|
{"Empty", "", ""},
|
|
{"Non-numeric", "abcde", ""},
|
|
{"Unrecognized prefix", "00100", ""},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := ZipToState(tt.zip)
|
|
assert.Equal(t, tt.expected, result)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestStateToClimateRegion_AllStatesPresent(t *testing.T) {
|
|
// All 50 states + DC should be in the map
|
|
allStates := []string{
|
|
"AL", "AK", "AZ", "AR", "CA", "CO", "CT", "DE", "FL", "GA",
|
|
"HI", "ID", "IL", "IN", "IA", "KS", "KY", "LA", "ME", "MD",
|
|
"MA", "MI", "MN", "MS", "MO", "MT", "NE", "NV", "NH", "NJ",
|
|
"NM", "NY", "NC", "ND", "OH", "OK", "OR", "PA", "RI", "SC",
|
|
"SD", "TN", "TX", "UT", "VT", "VA", "WA", "WV", "WI", "WY",
|
|
"DC",
|
|
}
|
|
|
|
for _, state := range allStates {
|
|
t.Run(state, func(t *testing.T) {
|
|
regionID := GetClimateRegionIDByState(state)
|
|
assert.Greater(t, regionID, uint(0), "State %s should map to a region", state)
|
|
assert.LessOrEqual(t, regionID, uint(8), "State %s region should be 1-8, got %d", state, regionID)
|
|
})
|
|
}
|
|
}
|