Skip to content

Commit 98bfef7

Browse files
committed
Raise error for upload_file_to_signed_url function
1 parent 8e282c0 commit 98bfef7

File tree

3 files changed

+184
-18
lines changed

3 files changed

+184
-18
lines changed

comfy_cli/file_utils.py

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -124,24 +124,14 @@ def zip_files(zip_filename):
124124

125125

126126
def upload_file_to_signed_url(signed_url: str, file_path: str):
127-
try:
128-
with open(file_path, "rb") as f:
129-
headers = {"Content-Type": "application/zip"}
130-
response = requests.put(signed_url, data=f, headers=headers)
131-
132-
# Simple success check
133-
if response.status_code == 200:
134-
print("Upload successful.")
135-
else:
136-
# Print a generic error message with status code and response text
137-
print(f"Upload failed with status code: {response.status_code}. Error: {response.text}")
138-
139-
except requests.exceptions.RequestException as e:
140-
# Print error related to the HTTP request
141-
print(f"An error occurred during the upload: {str(e)}")
142-
except FileNotFoundError:
143-
# Print file not found error
144-
print(f"Error: The file {file_path} does not exist.")
127+
with open(file_path, "rb") as f:
128+
headers = {"Content-Type": "application/zip"}
129+
response = requests.put(signed_url, data=f, headers=headers)
130+
131+
if response.status_code == 200:
132+
print("Upload successful.")
133+
else:
134+
raise Exception(f"Upload failed with status code: {response.status_code}. Error: {response.text}")
145135

146136

147137
def extract_package_as_zip(file_path: pathlib.Path, extract_path: pathlib.Path):

tests/comfy_cli/command/nodes/test_publish.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,33 @@ def test_publish_with_token_option():
8787
assert mock_publish.called
8888
assert mock_zip.called
8989
assert mock_upload.called
90+
91+
92+
def test_publish_exits_on_upload_failure():
93+
# Mock subprocess.run to simulate no violations
94+
mock_result = MagicMock()
95+
mock_result.returncode = 0
96+
mock_result.stdout = ""
97+
98+
with (
99+
patch("subprocess.run", return_value=mock_result),
100+
patch("comfy_cli.command.custom_nodes.command.extract_node_configuration") as mock_extract,
101+
patch("typer.prompt", return_value="test-token"),
102+
patch("comfy_cli.command.custom_nodes.command.registry_api.publish_node_version") as mock_publish,
103+
patch("comfy_cli.command.custom_nodes.command.zip_files") as mock_zip,
104+
patch("comfy_cli.command.custom_nodes.command.upload_file_to_signed_url") as mock_upload,
105+
):
106+
# Setup the mocks
107+
mock_extract.return_value = {"name": "test-node"}
108+
mock_publish.return_value = MagicMock(signedUrl="https://test.url")
109+
mock_upload.side_effect = Exception("Upload failed with status code: 403")
110+
111+
# Run the publish command
112+
result = runner.invoke(app, ["publish"])
113+
114+
# Verify the command exited with error
115+
assert result.exit_code == 1
116+
assert mock_extract.called
117+
assert mock_publish.called
118+
assert mock_zip.called
119+
assert mock_upload.called

tests/test_file_utils.py

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
import json
2+
import pathlib
3+
from unittest.mock import Mock, patch
4+
5+
import pytest
6+
import requests
7+
8+
from comfy_cli.file_utils import (
9+
DownloadException,
10+
check_unauthorized,
11+
download_file,
12+
extract_package_as_zip,
13+
guess_status_code_reason,
14+
upload_file_to_signed_url,
15+
)
16+
17+
18+
def test_guess_status_code_reason_401_with_json():
19+
message = json.dumps({"message": "API token required"}).encode()
20+
result = guess_status_code_reason(401, message)
21+
assert "API token required" in result
22+
assert "Unauthorized download (401)" in result
23+
24+
25+
def test_guess_status_code_reason_401_without_json():
26+
result = guess_status_code_reason(401, "not json")
27+
assert "Unauthorized download (401)" in result
28+
assert "manually log into browser" in result
29+
30+
31+
def test_guess_status_code_reason_403():
32+
result = guess_status_code_reason(403, "")
33+
assert "Forbidden url (403)" in result
34+
35+
36+
def test_guess_status_code_reason_404():
37+
result = guess_status_code_reason(404, "")
38+
assert "another castle (404)" in result
39+
40+
41+
def test_guess_status_code_reason_unknown():
42+
result = guess_status_code_reason(500, "")
43+
assert "Unknown error occurred (status code: 500)" in result
44+
45+
46+
@patch("requests.get")
47+
def test_check_unauthorized_true(mock_get):
48+
mock_response = Mock()
49+
mock_response.status_code = 401
50+
mock_get.return_value = mock_response
51+
52+
assert check_unauthorized("http://example.com") is True
53+
54+
55+
@patch("requests.get")
56+
def test_check_unauthorized_false(mock_get):
57+
mock_response = Mock()
58+
mock_response.status_code = 200
59+
mock_get.return_value = mock_response
60+
61+
assert check_unauthorized("http://example.com") is False
62+
63+
64+
@patch("requests.get")
65+
def test_check_unauthorized_exception(mock_get):
66+
mock_get.side_effect = requests.RequestException()
67+
68+
assert check_unauthorized("http://example.com") is False
69+
70+
71+
@patch("httpx.stream")
72+
def test_download_file_success(mock_stream, tmp_path):
73+
mock_response = Mock()
74+
mock_response.status_code = 200
75+
mock_response.headers = {"Content-Length": "1024"}
76+
mock_response.iter_bytes.return_value = [b"test data"]
77+
mock_response.__enter__ = Mock(return_value=mock_response)
78+
mock_response.__exit__ = Mock(return_value=None)
79+
mock_stream.return_value = mock_response
80+
81+
test_file = tmp_path / "test.txt"
82+
download_file("http://example.com", test_file)
83+
84+
assert test_file.exists()
85+
assert test_file.read_bytes() == b"test data"
86+
87+
88+
@patch("httpx.stream")
89+
def test_download_file_failure(mock_stream):
90+
mock_response = Mock()
91+
mock_response.status_code = 404
92+
mock_response.read.return_value = ""
93+
mock_response.__enter__ = Mock(return_value=mock_response)
94+
mock_response.__exit__ = Mock(return_value=None)
95+
mock_stream.return_value = mock_response
96+
97+
with pytest.raises(DownloadException) as exc_info:
98+
download_file("http://example.com", pathlib.Path("test.txt"))
99+
100+
assert "Failed to download file" in str(exc_info.value)
101+
102+
103+
@patch("requests.put")
104+
def test_upload_file_success(mock_put, tmp_path):
105+
test_file = tmp_path / "test.zip"
106+
test_file.write_bytes(b"test data")
107+
108+
mock_response = Mock()
109+
mock_response.status_code = 200
110+
mock_put.return_value = mock_response
111+
112+
upload_file_to_signed_url("http://example.com", str(test_file))
113+
114+
mock_put.assert_called_once()
115+
116+
117+
@patch("requests.put")
118+
def test_upload_file_failure(mock_put, tmp_path):
119+
test_file = tmp_path / "test.zip"
120+
test_file.write_bytes(b"test data")
121+
122+
mock_response = Mock()
123+
mock_response.status_code = 500
124+
mock_response.text = "Server error"
125+
mock_put.return_value = mock_response
126+
127+
with pytest.raises(Exception) as exc_info:
128+
upload_file_to_signed_url("http://example.com", str(test_file))
129+
130+
assert "Upload failed" in str(exc_info.value)
131+
132+
133+
def test_extract_package_as_zip(tmp_path):
134+
# Create a test zip file
135+
import zipfile
136+
137+
zip_path = tmp_path / "test.zip"
138+
extract_path = tmp_path / "extracted"
139+
140+
with zipfile.ZipFile(zip_path, "w") as test_zip:
141+
test_zip.writestr("test.txt", "test content")
142+
143+
extract_package_as_zip(zip_path, extract_path)
144+
145+
assert (extract_path / "test.txt").exists()
146+
assert (extract_path / "test.txt").read_text() == "test content"

0 commit comments

Comments
 (0)