Skip to content

Commit 8ab75a4

Browse files
fix: use sys.modules mock for revenueholdings_license in conftest (was AttributeError on require_tier)
1 parent 8b2a0ac commit 8ab75a4

2 files changed

Lines changed: 23 additions & 41 deletions

File tree

src/deploydiff/cli.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from .terraform_parser import parse_terraform_plan
1616

1717
try:
18-
from revenueholdings_license.integration import rh_check
18+
from revenueholdings_license import require_license
1919
_HAS_RH_LICENSE = True
2020
except ImportError:
2121
_HAS_RH_LICENSE = False
@@ -32,7 +32,7 @@ def main(ctx, no_gate) -> None:
3232
ctx.ensure_object(dict)
3333
ctx.obj["no_gate"] = no_gate
3434
if _HAS_RH_LICENSE and not no_gate:
35-
rh_check("deploydiff")
35+
require_license("deploydiff")
3636

3737

3838
@main.command()
@@ -76,8 +76,8 @@ def preview(terraform_file, cloudformation_file, pulumi_file, verbose, exit_on_d
7676
def cost(terraform_file, cloudformation_file, pulumi_file, pricing_file, threshold) -> None:
7777
"""Estimate monthly cost impact of infrastructure changes. (Pro feature)"""
7878
if _HAS_RH_LICENSE:
79-
from revenueholdings_license.license import Tier, require_tier
80-
require_tier(Tier.PRO, "deploydiff cost")
79+
from revenueholdings_license import require_tier
80+
require_tier("pro", "deploydiff cost")
8181
plan = _load_plan(terraform_file, cloudformation_file, pulumi_file)
8282
if plan is None:
8383
console.print("[red]Error: Provide one of --tf, --cfn, or --pulumi[/red]")
@@ -102,8 +102,8 @@ def cost(terraform_file, cloudformation_file, pulumi_file, pricing_file, thresho
102102
def rollback(terraform_file, cloudformation_file, pulumi_file) -> None:
103103
"""Generate rollback commands for infrastructure changes. (Pro feature)"""
104104
if _HAS_RH_LICENSE:
105-
from revenueholdings_license.license import Tier, require_tier
106-
require_tier(Tier.PRO, "deploydiff rollback")
105+
from revenueholdings_license import require_tier
106+
require_tier("pro", "deploydiff rollback")
107107
plan = _load_plan(terraform_file, cloudformation_file, pulumi_file)
108108
if plan is None:
109109
console.print("[red]Error: Provide one of --tf, --cfn, or --pulumi[/red]")
@@ -182,6 +182,6 @@ def mcp() -> None:
182182
"""Start an MCP server exposing all CLI commands as AI-callable tools.
183183
184184
Uses stdio transport compatible with Claude Code, Cursor, Codex, and
185-
any MCP-compatible agent. Run this from your MCP client configuration.
185+
any MCP-compatible agent. Run this from your MCP client configuration.
186186
"""
187187
run_for_app(main)

tests/conftest.py

Lines changed: 16 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,24 @@
11
"""Test configuration - mock license checks so tests run without a license."""
22

33
import pytest
4+
import sys
45
from unittest.mock import MagicMock
56

7+
# Replace revenueholdings_license with a mock BEFORE any src imports resolve it
8+
_mock_rl = MagicMock()
9+
_mock_rl.require_license = MagicMock(return_value=None)
10+
_mock_rl.require_tier = MagicMock(return_value=None)
11+
sys.modules["revenueholdings_license"] = _mock_rl
12+
sys.modules.setdefault("revenueholdings_license.integration", _mock_rl)
13+
sys.modules.setdefault("revenueholdings_license.rate_limiter", MagicMock())
14+
615

716
@pytest.fixture(autouse=True)
817
def _mock_license(monkeypatch):
9-
"""Auto-mock revenueholdings_license so all CLI commands bypass tier checks."""
10-
mock_require_tier = MagicMock()
11-
12-
mock_rh_check = MagicMock()
13-
mock_ci_gate = MagicMock()
14-
15-
# Patch at the integration module level
16-
try:
17-
import revenueholdings_license.integration as integration_mod
18-
monkeypatch.setattr(integration_mod, "rh_check", mock_rh_check)
19-
monkeypatch.setattr(integration_mod, "ci_gate", mock_ci_gate)
20-
except ImportError:
21-
pass
22-
23-
# Patch at the license module level
24-
try:
25-
import revenueholdings_license.license as license_mod
26-
monkeypatch.setattr(license_mod, "require_tier", mock_require_tier)
27-
except ImportError:
28-
pass
29-
30-
# Patch at the top-level gate module
31-
try:
32-
import revenueholdings_license.gate as gate_mod
33-
mock_status = MagicMock()
34-
mock_status.tier = "PRO"
35-
mock_status.allowed = True
36-
mock_status.remaining = 999
37-
mock_status.daily_limit = 999
38-
mock_status.error = None
39-
mock_require_license = MagicMock(return_value=mock_status)
40-
monkeypatch.setattr(gate_mod, "require_license", mock_require_license)
41-
except (ImportError, AttributeError):
42-
pass
18+
"""Ensure license checks stay mocked even if a test reimports."""
19+
monkeypatch.setattr(
20+
"revenueholdings_license.require_license", MagicMock(return_value=None)
21+
)
22+
monkeypatch.setattr(
23+
"revenueholdings_license.require_tier", MagicMock(return_value=None)
24+
)

0 commit comments

Comments
 (0)