diff --git a/railib/api.py b/railib/api.py index 8e28b72..22243ca 100644 --- a/railib/api.py +++ b/railib/api.py @@ -270,7 +270,7 @@ def _parse_multipart_form( txn_file.name = name.group(1).decode() filename = re.match(b'.*filename="(.+?)"', disposition) if not (filename is None): - txn_file.filename = name.group(1).decode() + txn_file.filename = filename.group(1).decode() result.append(txn_file) diff --git a/test/multipart.data b/test/multipart.data new file mode 100644 index 0000000..4bd88bc Binary files /dev/null and b/test/multipart.data differ diff --git a/test/test_integration.py b/test/test_integration.py index 6a0270e..a5def69 100644 --- a/test/test_integration.py +++ b/test/test_integration.py @@ -7,7 +7,7 @@ from logging.config import fileConfig from pathlib import Path from railib import api, config - +from unittest.mock import patch, MagicMock # Get creds from env vars if exists client_id = os.getenv("CLIENT_ID") @@ -78,6 +78,43 @@ def test_v2_exec(self): 1, 8, 27, 64, 125], 'v4': [ 1, 16, 81, 256, 625]}, rsp.results[0]["table"].to_pydict()) + @patch('railib.rest.request') + def test_v2_exec_mocked(self, mock_urlopen): + # mock the multipart response + mocked_resp = MagicMock() + mocked_resp.headers.get.return_value = "multipart/form-data; boundary=b11385ead6144ee0a9550db3672a7ccf" + with open(os.path.join(Path(__file__).parent, "multipart.data"), "rb") as f: + mocked_resp.read.return_value = f.read() + + mock_urlopen.return_value = mocked_resp + + # run the current test + cmd = "x, x^2, x^3, x^4 from x in {1; 2; 3; 4; 5}" + rsp = api.exec_async(ctx, "mocked_db", "mocked_engine", cmd) + + # transaction + self.assertEqual("COMPLETED", rsp.transaction["state"]) + + # metadata + with open(os.path.join(Path(__file__).parent, "metadata.pb"), "rb") as f: + data = f.read() + self.assertEqual( + rsp.metadata, + api._parse_metadata_proto(data) + ) + + # problems + self.assertEqual(0, len(rsp.problems)) + + # results + self.assertEqual( + { + 'v1': [ + 1, 2, 3, 4, 5], 'v2': [ + 1, 4, 9, 16, 25], 'v3': [ + 1, 8, 27, 64, 125], 'v4': [ + 1, 16, 81, 256, 625]}, rsp.results[0]["table"].to_pydict()) + def tearDown(self): api.delete_engine(ctx, engine) api.delete_database(ctx, dbname)