Repository: box/box-python-sdk
Pull request #866 (2024-01-18 11:37:49)

fix: Update exception file get download URL
Closes: SDK-3474

I'm using the `BoxException` not `BoxAPIException` because normally, the `BoxAPIException` will parse from response body but not any custom exception.

coveralls: ## Pull Request Test Coverage Report for [Build 7569455181](https://coveralls.io/builds/65149037)


* **0** of **0**   changed or added relevant lines in **0** files are covered.
* No unchanged relevant lines lost coverage.
* Overall coverage increased (+**0.005%**) to **93.536%**

---



|  Totals | [![Coverage Status](https://coveralls.io/builds/65149037/badge)](https://coveralls.io/builds/65149037) |
| :-- | --: |
| Change from base [Build 7556215294](https://coveralls.io/builds/65123074): |  0.005% |
| Covered Lines: | 3473 |
| Relevant Lines: | 3713 |

---
##### 💛  - [Coveralls](https://coveralls.io)


Patch:
diff --git a/boxsdk/object/file.py b/boxsdk/object/file.py
index 53fd17e..17eda2c 100644
--- a/boxsdk/object/file.py
+++ b/boxsdk/object/file.py
@@ -2,6 +2,7 @@
 import os
 from datetime import datetime
 from typing import TYPE_CHECKING, Optional, Tuple, Union, IO, Iterable, List, Any
+from boxsdk.exception import BoxException
 
 from boxsdk.util.datetime_formatter import normalize_date_to_rfc3339_format
 from .item import Item
@@ -177,6 +178,9 @@ def get_download_url(self, file_version: Optional['FileVersion'] = None) -> str:
             expect_json_response=False,
             allow_redirects=False,
         )
+        if 'location' not in box_response.headers:
+            raise BoxException('Download URL is not present in the response.')
+
         return box_response.headers['location']
 
     @api_call
diff --git a/docs/usage/authentication.md b/docs/usage/authentication.md
index f7885ef..bce264e 100644
--- a/docs/usage/authentication.md
+++ b/docs/usage/authentication.md
@@ -182,7 +182,7 @@ app_user_client = Client(app_user_auth)
 ### Client Credentials Grant
 
 Allows you to obtain an access token by having client credentials and secret with enterprise or user ID,
-which allows you to work using service or user account.
+which allows you to work using a service or user account.
 
 You can use `CCGAuth` to initialize a client object the same way as for other authentication types:
 
@@ -197,7 +197,7 @@ client = Client(auth)
 print(f'Id of the authenticated user is: {client.user().get().id}')
 ```
 
-Obtained token is valid for specified ammount of time, it will be refreshed automatically by default.
+Obtained token is valid for specified amount of time, it will be refreshed automatically by default.
 
 #### Obtaining Service Account token
 
@@ -216,7 +216,7 @@ auth = CCGAuth(
 )
 ```
 
-Remember that you can still make calls on behalf of managed users, which are part of your etnerprise, by using
+Remember that you can still make calls on behalf of managed users, which are part of your enterprise, by using
 [As-User](#as-user) bahaviour.
 
 #### Obtaining User token


Test patch:
diff --git a/test/unit/object/test_file.py b/test/unit/object/test_file.py
index 13b56f5..4449e49 100644
--- a/test/unit/object/test_file.py
+++ b/test/unit/object/test_file.py
@@ -8,7 +8,7 @@
 from pytest_lazyfixture import lazy_fixture
 
 from boxsdk.config import API
-from boxsdk.exception import BoxAPIException
+from boxsdk.exception import BoxAPIException, BoxException
 from boxsdk.object.comment import Comment
 from boxsdk.object.file import File
 from boxsdk.object.file_version import FileVersion
@@ -237,6 +237,20 @@ def test_get_download_url(test_file, mock_box_session):
     assert url == download_url
 
 
+def test_get_download_url_failed(test_file, mock_box_session):
+    expected_url = f'{API.BASE_API_URL}/files/{test_file.object_id}/content'
+    mock_box_session.get.return_value.headers = {}
+    with pytest.raises(BoxException) as exc_info:
+        test_file.get_download_url()
+    assert exc_info.value.args[0] == 'Download URL is not present in the response.'
+    mock_box_session.get.assert_called_once_with(
+        expected_url,
+        params=None,
+        expect_json_response=False,
+        allow_redirects=False
+    )
+
+
 def test_get_download_url_file_version(test_file, test_file_version, mock_box_session):
     expected_url = f'{API.BASE_API_URL}/files/{test_file.object_id}/content'
     download_url = 'https://dl.boxcloud.com/sdjhfgksdjfgshdbg'