github.com/line/line-bot-sdk-go/v7@v7.21.0/linebot/liff_test.go (about) 1 // Copyright 2018 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 "fmt" 19 "io" 20 "net/http" 21 "net/http/httptest" 22 "reflect" 23 "strconv" 24 "testing" 25 ) 26 27 func TestGetLIFF(t *testing.T) { 28 type want struct { 29 RequestBody []byte 30 Response *LIFFAppsResponse 31 Error error 32 } 33 testCases := []struct { 34 ResponseCode int 35 Response []byte 36 Want want 37 }{ 38 { 39 ResponseCode: 200, 40 Response: []byte(`{"apps":[{"liffId":"testliffId1","view":{"type":"full","url":"https://example.com/myservice"}},{"liffId":"testliffId2","view":{"type":"tall","url":"https://example.com/myservice2"}}]}`), 41 Want: want{ 42 RequestBody: []byte(``), 43 Response: &LIFFAppsResponse{ 44 Apps: []LIFFApp{ 45 { 46 LIFFID: "testliffId1", 47 View: View{ 48 Type: LIFFViewTypeFull, 49 URL: "https://example.com/myservice", 50 }, 51 }, 52 { 53 LIFFID: "testliffId2", 54 View: View{ 55 Type: LIFFViewTypeTall, 56 URL: "https://example.com/myservice2", 57 }, 58 }, 59 }, 60 }, 61 }, 62 }, 63 { 64 ResponseCode: 200, 65 Response: []byte(`{"apps":[{"liffId":"{liffId}","view":{"type":"full","url":"https://example.com/myservice"},"description":"Happy New York","permanentLinkPattern":"concat"},{"liffId":"{liffId}","view":{"type":"tall","url":"https://example.com/myservice2"},"features":{"ble":true,"qrCode":true},"permanentLinkPattern":"concat","scope":["profile","chat_message.write"],"botPrompt":"none"}]}`), 66 Want: want{ 67 RequestBody: []byte(``), 68 Response: &LIFFAppsResponse{ 69 Apps: []LIFFApp{ 70 { 71 LIFFID: "{liffId}", 72 View: View{ 73 Type: LIFFViewTypeFull, 74 URL: "https://example.com/myservice", 75 }, 76 Description: "Happy New York", 77 PermanentLinkPattern: "concat", 78 }, 79 { 80 LIFFID: "{liffId}", 81 View: View{ 82 Type: LIFFViewTypeTall, 83 URL: "https://example.com/myservice2", 84 }, 85 Features: &LIFFAppFeatures{BLE: true, QRCode: true}, 86 PermanentLinkPattern: "concat", 87 Scope: []LIFFViewScopeType{LIFFViewScopeTypeProfile, LIFFViewScopeTypeChatMessageWrite}, 88 BotPrompt: "none", 89 }, 90 }, 91 }, 92 }, 93 }, 94 } 95 var currentTestIdx int 96 server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 97 defer r.Body.Close() 98 tc := testCases[currentTestIdx] 99 if r.Method != http.MethodGet { 100 t.Errorf("Method %s; want %s", r.Method, http.MethodGet) 101 } 102 endpoint := APIEndpointGetAllLIFFApps 103 if r.URL.Path != endpoint { 104 t.Errorf("URLPath %s; want %s", r.URL.Path, endpoint) 105 } 106 body, err := io.ReadAll(r.Body) 107 if err != nil { 108 t.Fatal(err) 109 } 110 if !reflect.DeepEqual(body, tc.Want.RequestBody) { 111 t.Errorf("RequestBody\n %s; want\n %s", body, tc.Want.RequestBody) 112 } 113 w.WriteHeader(tc.ResponseCode) 114 w.Write(tc.Response) 115 })) 116 defer server.Close() 117 118 dataServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 119 defer r.Body.Close() 120 t.Error("Unexpected data API call") 121 w.WriteHeader(404) 122 w.Write([]byte(`{"message":"Not found"}`)) 123 })) 124 defer dataServer.Close() 125 126 client, err := mockClient(server, dataServer) 127 if err != nil { 128 t.Fatal(err) 129 } 130 for i, tc := range testCases { 131 currentTestIdx = i 132 t.Run(strconv.Itoa(i), func(t *testing.T) { 133 res, err := client.GetLIFF().Do() 134 if err != nil { 135 t.Error(err) 136 } 137 if !reflect.DeepEqual(res, tc.Want.Response) { 138 t.Errorf("Response %v; want %v", res, tc.Want.Response) 139 } 140 }) 141 } 142 } 143 144 func TestAddLIFF(t *testing.T) { 145 type want struct { 146 RequestBody []byte 147 Response *LIFFIDResponse 148 Error error 149 } 150 testCases := []struct { 151 LIFFApp LIFFApp 152 ResponseCode int 153 Response []byte 154 Want want 155 }{ 156 { 157 LIFFApp: LIFFApp{ 158 View: View{ 159 Type: LIFFViewTypeFull, 160 URL: "https://example.com/myservice", 161 }, 162 }, 163 ResponseCode: 200, 164 Response: []byte(`{"liffId":"testliffId"}`), 165 Want: want{ 166 RequestBody: []byte(`{"view":{"type":"full","url":"https://example.com/myservice"}}` + "\n"), 167 Response: &LIFFIDResponse{LIFFID: "testliffId"}, 168 }, 169 }, 170 { 171 LIFFApp: LIFFApp{ 172 View: View{ 173 Type: LIFFViewTypeFull, 174 URL: "https://example.com/myservice2", 175 }, 176 Scope: []LIFFViewScopeType{LIFFViewScopeTypeProfile, LIFFViewScopeTypeChatMessageWrite}, 177 PermanentLinkPattern: "concat", 178 Description: "Service Example", 179 Features: &LIFFAppFeatures{BLE: true, QRCode: true}, 180 BotPrompt: "none", 181 }, 182 ResponseCode: 200, 183 Response: []byte(`{"liffId":"testliffId3"}`), 184 Want: want{ 185 RequestBody: []byte(`{"view":{"type":"full","url":"https://example.com/myservice2"},"description":"Service Example","features":{"ble":true,"qrCode":true},"permanentLinkPattern":"concat","scope":["profile","chat_message.write"],"botPrompt":"none"}` + "\n"), 186 Response: &LIFFIDResponse{LIFFID: "testliffId3"}, 187 }, 188 }, 189 } 190 var currentTestIdx int 191 server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 192 defer r.Body.Close() 193 tc := testCases[currentTestIdx] 194 if r.Method != http.MethodPost { 195 t.Errorf("Method %s; want %s", r.Method, http.MethodPost) 196 } 197 endpoint := APIEndpointAddLIFFApp 198 if r.URL.Path != endpoint { 199 t.Errorf("URLPath %s; want %s", r.URL.Path, endpoint) 200 } 201 body, err := io.ReadAll(r.Body) 202 if err != nil { 203 t.Fatal(err) 204 } 205 if !reflect.DeepEqual(body, tc.Want.RequestBody) { 206 t.Errorf("%d, RequestBody\n %s; want\n %s", currentTestIdx, body, tc.Want.RequestBody) 207 } 208 w.WriteHeader(tc.ResponseCode) 209 w.Write(tc.Response) 210 })) 211 defer server.Close() 212 213 dataServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 214 defer r.Body.Close() 215 t.Error("Unexpected data API call") 216 w.WriteHeader(404) 217 w.Write([]byte(`{"message":"Not found"}`)) 218 })) 219 defer dataServer.Close() 220 221 client, err := mockClient(server, dataServer) 222 if err != nil { 223 t.Fatal(err) 224 } 225 for i, tc := range testCases { 226 currentTestIdx = i 227 t.Run(strconv.Itoa(i), func(t *testing.T) { 228 res, err := client.AddLIFF(tc.LIFFApp).Do() 229 if err != nil { 230 t.Error(err) 231 } 232 if !reflect.DeepEqual(res, tc.Want.Response) { 233 t.Errorf("Response %v; want %v", res, tc.Want.Response) 234 } 235 }) 236 } 237 } 238 239 func TestUpdateLIFF(t *testing.T) { 240 type want struct { 241 RequestBody []byte 242 Response *BasicResponse 243 Error error 244 } 245 testCases := []struct { 246 LIFFID string 247 LIFFApp LIFFApp 248 ResponseCode int 249 Response []byte 250 Want want 251 }{ 252 { 253 LIFFID: "testliffId", 254 LIFFApp: LIFFApp{ 255 View: View{ 256 Type: LIFFViewTypeFull, 257 URL: "https://example.com/myservice", 258 }, 259 }, 260 ResponseCode: 200, 261 Response: []byte(``), 262 Want: want{ 263 RequestBody: []byte(`{"view":{"type":"full","url":"https://example.com/myservice"}}` + "\n"), 264 Response: &BasicResponse{}, 265 }, 266 }, 267 } 268 var currentTestIdx int 269 server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 270 defer r.Body.Close() 271 tc := testCases[currentTestIdx] 272 if r.Method != http.MethodPut { 273 t.Errorf("Method %s; want %s", r.Method, http.MethodPut) 274 } 275 endpoint := fmt.Sprintf(APIEndpointUpdateLIFFApp, tc.LIFFID) 276 if r.URL.Path != endpoint { 277 t.Errorf("URLPath %s; want %s", r.URL.Path, endpoint) 278 } 279 body, err := io.ReadAll(r.Body) 280 if err != nil { 281 t.Fatal(err) 282 } 283 if !reflect.DeepEqual(body, tc.Want.RequestBody) { 284 t.Errorf("RequestBody\n %s; want\n %s", body, tc.Want.RequestBody) 285 } 286 w.WriteHeader(tc.ResponseCode) 287 w.Write(tc.Response) 288 })) 289 defer server.Close() 290 291 dataServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 292 defer r.Body.Close() 293 t.Error("Unexpected data API call") 294 w.WriteHeader(404) 295 w.Write([]byte(`{"message":"Not found"}`)) 296 })) 297 defer dataServer.Close() 298 299 client, err := mockClient(server, dataServer) 300 if err != nil { 301 t.Fatal(err) 302 } 303 for i, tc := range testCases { 304 t.Run(strconv.Itoa(i), func(t *testing.T) { 305 res, err := client.UpdateLIFF(tc.LIFFID, tc.LIFFApp).Do() 306 if err != nil { 307 t.Error(err) 308 } 309 if !reflect.DeepEqual(res, tc.Want.Response) { 310 t.Errorf("Response %v; want %v", res, tc.Want.Response) 311 } 312 }) 313 } 314 } 315 316 func TestDeleteLIFF(t *testing.T) { 317 type want struct { 318 RequestBody []byte 319 Response *BasicResponse 320 Error error 321 } 322 testCases := []struct { 323 LIFFID string 324 ResponseCode int 325 Response []byte 326 Want want 327 }{ 328 { 329 LIFFID: "testliffId", 330 ResponseCode: 200, 331 Response: []byte(``), 332 Want: want{ 333 RequestBody: []byte(``), 334 Response: &BasicResponse{}, 335 }, 336 }, 337 } 338 var currentTestIdx int 339 server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 340 defer r.Body.Close() 341 tc := testCases[currentTestIdx] 342 if r.Method != http.MethodDelete { 343 t.Errorf("Method %s; want %s", r.Method, http.MethodPut) 344 } 345 endpoint := fmt.Sprintf(APIEndpointDeleteLIFFApp, tc.LIFFID) 346 if r.URL.Path != endpoint { 347 t.Errorf("URLPath %s; want %s", r.URL.Path, endpoint) 348 } 349 body, err := io.ReadAll(r.Body) 350 if err != nil { 351 t.Fatal(err) 352 } 353 if !reflect.DeepEqual(body, tc.Want.RequestBody) { 354 t.Errorf("RequestBody\n %s; want\n %s", body, tc.Want.RequestBody) 355 } 356 w.WriteHeader(tc.ResponseCode) 357 w.Write(tc.Response) 358 })) 359 defer server.Close() 360 361 dataServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 362 defer r.Body.Close() 363 t.Error("Unexpected data API call") 364 w.WriteHeader(404) 365 w.Write([]byte(`{"message":"Not found"}`)) 366 })) 367 defer dataServer.Close() 368 369 client, err := mockClient(server, dataServer) 370 if err != nil { 371 t.Fatal(err) 372 } 373 for i, tc := range testCases { 374 t.Run(strconv.Itoa(i), func(t *testing.T) { 375 res, err := client.DeleteLIFF(tc.LIFFID).Do() 376 if err != nil { 377 t.Error(err) 378 } 379 if !reflect.DeepEqual(res, tc.Want.Response) { 380 t.Errorf("Response %v; want %v", res, tc.Want.Response) 381 } 382 }) 383 } 384 }