The picker accepts one MP4 or WebM, the thread lightbox zooms photos, and Discord gets the video as a file on a follow-up message so photo embeds still render.
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"plumber/internal/events"
|
||||
"plumber/internal/store"
|
||||
@@ -209,6 +210,125 @@ func TestOutboundUpdateWithoutLinkCreates(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestOutboundAttachesVideoFile(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
bus := events.New()
|
||||
defer bus.Close()
|
||||
events.SubscribeRelease(bus)
|
||||
links := newMemoryLinks()
|
||||
api := &fakeAPI{}
|
||||
bot := New("channel-1", links, api)
|
||||
bot.bus = bus
|
||||
|
||||
released := make(chan struct{})
|
||||
bot.Handle(context.Background(), events.PostCreated{
|
||||
PostEvent: events.PostEvent{
|
||||
PostID: "root-1",
|
||||
RootID: "root-1",
|
||||
Title: "Valve clip",
|
||||
Body: "Watch the handle.",
|
||||
AuthorName: "sam",
|
||||
Permalink: "https://www.askaplumberfirst.com/questions/root-1#post-root-1",
|
||||
Images: []events.Image{{URL: "https://cdn.example/clip.mp4", Kind: "video"}},
|
||||
},
|
||||
Media: []events.Media{{
|
||||
Name: "clip.mp4",
|
||||
ContentType: "video/mp4",
|
||||
Kind: "video",
|
||||
Bytes: []byte("fake-mp4"),
|
||||
}},
|
||||
Release: func() { close(released) },
|
||||
})
|
||||
|
||||
if len(api.sends) != 3 ||
|
||||
api.sends[1].Kind != "thread-msg" ||
|
||||
api.sends[2].Kind != "thread-msg" {
|
||||
t.Fatalf("sends = %+v", api.sends)
|
||||
}
|
||||
if len(api.sends[1].Msg.Files) != 0 {
|
||||
t.Fatalf("text message files = %+v", api.sends[1].Msg.Files)
|
||||
}
|
||||
files := api.sends[2].Msg.Files
|
||||
if len(files) != 1 || files[0].Name != "clip.mp4" || files[0].ContentType != "video/mp4" {
|
||||
t.Fatalf("video files = %+v", files)
|
||||
}
|
||||
content := messageContent(api.sends[1].Msg)
|
||||
if strings.Contains(content, "https://cdn.example/clip.mp4") {
|
||||
t.Fatalf("content still has video URL: %q", content)
|
||||
}
|
||||
select {
|
||||
case <-released:
|
||||
case <-time.After(time.Second):
|
||||
t.Fatal("PostedToDiscord did not release")
|
||||
}
|
||||
}
|
||||
|
||||
func TestOutboundPhotosThenVideo(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
api := &fakeAPI{}
|
||||
bot := New("channel-1", newMemoryLinks(), api)
|
||||
bot.Handle(context.Background(), events.PostCreated{
|
||||
PostEvent: events.PostEvent{
|
||||
PostID: "root-1",
|
||||
RootID: "root-1",
|
||||
Title: "Valve clip",
|
||||
Body: "Photo and video.",
|
||||
AuthorName: "sam",
|
||||
Images: []events.Image{
|
||||
{URL: "https://cdn.example/a.jpg"},
|
||||
{URL: "https://cdn.example/clip.mp4", Kind: "video"},
|
||||
},
|
||||
},
|
||||
Media: []events.Media{
|
||||
{Name: "still.jpg", ContentType: "image/jpeg", Kind: "image", Bytes: []byte("jpeg")},
|
||||
{Name: "clip.mp4", ContentType: "video/mp4", Kind: "video", Bytes: []byte("mp4")},
|
||||
},
|
||||
})
|
||||
if len(api.sends) != 3 ||
|
||||
api.sends[1].Kind != "thread-msg" ||
|
||||
api.sends[2].Kind != "thread-msg" {
|
||||
t.Fatalf("sends = %+v", api.sends)
|
||||
}
|
||||
photos := api.sends[1].Msg.Files
|
||||
if len(photos) != 0 {
|
||||
t.Fatalf("text message should not attach files: %+v", photos)
|
||||
}
|
||||
if got := api.sends[1].Msg.ImageURLs; len(got) != 1 || got[0] != "https://cdn.example/a.jpg" {
|
||||
t.Fatalf("text message images = %v", got)
|
||||
}
|
||||
if embeds := toEmbeds(api.sends[1].Msg); len(embeds) == 0 || embeds[0].Image == nil || embeds[0].Image.URL != "https://cdn.example/a.jpg" {
|
||||
t.Fatalf("text embeds = %+v", toEmbeds(api.sends[1].Msg))
|
||||
}
|
||||
videos := api.sends[2].Msg.Files
|
||||
if len(videos) != 1 || videos[0].Name != "clip.mp4" {
|
||||
t.Fatalf("video files = %+v", videos)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOutboundReleasesWhenAlreadyLinked(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
links := newMemoryLinks()
|
||||
if err := links.Upsert(context.Background(), store.DiscordLink{
|
||||
PostID: "root-1",
|
||||
MessageID: "d-root",
|
||||
ThreadID: "thread-1",
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
released := false
|
||||
bot := New("channel-1", links, &fakeAPI{})
|
||||
bot.Handle(context.Background(), events.PostCreated{
|
||||
PostEvent: events.PostEvent{PostID: "root-1", RootID: "root-1", Title: "Already posted"},
|
||||
Release: func() { released = true },
|
||||
})
|
||||
if !released {
|
||||
t.Fatal("skipped send did not release held upload")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormatMessage(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -218,7 +338,10 @@ func TestFormatMessage(t *testing.T) {
|
||||
City: "Oakland",
|
||||
AuthorName: "sam",
|
||||
Permalink: "https://example.com/q",
|
||||
Images: []events.Image{{URL: "https://cdn.example/a.jpg", Description: "ignored"}},
|
||||
Images: []events.Image{
|
||||
{URL: "https://cdn.example/a.jpg", Description: "ignored"},
|
||||
{URL: "https://cdn.example/clip.mp4", Kind: "video"},
|
||||
},
|
||||
})
|
||||
if got.Title != "Leaky sink" ||
|
||||
got.Description != "It drips." ||
|
||||
@@ -226,7 +349,8 @@ func TestFormatMessage(t *testing.T) {
|
||||
got.Author != "sam" ||
|
||||
got.URL != "https://example.com/q" ||
|
||||
got.ThreadName != "sam asks: Leaky sink" ||
|
||||
len(got.ImageURLs) != 1 {
|
||||
len(got.ImageURLs) != 1 || got.ImageURLs[0] != "https://cdn.example/a.jpg" ||
|
||||
len(got.VideoURLs) != 1 || got.VideoURLs[0] != "https://cdn.example/clip.mp4" {
|
||||
t.Fatalf("format = %+v", got)
|
||||
}
|
||||
|
||||
@@ -237,7 +361,9 @@ func TestFormatMessage(t *testing.T) {
|
||||
content := messageContent(got)
|
||||
if strings.Contains(content, "Leaky sink") ||
|
||||
!strings.Contains(content, "It drips.") ||
|
||||
!strings.Contains(content, "Oakland") {
|
||||
!strings.Contains(content, "Oakland") ||
|
||||
!strings.Contains(content, "https://cdn.example/a.jpg") ||
|
||||
!strings.Contains(content, "https://cdn.example/clip.mp4") {
|
||||
t.Fatalf("content = %q", content)
|
||||
}
|
||||
if publicURL("/questions/x") != "" || publicURL("http://localhost:8080/q") != "" {
|
||||
|
||||
Reference in New Issue
Block a user