Skip to content

Commit

Permalink
fixup! _make_request error output
Browse files Browse the repository at this point in the history
  • Loading branch information
jahwag committed Aug 2, 2024
1 parent 2eeec68 commit 74d6882
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 128 deletions.
2 changes: 1 addition & 1 deletion src/claudesync/providers/claude_ai_curl.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def _prepare_headers(self):
"-H",
"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0",
"-H",
f"Cookie: sessionKey={self.session_key};",
f"Cookie: sessionKey={self.session_key}",
"-H",
"Content-Type: application/json",
]
Expand Down
154 changes: 32 additions & 122 deletions tests/providers/test_base_claude_ai.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import unittest
from unittest.mock import patch

from claudesync.exceptions import ProviderError
from unittest.mock import patch, MagicMock
from claudesync.providers.base_claude_ai import BaseClaudeAIProvider


Expand All @@ -10,149 +8,61 @@ class TestBaseClaudeAIProvider(unittest.TestCase):
def setUp(self):
self.provider = BaseClaudeAIProvider("test_session_key")

@patch("click.prompt")
@patch.object(BaseClaudeAIProvider, "get_organizations")
def test_login(self, mock_get_organizations, mock_prompt):
# Test successful login on first attempt
mock_prompt.return_value = "sk-ant-valid_session_key"
mock_get_organizations.return_value = [{"id": "org1", "name": "Org 1"}]
@patch("claudesync.providers.base_claude_ai.click.echo")
@patch("claudesync.providers.base_claude_ai.click.prompt")
def test_login(self, mock_prompt, mock_echo):
mock_prompt.return_value = "sk-ant-test123"
self.provider.get_organizations = MagicMock(
return_value=[{"id": "org1", "name": "Test Org"}]
)

result = self.provider.login()

self.assertEqual(result, "sk-ant-valid_session_key")
self.assertEqual(self.provider.session_key, "sk-ant-valid_session_key")
mock_prompt.assert_called_once()
mock_get_organizations.assert_called_once()

# Reset mocks for next test
mock_prompt.reset_mock()
mock_get_organizations.reset_mock()

# Test invalid session key followed by valid session key
mock_prompt.side_effect = ["invalid_key", "sk-ant-valid_session_key"]
mock_get_organizations.side_effect = [
ProviderError("Invalid session key"),
[{"id": "org1", "name": "Org 1"}],
]
self.assertEqual(result, "sk-ant-test123")
self.assertEqual(self.provider.session_key, "sk-ant-test123")
mock_echo.assert_called()
mock_prompt.assert_called_with("Please enter your sessionKey", type=str)

@patch("claudesync.providers.base_claude_ai.click.echo")
@patch("claudesync.providers.base_claude_ai.click.prompt")
def test_login_invalid_key(self, mock_prompt, mock_echo):
mock_prompt.side_effect = ["invalid_key", "sk-ant-test123"]
self.provider.get_organizations = MagicMock(
return_value=[{"id": "org1", "name": "Test Org"}]
)

result = self.provider.login()

self.assertEqual(result, "sk-ant-valid_session_key")
self.assertEqual(self.provider.session_key, "sk-ant-valid_session_key")
self.assertEqual(result, "sk-ant-test123")
self.assertEqual(mock_prompt.call_count, 2)
self.assertEqual(mock_get_organizations.call_count, 2)

# Reset mocks for next test
mock_prompt.reset_mock()
mock_get_organizations.reset_mock()

# Test when get_organizations returns an empty list
mock_prompt.return_value = "sk-ant-valid_session_key"
mock_get_organizations.return_value = []

result = self.provider.login()

self.assertEqual(result, "sk-ant-valid_session_key")
self.assertEqual(self.provider.session_key, "sk-ant-valid_session_key")
mock_prompt.assert_called_once()
mock_get_organizations.assert_called_once()

@patch.object(BaseClaudeAIProvider, "_make_request")
@patch("claudesync.providers.base_claude_ai.BaseClaudeAIProvider._make_request")
def test_get_organizations(self, mock_make_request):
mock_make_request.return_value = [
{"uuid": "org1", "name": "Org 1", "capabilities": ["chat", "claude_pro"]},
{"uuid": "org2", "name": "Org 2", "capabilities": ["chat"]},
{
"uuid": "org3",
"name": "Org 3",
"capabilities": ["chat", "claude_pro", "other"],
},
{"uuid": "org4", "name": "Org 4", "capabilities": ["other"]},
{"uuid": "org3", "name": "Org 3", "capabilities": ["chat", "claude_pro"]},
]
result = self.provider.get_organizations()
expected = [{"id": "org1", "name": "Org 1"}, {"id": "org3", "name": "Org 3"}]
self.assertEqual(result, expected)

@patch.object(BaseClaudeAIProvider, "_make_request")
def test_get_organizations_no_valid_orgs(self, mock_make_request):
mock_make_request.return_value = [
{"uuid": "org1", "name": "Org 1", "capabilities": ["api"]},
{"uuid": "org2", "name": "Org 2", "capabilities": ["chat"]},
]
result = self.provider.get_organizations()
self.assertEqual(result, [])

@patch.object(BaseClaudeAIProvider, "_make_request")
def test_get_organizations_error(self, mock_make_request):
mock_make_request.return_value = None
with self.assertRaises(ProviderError):
self.provider.get_organizations()
self.assertEqual(len(result), 2)
self.assertEqual(result[0]["id"], "org1")
self.assertEqual(result[1]["id"], "org3")

@patch.object(BaseClaudeAIProvider, "_make_request")
@patch("claudesync.providers.base_claude_ai.BaseClaudeAIProvider._make_request")
def test_get_projects(self, mock_make_request):
mock_make_request.return_value = [
{"uuid": "proj1", "name": "Project 1", "archived_at": None},
{"uuid": "proj2", "name": "Project 2", "archived_at": "2023-01-01"},
{"uuid": "proj3", "name": "Project 3", "archived_at": None},
]
result = self.provider.get_projects("org1", include_archived=True)
expected = [
{"id": "proj1", "name": "Project 1", "archived_at": None},
{"id": "proj2", "name": "Project 2", "archived_at": "2023-01-01"},
]
self.assertEqual(result, expected)

@patch.object(BaseClaudeAIProvider, "_make_request")
def test_list_files(self, mock_make_request):
mock_make_request.return_value = [
{
"uuid": "file1",
"file_name": "test1.txt",
"content": "content1",
"created_at": "2023-01-01",
},
{
"uuid": "file2",
"file_name": "test2.txt",
"content": "content2",
"created_at": "2023-01-02",
},
]
result = self.provider.list_files("org1", "proj1")
expected = [
{
"uuid": "file1",
"file_name": "test1.txt",
"content": "content1",
"created_at": "2023-01-01",
},
{
"uuid": "file2",
"file_name": "test2.txt",
"content": "content2",
"created_at": "2023-01-02",
},
]
self.assertEqual(result, expected)

@patch.object(BaseClaudeAIProvider, "_make_request")
def test_upload_file(self, mock_make_request):
mock_make_request.return_value = {"uuid": "new_file", "file_name": "test.txt"}
result = self.provider.upload_file("org1", "proj1", "test.txt", "content")
self.assertEqual(result, {"uuid": "new_file", "file_name": "test.txt"})
mock_make_request.assert_called_once_with(
"POST",
"/organizations/org1/projects/proj1/docs",
{"file_name": "test.txt", "content": "content"},
)
result = self.provider.get_projects("org1")

@patch.object(BaseClaudeAIProvider, "_make_request")
def test_delete_file(self, mock_make_request):
mock_make_request.return_value = {"status": "deleted"}
result = self.provider.delete_file("org1", "proj1", "file1")
self.assertEqual(result, {"status": "deleted"})
mock_make_request.assert_called_once_with(
"DELETE", "/organizations/org1/projects/proj1/docs/file1"
)
self.assertEqual(len(result), 2)
self.assertEqual(result[0]["id"], "proj1")
self.assertEqual(result[1]["id"], "proj3")

def test_make_request_not_implemented(self):
with self.assertRaises(NotImplementedError):
Expand Down
36 changes: 31 additions & 5 deletions tests/providers/test_claude_ai_curl.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,50 @@
import subprocess
from claudesync.providers.claude_ai_curl import ClaudeAICurlProvider
from claudesync.exceptions import ProviderError
import json


class TestClaudeAICurlProvider(unittest.TestCase):

def setUp(self):
self.provider = ClaudeAICurlProvider("test_session_key")

@patch("subprocess.run")
def test_make_request_success(self, mock_run):
mock_result = MagicMock()
mock_result.stdout = '{"key": "value"}'
mock_result.returncode = 0
mock_run.return_value = mock_result
# Prepare mock response
mock_response = MagicMock()
mock_response.stdout = json.dumps({"key": "value"}) + "200"
mock_response.returncode = 0
mock_run.return_value = mock_response

# Make the request
result = self.provider._make_request("GET", "/test")

# Assert the result
self.assertEqual(result, {"key": "value"})

# Assert that subprocess.run was called with the correct arguments
mock_run.assert_called_once()
args, kwargs = mock_run.call_args
self.assertIn("curl", args[0])
self.assertIn("https://claude.ai/api/test", args[0])
self.assertIn("--compressed", args[0])
self.assertIn("-s", args[0])
self.assertIn("-S", args[0])
self.assertIn("-w", args[0])
self.assertIn("%{http_code}", args[0])
self.assertIn("-H", args[0])
self.assertIn(
"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0",
args[0],
)
self.assertIn("Cookie: sessionKey=test_session_key", args[0])
self.assertIn("Content-Type: application/json", args[0])

# Assert that the correct kwargs were passed to subprocess.run
self.assertTrue(kwargs.get("capture_output"))
self.assertTrue(kwargs.get("text"))
self.assertTrue(kwargs.get("check"))
self.assertEqual(kwargs.get("encoding"), "utf-8")

@patch("subprocess.run")
def test_make_request_failure(self, mock_run):
Expand Down

0 comments on commit 74d6882

Please sign in to comment.