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.
 
 
 
 
 
 

565 lines
23 KiB

  1. <?php declare(strict_types=1);
  2. /**
  3. * Created by PhpStorm.
  4. * User: zhengmingwei
  5. * Date: 2020/5/6
  6. * Time: 12:17 AM
  7. */
  8. namespace tests\unishop\controller;
  9. use addons\unishop\controller\Address;
  10. use addons\unishop\controller\Cart;
  11. use addons\unishop\controller\Order;
  12. use addons\unishop\controller\Pay;
  13. use addons\unishop\controller\Product;
  14. use addons\unishop\extend\Hashids;
  15. use addons\unishop\extend\PhpunitFunctionCustomize;
  16. use addons\unishop\model\Coupon;
  17. use addons\unishop\model\OrderRefund;
  18. use PHPUnit\Framework\TestCase;
  19. class OrderTest extends TestCase
  20. {
  21. use PhpunitFunctionCustomize;
  22. /**
  23. * @test
  24. */
  25. public function getProduct()
  26. {
  27. $this->userLogin();
  28. $products = (new \addons\unishop\model\Product)->where(['switch' => \addons\unishop\model\Product::SWITCH_ON])->field('id,specTableList,use_spec')->select();
  29. if ($products) {
  30. return collection($products)->append(['spec_table_list'])->toArray();
  31. }
  32. return [];
  33. }
  34. /**
  35. * @test
  36. */
  37. public function getAddress()
  38. {
  39. $contents = $this->request(Address::class, 'add', [
  40. 'name' => 'unishop',
  41. 'mobile' => self::$mobile,
  42. 'address' => 'unishop Address',
  43. 'is_default' => 1,
  44. 'province_id' => 1,
  45. 'city_id' => 2,
  46. 'area_id' => 3,
  47. ]);
  48. $this->assertIsArray($contents);
  49. $this->assertSame(1, $contents['code']);
  50. }
  51. /**
  52. * @test
  53. * @depends getProduct
  54. */
  55. public function addToCartAndCreatingOrder(array $products)
  56. {
  57. foreach ($products as $product) {
  58. $params['id'] = $product['product_id'];
  59. $params['spec'] = '';
  60. if ($product['use_spec'] == \addons\unishop\model\Product::SPEC_ON) {
  61. foreach ($product['spec_table_list'] as $row) {
  62. $params['spec'] = implode(',', $row['value']);
  63. $contents = $this->request(Cart::class, 'add', $params, 'get');
  64. $this->assertArrayHasKey('code', $contents);
  65. $this->assertArrayHasKey('data', $contents);
  66. $this->create(['id' => $product['product_id'], 'spec' => $params['spec']]);
  67. }
  68. } else {
  69. unset($params['spec']);
  70. $contents = $this->request(Cart::class, 'add', $params, 'get');
  71. $this->assertArrayHasKey('code', $contents);
  72. $this->assertArrayHasKey('data', $contents);
  73. $this->create(['id' => $product['product_id']]);
  74. }
  75. }
  76. }
  77. /**
  78. * @test
  79. */
  80. public function getCartList()
  81. {
  82. $contents = $this->request(Cart::class, 'index');
  83. $this->assertIsArray($contents);
  84. $this->assertSame(1, $contents['code']);
  85. $this->assertIsArray($contents['data']);
  86. if (count($contents['data']) > 0) {
  87. $cartIds = array_column($contents['data'], 'cart_id');
  88. $this->create(['cart' => implode(',', $cartIds)]);
  89. }
  90. }
  91. public function create($params = [])
  92. {
  93. if (!empty($params)) {
  94. $contents = $this->request(Order::class, 'create', $params);
  95. //print_r($contents);
  96. $this->assertIsArray($contents);
  97. $this->assertArrayHasKey('code', $contents);
  98. $this->assertArrayHasKey('data', $contents);
  99. if ($contents['code'] == 1) {
  100. $this->assertIsArray($contents['data']);
  101. $this->assertArrayHasKey('product', $contents['data']);
  102. $this->assertArrayHasKey('address', $contents['data']);
  103. $this->assertArrayHasKey('coupon', $contents['data']);
  104. $this->assertArrayHasKey('delivery', $contents['data']);
  105. // 验证商品
  106. $total_price = 0;
  107. $productIdToCreate = $specToCreate = $numberToCreate = [];
  108. foreach ($contents['data']['product'] as $product) {
  109. $this->assertNotEmpty($product['image']);
  110. $this->assertGreaterThanOrEqual(0, $product['market_price']);
  111. $this->assertGreaterThanOrEqual(0, $product['sales']);
  112. $this->assertGreaterThanOrEqual(0, $product['sales_price']);
  113. $this->assertGreaterThanOrEqual(0, $product['stock']);
  114. $this->assertGreaterThanOrEqual(1, $product['number']);
  115. $this->assertNotEmpty($product['title']);
  116. $this->assertNotEmpty($product['id']);
  117. $this->assertArrayHasKey('spec', $product);
  118. $total_price += $product['sales_price'];
  119. $productIdToCreate[] = $product['id'];
  120. $numberToCreate[] = $product['number'];
  121. $specToCreate[] = str_replace(',', '|', $product['spec']);
  122. }
  123. // 验证地址
  124. $address = $contents['data']['address'];
  125. $this->assertNotEmpty($address['id']);
  126. $this->assertNotEmpty($address['name']);
  127. $this->assertNotEmpty($address['mobile']);
  128. $this->assertNotEmpty($address['province_id']);
  129. $this->assertNotEmpty($address['city_id']);
  130. $this->assertNotEmpty($address['area_id']);
  131. $this->assertNotEmpty($address['province']['name']);
  132. $this->assertNotEmpty($address['city']['name']);
  133. $this->assertNotEmpty($address['area']['name']);
  134. // 验证优惠券
  135. $coupons = $contents['data']['coupon'];
  136. $useCouponId = 0;
  137. if (count($coupons)) {
  138. foreach ($coupons as $coupon) {
  139. $this->assertNotEmpty($coupon['id']);
  140. $this->assertNotEmpty($coupon['title']);
  141. $this->assertSame(1, $coupon['switch']);
  142. $this->assertGreaterThanOrEqual(0, $coupon['least']);
  143. $this->assertGreaterThan($coupon['value'], $coupon['least']);
  144. $this->assertGreaterThan($coupon['starttime'], time());
  145. $this->assertGreaterThan(time(), $coupon['endtime']);
  146. $this->assertEmpty($coupon['deletetime']);
  147. if ($total_price > $coupon['least']) {
  148. $useCouponId = $coupon['id'];
  149. }
  150. }
  151. }
  152. // 验证物流
  153. $deliverys = $contents['data']['delivery'];
  154. if (count($deliverys) > 0) {
  155. foreach ($deliverys as $delivery) {
  156. $this->assertNotEmpty($delivery['id']);
  157. $this->assertNotEmpty($delivery['name']);
  158. $this->assertNotEmpty($delivery['type']);
  159. $this->assertGreaterThan(0, $delivery['min']);
  160. $this->assertGreaterThan(0, $delivery['first']);
  161. $this->assertGreaterThan(0, $delivery['additional']);
  162. $this->assertGreaterThanOrEqual(0, $delivery['first_fee']);
  163. $this->assertGreaterThanOrEqual(0, $delivery['additional_fee']);
  164. // 创建订单
  165. $this->submit([
  166. 'city_id' => $address['city_id'],
  167. 'address_id' => $address['id'],
  168. 'delivery_id' => $delivery['id'],
  169. 'coupon_id' => $useCouponId,
  170. 'remark' => 'unishop_remark',
  171. 'product_id' => implode(',', $productIdToCreate),
  172. 'spec' => implode(',', $specToCreate),
  173. 'number' => implode(',', $numberToCreate),
  174. ]);
  175. }
  176. }
  177. }
  178. }
  179. }
  180. public function submit($params = [])
  181. {
  182. $this->userLogin();
  183. $contents = $this->request(Order::class, 'submit', $params);
  184. $this->assertIsArray($contents);
  185. $this->assertArrayHasKey('code', $contents);
  186. $this->assertArrayHasKey('data', $contents);
  187. if ($contents['code'] == 1) {
  188. $this->assertNotEmpty($contents['data']['order_id']);
  189. $this->assertNotEmpty($contents['data']['out_trade_no']);
  190. // 测试货到付款
  191. $contents = $this->request(Pay::class, 'offline', ['order_id' => $contents['data']['order_id']], 'get');
  192. $this->assertIsArray($contents);
  193. $this->assertArrayHasKey('code', $contents);
  194. $this->assertArrayHasKey('data', $contents);
  195. }
  196. }
  197. /**
  198. * @test
  199. */
  200. public function getDelivery($city_id = 3)
  201. {
  202. $contents = $this->request(Order::class, 'getDelivery', ['city_id' => $city_id], 'get');
  203. $this->assertIsArray($contents);
  204. $this->assertSame(1, $contents['code']);
  205. $this->assertArrayHasKey('data', $contents);
  206. if (count($contents['data']) > 0) {
  207. foreach ($contents['data'] as $delivery) {
  208. $this->assertNotEmpty($delivery['id']);
  209. $this->assertNotEmpty($delivery['name']);
  210. $this->assertNotEmpty($delivery['type']);
  211. $this->assertGreaterThan(0, $delivery['min']);
  212. $this->assertGreaterThan(0, $delivery['first']);
  213. $this->assertGreaterThan(0, $delivery['additional']);
  214. $this->assertGreaterThanOrEqual(0, $delivery['first_fee']);
  215. $this->assertGreaterThanOrEqual(0, $delivery['additional_fee']);
  216. }
  217. }
  218. }
  219. public function getOrdersProvider()
  220. {
  221. return [
  222. [0, 1, 10],
  223. [1, 1, 10]
  224. ];
  225. }
  226. /**
  227. * @test
  228. * @dataProvider getOrdersProvider
  229. */
  230. public function getOrders($type, $page, $pagesize)
  231. {
  232. $this->userLogin();
  233. $contents = $this->request(Order::class, 'getOrders', ['type' => $type, 'page' => $page, 'pagesize' => $pagesize], 'get');
  234. $this->assertIsArray($contents);
  235. foreach ($contents['data'] as $order) {
  236. $this->assertNotEmpty($order['out_trade_no']);
  237. $this->assertGreaterThanOrEqual(0, $order['order_price']);
  238. $this->assertGreaterThanOrEqual(0, $order['discount_price']);
  239. $this->assertGreaterThanOrEqual(0, $order['delivery_price']);
  240. $this->assertGreaterThanOrEqual(0, $order['total_price']);
  241. $this->assertGreaterThanOrEqual($order['total_price'], $order['order_price']);
  242. $this->assertTrue(in_array($order['pay_type'], [
  243. \addons\unishop\model\Order::PAY_ONLINE,
  244. \addons\unishop\model\Order::PAY_OFFLINE,
  245. \addons\unishop\model\Order::PAY_WXPAY,
  246. \addons\unishop\model\Order::PAY_ALIPAY
  247. ]));
  248. $this->assertArrayHasKey('remark', $order);
  249. $this->assertTrue(in_array($order['status'], [
  250. \addons\unishop\model\Order::STATUS_REFUND,
  251. \addons\unishop\model\Order::STATUS_CANCEL,
  252. \addons\unishop\model\Order::STATUS_NORMAL
  253. ]));
  254. $this->assertGreaterThanOrEqual(0, $order['have_paid']);
  255. $this->assertGreaterThanOrEqual(0, $order['have_delivered']);
  256. $this->assertGreaterThanOrEqual(0, $order['have_received']);
  257. $this->assertGreaterThanOrEqual(0, $order['have_commented']);
  258. $this->assertGreaterThanOrEqual(0, $order['refund_status']);
  259. $this->assertGreaterThanOrEqual(0, $order['had_refund']);
  260. $this->assertNotEmpty($order['createtime']);
  261. $this->assertIsArray($order['products']);
  262. foreach ($order['products'] as $product) {
  263. $this->assertNotEmpty($product['id']);
  264. $this->assertNotEmpty($product['title']);
  265. $this->assertNotEmpty($product['image']);
  266. $this->assertGreaterThanOrEqual(1, $product['number']);
  267. $this->assertGreaterThanOrEqual(0, $product['price']);
  268. $this->assertArrayHasKey('spec', $product);
  269. $this->assertNotEmpty($product['order_product_id']);
  270. $this->assertArrayHasKey('evaluate', $product);
  271. $this->assertArrayHasKey('refund', $product);
  272. }
  273. $this->assertArrayHasKey('extend', $order);
  274. $this->assertArrayHasKey('express_number', $order['extend']);
  275. $this->assertNotEmpty($order['order_id']);
  276. $this->assertTrue(in_array($order['state'], [
  277. \addons\unishop\model\Order::TYPE_ALL,
  278. \addons\unishop\model\Order::TYPE_PAY,
  279. \addons\unishop\model\Order::TYPE_DELIVES,
  280. \addons\unishop\model\Order::TYPE_RECEIVE,
  281. \addons\unishop\model\Order::TYPE_COMMENT,
  282. \addons\unishop\model\Order::TYPE_REFUND,
  283. \addons\unishop\model\Order::TYPE_REFUSE,
  284. \addons\unishop\model\Order::TYPE_OFF
  285. ]));
  286. $this->assertArrayHasKey('refund_status_text', $order);
  287. if ($order['have_paid'] > 0) {
  288. // 已支付
  289. // 改订单改成已发货, 尝试收货,尝试取消订单并删除
  290. $row = \addons\unishop\model\Order::get(Hashids::decodeHex($order['order_id']), ['extend']);
  291. if ($row) {
  292. $res1 = $row->save(['have_delivered' => time()]);
  293. $res2 = $row->extend->save(['express_number' => self::$mobile]);
  294. $this->received($order['order_id'], array_column($order['products'], 'id'));
  295. $this->cancel($order['order_id']);
  296. }
  297. } else {
  298. // 未支付
  299. // 尝试收货,尝试取消订单并删除
  300. $this->received($order['order_id'], array_column($order['products'], 'id'));
  301. $this->cancel($order['order_id']);
  302. }
  303. }
  304. }
  305. public function cancel($orderId)
  306. {
  307. $contents = $this->request(Order::class, 'cancel', ['order_id' => $orderId], 'get');
  308. $this->assertIsArray($contents);
  309. $this->assertArrayHasKey('code', $contents);
  310. $this->assertArrayHasKey('data', $contents);
  311. $this->delete($orderId);
  312. }
  313. public function delete($orderId)
  314. {
  315. $contents = $this->request(Order::class, 'delete', ['order_id' => $orderId], 'get');
  316. $this->assertIsArray($contents);
  317. $this->assertArrayHasKey('code', $contents);
  318. $this->assertArrayHasKey('data', $contents);
  319. }
  320. public function received($orderId, $productIds)
  321. {
  322. $contents = $this->request(Order::class, 'received', ['order_id' => $orderId], 'get');
  323. $this->assertIsArray($contents);
  324. $this->assertArrayHasKey('code', $contents);
  325. $this->assertArrayHasKey('data', $contents);
  326. $this->comment($orderId, $productIds);
  327. }
  328. public function comment($orderId, $productIds)
  329. {
  330. foreach ($productIds as $productId) {
  331. $contents = $this->request(Order::class, 'comment', [
  332. 'rate' => 5,
  333. 'anonymous' => 1,
  334. 'comment' => 'unishop_comment',
  335. 'order_id' => $orderId,
  336. 'product_id' => $productId
  337. ]);
  338. $this->assertIsArray($contents);
  339. $this->assertArrayHasKey('code', $contents);
  340. $this->assertArrayHasKey('data', $contents);
  341. $this->detail($orderId);
  342. $this->refundInfo($orderId);
  343. }
  344. }
  345. public function detail($orderId)
  346. {
  347. $contents = $this->request(Order::class, 'detail', ['order_id' => $orderId], 'get');
  348. $this->assertIsArray($contents);
  349. $this->assertSame(1, $contents['code']);
  350. $this->assertIsArray($contents['data']);
  351. $order = $contents['data'];
  352. $this->assertNotEmpty($order['out_trade_no']);
  353. $this->assertGreaterThanOrEqual(0, $order['order_price']);
  354. $this->assertGreaterThanOrEqual(0, $order['discount_price']);
  355. $this->assertGreaterThanOrEqual(0, $order['delivery_price']);
  356. $this->assertGreaterThanOrEqual(0, $order['total_price']);
  357. $this->assertGreaterThanOrEqual($order['total_price'], $order['order_price']);
  358. $this->assertTrue(in_array($order['pay_type'], [
  359. \addons\unishop\model\Order::PAY_ONLINE,
  360. \addons\unishop\model\Order::PAY_OFFLINE,
  361. \addons\unishop\model\Order::PAY_WXPAY,
  362. \addons\unishop\model\Order::PAY_ALIPAY,
  363. ]));
  364. $this->assertArrayHasKey('remark', $order);
  365. $this->assertArrayHasKey('status', $order);
  366. $this->assertGreaterThanOrEqual(0, $order['have_paid']);
  367. $this->assertGreaterThanOrEqual(0, $order['have_delivered']);
  368. $this->assertGreaterThanOrEqual(0, $order['have_received']);
  369. $this->assertGreaterThanOrEqual(0, $order['have_commented']);
  370. $this->assertGreaterThanOrEqual(0, $order['had_refund']);
  371. $this->assertTrue(in_array($order['refund_status'], [
  372. \addons\unishop\model\Order::REFUND_STATUS_NONE,
  373. \addons\unishop\model\Order::REFUND_STATUS_APPLY,
  374. \addons\unishop\model\Order::REFUND_STATUS_DELIVERY,
  375. \addons\unishop\model\Order::REFUND_STATUS_AGREE,
  376. \addons\unishop\model\Order::REFUND_STATUS_REFUSE,
  377. ]));
  378. $this->assertNotEmpty($order['createtime']);
  379. $this->assertIsArray($order['products']);
  380. foreach ($order['products'] as $product) {
  381. $this->assertNotEmpty($product['id']);
  382. $this->assertNotEmpty($product['image']);
  383. $this->assertGreaterThanOrEqual(1, $product['number']);
  384. $this->assertGreaterThanOrEqual(0, $product['price']);
  385. $this->assertArrayHasKey('spec', $product);
  386. $this->assertNotEmpty($product['title']);
  387. $this->assertNotEmpty($product['order_product_id']);
  388. $this->assertArrayHasKey('evaluate', $product);
  389. }
  390. $this->assertArrayHasKey('state', $order);
  391. $this->assertArrayHasKey('paidtime', $order);
  392. $this->assertArrayHasKey('deliveredtime', $order);
  393. $this->assertArrayHasKey('receivedtime', $order);
  394. $this->assertArrayHasKey('commentedtime', $order);
  395. $this->assertNotEmpty($order['pay_type_text']);
  396. $this->assertArrayHasKey('refund_status_text', $order);
  397. $this->assertArrayHasKey('express_number', $order);
  398. $this->assertIsArray($order['delivery']);
  399. $this->assertNotEmpty($order['delivery']['username']);
  400. $this->assertNotEmpty($order['delivery']['mobile']);
  401. $this->assertNotEmpty($order['delivery']['address']);
  402. }
  403. public function refundInfo($orderId)
  404. {
  405. $this->userLogin();
  406. $contents = $this->request(Order::class, 'refundInfo', [
  407. 'order_id' => $orderId
  408. ]);
  409. $this->assertIsArray($contents);
  410. $this->assertArrayHasKey('code', $contents);
  411. $this->assertIsArray($contents['data']);
  412. $this->assertArrayHasKey('status', $contents['data']);
  413. $this->assertArrayHasKey('total_price', $contents['data']);
  414. $this->assertArrayHasKey('delivery_price', $contents['data']);
  415. $this->assertArrayHasKey('have_commented', $contents['data']);
  416. $this->assertArrayHasKey('have_delivered', $contents['data']);
  417. $this->assertArrayHasKey('have_paid', $contents['data']);
  418. $this->assertArrayHasKey('have_received', $contents['data']);
  419. $this->assertArrayHasKey('refund_status', $contents['data']);
  420. $this->assertArrayHasKey('refund', $contents['data']);
  421. $this->assertArrayHasKey('refund_status_text', $contents['data']);
  422. $this->assertIsArray($contents['data']['products']);
  423. $order_product_id = [];
  424. foreach ($contents['data']['products'] as $product) {
  425. $this->assertNotEmpty($product['id']);
  426. $this->assertNotEmpty($product['image']);
  427. $this->assertNotEmpty($product['number']);
  428. $this->assertGreaterThanOrEqual(0, $product['price']);
  429. $this->assertArrayHasKey('spec', $product);
  430. $this->assertNotEmpty($product['title']);
  431. $this->assertArrayHasKey('choose', $product);
  432. $this->assertNotEmpty($product['order_product_id']);
  433. $order_product_id[] = $product['order_product_id'];
  434. }
  435. $this->refund($orderId, implode(',', $order_product_id));
  436. }
  437. public function refund($orderId, $order_product_id)
  438. {
  439. $contents = $this->request(Order::class, 'refund', [
  440. 'order_id' => $orderId,
  441. 'amount' => 100,
  442. 'service_type' => OrderRefund::TYPE_REFUND_NORETURN,
  443. 'receiving_status' => OrderRefund::RECEIVED,
  444. 'reason_type' => '其他',
  445. 'refund_explain' => 'unishop',
  446. 'order_product_id' => $order_product_id
  447. ]);
  448. $this->assertIsArray($contents);
  449. $this->assertArrayHasKey('code', $contents);
  450. $this->assertArrayHasKey('data', $contents);
  451. $this->assertSame(1, $contents['code']);
  452. if ($contents['code'] == 1) {
  453. $this->refundDelivery($orderId);
  454. }
  455. }
  456. public function refundDelivery($orderId)
  457. {
  458. $contents = $this->request(Order::class, 'refundDelivery', [
  459. 'order_id' => $orderId,
  460. 'express_number' => 'unishop'
  461. ]);
  462. $this->assertIsArray($contents);
  463. $this->assertArrayHasKey('code', $contents);
  464. $this->assertArrayHasKey('data', $contents);
  465. }
  466. /**
  467. * @test
  468. */
  469. public function countTest()
  470. {
  471. $this->userLogin();
  472. $contents = $this->request(Order::class, 'count');
  473. $this->assertIsArray($contents);
  474. $this->assertSame(1, $contents['code']);
  475. $this->assertIsArray($contents['data']);
  476. $this->assertGreaterThanOrEqual(0, $contents['data']['unpaid']);
  477. $this->assertGreaterThanOrEqual(0, $contents['data']['undelivered']);
  478. $this->assertGreaterThanOrEqual(0, $contents['data']['unreceived']);
  479. $this->assertGreaterThanOrEqual(0, $contents['data']['uncomment']);
  480. }
  481. public static function tearDownAfterClass()
  482. {
  483. $user = (new self())->userLogin()['data'];
  484. \addons\unishop\model\Address::destroy(['user_id' => $user['user_id']]);
  485. \addons\unishop\model\Cart::destroy(['user_id' => $user['user_id']]);
  486. \addons\unishop\model\Order::destroy(['user_id' => $user['user_id']], true);
  487. \addons\unishop\model\OrderProduct::destroy(['user_id' => $user['user_id']]);
  488. \addons\unishop\model\OrderExtend::destroy(['user_id' => $user['user_id']]);
  489. \addons\unishop\model\OrderRefund::destroy(['user_id' => $user['user_id']]);
  490. \addons\unishop\model\OrderRefundProduct::destroy(['user_id' => $user['user_id']]);
  491. \addons\unishop\model\Cart::destroy(['user_id' => $user['user_id']]);
  492. \addons\unishop\model\Evaluate::destroy(['user_id' => $user['user_id']], true);
  493. }
  494. }