|
2 | 2 | package tg |
3 | 3 |
|
4 | 4 | import ( |
| 5 | + "bytes" |
5 | 6 | "context" |
| 7 | + "encoding/json" |
| 8 | + "net/http" |
| 9 | + "strings" |
6 | 10 | "testing" |
7 | 11 | ) |
8 | 12 |
|
@@ -106,3 +110,147 @@ func TestEphemeralTextSuppressesLinkPreviewsLikeEveryOtherSend(t *testing.T) { |
106 | 110 | }) |
107 | 111 | } |
108 | 112 | } |
| 113 | + |
| 114 | +// A bot that is not an admin may answer a button press with an ephemeral |
| 115 | +// photo, shown to the one who pressed in place of the message they pressed |
| 116 | +// on. |
| 117 | +func TestSendPhotoCanBeEphemeral(t *testing.T) { |
| 118 | + handler, method, body := capture(t, `{"ok":true,"result":{"message_id":0,"ephemeral_message_id":5}}`) |
| 119 | + c, _ := newTestClient(t, handler) |
| 120 | + |
| 121 | + msg, err := c.SendPhoto(context.Background(), 42, InputFileString{Data: "file-1"}, CaptionOptions{ |
| 122 | + ReplyTo: 10, |
| 123 | + Caption: "only for you", |
| 124 | + Ephemeral: &Ephemeral{ReceiverUserID: 77, CallbackQueryID: "cb-1", ReplaceCallbackQueryMessage: true}, |
| 125 | + }) |
| 126 | + if err != nil { |
| 127 | + t.Fatalf("SendPhoto: %v", err) |
| 128 | + } |
| 129 | + if *method != "sendPhoto" || msg.EphemeralMessageID != 5 { |
| 130 | + t.Fatalf("method %q, message %+v", *method, msg) |
| 131 | + } |
| 132 | + params, _ := (*body)["ephemeral_message_parameters"].(map[string]any) |
| 133 | + if params["receiver_user_id"] != float64(77) || params["callback_query_id"] != "cb-1" || params["replace_callback_query_message"] != true { |
| 134 | + t.Fatalf("ephemeral_message_parameters = %v", params) |
| 135 | + } |
| 136 | + if _, flat := (*body)["receiver_user_id"]; flat { |
| 137 | + t.Fatal("receiver_user_id at the top level is the removed 10.2 shape") |
| 138 | + } |
| 139 | + // An ephemeral reply needs the message it answers to be there, so the |
| 140 | + // flag the public send carries is left out. |
| 141 | + reply, _ := (*body)["reply_parameters"].(map[string]any) |
| 142 | + if reply["message_id"] != float64(10) || len(reply) != 1 { |
| 143 | + t.Fatalf("reply_parameters = %v", reply) |
| 144 | + } |
| 145 | +} |
| 146 | + |
| 147 | +// An ephemeral command authorizes the answer through the reply to it. |
| 148 | +func TestAnEphemeralReplyNamesTheEphemeralMessage(t *testing.T) { |
| 149 | + handler, _, body := capture(t, `{"ok":true,"result":{"message_id":0,"ephemeral_message_id":6}}`) |
| 150 | + c, _ := newTestClient(t, handler) |
| 151 | + |
| 152 | + if _, err := c.SendAnimation(context.Background(), 42, InputFileString{Data: "loop"}, AnimationOptions{CaptionOptions: CaptionOptions{ |
| 153 | + ReplyToEphemeral: 3, |
| 154 | + Ephemeral: &Ephemeral{ReceiverUserID: 77}, |
| 155 | + }}); err != nil { |
| 156 | + t.Fatalf("SendAnimation: %v", err) |
| 157 | + } |
| 158 | + reply, _ := (*body)["reply_parameters"].(map[string]any) |
| 159 | + if reply["ephemeral_message_id"] != float64(3) || len(reply) != 1 { |
| 160 | + t.Fatalf("reply_parameters = %v", reply) |
| 161 | + } |
| 162 | + params, _ := (*body)["ephemeral_message_parameters"].(map[string]any) |
| 163 | + if len(params) != 1 || params["receiver_user_id"] != float64(77) { |
| 164 | + t.Fatalf("ephemeral_message_parameters = %v, want the receiver alone", params) |
| 165 | + } |
| 166 | +} |
| 167 | + |
| 168 | +func TestAnUploadedEphemeralPhotoCarriesItsParametersAsJSON(t *testing.T) { |
| 169 | + handler, got := captureUpload(t, `{"ok":true,"result":{"message_id":0,"ephemeral_message_id":7}}`) |
| 170 | + c, _ := newTestClient(t, handler) |
| 171 | + |
| 172 | + if _, err := c.SendPhoto(context.Background(), 42, InputFileUpload{Filename: "card.png", Data: bytes.NewReader([]byte("png"))}, CaptionOptions{ |
| 173 | + Ephemeral: &Ephemeral{ReceiverUserID: 77}, |
| 174 | + }); err != nil { |
| 175 | + t.Fatalf("SendPhoto: %v", err) |
| 176 | + } |
| 177 | + if got.files["photo"] != "png" || got.fields["ephemeral_message_parameters"] != `{"receiver_user_id":77}` { |
| 178 | + t.Fatalf("fields %v, files %v", got.fields, got.files) |
| 179 | + } |
| 180 | +} |
| 181 | + |
| 182 | +// The edit uploads a new picture the way editMessageMedia does, and addresses |
| 183 | +// the message by the flat receiver. |
| 184 | +func TestEditEphemeralMessageMediaUploadsTheNewPhoto(t *testing.T) { |
| 185 | + handler, got := captureUpload(t, `{"ok":true,"result":true}`) |
| 186 | + c, _ := newTestClient(t, handler) |
| 187 | + |
| 188 | + markup := &InlineKeyboardMarkup{InlineKeyboard: [][]InlineKeyboardButton{{{Text: "Generate", CallbackData: "go"}}}} |
| 189 | + err := c.EditEphemeralMessageMedia(context.Background(), 42, 77, 5, InputMediaPhoto{ |
| 190 | + Media: InputFileUpload{Filename: "card2.png", Data: bytes.NewReader([]byte("png2"))}, |
| 191 | + Caption: "<b>new</b>", |
| 192 | + }, markup) |
| 193 | + if err != nil { |
| 194 | + t.Fatalf("EditEphemeralMessageMedia: %v", err) |
| 195 | + } |
| 196 | + if got.method != "editEphemeralMessageMedia" { |
| 197 | + t.Fatalf("method = %q", got.method) |
| 198 | + } |
| 199 | + if got.fields["chat_id"] != "42" || got.fields["receiver_user_id"] != "77" || got.fields["ephemeral_message_id"] != "5" { |
| 200 | + t.Fatalf("fields = %v", got.fields) |
| 201 | + } |
| 202 | + var media map[string]any |
| 203 | + if err := json.Unmarshal([]byte(got.fields["media"]), &media); err != nil { |
| 204 | + t.Fatalf("media = %q: %v", got.fields["media"], err) |
| 205 | + } |
| 206 | + attach, _ := media["media"].(string) |
| 207 | + if media["type"] != "photo" || media["caption"] != "<b>new</b>" || !strings.HasPrefix(attach, "attach://") { |
| 208 | + t.Fatalf("media = %v", media) |
| 209 | + } |
| 210 | + if got.files[strings.TrimPrefix(attach, "attach://")] != "png2" { |
| 211 | + t.Fatalf("files = %v", got.files) |
| 212 | + } |
| 213 | + if !strings.Contains(got.fields["reply_markup"], `"callback_data":"go"`) { |
| 214 | + t.Fatalf("reply_markup = %q", got.fields["reply_markup"]) |
| 215 | + } |
| 216 | +} |
| 217 | + |
| 218 | +func TestEditEphemeralMessageCaptionAndButtons(t *testing.T) { |
| 219 | + handler, method, body := capture(t, `{"ok":true,"result":true}`) |
| 220 | + c, _ := newTestClient(t, handler) |
| 221 | + |
| 222 | + if err := c.EditEphemeralMessageCaption(context.Background(), 42, 77, 5, "≈ $0.04", EditCaptionOptions{ShowCaptionAboveMedia: true}); err != nil { |
| 223 | + t.Fatalf("EditEphemeralMessageCaption: %v", err) |
| 224 | + } |
| 225 | + if *method != "editEphemeralMessageCaption" || (*body)["caption"] != "≈ $0.04" || (*body)["parse_mode"] != "HTML" || |
| 226 | + (*body)["show_caption_above_media"] != true || (*body)["receiver_user_id"] != float64(77) || (*body)["ephemeral_message_id"] != float64(5) { |
| 227 | + t.Fatalf("%s %v", *method, *body) |
| 228 | + } |
| 229 | + if err := c.EditEphemeralMessageReplyMarkup(context.Background(), 42, 77, 5, nil); err != nil { |
| 230 | + t.Fatalf("EditEphemeralMessageReplyMarkup: %v", err) |
| 231 | + } |
| 232 | + if _, has := (*body)["reply_markup"]; *method != "editEphemeralMessageReplyMarkup" || has { |
| 233 | + t.Fatalf("%s %v", *method, *body) |
| 234 | + } |
| 235 | +} |
| 236 | + |
| 237 | +// A press that changes nothing is not a failure, as for every other edit. |
| 238 | +func TestEphemeralEditsTreatNotModifiedAsSuccess(t *testing.T) { |
| 239 | + c, _ := newTestClient(t, func(w http.ResponseWriter, r *http.Request) { |
| 240 | + w.WriteHeader(http.StatusBadRequest) |
| 241 | + _, _ = w.Write([]byte(`{"ok":false,"description":"Bad Request: message is not modified"}`)) |
| 242 | + }) |
| 243 | + ctx := context.Background() |
| 244 | + if err := c.EditEphemeralMessageMedia(ctx, 1, 2, 3, InputMediaPhoto{Media: InputFileString{Data: "id"}}, nil); err != nil { |
| 245 | + t.Fatalf("media: %v", err) |
| 246 | + } |
| 247 | + if err := c.EditEphemeralMessageCaption(ctx, 1, 2, 3, "x", EditCaptionOptions{}); err != nil { |
| 248 | + t.Fatalf("caption: %v", err) |
| 249 | + } |
| 250 | + if err := c.EditEphemeralMessageReplyMarkup(ctx, 1, 2, 3, nil); err != nil { |
| 251 | + t.Fatalf("markup: %v", err) |
| 252 | + } |
| 253 | + if err := c.EditEphemeralMessageMedia(ctx, 1, 2, 3, nil, nil); err == nil { |
| 254 | + t.Fatal("an edit without media was sent") |
| 255 | + } |
| 256 | +} |
0 commit comments