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 }