diff --git a/.gitignore b/.gitignore index a743447..0577391 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ .env .cache .DS_Store +*.gocache +*.exe */dist */node_modules \ No newline at end of file diff --git a/backend/docs/docs.go b/backend/docs/docs.go index 45abec5..171a03b 100644 --- a/backend/docs/docs.go +++ b/backend/docs/docs.go @@ -267,8 +267,7 @@ const docTemplate = `{ "ep_num", "ep_title", "playback_length", - "season_name", - "start_time" + "season_name" ], "properties": { "ep_num": { @@ -288,6 +287,7 @@ const docTemplate = `{ "example": "Season 1" }, "start_time": { + "description": "optional; defaults to 22:00:00", "type": "string", "example": "10:00:00" } diff --git a/backend/docs/swagger.json b/backend/docs/swagger.json index 4d24cf6..9b45839 100644 --- a/backend/docs/swagger.json +++ b/backend/docs/swagger.json @@ -265,8 +265,7 @@ "ep_num", "ep_title", "playback_length", - "season_name", - "start_time" + "season_name" ], "properties": { "ep_num": { @@ -286,6 +285,7 @@ "example": "Season 1" }, "start_time": { + "description": "optional; defaults to 22:00:00", "type": "string", "example": "10:00:00" } diff --git a/backend/docs/swagger.yaml b/backend/docs/swagger.yaml index 4f676c9..41820c9 100644 --- a/backend/docs/swagger.yaml +++ b/backend/docs/swagger.yaml @@ -15,6 +15,7 @@ definitions: example: Season 1 type: string start_time: + description: optional; defaults to 22:00:00 example: "10:00:00" type: string required: @@ -22,7 +23,6 @@ definitions: - ep_title - playback_length - season_name - - start_time type: object httpapi.CurrentResponse: properties: diff --git a/backend/internal/http/handlers.go b/backend/internal/http/handlers.go index 13ded5f..b8d2ef8 100644 --- a/backend/internal/http/handlers.go +++ b/backend/internal/http/handlers.go @@ -4,6 +4,7 @@ import ( "errors" "net/http" "strconv" + "strings" "time" "watch-party-backend/internal/core/episode" @@ -125,11 +126,16 @@ func createShowHandler(svc episode.UseCases) gin.HandlerFunc { return } + start := strings.TrimSpace(req.StartTime) + if start == "" { + start = "22:00:00" + } + in := episode.NewShowInput{ EpNum: req.EpNum, EpTitle: req.EpTitle, SeasonName: req.SeasonName, - StartTime: req.StartTime, + StartTime: start, PlaybackLength: req.PlaybackLength, } diff --git a/backend/internal/http/handlers_test.go b/backend/internal/http/handlers_test.go index a7a84a8..22f4029 100644 --- a/backend/internal/http/handlers_test.go +++ b/backend/internal/http/handlers_test.go @@ -296,6 +296,31 @@ func TestPostShows_OK(t *testing.T) { } } +func TestPostShows_DefaultStartTime(t *testing.T) { + now := time.Now().UTC() + svc := &fakeSvc{ + createRes: episode.Episode{ + Id: 11, + EpNum: 2, + EpTitle: "No Start", + SeasonName: "S2", + StartTime: "22:00:00", + PlaybackLength: "00:24:00", + DateCreated: now, + }, + } + r := newRouterWithSvc(svc) + w := doJSON(t, r, http.MethodPost, "/api/v1/shows", map[string]any{ + "ep_num": 2, "ep_title": "No Start", "season_name": "S2", "playback_length": "00:24:00", + }) + if w.Code != http.StatusCreated { + t.Fatalf("expected 201, got %d: %s", w.Code, w.Body.String()) + } + if svc.lastCreate.StartTime != "22:00:00" { + t.Fatalf("expected default start time, got %s", svc.lastCreate.StartTime) + } +} + func TestListShows_OK(t *testing.T) { svc := &fakeSvc{ listRes: []episode.Episode{ diff --git a/backend/internal/http/types.go b/backend/internal/http/types.go index e549dd9..53e2cbf 100644 --- a/backend/internal/http/types.go +++ b/backend/internal/http/types.go @@ -18,7 +18,7 @@ type CreateShowReq struct { EpNum int `json:"ep_num" binding:"required" example:"1"` EpTitle string `json:"ep_title" binding:"required" example:"Pilot"` SeasonName string `json:"season_name" binding:"required" example:"Season 1"` - StartTime string `json:"start_time" binding:"required" example:"10:00:00"` + StartTime string `json:"start_time" example:"10:00:00"` // optional; defaults to 22:00:00 PlaybackLength string `json:"playback_length" binding:"required" example:"00:24:00"` } diff --git a/backend/internal/service/episode_service.go b/backend/internal/service/episode_service.go index f7c7a02..c542a42 100644 --- a/backend/internal/service/episode_service.go +++ b/backend/internal/service/episode_service.go @@ -32,6 +32,8 @@ func (s *Service) GetCurrent(ctx context.Context) (episode.Episode, error) { var hhmmss = regexp.MustCompile(`^(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d$`) +const defaultStartTime = "22:00:00" + func parseHHMMSSToDuration(hhmmss string) (time.Duration, error) { parts := strings.Split(hhmmss, ":") if len(parts) != 3 { @@ -68,6 +70,10 @@ func (s *Service) Create(ctx context.Context, in episode.NewShowInput) (episode. if in.EpNum <= 0 || strings.TrimSpace(in.EpTitle) == "" || strings.TrimSpace(in.SeasonName) == "" { return episode.Episode{}, episode.ErrInvalidShowInput } + in.StartTime = strings.TrimSpace(in.StartTime) + if in.StartTime == "" { + in.StartTime = defaultStartTime + } if !hhmmss.MatchString(in.StartTime) { return episode.Episode{}, episode.ErrInvalidStartTime } diff --git a/backend/internal/service/episode_service_test.go b/backend/internal/service/episode_service_test.go index e83e544..cf7344e 100644 --- a/backend/internal/service/episode_service_test.go +++ b/backend/internal/service/episode_service_test.go @@ -242,3 +242,21 @@ func TestEpisodeService_Create_OK(t *testing.T) { t.Fatalf("bad input passed: %+v", fr.createIn[0]) } } + +func TestEpisodeService_Create_DefaultStartTime(t *testing.T) { + fr := &fakeRepo{createRes: episode.Episode{StartTime: "22:00:00"}} + svc := service.NewEpisodeService(fr) + _, err := svc.Create(context.Background(), episode.NewShowInput{ + EpNum: 1, + EpTitle: "Pilot", + SeasonName: "S1", + StartTime: "", + PlaybackLength: "00:24:00", + }) + if err != nil { + t.Fatalf("unexpected: %v", err) + } + if len(fr.createIn) != 1 || fr.createIn[0].StartTime != "22:00:00" { + t.Fatalf("expected default start time, got %+v", fr.createIn) + } +}