Skip to content

Commit c824fd9

Browse files
Merge pull request #815 from adamtheturtle/test-no-such-target
Test no such target
2 parents e5c4faa + bc8bd22 commit c824fd9

File tree

3 files changed

+141
-7
lines changed

3 files changed

+141
-7
lines changed

src/vws/exceptions.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
"""
2+
Custom exceptions for Vuforia errors.
3+
"""
4+
5+
from requests import Response
6+
7+
8+
class UnknownTarget(Exception):
9+
"""
10+
Exception raised when Vuforia returns a response with a result code
11+
'UnknownTarget'.
12+
"""
13+
14+
def __init__(self, response: Response) -> None:
15+
"""
16+
Args:
17+
response: The response to a request to Vuforia.
18+
"""
19+
super().__init__()
20+
self.response = response

src/vws/vws.py

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import base64
66
import io
77
import json
8+
from enum import Enum
89
from time import sleep
910
from typing import Dict, List, Union
1011
from urllib.parse import urljoin
@@ -14,6 +15,7 @@
1415
from requests import Response
1516

1617
from vws._authorization import authorization_header, rfc_1123_date
18+
from vws.exceptions import UnknownTarget
1719

1820

1921
def _target_api_request(
@@ -74,6 +76,39 @@ def _target_api_request(
7476
return response
7577

7678

79+
class _ResultCodes(Enum):
80+
"""
81+
Constants representing various VWS result codes.
82+
83+
See
84+
https://library.vuforia.com/articles/Solution/How-To-Use-the-Vuforia-Web-Services-API.html#How-To-Interperete-VWS-API-Result-Codes
85+
86+
Some codes here are not documented in the above link.
87+
"""
88+
89+
SUCCESS = 'Success'
90+
TARGET_CREATED = 'TargetCreated'
91+
AUTHENTICATION_FAILURE = 'AuthenticationFailure'
92+
REQUEST_TIME_TOO_SKEWED = 'RequestTimeTooSkewed'
93+
TARGET_NAME_EXIST = 'TargetNameExist'
94+
UNKNOWN_TARGET = 'UnknownTarget'
95+
BAD_IMAGE = 'BadImage'
96+
IMAGE_TOO_LARGE = 'ImageTooLarge'
97+
METADATA_TOO_LARGE = 'MetadataTooLarge'
98+
DATE_RANGE_ERROR = 'DateRangeError'
99+
FAIL = 'Fail'
100+
TARGET_STATUS_PROCESSING = 'TargetStatusProcessing'
101+
REQUEST_QUOTA_REACHED = 'RequestQuotaReached'
102+
TARGET_STATUS_NOT_SUCCESS = 'TargetStatusNotSuccess'
103+
PROJECT_INACTIVE = 'ProjectInactive'
104+
INACTIVE_PROJECT = 'InactiveProject'
105+
106+
107+
_EXCEPTIONS = {
108+
_ResultCodes.UNKNOWN_TARGET: UnknownTarget,
109+
}
110+
111+
77112
class VWS:
78113
"""
79114
An interface to Vuforia Web Services APIs.
@@ -162,7 +197,12 @@ def get_target_record(self, target_id: str) -> Dict[str, Union[str, int]]:
162197
base_vws_url=self._base_vws_url,
163198
)
164199

165-
return dict(response.json()['target_record'])
200+
result_code = response.json()['result_code']
201+
if _ResultCodes(result_code) == _ResultCodes.SUCCESS:
202+
return dict(response.json()['target_record'])
203+
204+
exception = _EXCEPTIONS[_ResultCodes(result_code)]
205+
raise exception(response=response)
166206

167207
@timeout_decorator.timeout(seconds=60 * 5)
168208
def wait_for_target_processed(self, target_id: str) -> None:
@@ -187,11 +227,6 @@ def wait_for_target_processed(self, target_id: str) -> None:
187227
# hitting the request quota.
188228
sleep(0.2)
189229

190-
# We wait 0.2 seconds rather than less than that to decrease the
191-
# number of calls made to the API, to decrease the likelihood of
192-
# hitting the request quota.
193-
sleep(0.2)
194-
195230
def list_targets(self) -> List[str]:
196231
"""
197232
List target IDs.
@@ -232,7 +267,12 @@ def get_target_summary_report(
232267
base_vws_url=self._base_vws_url,
233268
)
234269

235-
return dict(response.json())
270+
result_code = response.json()['result_code']
271+
if _ResultCodes(result_code) == _ResultCodes.SUCCESS:
272+
return dict(response.json())
273+
274+
exception = _EXCEPTIONS[_ResultCodes(result_code)]
275+
raise exception(response=response)
236276

237277
def get_database_summary_report(self) -> Dict[str, Union[str, int]]:
238278
"""
@@ -259,3 +299,18 @@ def delete_target(self, target_id: str) -> None:
259299
Args:
260300
target_id: The ID of the target to delete.
261301
"""
302+
response = _target_api_request(
303+
server_access_key=self._server_access_key,
304+
server_secret_key=self._server_secret_key,
305+
method='GET',
306+
content=b'',
307+
request_path=f'/summary/{target_id}',
308+
base_vws_url=self._base_vws_url,
309+
)
310+
311+
result_code = response.json()['result_code']
312+
if _ResultCodes(result_code) == _ResultCodes.SUCCESS:
313+
return
314+
315+
exception = _EXCEPTIONS[_ResultCodes(result_code)]
316+
raise exception(response=response)

tests/test_unknown_target.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
"""
2+
Tests for passing invalid target IDs to helpers which require a target ID to
3+
be given.
4+
"""
5+
6+
from typing import Any, Callable, Dict, Union
7+
8+
import pytest
9+
from _pytest.fixtures import SubRequest
10+
from requests import codes
11+
12+
from vws import VWS
13+
from vws.exceptions import UnknownTarget
14+
15+
16+
@pytest.fixture()
17+
def _delete_target(client: VWS) -> Callable[[str], None]:
18+
return client.delete_target
19+
20+
21+
@pytest.fixture()
22+
def _get_target_record(client: VWS,
23+
) -> Callable[[str], Dict[str, Union[str, int]]]:
24+
return client.get_target_record
25+
26+
27+
@pytest.fixture()
28+
def _wait_for_target_processed(client: VWS) -> Any:
29+
return client.wait_for_target_processed
30+
31+
32+
@pytest.fixture()
33+
def _get_target_summary_report(
34+
client: VWS,
35+
) -> Callable[[str], Dict[str, Union[str, int]]]:
36+
return client.get_target_summary_report
37+
38+
39+
@pytest.mark.parametrize(
40+
'fixture',
41+
[
42+
'_delete_target',
43+
'_get_target_record',
44+
'_wait_for_target_processed',
45+
'_get_target_summary_report',
46+
],
47+
)
48+
def test_invalid_given_id(
49+
fixture: Callable[[str], None],
50+
request: SubRequest,
51+
) -> None:
52+
"""
53+
Giving an invalid ID to a helper which requires a target ID to be given
54+
causes an ``UnknownTarget`` exception to be raised.
55+
"""
56+
func = request.getfixturevalue(fixture)
57+
with pytest.raises(UnknownTarget) as exc:
58+
func(target_id='x')
59+
assert exc.value.response.status_code == codes.NOT_FOUND

0 commit comments

Comments
 (0)