unformatted: File would be reformatted --> gateway/platforms/telegram_nutrition_onboarding_copy.py:1:1 83 | if status.state.value == "collecting": 84 | return PROMPTS[status.next_field], None, "customer" 85 | if status.state.value == "customer_attestation": - return "입력 요약이 준비됐습니다. 본인이 입력한 내용임을 확인해 주세요.", "attest", "customer" 86 + return ( 87 + "입력 요약이 준비됐습니다. 본인이 입력한 내용임을 확인해 주세요.", 88 + "attest", 89 + "customer", 90 + ) 91 | if status.state.value == "owner_review": 92 | return "고객 영양 기초정보의 운영자 검토가 필요합니다.", "owner_ok", "owner" 93 | if status.state.value == "safety_hold": unformatted: File would be reformatted --> gateway/platforms/telegram_nutrition_onboarding_runtime.py:1:1 66 | self.profile_root = Path(profile_root).resolve() 67 | self.bootstrap = bootstrap_transport 68 | self.reconciler = reconciler or NutritionOnboardingReconciler() - self._publication_outbox = GatewayOnboardingPublicationOutbox( - self.profile_root - ) - self.domain = importlib.import_module( - "checkin_cli.nutrition_onboarding" - ) 69 + self._publication_outbox = GatewayOnboardingPublicationOutbox(self.profile_root) 70 + self.domain = importlib.import_module("checkin_cli.nutrition_onboarding") 71 | source_path = getattr(self.domain, "__file__", None) 72 | if not isinstance(source_path, str): 73 | raise NutritionOnboardingRuntimeError( -------------------------------------------------------------------------------- 111 | self.domain.record_current_registry_consent( 112 | self.profile_root, 113 | current.customer_key, - recorded_on=recorded_at.astimezone( - ZoneInfo("Asia/Seoul") - ).date(), 114 + recorded_on=recorded_at.astimezone(ZoneInfo("Asia/Seoul")).date(), 115 | ) 116 | except (OSError, TypeError, ValueError): - await query.answer( - text="현재 동의를 안전하게 저장하지 못했습니다." - ) 117 + await query.answer(text="현재 동의를 안전하게 저장하지 못했습니다.") 118 | return 119 | try: 120 | authority = self._current_authority(current) 121 | except (OSError, ValueError): - await query.answer( - text="온보딩 권한 또는 동의가 변경됐습니다." - ) 122 + await query.answer(text="온보딩 권한 또는 동의가 변경됐습니다.") 123 | return 124 | evidence = self._evidence( 125 | actor_id=getattr( -------------------------------------------------------------------------------- 258 | """Authenticate and receipt one owner commit whose UI recovered later.""" 259 | outbox = getattr(self, "_publication_outbox", None) 260 | ready_path = getattr(service, "ready_path", None) - baseline_path = ready_path.parent / "baseline-v1.json" if isinstance(ready_path, Path) else None 261 + baseline_path = ( 262 + ready_path.parent / "baseline-v1.json" 263 + if isinstance(ready_path, Path) 264 + else None 265 + ) 266 | callback = getattr( 267 | getattr(self, "adapter", None), 268 | "_reconcile_telegram_business_commit", -------------------------------------------------------------------------------- 348 | or event.action != "Approve" 349 | or event.actor_user_id != authority.owner_user_id 350 | or event.authority != authority_values - or event.route != tuple(str(item) for item in self._route(session, "owner")) 351 + or event.route 352 + != tuple(str(item) for item in self._route(session, "owner")) 353 | or event.callback_data != expected_callback_data 354 | ): 355 | return False -------------------------------------------------------------------------------- 434 | ) 435 | raw_answers = document.get("answers") 436 | if not isinstance(raw_answers, dict): - raise NutritionOnboardingRuntimeError( - "invalid onboarding answers" - ) 437 + raise NutritionOnboardingRuntimeError("invalid onboarding answers") 438 | answers: dict[str, object] = {} 439 | for key, value in raw_answers.items(): 440 | if not isinstance(key, str): - raise NutritionOnboardingRuntimeError( - "invalid onboarding answers" - ) 441 + raise NutritionOnboardingRuntimeError("invalid onboarding answers") 442 | answers[key] = value 443 | target_field = fields[target_cursor] 444 | if target_field == "schedule_constraints": unformatted: File would be reformatted --> tests/gateway/test_telegram_nutrition_onboarding.py:1:1 157 | customer_key="customer_001", 158 | owner_id="103", 159 | chat_id="-100200", - role_claim=lambda role: ( - customer if role.value == "customer" else trainer - ), 160 + role_claim=lambda role: customer if role.value == "customer" else trainer, 161 | topic_id=lambda _slot: None, 162 | ) 163 | -------------------------------------------------------------------------------- 209 | {"evidence_id": "checkin.current", "text": "현재 확정 체크인"} 210 | ], 211 | "decision_guardrails": { - "action_options": [ - {"id": "maintain_plan", "text": "현재 계획 유지"} - ] 212 + "action_options": [{"id": "maintain_plan", "text": "현재 계획 유지"}] 213 | }, 214 | }, 215 | } -------------------------------------------------------------------------------- 356 | ) 357 | 358 | adapter._request_physique_coaching_stage = MagicMock(side_effect=coach_response) 359 + 360 | async def polish_copy(*_args, artifact_sink=None, **_kwargs): 361 | assert artifact_sink is not None - artifact_sink( - { - "raw_polish_output": '{"slots":[]}', - "polish_valid": True, - } - ) 362 + artifact_sink({ 363 + "raw_polish_output": '{"slots":[]}', 364 + "polish_valid": True, 365 + }) 366 | return ( 367 | "현재 자료를 함께 살펴보면 하루 목표를 2000kcal로 조정하는 안을 " 368 | "운영자와 먼저 확인하겠습니다." -------------------------------------------------------------------------------- 466 | adapter._physique_chat_id = lambda *_args: "100" 467 | adapter._physique_thread_id = lambda *_args: "59" 468 | message = SimpleNamespace( - text=( - "목표 2100 170 205 65\n" - "하루 목표 2100kcal 조정안을 확인하겠습니다." - ) 469 + text=("목표 2100 170 205 65\n하루 목표 2100kcal 조정안을 확인하겠습니다.") 470 | ) 471 | 472 | handled = await adapter._handle_nutrition_draft_edit_text( -------------------------------------------------------------------------------- 527 | payload={"body_digest": "owner-card", "state": "owner_review"}, 528 | ) 529 | - assert publication_generation( - ready, - current=current, - payload={"body_digest": "ready-card", "state": "ready"}, - ) == 24 530 + assert ( 531 + publication_generation( 532 + ready, 533 + current=current, 534 + payload={"body_digest": "ready-card", "state": "ready"}, 535 + ) 536 + == 24 537 + ) 538 | 539 | 540 | def test_changed_recovered_card_body_advances_publication_generation() -> None: -------------------------------------------------------------------------------- 554 | "state": "customer_attestation", 555 | } 556 | - assert publication_generation( - attestation, - current=current, - payload=corrected, - ) == 25 - assert publication_generation( - attestation, - current=SimpleNamespace(generation=24, payload=corrected), - payload=corrected, - ) == 24 557 + assert ( 558 + publication_generation( 559 + attestation, 560 + current=current, 561 + payload=corrected, 562 + ) 563 + == 25 564 + ) 565 + assert ( 566 + publication_generation( 567 + attestation, 568 + current=SimpleNamespace(generation=24, payload=corrected), 569 + payload=corrected, 570 + ) 571 + == 24 572 + ) 573 | 574 | 575 | def test_ready_card_announces_activation_readiness_to_owner() -> None: -------------------------------------------------------------------------------- 591 | 592 | 593 | @pytest.mark.asyncio - async def test_consent_withdrawal_text_short_circuits_handle_text_without_bootstrap_lookup() -> None: 594 + async def test_consent_withdrawal_text_short_circuits_handle_text_without_bootstrap_lookup() -> ( 595 + None 596 + ): 597 | runtime = object.__new__(TelegramNutritionOnboardingRuntime) 598 | runtime.bootstrap = SimpleNamespace( 599 | store=SimpleNamespace( -------------------------------------------------------------------------------- 741 | state_dir = tmp_path / "data/onboarding/telegram-publication-outbox-v1" 742 | state_dir.mkdir(parents=True, mode=0o700) 743 | legacy = state_dir / "ledger.json" - legacy_document = json.dumps( - { - "schema": "telegram-nutrition-onboarding-publication-outbox-v1", - "records": [ - { - "session_id": "session-1", - "generation": 0, - "payload": {"state": "collecting"}, - "state": "RECEIPTED", - "message_id": 901, - } - ], - } - ) 744 + legacy_document = json.dumps({ 745 + "schema": "telegram-nutrition-onboarding-publication-outbox-v1", 746 + "records": [ 747 + { 748 + "session_id": "session-1", 749 + "generation": 0, 750 + "payload": {"state": "collecting"}, 751 + "state": "RECEIPTED", 752 + "message_id": 901, 753 + } 754 + ], 755 + }) 756 | legacy.write_text(legacy_document, encoding="utf-8") 757 | legacy.chmod(0o600) 758 | -------------------------------------------------------------------------------- 844 | monkeypatch: pytest.MonkeyPatch, 845 | ) -> None: 846 | outbox = GatewayOnboardingPublicationOutbox(tmp_path) - monkeypatch.setattr(outbox, "record_receipt", Mock(side_effect=OSError("primary down"))) 847 + monkeypatch.setattr( 848 + outbox, "record_receipt", Mock(side_effect=OSError("primary down")) 849 + ) 850 | runtime = object.__new__(TelegramNutritionOnboardingRuntime) 851 | runtime._publication_outbox = outbox 852 | runtime.adapter = SimpleNamespace( -------------------------------------------------------------------------------- 863 | await runtime._send_publication( 864 | session=SimpleNamespace(session_id="session-1", sid_hash="a" * 64), 865 | service=SimpleNamespace(store=store), - status=SimpleNamespace(state=SimpleNamespace(value="collecting"), answer_count=0), 866 + status=SimpleNamespace( 867 + state=SimpleNamespace(value="collecting"), answer_count=0 868 + ), 869 | text="current onboarding card", 870 | role="customer", 871 | payload={"body_digest": "b" * 64, "state": "collecting"}, -------------------------------------------------------------------------------- 886 | monkeypatch: pytest.MonkeyPatch, 887 | ) -> None: 888 | outbox = GatewayOnboardingPublicationOutbox(tmp_path) - monkeypatch.setattr(outbox, "record_receipt", Mock(side_effect=OSError("primary down"))) 889 + monkeypatch.setattr( 890 + outbox, "record_receipt", Mock(side_effect=OSError("primary down")) 891 + ) 892 | first = object.__new__(TelegramNutritionOnboardingRuntime) 893 | first._publication_outbox = outbox 894 | first.adapter = SimpleNamespace( -------------------------------------------------------------------------------- 907 | await first._send_publication( 908 | session=SimpleNamespace(session_id="session-1", sid_hash="a" * 64), 909 | service=SimpleNamespace(store=first_store), - status=SimpleNamespace(state=SimpleNamespace(value="collecting"), answer_count=0), 910 + status=SimpleNamespace( 911 + state=SimpleNamespace(value="collecting"), answer_count=0 912 + ), 913 | text="current onboarding card", 914 | role="customer", 915 | payload=payload, -------------------------------------------------------------------------------- 932 | mark_committed=Mock(), 933 | ) 934 | - assert await restarted._recover_publication_receipts(SimpleNamespace(store=restarted_store)) == 1 935 + assert ( 936 + await restarted._recover_publication_receipts( 937 + SimpleNamespace(store=restarted_store) 938 + ) 939 + == 1 940 + ) 941 | restarted_store.mark_committed.assert_called_once_with( 942 | session_id="session-1", generation=0, message_id=901 943 | ) - assert GatewayOnboardingPublicationOutbox(tmp_path).records()[0].state == "COMMITTED" 944 + assert ( 945 + GatewayOnboardingPublicationOutbox(tmp_path).records()[0].state == "COMMITTED" 946 + ) 947 | 948 | 949 | @pytest.mark.asyncio -------------------------------------------------------------------------------- 952 | monkeypatch: pytest.MonkeyPatch, 953 | ) -> None: 954 | outbox = GatewayOnboardingPublicationOutbox(tmp_path) - monkeypatch.setattr(outbox, "record_receipt", Mock(side_effect=OSError("primary down"))) 955 | monkeypatch.setattr( 956 + outbox, "record_receipt", Mock(side_effect=OSError("primary down")) 957 + ) 958 + monkeypatch.setattr( 959 | outbox, 960 | "record_emergency_receipt", 961 | Mock(side_effect=OSError("emergency down")), -------------------------------------------------------------------------------- 974 | mark_committed=Mock(), 975 | ) 976 | - with pytest.raises(PublicationReceiptPersistenceError, match="primary and emergency"): 977 + with pytest.raises( 978 + PublicationReceiptPersistenceError, match="primary and emergency" 979 + ): 980 | await runtime._send_publication( 981 | session=SimpleNamespace(session_id="session-1", sid_hash="a" * 64), 982 | service=SimpleNamespace(store=store), - status=SimpleNamespace(state=SimpleNamespace(value="collecting"), answer_count=0), 983 + status=SimpleNamespace( 984 + state=SimpleNamespace(value="collecting"), answer_count=0 985 + ), 986 | text="current onboarding card", 987 | role="customer", 988 | payload={"body_digest": "b" * 64, "state": "collecting"}, -------------------------------------------------------------------------------- 1029 | mark_committed=Mock(), 1030 | ) 1031 | - assert await runtime._recover_publication_receipts(SimpleNamespace(store=store)) == 0 1032 + assert ( 1033 + await runtime._recover_publication_receipts(SimpleNamespace(store=store)) == 0 1034 + ) 1035 | store.mark_committed.assert_not_called() 1036 | 1037 | -------------------------------------------------------------------------------- 1070 | mark_committed=Mock(), 1071 | ) 1072 | - assert await runtime._recover_publication_receipts( - SimpleNamespace(store=store), - session=SimpleNamespace(session_id="session-1"), - ) == 0 1073 + assert ( 1074 + await runtime._recover_publication_receipts( 1075 + SimpleNamespace(store=store), 1076 + session=SimpleNamespace(session_id="session-1"), 1077 + ) 1078 + == 0 1079 + ) 1080 | store.mark_committed.assert_not_called() 1081 | assert runtime._publication_outbox.records()[0].state == "RECEIPTED" 1082 | -------------------------------------------------------------------------------- 1102 | await runtime._send_publication( 1103 | session=SimpleNamespace(session_id="session-1", sid_hash="a" * 64), 1104 | service=SimpleNamespace(store=store), - status=SimpleNamespace(state=SimpleNamespace(value="collecting"), answer_count=0), 1105 + status=SimpleNamespace( 1106 + state=SimpleNamespace(value="collecting"), answer_count=0 1107 + ), 1108 | text="current onboarding card", 1109 | role="customer", 1110 | payload={"body_digest": "b" * 64, "state": "collecting"}, -------------------------------------------------------------------------------- 1174 | first = object.__new__(TelegramNutritionOnboardingRuntime) 1175 | first._publication_outbox = GatewayOnboardingPublicationOutbox(tmp_path) 1176 | first.adapter = SimpleNamespace( - _send_nutrition_topic=AsyncMock( - return_value=SimpleNamespace(message_id=901) - ) 1177 + _send_nutrition_topic=AsyncMock(return_value=SimpleNamespace(message_id=901)) 1178 | ) 1179 | first._route = Mock(return_value=("-100", "20")) 1180 | first_store = SimpleNamespace( -------------------------------------------------------------------------------- 1224 | generation=0, 1225 | message_id=901, 1226 | ) - assert GatewayOnboardingPublicationOutbox(tmp_path).records()[0].state == "COMMITTED" 1227 + assert ( 1228 + GatewayOnboardingPublicationOutbox(tmp_path).records()[0].state == "COMMITTED" 1229 + ) 1230 | restarted.adapter = SimpleNamespace( 1231 | _send_nutrition_topic=AsyncMock( 1232 | side_effect=AssertionError("committed card was sent twice") -------------------------------------------------------------------------------- 1270 | ) 1271 | runtime._publication_outbox = GatewayOnboardingPublicationOutbox(tmp_path) 1272 | service = SimpleNamespace( - status=Mock(return_value=SimpleNamespace(state=SimpleNamespace(value="collecting"))), 1273 + status=Mock( 1274 + return_value=SimpleNamespace(state=SimpleNamespace(value="collecting")) 1275 + ), 1276 | store=SimpleNamespace(mark_committed=Mock()), 1277 | ) 1278 | runtime._service = Mock(return_value=service) -------------------------------------------------------------------------------- 1292 | async def test_optional_question_force_reply_preserves_skip_affordance() -> None: 1293 | runtime = object.__new__(TelegramNutritionOnboardingRuntime) 1294 | runtime.adapter = SimpleNamespace( - _send_nutrition_topic=AsyncMock( - return_value=SimpleNamespace(message_id=901) - ) 1295 + _send_nutrition_topic=AsyncMock(return_value=SimpleNamespace(message_id=901)) 1296 | ) 1297 | runtime._route = Mock(return_value=("-100", "20")) 1298 | store = SimpleNamespace( -------------------------------------------------------------------------------- 1329 | async def test_required_question_never_offers_skip() -> None: 1330 | runtime = object.__new__(TelegramNutritionOnboardingRuntime) 1331 | runtime.adapter = SimpleNamespace( - _send_nutrition_topic=AsyncMock( - return_value=SimpleNamespace(message_id=902) - ) 1332 + _send_nutrition_topic=AsyncMock(return_value=SimpleNamespace(message_id=902)) 1333 | ) 1334 | runtime._route = Mock(return_value=("-100", "20")) 1335 | service = SimpleNamespace( -------------------------------------------------------------------------------- 1375 | ) 1376 | ) 1377 | runtime.adapter = SimpleNamespace( - _send_nutrition_topic=AsyncMock( - return_value=SimpleNamespace(message_id=903) - ) 1378 + _send_nutrition_topic=AsyncMock(return_value=SimpleNamespace(message_id=903)) 1379 | ) 1380 | runtime._current_authority = Mock( 1381 | return_value=SimpleNamespace(consent_granted=True) -------------------------------------------------------------------------------- 1416 | 1417 | await runtime._publish(session, service, status) 1418 | - keyboard = runtime.adapter._send_nutrition_topic.await_args.kwargs[ - "reply_markup" - ] 1419 + keyboard = runtime.adapter._send_nutrition_topic.await_args.kwargs["reply_markup"] 1420 | buttons = [button for row in keyboard.inline_keyboard for button in row] 1421 | assert [button.text for button in buttons] == [ 1422 | "입력 내용이 맞습니다", 1423 | "수정", 1424 | ] - assert [_load().decode_callback(button.callback_data).action for button in buttons] == [ 1425 + assert [ 1426 + _load().decode_callback(button.callback_data).action for button in buttons 1427 + ] == [ 1428 | "attest", 1429 | "revise", 1430 | ] -------------------------------------------------------------------------------- 1445 | reconcile=AsyncMock(return_value=reconciliation) 1446 | ) 1447 | runtime.adapter = SimpleNamespace( - _send_nutrition_topic=AsyncMock( - return_value=SimpleNamespace(message_id=904) - ) 1448 + _send_nutrition_topic=AsyncMock(return_value=SimpleNamespace(message_id=904)) 1449 | ) 1450 | runtime._current_authority = Mock( 1451 | return_value=SimpleNamespace(consent_granted=True) -------------------------------------------------------------------------------- 1597 | reconcile=AsyncMock(return_value=reconciliation) 1598 | ) 1599 | runtime.adapter = SimpleNamespace( - _send_nutrition_topic=AsyncMock( - return_value=SimpleNamespace(message_id=905) - ) 1600 + _send_nutrition_topic=AsyncMock(return_value=SimpleNamespace(message_id=905)) 1601 | ) 1602 | runtime._current_authority = Mock(return_value=authority) 1603 | runtime._route = Mock(return_value=("-100", "20")) -------------------------------------------------------------------------------- 1613 | assert reconciliation.summary_ko in sent["text"] 1614 | assert persisted is not None 1615 | assert persisted["answers_digest"] == current_digest - assert ( - persisted["advisory"]["summary_ko"] - == reconciliation.summary_ko - ) 1616 + assert persisted["advisory"]["summary_ko"] == reconciliation.summary_ko 1617 | 1618 | 1619 | @pytest.mark.asyncio 1620 | @pytest.mark.parametrize( 1621 | "state,labels,actions", - (( - "owner_review", - ["Approve", "Revise", "Reject", "Safety Hold"], - ["owner_ok", "op_rev", "op_rej", "op_hold"], - ),), 1622 + ( 1623 + ( 1624 + "owner_review", 1625 + ["Approve", "Revise", "Reject", "Safety Hold"], 1626 + ["owner_ok", "op_rev", "op_rej", "op_hold"], 1627 + ), 1628 + ), 1629 | ) 1630 | async def test_review_cards_offer_all_canonical_actions( 1631 | state: str, -------------------------------------------------------------------------------- 1634 | ) -> None: 1635 | runtime = object.__new__(TelegramNutritionOnboardingRuntime) 1636 | runtime.adapter = SimpleNamespace( - _send_nutrition_topic=AsyncMock( - return_value=SimpleNamespace(message_id=904) - ) 1637 + _send_nutrition_topic=AsyncMock(return_value=SimpleNamespace(message_id=904)) 1638 | ) 1639 | runtime._route = Mock(return_value=("-100", "20")) 1640 | service = SimpleNamespace( -------------------------------------------------------------------------------- 1654 | 1655 | await runtime._publish(session, service, status) 1656 | - keyboard = runtime.adapter._send_nutrition_topic.await_args.kwargs[ - "reply_markup" - ] 1657 + keyboard = runtime.adapter._send_nutrition_topic.await_args.kwargs["reply_markup"] 1658 | buttons = [button for row in keyboard.inline_keyboard for button in row] 1659 | assert [button.text for button in buttons] == labels 1660 | assert [ - _load().decode_callback(button.callback_data).action - for button in buttons 1661 + _load().decode_callback(button.callback_data).action for button in buttons 1662 | ] == actions - assert all( - len(button.callback_data.encode("utf-8")) <= 64 - for button in buttons - ) 1663 + assert all(len(button.callback_data.encode("utf-8")) <= 64 for button in buttons) 1664 | 1665 | 1666 | @dataclass -------------------------------------------------------------------------------- 1685 | *, 1686 | reply_markup: object | None = None, 1687 | ) -> object: - return await self.edit_message_reply_markup_mock( - reply_markup=reply_markup - ) 1688 + return await self.edit_message_reply_markup_mock(reply_markup=reply_markup) 1689 | 1690 | 1691 | @dataclass -------------------------------------------------------------------------------- 1727 | return_value=SimpleNamespace(generation=24, message_id=905) 1728 | ) 1729 | ), - status=Mock( - return_value=SimpleNamespace(state=SimpleNamespace(value=state)) - ), 1730 + status=Mock(return_value=SimpleNamespace(state=SimpleNamespace(value=state))), 1731 | review_as_trainer=Mock(return_value=result), 1732 | review_as_owner=Mock(return_value=result), 1733 | ) -------------------------------------------------------------------------------- 1838 | 1839 | 1840 | @pytest.mark.asyncio - async def test_historical_trainer_callback_is_rejected_before_route_or_service_mutation() -> None: 1841 + async def test_historical_trainer_callback_is_rejected_before_route_or_service_mutation() -> ( 1842 + None 1843 + ): 1844 | runtime, service, query, message = _review_callback_runtime( 1845 | state="trainer_review", 1846 | result_state="owner_review", 1847 | ) - data = _load().encode_callback_hash( - action="train_ok", - generation=23, - sid_hash="a" * 64, - ).replace("non2:", "non1:", 1) 1848 + data = ( 1849 + _load() 1850 + .encode_callback_hash( 1851 + action="train_ok", 1852 + generation=23, 1853 + sid_hash="a" * 64, 1854 + ) 1855 + .replace("non2:", "non1:", 1) 1856 + ) 1857 | 1858 | await runtime.handle_callback(query, data, message) 1859 | -------------------------------------------------------------------------------- 1946 | service = SimpleNamespace( 1947 | status=Mock(return_value=status), 1948 | store=SimpleNamespace( - load_session=Mock( - return_value=SimpleNamespace(message_id=901, payload={}) - ) 1949 + load_session=Mock(return_value=SimpleNamespace(message_id=901, payload={})) 1950 | ), 1951 | submit_answer=Mock(return_value=next_status), 1952 | ) -------------------------------------------------------------------------------- 2083 | next_field="schedule_constraints", 2084 | ) 2085 | ), - OnboardingState=SimpleNamespace( - COLLECTING=SimpleNamespace(value="collecting") - ), 2086 + OnboardingState=SimpleNamespace(COLLECTING=SimpleNamespace(value="collecting")), 2087 | ) 2088 | service = SimpleNamespace( 2089 | session_path=Path("/private/workflow.json"), -------------------------------------------------------------------------------- 2129 | load_mutable_session=Mock(return_value=document), 2130 | save_session=Mock(), 2131 | build_status=Mock(return_value="collecting"), - OnboardingState=SimpleNamespace( - COLLECTING=SimpleNamespace(value="collecting") - ), 2132 + OnboardingState=SimpleNamespace(COLLECTING=SimpleNamespace(value="collecting")), 2133 | ) 2134 | service = SimpleNamespace( 2135 | session_path=Path("/private/workflow.json"), -------------------------------------------------------------------------------- 2257 | update_id=132, 2258 | ), 2259 | ) - baseline = json.loads( - service.baseline_path.read_text(encoding="utf-8") - )["baseline"] 2260 + baseline = json.loads(service.baseline_path.read_text(encoding="utf-8"))["baseline"] 2261 | assert attested.state.value == "owner_review" 2262 | assert baseline["activity_category"] == "moderate" 2263 | assert baseline["activity_rationale"].startswith("주 3회, 회당 60분") 3 files would be reformatted, 1 file already formatted