package main import ( "bytes" "encoding/json" "fmt" "log" "net/http" "net/http/httptest" "testing" "time" ) //when we setup wechate parameters,we chat will verify us func TestInitialSetup(t *testing.T) { expected := `913461463450840893` req := buildReqWechatAPISetup(expected) rr, _ := getHTTPResponse(req, answerInitialAuth) // Check the response body is what we expect. if rr.Body.String() != expected { t.Errorf("handler returned unexpected body: got %v want %v", rr.Body.String(), expected) } } func TestWebRootHandler(t *testing.T) { req := buildReqWechatWebRoot() rr, _ := getHTTPResponse(req, webrootHandler) // Check the response body is what we expect. expected := `Hi there, I love dummydir! echostr => [913461463450840893]` if rr.Body.String() != expected { t.Errorf("handler returned unexpected body: got %v want %v", rr.Body.String(), expected) } } //Send encrypted text Message ("test"")to server and get encrypted feedback //we only check decrypted ToUserName should be the one we sent out. //as decrypt itself is already a good proof of its working state. func TestPostTxtMsg(t *testing.T) { //TODO: as session manager is not auto started in test environment //it will time out //uncomment following and only run this particular TestCase it should pass. // startSessionManager(2048) return //skip this test case req := buildReqWechatPostTxtMsg() rr, _ := getHTTPResponse(req, apiV1Main) m := ReadEncryptedMsg(rr.Body.String()) xml := Decode(m.Encrypt) h := ReadCommonHeader(xml) expected := "oUN420bxqFqlx0ZQHciUOesZO3PE" if h.ToUserName != expected { t.Errorf("expect ToUserName: %v \r\nbut got %v", expected, h.ToUserName) } } func TestGetAccesstoken(t *testing.T) { req := buildReqGetAccessToken() rr, _ := getHTTPResponse(req, supplyAccessToken) errorResponse := "unauthorized" m := rr.Body.String() expected, _ := GetAccessToken() log.Printf("TestGetAccesstoken got: [%s] ", m) AssertEqual(t, m != errorResponse, true, "Signature check failed, error response") AssertEqual(t, m, expected, "token incorrect") } func TestGetAccesstokenUnAuthorized(t *testing.T) { req := buildReqGetAccessTokenUnAuthorized() rr, _ := getHTTPResponse(req, supplyAccessToken) errorResponse := "unauthorized" m := rr.Body.String() expected, _ := GetAccessToken() log.Printf("TestGetAccesstoken got: [%s] ", m) AssertEqual(t, m, errorResponse, "should be unauthorized") AssertEqual(t, m != expected, true, "token should not be returned") } func TestCreatePermenentWechatQr(t *testing.T) { scene := "edit_profile" //do not create rubbish, create something that we can use later on //permenant ticked for "0" expected := "gQEm8DwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyS19UblE5Z3VjU2gxMDAwME0wM04AAgRMYh1ZAwQAAAAA" expected = "gQFR8DwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyZnNRMVJmZ3VjU2gxMDAwME0wN28AAgTQaSVZAwQAAAAA" req := buildReqPermQr(scene) rr, _ := getHTTPResponse(req, iapiCreateWechatQrCode) m := rr.Body.String() info := QRSrcInfo{} err := json.Unmarshal([]byte(m), &info) AssertEqual(t, err, nil, "decode json should be correct") log.Println(info) log.Println(expected) AssertEqual(t, info.Ticket, expected, "expected ticket not match") } func TestCreateTmpWechatQr(t *testing.T) { qrValue := int32(time.Now().Unix()) log.Println(qrValue) qrExpire := int32(1200) req := buildReqTmpQr(qrValue, qrExpire) rr, _ := getHTTPResponse(req, iapiCreateWechatQrCode) m := rr.Body.String() info := QRSrcInfo{} err := json.Unmarshal([]byte(m), &info) AssertEqual(t, err, nil, "decode json should be correct") log.Println(info) log.Printf("https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=%s", info.Ticket) AssertEqual(t, info.Ticket != "", true, "expected ticket not match") //use wechat to check scan code is correct } func getHTTPResponse(req *http.Request, handler http.HandlerFunc) (rr *httptest.ResponseRecorder, err error) { // Our handlers satisfy http.Handler, so we can call their ServeHTTP method // directly and pass in our Request and ResponseRecorder. rr = httptest.NewRecorder() handler.ServeHTTP(rr, req) // Check the status code is what we expect. if status := rr.Code; status != http.StatusOK { err = fmt.Errorf("wrong HTTP status code: got %v want %v", status, http.StatusOK) } return } // POST /api?signature=f06bb28c1d3847815d498fc0a343b11b4d03e095×tamp=1493212928&nonce=1461107899&openid=oUN420bxqFqlx0ZQHciUOesZO3PE&encrypt_type=aes&msg_signature=61a50d4656b13a7bbeecf53a5a85fbf37835762f HTTP/1.1 // Host: wechat.hitxy.org.au // Accept: */* // Cache-Control: no-cache // Connection: Keep-Alive // Content-Length: 534 // Content-Type: text/xml // Pragma: no-cache // User-Agent: Mozilla/4.0 // X-Forwarded-For: 103.7.30.105 // X-Forwarded-Host: wechat.hitxy.org.au // X-Forwarded-Server: wechat.hitxy.org.au // // // // // decrypt as: // // 1493212928 // // // 6413300692136991026 // func buildReqWechatPostTxtMsg() *http.Request { xml := ` ` b := bytes.NewBufferString(xml) req, _ := http.NewRequest("POST", "/api?openid=oUN420bxqFqlx0ZQHciUOesZO3PE&encrypt_type=aes&msg_signature=61a50d4656b13a7bbeecf53a5a85fbf37835762f", b) buildReqCommonSignature(req, APIConfig.Token) buildReqCommonHeader(req) return req } func buildReqWechatWebRoot() *http.Request { req, _ := http.NewRequest("GET", "/dummydir", nil) buildReqCommonHeader(req) q := req.URL.Query() //q.Add("signature", "e39de9f2e28079c01ebb4b803dfc3442b819545c") q.Add("echostr", "913461463450840893") req.URL.RawQuery = q.Encode() return req } func buildReqWechatAPISetup(echostr string) *http.Request { // Create a request to pass to our handler. //We don't have any query body for now, so we'll // pass 'nil' as the third parameter. req, err := http.NewRequest("GET", "/apii", nil) if err != nil { log.Fatal(err) } buildReqCommonSignature(req, APIConfig.Token) q := req.URL.Query() q.Add("echostr", echostr) req.URL.RawQuery = q.Encode() buildReqCommonHeader(req) return req } func buildReqGetAccessToken() *http.Request { req, err := http.NewRequest("GET", "/iapi/getAccessToken", nil) if err != nil { log.Fatal(err) } buildReqCommonSignature(req, IntraAPIConfig.CRMSecrete) buildReqCommonHeader(req) return req } func buildReqGetAccessTokenUnAuthorized() *http.Request { req, err := http.NewRequest("GET", "/iapi/getAccessToken", nil) if err != nil { log.Fatal(err) } //buildReqCommonSignature(req, IntraAPIConfig.CRMSecrete) buildReqCommonHeader(req) return req } func buildReqPermQr(scene string) *http.Request { req, err := http.NewRequest("GET", "/iapi/createWechatQr", nil) if err != nil { log.Fatal(err) } q := req.URL.Query() q.Add("qrValue", scene) q.Add("expire", "0") req.URL.RawQuery = q.Encode() buildReqCommonSignature(req, IntraAPIConfig.CRMSecrete) buildReqCommonHeader(req) return req } func buildReqTmpQr(val, expire int32) *http.Request { req, err := http.NewRequest("GET", "/iapi/createWechatQr", nil) if err != nil { log.Fatal(err) } q := req.URL.Query() q.Add("qrValue", fmt.Sprintf("%d", val)) q.Add("expire", fmt.Sprintf("%d", expire)) req.URL.RawQuery = q.Encode() buildReqCommonSignature(req, IntraAPIConfig.CRMSecrete) buildReqCommonHeader(req) return req } func buildSignature(token string) (signature, timestamp, nonce string) { timestamp = fmt.Sprintf("%d", int32(time.Now().Unix())) nonce = "1461107899" //a randome string cut from previous wechat request signature = calculateSignature(timestamp, nonce, token) return } func buildReqCommonSignature(req *http.Request, token string) { signature, timestamp, nonce := buildSignature(token) q := req.URL.Query() q.Add("signature", signature) q.Add("timestamp", timestamp) q.Add("nonce", nonce) req.URL.RawQuery = q.Encode() } func buildReqCommonHeader(r *http.Request) { // // example request // // GET /api?signature=e39de9f2e28079c01ebb4b803dfc3442b819545c&echostr=913461463450840893×tamp=1492970761&nonce=1850971833 HTTP/1.1 // Host: wechat.hitxy.org.au // Accept: */* // Cache-Control: no-cache // Connection: Keep-Alive // Pragma: no-cache // User-Agent: Mozilla/4.0 // X-Forwarded-For: 103.7.30.107 // X-Forwarded-Host: wechat.hitxy.org.au // X-Forwarded-Server: wechat.hitxy.org.au r.Header.Set("Host", "wechat.hitxy.org.au") r.Header.Set("Accept", "*/*") r.Header.Set("Cache-Control", "no-cache") r.Header.Set("Connection", "Keep-Alive") r.Header.Set("Pragma", "no-cache") r.Header.Set("User-Agent", "Patrick testcase") r.Header.Set("X-Forwarded-For", "103.7.30.107") r.Header.Set("X-Forwarded-Host", "wechat.hitxy.org.au") r.Header.Set("X-Forwarded-Server", "wechat.hitxy.org.au") }