From 9a5ceb2c0d5316b2ebf455ce946c1d5ff7ed84fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20=C5=BBydek?= Date: Mon, 7 Oct 2024 12:11:18 +0200 Subject: [PATCH] test: fix tests --- .../get_event_200_with_broken_format.json | 283 ++++++++++++++++++ test/test_fingerprint_api.py | 27 +- test/test_sealed.py | 105 ++++++- 3 files changed, 392 insertions(+), 23 deletions(-) create mode 100644 test/mocks/get_event_200_with_broken_format.json diff --git a/test/mocks/get_event_200_with_broken_format.json b/test/mocks/get_event_200_with_broken_format.json new file mode 100644 index 00000000..4ac8b6f5 --- /dev/null +++ b/test/mocks/get_event_200_with_broken_format.json @@ -0,0 +1,283 @@ +{ + "products": { + "identification": { + "data": { + "visitorId": "Ibk1527CUFmcnjLwIs4A9", + "requestId": "1708102555327.NLOjmg", + "incognito": true, + "linkedId": { + "broken": "format" + }, + "tag": {}, + "time": "2019-05-21T16:40:13Z", + "timestamp": 1582299576512, + "url": "https://www.example.com/login?hope{this{works[!", + "ip": "61.127.217.15", + "ipLocation": { + "accuracyRadius": 10, + "latitude": 49.982, + "longitude": 36.2566, + "postalCode": "61202", + "timezone": "Europe/Dusseldorf", + "city": { + "name": "Dusseldorf" + }, + "country": { + "code": "DE", + "name": "Germany" + }, + "continent": { + "code": "EU", + "name": "Europe" + }, + "subdivisions": [ + { + "isoCode": "63", + "name": "North Rhine-Westphalia" + } + ] + }, + "browserDetails": { + "browserName": "Chrome", + "browserMajorVersion": "74", + "browserFullVersion": "74.0.3729", + "os": "Windows", + "osVersion": "7", + "device": "Other", + "userAgent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) ...." + }, + "confidence": { + "score": 0.97 + }, + "visitorFound": false, + "firstSeenAt": { + "global": "2022-03-16T11:26:45.362Z", + "subscription": "2022-03-16T11:31:01.101Z" + }, + "lastSeenAt": { + "global": null, + "subscription": null + } + } + }, + "botd": { + "data": { + "bot": { + "result": "notDetected" + }, + "url": "https://www.example.com/login?hope{this{works}[!", + "ip": "61.127.217.15", + "time": "2019-05-21T16:40:13Z", + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 YaBrowser/24.1.0.0 Safari/537.36", + "requestId": "1708102555327.NLOjmg" + } + }, + "rootApps": { + "data": { + "result": false + } + }, + "emulator": { + "data": { + "result": false + } + }, + "ipInfo": { + "data": { + "v4": { + "address": "94.142.239.124", + "geolocation": { + "accuracyRadius": 20, + "latitude": 50.05, + "longitude": 14.4, + "postalCode": "150 00", + "timezone": "Europe/Prague", + "city": { + "name": "Prague" + }, + "country": { + "code": "CZ", + "name": "Czechia" + }, + "continent": { + "code": "EU", + "name": "Europe" + }, + "subdivisions": [ + { + "isoCode": "10", + "name": "Hlavni mesto Praha" + } + ] + }, + "asn": { + "asn": "7922", + "name": "COMCAST-7922", + "network": "73.136.0.0/13" + }, + "datacenter": { + "result": true, + "name": "DediPath" + } + }, + "v6": { + "address": "2001:db8:3333:4444:5555:6666:7777:8888", + "geolocation": { + "accuracyRadius": 5, + "latitude": 49.982, + "longitude": 36.2566, + "postalCode": "10112", + "timezone": "Europe/Berlin", + "city": { + "name": "Berlin" + }, + "country": { + "code": "DE", + "name": "Germany" + }, + "continent": { + "code": "EU", + "name": "Europe" + }, + "subdivisions": [ + { + "isoCode": "BE", + "name": "Land Berlin" + } + ] + }, + "asn": { + "asn": "6805", + "name": "Telefonica Germany", + "network": "2a02:3100::/24" + }, + "datacenter": { + "result": false, + "name": "" + } + } + } + }, + "ipBlocklist": { + "data": { + "result": false, + "details": { + "emailSpam": false, + "attackSource": false + } + } + }, + "tor": { + "data": { + "result": false + } + }, + "vpn": { + "data": { + "result": false, + "originTimezone": "Europe/Berlin", + "originCountry": "unknown", + "methods": { + "timezoneMismatch": false, + "publicVPN": false, + "auxiliaryMobile": false + } + } + }, + "proxy": { + "data": { + "result": false + } + }, + "incognito": { + "data": { + "result": false + } + }, + "tampering": { + "data": { + "result": false, + "anomalyScore": 0.1955 + } + }, + "clonedApp": { + "data": { + "result": false + } + }, + "factoryReset": { + "data": { + "time": "1970-01-01T00:00:00Z", + "timestamp": 0 + } + }, + "jailbroken": { + "data": { + "result": false + } + }, + "frida": { + "data": { + "result": false + } + }, + "privacySettings": { + "data": { + "result": false + } + }, + "virtualMachine": { + "data": { + "result": false + } + }, + "rawDeviceAttributes": { + "data": { + "architecture": { + "value": 127 + }, + "audio": { + "value": 35.73832903057337 + }, + "canvas": { + "value": { + "Winding": true, + "Geometry": "4dce9d6017c3e0c052a77252f29f2b1c", + "Text": "dd2474a56ff78c1de3e7a07070ba3b7d" + } + }, + "colorDepth": { + "value": 30 + }, + "colorGamut": { + "value": "p3" + }, + "contrast": { + "value": 0 + }, + "cookiesEnabled": { + "value": true + }, + "cpuClass": {}, + "fonts": { + "value": [ + "Arial Unicode MS", + "Gill Sans", + "Helvetica Neue", + "Menlo" + ] + } + } + }, + "highActivity": { + "data": { + "result": false + } + }, + "locationSpoofing": { + "data": { + "result": false + } + } + } +} diff --git a/test/test_fingerprint_api.py b/test/test_fingerprint_api.py index ddee452b..7e494a4c 100644 --- a/test/test_fingerprint_api.py +++ b/test/test_fingerprint_api.py @@ -11,6 +11,7 @@ """ import io +import os import unittest import urllib3 @@ -30,9 +31,14 @@ class MockPoolManager(object): - def __init__(self, tc): + + + def __init__(self, tc, request_headers=None): + if request_headers is None: + request_headers = {} self._tc = tc self._reqs = [] + self.request_headers = request_headers def expect_request(self, *args, **kwargs): self._reqs.append((args, kwargs)) @@ -72,14 +78,15 @@ def request(self, *args, **kwargs): if mock_file_by_first_argument == 'update_event': return urllib3.HTTPResponse(status=200, body='OK') try: - with io.open('./test/mocks/' + mock_file_by_first_argument, 'r', encoding='utf-8') as mock_file: + path = './test/mocks/' + mock_file_by_first_argument + + if not os.path.isfile(path): + path = './test/mocks/shared/' + mock_file_by_first_argument + + with io.open(path, 'r', encoding='utf-8') as mock_file: answer_mock = mock_file.read() mock_file.close() - headers = {} - if mock_file_by_first_argument == 'get_visits_429_too_many_requests_error.json': - headers.update({'Retry-After': '4'}) - - return urllib3.HTTPResponse(status=status, body=answer_mock, headers=headers) + return urllib3.HTTPResponse(status=status, body=answer_mock, headers=self.request_headers) except IOError as e: print(e) return urllib3.HTTPResponse(status=200, body='{"visitorId": "%s", "visits": []}' % mock_file_by_first_argument) @@ -161,7 +168,7 @@ def test_get_visits_error_403(self): def test_get_visits_error_429(self): """Test checks correct code run result in case of 429 error for get_visits method""" - mock_pool = MockPoolManager(self) + mock_pool = MockPoolManager(self, request_headers={'Retry-After': '4'}) self.api.api_client.rest_client.pool_manager = mock_pool mock_file = 'get_visits_429_too_many_requests_error.json' mock_pool.expect_request('GET', TestFingerprintApi.get_visitors_path(visitor_id=mock_file), @@ -177,7 +184,7 @@ def test_get_visits_error_429_empty_retry_after(self): """Test checks retry after value in exception in case of 429 error for get_visits method""" mock_pool = MockPoolManager(self) self.api.api_client.rest_client.pool_manager = mock_pool - mock_file = 'get_visits_429_too_many_requests_error_empty_header.json' + mock_file = 'get_visits_429_too_many_requests_error.json' mock_pool.expect_request('GET', TestFingerprintApi.get_visitors_path(visitor_id=mock_file), fields=[self.integration_info], headers=self.request_headers, preload_content=True, timeout=None, status=429) @@ -501,7 +508,7 @@ def test_get_event_wrong_shape(self): mock_pool = MockPoolManager(self) self.api.api_client.rest_client.pool_manager = mock_pool - mock_file = 'get_event_200_wrong_shape.json' + mock_file = 'get_event_200_with_broken_format.json' mock_pool.expect_request('GET', TestFingerprintApi.get_events_path(request_id=mock_file), fields=[self.integration_info], headers=self.request_headers, preload_content=True, timeout=None) diff --git a/test/test_sealed.py b/test/test_sealed.py index 658f870c..f8023114 100644 --- a/test/test_sealed.py +++ b/test/test_sealed.py @@ -2,6 +2,7 @@ import io import json import unittest +from unittest import expectedFailure from fingerprint_pro_server_api_sdk import ApiClientDeserializer, DecryptionAlgorithm, DecryptionKey, \ unseal_event_response, UnsealError, UnsealAggregateError, EventResponse, ProductsResponse, \ @@ -12,22 +13,100 @@ class TestSealed(unittest.TestCase): invalid_key = base64.b64decode('a2PA7MGy5tx56cnyJaFZMr96BCFwZeHjZV2EqMvTq53=') def test_unseal_aes256gcm(self): - with io.open("./test/mocks/sealed_result.json", 'r', encoding='utf-8') as f: - expected_result = ApiClientDeserializer.deserialize(json.load(f), 'EventResponse') + sealed_result = '''{ + "products": { + "identification": { + "data": { + "visitorId": "2ZEDCZEfOfXjEmMuE3tq", + "requestId": "1703067132750.Z5hutJ", + "browserDetails": { + "browserName": "Safari", + "browserMajorVersion": "17", + "browserFullVersion": "17.3", + "os": "Mac OS X", + "osVersion": "10.15.7", + "device": "Other", + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.3 Safari/605.1.15" + }, + "incognito": false, + "ip": "::1", + "ipLocation": { + "accuracyRadius": 1000, + "latitude": 59.3241, + "longitude": 18.0517, + "postalCode": "100 05", + "timezone": "Europe/Stockholm", + "city": { + "name": "Stockholm" + }, + "country": { + "code": "SE", + "name": "Sweden" + }, + "continent": { + "code": "EU", + "name": "Europe" + }, + "subdivisions": [ + { + "isoCode": "AB", + "name": "Stockholm County" + } + ] + }, + "timestamp": 1703067136286, + "time": "2023-12-20T10:12:16Z", + "url": "http://localhost:8080/", + "tag": { + "foo": "bar" + }, + "confidence": { + "score": 1 + }, + "visitorFound": true, + "firstSeenAt": { + "global": "2023-12-15T12:13:55.103Z", + "subscription": "2023-12-15T12:13:55.103Z" + }, + "lastSeenAt": { + "global": "2023-12-19T11:39:51.52Z", + "subscription": "2023-12-19T11:39:51.52Z" + } + } + }, + "botd": { + "data": { + "bot": { + "result": "notDetected" + }, + "meta": { + "foo": "bar" + }, + "url": "http://localhost:8080/", + "ip": "::1", + "time": "2023-12-20T10:12:13.894Z", + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.3 Safari/605.1.15", + "requestId": "1703067132750.Z5hutJ" + } + } + } +}''' + expected_result = ApiClientDeserializer.deserialize(json.loads(sealed_result), 'EventResponse') - sealed_data = base64.b64decode( - 'noXc7SXO+mqeAGrvBMgObi/S0fXTpP3zupk8qFqsO/1zdtWCD169iLA3VkkZh9ICHpZ0oWRzqG0M9/TnCeKFohgBLqDp6O0zEfXOv6i5q++aucItznQdLwrKLP+O0blfb4dWVI8/aSbd4ELAZuJJxj9bCoVZ1vk+ShbUXCRZTD30OIEAr3eiG9aw00y1UZIqMgX6CkFlU9L9OnKLsNsyomPIaRHTmgVTI5kNhrnVNyNsnzt9rY7fUD52DQxJILVPrUJ1Q+qW7VyNslzGYBPG0DyYlKbRAomKJDQIkdj/Uwa6bhSTq4XYNVvbk5AJ/dGwvsVdOnkMT2Ipd67KwbKfw5bqQj/cw6bj8Cp2FD4Dy4Ud4daBpPRsCyxBM2jOjVz1B/lAyrOp8BweXOXYugwdPyEn38MBZ5oL4D38jIwR/QiVnMHpERh93jtgwh9Abza6i4/zZaDAbPhtZLXSM5ztdctv8bAb63CppLU541Kf4OaLO3QLvfLRXK2n8bwEwzVAqQ22dyzt6/vPiRbZ5akh8JB6QFXG0QJF9DejsIspKF3JvOKjG2edmC9o+GfL3hwDBiihYXCGY9lElZICAdt+7rZm5UxMx7STrVKy81xcvfaIp1BwGh/HyMsJnkE8IczzRFpLlHGYuNDxdLoBjiifrmHvOCUDcV8UvhSV+UAZtAVejdNGo5G/bz0NF21HUO4pVRPu6RqZIs/aX4hlm6iO/0Ru00ct8pfadUIgRcephTuFC2fHyZxNBC6NApRtLSNLfzYTTo/uSjgcu6rLWiNo5G7yfrM45RXjalFEFzk75Z/fu9lCJJa5uLFgDNKlU+IaFjArfXJCll3apbZp4/LNKiU35ZlB7ZmjDTrji1wLep8iRVVEGht/DW00MTok7Zn7Fv+MlxgWmbZB3BuezwTmXb/fNw==') + sealed_data = base64.b64decode( + 'noXc7SXO+mqeAGrvBMgObi/S0fXTpP3zupk8qFqsO/1zdtWCD169iLA3VkkZh9ICHpZ0oWRzqG0M9/TnCeKFohgBLqDp6O0zEfXOv6i5q++aucItznQdLwrKLP+O0blfb4dWVI8/aSbd4ELAZuJJxj9bCoVZ1vk+ShbUXCRZTD30OIEAr3eiG9aw00y1UZIqMgX6CkFlU9L9OnKLsNsyomPIaRHTmgVTI5kNhrnVNyNsnzt9rY7fUD52DQxJILVPrUJ1Q+qW7VyNslzGYBPG0DyYlKbRAomKJDQIkdj/Uwa6bhSTq4XYNVvbk5AJ/dGwvsVdOnkMT2Ipd67KwbKfw5bqQj/cw6bj8Cp2FD4Dy4Ud4daBpPRsCyxBM2jOjVz1B/lAyrOp8BweXOXYugwdPyEn38MBZ5oL4D38jIwR/QiVnMHpERh93jtgwh9Abza6i4/zZaDAbPhtZLXSM5ztdctv8bAb63CppLU541Kf4OaLO3QLvfLRXK2n8bwEwzVAqQ22dyzt6/vPiRbZ5akh8JB6QFXG0QJF9DejsIspKF3JvOKjG2edmC9o+GfL3hwDBiihYXCGY9lElZICAdt+7rZm5UxMx7STrVKy81xcvfaIp1BwGh/HyMsJnkE8IczzRFpLlHGYuNDxdLoBjiifrmHvOCUDcV8UvhSV+UAZtAVejdNGo5G/bz0NF21HUO4pVRPu6RqZIs/aX4hlm6iO/0Ru00ct8pfadUIgRcephTuFC2fHyZxNBC6NApRtLSNLfzYTTo/uSjgcu6rLWiNo5G7yfrM45RXjalFEFzk75Z/fu9lCJJa5uLFgDNKlU+IaFjArfXJCll3apbZp4/LNKiU35ZlB7ZmjDTrji1wLep8iRVVEGht/DW00MTok7Zn7Fv+MlxgWmbZB3BuezwTmXb/fNw==') - result = unseal_event_response(sealed_data, [ - DecryptionKey(self.invalid_key, DecryptionAlgorithm['Aes256Gcm']), - DecryptionKey(self.valid_key, DecryptionAlgorithm['Aes256Gcm']), - ]) + result = unseal_event_response(sealed_data, [ + DecryptionKey(self.invalid_key, DecryptionAlgorithm['Aes256Gcm']), + DecryptionKey(self.valid_key, DecryptionAlgorithm['Aes256Gcm']), + ]) + + self.assertEqual(result, expected_result) + self.assertIsInstance(result, EventResponse) + self.assertIsInstance(result.products, ProductsResponse) + self.assertIsInstance(result.products.identification, ProductsResponseIdentification) + self.assertIsInstance(result.products.identification.data.browser_details, BrowserDetails) - self.assertEqual(result, expected_result) - self.assertIsInstance(result, EventResponse) - self.assertIsInstance(result.products, ProductsResponse) - self.assertIsInstance(result.products.identification, ProductsResponseIdentification) - self.assertIsInstance(result.products.identification.data.browser_details, BrowserDetails) def test_unseal_invalid_header(self): sealed_data = base64.b64decode(