feat(auth) normalise the way in which we check whether a user has free/paid access to nous portal so we can expose behaviour and error messages accordingly.
This commit is contained in:
@@ -9,6 +9,8 @@ from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from hermes_cli.nous_account import NousPortalAccountInfo
|
||||
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[2]
|
||||
TOOLS_DIR = REPO_ROOT / "tools"
|
||||
@@ -69,10 +71,17 @@ def _enable_managed_nous_tools(monkeypatch):
|
||||
The _install_fake_tools_package() helper resets and reimports tool modules,
|
||||
so a simple monkeypatch on tool_backend_helpers doesn't survive. We patch
|
||||
the *source* modules that the reimported modules will import from — both
|
||||
hermes_cli.auth and hermes_cli.models — so the function body returns True.
|
||||
hermes_cli.nous_account — so the function body returns True.
|
||||
"""
|
||||
monkeypatch.setattr("hermes_cli.auth.get_nous_auth_status", lambda: {"logged_in": True})
|
||||
monkeypatch.setattr("hermes_cli.models.check_nous_free_tier", lambda: False)
|
||||
monkeypatch.setattr(
|
||||
"hermes_cli.nous_account.get_nous_portal_account_info",
|
||||
lambda: NousPortalAccountInfo(
|
||||
logged_in=True,
|
||||
source="jwt",
|
||||
fresh=False,
|
||||
paid_service_access=True,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def _install_fake_tools_package():
|
||||
|
||||
@@ -5,6 +5,8 @@ from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from hermes_cli.nous_account import NousPortalAccountInfo
|
||||
|
||||
|
||||
TOOLS_DIR = Path(__file__).resolve().parents[2] / "tools"
|
||||
|
||||
@@ -48,8 +50,15 @@ def _restore_tool_and_agent_modules():
|
||||
def _enable_managed_nous_tools(monkeypatch):
|
||||
"""Patch the source modules so managed_nous_tools_enabled() returns True
|
||||
even after tool modules are dynamically reloaded."""
|
||||
monkeypatch.setattr("hermes_cli.auth.get_nous_auth_status", lambda: {"logged_in": True})
|
||||
monkeypatch.setattr("hermes_cli.models.check_nous_free_tier", lambda: False)
|
||||
monkeypatch.setattr(
|
||||
"hermes_cli.nous_account.get_nous_portal_account_info",
|
||||
lambda: NousPortalAccountInfo(
|
||||
logged_in=True,
|
||||
source="jwt",
|
||||
fresh=False,
|
||||
paid_service_access=True,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def _install_fake_tools_package():
|
||||
|
||||
@@ -16,10 +16,12 @@ from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from hermes_cli.nous_account import NousPaidServiceAccessInfo, NousPortalAccountInfo
|
||||
from tools.tool_backend_helpers import (
|
||||
coerce_modal_mode,
|
||||
has_direct_modal_credentials,
|
||||
managed_nous_tools_enabled,
|
||||
nous_tool_gateway_unavailable_message,
|
||||
normalize_browser_cloud_provider,
|
||||
normalize_modal_mode,
|
||||
prefers_gateway,
|
||||
@@ -40,42 +42,73 @@ class TestManagedNousToolsEnabled:
|
||||
|
||||
def test_disabled_when_not_logged_in(self, monkeypatch):
|
||||
monkeypatch.setattr(
|
||||
"hermes_cli.auth.get_nous_auth_status",
|
||||
lambda: {},
|
||||
"hermes_cli.nous_account.get_nous_portal_account_info",
|
||||
lambda: NousPortalAccountInfo(logged_in=False, source="none", fresh=False),
|
||||
)
|
||||
assert managed_nous_tools_enabled() is False
|
||||
|
||||
def test_disabled_for_free_tier(self, monkeypatch):
|
||||
monkeypatch.setattr(
|
||||
"hermes_cli.auth.get_nous_auth_status",
|
||||
lambda: {"logged_in": True},
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"hermes_cli.models.check_nous_free_tier",
|
||||
lambda: True,
|
||||
"hermes_cli.nous_account.get_nous_portal_account_info",
|
||||
lambda: NousPortalAccountInfo(
|
||||
logged_in=True,
|
||||
source="jwt",
|
||||
fresh=False,
|
||||
paid_service_access=False,
|
||||
),
|
||||
)
|
||||
assert managed_nous_tools_enabled() is False
|
||||
|
||||
def test_enabled_for_paid_subscriber(self, monkeypatch):
|
||||
monkeypatch.setattr(
|
||||
"hermes_cli.auth.get_nous_auth_status",
|
||||
lambda: {"logged_in": True},
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"hermes_cli.models.check_nous_free_tier",
|
||||
lambda: False,
|
||||
"hermes_cli.nous_account.get_nous_portal_account_info",
|
||||
lambda: NousPortalAccountInfo(
|
||||
logged_in=True,
|
||||
source="jwt",
|
||||
fresh=False,
|
||||
paid_service_access=True,
|
||||
),
|
||||
)
|
||||
assert managed_nous_tools_enabled() is True
|
||||
|
||||
def test_returns_false_on_exception(self, monkeypatch):
|
||||
"""Should never crash — returns False on any exception."""
|
||||
monkeypatch.setattr(
|
||||
"hermes_cli.auth.get_nous_auth_status",
|
||||
"hermes_cli.nous_account.get_nous_portal_account_info",
|
||||
_raise_import,
|
||||
)
|
||||
assert managed_nous_tools_enabled() is False
|
||||
|
||||
|
||||
class TestNousToolGatewayUnavailableMessage:
|
||||
def test_uses_entitlement_reason_for_logged_in_user(self, monkeypatch):
|
||||
monkeypatch.setattr(
|
||||
"hermes_cli.nous_account.get_nous_portal_account_info",
|
||||
lambda force_fresh=False: NousPortalAccountInfo(
|
||||
logged_in=True,
|
||||
source="account_api",
|
||||
fresh=True,
|
||||
paid_service_access=False,
|
||||
portal_base_url="https://portal.example.test",
|
||||
paid_service_access_info=NousPaidServiceAccessInfo(
|
||||
allowed=False,
|
||||
reason="no_usable_credits",
|
||||
has_active_subscription=True,
|
||||
active_subscription_is_paid=True,
|
||||
subscription_credits_remaining=0,
|
||||
purchased_credits_remaining=0,
|
||||
total_usable_credits=0,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
message = nous_tool_gateway_unavailable_message("managed image generation")
|
||||
|
||||
assert "credits are exhausted" in message
|
||||
assert "managed image generation" in message
|
||||
assert "https://portal.example.test/billing" in message
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# normalize_browser_cloud_provider
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user