"""Fixture payloads for ``POST /pc/customer/smsLogsList`` (M4 SMS scraper). These records mirror the real field names confirmed by Phase-0 + the data dictionary §4 (短信记录 sms): ``id, customerPhone, sms(全文)/smsSub(预览), sender, direction(0收/1发), userId, senderDepartment/senderDepartmentId, receiveName, createTime(YYYY-MM-DD HH:MM), simPhone/simNumber, source``. Live ``dataCount`` is 53. The envelope differs from the callLog + wechat shapes: the row list sits under ``data.data`` (same) but the declared row count is ``data.dataCount`` (NOT ``totalCount`` and NOT ``total``), and there is **no** ``pageCount``:: {"message":"调用成功","code":"10000","success":true,"traceId":"...", "data":{"data":[...], "dataCount":.., "power":...}} Because there is no ``pageCount``, the scraper relies solely on the empty-page stop signal (advance ``pageNum`` until a page comes back with an empty ``data.data`` array). The cassette ships three records across two pages so a test can drive the page-number paginator across the empty-page stop signal: * page 1 -> 2 of the 3 fixture records, ``dataCount=3`` * page 2 -> the remaining 1 record, ``dataCount=3`` * (page 3 -> empty ``data`` array, served inline by the test) Records deliberately exercise the documented mapping edges: * ``sms_3001`` — incoming SMS (``direction=0`` 收) with full + preview text. * ``sms_3002`` — outgoing SMS (``direction=1`` 发) to a different customer. * ``sms_3003`` — incoming SMS with an empty preview (exercises the ``content_preview`` None path; ``sms`` still carries the full text). ``createTime`` is a ``YYYY-MM-DD HH:MM`` datetime string (NO seconds — one format precision shorter than the callLog's ``startCallTime``); the scraper parses it to a ms-epoch int treating the missing seconds as ``:00``. """ # The module name mirrors the upstream endpoint name (``smsLogsList`` -> # ``smsLogs``); the M4 spec uses this naming family. # ruff: noqa: N999 from __future__ import annotations from typing import Any # --------------------------------------------------------------------------- # Capture-shaped SMS records (3 total across 2 pages: page1=2, page2=1). # --------------------------------------------------------------------------- SMS_RECORDS: list[dict[str, Any]] = [ { # Incoming SMS (0=收) with full + preview text. "id": "sms_3001", "customerPhone": "8613800000001", "sms": "您好,我在网上看到您的产品介绍,想了解一下价格和详情,方便回电吗?", "smsSub": "您好,我在网上看到您的产品介绍...", "sender": "8613800000001", "direction": 0, # 0=收 (incoming) "userId": "staff_user_001", "senderDepartment": "销售一部", "senderDepartmentId": "dept_sales_east", "receiveName": "Alice Wang", "createTime": "2026-01-15 10:30", # YYYY-MM-DD HH:MM (no seconds) "simPhone": "8613800000111", "simNumber": "8986000112345678901", "source": "card", }, { # Outgoing SMS (1=发) to a different customer. "id": "sms_3002", "customerPhone": "8613800000002", "sms": "王先生您好,这是您咨询的订单详情,请查收附件。", "smsSub": "王先生您好,这是您咨询的订单详情...", "sender": "system", "direction": 1, # 1=发 (outgoing) "userId": "staff_user_002", "senderDepartment": "销售二部", "senderDepartmentId": "dept_sales_west", "receiveName": "Bob Chen", "createTime": "2026-01-15 11:00", "simPhone": "8613800000222", "simNumber": "8986000223456789012", "source": "manual", }, { # Incoming SMS with an EMPTY preview (content_preview None path). "id": "sms_3003", "customerPhone": "8613800000003", "sms": "好的,收到。", "smsSub": "", # empty preview -> content_preview None "sender": "8613800000003", "direction": 0, # incoming "userId": "staff_user_001", "senderDepartment": "销售一部", "senderDepartmentId": "dept_sales_east", "receiveName": "Alice Wang", "createTime": "2026-01-16 09:00", "simPhone": "8613800000111", "simNumber": "8986000112345678901", "source": "reply", }, ] # Default page size for the fixture (and the scraper). dataCount=3 with # page_size=2 fills page 1 (2 records) + page 2 (1 record) + a terminating # empty page. DATA_COUNT = len(SMS_RECORDS) DEFAULT_PAGE_SIZE = 2 def make_sms_logs_response( records: list[dict[str, Any]], *, data_count: int, trace_id: str | None = None, ) -> dict[str, Any]: """Build a capture-shaped ``smsLogsList`` response envelope. Shape (row list under ``data.data``; row count on ``data.dataCount``; no ``pageCount`` / ``pageNum``):: {"message":"调用成功","code":"10000","success":true,"traceId":"...", "data":{"data":[...], "dataCount":.., "power":true}} """ return { "message": "调用成功", "code": "10000", "success": True, "traceId": trace_id or "trace-1", "data": { "data": list(records), "dataCount": data_count, "power": True, }, }