diff --git a/fittrackee/tests/workouts/test_workouts_api_1_post.py b/fittrackee/tests/workouts/test_workouts_api_1_post.py index c500d8fd..da727f10 100644 --- a/fittrackee/tests/workouts/test_workouts_api_1_post.py +++ b/fittrackee/tests/workouts/test_workouts_api_1_post.py @@ -1177,6 +1177,40 @@ class TestPostWorkoutWithZipArchive(ApiTestCaseMixin): ) assert 'data' not in data + def test_it_returns_error_if_a_file_from_archive_size_exceeds_limit( + self, + app_with_max_file_size: Flask, + user_1: User, + sport_1_cycling: Sport, + ) -> None: + file_path = os.path.join( + app_with_max_file_size.root_path, 'tests/files/gpx_test.zip' + ) + # 'gpx_test.zip' contains 3 gpx files (same data) and 1 non-gpx file + with open(file_path, 'rb') as zip_file: + client, auth_token = self.get_test_client_and_auth_token( + app_with_max_file_size, user_1.email + ) + + response = client.post( + '/api/workouts', + data=dict( + file=(zip_file, 'gpx_test.zip'), data='{"sport_id": 1}' + ), + headers=dict( + content_type='multipart/form-data', + Authorization=f'Bearer {auth_token}', + ), + ) + + data = self.assert_400( + response, + 'at least one file in zip archive exceeds size limit, ' + 'please check the archive', + 'fail', + ) + assert 'data' not in data + class TestPostAndGetWorkoutWithGpx(ApiTestCaseMixin): def workout_assertion( diff --git a/fittrackee/workouts/utils/workouts.py b/fittrackee/workouts/utils/workouts.py index 03eb21b1..568de418 100644 --- a/fittrackee/workouts/utils/workouts.py +++ b/fittrackee/workouts/utils/workouts.py @@ -349,15 +349,27 @@ def process_zip_archive( does not exceed defined limit. """ with zipfile.ZipFile(common_params['file_path'], "r") as zip_ref: - info_list = [ - zip_info - for zip_info in zip_ref.infolist() - if is_gpx_file(zip_info.filename) - ] - if len(info_list) > current_app.config['gpx_limit_import']: + max_file_size = current_app.config['max_single_file_size'] + gpx_files_count = 0 + files_with_invalid_size_count = 0 + for zip_info in zip_ref.infolist(): + if is_gpx_file(zip_info.filename): + gpx_files_count += 1 + if zip_info.file_size > max_file_size: + files_with_invalid_size_count += 1 + + if gpx_files_count > current_app.config['gpx_limit_import']: raise WorkoutException( 'fail', 'the number of files in the archive exceeds the limit' ) + + if files_with_invalid_size_count > 0: + raise WorkoutException( + 'fail', + 'at least one file in zip archive exceeds size limit, ' + 'please check the archive', + ) + zip_ref.extractall(extract_dir) new_workouts = []