]> git.giacomolli.uk - onechat/blob - image_show_test.go
Show stored images to the user
[onechat] / image_show_test.go
1 package main
2
3 import (
4 "encoding/json"
5 "net/http"
6 "path/filepath"
7 "testing"
8
9 "github.com/stretchr/testify/require"
10 )
11
12 func TestImageShowUsesStoredImageForTelegramAndTerminal(t *testing.T) {
13 picture := imageTestPNG(t, 5, 4)
14 store := &ImageStore{dir: filepath.Join(t.TempDir(), imageDirName)}
15 name, err := store.Save(picture)
16 require.NoError(t, err)
17
18 telegram := newTelegramFake(t)
19 bot, logs := telegramStartTestBot(t, telegram)
20 box := &Toolbox{imageShow: &ImageShow{
21 store: store,
22 bot: bot,
23 }}
24 args, err := json.Marshal(ToolImageShowArguments{
25 Image: name,
26 Caption: "A red point.",
27 })
28 require.NoError(t, err)
29
30 output := box.run(t.Context(), "image_show", string(args))
31 require.Equal(t, imageText([]string{name}, "A red point.")+"\n"+filepath.Join(store.dir, name), output)
32
33 calls := telegram.Calls()
34 require.Len(t, calls, 1)
35 require.Equal(t, "sendPhoto", calls[0].method)
36 require.Equal(t, "4242", calls[0].params["chat_id"])
37 require.Equal(t, "A red point.", calls[0].params["caption"])
38 require.Equal(t, name, calls[0].params["photo_name"])
39 require.Equal(t, picture, calls[0].params["photo"])
40 require.Empty(t, logs.String())
41 }
42
43 func TestImageShowRefusesUnknownNamesBeforeSending(t *testing.T) {
44 telegram := newTelegramFake(t)
45 bot, _ := telegramStartTestBot(t, telegram)
46 show := &ImageShow{
47 store: &ImageStore{dir: t.TempDir()},
48 bot: bot,
49 }
50
51 for _, name := range []string{"../image.png", "unknown", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.png"} {
52 _, err := show.Show(t.Context(), name, "Do not send this.")
53 require.Error(t, err)
54 }
55
56 require.Empty(t, telegram.Calls())
57
58 box := &Toolbox{}
59 require.Equal(t, `error: unknown tool "image_show"`, box.run(t.Context(), "image_show", `{"image":"unknown","caption":""}`))
60 }
61
62 func TestImageShowFallsBackOnlyWhenTelegramRefusesPhoto(t *testing.T) {
63 testCases := []struct {
64 name string
65 status int
66 methods []string
67 failure bool
68 }{
69 {
70 name: "refused photo sends document",
71 status: http.StatusBadRequest,
72 methods: []string{"sendPhoto", "sendDocument"},
73 },
74 {
75 name: "uncertain server error does not send twice",
76 status: http.StatusBadGateway,
77 methods: []string{"sendPhoto"},
78 failure: true,
79 },
80 }
81 for _, tc := range testCases {
82 t.Run(tc.name, func(t *testing.T) {
83 telegram := newTelegramFake(t)
84 telegram.fail = func(call TelegramFakeCall) (int, string) {
85 if call.method == "sendPhoto" {
86 return tc.status, "photo refused"
87 }
88
89 return 0, ""
90 }
91 store := &ImageStore{dir: t.TempDir()}
92 picture := imageTestPNG(t, 3, 3)
93 name, err := store.Save(picture)
94 require.NoError(t, err)
95
96 bot, _ := telegramStartTestBot(t, telegram)
97 show := &ImageShow{
98 store: store,
99 bot: bot,
100 }
101 _, err = show.Show(t.Context(), name, "Caption")
102 if tc.failure {
103 require.Error(t, err)
104 } else {
105 require.NoError(t, err)
106 }
107
108 var methods []string
109
110 for _, call := range telegram.Calls() {
111 methods = append(methods, call.method)
112 if call.method == "sendDocument" {
113 require.Equal(t, picture, call.params["document"])
114 require.Equal(t, name, call.params["document_name"])
115 require.Equal(t, "Caption", call.params["caption"])
116 }
117 }
118
119 require.Equal(t, tc.methods, methods)
120 })
121 }
122 }
123
124 func TestAgentShowsImageInTerminalWithoutTelegram(t *testing.T) {
125 server := newModelFake(t)
126 test := newTestTurnLoop(t, server)
127 name, err := test.agent.Images().Save(imageTestPNG(t, 2, 2))
128 require.NoError(t, err)
129
130 output := test.loop.tools.run(t.Context(), "image_show", `{"image":"`+name+`","caption":"Here it is."}`)
131 require.Equal(t, imageText([]string{name}, "Here it is.")+"\n"+filepath.Join(test.agent.Images().dir, name), output)
132 require.Contains(t, terminalEventText(Event{
133 Kind: "echo",
134 Text: output,
135 }), filepath.Join(test.agent.Images().dir, name))
136 }