github.com/line/line-bot-sdk-go/v7@v7.21.0/linebot/get_profile_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 TestGetProfile(t *testing.T) { 30 type want struct { 31 URLPath string 32 RequestBody []byte 33 Response *UserProfileResponse 34 Error error 35 } 36 testCases := []struct { 37 Label string 38 UserID string 39 ResponseCode int 40 Response []byte 41 Want want 42 }{ 43 { 44 Label: "Success", 45 UserID: "U0047556f2e40dba2456887320ba7c76d", 46 ResponseCode: 200, 47 Response: []byte(`{"userId":"U0047556f2e40dba2456887320ba7c76d","displayName":"BOT API","pictureUrl":"https://obs.line-apps.com/abcdefghijklmn","statusMessage":"Hello, LINE!","language":"en"}`), 48 Want: want{ 49 URLPath: fmt.Sprintf(APIEndpointGetProfile, "U0047556f2e40dba2456887320ba7c76d"), 50 RequestBody: []byte(""), 51 Response: &UserProfileResponse{ 52 UserID: "U0047556f2e40dba2456887320ba7c76d", 53 DisplayName: "BOT API", 54 PictureURL: "https://obs.line-apps.com/abcdefghijklmn", 55 StatusMessage: "Hello, LINE!", 56 Language: "en", 57 }, 58 }, 59 }, 60 { 61 Label: "Internal server error", 62 UserID: "U0047556f2e40dba2456887320ba7c76d", 63 ResponseCode: 500, 64 Response: []byte("500 Internal server error"), 65 Want: want{ 66 URLPath: fmt.Sprintf(APIEndpointGetProfile, "U0047556f2e40dba2456887320ba7c76d"), 67 RequestBody: []byte(""), 68 Error: &APIError{ 69 Code: 500, 70 }, 71 }, 72 }, 73 } 74 75 var currentTestIdx int 76 server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 77 defer r.Body.Close() 78 tc := testCases[currentTestIdx] 79 if r.Method != http.MethodGet { 80 t.Errorf("Method %s; want %s", r.Method, http.MethodGet) 81 } 82 if r.URL.Path != tc.Want.URLPath { 83 t.Errorf("URLPath %s; want %s", r.URL.Path, tc.Want.URLPath) 84 } 85 body, err := io.ReadAll(r.Body) 86 if err != nil { 87 t.Fatal(err) 88 } 89 if !reflect.DeepEqual(body, tc.Want.RequestBody) { 90 t.Errorf("RequestBody %s; want %s", body, tc.Want.RequestBody) 91 } 92 w.WriteHeader(tc.ResponseCode) 93 w.Write(tc.Response) 94 })) 95 defer server.Close() 96 97 dataServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 98 defer r.Body.Close() 99 t.Error("Unexpected Data API call") 100 w.WriteHeader(404) 101 w.Write([]byte(`{"message":"Not found"}`)) 102 })) 103 defer dataServer.Close() 104 105 client, err := mockClient(server, dataServer) 106 if err != nil { 107 t.Fatal(err) 108 } 109 for i, tc := range testCases { 110 currentTestIdx = i 111 t.Run(strconv.Itoa(i)+"/"+tc.Label, func(t *testing.T) { 112 res, err := client.GetProfile(tc.UserID).Do() 113 if tc.Want.Error != nil { 114 if !reflect.DeepEqual(err, tc.Want.Error) { 115 t.Errorf("Error %v; want %v", err, tc.Want.Error) 116 } 117 } else { 118 if err != nil { 119 t.Error(err) 120 } 121 } 122 if !reflect.DeepEqual(res, tc.Want.Response) { 123 t.Errorf("Response %v; want %v", res, tc.Want.Response) 124 } 125 }) 126 } 127 } 128 129 func TestGetProfileWithContext(t *testing.T) { 130 server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 131 defer r.Body.Close() 132 time.Sleep(10 * time.Millisecond) 133 w.Write([]byte("{}")) 134 })) 135 defer server.Close() 136 137 dataServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 138 defer r.Body.Close() 139 t.Error("Unexpected Data API call") 140 w.WriteHeader(404) 141 w.Write([]byte(`{"message":"Not found"}`)) 142 })) 143 defer dataServer.Close() 144 145 client, err := mockClient(server, dataServer) 146 if err != nil { 147 t.Fatal(err) 148 } 149 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Millisecond) 150 defer cancel() 151 _, err = client.GetProfile("U0047556f2e40dba2456887320ba7c76d").WithContext(ctx).Do() 152 expectCtxDeadlineExceed(ctx, err, t) 153 } 154 155 func BenchmarkGetProfile(b *testing.B) { 156 server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 157 defer r.Body.Close() 158 w.Write([]byte(`{"userId":"U","displayName":"A","pictureUrl":"https://","statusMessage":"B"}`)) 159 })) 160 defer server.Close() 161 162 dataServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 163 defer r.Body.Close() 164 b.Error("Unexpected Data API call") 165 w.WriteHeader(404) 166 w.Write([]byte(`{"message":"Not found"}`)) 167 })) 168 defer dataServer.Close() 169 170 client, err := mockClient(server, dataServer) 171 if err != nil { 172 b.Fatal(err) 173 } 174 b.ResetTimer() 175 for i := 0; i < b.N; i++ { 176 client.GetProfile("U0047556f2e40dba2456887320ba7c76d").Do() 177 } 178 } 179 180 func TestGetGroupMemberProfile(t *testing.T) { 181 type want struct { 182 URLPath string 183 RequestBody []byte 184 Response *UserProfileResponse 185 Error error 186 } 187 testCases := []struct { 188 Label string 189 GroupID string 190 UserID string 191 ResponseCode int 192 Response []byte 193 Want want 194 }{ 195 { 196 Label: "Success", 197 GroupID: "cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", 198 UserID: "U0047556f2e40dba2456887320ba7c76d", 199 ResponseCode: 200, 200 Response: []byte(`{"userId":"U0047556f2e40dba2456887320ba7c76d","displayName":"BOT API","pictureUrl":"https://obs.line-apps.com/abcdefghijklmn","statusMessage":"Hello, LINE!"}`), 201 Want: want{ 202 URLPath: fmt.Sprintf(APIEndpointGetGroupMemberProfile, "cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "U0047556f2e40dba2456887320ba7c76d"), 203 RequestBody: []byte(""), 204 Response: &UserProfileResponse{ 205 UserID: "U0047556f2e40dba2456887320ba7c76d", 206 DisplayName: "BOT API", 207 PictureURL: "https://obs.line-apps.com/abcdefghijklmn", 208 StatusMessage: "Hello, LINE!", 209 }, 210 }, 211 }, 212 { 213 Label: "Internal server error", 214 GroupID: "cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", 215 UserID: "U0047556f2e40dba2456887320ba7c76d", 216 ResponseCode: 500, 217 Response: []byte("500 Internal server error"), 218 Want: want{ 219 URLPath: fmt.Sprintf(APIEndpointGetGroupMemberProfile, "cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "U0047556f2e40dba2456887320ba7c76d"), 220 RequestBody: []byte(""), 221 Error: &APIError{ 222 Code: 500, 223 }, 224 }, 225 }, 226 } 227 228 var currentTestIdx int 229 server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 230 defer r.Body.Close() 231 tc := testCases[currentTestIdx] 232 if r.Method != http.MethodGet { 233 t.Errorf("Method %s; want %s", r.Method, http.MethodGet) 234 } 235 if r.URL.Path != tc.Want.URLPath { 236 t.Errorf("URLPath %s; want %s", r.URL.Path, tc.Want.URLPath) 237 } 238 body, err := io.ReadAll(r.Body) 239 if err != nil { 240 t.Fatal(err) 241 } 242 if !reflect.DeepEqual(body, tc.Want.RequestBody) { 243 t.Errorf("RequestBody %s; want %s", body, tc.Want.RequestBody) 244 } 245 w.WriteHeader(tc.ResponseCode) 246 w.Write(tc.Response) 247 })) 248 defer server.Close() 249 250 dataServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 251 defer r.Body.Close() 252 t.Error("Unexpected Data API call") 253 w.WriteHeader(404) 254 w.Write([]byte(`{"message":"Not found"}`)) 255 })) 256 defer dataServer.Close() 257 258 client, err := mockClient(server, dataServer) 259 if err != nil { 260 t.Fatal(err) 261 } 262 for i, tc := range testCases { 263 currentTestIdx = i 264 t.Run(strconv.Itoa(i)+"/"+tc.Label, func(t *testing.T) { 265 res, err := client.GetGroupMemberProfile(tc.GroupID, tc.UserID).Do() 266 if tc.Want.Error != nil { 267 if !reflect.DeepEqual(err, tc.Want.Error) { 268 t.Errorf("Error %v; want %v", err, tc.Want.Error) 269 } 270 } else { 271 if err != nil { 272 t.Error(err) 273 } 274 } 275 if !reflect.DeepEqual(res, tc.Want.Response) { 276 t.Errorf("Response %v; want %v", res, tc.Want.Response) 277 } 278 }) 279 } 280 } 281 282 func TestGetGroupMemberProfileWithContext(t *testing.T) { 283 server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 284 defer r.Body.Close() 285 time.Sleep(10 * time.Millisecond) 286 w.Write([]byte("{}")) 287 })) 288 defer server.Close() 289 290 dataServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 291 defer r.Body.Close() 292 t.Error("Unexpected Data API call") 293 w.WriteHeader(404) 294 w.Write([]byte(`{"message":"Not found"}`)) 295 })) 296 defer dataServer.Close() 297 298 client, err := mockClient(server, dataServer) 299 if err != nil { 300 t.Fatal(err) 301 } 302 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Millisecond) 303 defer cancel() 304 _, err = client.GetGroupMemberProfile("cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "U0047556f2e40dba2456887320ba7c76d").WithContext(ctx).Do() 305 expectCtxDeadlineExceed(ctx, err, t) 306 } 307 308 func BenchmarkGetGroupMemberProfile(b *testing.B) { 309 server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 310 defer r.Body.Close() 311 w.Write([]byte(`{"userId":"U","displayName":"A","pictureUrl":"https://","statusMessage":"B"}`)) 312 })) 313 defer server.Close() 314 315 dataServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 316 defer r.Body.Close() 317 b.Error("Unexpected Data API call") 318 w.WriteHeader(404) 319 w.Write([]byte(`{"message":"Not found"}`)) 320 })) 321 defer dataServer.Close() 322 323 client, err := mockClient(server, dataServer) 324 if err != nil { 325 b.Fatal(err) 326 } 327 b.ResetTimer() 328 for i := 0; i < b.N; i++ { 329 client.GetGroupMemberProfile("cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "U0047556f2e40dba2456887320ba7c76d").Do() 330 } 331 } 332 333 func TestGetRoomMemberProfile(t *testing.T) { 334 type want struct { 335 URLPath string 336 RequestBody []byte 337 Response *UserProfileResponse 338 Error error 339 } 340 testCases := []struct { 341 Label string 342 RoomID string 343 UserID string 344 ResponseCode int 345 Response []byte 346 Want want 347 }{ 348 { 349 Label: "Success", 350 RoomID: "cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", 351 UserID: "U0047556f2e40dba2456887320ba7c76d", 352 ResponseCode: 200, 353 Response: []byte(`{"userId":"U0047556f2e40dba2456887320ba7c76d","displayName":"BOT API","pictureUrl":"https://obs.line-apps.com/abcdefghijklmn","statusMessage":"Hello, LINE!"}`), 354 Want: want{ 355 URLPath: fmt.Sprintf(APIEndpointGetRoomMemberProfile, "cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "U0047556f2e40dba2456887320ba7c76d"), 356 RequestBody: []byte(""), 357 Response: &UserProfileResponse{ 358 UserID: "U0047556f2e40dba2456887320ba7c76d", 359 DisplayName: "BOT API", 360 PictureURL: "https://obs.line-apps.com/abcdefghijklmn", 361 StatusMessage: "Hello, LINE!", 362 }, 363 }, 364 }, 365 { 366 Label: "Internal server error", 367 RoomID: "cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", 368 UserID: "U0047556f2e40dba2456887320ba7c76d", 369 ResponseCode: 500, 370 Response: []byte("500 Internal server error"), 371 Want: want{ 372 URLPath: fmt.Sprintf(APIEndpointGetRoomMemberProfile, "cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "U0047556f2e40dba2456887320ba7c76d"), 373 RequestBody: []byte(""), 374 Error: &APIError{ 375 Code: 500, 376 }, 377 }, 378 }, 379 } 380 381 var currentTestIdx int 382 server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 383 defer r.Body.Close() 384 tc := testCases[currentTestIdx] 385 if r.Method != http.MethodGet { 386 t.Errorf("Method %s; want %s", r.Method, http.MethodGet) 387 } 388 if r.URL.Path != tc.Want.URLPath { 389 t.Errorf("URLPath %s; want %s", r.URL.Path, tc.Want.URLPath) 390 } 391 body, err := io.ReadAll(r.Body) 392 if err != nil { 393 t.Fatal(err) 394 } 395 if !reflect.DeepEqual(body, tc.Want.RequestBody) { 396 t.Errorf("RequestBody %s; want %s", body, tc.Want.RequestBody) 397 } 398 w.WriteHeader(tc.ResponseCode) 399 w.Write(tc.Response) 400 })) 401 defer server.Close() 402 403 dataServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 404 defer r.Body.Close() 405 t.Error("Unexpected Data API call") 406 w.WriteHeader(404) 407 w.Write([]byte(`{"message":"Not found"}`)) 408 })) 409 defer dataServer.Close() 410 411 client, err := mockClient(server, dataServer) 412 if err != nil { 413 t.Fatal(err) 414 } 415 for i, tc := range testCases { 416 currentTestIdx = i 417 t.Run(strconv.Itoa(i)+"/"+tc.Label, func(t *testing.T) { 418 res, err := client.GetRoomMemberProfile(tc.RoomID, tc.UserID).Do() 419 if tc.Want.Error != nil { 420 if !reflect.DeepEqual(err, tc.Want.Error) { 421 t.Errorf("Error %v; want %v", err, tc.Want.Error) 422 } 423 } else { 424 if err != nil { 425 t.Error(err) 426 } 427 } 428 if !reflect.DeepEqual(res, tc.Want.Response) { 429 t.Errorf("Response %v; want %v", res, tc.Want.Response) 430 } 431 }) 432 } 433 } 434 435 func TestGetRoomMemberProfileWithContext(t *testing.T) { 436 server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 437 defer r.Body.Close() 438 time.Sleep(10 * time.Millisecond) 439 w.Write([]byte("{}")) 440 })) 441 defer server.Close() 442 443 dataServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 444 defer r.Body.Close() 445 t.Error("Unexpected Data API call") 446 w.WriteHeader(404) 447 w.Write([]byte(`{"message":"Not found"}`)) 448 })) 449 defer dataServer.Close() 450 451 client, err := mockClient(server, dataServer) 452 if err != nil { 453 t.Fatal(err) 454 } 455 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Millisecond) 456 defer cancel() 457 _, err = client.GetRoomMemberProfile("cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "U0047556f2e40dba2456887320ba7c76d").WithContext(ctx).Do() 458 expectCtxDeadlineExceed(ctx, err, t) 459 } 460 461 func BenchmarkGetRoomMemberProfile(b *testing.B) { 462 server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 463 defer r.Body.Close() 464 w.Write([]byte(`{"userId":"U","displayName":"A","pictureUrl":"https://","statusMessage":"B"}`)) 465 })) 466 defer server.Close() 467 468 dataServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 469 defer r.Body.Close() 470 b.Error("Unexpected Data API call") 471 w.WriteHeader(404) 472 w.Write([]byte(`{"message":"Not found"}`)) 473 })) 474 defer dataServer.Close() 475 476 client, err := mockClient(server, dataServer) 477 if err != nil { 478 b.Fatal(err) 479 } 480 b.ResetTimer() 481 for i := 0; i < b.N; i++ { 482 client.GetRoomMemberProfile("cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "U0047556f2e40dba2456887320ba7c76d").Do() 483 } 484 }