github.com/line/line-bot-sdk-go/v7@v7.21.0/linebot/httphandler/httphandler_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 httphandler
    16  
    17  import (
    18  	"bytes"
    19  	"crypto/hmac"
    20  	"crypto/sha256"
    21  	"crypto/tls"
    22  	"encoding/base64"
    23  	"net/http"
    24  	"net/http/httptest"
    25  	"testing"
    26  
    27  	"github.com/line/line-bot-sdk-go/v7/linebot"
    28  )
    29  
    30  var testRequestBody = `{
    31      "events": [
    32          {
    33              "replyToken": "nHuyWiB7yP5Zw52FIkcQobQuGDXCTA",
    34              "type": "message",
    35              "timestamp": 1462629479859,
    36              "source": {
    37                  "type": "user",
    38                  "userId": "u206d25c2ea6bd87c17655609a1c37cb8"
    39              },
    40              "message": {
    41                  "id": "325708",
    42                  "type": "text",
    43                  "text": "Hello, world"
    44              }
    45          }
    46      ]
    47  }
    48  `
    49  
    50  const (
    51  	testChannelSecret = "testsecret"
    52  	testChannelToken  = "testtoken"
    53  )
    54  
    55  func TestWebhookHandler(t *testing.T) {
    56  	handler, err := New(testChannelSecret, testChannelToken)
    57  	if err != nil {
    58  		t.Error(err)
    59  	}
    60  	handlerFunc := func(events []*linebot.Event, r *http.Request) {
    61  		if events == nil {
    62  			t.Errorf("events is nil")
    63  		}
    64  		if r == nil {
    65  			t.Errorf("r is nil")
    66  		}
    67  		bot, err := handler.NewClient()
    68  		if err != nil {
    69  			t.Fatal(err)
    70  		}
    71  		if bot == nil {
    72  			t.Errorf("bot is nil")
    73  		}
    74  	}
    75  	handler.HandleEvents(handlerFunc)
    76  
    77  	server := httptest.NewTLSServer(handler)
    78  	defer server.Close()
    79  	httpClient := &http.Client{
    80  		Transport: &http.Transport{
    81  			TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
    82  		},
    83  	}
    84  
    85  	// valid signature
    86  	{
    87  		body := []byte(testRequestBody)
    88  		req, err := http.NewRequest("POST", server.URL, bytes.NewReader(body))
    89  		if err != nil {
    90  			t.Fatal(err)
    91  		}
    92  		// generate signature
    93  		mac := hmac.New(sha256.New, []byte(testChannelSecret))
    94  		mac.Write(body)
    95  
    96  		req.Header.Set("X-Line-Signature", base64.StdEncoding.EncodeToString(mac.Sum(nil)))
    97  		res, err := httpClient.Do(req)
    98  		if err != nil {
    99  			t.Fatal(err)
   100  		}
   101  		if res == nil {
   102  			t.Fatal("response is nil")
   103  		}
   104  		if res.StatusCode != http.StatusOK {
   105  			t.Errorf("status: %d", res.StatusCode)
   106  		}
   107  	}
   108  
   109  	// invalid signature
   110  	handler.HandleError(func(err error, r *http.Request) {
   111  		if err != linebot.ErrInvalidSignature {
   112  			t.Errorf("err %v; want %v", err, linebot.ErrInvalidSignature)
   113  		}
   114  		if r == nil {
   115  			t.Errorf("r is nil")
   116  		}
   117  	})
   118  	{
   119  		body := []byte(testRequestBody)
   120  		req, err := http.NewRequest("POST", server.URL, bytes.NewReader(body))
   121  		if err != nil {
   122  			t.Fatal(err)
   123  		}
   124  		req.Header.Set("X-LINE-Signature", "invalidSignature")
   125  		res, err := httpClient.Do(req)
   126  		if err != nil {
   127  			t.Fatal(err)
   128  		}
   129  		if res == nil {
   130  			t.Fatal("response is nil")
   131  		}
   132  		if res.StatusCode != 400 {
   133  			t.Errorf("status: %d", 400)
   134  		}
   135  	}
   136  }