def test_make_order(): uid, token = next(token_gen) cart_id = new_cart(token) item_items = [next(item_gen)] # make order success res = make_order(uid, token, cart_id, item_items) assert res.status_code == 200 order_id = res.json()["order_id"] assert len(order_id) > 0 # verify query return the same order orders = json_get("/orders", token).json() assert len(orders) == 1 q_order = orders[0] assert q_order["id"] == order_id assert q_order["items"] == item_items # verify order info correct _price = lambda i: item_store[i]["price"] assert q_order["total"] == sum( _price(item["item_id"]) * item["count"] for item in q_order["items"]) # test only one order can be made res2 = make_order(uid, token, cart_id, item_items) assert res2.status_code == 403 assert res2.json() == { "code": "ORDER_OUT_OF_LIMIT", "message": u"每个用户只能下一单" }
def test_make_order(): uid, token = next(token_gen) cart_id = new_cart(token) food_items = [next(food_gen)] # make order success res = make_order(uid, token, cart_id, food_items) assert res.status_code == 200 order_id = res.json()["id"] assert len(order_id) > 0 # verify query return the same order orders = json_get("/orders", token).json() assert len(orders) == 1 q_order = orders[0] assert q_order["id"] == order_id assert q_order["items"] == food_items # verify order info correct _price = lambda i: food_store[i]["price"] assert q_order["total"] == sum( _price(item["food_id"]) * item["count"] for item in q_order["items"]) # test only one order can be made res2 = make_order(uid, token, cart_id, food_items) assert res2.status_code == 403 assert res2.json() == {"code": "ORDER_OUT_OF_LIMIT", "message": u"每个用户只能下一单"}
def test_food_not_oversold_under_concurrent(): TEST_FOOD_COUNT = 5 TEST_FOOD_STOCK = 10 # random choose foods with more than 10 stock test_food_ids = random.sample( [f for f, s in food_store.items() if s["stock"] >= TEST_FOOD_STOCK], TEST_FOOD_COUNT) for food_id in test_food_ids: buy_to_stock(food_id, TEST_FOOD_STOCK) assert food_store[food_id]["stock"] == TEST_FOOD_STOCK # enumerate all food items total_food_items = [] for food_id in test_food_ids: remain_stock = food_store[food_id]["stock"] items = [{"food_id": food_id, "count": 1}] * remain_stock total_food_items.extend(items) assert len(total_food_items) == TEST_FOOD_COUNT * TEST_FOOD_STOCK # try to buy as much as twice of the stock test_food_items = total_food_items * 2 random.shuffle(test_food_items) # prepare carts & tokens, each carts contains 2 foods cart_ids, tokens, items_list = [], [], [] for food_items in zip(test_food_items[::2], test_food_items[1::2]): _, token = next(token_gen) cart_id = new_cart(token) for item in food_items: res = json_patch("/carts/%s" % cart_id, token, item) assert res.status_code == 204 cart_ids.append(cart_id) tokens.append(token) items_list.append(food_items) def _make(cart_id, token, food_items): res = json_post("/orders", token, {"cart_id": cart_id}) if res.status_code == 200: for food_item in food_items: food_store[food_item["food_id"]]["stock"] -= 1 return res # make order with prepared carts, using 3 concurrent threads # allow sell slower (remain stock > 0) # best sell all and correct (remain stock == 0) # disallow oversold (remain stock < 0) with ThreadPoolExecutor(max_workers=3) as executor: future_results = [ executor.submit(_make, ct, tk, fs) for ct, tk, fs in zip(cart_ids, tokens, items_list)] concurrent.futures.wait(future_results, timeout=30) # test not oversold for food_id in test_food_ids: print("stock %s -> %s" % (food_id, food_store[food_id]["stock"])) assert food_store[food_id]["stock"] >= 0
def test_food_not_oversold_under_concurrent(): TEST_FOOD_COUNT = 5 TEST_FOOD_STOCK = 10 # random choose foods with more than 10 stock test_food_ids = random.sample( [f for f, s in food_store.items() if s["stock"] >= TEST_FOOD_STOCK], TEST_FOOD_COUNT) for food_id in test_food_ids: buy_to_stock(food_id, TEST_FOOD_STOCK) assert food_store[food_id]["stock"] == TEST_FOOD_STOCK # enumerate all food items total_food_items = [] for food_id in test_food_ids: remain_stock = food_store[food_id]["stock"] items = [{"food_id": food_id, "count": 1}] * remain_stock total_food_items.extend(items) assert len(total_food_items) == TEST_FOOD_COUNT * TEST_FOOD_STOCK # try to buy as much as twice of the stock test_food_items = total_food_items * 2 random.shuffle(test_food_items) # prepare carts & tokens, each carts contains 2 foods cart_ids, tokens, items_list = [], [], [] for food_items in zip(test_food_items[::2], test_food_items[1::2]): _, token = next(token_gen) cart_id = new_cart(token) for item in food_items: res = json_patch("/carts/%s" % cart_id, token, item) assert res.status_code == 204 cart_ids.append(cart_id) tokens.append(token) items_list.append(food_items) def _make(cart_id, token, food_items): res = json_post("/orders", token, {"cart_id": cart_id}) if res.status_code == 200: for food_item in food_items: food_store[food_item["food_id"]]["stock"] -= 1 return res # make order with prepared carts, using 3 concurrent threads # allow sell slower (remain stock > 0) # best sell all and correct (remain stock == 0) # disallow oversold (remain stock < 0) with ThreadPoolExecutor(max_workers=3) as executor: future_results = [ executor.submit(_make, ct, tk, fs) for ct, tk, fs in zip(cart_ids, tokens, items_list)] concurrent.futures.wait(future_results, timeout=30) # test not oversold for food_id in test_food_ids: # print("stock %s -> %s" % (food_id, food_store[food_id]["stock"])) assert food_store[food_id]["stock"] >= 0
def test_cart_not_owned_error(): _, token1 = next(token_gen) _, token2 = next(token_gen) cart_id2 = new_cart(token2) res = json_patch("/carts/%s" % cart_id2, token1, next(food_gen)) assert res.status_code == 401 assert res.json() == {"code": "NOT_AUTHORIZED_TO_ACCESS_CART", "message": u"无权限访问指定的篮子"}
def test_food_not_found_error(): _, token = next(token_gen) cart_id = new_cart(token) item = {"food_id": -1, "count": 2} res = json_patch("/carts/%s" % cart_id, token, item) assert res.status_code == 404 assert res.json() == {"code": "FOOD_NOT_FOUND", "message": u"食物不存在"}
def test_make_order_cart_not_owned_error(): uid, token1 = next(token_gen) cart_id1 = new_cart(token1) _, token2 = next(token_gen) res = make_order(uid, token2, cart_id1, [next(food_gen)]) assert res.status_code == 401 assert res.json() == {"code": "NOT_AUTHORIZED_TO_ACCESS_CART", "message": u"无权限访问指定的篮子"}
def test_pay_order_not_owned_error(): uid, token1 = next(token_gen) cart_id1 = new_cart(token1) _, token2 = next(token_gen) res = make_order(uid, token1, cart_id1, [next(item_gen)]) assert res.status_code == 200 order_id1 = res.json()["order_id"] res = pay_order(uid, token2, order_id1) assert res.status_code == 401 assert res.json() == {"code": "NOT_AUTHORIZED_TO_ACCESS_ORDER", "message": u"无权限访问指定的订单"}
def test_add_food(): _, token = next(token_gen) cart_id = new_cart(token) # success add 3 food for i in range(3): res = json_patch("/carts/%s" % cart_id, token, next(food_gen)) assert res.status_code == 204 assert len(res.content) == 0 # fail if try to add more res = json_patch("/carts/%s" % cart_id, token, next(food_gen)) assert res.status_code == 403 assert res.json() == {"code": "FOOD_OUT_OF_LIMIT", "message": u"篮子中食物数量超过了三个"}
def test_del_food(): _, token = next(token_gen) cart_id = new_cart(token) item = next(food_gen) json_patch("/carts/%s" % cart_id, token, item) # delete existing food item["count"] = -1 res = json_patch("/carts/%s" % cart_id, token, item) assert res.status_code == 204 assert len(res.content) == 0 # delete non-exist food res = json_patch("/carts/%s" % cart_id, token, next(food_gen)) assert res.status_code == 204 assert len(res.content) == 0
def test_pay_order_balance_insufficient(): uid, token = next(balance_insufficient_token_gen) cart_id = new_cart(token) item_items = [next(item_gen)] # make order success res = make_order(uid, token, cart_id, item_items) assert res.status_code == 200 order_id = res.json()["order_id"] assert len(order_id) > 0 res = pay_order(uid, token, order_id) assert res.status_code == 403 assert res.json() == {"code": "BALANCE_INSUFFICIENT", "message": u"余额不足"}
def test_pay_order(): uid, token = next(balance_ok_token_gen) cart_id = new_cart(token) item_items = [next(item_gen)] # make order success res = make_order(uid, token, cart_id, item_items) assert res.status_code == 200 order_id = res.json()["order_id"] assert len(order_id) > 0 res = pay_order(uid, token, order_id) assert res.status_code == 200 # test only one payment can be made res = pay_order(uid, token, order_id) assert res.status_code == 403 assert res.json() == {"code": "ORDER_PAID", "message": u"订单已支付"}