Skip to content

Commit c2d9d61

Browse files
committed
Update passport tests
1 parent 0681197 commit c2d9d61

File tree

2 files changed

+94
-82
lines changed

2 files changed

+94
-82
lines changed

tests/test_message.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
#
1717
# You should have received a copy of the GNU Lesser Public License
1818
# along with this program. If not, see [http://www.gnu.org/licenses/].
19-
from copy import deepcopy
2019
from datetime import datetime
2120

2221
import pytest
@@ -89,7 +88,7 @@ def message(bot):
8988
{'photo': [PhotoSize('photo_id', 50, 50)],
9089
'caption': 'photo_file',
9190
'media_group_id': 1234443322222},
92-
'PASSPORT'
91+
{'passport_data': PassportData.de_json(RAW_PASSPORT_DATA, None)}
9392
],
9493
ids=['forwarded_user', 'forwarded_channel', 'reply', 'edited', 'text',
9594
'caption_entities', 'audio', 'document', 'animation', 'game', 'photo',
@@ -100,9 +99,6 @@ def message(bot):
10099
'connected_website', 'forward_signature', 'author_signature',
101100
'photo_from_media_group', 'passport_data'])
102101
def message_params(bot, request):
103-
if request.param == 'PASSPORT': # We need a bot to decrypt stuff
104-
request.param = {'passport_data': PassportData.de_json(deepcopy(RAW_PASSPORT_DATA),
105-
bot=bot)}
106102
return Message(message_id=TestMessage.id,
107103
from_user=TestMessage.from_user,
108104
date=TestMessage.date,

tests/test_passport.py

Lines changed: 93 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,11 @@
1717
# You should have received a copy of the GNU Lesser Public License
1818
# along with this program. If not, see [http://www.gnu.org/licenses/].
1919
from copy import deepcopy
20-
from threading import Event
2120

2221
import pytest
2322

24-
from telegram import (PassportData, PassportFile, Bot, Update, File, PassportElementErrorSelfie,
25-
PassportElementErrorDataField)
23+
from telegram import (PassportData, PassportFile, Bot, File, PassportElementErrorSelfie,
24+
PassportElementErrorDataField, Credentials, TelegramDecryptionError)
2625

2726
RAW_PASSPORT_DATA = {'data': [{'type': 'personal_details',
2827
'data': 'tj3pNwOpN+ZHsyb6F3aJcNmEyPxrOtGTbu3waBlCQDNaQ9oJlkbXpw+HI3y9faq/+TCeB/WsS/2TxRXTKZw4zXvGP2UsfdRkJ2SQq6x+Ffe/oTF9/q8sWp2BwU3hHUOz7ec1/QrdPBhPJjbwSykEBNggPweiBVDZ0x/DWJ0guCkGT9smYGqog1vqlqbIWG7AWcxVy2fpUy9w/zDXjxj5WQ3lRpHJmi46s9xIHobNGGBvWw6/bGBCInMoovgqRCEu1sgz2QXF3wNiUzGFycEzLz7o+1htLys5n8Pdi9MG4RY='},
@@ -35,7 +34,7 @@
3534
'front_side': {'file_id': 'DgADBAADxwMAApnQgVPK2-ckL2eXVAI',
3635
'file_date': 1534074942}},
3736
{'type': 'address',
38-
'data': 'j9SksVkSj128DBtZA+3aNjSFNirzv+R97guZaMgae4Gi0oDVNAF7twPR7j9VSmPedfJrEwL3O889Ei+a5F1xyLLyEI/qEBljvL70GFIhYGitS0JmNabHPHSZrjOl8b4s/0Z0Px2GpLO5siusTLQonimdUvu4UPjKquYISmlKEKhtmGATy+h+JDjNCYuOkhakeNw0Rk0BHgj0C3fCb7WZNQSyVb+2GTu6caR6eXf/AFwFp0TV3sRz3h0WIVPW8bna'}, # noqa: E501
37+
'data': 'j9SksVkSj128DBtZA+3aNjSFNirzv+R97guZaMgae4Gi0oDVNAF7twPR7j9VSmPedfJrEwL3O889Ei+a5F1xyLLyEI/qEBljvL70GFIhYGitS0JmNabHPHSZrjOl8b4s/0Z0Px2GpLO5siusTLQonimdUvu4UPjKquYISmlKEKhtmGATy+h+JDjNCYuOkhakeNw0Rk0BHgj0C3fCb7WZNQSyVb+2GTu6caR6eXf/AFwFp0TV3sRz3h0WIVPW8bna'},
3938
{'type': 'utility_bill', 'files': [
4039
{'file_id': 'DgADBAADLAMAAhwfgVMyfGa5Nr0LvAI',
4140
'file_date': 1534074988},
@@ -50,39 +49,38 @@
5049

5150
@pytest.fixture(scope='function')
5251
def all_passport_data():
53-
raw_passport_data = deepcopy(RAW_PASSPORT_DATA)
5452
return [{'type': 'personal_details',
55-
'data': raw_passport_data['data'][0]['data']},
53+
'data': RAW_PASSPORT_DATA['data'][0]['data']},
5654
{'type': 'passport',
57-
'data': raw_passport_data['data'][1]['data'],
58-
'front_side': raw_passport_data['data'][1]['front_side'],
59-
'selfie': raw_passport_data['data'][1]['selfie']},
55+
'data': RAW_PASSPORT_DATA['data'][1]['data'],
56+
'front_side': RAW_PASSPORT_DATA['data'][1]['front_side'],
57+
'selfie': RAW_PASSPORT_DATA['data'][1]['selfie']},
6058
{'type': 'internal_passport',
61-
'data': raw_passport_data['data'][1]['data'],
62-
'front_side': raw_passport_data['data'][1]['front_side'],
63-
'selfie': raw_passport_data['data'][1]['selfie']},
59+
'data': RAW_PASSPORT_DATA['data'][1]['data'],
60+
'front_side': RAW_PASSPORT_DATA['data'][1]['front_side'],
61+
'selfie': RAW_PASSPORT_DATA['data'][1]['selfie']},
6462
{'type': 'driver_license',
65-
'data': raw_passport_data['data'][1]['data'],
66-
'front_side': raw_passport_data['data'][1]['front_side'],
67-
'reverse_side': raw_passport_data['data'][1]['reverse_side'],
68-
'selfie': raw_passport_data['data'][1]['selfie']},
63+
'data': RAW_PASSPORT_DATA['data'][1]['data'],
64+
'front_side': RAW_PASSPORT_DATA['data'][1]['front_side'],
65+
'reverse_side': RAW_PASSPORT_DATA['data'][1]['reverse_side'],
66+
'selfie': RAW_PASSPORT_DATA['data'][1]['selfie']},
6967
{'type': 'identity_card',
70-
'data': raw_passport_data['data'][1]['data'],
71-
'front_side': raw_passport_data['data'][1]['front_side'],
72-
'reverse_side': raw_passport_data['data'][1]['reverse_side'],
73-
'selfie': raw_passport_data['data'][1]['selfie']},
68+
'data': RAW_PASSPORT_DATA['data'][1]['data'],
69+
'front_side': RAW_PASSPORT_DATA['data'][1]['front_side'],
70+
'reverse_side': RAW_PASSPORT_DATA['data'][1]['reverse_side'],
71+
'selfie': RAW_PASSPORT_DATA['data'][1]['selfie']},
7472
{'type': 'address',
75-
'data': raw_passport_data['data'][2]['data']},
73+
'data': RAW_PASSPORT_DATA['data'][2]['data']},
7674
{'type': 'utility_bill',
77-
'files': raw_passport_data['data'][3]['files']},
75+
'files': RAW_PASSPORT_DATA['data'][3]['files']},
7876
{'type': 'bank_statement',
79-
'files': raw_passport_data['data'][3]['files']},
77+
'files': RAW_PASSPORT_DATA['data'][3]['files']},
8078
{'type': 'rental_agreement',
81-
'files': raw_passport_data['data'][3]['files']},
79+
'files': RAW_PASSPORT_DATA['data'][3]['files']},
8280
{'type': 'passport_registration',
83-
'files': raw_passport_data['data'][3]['files']},
81+
'files': RAW_PASSPORT_DATA['data'][3]['files']},
8482
{'type': 'temporary_registration',
85-
'files': raw_passport_data['data'][3]['files']},
83+
'files': RAW_PASSPORT_DATA['data'][3]['files']},
8684
{'type': 'email',
8785
'email': 'fb3e3i47zt@dispostable.com'},
8886
{'type': 'phone_number',
@@ -91,7 +89,7 @@ def all_passport_data():
9189

9290
@pytest.fixture(scope='function')
9391
def passport_data(bot):
94-
return PassportData.de_json(deepcopy(RAW_PASSPORT_DATA), bot=bot)
92+
return PassportData.de_json(RAW_PASSPORT_DATA, bot=bot)
9593

9694

9795
class TestPassport(object):
@@ -106,9 +104,37 @@ class TestPassport(object):
106104
def test_creation(self, passport_data):
107105
assert isinstance(passport_data, PassportData)
108106

109-
def test_expected_values(self, passport_data):
107+
def test_expected_encrypted_values(self, passport_data):
110108
personal_details, driver_license, address, utility_bill, email = passport_data.data
111109

110+
assert personal_details.type == 'personal_details'
111+
assert personal_details.data == RAW_PASSPORT_DATA['data'][0]['data']
112+
113+
assert driver_license.type == 'driver_license'
114+
assert driver_license.data == RAW_PASSPORT_DATA['data'][1]['data']
115+
assert isinstance(driver_license.selfie, PassportFile)
116+
assert driver_license.selfie.file_id == self.driver_license_selfie_file_id
117+
assert isinstance(driver_license.front_side, PassportFile)
118+
assert driver_license.front_side.file_id == self.driver_license_front_side_file_id
119+
assert isinstance(driver_license.reverse_side, PassportFile)
120+
assert driver_license.reverse_side.file_id == self.driver_license_reverse_side_file_id
121+
122+
assert address.type == 'address'
123+
assert address.data == RAW_PASSPORT_DATA['data'][2]['data']
124+
125+
assert utility_bill.type == 'utility_bill'
126+
assert isinstance(utility_bill.files[0], PassportFile)
127+
assert utility_bill.files[0].file_id == self.utility_bill_1_file_id
128+
assert isinstance(utility_bill.files[1], PassportFile)
129+
assert utility_bill.files[1].file_id == self.utility_bill_2_file_id
130+
131+
assert email.type == 'email'
132+
assert email.email == 'fb3e3i47zt@dispostable.com'
133+
134+
def test_expected_decrypted_values(self, passport_data):
135+
(personal_details, driver_license, address,
136+
utility_bill, email) = passport_data.decrypted_data
137+
112138
assert personal_details.type == 'personal_details'
113139
assert personal_details.data.to_dict() == {'gender': 'female',
114140
'residence_country_code': 'DK',
@@ -142,11 +168,11 @@ def test_expected_values(self, passport_data):
142168
assert email.email == 'fb3e3i47zt@dispostable.com'
143169

144170
def test_all_types(self, passport_data, bot, all_passport_data):
145-
credentials = passport_data.credentials.to_dict()
171+
credentials = passport_data.decrypted_credentials.to_dict()
146172

147173
# Copy credentials from other types to all types so we can decrypt everything
148-
sd = credentials['data']['secure_data']
149-
credentials['data']['secure_data'] = {
174+
sd = credentials['secure_data']
175+
credentials['secure_data'] = {
150176
'personal_details': sd['personal_details'].copy(),
151177
'passport': sd['driver_license'].copy(),
152178
'internal_passport': sd['driver_license'].copy(),
@@ -160,10 +186,16 @@ def test_all_types(self, passport_data, bot, all_passport_data):
160186
'temporary_registration': sd['utility_bill'].copy(),
161187
}
162188

163-
assert isinstance(PassportData.de_json({
189+
new = PassportData.de_json({
164190
'data': all_passport_data,
165-
'credentials': credentials
166-
}, bot=bot), PassportData)
191+
# Replaced below
192+
'credentials': {'data': 'data', 'hash': 'hash', 'secret': 'secret'}
193+
}, bot=bot)
194+
195+
new.credentials._decrypted_data = Credentials.de_json(credentials, bot)
196+
197+
assert isinstance(new, PassportData)
198+
assert new.decrypted_data
167199

168200
def test_bot_init_invalid_key(self, bot):
169201
with pytest.raises(TypeError):
@@ -172,61 +204,36 @@ def test_bot_init_invalid_key(self, bot):
172204
with pytest.raises(ValueError):
173205
Bot(bot.token, private_key=b'Invalid key!')
174206

175-
def test_passport_data_update_on_non_crypto_bot(self, bot):
207+
def test_passport_data_okay_with_non_crypto_bot(self, bot):
176208
b = Bot(bot.token)
177-
with pytest.warns(UserWarning):
178-
PassportData.de_json(deepcopy(RAW_PASSPORT_DATA), bot=b)
209+
assert PassportData.de_json(RAW_PASSPORT_DATA, bot=b)
179210

180211
def test_wrong_hash(self, bot):
181212
data = deepcopy(RAW_PASSPORT_DATA)
182213
data['credentials']['hash'] = b'notcorrecthash'
183-
with pytest.warns(UserWarning, match='Telegram passport decryption error: '
184-
'Hashes are not equal!'):
185-
PassportData.de_json(data, bot=bot)
186-
187-
def test_wrong_hash_in_updater(self, updater, dp, monkeypatch):
188-
# Make sure first call doesn't halt the updater by requiring two calls
189-
event = Event()
190-
event2 = Event()
191-
192-
def test(*args, **kwargs):
193-
if event.is_set():
194-
event2.set()
195-
else:
196-
event.set()
197-
data = deepcopy(RAW_PASSPORT_DATA)
198-
data['credentials']['hash'] = b'notcorrecthash'
199-
return [Update(1, passport_data=PassportData.de_json(data,
200-
bot=dp.bot))]
201-
202-
monkeypatch.setattr('telegram.Bot.get_updates', test)
203-
monkeypatch.setattr('telegram.Bot.set_webhook', lambda *args, **kwargs: True)
204-
with pytest.warns(UserWarning, match='Telegram passport decryption error: '
205-
'Hashes are not equal!'):
206-
updater.start_polling(0.01)
207-
event2.wait()
214+
passport_data = PassportData.de_json(data, bot=bot)
215+
with pytest.raises(TelegramDecryptionError):
216+
assert passport_data.decrypted_data
208217

209218
def test_wrong_key(self, bot):
210219
short_key = b"-----BEGIN RSA PRIVATE KEY-----\r\nMIIBOQIBAAJBAKU+OZ2jJm7sCA/ec4gngNZhXYPu+DZ/TAwSMl0W7vAPXAsLplBk\r\nO8l6IBHx8N0ZC4Bc65mO3b2G8YAzqndyqH8CAwEAAQJAWOx3jQFzeVXDsOaBPdAk\r\nYTncXVeIc6tlfUl9mOLyinSbRNCy1XicOiOZFgH1rRKOGIC1235QmqxFvdecySoY\r\nwQIhAOFeGgeX9CrEPuSsd9+kqUcA2avCwqdQgSdy2qggRFyJAiEAu7QHT8JQSkHU\r\nDELfzrzc24AhjyG0z1DpGZArM8COascCIDK42SboXj3Z2UXiQ0CEcMzYNiVgOisq\r\nBUd5pBi+2mPxAiAM5Z7G/Sv1HjbKrOGh29o0/sXPhtpckEuj5QMC6E0gywIgFY6S\r\nNjwrAA+cMmsgY0O2fAzEKkDc5YiFsiXaGaSS4eA=\r\n-----END RSA PRIVATE KEY-----"
211220
b = Bot(bot.token, private_key=short_key)
212-
data = deepcopy(RAW_PASSPORT_DATA)
213-
with pytest.warns(UserWarning, match='Telegram passport decryption error: Ciphertext '
214-
'length must be equal to key size'):
215-
PassportData.de_json(data, bot=b)
221+
passport_data = PassportData.de_json(RAW_PASSPORT_DATA, bot=b)
222+
with pytest.raises(TelegramDecryptionError):
223+
assert passport_data.decrypted_data
216224

217225
wrong_key = b"-----BEGIN RSA PRIVATE KEY-----\r\nMIIEogIBAAKCAQB4qCFltuvHakZze86TUweU7E/SB3VLGEHAe7GJlBmrou9SSWsL\r\nH7E++157X6UqWFl54LOE9MeHZnoW7rZ+DxLKhk6NwAHTxXPnvw4CZlvUPC3OFxg3\r\nhEmNen6ojSM4sl4kYUIa7F+Q5uMEYaboxoBen9mbj4zzMGsG4aY/xBOb2ewrXQyL\r\nRh//tk1Px4ago+lUPisAvQVecz7/6KU4Xj4Lpv2z20f3cHlZX6bb7HlE1vixCMOf\r\nxvfC5SkWEGZMR/ZoWQUsoDkrDSITF/S3GtLfg083TgtCKaOF3mCT27sJ1og77npP\r\n0cH/qdlbdoFtdrRj3PvBpaj/TtXRhmdGcJBxAgMBAAECggEAYSq1Sp6XHo8dkV8B\r\nK2/QSURNu8y5zvIH8aUrgqo8Shb7OH9bryekrB3vJtgNwR5JYHdu2wHttcL3S4SO\r\nftJQxbyHgmxAjHUVNGqOM6yPA0o7cR70J7FnMoKVgdO3q68pVY7ll50IET9/T0X9\r\nDrTdKFb+/eILFsXFS1NpeSzExdsKq3zM0sP/vlJHHYVTmZDGaGEvny/eLAS+KAfG\r\nrKP96DeO4C/peXEJzALZ/mG1ReBB05Qp9Dx1xEC20yreRk5MnnBA5oiHVG5ZLOl9\r\nEEHINidqN+TMNSkxv67xMfQ6utNu5IpbklKv/4wqQOJOO50HZ+qBtSurTN573dky\r\nzslbCQKBgQDHDUBYyKN/v69VLmvNVcxTgrOcrdbqAfefJXb9C3dVXhS8/oRkCRU/\r\ndzxYWNT7hmQyWUKor/izh68rZ/M+bsTnlaa7IdAgyChzTfcZL/2pxG9pq05GF1Q4\r\nBSJ896ZEe3jEhbpJXRlWYvz7455svlxR0H8FooCTddTmkU3nsQSx0wKBgQCbLSa4\r\nyZs2QVstQQerNjxAtLi0IvV8cJkuvFoNC2Q21oqQc7BYU7NJL7uwriprZr5nwkCQ\r\nOFQXi4N3uqimNxuSng31ETfjFZPp+pjb8jf7Sce7cqU66xxR+anUzVZqBG1CJShx\r\nVxN7cWN33UZvIH34gA2Ax6AXNnJG42B5Gn1GKwKBgQCZ/oh/p4nGNXfiAK3qB6yy\r\nFvX6CwuvsqHt/8AUeKBz7PtCU+38roI/vXF0MBVmGky+HwxREQLpcdl1TVCERpIT\r\nUFXThI9OLUwOGI1IcTZf9tby+1LtKvM++8n4wGdjp9qAv6ylQV9u09pAzZItMwCd\r\nUx5SL6wlaQ2y60tIKk0lfQKBgBJS+56YmA6JGzY11qz+I5FUhfcnpauDNGOTdGLT\r\n9IqRPR2fu7RCdgpva4+KkZHLOTLReoRNUojRPb4WubGfEk93AJju5pWXR7c6k3Bt\r\novS2mrJk8GQLvXVksQxjDxBH44sLDkKMEM3j7uYJqDaZNKbyoCWT7TCwikAau5qx\r\naRevAoGAAKZV705dvrpJuyoHFZ66luANlrAwG/vNf6Q4mBEXB7guqMkokCsSkjqR\r\nhsD79E6q06zA0QzkLCavbCn5kMmDS/AbA80+B7El92iIN6d3jRdiNZiewkhlWhEG\r\nm4N0gQRfIu+rUjsS/4xk8UuQUT/Ossjn/hExi7ejpKdCc7N++bc=\r\n-----END RSA PRIVATE KEY-----"
218226
b = Bot(bot.token, private_key=wrong_key)
219-
data = deepcopy(RAW_PASSPORT_DATA)
220-
with pytest.warns(UserWarning, match='Telegram passport decryption error: '
221-
'Decryption failed.'):
222-
PassportData.de_json(data, bot=b)
227+
passport_data = PassportData.de_json(RAW_PASSPORT_DATA, bot=b)
228+
with pytest.raises(TelegramDecryptionError):
229+
assert passport_data.decrypted_data
223230

224231
def test_mocked_download_passport_file(self, passport_data, monkeypatch):
225232
# The files are not coming from our test bot, therefore the file id is invalid/wrong
226233
# when coming from this bot, so we monkeypatch the call, to make sure that Bot.get_file
227234
# at least gets called
228235
# TODO: Actually download a passport file in a test
229-
selfie = passport_data.data[1].selfie
236+
selfie = passport_data.decrypted_data[1].selfie
230237

231238
def get_file(*args, **kwargs):
232239
return File(args[1])
@@ -240,25 +247,34 @@ def get_file(*args, **kwargs):
240247
def test_mocked_set_passport_data_errors(self, monkeypatch, bot, chat_id, passport_data):
241248
def test(_, url, data, **kwargs):
242249
return (data['user_id'] == chat_id and
243-
data['errors'][0]['file_hash'] == (passport_data.credentials.data.secure_data
244-
.driver_license.selfie.file_hash) and
245-
data['errors'][1]['data_hash'] == (passport_data.credentials.data.secure_data
246-
.driver_license.data.data_hash))
250+
data['errors'][0]['file_hash'] == (passport_data.decrypted_credentials
251+
.secure_data.driver_license
252+
.selfie.file_hash) and
253+
data['errors'][1]['data_hash'] == (passport_data.decrypted_credentials
254+
.secure_data.driver_license
255+
.data.data_hash))
247256

248257
monkeypatch.setattr('telegram.utils.request.Request.post', test)
249258
message = bot.set_passport_data_errors(chat_id, [
250259
PassportElementErrorSelfie('driver_license',
251-
(passport_data.credentials.data
260+
(passport_data.decrypted_credentials
252261
.secure_data.driver_license.selfie.file_hash),
253262
'You\'re not handsome enough to use this app!'),
254263
PassportElementErrorDataField('driver_license',
255264
'expiry_date',
256-
(passport_data.credentials.data
265+
(passport_data.decrypted_credentials
257266
.secure_data.driver_license.data.data_hash),
258267
'Your driver license is expired!')
259268
])
260269
assert message
261270

271+
def test_de_json_and_to_dict(self, bot):
272+
passport_data = PassportData.de_json(RAW_PASSPORT_DATA, bot)
273+
assert passport_data.to_dict() == RAW_PASSPORT_DATA
274+
275+
assert passport_data.decrypted_data
276+
assert passport_data.to_dict() == RAW_PASSPORT_DATA
277+
262278
def test_equality(self, passport_data):
263279
a = PassportData(passport_data.data, passport_data.credentials)
264280
b = PassportData(passport_data.data, passport_data.credentials)

0 commit comments

Comments
 (0)