diff --git a/API/Routes/Case/CaseRoute.py b/API/Routes/Case/CaseRoute.py index d95482f41..5750fb276 100644 --- a/API/Routes/Case/CaseRoute.py +++ b/API/Routes/Case/CaseRoute.py @@ -433,6 +433,8 @@ def prepareCSV(): def downloadCSV(): try: casename = session.get('osycase', None) + if not casename: + return jsonify({'message': 'No active case session.', 'status_code': 'error'}), 400 dataFile = Path(Config.DATA_STORAGE,casename,'export.csv') dir = Path(Config.DATA_STORAGE,casename) diff --git a/API/Routes/DataFile/DataFileRoute.py b/API/Routes/DataFile/DataFileRoute.py index 2b7e98eff..dceb7636d 100644 --- a/API/Routes/DataFile/DataFileRoute.py +++ b/API/Routes/DataFile/DataFileRoute.py @@ -160,17 +160,9 @@ def validateInputs(): @datafile_api.route("/downloadDataFile", methods=['GET']) def downloadDataFile(): try: - #casename = request.json['casename'] - #casename = 'DEMO CASE' - # txtFile = DataFile(casename) - # downloadPath = txtFile.downloadDataFile() - # response = { - # "message": "You have downloaded data.txt to "+ str(downloadPath) +"!", - # "status_code": "success" - # } - # return jsonify(response), 200 - #path = "/Examples.pdf" case = session.get('osycase', None) + if not case: + return jsonify({'message': 'No active case session.', 'status_code': 'error'}), 400 caserunname = request.args.get('caserunname') dataFile = Path(Config.DATA_STORAGE,case, 'res',caserunname, 'data.txt') return send_file(dataFile.resolve(), as_attachment=True, max_age=0) @@ -182,6 +174,8 @@ def downloadDataFile(): def downloadFile(): try: case = session.get('osycase', None) + if not case: + return jsonify({'message': 'No active case session.', 'status_code': 'error'}), 400 file = request.args.get('file') dataFile = Path(Config.DATA_STORAGE,case,'res','csv',file) return send_file(dataFile.resolve(), as_attachment=True, max_age=0) @@ -193,6 +187,8 @@ def downloadFile(): def downloadCSVFile(): try: case = session.get('osycase', None) + if not case: + return jsonify({'message': 'No active case session.', 'status_code': 'error'}), 400 file = request.args.get('file') caserunname = request.args.get('caserunname') dataFile = Path(Config.DATA_STORAGE,case,'res',caserunname,'csv',file) @@ -205,6 +201,8 @@ def downloadCSVFile(): def downloadResultsFile(): try: case = session.get('osycase', None) + if not case: + return jsonify({'message': 'No active case session.', 'status_code': 'error'}), 400 caserunname = request.args.get('caserunname') dataFile = Path(Config.DATA_STORAGE,case, 'res', caserunname,'results.txt') return send_file(dataFile.resolve(), as_attachment=True, max_age=0) diff --git a/test_issue_356.py b/test_issue_356.py new file mode 100644 index 000000000..544ff8774 --- /dev/null +++ b/test_issue_356.py @@ -0,0 +1,52 @@ +""" +Test for Issue #356: Download endpoints crash with TypeError when no case session is set. +Verifies that all 5 download endpoints return 400 JSON instead of crashing with TypeError. +""" +import sys +import os + +# Add project root so imports resolve +sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'API')) + +from API.app import app + + +def run_tests(): + app.config['TESTING'] = True + client = app.test_client() + + endpoints = [ + ('/downloadDataFile', 'GET', {'caserunname': 'test'}), + ('/downloadFile', 'GET', {'file': 'test.csv'}), + ('/downloadCSVFile', 'GET', {'file': 'test.csv', 'caserunname': 'test'}), + ('/downloadResultsFile', 'GET', {'caserunname': 'test'}), + ('/downloadCSV', 'GET', {}), + ] + + passed = 0 + failed = 0 + + for path, method, params in endpoints: + resp = client.get(path, query_string=params) + + if resp.status_code == 400: + data = resp.get_json() + if data and data.get('status_code') == 'error': + print(f"PASS: {path} -> 400 JSON error") + passed += 1 + else: + print(f"FAIL: {path} -> 400 but unexpected body: {data}") + failed += 1 + elif resp.status_code == 500: + print(f"FAIL: {path} -> 500 (TypeError not fixed!)") + failed += 1 + else: + print(f"FAIL: {path} -> unexpected {resp.status_code}") + failed += 1 + + print(f"\nResults: {passed} passed, {failed} failed out of {len(endpoints)}") + sys.exit(0 if failed == 0 else 1) + + +if __name__ == "__main__": + run_tests()