Skip to content

Commit ffb407d

Browse files
author
Vasile Zaremba
authored
Merge pull request #1 from getyoti/handle_empty_profiles
Handle empty profiles
2 parents 5f48d38 + c86442a commit ffb407d

File tree

11 files changed

+127
-10
lines changed

11 files changed

+127
-10
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,4 @@ ENV/
9292
# IDE
9393
.idea/
9494
*.un~
95+
.history/

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](http://keepachangelog.com/)
66
and this project adheres to [Semantic Versioning](http://semver.org/).
77

8+
## [1.1.0] - 2017-03-20
9+
### Changed
10+
- Allow empty profiles
11+
812
## [0.1.2] - 2016-11-23
913

1014
### Fixed

yoti_python_sdk/activity_details.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33

44

55
class ActivityDetails:
6-
def __init__(self, receipt, decrypted_profile):
6+
def __init__(self, receipt, decrypted_profile=None):
77
self.decrypted_profile = decrypted_profile
88
self.user_profile = {}
99

10-
if hasattr(decrypted_profile, 'attributes'):
10+
if decrypted_profile and hasattr(decrypted_profile, 'attributes'):
1111
for field in decrypted_profile.attributes:
1212
value = Protobuf().value_based_on_content_type(
1313
field.value,

yoti_python_sdk/client.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ def get_activity_details(self, encrypted_request_token):
5757

5858
encrypted_data = protobuf.Protobuf().current_user(receipt)
5959

60+
if not encrypted_data:
61+
return ActivityDetails(receipt)
62+
6063
unwrapped_key = self.__crypto.decrypt_token(receipt['wrapped_receipt_key'])
6164
decrypted_data = self.__crypto.decipher(
6265
unwrapped_key,

yoti_python_sdk/protobuf/v1/protobuf.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ class Protobuf(object):
1515
CT_PNG = 4 # standard .png image
1616

1717
def current_user(self, receipt):
18-
if receipt.get('other_party_profile_content') is None:
19-
raise ValueError('The receipt has invalid data')
18+
if receipt.get('other_party_profile_content') is None or receipt.get('other_party_profile_content') == '':
19+
return None
20+
2021
profile_content = receipt['other_party_profile_content']
2122
decoded_profile_content = base64.b64decode(profile_content)
2223

yoti_python_sdk/tests/fixtures/response_empty_profile.txt

Lines changed: 16 additions & 0 deletions
Large diffs are not rendered by default.

yoti_python_sdk/tests/fixtures/response_missing_profile.txt

Lines changed: 15 additions & 0 deletions
Large diffs are not rendered by default.

yoti_python_sdk/tests/fixtures/response_null_profile.txt

Lines changed: 16 additions & 0 deletions
Large diffs are not rendered by default.

yoti_python_sdk/tests/mocks.py

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,36 @@
11
from uuid import UUID
22

33

4-
def mocked_requests_get(*args, **kwargs):
5-
class MockResponse:
6-
def __init__(self, status_code, text):
7-
self.status_code = status_code
8-
self.text = text
4+
class MockResponse:
5+
def __init__(self, status_code, text):
6+
self.status_code = status_code
7+
self.text = text
8+
99

10+
def mocked_requests_get(*args, **kwargs):
1011
with open('yoti_python_sdk/tests/fixtures/response.txt', 'r') as f:
1112
response = f.read()
1213
return MockResponse(status_code=200, text=response)
1314

1415

16+
def mocked_requests_get_null_profile(*args, **kwargs):
17+
with open('yoti_python_sdk/tests/fixtures/response_null_profile.txt', 'r') as f:
18+
response = f.read()
19+
return MockResponse(status_code=200, text=response)
20+
21+
22+
def mocked_requests_get_empty_profile(*args, **kwargs):
23+
with open('yoti_python_sdk/tests/fixtures/response_empty_profile.txt', 'r') as f:
24+
response = f.read()
25+
return MockResponse(status_code=200, text=response)
26+
27+
28+
def mocked_requests_get_missing_profile(*args, **kwargs):
29+
with open('yoti_python_sdk/tests/fixtures/response_missing_profile.txt', 'r') as f:
30+
response = f.read()
31+
return MockResponse(status_code=200, text=response)
32+
33+
1534
def mocked_timestamp():
1635
return 1476441361.2395663
1736

yoti_python_sdk/tests/test_client.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
from yoti_python_sdk.tests.conftest import YOTI_CLIENT_SDK_ID, PEM_FILE_PATH
1919
from yoti_python_sdk.tests.mocks import (
2020
mocked_requests_get,
21+
mocked_requests_get_null_profile,
22+
mocked_requests_get_empty_profile,
23+
mocked_requests_get_missing_profile,
2124
mocked_timestamp,
2225
mocked_uuid4
2326
)
@@ -105,6 +108,46 @@ def test_requesting_activity_details_with_correct_data(
105108

106109
mock_get.assert_called_once_with(url=expected_url, headers=expected_headers)
107110
assert isinstance(activity_details, ActivityDetails)
111+
assert activity_details.user_id == "ijH4kkqMKTG0FSNUgQIvd2Z3Nx1j8f5RjVQMyoKOvO/hkv43Ik+t6d6mGfP2tdrN"
108112
selfie = activity_details.user_profile.get('selfie')
109113
assert isinstance(selfie, basestring)
110114
assert selfie.startswith('data:image/jpeg;base64')
115+
116+
117+
@mock.patch('requests.get', side_effect=mocked_requests_get_null_profile)
118+
@mock.patch('time.time', side_effect=mocked_timestamp)
119+
@mock.patch('uuid.uuid4', side_effect=mocked_uuid4)
120+
def test_requesting_activity_details_with_null_profile(
121+
mock_uuid4, mock_time, mock_get, client, expected_url,
122+
expected_headers, encrypted_request_token):
123+
activity_details = client.get_activity_details(encrypted_request_token)
124+
125+
mock_get.assert_called_once_with(url=expected_url, headers=expected_headers)
126+
assert activity_details.user_id == "ijH4kkqMKTG0FSNUgQIvd2Z3Nx1j8f5RjVQMyoKOvO/hkv43Ik+t6d6mGfP2tdrN"
127+
assert isinstance(activity_details, ActivityDetails)
128+
129+
130+
@mock.patch('requests.get', side_effect=mocked_requests_get_empty_profile)
131+
@mock.patch('time.time', side_effect=mocked_timestamp)
132+
@mock.patch('uuid.uuid4', side_effect=mocked_uuid4)
133+
def test_requesting_activity_details_with_empty_profile(
134+
mock_uuid4, mock_time, mock_get, client, expected_url,
135+
expected_headers, encrypted_request_token):
136+
activity_details = client.get_activity_details(encrypted_request_token)
137+
138+
mock_get.assert_called_once_with(url=expected_url, headers=expected_headers)
139+
assert activity_details.user_id == "ijH4kkqMKTG0FSNUgQIvd2Z3Nx1j8f5RjVQMyoKOvO/hkv43Ik+t6d6mGfP2tdrN"
140+
assert isinstance(activity_details, ActivityDetails)
141+
142+
143+
@mock.patch('requests.get', side_effect=mocked_requests_get_missing_profile)
144+
@mock.patch('time.time', side_effect=mocked_timestamp)
145+
@mock.patch('uuid.uuid4', side_effect=mocked_uuid4)
146+
def test_requesting_activity_details_with_missing_profile(
147+
mock_uuid4, mock_time, mock_get, client, expected_url,
148+
expected_headers, encrypted_request_token):
149+
activity_details = client.get_activity_details(encrypted_request_token)
150+
151+
mock_get.assert_called_once_with(url=expected_url, headers=expected_headers)
152+
assert activity_details.user_id == "ijH4kkqMKTG0FSNUgQIvd2Z3Nx1j8f5RjVQMyoKOvO/hkv43Ik+t6d6mGfP2tdrN"
153+
assert isinstance(activity_details, ActivityDetails)

0 commit comments

Comments
 (0)