mirror of
https://github.com/AmanTahiliani/box-box.git
synced 2026-08-08 04:06:18 -04:00
Add local navigation API
This commit is contained in:
50
internal/web/navigation.go
Normal file
50
internal/web/navigation.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/AmanTahiliani/box-box/internal/query"
|
||||
)
|
||||
|
||||
func (s *Server) handleSeasons(w http.ResponseWriter, r *http.Request) {
|
||||
if !s.hasLocalQuery() {
|
||||
writeJSON(w, []int{})
|
||||
return
|
||||
}
|
||||
|
||||
years, err := s.query.ListSeasons()
|
||||
if err != nil {
|
||||
writeError(w, err, http.StatusInternalServerError, false)
|
||||
return
|
||||
}
|
||||
if years == nil {
|
||||
years = []int{}
|
||||
}
|
||||
writeJSON(w, years)
|
||||
}
|
||||
|
||||
func (s *Server) handleWeekend(w http.ResponseWriter, r *http.Request) {
|
||||
meetingKey, err := strconv.Atoi(r.URL.Query().Get("meeting_key"))
|
||||
if err != nil || meetingKey == 0 {
|
||||
http.Error(w, "meeting_key required", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if !s.hasLocalQuery() {
|
||||
writeError(w, query.ErrMeetingNotFound, http.StatusNotFound, false)
|
||||
return
|
||||
}
|
||||
|
||||
weekend, err := s.query.GetWeekend(meetingKey)
|
||||
if err != nil {
|
||||
if errors.Is(err, query.ErrMeetingNotFound) {
|
||||
writeError(w, err, http.StatusNotFound, false)
|
||||
return
|
||||
}
|
||||
writeError(w, err, http.StatusInternalServerError, false)
|
||||
return
|
||||
}
|
||||
writeJSON(w, weekend)
|
||||
}
|
||||
@@ -150,3 +150,96 @@ func TestHandleRaceHubRequiresSessionKey(t *testing.T) {
|
||||
t.Fatalf("status = %d, want 400", rec.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleSeasonsEmpty(t *testing.T) {
|
||||
srv := testServer(t, nil)
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/v1/seasons", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
srv.handleSeasons(rec, req)
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Fatalf("status = %d, want 200", rec.Code)
|
||||
}
|
||||
|
||||
var years []int
|
||||
if err := json.Unmarshal(rec.Body.Bytes(), &years); err != nil {
|
||||
t.Fatalf("decode response: %v", err)
|
||||
}
|
||||
if len(years) != 0 {
|
||||
t.Fatalf("years = %v, want empty", years)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleSeasonsWithData(t *testing.T) {
|
||||
st := openTestStore(t)
|
||||
seedRaceHubStore(t, st)
|
||||
srv := testServer(t, st)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/v1/seasons", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
srv.handleSeasons(rec, req)
|
||||
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Fatalf("status = %d, want 200", rec.Code)
|
||||
}
|
||||
|
||||
var years []int
|
||||
if err := json.Unmarshal(rec.Body.Bytes(), &years); err != nil {
|
||||
t.Fatalf("decode response: %v", err)
|
||||
}
|
||||
if len(years) != 1 || years[0] != 2025 {
|
||||
t.Fatalf("years = %v, want [2025]", years)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleWeekendNotFound(t *testing.T) {
|
||||
st := openTestStore(t)
|
||||
srv := testServer(t, st)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/v1/weekend?meeting_key=1229", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
srv.handleWeekend(rec, req)
|
||||
|
||||
if rec.Code != http.StatusNotFound {
|
||||
t.Fatalf("status = %d, want 404", rec.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleWeekendWithData(t *testing.T) {
|
||||
st := openTestStore(t)
|
||||
seedRaceHubStore(t, st)
|
||||
srv := testServer(t, st)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/v1/weekend?meeting_key=1229", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
srv.handleWeekend(rec, req)
|
||||
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Fatalf("status = %d, want 200", rec.Code)
|
||||
}
|
||||
|
||||
var weekend query.Weekend
|
||||
if err := json.Unmarshal(rec.Body.Bytes(), &weekend); err != nil {
|
||||
t.Fatalf("decode response: %v", err)
|
||||
}
|
||||
if weekend.Meeting.MeetingName != "Monaco" {
|
||||
t.Fatalf("meeting = %q, want Monaco", weekend.Meeting.MeetingName)
|
||||
}
|
||||
if len(weekend.Sessions) != 1 {
|
||||
t.Fatalf("sessions len = %d, want 1", len(weekend.Sessions))
|
||||
}
|
||||
if weekend.DefaultSessionKey != 9472 {
|
||||
t.Fatalf("default_session_key = %d, want 9472", weekend.DefaultSessionKey)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleWeekendRequiresMeetingKey(t *testing.T) {
|
||||
srv := testServer(t, nil)
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/v1/weekend", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
srv.handleWeekend(rec, req)
|
||||
if rec.Code != http.StatusBadRequest {
|
||||
t.Fatalf("status = %d, want 400", rec.Code)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,8 @@ func (s *Server) Start() error {
|
||||
// REST API — /api/v1/laps/comparison must be registered before /api/v1/laps
|
||||
// because Go's ServeMux uses longest-prefix matching.
|
||||
mux.HandleFunc("/api/v1/race-hub", s.handleRaceHub)
|
||||
mux.HandleFunc("/api/v1/seasons", s.handleSeasons)
|
||||
mux.HandleFunc("/api/v1/weekend", s.handleWeekend)
|
||||
mux.HandleFunc("/api/v1/meetings", s.handleMeetings)
|
||||
mux.HandleFunc("/api/v1/sessions", s.handleSessions)
|
||||
mux.HandleFunc("/api/v1/drivers", s.handleDrivers)
|
||||
|
||||
Reference in New Issue
Block a user