Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

296 lines
9.7KB

  1. package main
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. "log"
  7. "net/http"
  8. "net/http/httptest"
  9. "testing"
  10. "time"
  11. )
  12. //when we setup wechate parameters,we chat will verify us
  13. func TestInitialSetup(t *testing.T) {
  14. expected := `913461463450840893`
  15. req := buildReqWechatAPISetup(expected)
  16. rr, _ := getHTTPResponse(req, answerInitialAuth)
  17. // Check the response body is what we expect.
  18. if rr.Body.String() != expected {
  19. t.Errorf("handler returned unexpected body: got %v want %v",
  20. rr.Body.String(), expected)
  21. }
  22. }
  23. func TestWebRootHandler(t *testing.T) {
  24. req := buildReqWechatWebRoot()
  25. rr, _ := getHTTPResponse(req, webrootHandler)
  26. // Check the response body is what we expect.
  27. expected := `Hi there, I love dummydir!
  28. echostr => [913461463450840893]`
  29. if rr.Body.String() != expected {
  30. t.Errorf("handler returned unexpected body: got %v want %v",
  31. rr.Body.String(), expected)
  32. }
  33. }
  34. //Send encrypted text Message ("test"")to server and get encrypted feedback
  35. //we only check decrypted ToUserName should be the one we sent out.
  36. //as decrypt itself is already a good proof of its working state.
  37. func TestPostTxtMsg(t *testing.T) {
  38. //TODO: as session manager is not auto started in test environment
  39. //it will time out
  40. //uncomment following and only run this particular TestCase it should pass.
  41. // startSessionManager(2048)
  42. return //skip this test case
  43. req := buildReqWechatPostTxtMsg()
  44. rr, _ := getHTTPResponse(req, apiV1Main)
  45. m := ReadEncryptedMsg(rr.Body.String())
  46. xml := Decode(m.Encrypt)
  47. h := ReadCommonHeader(xml)
  48. expected := "oUN420bxqFqlx0ZQHciUOesZO3PE"
  49. if h.ToUserName != expected {
  50. t.Errorf("expect ToUserName: %v \r\nbut got %v",
  51. expected, h.ToUserName)
  52. }
  53. }
  54. func TestGetAccesstoken(t *testing.T) {
  55. req := buildReqGetAccessToken()
  56. rr, _ := getHTTPResponse(req, supplyAccessToken)
  57. errorResponse := "unauthorized"
  58. m := rr.Body.String()
  59. expected, _ := GetAccessToken()
  60. log.Printf("TestGetAccesstoken got: [%s] ", m)
  61. AssertEqual(t, m != errorResponse, true, "Signature check failed, error response")
  62. AssertEqual(t, m, expected, "token incorrect")
  63. }
  64. func TestGetAccesstokenUnAuthorized(t *testing.T) {
  65. req := buildReqGetAccessTokenUnAuthorized()
  66. rr, _ := getHTTPResponse(req, supplyAccessToken)
  67. errorResponse := "unauthorized"
  68. m := rr.Body.String()
  69. expected, _ := GetAccessToken()
  70. log.Printf("TestGetAccesstoken got: [%s] ", m)
  71. AssertEqual(t, m, errorResponse, "should be unauthorized")
  72. AssertEqual(t, m != expected, true, "token should not be returned")
  73. }
  74. func TestCreatePermenentWechatQr(t *testing.T) {
  75. scene := "edit_profile" //do not create rubbish, create something that we can use later on
  76. //permenant ticked for "0"
  77. expected := "gQEm8DwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyS19UblE5Z3VjU2gxMDAwME0wM04AAgRMYh1ZAwQAAAAA"
  78. expected = "gQFR8DwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyZnNRMVJmZ3VjU2gxMDAwME0wN28AAgTQaSVZAwQAAAAA"
  79. req := buildReqPermQr(scene)
  80. rr, _ := getHTTPResponse(req, iapiCreateWechatQrCode)
  81. m := rr.Body.String()
  82. info := QRSrcInfo{}
  83. err := json.Unmarshal([]byte(m), &info)
  84. AssertEqual(t, err, nil, "decode json should be correct")
  85. log.Println(info)
  86. log.Println(expected)
  87. AssertEqual(t, info.Ticket, expected, "expected ticket not match")
  88. }
  89. func TestCreateTmpWechatQr(t *testing.T) {
  90. qrValue := int32(time.Now().Unix())
  91. log.Println(qrValue)
  92. qrExpire := int32(0)
  93. req := buildReqTmpQr(qrValue, qrExpire)
  94. rr, _ := getHTTPResponse(req, iapiCreateWechatQrCode)
  95. m := rr.Body.String()
  96. info := QRSrcInfo{}
  97. err := json.Unmarshal([]byte(m), &info)
  98. AssertEqual(t, err, nil, "decode json should be correct")
  99. log.Println(info)
  100. log.Printf("https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=%s", info.Ticket)
  101. AssertEqual(t, info.Ticket != "", true, "expected ticket not match")
  102. //use wechat to check scan code is correct
  103. }
  104. func getHTTPResponse(req *http.Request, handler http.HandlerFunc) (rr *httptest.ResponseRecorder, err error) {
  105. // Our handlers satisfy http.Handler, so we can call their ServeHTTP method
  106. // directly and pass in our Request and ResponseRecorder.
  107. rr = httptest.NewRecorder()
  108. handler.ServeHTTP(rr, req)
  109. // Check the status code is what we expect.
  110. if status := rr.Code; status != http.StatusOK {
  111. err = fmt.Errorf("wrong HTTP status code: got %v want %v",
  112. status, http.StatusOK)
  113. }
  114. return
  115. }
  116. // POST /api?signature=f06bb28c1d3847815d498fc0a343b11b4d03e095&timestamp=1493212928&nonce=1461107899&openid=oUN420bxqFqlx0ZQHciUOesZO3PE&encrypt_type=aes&msg_signature=61a50d4656b13a7bbeecf53a5a85fbf37835762f HTTP/1.1
  117. // Host: wechat.hitxy.org.au
  118. // Accept: */*
  119. // Cache-Control: no-cache
  120. // Connection: Keep-Alive
  121. // Content-Length: 534
  122. // Content-Type: text/xml
  123. // Pragma: no-cache
  124. // User-Agent: Mozilla/4.0
  125. // X-Forwarded-For: 103.7.30.105
  126. // X-Forwarded-Host: wechat.hitxy.org.au
  127. // X-Forwarded-Server: wechat.hitxy.org.au
  128. // <xml>
  129. // <ToUserName><![CDATA[gh_f09231355c68]]></ToUserName>
  130. // <Encrypt><![CDATA[HKILXQjAOV4Zi5Zb8gQ8zt6EPA6cBCRYSq90PZuyMqZSGhtjMESSgveIps74rS2+Q5aZPJhytXIkmuE+dxMTkV06qGNSYuSurXsoJE7bNfrE/Nmxq6GwKH1rwHXk3c50NoHW/h6/jCXu8x0oY1oW/ea1tLRGY4xeoQ9voCuvVYRFSyuU7Zz2QjlbP+AG8mCnGBxUwqrthqWFe7wDEkYa38EoD9DrjrQKRc4Hn2ZIHYN569cn5PDvsif+5FUX4p+3gEkgk/HVxicC7wT9wYzNSk9HH7bET3V7hnhJ+PJa+ZEH7HAPzry61UZ1gghf4dJAGVE9D8R4/0M6DpKGCQBGXmlI/Q3NjN0jx9NAqffPRxsoW4BF7mLV8RmfDbJJEa0W5i0buwyluMyVcrF5KT9Bd2DBvsULCXfuwwp01DmJdfc=]]></Encrypt>
  131. // </xml>
  132. // decrypt as: <xml><ToUserName><![CDATA[gh_f09231355c68]]></ToUserName>
  133. // <FromUserName><![CDATA[oUN420bxqFqlx0ZQHciUOesZO3PE]]></FromUserName>
  134. // <CreateTime>1493212928</CreateTime>
  135. // <MsgType><![CDATA[text]]></MsgType>
  136. // <Content><![CDATA[test]]></Content>
  137. // <MsgId>6413300692136991026</MsgId>
  138. // </xml>
  139. func buildReqWechatPostTxtMsg() *http.Request {
  140. xml := `<xml>
  141. <ToUserName><![CDATA[gh_f09231355c68]]></ToUserName>
  142. <Encrypt><![CDATA[HKILXQjAOV4Zi5Zb8gQ8zt6EPA6cBCRYSq90PZuyMqZSGhtjMESSgveIps74rS2+Q5aZPJhytXIkmuE+dxMTkV06qGNSYuSurXsoJE7bNfrE/Nmxq6GwKH1rwHXk3c50NoHW/h6/jCXu8x0oY1oW/ea1tLRGY4xeoQ9voCuvVYRFSyuU7Zz2QjlbP+AG8mCnGBxUwqrthqWFe7wDEkYa38EoD9DrjrQKRc4Hn2ZIHYN569cn5PDvsif+5FUX4p+3gEkgk/HVxicC7wT9wYzNSk9HH7bET3V7hnhJ+PJa+ZEH7HAPzry61UZ1gghf4dJAGVE9D8R4/0M6DpKGCQBGXmlI/Q3NjN0jx9NAqffPRxsoW4BF7mLV8RmfDbJJEa0W5i0buwyluMyVcrF5KT9Bd2DBvsULCXfuwwp01DmJdfc=]]></Encrypt>
  143. </xml>`
  144. b := bytes.NewBufferString(xml)
  145. req, _ := http.NewRequest("POST", "/api?openid=oUN420bxqFqlx0ZQHciUOesZO3PE&encrypt_type=aes&msg_signature=61a50d4656b13a7bbeecf53a5a85fbf37835762f", b)
  146. buildReqCommonSignature(req, APIConfig.Token)
  147. buildReqCommonHeader(req)
  148. return req
  149. }
  150. func buildReqWechatWebRoot() *http.Request {
  151. req, _ := http.NewRequest("GET", "/dummydir", nil)
  152. buildReqCommonHeader(req)
  153. q := req.URL.Query()
  154. //q.Add("signature", "e39de9f2e28079c01ebb4b803dfc3442b819545c")
  155. q.Add("echostr", "913461463450840893")
  156. req.URL.RawQuery = q.Encode()
  157. return req
  158. }
  159. func buildReqWechatAPISetup(echostr string) *http.Request {
  160. // Create a request to pass to our handler.
  161. //We don't have any query body for now, so we'll
  162. // pass 'nil' as the third parameter.
  163. req, err := http.NewRequest("GET", "/apii", nil)
  164. if err != nil {
  165. log.Fatal(err)
  166. }
  167. buildReqCommonSignature(req, APIConfig.Token)
  168. q := req.URL.Query()
  169. q.Add("echostr", echostr)
  170. req.URL.RawQuery = q.Encode()
  171. buildReqCommonHeader(req)
  172. return req
  173. }
  174. func buildReqGetAccessToken() *http.Request {
  175. req, err := http.NewRequest("GET", "/iapi/getAccessToken", nil)
  176. if err != nil {
  177. log.Fatal(err)
  178. }
  179. buildReqCommonSignature(req, IntraAPIConfig.CRMSecrete)
  180. buildReqCommonHeader(req)
  181. return req
  182. }
  183. func buildReqGetAccessTokenUnAuthorized() *http.Request {
  184. req, err := http.NewRequest("GET", "/iapi/getAccessToken", nil)
  185. if err != nil {
  186. log.Fatal(err)
  187. }
  188. //buildReqCommonSignature(req, IntraAPIConfig.CRMSecrete)
  189. buildReqCommonHeader(req)
  190. return req
  191. }
  192. func buildReqPermQr(scene string) *http.Request {
  193. req, err := http.NewRequest("GET", "/iapi/createWechatQr", nil)
  194. if err != nil {
  195. log.Fatal(err)
  196. }
  197. q := req.URL.Query()
  198. q.Add("qrValue", scene)
  199. q.Add("expire", "0")
  200. req.URL.RawQuery = q.Encode()
  201. buildReqCommonSignature(req, IntraAPIConfig.CRMSecrete)
  202. buildReqCommonHeader(req)
  203. return req
  204. }
  205. func buildReqTmpQr(val, expire int32) *http.Request {
  206. req, err := http.NewRequest("GET", "/iapi/createWechatQr", nil)
  207. if err != nil {
  208. log.Fatal(err)
  209. }
  210. q := req.URL.Query()
  211. q.Add("qrValue", fmt.Sprintf("%d", val))
  212. q.Add("expire", fmt.Sprintf("%d", expire))
  213. req.URL.RawQuery = q.Encode()
  214. buildReqCommonSignature(req, IntraAPIConfig.CRMSecrete)
  215. buildReqCommonHeader(req)
  216. return req
  217. }
  218. func buildReqCommonHeader(r *http.Request) {
  219. //
  220. // example request
  221. //
  222. // GET /api?signature=e39de9f2e28079c01ebb4b803dfc3442b819545c&echostr=913461463450840893&timestamp=1492970761&nonce=1850971833 HTTP/1.1
  223. // Host: wechat.hitxy.org.au
  224. // Accept: */*
  225. // Cache-Control: no-cache
  226. // Connection: Keep-Alive
  227. // Pragma: no-cache
  228. // User-Agent: Mozilla/4.0
  229. // X-Forwarded-For: 103.7.30.107
  230. // X-Forwarded-Host: wechat.hitxy.org.au
  231. // X-Forwarded-Server: wechat.hitxy.org.au
  232. r.Header.Set("Host", "wechat.hitxy.org.au")
  233. r.Header.Set("Accept", "*/*")
  234. r.Header.Set("Cache-Control", "no-cache")
  235. r.Header.Set("Connection", "Keep-Alive")
  236. r.Header.Set("Pragma", "no-cache")
  237. r.Header.Set("User-Agent", "Patrick testcase")
  238. r.Header.Set("X-Forwarded-For", "103.7.30.107")
  239. r.Header.Set("X-Forwarded-Host", "wechat.hitxy.org.au")
  240. r.Header.Set("X-Forwarded-Server", "wechat.hitxy.org.au")
  241. }
  242. func TestBuildQueryString(t *testing.T) {
  243. url := "http://www.hitxy.org.au/crmcache?a=abc"
  244. newURL := buildSignatureAppend2Url(url, IntraAPIConfig.CRMSecrete)
  245. //log.Println(newURL)
  246. AssertEqual(t, url != newURL, true, "URL append signature should be correct")
  247. req, err := http.NewRequest("GET", newURL, nil)
  248. AssertEqual(t, err, nil, "pase new URL should be correct")
  249. AssertEqual(t, checkSignatureByToken(req, IntraAPIConfig.CRMSecrete), true, "check signature shold be correct")
  250. }