diff --git a/.env_example b/.env_example index 4438f80..6e042bc 100644 --- a/.env_example +++ b/.env_example @@ -1,2 +1,3 @@ HOST=0.0.0.0 -PORT=8050 \ No newline at end of file +PORT=8050 +USER_FILE_PATH='file/path/user.json' \ No newline at end of file diff --git a/.gitignore b/.gitignore index f1d79e3..4e7ff0b 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,6 @@ data/ *__pycache__/ *.pyc ./.pytest_cache -.env \ No newline at end of file +.env +.vscode +.pytest_cache \ No newline at end of file diff --git a/app/importers/UserImporter.py b/app/importers/UserImporter.py new file mode 100644 index 0000000..1747d2e --- /dev/null +++ b/app/importers/UserImporter.py @@ -0,0 +1,19 @@ +import os +import json + +from app.tools.Logger import logger + +class UserImporter: + def __init__(self): + self.user_file_path = os.environ.get("USER_FILE_PATH") + if self.user_file_path is None: + raise Exception("USER_FILE_PATH environment variable is not set.") + + if '.json' not in self.user_file_path: + raise Exception("The user file needs to be a JSON file.") + + with open(self.user_file_path, 'r') as file: + user_data = json.load(file) + logger.info(f"Imported user data from {self.user_file_path}.") + + self.user_data = user_data \ No newline at end of file diff --git a/app/importers/__init__.py b/app/importers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/importers/__init__.py b/tests/importers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/importers/test_UserImporter.py b/tests/importers/test_UserImporter.py new file mode 100644 index 0000000..93e3196 --- /dev/null +++ b/tests/importers/test_UserImporter.py @@ -0,0 +1,85 @@ +import pytest +import os +import json +from unittest.mock import mock_open, patch + +from app.importers.UserImporter import UserImporter + + +######################################################################################### +# test values +######################################################################################### +USER_FILE_PATH = "fake/file/path/users.json" +USER_DATA = ''' +{ + "devices": [ + { + "ip_address": "174.234.168.00", + "device_model": "unknown", + "device_platform": "ios", + "device_os_versions": "16.5.1" + } + ], + "account": { + "signup_time": "2001-06-29 03:27:17.539", + "last_pause_time": "2003-09-04 03:04:32", + "last_unpause_time": "2020-12-10 16:53:40", + "last_seen": "2024-01-17 04:07:39", + "device_platform": "ios", + "device_os": "16.6.1", + "device_model": "unknown", + "app_version": "9.30.0", + "push_notifications_enabled": false + } +} +''' + +######################################################################################### +# pytest fixtures +######################################################################################### +@pytest.fixture +def user_importer(monkeypatch): + monkeypatch.setenv("USER_FILE_PATH", USER_FILE_PATH) + + with patch("builtins.open", mock_open(read_data=USER_DATA)) as mock_file, \ + patch("json.load", return_value=json.loads(USER_DATA)) as mock_json_load: + + user_importer = UserImporter() + return user_importer + + +######################################################################################### +# unit tests +######################################################################################### +def test_exists(user_importer): + assert user_importer is not None + +def test_user_file_path_not_set(): + if "USER_FILE_PATH" in os.environ: + del os.environ["USER_FILE_PATH"] + + with pytest.raises(Exception, match="USER_FILE_PATH environment variable is not set."): + UserImporter() + +def test_user_file_not_json(): + os.environ["USER_FILE_PATH"] = "invalid_file.txt" # invalid value + + with pytest.raises(Exception, match="The user file needs to be a JSON file."): + UserImporter() + +def test_user_importer_loads_data(user_importer): + assert isinstance(user_importer.user_data, dict) + assert "devices" in user_importer.user_data + assert "account" in user_importer.user_data + +def test_device_data(user_importer): + device = user_importer.user_data["devices"][0] + assert device["ip_address"] == "174.234.168.00" + assert device["device_platform"] == "ios" + assert device["device_os_versions"] == "16.5.1" + +def test_account_data(user_importer): + account = user_importer.user_data["account"] + assert account["device_os"] == "16.6.1" + assert account["app_version"] == "9.30.0" + assert account["push_notifications_enabled"] is False diff --git a/tests/test_MatchAnalytics.py b/tests/test_MatchAnalytics.py deleted file mode 100644 index fa706d2..0000000 --- a/tests/test_MatchAnalytics.py +++ /dev/null @@ -1,36 +0,0 @@ -import unittest -import app.analytics.MatchAnalytics as MatchAnalytics - -USER_FILE_PATH = 'tests/test_user.json' -MATCHES_FILE_PATH = 'tests/test_matches.json' - - -class AnalyticsTest(unittest.TestCase): - def test_total_event_count(self): - test_events = MatchAnalytics.prepare_uploaded_match_data(MATCHES_FILE_PATH) - total_events = MatchAnalytics.total_counts(test_events) - self.assertEqual(total_events.size, 8) - - def test_invalid_file_type(self): - with self.assertRaises(ValueError): - MatchAnalytics.prepare_uploaded_match_data('tests/matches.csv') - - def test_invalid_match_file_upload(self): - with self.assertRaises(ValueError): - MatchAnalytics.prepare_uploaded_match_data(USER_FILE_PATH) - - def test_invalid_user_file_upload(self): - with self.assertRaises(ValueError): - MatchAnalytics.import_user_account_data(MATCHES_FILE_PATH) - - def test_account_data_import(self): - results = MatchAnalytics.import_user_account_data(USER_FILE_PATH) - self.assertEqual(len(results), 9) # 9 keys in the dictionary - - def test_device_data_import(self): - results = MatchAnalytics.import_user_device_data(USER_FILE_PATH) - self.assertEqual(len(results), 5) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/test_matches.json b/tests/test_matches.json deleted file mode 100644 index 158d0e0..0000000 --- a/tests/test_matches.json +++ /dev/null @@ -1,126 +0,0 @@ -[ - { - "like": [ - { - "content": "[{\"photo\":{\"url\":\"test_data/sulley_sunglasses.jpg\",\"boundingBox\":{\"bottomRight\":{\"x\":1.0,\"y\":1.0},\"topLeft\":{\"x\":0.0,\"y\":0.0}},\"caption\":\"\",\"location\":\"\",\"promptId\":\"\",\"cdnId\":\"hfy4sksrpr6anuhyr7l2\",\"contentId\":\"f85e0278-554c-41d3-9f52-6cc217c90ee9\"},\"prompt\":{\"question\":\"\",\"answer\":\"\"},\"comment\":\"Love the sleeve!\",\"video\":{\"url\":\"\",\"thumbnail\":\"\",\"boundingBox\":{\"bottomRight\":{\"x\":0.0,\"y\":0.0},\"topLeft\":{\"x\":0.0,\"y\":0.0}},\"caption\":\"\",\"location\":\"\",\"promptId\":\"\",\"cdnId\":\"\",\"contentId\":\"\"},\"voicePrompt\":{\"question\":\"\",\"url\":\"\",\"waveform\":\"\",\"cdnId\":\"\"},\"promptPoll\":{\"contentId\":\"\",\"questionId\":\"\",\"options\":[],\"selectedOptionIndex\":{\"int\":0},\"selectedOption\":\"\"},\"videoPrompt\":{\"contentId\":\"\",\"cdnId\":\"\",\"videoUrl\":\"\",\"questionId\":\"\",\"thumbnailUrl\":\"\",\"boundingBox\":{\"bottomRight\":{\"x\":0.0,\"y\":0.0},\"topLeft\":{\"x\":0.0,\"y\":0.0}}}}]", - "timestamp": "2023-10-08 22:51:39", - "like": [ - { - "timestamp": "2023-10-08 22:51:39", - "comment": "Hello, World!" - } - ], - "type": "like" - } - ] - }, - { - "like": [ - { - "content": "[{\"photo\":{\"url\":\"test_data/sulley_sunglasses.jpg\",\"boundingBox\":{\"bottomRight\":{\"x\":1.0,\"y\":1.0},\"topLeft\":{\"x\":0.0,\"y\":0.0}},\"caption\":\"\",\"location\":\"\",\"promptId\":\"\",\"cdnId\":\"hfy4sksrpr6anuhyr7l2\",\"contentId\":\"f85e0278-554c-41d3-9f52-6cc217c90ee9\"},\"prompt\":{\"question\":\"\",\"answer\":\"\"},\"comment\":\"Love the sleeve!\",\"video\":{\"url\":\"\",\"thumbnail\":\"\",\"boundingBox\":{\"bottomRight\":{\"x\":0.0,\"y\":0.0},\"topLeft\":{\"x\":0.0,\"y\":0.0}},\"caption\":\"\",\"location\":\"\",\"promptId\":\"\",\"cdnId\":\"\",\"contentId\":\"\"},\"voicePrompt\":{\"question\":\"\",\"url\":\"\",\"waveform\":\"\",\"cdnId\":\"\"},\"promptPoll\":{\"contentId\":\"\",\"questionId\":\"\",\"options\":[],\"selectedOptionIndex\":{\"int\":0},\"selectedOption\":\"\"},\"videoPrompt\":{\"contentId\":\"\",\"cdnId\":\"\",\"videoUrl\":\"\",\"questionId\":\"\",\"thumbnailUrl\":\"\",\"boundingBox\":{\"bottomRight\":{\"x\":0.0,\"y\":0.0},\"topLeft\":{\"x\":0.0,\"y\":0.0}}}}]", - "timestamp": "2023-10-09 22:51:39", - "like": [ - { - "timestamp": "2023-10-08 22:51:39", - "comment": "Hello, World again!" - } - ], - "type": "like" - } - ] - }, - { - "like": [ - { - "content": "[{\"photo\":{\"url\":\"test_data/sulley_sunglasses.jpg\",\"boundingBox\":{\"bottomRight\":{\"x\":1.0,\"y\":1.0},\"topLeft\":{\"x\":0.0,\"y\":0.0}},\"caption\":\"\",\"location\":\"\",\"promptId\":\"\",\"cdnId\":\"hfy4sksrpr6anuhyr7l2\",\"contentId\":\"f85e0278-554c-41d3-9f52-6cc217c90ee9\"},\"prompt\":{\"question\":\"\",\"answer\":\"\"},\"comment\":\"Love the sleeve!\",\"video\":{\"url\":\"\",\"thumbnail\":\"\",\"boundingBox\":{\"bottomRight\":{\"x\":0.0,\"y\":0.0},\"topLeft\":{\"x\":0.0,\"y\":0.0}},\"caption\":\"\",\"location\":\"\",\"promptId\":\"\",\"cdnId\":\"\",\"contentId\":\"\"},\"voicePrompt\":{\"question\":\"\",\"url\":\"\",\"waveform\":\"\",\"cdnId\":\"\"},\"promptPoll\":{\"contentId\":\"\",\"questionId\":\"\",\"options\":[],\"selectedOptionIndex\":{\"int\":0},\"selectedOption\":\"\"},\"videoPrompt\":{\"contentId\":\"\",\"cdnId\":\"\",\"videoUrl\":\"\",\"questionId\":\"\",\"thumbnailUrl\":\"\",\"boundingBox\":{\"bottomRight\":{\"x\":0.0,\"y\":0.0},\"topLeft\":{\"x\":0.0,\"y\":0.0}}}}]", - "timestamp": "2023-11-10 22:51:39", - "like": [ - { - "timestamp": "2023-11-10 22:51:39", - "comment": "Hi there!" - } - ], - "type": "like" - } - ] - }, - { - "like": [ - { - "content": "[{\"photo\":{\"url\":\"test_data/sulley_sunglasses.jpg\",\"boundingBox\":{\"bottomRight\":{\"x\":1.0,\"y\":1.0},\"topLeft\":{\"x\":0.0,\"y\":0.0}},\"caption\":\"\",\"location\":\"\",\"promptId\":\"\",\"cdnId\":\"hfy4sksrpr6anuhyr7l2\",\"contentId\":\"f85e0278-554c-41d3-9f52-6cc217c90ee9\"},\"prompt\":{\"question\":\"\",\"answer\":\"\"},\"comment\":\"Love the sleeve!\",\"video\":{\"url\":\"\",\"thumbnail\":\"\",\"boundingBox\":{\"bottomRight\":{\"x\":0.0,\"y\":0.0},\"topLeft\":{\"x\":0.0,\"y\":0.0}},\"caption\":\"\",\"location\":\"\",\"promptId\":\"\",\"cdnId\":\"\",\"contentId\":\"\"},\"voicePrompt\":{\"question\":\"\",\"url\":\"\",\"waveform\":\"\",\"cdnId\":\"\"},\"promptPoll\":{\"contentId\":\"\",\"questionId\":\"\",\"options\":[],\"selectedOptionIndex\":{\"int\":0},\"selectedOption\":\"\"},\"videoPrompt\":{\"contentId\":\"\",\"cdnId\":\"\",\"videoUrl\":\"\",\"questionId\":\"\",\"thumbnailUrl\":\"\",\"boundingBox\":{\"bottomRight\":{\"x\":0.0,\"y\":0.0},\"topLeft\":{\"x\":0.0,\"y\":0.0}}}}]", - "timestamp": "2023-09-09 22:51:39", - "like": [ - { - "timestamp": "2023-10-08 22:51:39", - "comment": "Hi!" - } - ], - "type": "like" - } - ] - }, - { - "like": [ - { - "timestamp": "2023-07-15T12:54:04", - "type": "like" - } - ] - }, - { - "like": [ - { - "timestamp": "2023-07-20T12:54:04", - "type": "like" - } - ] - }, - { - "like": [ - { - "timestamp": "2023-07-25T12:54:04", - "type": "like" - } - ] - }, - { - "like": [ - { - "timestamp": "2023-07-30T12:54:04", - "type": "like" - } - ] - }, - { - "block": [ - { - "block_type": "remove", - "timestamp": "2023-08-17T13:25:48", - "type": "block" - } - ], - "chats": [ - { - "body": "Hello", - "timestamp": "2023-08-08T23:42:01", - "type": "chats" - }, - { - "body": "How are you?", - "timestamp": "2023-08-10T04:09:26", - "type": "chats" - }, - { - "body": "Let's grab coffee. My number is 555-555-5555", - "timestamp": "2023-08-12T04:04:52", - "type": "chats" - } - ], - "match": [ - { - "timestamp": "2023-08-08T23:41:29", - "type": "match" - } - ] - } -] \ No newline at end of file diff --git a/tests/test_user.json b/tests/test_user.json deleted file mode 100644 index 257a071..0000000 --- a/tests/test_user.json +++ /dev/null @@ -1,157 +0,0 @@ -{ - "devices": [ - { - "ip_address": "174.242.128.24", - "device_model": "unknown", - "device_platform": "ios", - "device_os_versions": "16.5.1" - }, - { - "ip_address": "174.231.89.0", - "device_model": "unknown", - "device_platform": "ios", - "device_os_versions": "17.1.1" - }, - { - "ip_address": "174.215.23.182", - "device_model": "unknown", - "device_platform": "ios", - "device_os_versions": "16.6.1" - }, - { - "ip_address": "174.231.92.217", - "device_model": "unknown", - "device_platform": "ios", - "device_os_versions": "17.1.2" - }, - { - "ip_address": "174.231.90.225", - "device_model": "unknown", - "device_platform": "ios", - "device_os_versions": "16.6.1" - } - ], - "account": { - "signup_time": "2023-06-29 03:27:17.539", - "last_pause_time": "2023-12-04 03:04:32", - "last_unpause_time": "2023-12-04 16:53:40", - "last_seen": "2024-01-17 04:07:39", - "device_platform": "ios", - "device_os": "16.6.1", - "device_model": "unknown", - "app_version": "9.30.0", - "push_notifications_enabled": false - }, - "profile": { - "first_name": "Shelby", - "age": 99, - "height_centimeters": 213, - "gender": "female", - "gender_identity": "[\"Prefer Not to Say\"]", - "gender_identity_displayed": false, - "ethnicities": "[\"Prefer Not to Say\"]", - "ethnicities_displayed": false, - "religions": "[\"Prefer Not to Say\"]", - "religions_displayed": true, - "workplaces": "[\"Prefer Not to Say\"]", - "workplaces_displayed": false, - "job_title": "Software Engineer", - "job_title_displayed": true, - "schools": "[\"University of Denver\"]", - "schools_displayed": true, - "hometowns": "[\"Prefer Not to Say\"]", - "hometowns_displayed": false, - "smoking": "[\"Prefer Not to Say\"]", - "smoking_displayed": false, - "drinking": "[\"Prefer Not to Say\"]", - "drinking_displayed": false, - "marijuana": "Prefer Not to Say", - "marijuana_displayed": false, - "drugs": "Prefer Not to Say", - "drugs_displayed": false, - "children": "Prefer Not to Say", - "children_displayed": false, - "family_plans": "Not sure yet", - "family_plans_displayed": false, - "education_attained": "Undergraduate", - "politics": "Prefer Not to Say", - "politics_displayed": false, - "instagram_displayed": false, - "vaccination_status": "Prefer Not to Say", - "vaccination_status_displayed": false, - "dating_intention_displayed": false, - "dating_intention": "Prefer Not to Say", - "dating_intention_text": "", - "languages_spoken_displayed": true, - "languages_spoken": "English", - "pets_displayed": true, - "pets": "Dog", - "relationship_type_displayed": false, - "relationship_types": "Prefer Not to Say", - "selfie_verified": false - }, - "preferences": { - "distance_miles_max": 50, - "age_min": 18, - "age_max": 99, - "age_dealbreaker": true, - "height_min": 92, - "height_max": 214, - "height_dealbreaker": false, - "gender_preference": "Dogs", - "ethnicity_preference": "[\"Open to All\"]", - "ethnicity_dealbreaker": false, - "religion_preference": "[\"Open to All\"]", - "religion_dealbreaker": false, - "smoking_preference": "[\"Open to All\"]", - "smoking_dealbreaker": false, - "drinking_preference": "[\"Open to All\"]", - "drinking_dealbreaker": false, - "marijuana_preference": "[\"Open to All\"]", - "marijuana_dealbreaker": false, - "drugs_preference": "[\"Open to All\"]", - "drugs_dealbreaker": false, - "children_preference": "[\"Open to All\"]", - "children_dealbreaker": false, - "family_plans_preference": "[\"Open to All\"]", - "family_plans_dealbreaker": false, - "education_attained_preference": "[\"Open to All\"]", - "education_attained_dealbreaker": false, - "politics_preference": "[\"Open to All\"]", - "politics_dealbreaker": false - }, - "location": { - "latitude": 40.652378, - "longitude": -73.959015, - "country": "United States", - "country_short": "US", - "admin_area_1": "New York", - "admin_area_1_short": "NY", - "admin_area_2": "Kings County", - "cbsa": "New York-Newark-Jersey City, NY-NJ-PA", - "locality": "New York", - "sublocality": "Brooklyn", - "neighborhood": "Flatbush", - "postal_code": "11226", - "postal_suffix": "3101", - "location_source": "google" - }, - "identity": { - "email": "faker@gmail.com", - "instagram_authorized": false, - "phone_number": "+15553334444", - "phone_country_code": "US", - "phone_country_calling_code": "1", - "phone_carrier": "Verizon Wireless", - "phone_line_type": "Mobile", - "phone_is_prepaid": false - }, - "installs": [ - { - "ip_address": "73.153.4.225", - "idfv": "CF6EDB9A-59AE-420C-A716-60C832907164", - "user_agent": "Hinge/11472 CFNetwork/1408.0.4 Darwin/22.5.0", - "install_time": "2023-06-29 03:28:49.239" - } - ] -} \ No newline at end of file