Skip to content

Commit 078ddbc

Browse files
committed
refactor: pass in JWTs instead of convoluted temp dir, fix test
1 parent 9bb2074 commit 078ddbc

5 files changed

Lines changed: 59 additions & 25 deletions

File tree

‎crates/tower-cmd/src/mcp.rs‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use anyhow::Result;
22
use clap::Command;
33
use crate::{Config, api, deploy, run};
4+
use config::Session;
45
use rmcp::{
56
ErrorData as McpError, ServerHandler,
67
handler::server::{tool::{Parameters, ToolRouter}},
@@ -125,7 +126,11 @@ pub struct TowerService {
125126
impl TowerService {
126127
pub fn new(config: Config) -> Self {
127128
Self {
128-
config,
129+
config: std::env::var("TOWER_JWT")
130+
.ok()
131+
.and_then(|token| Session::from_jwt(&token).ok())
132+
.map(|session| config.clone().with_session(session))
133+
.unwrap_or(config),
129134
tool_router: Self::tool_router(),
130135
}
131136
}

‎tests/integration/features/environment.py‎

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import subprocess
33
import time
44
import tempfile
5-
import json
65
import socket
76
from pathlib import Path
87

@@ -23,12 +22,11 @@ def before_scenario(context, scenario):
2322

2423
# Set up environment
2524
test_env = os.environ.copy()
26-
test_env["TOWER_RUN_TIMEOUT"] = "1"
25+
test_env["TOWER_RUN_TIMEOUT"] = "3"
2726

28-
# Create mock config if tower_url is set
2927
if context.tower_url:
3028
test_env["TOWER_URL"] = context.tower_url
31-
_setup_mock_config(test_env, context.tower_url)
29+
test_env["TOWER_JWT"] = "mock_jwt_token"
3230

3331
# Find a free port for this test scenario
3432
mcp_port = _find_free_port()
@@ -38,7 +36,7 @@ def before_scenario(context, scenario):
3836
[tower_binary, "mcp-server", "--port", str(mcp_port)],
3937
env=test_env,
4038
stdout=subprocess.DEVNULL,
41-
stderr=subprocess.PIPE,
39+
stderr=subprocess.DEVNULL,
4240
text=True
4341
)
4442

@@ -81,23 +79,6 @@ def _find_free_port():
8179
port = s.getsockname()[1]
8280
return port
8381

84-
def _setup_mock_config(test_env, tower_url):
85-
"""Create a temporary tower configuration with mock session data"""
86-
temp_config_dir = tempfile.mkdtemp(prefix="tower_test_config_")
87-
test_env["HOME"] = temp_config_dir
88-
89-
config_dir = os.path.join(temp_config_dir, ".config", "tower")
90-
os.makedirs(config_dir, exist_ok=True)
91-
92-
mock_session = {
93-
"user": {"id": "mock_user_id", "email": "test@example.com"},
94-
"teams": [{"name": "default", "type": "user", "token": {"jwt": "mock_jwt_token"}}],
95-
"active_team": {"name": "default", "type": "user", "token": {"jwt": "mock_jwt_token"}},
96-
"tower_url": tower_url
97-
}
98-
99-
with open(os.path.join(config_dir, "session.json"), 'w') as f:
100-
json.dump(mock_session, f)
10182

10283
def _find_tower_binary():
10384
# Look for debug build first

‎tests/integration/features/steps/mcp_steps.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ def step_check_timeout_message(context):
199199
assert hasattr(context, 'mcp_response'), "No MCP response was recorded"
200200

201201
response_text = str(context.mcp_response).lower()
202-
timeout_keywords = ["timeout", "timed out", "1 seconds"]
202+
timeout_keywords = ["timeout", "timed out", "3 seconds"]
203203

204204
found_timeout = any(keyword in response_text for keyword in timeout_keywords)
205205
assert found_timeout, f"Response should indicate timeout, got: {context.mcp_response}"
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
import time
22
print("Starting guaranteed-slow script (will timeout)...")
3-
time.sleep(10)
3+
time.sleep(5)
44
print("This should never print")

‎tests/mock-api-server/main.py‎

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,54 @@ async def describe_secrets_key():
190190
-----END RSA PUBLIC KEY-----"""
191191
return {"public_key": mock_public_key}
192192

193+
def empty_paginated_response(key: str):
194+
"""Create empty paginated response for any resource type."""
195+
return {
196+
key: [],
197+
"pages": {"page": 1, "total": 0, "num_pages": 1, "page_size": 20}
198+
}
199+
200+
@app.post("/v1/secrets/export")
201+
async def export_secrets(export_params: Dict[str, Any]):
202+
"""Mock endpoint for exporting secrets with encryption."""
203+
return empty_paginated_response("secrets")
204+
205+
@app.post("/v1/catalogs/export")
206+
async def export_catalogs(export_params: Dict[str, Any]):
207+
"""Mock endpoint for exporting catalogs with encryption."""
208+
return empty_paginated_response("catalogs")
209+
210+
@app.get("/v1/session")
211+
async def get_session():
212+
"""Mock endpoint for getting current session."""
213+
return {
214+
"session": {
215+
"featurebase_identity": {
216+
"company_hash": "mock_company_hash",
217+
"user_hash": "mock_user_hash"
218+
},
219+
"user": {
220+
"company": "Mock Company",
221+
"country": "US",
222+
"created_at": "2023-01-01T00:00:00Z",
223+
"email": "test@example.com",
224+
"first_name": "Test",
225+
"is_alerts_enabled": True,
226+
"is_invitation_claimed": True,
227+
"last_name": "User",
228+
"profile_photo_url": "https://example.com/photo.jpg"
229+
},
230+
"teams": [
231+
{
232+
"name": "default",
233+
"type": "user",
234+
"token": {"jwt": "mock_jwt_token"}
235+
}
236+
],
237+
"token": {"jwt": "mock_jwt_token"}
238+
}
239+
}
240+
193241
@app.post("/v1/session/refresh")
194242
async def refresh_session(refresh_params: Dict[str, Any] = None):
195243
"""Mock endpoint for refreshing session."""

0 commit comments

Comments
 (0)