Skip to content

Commit e1c2c8e

Browse files
SK-2842: improve coverage and revert details in skyflow error class
1 parent 5345434 commit e1c2c8e

12 files changed

Lines changed: 469 additions & 1 deletion

File tree

skyflow/error/_skyflow_error.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ def __init__(self,
1212
self.http_code = http_code
1313
self.grpc_code = grpc_code
1414
self.http_status = http_status if http_status else SkyflowMessages.HttpStatus.BAD_REQUEST.value
15-
self.details = details if details else None
15+
self.details = details if details else []
1616
self.request_id = request_id
1717
super().__init__(message)

tests/vault/connection/__init__.py

Whitespace-only changes.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import unittest
2+
from skyflow.vault.connection._invoke_connection_response import InvokeConnectionResponse
3+
4+
5+
class TestInvokeConnectionResponse(unittest.TestCase):
6+
def test_repr(self):
7+
r = InvokeConnectionResponse(data={"key": "val"}, metadata={"m": 1}, errors=None)
8+
self.assertIn("ConnectionResponse", repr(r))
9+
10+
def test_str(self):
11+
r = InvokeConnectionResponse(data={"key": "val"})
12+
self.assertEqual(str(r), repr(r))
13+
14+
def test_defaults(self):
15+
r = InvokeConnectionResponse()
16+
self.assertIsNone(r.data)
17+
self.assertEqual(r.metadata, {})
18+
self.assertIsNone(r.errors)
19+
20+
def test_metadata_defaults_to_empty_dict_when_falsy(self):
21+
r = InvokeConnectionResponse(metadata=None)
22+
self.assertEqual(r.metadata, {})
23+
24+
25+
if __name__ == "__main__":
26+
unittest.main()
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import unittest
2+
from skyflow.vault.controller._audit import Audit
3+
from skyflow.vault.controller._bin_look_up import BinLookUp
4+
5+
6+
class TestAudit(unittest.TestCase):
7+
def test_instantiation(self):
8+
a = Audit()
9+
self.assertIsNotNone(a)
10+
11+
def test_list_returns_none(self):
12+
a = Audit()
13+
self.assertIsNone(a.list())
14+
15+
16+
class TestBinLookUp(unittest.TestCase):
17+
def test_instantiation(self):
18+
b = BinLookUp()
19+
self.assertIsNotNone(b)
20+
21+
def test_get_returns_none(self):
22+
b = BinLookUp()
23+
self.assertIsNone(b.get())
24+
25+
26+
if __name__ == "__main__":
27+
unittest.main()

tests/vault/controller/test__detect.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,48 @@ def test_save_output_write_exception(self):
781781
response, tmp_dir, "file.txt", "file"
782782
)
783783

784+
def test_save_output_no_file_extension_uses_original_name(self):
785+
"""Branches 113->117 and 119->124: processed_file_extension is falsy — safe_ext stays None."""
786+
with tempfile.TemporaryDirectory() as tmp_dir:
787+
output = Mock()
788+
output.processedFile = base64.b64encode(b"data").decode()
789+
output.processedFileType = "redacted_file"
790+
output.processedFileExtension = None
791+
output.processed_file_extension = None
792+
response = Mock()
793+
response.output = [output]
794+
self.detect._Detect__save_deidentify_file_response_output(
795+
response, tmp_dir, "original.txt", "original"
796+
)
797+
798+
@patch("skyflow.vault.controller._detect.time.sleep", return_value=None)
799+
def test_poll_unknown_status_then_success(self, mock_sleep):
800+
"""Branch 80->65: status is unknown, loops back, then returns SUCCESS."""
801+
files_api = Mock()
802+
files_api.with_raw_response = files_api
803+
self.vault_client.get_detect_file_api.return_value = files_api
804+
805+
call_count = {"n": 0}
806+
807+
def side_effect(*args, **kwargs):
808+
call_count["n"] += 1
809+
r = Mock()
810+
if call_count["n"] == 1:
811+
r.status = "UNKNOWN_STATUS"
812+
else:
813+
r.status = "SUCCESS"
814+
return Mock(data=r)
815+
816+
files_api.get_run.side_effect = side_effect
817+
result = self.detect._Detect__poll_for_processed_file("runid", max_wait_time=10)
818+
self.assertEqual(result.status, "SUCCESS")
819+
820+
def test_get_file_from_request_no_file_no_path_returns_none(self):
821+
"""Branch 285->exit: file_input has neither file nor file_path set."""
822+
req = DeidentifyFileRequest(file=FileInput(file=None, file_path=None))
823+
result = self.detect._Detect__get_file_from_request(req)
824+
self.assertIsNone(result)
825+
784826
@patch("skyflow.vault.controller._detect.validate_deidentify_file_request")
785827
@patch("skyflow.vault.controller._detect.base64")
786828
def test_deidentify_file_api_error_inside_try(self, mock_base64, mock_validate):

tests/vault/controller/test__vault.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,56 @@ def test_upload_file_without_skyflow_id_successful(self, mock_validate):
742742
self.assertEqual(result.skyflow_id, "generated-id-123")
743743
self.assertIsNone(result.errors)
744744

745+
@patch("skyflow.vault.controller._vault.validate_file_upload_request")
746+
@patch("skyflow.vault.controller._vault.open", mock_open(read_data=b"file_content"), create=True)
747+
def test_upload_file_file_path_with_existing_file_name(self, mock_validate):
748+
"""Branch 73->76: file_name already set when file_path is present — skips basename call."""
749+
request = FileUploadRequest(
750+
table=TABLE_NAME,
751+
column_name="file_col",
752+
file_path="/path/to/file.txt",
753+
file_name="already_set.txt"
754+
)
755+
mock_api = self.vault_client.get_records_api.return_value.with_raw_response
756+
mock_response = Mock()
757+
mock_response.data.skyflow_id = "sky123"
758+
mock_api.upload_file_v_2.return_value = mock_response
759+
760+
self.vault.upload_file(request)
761+
mock_api.upload_file_v_2.assert_called_once()
762+
763+
@patch("skyflow.vault.controller._vault.validate_file_upload_request")
764+
def test_upload_file_file_object_without_name_attr(self, mock_validate):
765+
"""Branch 84->89: file_object has no 'name' attr — __get_file_for_file_upload returns None."""
766+
file_obj = Mock(spec=[])
767+
request = FileUploadRequest(
768+
table=TABLE_NAME,
769+
column_name="file_col",
770+
file_object=file_obj
771+
)
772+
mock_api = self.vault_client.get_records_api.return_value.with_raw_response
773+
mock_response = Mock()
774+
mock_response.data.skyflow_id = "sky123"
775+
mock_api.upload_file_v_2.return_value = mock_response
776+
777+
self.vault.upload_file(request)
778+
mock_api.upload_file_v_2.assert_called_once()
779+
780+
@patch("skyflow.vault.controller._vault.validate_file_upload_request")
781+
def test_upload_file_no_file_source_returns_none_file(self, mock_validate):
782+
"""Branch 84->89 (elif False): all file sources None — __get_file_for_file_upload returns None."""
783+
request = FileUploadRequest(
784+
table=TABLE_NAME,
785+
column_name="file_col"
786+
)
787+
mock_api = self.vault_client.get_records_api.return_value.with_raw_response
788+
mock_response = Mock()
789+
mock_response.data.skyflow_id = "sky123"
790+
mock_api.upload_file_v_2.return_value = mock_response
791+
792+
self.vault.upload_file(request)
793+
mock_api.upload_file_v_2.assert_called_once()
794+
745795
class TestFileUploadValidation(unittest.TestCase):
746796
def setUp(self):
747797
self.logger = Mock()

tests/vault/data/__init__.py

Whitespace-only changes.

tests/vault/data/test_responses.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import unittest
2+
from skyflow.vault.data._delete_response import DeleteResponse
3+
from skyflow.vault.data._file_upload_response import FileUploadResponse
4+
from skyflow.vault.data._get_response import GetResponse
5+
from skyflow.vault.data._insert_response import InsertResponse
6+
from skyflow.vault.data._query_response import QueryResponse
7+
from skyflow.vault.data._update_response import UpdateResponse
8+
from skyflow.vault.data._upload_file_request import UploadFileRequest
9+
10+
11+
class TestDeleteResponse(unittest.TestCase):
12+
def test_repr(self):
13+
r = DeleteResponse(deleted_ids=["id1"], errors=None)
14+
self.assertIn("DeleteResponse", repr(r))
15+
self.assertIn("id1", repr(r))
16+
17+
def test_str(self):
18+
r = DeleteResponse(deleted_ids=["id1"], errors=None)
19+
self.assertEqual(str(r), repr(r))
20+
21+
def test_defaults(self):
22+
r = DeleteResponse()
23+
self.assertIsNone(r.deleted_ids)
24+
self.assertIsNone(r.errors)
25+
26+
27+
class TestFileUploadResponse(unittest.TestCase):
28+
def test_repr(self):
29+
r = FileUploadResponse(skyflow_id="sky123", errors=None)
30+
self.assertIn("FileUploadResponse", repr(r))
31+
self.assertIn("sky123", repr(r))
32+
33+
def test_str(self):
34+
r = FileUploadResponse(skyflow_id="sky123", errors=None)
35+
self.assertEqual(str(r), repr(r))
36+
37+
38+
class TestGetResponse(unittest.TestCase):
39+
def test_repr(self):
40+
r = GetResponse(data=[{"field": "val"}], errors=None)
41+
self.assertIn("GetResponse", repr(r))
42+
43+
def test_str(self):
44+
r = GetResponse(data=[{"field": "val"}], errors=None)
45+
self.assertEqual(str(r), repr(r))
46+
47+
def test_none_data_defaults_to_empty_list(self):
48+
r = GetResponse(data=None)
49+
self.assertEqual(r.data, [])
50+
51+
def test_empty_data_not_replaced(self):
52+
r = GetResponse(data={})
53+
self.assertEqual(r.data, {})
54+
55+
56+
class TestInsertResponse(unittest.TestCase):
57+
def test_repr(self):
58+
r = InsertResponse(inserted_fields=[{"skyflow_id": "id1"}], errors=None)
59+
self.assertIn("InsertResponse", repr(r))
60+
61+
def test_str(self):
62+
r = InsertResponse(inserted_fields=[{"skyflow_id": "id1"}])
63+
self.assertEqual(str(r), repr(r))
64+
65+
def test_defaults(self):
66+
r = InsertResponse()
67+
self.assertIsNone(r.inserted_fields)
68+
self.assertIsNone(r.errors)
69+
70+
71+
class TestQueryResponse(unittest.TestCase):
72+
def test_repr(self):
73+
r = QueryResponse()
74+
self.assertIn("QueryResponse", repr(r))
75+
76+
def test_str(self):
77+
r = QueryResponse()
78+
self.assertEqual(str(r), repr(r))
79+
80+
def test_defaults(self):
81+
r = QueryResponse()
82+
self.assertEqual(r.fields, [])
83+
self.assertIsNone(r.errors)
84+
85+
86+
class TestUpdateResponse(unittest.TestCase):
87+
def test_repr(self):
88+
r = UpdateResponse(updated_field={"skyflow_id": "id1"}, errors=None)
89+
self.assertIn("UpdateResponse", repr(r))
90+
91+
def test_str(self):
92+
r = UpdateResponse(updated_field={"skyflow_id": "id1"})
93+
self.assertEqual(str(r), repr(r))
94+
95+
def test_defaults(self):
96+
r = UpdateResponse()
97+
self.assertIsNone(r.updated_field)
98+
self.assertIsNone(r.errors)
99+
100+
101+
class TestUploadFileRequest(unittest.TestCase):
102+
def test_instantiation(self):
103+
r = UploadFileRequest()
104+
self.assertIsNotNone(r)
105+
106+
107+
if __name__ == "__main__":
108+
unittest.main()

tests/vault/detect/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)