附近小店
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

express_business_test.go 23 KiB

3 months ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954
  1. package weapp
  2. import (
  3. "encoding/base64"
  4. "encoding/json"
  5. "net/http"
  6. "net/http/httptest"
  7. "strings"
  8. "testing"
  9. )
  10. func TestAddExpressOrder(t *testing.T) {
  11. ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  12. if r.Method != "POST" {
  13. t.Fatalf("Expect 'POST' get '%s'", r.Method)
  14. }
  15. path := r.URL.EscapedPath()
  16. if path != apiAddExpressOrder {
  17. t.Fatalf("Except to path '%s',get '%s'", apiAddExpressOrder, path)
  18. }
  19. if err := r.ParseForm(); err != nil {
  20. t.Fatal(err)
  21. }
  22. if r.Form.Get("access_token") == "" {
  23. t.Fatalf("access_token can not be empty")
  24. }
  25. params := struct {
  26. AddSource uint8 `json:"add_source"`
  27. WXAppID string `json:"wx_appid"`
  28. OrderID string `json:"order_id"`
  29. OpenID string `json:"openid"`
  30. DeliveryID string `json:"delivery_id"`
  31. BizID string `json:"biz_id"`
  32. CustomRemark string `json:"custom_remark"`
  33. Sender struct {
  34. Name string `json:"name"`
  35. Tel string `json:"tel"`
  36. Mobile string `json:"mobile"`
  37. Company string `json:"company"`
  38. PostCode string `json:"post_code"`
  39. Country string `json:"country"`
  40. Province string `json:"province"`
  41. City string `json:"city"`
  42. Area string `json:"area"`
  43. Address string `json:"address"`
  44. } `json:"sender"`
  45. Receiver struct {
  46. Name string `json:"name"`
  47. Tel string `json:"tel"`
  48. Mobile string `json:"mobile"`
  49. Company string `json:"company"`
  50. PostCode string `json:"post_code"`
  51. Country string `json:"country"`
  52. Province string `json:"province"`
  53. City string `json:"city"`
  54. Area string `json:"area"`
  55. Address string `json:"address"`
  56. } `json:"receiver"`
  57. Cargo struct {
  58. Count uint `json:"count"`
  59. Weight float64 `json:"weight"`
  60. SpaceX float64 `json:"space_x"`
  61. SpaceY float64 `json:"space_y"`
  62. SpaceZ float64 `json:"space_z"`
  63. DetailList []struct {
  64. Name string `json:"name"`
  65. Count uint `json:"count"`
  66. } `json:"detail_list"`
  67. } `json:"cargo"`
  68. Shop struct {
  69. WXAPath string `json:"wxa_path"`
  70. IMGUrl string `json:"img_url"`
  71. GoodsName string `json:"goods_name"`
  72. GoodsCount uint `json:"goods_count"`
  73. } `json:"shop"`
  74. Insured struct {
  75. Used InsureStatus `json:"use_insured"`
  76. Value uint `json:"insured_value"`
  77. } `json:"insured"`
  78. Service struct {
  79. Type uint8 `json:"service_type"`
  80. Name string `json:"service_name"`
  81. } `json:"service"`
  82. ExpectTime uint `json:"expect_time"`
  83. }{}
  84. if err := json.NewDecoder(r.Body).Decode(&params); err != nil {
  85. t.Fatal(err)
  86. }
  87. if params.AddSource == 2 && params.WXAppID == "" {
  88. t.Error("param wx_appid can not be empty")
  89. }
  90. if params.AddSource != 2 && params.OpenID == "" {
  91. t.Error("param openid can not be empty")
  92. }
  93. if params.OrderID == "" {
  94. t.Error("param order_id can not be empty")
  95. }
  96. if params.DeliveryID == "" {
  97. t.Error("param delivery_id can not be empty")
  98. }
  99. if params.BizID == "" {
  100. t.Error("param biz_id can not be empty")
  101. }
  102. if params.Sender.Name == "" {
  103. t.Error("param sender.name can not be empty")
  104. }
  105. if params.Sender.Province == "" {
  106. t.Error("param sender.province can not be empty")
  107. }
  108. if params.Sender.City == "" {
  109. t.Error("param sender.city can not be empty")
  110. }
  111. if params.Sender.Area == "" {
  112. t.Error("param sender.area can not be empty")
  113. }
  114. if params.Sender.Address == "" {
  115. t.Error("param sender.address can not be empty")
  116. }
  117. if params.Receiver.Name == "" {
  118. t.Error("param receiver.name can not be empty")
  119. }
  120. if params.Receiver.Province == "" {
  121. t.Error("param receiver.province can not be empty")
  122. }
  123. if params.Receiver.City == "" {
  124. t.Error("param receiver.city can not be empty")
  125. }
  126. if params.Receiver.Area == "" {
  127. t.Error("param receiver.area can not be empty")
  128. }
  129. if params.Receiver.Address == "" {
  130. t.Error("param receiver.address can not be empty")
  131. }
  132. if params.Cargo.Count == 0 {
  133. t.Error("param cargo.count can not be zero")
  134. }
  135. if params.Cargo.Weight == 0 {
  136. t.Error("param cargo.weight can not be zero")
  137. }
  138. if params.Cargo.SpaceX == 0 {
  139. t.Error("param cargo.spaceX can not be zero")
  140. }
  141. if params.Cargo.SpaceY == 0 {
  142. t.Error("param cargo.spaceY can not be zero")
  143. }
  144. if params.Cargo.SpaceZ == 0 {
  145. t.Error("param cargo.spaceZ can not be zero")
  146. }
  147. if len(params.Cargo.DetailList) == 0 {
  148. t.Error("param cargo.detailList can not be empty")
  149. } else {
  150. if (params.Cargo.DetailList[0].Name) == "" {
  151. t.Error("param cargo.detailList.name can not be empty")
  152. }
  153. if (params.Cargo.DetailList[0].Count) == 0 {
  154. t.Error("param cargo.detailList.count can not be zero")
  155. }
  156. }
  157. if params.Shop.WXAPath == "" {
  158. t.Error("param shop.wxa_path can not be empty")
  159. }
  160. if params.Shop.IMGUrl == "" {
  161. t.Error("param shop.img_url can not be empty")
  162. }
  163. if params.Shop.GoodsName == "" {
  164. t.Error("param shop.goods_name can not be empty")
  165. }
  166. if params.Shop.GoodsCount == 0 {
  167. t.Error("param shop.goods_count can not be zero")
  168. }
  169. if params.Insured.Used == 0 {
  170. t.Error("param insured.use_insured can not be zero")
  171. }
  172. if params.Service.Name == "" {
  173. t.Error("param Service.service_name can not be empty")
  174. }
  175. w.WriteHeader(http.StatusOK)
  176. w.Header().Set("Content-Type", "application/json")
  177. raw := `{
  178. "errcode": 9300501,
  179. "errmsg": "delivery logic fail",
  180. "delivery_resultcode": 10002,
  181. "delivery_resultmsg": "客户密码不正确",
  182. "order_id": "01234567890123456789",
  183. "waybill_id": "123456789",
  184. "waybill_data": [
  185. {
  186. "key": "SF_bagAddr",
  187. "value": "广州"
  188. },
  189. {
  190. "key": "SF_mark",
  191. "value": "101- 07-03 509"
  192. }
  193. ]
  194. }`
  195. if _, err := w.Write([]byte(raw)); err != nil {
  196. t.Fatal(err)
  197. }
  198. }))
  199. defer ts.Close()
  200. creator := ExpressOrderCreator{
  201. AddSource: 0,
  202. ExpressOrder: ExpressOrder{
  203. OrderID: "01234567890123456789",
  204. OpenID: "oABC123456",
  205. DeliveryID: "SF",
  206. BizID: "xyz",
  207. CustomRemark: "易碎物品",
  208. Sender: ExpreseeUserInfo{
  209. "张三",
  210. "020-88888888",
  211. "18666666666",
  212. "公司名",
  213. "123456",
  214. "中国",
  215. "广东省",
  216. "广州市",
  217. "海珠区",
  218. "XX路XX号XX大厦XX栋XX",
  219. },
  220. Receiver: ExpreseeUserInfo{
  221. "王小蒙",
  222. "020-77777777",
  223. "18610000000",
  224. "公司名",
  225. "654321",
  226. "中国",
  227. "广东省",
  228. "广州市",
  229. "天河区",
  230. "XX路XX号XX大厦XX栋XX",
  231. },
  232. Shop: ExpressShop{
  233. "/index/index?from=waybill&id=01234567890123456789",
  234. "https://mmbiz.qpic.cn/mmbiz_png/OiaFLUqewuIDNQnTiaCInIG8ibdosYHhQHPbXJUrqYSNIcBL60vo4LIjlcoNG1QPkeH5GWWEB41Ny895CokeAah8A/640",
  235. "一千零一夜钻石包&爱马仕铂金包",
  236. 2,
  237. },
  238. Cargo: ExpressCargo{
  239. 2,
  240. 5.5,
  241. 30.5,
  242. 20,
  243. 20,
  244. []CargoDetail{
  245. {
  246. "一千零一夜钻石包",
  247. 1,
  248. },
  249. {
  250. "爱马仕铂金包",
  251. 1,
  252. },
  253. },
  254. },
  255. Insured: ExpressInsure{
  256. 1,
  257. 10000,
  258. },
  259. Service: ExpressService{
  260. 0,
  261. "标准快递",
  262. },
  263. },
  264. }
  265. _, err := creator.create(ts.URL+apiAddExpressOrder, "mock-access-token")
  266. if err != nil {
  267. t.Fatal(err)
  268. }
  269. }
  270. func TestCancelExpressOrder(t *testing.T) {
  271. ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  272. if r.Method != "POST" {
  273. t.Fatalf("Expect 'POST' get '%s'", r.Method)
  274. }
  275. path := r.URL.EscapedPath()
  276. if path != apiCancelExpressOrder {
  277. t.Fatalf("Except to path '%s',get '%s'", apiCancelExpressOrder, path)
  278. }
  279. if err := r.ParseForm(); err != nil {
  280. t.Fatal(err)
  281. }
  282. if r.Form.Get("access_token") == "" {
  283. t.Fatalf("access_token can not be empty")
  284. }
  285. params := struct {
  286. OrderID string `json:"order_id"`
  287. OpenID string `json:"openid"`
  288. DeliveryID string `json:"delivery_id"`
  289. WaybillID string `json:"waybill_id"`
  290. }{}
  291. if err := json.NewDecoder(r.Body).Decode(&params); err != nil {
  292. t.Fatal(err)
  293. }
  294. if params.OrderID == "" {
  295. t.Error("param order_id can not be empty")
  296. }
  297. if params.DeliveryID == "" {
  298. t.Error("param delivery_id can not be empty")
  299. }
  300. if params.WaybillID == "" {
  301. t.Error("param waybill_id can not be empty")
  302. }
  303. w.WriteHeader(http.StatusOK)
  304. w.Header().Set("Content-Type", "application/json")
  305. raw := `{
  306. "errcode": 0,
  307. "errmsg": "ok"
  308. }`
  309. if _, err := w.Write([]byte(raw)); err != nil {
  310. t.Fatal(err)
  311. }
  312. }))
  313. defer ts.Close()
  314. canceler := ExpressOrderCanceler{
  315. OrderID: "01234567890123456789",
  316. OpenID: "oABC123456",
  317. DeliveryID: "SF",
  318. WaybillID: "123456789",
  319. }
  320. _, err := canceler.cancel(ts.URL+apiCancelExpressOrder, "mock-access-token")
  321. if err != nil {
  322. t.Fatal(err)
  323. }
  324. }
  325. func TestGetAllDelivery(t *testing.T) {
  326. ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  327. if r.Method != "GET" {
  328. t.Fatalf("Expect 'GET' get '%s'", r.Method)
  329. }
  330. path := r.URL.EscapedPath()
  331. if path != apiGetAllDelivery {
  332. t.Fatalf("Except to path '%s',get '%s'", apiGetAllDelivery, path)
  333. }
  334. if err := r.ParseForm(); err != nil {
  335. t.Fatal(err)
  336. }
  337. if r.Form.Get("access_token") == "" {
  338. t.Fatalf("access_token can not be empty")
  339. }
  340. w.WriteHeader(http.StatusOK)
  341. raw := `{
  342. "count": 8,
  343. "data": [
  344. {
  345. "delivery_id": "BEST",
  346. "delivery_name": "百世快递"
  347. },
  348. {
  349. "delivery_id": "EMS",
  350. "delivery_name": "中国邮政速递物流"
  351. },
  352. {
  353. "delivery_id": "OTP",
  354. "delivery_name": "承诺达特快"
  355. },
  356. {
  357. "delivery_id": "PJ",
  358. "delivery_name": "品骏物流"
  359. },
  360. {
  361. "delivery_id": "SF",
  362. "delivery_name": "顺丰速运"
  363. },
  364. {
  365. "delivery_id": "YTO",
  366. "delivery_name": "圆通速递"
  367. },
  368. {
  369. "delivery_id": "YUNDA",
  370. "delivery_name": "韵达快递"
  371. },
  372. {
  373. "delivery_id": "ZTO",
  374. "delivery_name": "中通快递"
  375. }
  376. ]
  377. }`
  378. if _, err := w.Write([]byte(raw)); err != nil {
  379. t.Fatal(err)
  380. }
  381. }))
  382. defer ts.Close()
  383. _, err := getAllDelivery(ts.URL+apiGetAllDelivery, "mock-access-token")
  384. if err != nil {
  385. t.Fatal(err)
  386. }
  387. }
  388. func TestGetExpressOrder(t *testing.T) {
  389. ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  390. if r.Method != "POST" {
  391. t.Fatalf("Expect 'POST' get '%s'", r.Method)
  392. }
  393. path := r.URL.EscapedPath()
  394. if path != apiGetExpressOrder {
  395. t.Fatalf("Except to path '%s',get '%s'", apiGetExpressOrder, path)
  396. }
  397. if err := r.ParseForm(); err != nil {
  398. t.Fatal(err)
  399. }
  400. if r.Form.Get("access_token") == "" {
  401. t.Fatalf("access_token can not be empty")
  402. }
  403. params := struct {
  404. OrderID string `json:"order_id"`
  405. OpenID string `json:"openid"`
  406. DeliveryID string `json:"delivery_id"`
  407. WaybillID string `json:"waybill_id"`
  408. }{}
  409. if err := json.NewDecoder(r.Body).Decode(&params); err != nil {
  410. t.Fatal(err)
  411. }
  412. if params.OrderID == "" {
  413. t.Error("param order_id can not be empty")
  414. }
  415. if params.DeliveryID == "" {
  416. t.Error("param delivery_id can not be empty")
  417. }
  418. if params.WaybillID == "" {
  419. t.Error("param waybill_id can not be empty")
  420. }
  421. w.WriteHeader(http.StatusOK)
  422. w.Header().Set("Content-Type", "application/json")
  423. raw := `{
  424. "errcode": 0,
  425. "errmsg": "ok"
  426. }`
  427. if _, err := w.Write([]byte(raw)); err != nil {
  428. t.Fatal(err)
  429. }
  430. }))
  431. defer ts.Close()
  432. canceler := ExpressOrderGetter{
  433. OrderID: "01234567890123456789",
  434. OpenID: "oABC123456",
  435. DeliveryID: "SF",
  436. WaybillID: "123456789",
  437. }
  438. _, err := canceler.get(ts.URL+apiGetExpressOrder, "mock-access-token")
  439. if err != nil {
  440. t.Fatal(err)
  441. }
  442. }
  443. func TestGetExpressPath(t *testing.T) {
  444. ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  445. if r.Method != "POST" {
  446. t.Fatalf("Expect 'POST' get '%s'", r.Method)
  447. }
  448. path := r.URL.EscapedPath()
  449. expectedPath := "/cgi-bin/express/business/path/get"
  450. if path != expectedPath {
  451. t.Fatalf("Except to path '%s',get '%s'", expectedPath, path)
  452. }
  453. if err := r.ParseForm(); err != nil {
  454. t.Fatal(err)
  455. }
  456. if r.Form.Get("access_token") == "" {
  457. t.Fatalf("access_token can not be empty")
  458. }
  459. params := struct {
  460. OrderID string `json:"order_id"`
  461. OpenID string `json:"openid"`
  462. DeliveryID string `json:"delivery_id"`
  463. WaybillID string `json:"waybill_id"`
  464. }{}
  465. if err := json.NewDecoder(r.Body).Decode(&params); err != nil {
  466. t.Fatal(err)
  467. }
  468. if params.OrderID == "" {
  469. t.Error("param order_id can not be empty")
  470. }
  471. if params.DeliveryID == "" {
  472. t.Error("param delivery_id can not be empty")
  473. }
  474. if params.WaybillID == "" {
  475. t.Error("param waybill_id can not be empty")
  476. }
  477. w.WriteHeader(http.StatusOK)
  478. w.Header().Set("Content-Type", "application/json")
  479. raw := `{
  480. "openid": "OPENID",
  481. "delivery_id": "SF",
  482. "waybill_id": "12345678901234567890",
  483. "path_item_num": 3,
  484. "path_item_list": [
  485. {
  486. "action_time": 1533052800,
  487. "action_type": 100001,
  488. "action_msg": "快递员已成功取件"
  489. },
  490. {
  491. "action_time": 1533062800,
  492. "action_type": 200001,
  493. "action_msg": "快件已到达xxx集散中心,准备发往xxx"
  494. },
  495. {
  496. "action_time": 1533072800,
  497. "action_type": 300001,
  498. "action_msg": "快递员已出发,联系电话xxxxxx"
  499. }
  500. ]
  501. }`
  502. if _, err := w.Write([]byte(raw)); err != nil {
  503. t.Fatal(err)
  504. }
  505. }))
  506. defer ts.Close()
  507. getter := ExpressPathGetter{
  508. OrderID: "01234567890123456789",
  509. OpenID: "oABC123456",
  510. DeliveryID: "SF",
  511. WaybillID: "123456789",
  512. }
  513. _, err := getter.get(ts.URL+apiGetExpressPath, "mock-access-token")
  514. if err != nil {
  515. t.Fatal(err)
  516. }
  517. }
  518. func TestGetPrinter(t *testing.T) {
  519. ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  520. if r.Method != "GET" {
  521. t.Fatalf("Expect 'GET' get '%s'", r.Method)
  522. }
  523. path := r.URL.EscapedPath()
  524. expectedPath := "/cgi-bin/express/business/printer/getall"
  525. if path != expectedPath {
  526. t.Fatalf("Except to path '%s',get '%s'", expectedPath, path)
  527. }
  528. if err := r.ParseForm(); err != nil {
  529. t.Fatal(err)
  530. }
  531. if r.Form.Get("access_token") == "" {
  532. t.Fatalf("access_token can not be empty")
  533. }
  534. w.WriteHeader(http.StatusOK)
  535. w.Header().Set("Content-Type", "application/json")
  536. raw := `{
  537. "count": 2,
  538. "openid": [
  539. "oABC",
  540. "oXYZ"
  541. ],
  542. "tagid_list": [
  543. "123",
  544. "456"
  545. ]
  546. }`
  547. if _, err := w.Write([]byte(raw)); err != nil {
  548. t.Fatal(err)
  549. }
  550. }))
  551. defer ts.Close()
  552. _, err := getPrinter(ts.URL+apiGetPrinter, "mock-access-token")
  553. if err != nil {
  554. t.Fatal(err)
  555. }
  556. }
  557. func TestGetQuota(t *testing.T) {
  558. ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  559. if r.Method != "POST" {
  560. t.Fatalf("Expect 'POST' get '%s'", r.Method)
  561. }
  562. path := r.URL.EscapedPath()
  563. expectedPath := "/cgi-bin/express/business/quota/get"
  564. if path != expectedPath {
  565. t.Fatalf("Except to path '%s',get '%s'", expectedPath, path)
  566. }
  567. if err := r.ParseForm(); err != nil {
  568. t.Fatal(err)
  569. }
  570. if r.Form.Get("access_token") == "" {
  571. t.Fatalf("access_token can not be empty")
  572. }
  573. params := struct {
  574. DeliveryID string `json:"delivery_id"`
  575. BizID string `json:"biz_id"`
  576. }{}
  577. if err := json.NewDecoder(r.Body).Decode(&params); err != nil {
  578. t.Fatal(err)
  579. }
  580. if params.DeliveryID == "" {
  581. t.Error("param delivery_id can not be empty")
  582. }
  583. if params.BizID == "" {
  584. t.Error("param biz_id can not be empty")
  585. }
  586. w.WriteHeader(http.StatusOK)
  587. w.Header().Set("Content-Type", "application/json")
  588. raw := `{
  589. "quota_num": 210
  590. }`
  591. if _, err := w.Write([]byte(raw)); err != nil {
  592. t.Fatal(err)
  593. }
  594. }))
  595. defer ts.Close()
  596. getter := QuotaGetter{
  597. DeliveryID: "YTO",
  598. BizID: "xyz",
  599. }
  600. _, err := getter.get(ts.URL+apiGetQuota, "mock-access-token")
  601. if err != nil {
  602. t.Fatal(err)
  603. }
  604. }
  605. func TestOnPathUpdate(t *testing.T) {
  606. ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  607. aesKey := base64.StdEncoding.EncodeToString([]byte("mock-aes-key"))
  608. srv, err := NewServer("mock-app-id", "mock-access-token", aesKey, "mock-mch-id", "mock-api-key", false)
  609. if err != nil {
  610. t.Fatal(err)
  611. }
  612. srv.OnExpressPathUpdate(func(mix *ExpressPathUpdateResult) {
  613. if mix.ToUserName == "" {
  614. t.Error("ToUserName can not be empty")
  615. }
  616. if mix.FromUserName == "" {
  617. t.Error("FromUserName can not be empty")
  618. }
  619. if mix.CreateTime == 0 {
  620. t.Error("CreateTime can not be zero")
  621. }
  622. if mix.MsgType != "event" {
  623. t.Error("Unexpected message type")
  624. }
  625. if mix.Event != "add_express_path" {
  626. t.Error("Unexpected message event")
  627. }
  628. if mix.DeliveryID == "" {
  629. t.Error("DeliveryID can not be empty")
  630. }
  631. if mix.WayBillID == "" {
  632. t.Error("WayBillID can not be empty")
  633. }
  634. if mix.Version == 0 {
  635. t.Error("Version can not be zero")
  636. }
  637. if mix.Count == 0 {
  638. t.Error("Count can not be zero")
  639. }
  640. if len(mix.Actions) > 0 {
  641. if mix.Actions[0].ActionTime == 0 {
  642. t.Error("Actions.ActionTime can not be zero")
  643. }
  644. if mix.Actions[0].ActionType == 0 {
  645. t.Error("Actions.ActionType can not be zero")
  646. }
  647. if mix.Actions[0].ActionMsg == "" {
  648. t.Error("Actions.ActionMsg can not be empty")
  649. }
  650. }
  651. })
  652. if err := srv.Serve(w, r); err != nil {
  653. t.Fatal(err)
  654. }
  655. }))
  656. defer ts.Close()
  657. xmlData := `<xml>
  658. <ToUserName><![CDATA[toUser]]></ToUserName>
  659. <FromUserName><![CDATA[fromUser]]></FromUserName>
  660. <CreateTime>1546924844</CreateTime>
  661. <MsgType><![CDATA[event]]></MsgType>
  662. <Event><![CDATA[add_express_path]]></Event>
  663. <DeliveryID><![CDATA[SF]]></DeliveryID>
  664. <WayBillId><![CDATA[123456789]]></WayBillId>
  665. <Version>3</Version>
  666. <Count>3</Count>
  667. <Actions>
  668. <ActionTime>1546924840</ActionTime>
  669. <ActionType>100001</ActionType>
  670. <ActionMsg><![CDATA[小哥A揽件成功]]></ActionMsg>
  671. </Actions>
  672. <Actions>
  673. <ActionTime>1546924841</ActionTime>
  674. <ActionType>200001</ActionType>
  675. <ActionMsg><![CDATA[到达广州集包地]]></ActionMsg>
  676. </Actions>
  677. <Actions>
  678. <ActionTime>1546924842</ActionTime>
  679. <ActionType>200001</ActionType>
  680. <ActionMsg><![CDATA[运往目的地]]></ActionMsg>
  681. </Actions>
  682. </xml>`
  683. res, err := http.Post(ts.URL, "text/xml", strings.NewReader(xmlData))
  684. if err != nil {
  685. t.Fatal(err)
  686. }
  687. defer res.Body.Close()
  688. jsonData := `{
  689. "ToUserName": "toUser",
  690. "FromUserName": "fromUser",
  691. "CreateTime": 1546924844,
  692. "MsgType": "event",
  693. "Event": "add_express_path",
  694. "DeliveryID": "SF",
  695. "WayBillId": "123456789",
  696. "Version": 2,
  697. "Count": 3,
  698. "Actions": [
  699. {
  700. "ActionTime": 1546924840,
  701. "ActionType": 100001,
  702. "ActionMsg": "小哥A揽件成功"
  703. },
  704. {
  705. "ActionTime": 1546924841,
  706. "ActionType": 200001,
  707. "ActionMsg": "到达广州集包地"
  708. },
  709. {
  710. "ActionTime": 1546924842,
  711. "ActionType": 200001,
  712. "ActionMsg": "运往目的地"
  713. }
  714. ]
  715. }`
  716. res, err = http.Post(ts.URL, "application/json", strings.NewReader(jsonData))
  717. if err != nil {
  718. t.Fatal(err)
  719. }
  720. defer res.Body.Close()
  721. }
  722. func TestTestUpdateOrder(t *testing.T) {
  723. ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  724. if r.Method != "POST" {
  725. t.Fatalf("Expect 'POST' get '%s'", r.Method)
  726. }
  727. path := r.URL.EscapedPath()
  728. expectedPath := "/cgi-bin/express/business/test_update_order"
  729. if path != expectedPath {
  730. t.Fatalf("Except to path '%s',get '%s'", expectedPath, path)
  731. }
  732. if err := r.ParseForm(); err != nil {
  733. t.Fatal(err)
  734. }
  735. if r.Form.Get("access_token") == "" {
  736. t.Fatalf("access_token can not be empty")
  737. }
  738. params := struct {
  739. BizID string `json:"biz_id"` // 商户id,需填test_biz_id
  740. OrderID string `json:"order_id"` // 订单ID,下单成功时返回
  741. WaybillID string `json:"waybill_id"` // 运单 ID
  742. DeliveryID string `json:"delivery_id"` // 快递公司 ID
  743. ActionTime uint `json:"action_time"` // 轨迹变化 Unix 时间戳
  744. ActionType int `json:"action_type"` // 轨迹变化类型
  745. ActionMsg string `json:"action_msg"` // 轨迹变化具体信息说明,展示在快递轨迹详情页中。若有手机号码,则直接写11位手机号码。使用UTF-8编码。
  746. }{}
  747. if err := json.NewDecoder(r.Body).Decode(&params); err != nil {
  748. t.Fatal(err)
  749. }
  750. if params.DeliveryID == "" {
  751. t.Error("param delivery_id can not be empty")
  752. }
  753. if params.OrderID == "" {
  754. t.Error("param order_id can not be empty")
  755. }
  756. if params.WaybillID == "" {
  757. t.Error("param waybill_id can not be empty")
  758. }
  759. if params.BizID == "" {
  760. t.Error("param biz_id can not be empty")
  761. }
  762. if params.ActionMsg == "" {
  763. t.Error("param action_msg can not be empty")
  764. }
  765. if params.ActionTime == 0 {
  766. t.Error("param action_time can not be empty")
  767. }
  768. if params.ActionType == 0 {
  769. t.Error("param action_type can not be empty")
  770. }
  771. w.WriteHeader(http.StatusOK)
  772. w.Header().Set("Content-Type", "application/json")
  773. raw := `{
  774. "errcode": 0,
  775. "errmsg": "ok"
  776. }`
  777. if _, err := w.Write([]byte(raw)); err != nil {
  778. t.Fatal(err)
  779. }
  780. }))
  781. defer ts.Close()
  782. params := `{
  783. "biz_id": "test_biz_id",
  784. "order_id": "xxxxxxxxxxxx",
  785. "delivery_id": "TEST",
  786. "waybill_id": "xxxxxxxxxx",
  787. "action_time": 123456789,
  788. "action_type": 100001,
  789. "action_msg": "揽件阶段"
  790. }`
  791. tester := new(UpdateExpressOrderTester)
  792. err := json.Unmarshal([]byte(params), tester)
  793. if err != nil {
  794. t.Error(err)
  795. }
  796. _, err = tester.test(ts.URL+apiTestUpdateOrder, "mock-access-token")
  797. if err != nil {
  798. t.Error(err)
  799. }
  800. }
  801. func TestUpdatePrinter(t *testing.T) {
  802. ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  803. if r.Method != "POST" {
  804. t.Fatalf("Expect 'POST' get '%s'", r.Method)
  805. }
  806. path := r.URL.EscapedPath()
  807. if path != "/cgi-bin/express/business/printer/update" {
  808. t.Error("Invalid request path")
  809. }
  810. if err := r.ParseForm(); err != nil {
  811. t.Fatal(err)
  812. }
  813. if r.Form.Get("access_token") == "" {
  814. t.Fatalf("access_token can not be empty")
  815. }
  816. params := struct {
  817. OpenID string `json:"openid"` // 打印员 openid
  818. Type BindType `json:"update_type"` // 更新类型
  819. TagIDList string `json:"tagid_list"`
  820. }{}
  821. if err := json.NewDecoder(r.Body).Decode(&params); err != nil {
  822. t.Fatal(err)
  823. }
  824. if params.OpenID == "" {
  825. t.Error("param openid can not be empty")
  826. }
  827. if params.Type == "" {
  828. t.Error("param update_type can not be empty")
  829. }
  830. w.WriteHeader(http.StatusOK)
  831. w.Header().Set("Content-Type", "application/json")
  832. raw := `{
  833. "errcode": 0,
  834. "errmsg": "ok"
  835. }`
  836. if _, err := w.Write([]byte(raw)); err != nil {
  837. t.Fatal(err)
  838. }
  839. }))
  840. defer ts.Close()
  841. params := `{
  842. "openid": "oJ4v0wRAfiXcnIbM3SgGEUkTw3Qw",
  843. "update_type": "bind",
  844. "tagid_list": "123,456"
  845. }`
  846. updater := new(PrinterUpdater)
  847. err := json.Unmarshal([]byte(params), updater)
  848. if err != nil {
  849. t.Fatal(err)
  850. }
  851. _, err = updater.update(ts.URL+apiUpdatePrinter, "mock-access-token")
  852. if err != nil {
  853. t.Fatal(err)
  854. }
  855. }