"""Fixture payloads for ``POST /qqweb/WhatsAppUser/businessFriendList`` (M3). These records mirror the real field names captured from the live CRM (see phase0-findings.md §5; live total = **11292**): ``uid`` (owning staff ``@s.whatsapp.net``), ``userId`` / ``userName`` / ``salePhone`` / ``salesNickName`` / ``salesBindPhone`` (owning staff), ``friendUid`` (customer -> ``friend_id`` PK), ``nickName`` (customer nickname), ``phone``, ``createTime`` / ``lastUpdate``, ``groupNum`` / ``contactsNum`` / ``talkerCount`` / ``friendAddNum`` / ``messageCount`` / ``sensitiveWordNum``. The envelope is the SAME shape as ``businessSalesList``: rows under ``data.overviews``, declared count under ``data.totalCount``, page count under ``data.pageCount``:: {"message":"调用成功","code":"10000","success":true,"traceId":"...", "data":{"page":.., "pageCount":.., "totalCount":.., "overviews":[...]}} The fixture's ``TOTAL`` is pinned to the record count (not the live 11292) so the paginator's over-fetch ceiling does not fire early in the multi-page test. """ from __future__ import annotations import math from typing import Any # --------------------------------------------------------------------------- # Capture-shaped WhatsApp contact records (3 total across 2 pages). # --------------------------------------------------------------------------- WA_FRIEND_RECORDS: list[dict[str, Any]] = [ { "uid": "8613800000001@s.whatsapp.net", # owning staff account "userId": "wa_staff_001", "userName": "Alice Wang", "salePhone": "8613800000001", "salesNickName": "Alice Sale", "salesBindPhone": "8613900000001", "friendUid": "8613800000111@s.whatsapp.net", # customer -> friend_id "nickName": "Customer One", "phone": "8613800000111", "createTime": 1699000000000, "lastUpdate": 1700000000123, "groupNum": 2, "contactsNum": 421, "talkerCount": 38, "friendAddNum": 1, "messageCount": 57, "sensitiveWordNum": 0, "version": "v1.20260731.cust1", }, { "uid": "8613800000001@s.whatsapp.net", "userId": "wa_staff_001", "userName": "Alice Wang", "salePhone": "8613800000001", "salesNickName": "Alice Sale", "salesBindPhone": "8613900000001", "friendUid": "8613800000222@s.whatsapp.net", "nickName": "Customer Two", "phone": "8613800000222", "createTime": 1699100000000, "lastUpdate": 1700000000456, "groupNum": 1, "contactsNum": 421, "talkerCount": 38, "friendAddNum": 1, "messageCount": 9, "sensitiveWordNum": 0, "version": "v1.20260731.cust2", }, { # Contact owned by a different staff account. "uid": "8613800000002@s.whatsapp.net", "userId": "wa_staff_002", "userName": "Bob Chen", "salePhone": "8613800000002", "salesNickName": "Bob Sale", "salesBindPhone": "8613900000002", "friendUid": "8613800000333@s.whatsapp.net", "nickName": "Customer Three", "phone": "8613800000333", "createTime": 1699200000000, "lastUpdate": 1700000000789, "groupNum": 0, "contactsNum": 58, "talkerCount": 9, "friendAddNum": 0, "messageCount": 4, "sensitiveWordNum": 1, "version": "v1.20260731.cust3", }, ] TOTAL = len(WA_FRIEND_RECORDS) DEFAULT_PAGE_SIZE = 2 def make_wa_friends_response( records: list[dict[str, Any]], *, total_count: int, page: int = 1, page_size: int = DEFAULT_PAGE_SIZE, page_count: int | None = None, trace_id: str | None = None, ) -> dict[str, Any]: """Build a capture-shaped ``businessFriendList`` response envelope. Shape (same as ``businessSalesList``):: {"message":"调用成功","code":"10000","success":true,"traceId":"...", "data":{"page":.., "pageCount":.., "totalCount":.., "overviews":[...]}} """ if page_count is None: page_count = math.ceil(total_count / page_size) if page_size else 1 return { "message": "调用成功", "code": "10000", "success": True, "traceId": trace_id or f"trace-wa-friend-{page}", "data": { "page": page, "pageCount": page_count, "totalCount": total_count, "overviews": list(records), }, }