github.com/line/line-bot-sdk-go/v7@v7.21.0/linebot/raw_test.go (about)

     1  // Copyright 2021 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  	"bytes"
    19  	"io"
    20  	"net/http"
    21  	"net/http/httptest"
    22  	"reflect"
    23  	"strconv"
    24  	"testing"
    25  )
    26  
    27  type requestWant struct {
    28  	Path        string
    29  	Method      string
    30  	ContentType string
    31  	RequestBody []byte
    32  }
    33  
    34  type responseWant struct {
    35  	Status       int
    36  	ResponseBody []byte
    37  }
    38  type testcase struct {
    39  	ResponseCode int
    40  	Response     []byte
    41  	ResponseWant responseWant
    42  	RequestWant  requestWant
    43  	Call         func(client *Client) (*http.Response, error)
    44  }
    45  
    46  func TestRaw(t *testing.T) {
    47  	testcases := []testcase{
    48  		newTestCase(
    49  			http.MethodGet,
    50  			"",
    51  			[]byte(""),
    52  			func(client *Client) (*http.Response, error) {
    53  				call, err := client.NewRawCall(http.MethodGet, "/abcdefg")
    54  				if err != nil {
    55  					panic(err)
    56  				}
    57  				return call.Do()
    58  			},
    59  		),
    60  		newTestCase(
    61  			http.MethodPost,
    62  			"application/json; charset=UTF-8",
    63  			[]byte(`RRRREQUEST_BODY`),
    64  			func(client *Client) (*http.Response, error) {
    65  				call, err := client.NewRawCallWithBody(http.MethodPost, "/abcdefg", bytes.NewReader([]byte(`RRRREQUEST_BODY`)))
    66  				if err != nil {
    67  					panic(err)
    68  				}
    69  				call.AddHeader("content-type", "application/json; charset=UTF-8")
    70  				return call.Do()
    71  			},
    72  		),
    73  		newTestCase(
    74  			http.MethodPost,
    75  			"application/x-www-form-urlencoded",
    76  			[]byte(`RRRREQUEST_BODY`),
    77  			func(client *Client) (*http.Response, error) {
    78  				call, err := client.NewRawCallWithBody(http.MethodPost, "/abcdefg", bytes.NewReader([]byte(`RRRREQUEST_BODY`)))
    79  				if err != nil {
    80  					panic(err)
    81  				}
    82  				call.AddHeader("content-type", "application/x-www-form-urlencoded")
    83  				return call.Do()
    84  			},
    85  		),
    86  		newTestCase(
    87  			http.MethodPut,
    88  			"application/json; charset=UTF-8",
    89  			[]byte(`RRRREQUEST_BODY`),
    90  			func(client *Client) (*http.Response, error) {
    91  				call, err := client.NewRawCallWithBody(http.MethodPut, "/abcdefg", bytes.NewReader([]byte(`RRRREQUEST_BODY`)))
    92  				if err != nil {
    93  					panic(err)
    94  				}
    95  				call.AddHeader("content-type", "application/json; charset=UTF-8")
    96  				return call.Do()
    97  			},
    98  		),
    99  		newTestCase(
   100  			http.MethodDelete,
   101  			"",
   102  			[]byte(``),
   103  			func(client *Client) (*http.Response, error) {
   104  				call, err := client.NewRawCall(http.MethodDelete, "/abcdefg")
   105  				if err != nil {
   106  					panic(err)
   107  				}
   108  				return call.Do()
   109  			},
   110  		),
   111  	}
   112  
   113  	for i, tc := range testcases {
   114  		t.Run(strconv.Itoa(i)+"_"+tc.RequestWant.Method, func(t *testing.T) {
   115  			runTestCase(t, tc)
   116  		})
   117  	}
   118  }
   119  
   120  func newTestCase(expectedRequestMethod string,
   121  	expectedRequestContentType string,
   122  	expectedRequestBody []byte,
   123  	call func(client *Client) (*http.Response, error)) testcase {
   124  	return testcase{
   125  		ResponseCode: 200,
   126  		Response:     []byte(`TESTDATA`),
   127  		Call:         call,
   128  		RequestWant: requestWant{
   129  			Method:      expectedRequestMethod,
   130  			Path:        "/abcdefg",
   131  			RequestBody: expectedRequestBody,
   132  			ContentType: expectedRequestContentType,
   133  		},
   134  		ResponseWant: responseWant{
   135  			Status:       200,
   136  			ResponseBody: []byte(`TESTDATA`),
   137  		},
   138  	}
   139  }
   140  
   141  func runTestCase(t *testing.T, tc testcase) {
   142  	server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   143  		defer r.Body.Close()
   144  		if r.Method != tc.RequestWant.Method {
   145  			t.Errorf("Method %s; want %s", r.Method, tc.RequestWant.Method)
   146  		}
   147  		if r.URL.Path != tc.RequestWant.Path {
   148  			t.Errorf("URLPath %s; want %s", r.URL.Path, tc.RequestWant.Path)
   149  		}
   150  		body, err := io.ReadAll(r.Body)
   151  		if err != nil {
   152  			t.Fatal(err)
   153  		}
   154  		contentType := r.Header.Get("content-type")
   155  		if !reflect.DeepEqual(contentType, tc.RequestWant.ContentType) {
   156  			t.Errorf("Content\n %v; want\n %v", contentType, tc.RequestWant.ContentType)
   157  		}
   158  
   159  		if tc.RequestWant.RequestBody != nil {
   160  			if !reflect.DeepEqual(body, tc.RequestWant.RequestBody) {
   161  				t.Errorf("RequestBody\n %s; want\n %s", body, tc.RequestWant.RequestBody)
   162  			}
   163  		}
   164  
   165  		w.WriteHeader(tc.ResponseCode)
   166  		w.Write(tc.Response)
   167  	}))
   168  	defer server.Close()
   169  
   170  	dataServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   171  		defer r.Body.Close()
   172  		t.Error("Unexpected data API call")
   173  		w.WriteHeader(404)
   174  		w.Write([]byte(`{"message":"Not found"}`))
   175  	}))
   176  	defer dataServer.Close()
   177  
   178  	client, err := mockClient(server, dataServer)
   179  	if err != nil {
   180  		t.Fatal(err)
   181  	}
   182  	res, err := tc.Call(client)
   183  	if err != nil {
   184  		t.Error(err)
   185  	}
   186  	defer res.Body.Close()
   187  
   188  	body, err := io.ReadAll(res.Body)
   189  	if err != nil {
   190  		t.Fatal(err)
   191  	}
   192  	if !reflect.DeepEqual(body, tc.ResponseWant.ResponseBody) {
   193  		t.Errorf("Response %v; want %v", body, tc.ResponseWant.ResponseBody)
   194  	}
   195  	if res.StatusCode != tc.ResponseWant.Status {
   196  		t.Errorf("Response %v; want %v", res.StatusCode, tc.ResponseWant.Status)
   197  	}
   198  }