FEAT: Return Playback URL in Get Videos
Build, Push and Deploy CMS / build-push-deploy (push) Successful in 2m28s
Deploy Infrastructure / pulumi-up (push) Successful in 2s

This commit is contained in:
FahdShalhoub
2026-08-27 21:31:13 +03:00
parent 8c75d7500f
commit 0cfd89f200
7 changed files with 146 additions and 20 deletions
+60 -11
View File
@@ -429,15 +429,32 @@ func mediaConvertReportsState(t gobdd.StepTest, ctx gobdd.Context, state string)
t.Fatalf("no transcoding job has been started, so there is no job to report on")
return
}
publishJobState(t, w.video.MediaConvertJobID, state)
// A real COMPLETE from an HLS output group always names the manifests it
// wrote; the other states carry no output at all.
playlist := ""
if state == "COMPLETE" {
playlist = playlistPathFor(w.video.StorageKey)
}
publishJobState(t, w.video.MediaConvertJobID, state, playlist)
}
func mediaConvertReportsStateWithoutPlaylist(t gobdd.StepTest, ctx gobdd.Context, state string) {
w := worldOf(t, ctx)
if strings.TrimSpace(w.video.MediaConvertJobID) == "" {
t.Fatalf("no transcoding job has been started, so there is no job to report on")
return
}
publishJobState(t, w.video.MediaConvertJobID, state, "")
}
func mediaConvertReportsStateForJob(t gobdd.StepTest, ctx gobdd.Context, jobID, state string) {
worldOf(t, ctx) // keeps the step honest about needing a scenario world
publishJobState(t, jobID, state)
publishJobState(t, jobID, state, "")
}
func publishJobState(t gobdd.StepTest, jobID, state string) {
func publishJobState(t gobdd.StepTest, jobID, state, playlistPath string) {
background := context.Background()
publisher, err := newEventPublisher(background)
@@ -445,7 +462,7 @@ func publishJobState(t gobdd.StepTest, jobID, state string) {
t.Fatalf("could not reach the job events topic: %s", err)
return
}
if err := publisher.publishJobState(background, jobID, state); err != nil {
if err := publisher.publishJobState(background, jobID, state, playlistPath); err != nil {
t.Fatalf("could not publish the job state change: %s", err)
}
}
@@ -481,25 +498,57 @@ func theVideoKeepsStatus(t gobdd.StepTest, ctx gobdd.Context, want string) {
}
}
// currentStatus re-reads the video over the API. It deliberately does not
// touch w.last: these steps assert on the record, not on an exchange.
func currentStatus(t gobdd.StepTest, w *world) string {
// currentVideo re-reads the video over the API. It deliberately does not touch
// w.last: these steps assert on the record, not on an exchange.
func currentVideo(t gobdd.StepTest, w *world) videoBody {
result, err := w.client.get("/api/videos/" + w.video.ID)
if err != nil {
t.Fatalf("could not re-read the video: %s", err)
return ""
return videoBody{}
}
if result.status != 200 {
t.Fatalf("could not re-read the video: %s", result.summary())
return ""
return videoBody{}
}
var body videoBody
if err := result.json(&body); err != nil {
t.Fatalf("could not decode the video: %s", err)
return ""
return videoBody{}
}
return body
}
func currentStatus(t gobdd.StepTest, w *world) string {
return currentVideo(t, w).Status
}
func theVideoHasAPlaybackURL(t gobdd.StepTest, ctx gobdd.Context) {
w := worldOf(t, ctx)
video := currentVideo(t, w)
want := playbackURLFor(video.StorageKey)
if video.PlaybackURL != want {
t.Errorf("expected the playback URL %q, got %q", want, video.PlaybackURL)
return
}
// The point of the rewrite: what is stored has to be something a player
// can fetch, not the s3:// path MediaConvert reported.
if !strings.HasSuffix(video.PlaybackURL, ".m3u8") {
t.Errorf("the playback URL %q is not an HLS playlist", video.PlaybackURL)
}
if strings.HasPrefix(video.PlaybackURL, "s3://") {
t.Errorf("the playback URL %q is still an S3 URI, which no player can fetch", video.PlaybackURL)
}
}
func theVideoHasNoPlaybackURL(t gobdd.StepTest, ctx gobdd.Context) {
w := worldOf(t, ctx)
if got := currentVideo(t, w).PlaybackURL; got != "" {
t.Errorf("expected no playback URL, got %q", got)
}
return body.Status
}
// askForThatVideoWrittenAs re-reads the video by a different, still-valid