From 41890ddd3386371ed54673170000668ba3e4c134 Mon Sep 17 00:00:00 2001 From: zetaloop Date: Wed, 29 Apr 2026 23:40:17 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20player=20=E8=AF=A6?= =?UTF-8?q?=E6=83=85=20completionRate=20=E5=92=8C=20k8s=20=E5=85=AC?= =?UTF-8?q?=E5=BC=80=E8=B7=AF=E7=94=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 同步 k8s Envoy 中已放行公开接口的实际路由,避免落到泛用 user API;同时规范 dev API 测试脚本的响应体解析,使新增负向断言通过静态检查。 --- .../internal/logic/player/getPlayerLogic.go | 19 +- deploy/dev/test_all_apis.py | 303 ++++++++++++------ deploy/k8s/envoy/envoy.yaml | 92 ++++++ 3 files changed, 313 insertions(+), 101 deletions(-) diff --git a/app/player/api/internal/logic/player/getPlayerLogic.go b/app/player/api/internal/logic/player/getPlayerLogic.go index 2a6d460..fd08f20 100644 --- a/app/player/api/internal/logic/player/getPlayerLogic.go +++ b/app/player/api/internal/logic/player/getPlayerLogic.go @@ -45,15 +45,20 @@ func (l *GetPlayerLogic) GetPlayer(req *types.GetPlayerReq) (resp *types.PlayerP if player == nil { return nil, errors.New("player not found") } + completionRate := 0.0 + if player.TotalOrders > 0 { + completionRate = float64(player.CompletedOrders) / float64(player.TotalOrders) + } resp = &types.PlayerProfile{ - Id: player.Id, - Rating: player.Rating, - TotalOrders: player.TotalOrders, - Status: player.Status, - Gender: player.Gender, - Services: []types.PlayerService{}, - Tags: append([]string{}, player.Tags...), + Id: player.Id, + Rating: player.Rating, + TotalOrders: player.TotalOrders, + CompletionRate: completionRate, + Status: player.Status, + Gender: player.Gender, + Services: []types.PlayerService{}, + Tags: append([]string{}, player.Tags...), } games := make([]string, 0, len(player.Games)) diff --git a/deploy/dev/test_all_apis.py b/deploy/dev/test_all_apis.py index a5626a0..de0b2b2 100644 --- a/deploy/dev/test_all_apis.py +++ b/deploy/dev/test_all_apis.py @@ -16,7 +16,12 @@ import urllib.parse import http.cookiejar import os import subprocess +from collections.abc import Callable from decimal import Decimal, InvalidOperation +from typing import Any + +Body = dict[str, Any] +StatusExpectation = int | tuple[int, ...] | list[int] | set[int] GATEWAY = "http://127.0.0.1:18080" ADMIN_USERNAME = os.getenv("ADMIN_USERNAME", "admin") @@ -50,7 +55,19 @@ def same_id(left, right): return str(left) == str(right) -def body_text(body): +def response_body(data: str) -> Body: + if not data: + return {} + try: + parsed = json.loads(data) + except json.JSONDecodeError: + return {"_raw": data} + if isinstance(parsed, dict): + return parsed + return {"_raw": parsed} + + +def body_text(body: object): if not isinstance(body, dict): return str(body) if "_raw" in body: @@ -72,15 +89,17 @@ def report_rejected(name, status_code, body, expect_status=(400, 403, 500)): report_check(f"{name} returns error body", bool(body_text(body)), body) -def pick_items(body): +def pick_items(body: object) -> list[Body]: + if not isinstance(body, dict): + return [] if isinstance(body.get("items"), list): - return body["items"] + return [item for item in body["items"] if isinstance(item, dict)] if isinstance(body.get("list"), list): - return body["list"] + return [item for item in body["list"] if isinstance(item, dict)] return [] -def find_item(items, predicate): +def find_item(items: list[Body], predicate: Callable[[Body], bool]) -> Body | None: for item in items: if predicate(item): return item @@ -91,7 +110,7 @@ def find_item_by_id(items, item_id): return find_item(items, lambda item: same_id(item.get("id"), item_id)) -def user_from(body): +def user_from(body: Body) -> Body: user = body.get("user") if isinstance(body, dict) else None return user if isinstance(user, dict) else {} @@ -186,7 +205,7 @@ class Session: headers=None, form_data=None, raw_body=None, - ): + ) -> tuple[int, Body, dict[str, str]]: hdrs = headers or {} body = None if json_body is not None: @@ -202,35 +221,31 @@ class Session: try: resp = self.opener.open(req, timeout=15) data = resp.read().decode() - try: - return resp.status, json.loads(data) if data else {}, dict(resp.headers) - except json.JSONDecodeError: - return resp.status, {"_raw": data}, dict(resp.headers) + return resp.status, response_body(data), dict(resp.headers) except urllib.error.HTTPError as e: data = e.read().decode() if e.fp else "" - try: - return e.code, json.loads(data) if data else {}, dict(e.headers) - except json.JSONDecodeError: - return e.code, {"_raw": data}, dict(e.headers) + return e.code, response_body(data), dict(e.headers) except Exception as e: return 0, {"_error": str(e)}, {} - def get(self, url, **kw): + def get(self, url, **kw) -> tuple[int, Body, dict[str, str]]: return self.request("GET", url, **kw) - def post(self, url, **kw): + def post(self, url, **kw) -> tuple[int, Body, dict[str, str]]: return self.request("POST", url, **kw) - def post_multipart(self, url, fields, files, headers=None): + def post_multipart( + self, url, fields, files, headers=None + ) -> tuple[int, Body, dict[str, str]]: hdrs = dict(headers or {}) content_type, body = build_multipart_form(fields, files) hdrs["Content-Type"] = content_type return self.post(url, headers=hdrs, raw_body=body) - def put(self, url, **kw): + def put(self, url, **kw) -> tuple[int, Body, dict[str, str]]: return self.request("PUT", url, **kw) - def delete(self, url, **kw): + def delete(self, url, **kw) -> tuple[int, Body, dict[str, str]]: return self.request("DELETE", url, **kw) def csrf_headers(self): @@ -238,7 +253,7 @@ class Session: return {"xsrf-token": token} if token else {} -def report(name, status_code, body, expect_status=200): +def report(name, status_code, body, expect_status: StatusExpectation = 200): global passed, failed if isinstance(expect_status, (list, tuple, set)): ok = status_code in expect_status @@ -276,7 +291,7 @@ def skip(name, reason): print(f" [SKIP] {name}: {reason}") -def check_order_status(session, order_id, expected_status, label): +def check_order_status(session, order_id, expected_status, label) -> Body: code, body, _ = session.get(f"{GATEWAY}/api/v1/orders/{order_id}") report(f"GET /orders/{order_id} ({label})", code, body) report_check( @@ -521,8 +536,9 @@ def phase3_admin_and_verification( all( find_item( pick_items(body), - lambda item, role=role: item.get("role") == role - and item.get("status") == "pending", + lambda item, role=role: ( + item.get("role") == role and item.get("status") == "pending" + ), ) for role in ("player", "owner") ), @@ -539,8 +555,9 @@ def phase3_admin_and_verification( bool( find_item( pick_items(body), - lambda item: item.get("role") == "owner" - and item.get("status") == "pending", + lambda item: ( + item.get("role") == "owner" and item.get("status") == "pending" + ), ) ), body, @@ -586,9 +603,11 @@ def phase3_admin_and_verification( bool( find_item( pick_items(body), - lambda item: item.get("role") == "owner" - and item.get("status") == "rejected" - and item.get("rejectReason") == "test reject flow", + lambda item: ( + item.get("role") == "owner" + and item.get("status") == "rejected" + and item.get("rejectReason") == "test reject flow" + ), ) ), body, @@ -671,8 +690,9 @@ def phase3b_secondary_player(s_admin: Session, s_player: Session): bool( find_item( pick_items(body), - lambda item: item.get("role") == "player" - and item.get("status") == "pending", + lambda item: ( + item.get("role") == "player" and item.get("status") == "pending" + ), ) ), body, @@ -698,7 +718,9 @@ def phase3b_secondary_player(s_admin: Session, s_player: Session): report("POST /users/me/switch-role (invited user player)", code, body) code, body, _ = s_player.get(f"{GATEWAY}/api/v1/users/me") report("GET /users/me (invited user player role)", code, body) - report_check("invited user current role is player", body.get("role") == "player", body) + report_check( + "invited user current role is player", body.get("role") == "player", body + ) code, body, _ = s_player.post( f"{GATEWAY}/api/v1/players/me", @@ -739,7 +761,9 @@ def phase5_games(s: Session, s_admin: Session): code, body, _ = s.get(f"{GATEWAY}/api/v1/games") report("GET /games", code, body) - report_check("GET /games returns list shape", isinstance(pick_items(body), list), body) + report_check( + "GET /games returns list shape", isinstance(pick_items(body), list), body + ) csrf_admin = s_admin.csrf_headers() game_name = f"TestGame_{rand_str(4)}" @@ -820,7 +844,9 @@ def phase6_player(s: Session, game_id): code, body, _ = s.get(f"{GATEWAY}/api/v1/players") report("GET /players", code, body) - report_check("GET /players returns list shape", isinstance(pick_items(body), list), body) + report_check( + "GET /players returns list shape", isinstance(pick_items(body), list), body + ) if player_id: code, body, _ = s.get(f"{GATEWAY}/api/v1/players/{player_id}") @@ -866,7 +892,9 @@ def phase6_player(s: Session, game_id): code, body, _ = s.get(f"{GATEWAY}/api/v1/services") report("GET /services", code, body) - report_check("GET /services returns list shape", isinstance(pick_items(body), list), body) + report_check( + "GET /services returns list shape", isinstance(pick_items(body), list), body + ) service_id = svc_body.get("id", 0) if svc_body else 0 if service_id: @@ -1058,7 +1086,8 @@ def phase7_shop( report(f"GET /shops/{shop_id} (after announcement delete)", code, body) report_check( "deleted announcement is absent", - announcement not in [str(item) for item in body.get("announcements") or []], + announcement + not in [str(item) for item in body.get("announcements") or []], body, ) @@ -1155,7 +1184,9 @@ def phase7_shop( code, body, _ = s_owner.get( f"{GATEWAY}/api/v1/shops/{shop_id}/invitations", ) - report(f"GET /shops/{shop_id}/invitations (after wrong accept)", code, body) + report( + f"GET /shops/{shop_id}/invitations (after wrong accept)", code, body + ) pending_invitation = find_item_by_id(pick_items(body), invitation_id) report_check( "wrong invitation accept keeps status pending", @@ -1248,7 +1279,9 @@ def phase7_shop( code, body, _ = s_owner.get( f"{GATEWAY}/api/v1/shops/{shop_id}/invitations", ) - report(f"GET /shops/{shop_id}/invitations (after reject)", code, body) + report( + f"GET /shops/{shop_id}/invitations (after reject)", code, body + ) rejected = find_item_by_id(pick_items(body), reinvite_id) report_check( "rejected invitation has rejected status", @@ -1260,7 +1293,9 @@ def phase7_shop( code, body, _ = s_owner.get(f"{GATEWAY}/api/v1/shops/mine") report("GET /shops/mine", code, body) - report_check("GET /shops/mine returns owned shop", same_id(body.get("id"), shop_id), body) + report_check( + "GET /shops/mine returns owned shop", same_id(body.get("id"), shop_id), body + ) return shop_id @@ -1331,7 +1366,9 @@ def phase8_order(s_consumer: Session, s_actor: Session, player_id, service_id, s ) if order_id: - body = check_order_status(s_consumer, order_id, "pending_payment", "after create") + body = check_order_status( + s_consumer, order_id, "pending_payment", "after create" + ) report_check( "created order detail matches participants", same_id(body.get("consumerId"), consumer_user_id) @@ -1348,15 +1385,21 @@ def phase8_order(s_consumer: Session, s_actor: Session, player_id, service_id, s headers=s_actor.csrf_headers(), ) report_rejected(f"POST /orders/{order_id}/accept (before pay)", code, body) - check_order_status(s_consumer, order_id, "pending_payment", "after early accept") + check_order_status( + s_consumer, order_id, "pending_payment", "after early accept" + ) code, body, _ = s_consumer.post( f"{GATEWAY}/api/v1/orders/{order_id}/confirm-close", json_body={}, headers=csrf, ) - report_rejected(f"POST /orders/{order_id}/confirm-close (before close request)", code, body) - check_order_status(s_consumer, order_id, "pending_payment", "after early confirm-close") + report_rejected( + f"POST /orders/{order_id}/confirm-close (before close request)", code, body + ) + check_order_status( + s_consumer, order_id, "pending_payment", "after early confirm-close" + ) code, body, _ = s_consumer.post( f"{GATEWAY}/api/v1/orders/{order_id}/pay", @@ -1371,8 +1414,12 @@ def phase8_order(s_consumer: Session, s_actor: Session, player_id, service_id, s json_body={}, headers=s_actor.csrf_headers(), ) - report_rejected(f"POST /orders/{order_id}/request-close (before accept)", code, body) - check_order_status(s_consumer, order_id, "pending_accept", "after early request-close") + report_rejected( + f"POST /orders/{order_id}/request-close (before accept)", code, body + ) + check_order_status( + s_consumer, order_id, "pending_accept", "after early request-close" + ) code, body, _ = s_consumer.post( f"{GATEWAY}/api/v1/orders/{order_id}/pay", @@ -1380,7 +1427,9 @@ def phase8_order(s_consumer: Session, s_actor: Session, player_id, service_id, s headers=csrf, ) report_rejected(f"POST /orders/{order_id}/pay (second time)", code, body) - check_order_status(s_consumer, order_id, "pending_accept", "after duplicate pay") + check_order_status( + s_consumer, order_id, "pending_accept", "after duplicate pay" + ) code, body, _ = s_actor.post( f"{GATEWAY}/api/v1/orders/{order_id}/accept", @@ -1389,15 +1438,21 @@ def phase8_order(s_consumer: Session, s_actor: Session, player_id, service_id, s ) report(f"POST /orders/{order_id}/accept", code, body) body = check_order_status(s_consumer, order_id, "in_progress", "after accept") - report_check("accepted order has acceptedAt", bool(body.get("acceptedAt")), body) + report_check( + "accepted order has acceptedAt", bool(body.get("acceptedAt")), body + ) code, body, _ = s_consumer.post( f"{GATEWAY}/api/v1/orders/{order_id}/confirm-close", json_body={}, headers=csrf, ) - report_rejected(f"POST /orders/{order_id}/confirm-close (before request-close)", code, body) - check_order_status(s_consumer, order_id, "in_progress", "after early confirm-close") + report_rejected( + f"POST /orders/{order_id}/confirm-close (before request-close)", code, body + ) + check_order_status( + s_consumer, order_id, "in_progress", "after early confirm-close" + ) code, body, _ = s_actor.post( f"{GATEWAY}/api/v1/orders/{order_id}/request-close", @@ -1413,7 +1468,9 @@ def phase8_order(s_consumer: Session, s_actor: Session, player_id, service_id, s headers=csrf, ) report(f"POST /orders/{order_id}/confirm-close", code, body) - check_order_status(s_consumer, order_id, "pending_review", "after confirm-close") + check_order_status( + s_consumer, order_id, "pending_review", "after confirm-close" + ) code, body, _ = s_consumer.post( f"{GATEWAY}/api/v1/orders", @@ -1438,8 +1495,12 @@ def phase8_order(s_consumer: Session, s_actor: Session, player_id, service_id, s json_body={"rating": 5, "content": "too early"}, headers=csrf, ) - report_rejected(f"POST /orders/{order2_id}/review (before completion)", code, body) - check_order_status(s_consumer, order2_id, "pending_payment", "after early review") + report_rejected( + f"POST /orders/{order2_id}/review (before completion)", code, body + ) + check_order_status( + s_consumer, order2_id, "pending_payment", "after early review" + ) if order_id: code, body, _ = s_consumer.post( @@ -1465,7 +1526,9 @@ def phase8_order(s_consumer: Session, s_actor: Session, player_id, service_id, s headers=csrf, ) report(f"POST /orders/{order2_id}/pay (before cancel)", code, body) - check_order_status(s_consumer, order2_id, "pending_accept", "second order after pay") + check_order_status( + s_consumer, order2_id, "pending_accept", "second order after pay" + ) code, body, _ = s_consumer.post( f"{GATEWAY}/api/v1/orders/{order2_id}/cancel", @@ -1473,7 +1536,9 @@ def phase8_order(s_consumer: Session, s_actor: Session, player_id, service_id, s headers=csrf, ) report(f"POST /orders/{order2_id}/cancel", code, body) - check_order_status(s_consumer, order2_id, "cancelled", "second order after cancel") + check_order_status( + s_consumer, order2_id, "cancelled", "second order after cancel" + ) code, body, _ = s_consumer.post( f"{GATEWAY}/api/v1/orders/{order2_id}/pay", @@ -1547,8 +1612,14 @@ def phase8b_review( ) report(f"POST /orders/{order_id}/review (counterparty)", code, body) - order_body = check_order_status(s_consumer, order_id, "completed", "after two reviews") - report_check("completed order has completedAt", bool(order_body.get("completedAt")), order_body) + order_body = check_order_status( + s_consumer, order_id, "completed", "after two reviews" + ) + report_check( + "completed order has completedAt", + bool(order_body.get("completedAt")), + order_body, + ) code, body, _ = s_consumer.get(f"{GATEWAY}/api/v1/orders/{order_id}/reviews") report(f"GET /orders/{order_id}/reviews (after two reviews)", code, body) @@ -1558,8 +1629,12 @@ def phase8b_review( len(reviews) == 2 and all(same_id(item.get("orderId"), order_id) for item in reviews) and all(item.get("sealed") is False for item in reviews) - and bool(find_item(reviews, lambda item: item.get("content") == "great service")) - and bool(find_item(reviews, lambda item: item.get("content") == "smooth buyer")), + and bool( + find_item(reviews, lambda item: item.get("content") == "great service") + ) + and bool( + find_item(reviews, lambda item: item.get("content") == "smooth buyer") + ), body, ) @@ -1570,8 +1645,10 @@ def phase8b_review( bool( find_item( pick_items(body), - lambda item: same_id(item.get("orderId"), order_id) - and item.get("sealed") is False, + lambda item: ( + same_id(item.get("orderId"), order_id) + and item.get("sealed") is False + ), ) ), body, @@ -1587,16 +1664,20 @@ def phase8b_review( bool( find_item( pick_items(body), - lambda item: same_id(item.get("orderId"), order_id) - and same_id(item.get("fromUserId"), consumer_user_id) - and item.get("content") == "great service", + lambda item: ( + same_id(item.get("orderId"), order_id) + and same_id(item.get("fromUserId"), consumer_user_id) + and item.get("content") == "great service" + ), ) ), body, ) -def phase8c_dispute(s_consumer: Session, s_actor: Session, player_id, service_id, shop_id): +def phase8c_dispute( + s_consumer: Session, s_actor: Session, player_id, service_id, shop_id +): print("\n=== Phase 8c: Disputes ===") if not player_id or not service_id: skip("Dispute flow", "Missing player or service id") @@ -1643,7 +1724,9 @@ def phase8c_dispute(s_consumer: Session, s_actor: Session, player_id, service_id headers=csrf, ) report(f"POST /orders/{order_id}/pay (dispute flow)", code, body) - check_order_status(s_consumer, order_id, "pending_accept", "dispute order after pay") + check_order_status( + s_consumer, order_id, "pending_accept", "dispute order after pay" + ) code, body, _ = s_actor.post( f"{GATEWAY}/api/v1/orders/{order_id}/accept", @@ -1651,7 +1734,9 @@ def phase8c_dispute(s_consumer: Session, s_actor: Session, player_id, service_id headers=s_actor.csrf_headers(), ) report(f"POST /orders/{order_id}/accept (dispute flow)", code, body) - check_order_status(s_consumer, order_id, "in_progress", "dispute order after accept") + check_order_status( + s_consumer, order_id, "in_progress", "dispute order after accept" + ) code, body, _ = s_consumer.post( f"{GATEWAY}/api/v1/orders/{order_id}/dispute", @@ -1694,8 +1779,9 @@ def phase8c_dispute(s_consumer: Session, s_actor: Session, player_id, service_id bool( find_item( pick_items(body), - lambda item: same_id(item.get("id"), dispute_id) - and item.get("status") == "open", + lambda item: ( + same_id(item.get("id"), dispute_id) and item.get("status") == "open" + ), ) ), body, @@ -1746,7 +1832,9 @@ def phase8d_notifications(s: Session): report("GET /notifications", code, body) report_check( "GET /notifications returns list shape", - code == 200 and isinstance(pick_items(body), list) and isinstance(body.get("meta"), dict), + code == 200 + and isinstance(pick_items(body), list) + and isinstance(body.get("meta"), dict), body, ) @@ -1812,7 +1900,9 @@ def phase8e_search_and_favorites(s: Session, user_id, player_id, shop_id): report("GET /favorites", code, body) report_check( "GET /favorites returns list shape", - code == 200 and isinstance(pick_items(body), list) and isinstance(body.get("meta"), dict), + code == 200 + and isinstance(pick_items(body), list) + and isinstance(body.get("meta"), dict), body, ) @@ -1833,8 +1923,10 @@ def phase8e_search_and_favorites(s: Session, user_id, player_id, shop_id): not bool( find_item( pick_items(body), - lambda item: item.get("targetType") == "player" - and same_id(item.get("targetId"), "not-a-snowflake"), + lambda item: ( + item.get("targetType") == "player" + and same_id(item.get("targetId"), "not-a-snowflake") + ), ) ), body, @@ -1871,9 +1963,11 @@ def phase8e_search_and_favorites(s: Session, user_id, player_id, shop_id): bool( find_item( favorite_items, - lambda item: item.get("targetType") == "player" - and same_id(item.get("targetId"), player_id) - and same_id(item.get("userId"), user_id), + lambda item: ( + item.get("targetType") == "player" + and same_id(item.get("targetId"), player_id) + and same_id(item.get("userId"), user_id) + ), ) ), body, @@ -1884,18 +1978,19 @@ def phase8e_search_and_favorites(s: Session, user_id, player_id, shop_id): bool( find_item( favorite_items, - lambda item: item.get("targetType") == "shop" - and same_id(item.get("targetId"), shop_id) - and same_id(item.get("userId"), user_id), + lambda item: ( + item.get("targetType") == "shop" + and same_id(item.get("targetId"), shop_id) + and same_id(item.get("userId"), user_id) + ), ) ), body, ) favorite_id = 0 for item in favorite_items: - if ( - item.get("targetType") == "player" - and str(item.get("targetId")) == str(player_id) + if item.get("targetType") == "player" and str(item.get("targetId")) == str( + player_id ): favorite_id = as_int(item.get("id")) break @@ -1914,7 +2009,9 @@ def phase8e_search_and_favorites(s: Session, user_id, player_id, shop_id): ) report(f"GET /users/{user_id}/favorites/check (after delete)", code, body) if code == 200: - report_check("favorite check after delete", body.get("favorited") is False, body) + report_check( + "favorite check after delete", body.get("favorited") is False, body + ) code, body, _ = s.get(f"{GATEWAY}/api/v1/favorites") report("GET /favorites (after delete)", code, body) report_check( @@ -1922,8 +2019,10 @@ def phase8e_search_and_favorites(s: Session, user_id, player_id, shop_id): not bool( find_item( pick_items(body), - lambda item: item.get("targetType") == "player" - and same_id(item.get("targetId"), player_id), + lambda item: ( + item.get("targetType") == "player" + and same_id(item.get("targetId"), player_id) + ), ) ), body, @@ -2011,17 +2110,21 @@ def phase9_wallet(s: Session): bool( find_item( transactions, - lambda item: item.get("type") == "topup" - and as_decimal(item.get("amount")) == Decimal("100") - and item.get("description") == "topup via alipay", + lambda item: ( + item.get("type") == "topup" + and as_decimal(item.get("amount")) == Decimal("100") + and item.get("description") == "topup via alipay" + ), ) ) and bool( find_item( transactions, - lambda item: item.get("type") == "withdrawal" - and as_decimal(item.get("amount")) == Decimal("10") - and item.get("description") == "withdraw via alipay", + lambda item: ( + item.get("type") == "withdrawal" + and as_decimal(item.get("amount")) == Decimal("10") + and item.get("description") == "withdraw via alipay" + ), ) ), body, @@ -2060,7 +2163,11 @@ def phase10_community(s: Session, user_id): code, body, _ = s.get(f"{GATEWAY}/api/v1/posts") report("GET /posts", code, body) - report_check("created post appears in list", bool(find_item_by_id(pick_items(body), post_id)), body) + report_check( + "created post appears in list", + bool(find_item_by_id(pick_items(body), post_id)), + body, + ) if post_id: code, body, _ = s.get(f"{GATEWAY}/api/v1/posts/{post_id}") @@ -2181,7 +2288,11 @@ def phase10_community(s: Session, user_id): code, body, _ = s.get(f"{GATEWAY}/api/v1/users/{user_id}/posts") report(f"GET /users/{user_id}/posts", code, body) - report_check("user posts contain created post", bool(find_item_by_id(pick_items(body), post_id)), body) + report_check( + "user posts contain created post", + bool(find_item_by_id(pick_items(body), post_id)), + body, + ) return post_id @@ -2241,7 +2352,9 @@ def phase12_email(s: Session): report("POST /email/verification-code/send (gateway)", code, body) report_check( "email verification send returns request id", - code == 200 and bool(body.get("requestId")) and as_int(body.get("expireInSec")) > 0, + code == 200 + and bool(body.get("requestId")) + and as_int(body.get("expireInSec")) > 0, body, ) @@ -2253,7 +2366,9 @@ def phase12_email(s: Session): report("POST /auth/forgot-password/send (gateway)", code, body) report_check( "forgot password send returns request id", - code == 200 and bool(body.get("requestId")) and as_int(body.get("expireInSec")) > 0, + code == 200 + and bool(body.get("requestId")) + and as_int(body.get("expireInSec")) > 0, body, ) diff --git a/deploy/k8s/envoy/envoy.yaml b/deploy/k8s/envoy/envoy.yaml index b330acc..0a5abff 100644 --- a/deploy/k8s/envoy/envoy.yaml +++ b/deploy/k8s/envoy/envoy.yaml @@ -141,6 +141,98 @@ data: route: cluster: player_api_cluster timeout: 30s + - match: + prefix: /api/v1/services + headers: + - name: ":method" + exact_match: "GET" + route: + cluster: player_api_cluster + timeout: 30s + typed_per_filter_config: + envoy.filters.http.ext_authz: + "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute + disabled: true + - match: + path: /api/v1/shops + headers: + - name: ":method" + exact_match: "GET" + route: + cluster: shop_api_cluster + timeout: 30s + typed_per_filter_config: + envoy.filters.http.ext_authz: + "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute + disabled: true + - match: + safe_regex: + google_re2: {} + regex: "^/api/v1/shops/[^/]+$" + headers: + - name: ":method" + exact_match: "GET" + route: + cluster: shop_api_cluster + timeout: 30s + typed_per_filter_config: + envoy.filters.http.ext_authz: + "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute + disabled: true + - match: + safe_regex: + google_re2: {} + regex: "^/api/v1/shops/[^/]+/players$" + headers: + - name: ":method" + exact_match: "GET" + route: + cluster: shop_api_cluster + timeout: 30s + typed_per_filter_config: + envoy.filters.http.ext_authz: + "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute + disabled: true + - match: + safe_regex: + google_re2: {} + regex: "^/api/v1/users/[^/]+/posts$" + headers: + - name: ":method" + exact_match: "GET" + route: + cluster: community_api_cluster + timeout: 30s + typed_per_filter_config: + envoy.filters.http.ext_authz: + "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute + disabled: true + - match: + safe_regex: + google_re2: {} + regex: "^/api/v1/users/[^/]+/shop$" + headers: + - name: ":method" + exact_match: "GET" + route: + cluster: shop_api_cluster + timeout: 30s + typed_per_filter_config: + envoy.filters.http.ext_authz: + "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute + disabled: true + - match: + prefix: /api/v1/posts + headers: + - name: ":method" + exact_match: "GET" + route: + cluster: community_api_cluster + timeout: 30s + typed_per_filter_config: + envoy.filters.http.ext_authz: + "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute + disabled: true # - match: # prefix: /api/v1/shop # route: