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  }