github.com/line/line-bot-sdk-go/v7@v7.21.0/linebot/get_content_test.go (about) 1 // Copyright 2016 LINE Corporation 2 // 3 // LINE Corporation licenses this file to you under the Apache License, 4 // version 2.0 (the "License"); you may not use this file except in compliance 5 // with the License. You may obtain a copy of the License at: 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations 13 // under the License. 14 15 package linebot 16 17 import ( 18 "context" 19 "fmt" 20 "io" 21 "net/http" 22 "net/http/httptest" 23 "reflect" 24 "strconv" 25 "testing" 26 "time" 27 ) 28 29 func TestGetMessageContent(t *testing.T) { 30 type want struct { 31 URLPath string 32 RequestBody []byte 33 Response *MessageContentResponse 34 ResponseContent []byte 35 Error error 36 } 37 testCases := []struct { 38 Label string 39 MessageID string 40 ResponseCode int 41 Response []byte 42 ResponseHeader map[string]string 43 Want want 44 }{ 45 { 46 Label: "Success", 47 MessageID: "325708", 48 ResponseCode: 200, 49 Response: []byte{0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10}, 50 ResponseHeader: map[string]string{ 51 "Content-Type": "image/jpeg", 52 "Content-Length": "6", 53 }, 54 Want: want{ 55 URLPath: fmt.Sprintf(APIEndpointGetMessageContent, "325708"), 56 RequestBody: []byte(""), 57 Response: &MessageContentResponse{ 58 ContentType: "image/jpeg", 59 ContentLength: 6, 60 }, 61 ResponseContent: []byte{0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10}, 62 }, 63 }, 64 { 65 Label: "503 Service Unavailable", 66 MessageID: "325708", 67 ResponseCode: 503, 68 Response: []byte("Service Unavailable"), 69 Want: want{ 70 URLPath: fmt.Sprintf(APIEndpointGetMessageContent, "325708"), 71 RequestBody: []byte(""), 72 Error: &APIError{ 73 Code: 503, 74 }, 75 }, 76 }, 77 } 78 79 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 80 defer r.Body.Close() 81 t.Error("Unexpected API call") 82 w.WriteHeader(404) 83 w.Write([]byte(`{"message":"Not found"}`)) 84 })) 85 defer server.Close() 86 87 var currentTestIdx int 88 dataServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 89 defer r.Body.Close() 90 tc := testCases[currentTestIdx] 91 if r.Method != http.MethodGet { 92 t.Errorf("Method %s; want %s", r.Method, http.MethodGet) 93 } 94 if r.URL.Path != tc.Want.URLPath { 95 t.Errorf("URLPath %s; want %s", r.URL.Path, tc.Want.URLPath) 96 } 97 body, err := io.ReadAll(r.Body) 98 if err != nil { 99 t.Fatal(err) 100 } 101 if !reflect.DeepEqual(body, tc.Want.RequestBody) { 102 t.Errorf("RequestBody %s; want %s", body, tc.Want.RequestBody) 103 } 104 for k, v := range tc.ResponseHeader { 105 w.Header().Add(k, v) 106 } 107 w.WriteHeader(tc.ResponseCode) 108 w.Write(tc.Response) 109 })) 110 defer dataServer.Close() 111 112 client, err := mockClient(server, dataServer) 113 if err != nil { 114 t.Fatal(err) 115 } 116 for i, tc := range testCases { 117 currentTestIdx = i 118 t.Run(strconv.Itoa(i)+"/"+tc.Label, func(t *testing.T) { 119 res, err := client.GetMessageContent(tc.MessageID).Do() 120 if tc.Want.Error != nil { 121 if !reflect.DeepEqual(err, tc.Want.Error) { 122 t.Errorf("Error %v; want %v", err, tc.Want.Error) 123 } 124 } else { 125 if err != nil { 126 t.Error(err) 127 } 128 } 129 if tc.Want.Response != nil { 130 body := res.Content 131 defer body.Close() 132 res.Content = nil // Set nil because streams aren't comparable. 133 if !reflect.DeepEqual(res, tc.Want.Response) { 134 t.Errorf("Response %v; want %v", res, tc.Want.Response) 135 } 136 bodyGot, err := io.ReadAll(body) 137 if err != nil { 138 t.Fatal(err) 139 } 140 if !reflect.DeepEqual(bodyGot, tc.Want.ResponseContent) { 141 t.Errorf("ResponseContent %X; want %X", bodyGot, tc.Want.ResponseContent) 142 } 143 } 144 }) 145 } 146 } 147 148 func TestGetMessageContentWithContext(t *testing.T) { 149 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 150 defer r.Body.Close() 151 t.Error("Unexpected API call") 152 w.WriteHeader(404) 153 w.Write([]byte(`{"message":"Not found"}`)) 154 })) 155 defer server.Close() 156 157 dataServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 158 defer r.Body.Close() 159 time.Sleep(10 * time.Millisecond) 160 w.Write([]byte{0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10}) 161 })) 162 defer dataServer.Close() 163 164 client, err := mockClient(server, dataServer) 165 if err != nil { 166 t.Fatal(err) 167 } 168 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Millisecond) 169 defer cancel() 170 _, err = client.GetMessageContent("325708A").WithContext(ctx).Do() 171 expectCtxDeadlineExceed(ctx, err, t) 172 } 173 174 func BenchmarkGetMessageContent(b *testing.B) { 175 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 176 defer r.Body.Close() 177 b.Error("Unexpected API call") 178 w.WriteHeader(404) 179 w.Write([]byte(`{"message":"Not found"}`)) 180 })) 181 defer server.Close() 182 183 dataServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 184 defer r.Body.Close() 185 w.Write([]byte{0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10}) 186 })) 187 defer dataServer.Close() 188 189 client, err := mockClient(server, dataServer) 190 if err != nil { 191 b.Fatal(err) 192 } 193 b.ResetTimer() 194 for i := 0; i < b.N; i++ { 195 res, _ := client.GetMessageContent("325708A").Do() 196 defer res.Content.Close() 197 io.ReadAll(res.Content) 198 } 199 }