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  }