test(web): a video file is accepted and the user is told the video was ignored (red)

Video with no audio is rejected for having none. A file with a video track is
accepted and marked had_video; every state of its page (queued, transcribing,
done, failed) says only its audio was used and the video was discarded, and a
plain audio file shows no such notice.

Red: the had_video column does not exist.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-01 18:42:33 +02:00
co-authored by Claude Sonnet 5.5
parent eb55c7d9d1
commit 7aec2538be
+64 -3
View File
@@ -158,12 +158,12 @@ func TestUploadPost_RejectionsAreSynchronousWithAMessageAndNoRow(t *testing.T) {
wantInBody []string
}{
{
name: "video names issue 28",
probe: uploads.Probe{Duration: time.Minute, HasAudio: true, HasVideo: true},
name: "video with no audio is rejected for having no audio",
probe: uploads.Probe{Duration: time.Minute, HasVideo: true},
maxBytes: 1 << 20,
content: "x",
wantStatus: http.StatusUnprocessableEntity,
wantInBody: []string{"video", "#28"},
wantInBody: []string{"no audio"},
},
{
name: "too long states both lengths",
@@ -275,3 +275,64 @@ func TestUploadStatus_DoneNamesTheEndpointThatServedIt(t *testing.T) {
"which backend served a transcript is a quality fact, and berget means the audio left the homelab")
assert.True(t, strings.Contains(b, "45 min"), "the audio length is shown")
}
func markHadVideo(t *testing.T, id string) {
t.Helper()
_, err := rawPool(t).Exec(context.Background(), `UPDATE uploaded_transcripts SET had_video = TRUE WHERE id = $1`, id)
require.NoError(t, err)
}
func TestUploadPost_AFileWithAVideoTrackIsAcceptedAndTheRowRemembersIt(t *testing.T) {
// A Teams meeting with the camera off is still an .mp4 with a video track.
app, sub := newUploadApp(t, uploads.Probe{Duration: 62 * time.Minute, HasAudio: true, HasVideo: true}, 200<<20)
rec := do(t, app, uploadReq(t, "Project notes", "Teams meeting.mp4", []byte("synthetic bytes")))
require.Equal(t, http.StatusSeeOther, rec.Code, "it must be accepted, not rejected as video")
var hadVideo bool
require.NoError(t, rawPool(t).QueryRow(context.Background(),
`SELECT had_video FROM uploaded_transcripts WHERE user_id = $1`, userID).Scan(&hadVideo))
assert.True(t, hadVideo)
assert.Len(t, sub.jobs, 1)
}
func TestUploadPost_AudioOnlyIsNotMarkedAsHavingHadVideo(t *testing.T) {
app, _ := newUploadApp(t, audioOK, 200<<20)
do(t, app, uploadReq(t, "Voice memo", "memo.m4a", []byte("x")))
var hadVideo bool
require.NoError(t, rawPool(t).QueryRow(context.Background(),
`SELECT had_video FROM uploaded_transcripts WHERE user_id = $1`, userID).Scan(&hadVideo))
assert.False(t, hadVideo)
}
func TestUploadStatus_TellsTheUserTheVideoWasIgnoredInEveryStateAndOnlyWhenItWas(t *testing.T) {
app, _ := newUploadApp(t, audioOK, 200<<20)
states := []struct{ status, content string }{
{"queued", ""}, {"transcribing", ""}, {"done", "Synthetic transcript."}, {"failed", "interrupted"},
}
for _, st := range states {
t.Run(st.status, func(t *testing.T) {
withVideo := seedUpload(t, userID, "camera off "+st.status, st.status, st.content)
markHadVideo(t, withVideo)
audioOnly := seedUpload(t, userID, "voice only "+st.status, st.status, st.content)
notice := body(t, do(t, app, get("/uploads/"+withVideo+"/status")))
plain := body(t, do(t, app, get("/uploads/"+audioOnly+"/status")))
assert.Contains(t, notice, "video track")
assert.Contains(t, notice, "only its audio was used", "say what happened, not just that something did")
assert.Contains(t, notice, "discarded")
assert.NotContains(t, plain, "video track", "no notice when there was no video")
})
}
}
func TestUploadPage_AlsoCarriesTheVideoNotice(t *testing.T) {
app, _ := newUploadApp(t, audioOK, 200<<20)
id := seedUpload(t, userID, "camera off", "done", "Synthetic transcript.")
markHadVideo(t, id)
assert.Contains(t, body(t, do(t, app, get("/uploads/"+id))), "only its audio was used")
}