package inventory import ( "context" "errors" "net/http" "net/http/httptest" "strings" "testing" ) type mockStockReader struct { stock map[string]int64 err error } func (m *mockStockReader) GetInventory(ctx context.Context, sku SKU, locationID LocationID) (int64, error) { if m.err != nil { return 0, m.err } qty, ok := m.stock[string(sku)] if !ok { return 0, errors.New("sku not found") } return qty, nil } func TestBadgeHandler(t *testing.T) { mock := &mockStockReader{ stock: map[string]int64{ "HIGH": 25, "LOW": 3, "OUT": 0, }, } handler := BadgeHandler(mock) tests := []struct { name string url string expectedCode int expectedSubstr string }{ { name: "missing sku", url: "/inventory/badge", expectedCode: http.StatusBadRequest, expectedSubstr: "missing sku parameter", }, { name: "high stock", url: "/inventory/badge?sku=HIGH", expectedCode: http.StatusOK, expectedSubstr: "stock-in-stock", }, { name: "low stock", url: "/inventory/badge?sku=LOW", expectedCode: http.StatusOK, expectedSubstr: "Only 3 left!", }, { name: "out of stock", url: "/inventory/badge?sku=OUT", expectedCode: http.StatusOK, expectedSubstr: "stock-out-of-stock", }, { name: "unknown stock / error", url: "/inventory/badge?sku=UNKNOWN", expectedCode: http.StatusOK, expectedSubstr: "stock-unknown", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { req := httptest.NewRequest(http.MethodGet, tt.url, nil) rr := httptest.NewRecorder() handler.ServeHTTP(rr, req) if rr.Code != tt.expectedCode { t.Errorf("expected status code %d, got %d", tt.expectedCode, rr.Code) } body := rr.Body.String() if !strings.Contains(body, tt.expectedSubstr) { t.Errorf("expected body to contain %q, got %q", tt.expectedSubstr, body) } }) } }