diff --git a/menubar.py b/menubar.py index 837a086..3690ce8 100644 --- a/menubar.py +++ b/menubar.py @@ -816,9 +816,13 @@ def _refresh_in_background(self) -> None: except Exception as exc: if os.environ.get("USAGE_DEBUG") == "1": logger.warning("refresh failed", exc_info=True) + codex_rows = codex_result["codex_rows"] codex_5h_pct = codex_result["codex_5h_pct"] codex_model = codex_result.get("codex_model", "unknown") state = _error_state(type(exc).__name__, self.mock, self.language) + state.codex_session = codex_rows[0] + state.codex_weekly = codex_rows[1] + state.codex_stale = codex_result.get("codex_stale") result = {"state": state, "codex_5h_pct": codex_5h_pct, "codex_model": codex_model} self.performSelectorOnMainThread_withObject_waitUntilDone_( diff --git a/tests/test_menubar.py b/tests/test_menubar.py index 9c70ea4..7f41028 100644 --- a/tests/test_menubar.py +++ b/tests/test_menubar.py @@ -1218,6 +1218,57 @@ def button(self) -> FakeButton: assert button.titles[-1].endswith("18.5%") +def test_refresh_error_preserves_codex_quota() -> None: + captured: dict[str, object] = {} + session = menubar_state.QuotaRowState( + title="Session", + percent=1.0, + percent_text="1% used", + reset_text="Resets in 4h", + color=menubar.CODEX_COLOR, + ) + weekly = menubar_state.QuotaRowState( + title="Weekly", + percent=37.0, + percent_text="37% used", + reset_text="Resets in 5d", + color=menubar.CODEX_COLOR, + ) + + class Delegate: + mock = False + language = "en" + + def _load_codex_refresh_result(self) -> dict[str, object]: + return { + "codex_rows": (session, weekly), + "codex_5h_pct": 1.0, + "codex_model": "gpt-test", + "codex_stale": None, + } + + def performSelectorOnMainThread_withObject_waitUntilDone_( + self, selector: str, result: dict[str, object], wait: bool + ) -> None: + captured["selector"] = selector + captured["result"] = result + captured["wait"] = wait + + async def _fetch(self) -> PollOutcome: + raise RuntimeError("fetch failed") + + menubar.AppDelegate._refresh_in_background(cast(Any, Delegate())) + + result = captured["result"] + assert isinstance(result, dict) + state = result["state"] + assert isinstance(state, menubar_state.PopoverState) + assert state.codex_session == session + assert state.codex_weekly == weekly + assert result["codex_5h_pct"] == 1.0 + assert result["codex_model"] == "gpt-test" + + def test_refresh_now_queues_when_refresh_is_busy() -> None: delegate = menubar.AppDelegate.alloc().initWithMock_interval_(True, 60) delegate._refresh_in_flight = True