|
| 1 | +# pylint: disable=missing-function-docstring, missing-module-docstring, invalid-name, import-error |
| 2 | +# integration test for one_way_sync.py |
| 3 | +import pickle |
| 4 | +from datetime import datetime |
| 5 | +from dateutil.tz import tzoffset |
| 6 | +import pytest |
| 7 | +import requests |
| 8 | +import vcr |
| 9 | +from mockito import when, mock, when2, verify, captor, ANY, arg_that |
| 10 | +from one_way_sync import sync_todoist_to_habitica |
| 11 | +from todoist_api_python import models |
| 12 | +from common_fixtures import empty_pickle, fake_config_file, mock_web_calls # pylint: disable=unused-import |
| 13 | +# pylint: enable=invalid-name |
| 14 | + |
| 15 | + |
| 16 | +def case1(): |
| 17 | + hab_val = {"data": []} |
| 18 | + |
| 19 | + due_dict = {'date': '2024-12-27', |
| 20 | + 'datetime': None, |
| 21 | + 'is_recurring': True, |
| 22 | + 'string': 'every day', |
| 23 | + 'timezone': None} |
| 24 | + duedate = models.Due.from_dict(due_dict) |
| 25 | + created_at = '2025-01-04T00:00:00.0Z' |
| 26 | + |
| 27 | + todoist_task = models.Task(None, # assignee id |
| 28 | + None, # assigner id |
| 29 | + 0, # comment count |
| 30 | + False, # is_completed |
| 31 | + 'Test task 1', # content |
| 32 | + created_at, # created_at |
| 33 | + '59292300', # creater_id |
| 34 | + '', # description |
| 35 | + duedate, # due |
| 36 | + '8296278113', # id |
| 37 | + [], # labels |
| 38 | + 0, # order |
| 39 | + None, # parent id |
| 40 | + 1, # priority |
| 41 | + '9187482462', # project id |
| 42 | + '19099659', # section id |
| 43 | + None, # url |
| 44 | + '' # duration |
| 45 | + ) |
| 46 | + todo_tasks = [todoist_task] |
| 47 | + completed_todos = [] |
| 48 | + |
| 49 | + inputs = {'hab_task': hab_val, |
| 50 | + 'completed_habs': hab_val, |
| 51 | + 'todo_tasks': todo_tasks, |
| 52 | + 'done_tasks': completed_todos} |
| 53 | + |
| 54 | + return inputs |
| 55 | + |
| 56 | + |
| 57 | +'''def check_headers(headers): |
| 58 | + assert headers['url'] == 'https://habitica.com' |
| 59 | + assert headers['x-api-user'] == 'cd18fc9f-b649-4384-932a-f3bda6fe8102' |
| 60 | + assert headers['x-api-key'] == '18f22441-2c87-6d8e-fb2a-3fa670837b5a' |
| 61 | +''' |
| 62 | + |
| 63 | + |
| 64 | +def verify_post_request(data): |
| 65 | + if data['text'] == 'Test task 1': |
| 66 | + assert data['type'] == 'todo' |
| 67 | + assert data['text'] == 'Test task 1' |
| 68 | + assert data['date'] == '12/27/2024, 00:00:00' |
| 69 | + assert data['alias'] == '8296278113' |
| 70 | + assert data['priority'] == '2' |
| 71 | + assert data['attribute'] == 'str' |
| 72 | + return True |
| 73 | + return False |
| 74 | + |
| 75 | +''' |
| 76 | +def verify_put_request(the_url, the_data): |
| 77 | + assert the_url.value == 'https://habitica.com/api/v3/tasks/96935939' |
| 78 | + data = the_data.value |
| 79 | + assert data['alias'] == '96935939' |
| 80 | + assert data['text'] == 'Some test task' |
| 81 | + assert data['priority'] == 1 |
| 82 | +''' |
| 83 | + |
| 84 | + |
| 85 | +def verify_pickle_dump(dump_dict): |
| 86 | + data = dump_dict.value |
| 87 | + # check 'simple' values |
| 88 | + assert '8296278113' in data.keys() |
| 89 | + data = data['8296278113'] |
| 90 | + assert data['recurs'] == 'No' |
| 91 | + assert data['duelast'] == 'NA' |
| 92 | + # Get objects to verify |
| 93 | + assert 'tod' in data.keys() |
| 94 | + tod_task = data['tod'] |
| 95 | + assert 'hab' in data.keys() |
| 96 | + hab_task = data['hab'] |
| 97 | + # Check tod_task |
| 98 | + tod_data = tod_task.task_dict |
| 99 | + assert tod_data['content'] == 'Test task 1' |
| 100 | + assert tod_data['id'] == '8296278113' |
| 101 | + assert tod_data['created_at'] == '2025-01-04T00:00:00.0Z' |
| 102 | + assert tod_data['priority'] == 1 |
| 103 | + # Check hab_task |
| 104 | + hab_data = hab_task.task_dict |
| 105 | + assert hab_data['type'] == 'daily' |
| 106 | + assert hab_data['alias'] == '96935939' |
| 107 | + assert hab_data['text'] == 'Some test task' |
| 108 | + assert hab_data['priority'] == 1 |
| 109 | + expected_due = datetime(2024, 12, 27, tzinfo=tzoffset(None, -25200)) |
| 110 | + due = hab_task.due |
| 111 | + assert due == expected_due |
| 112 | + |
| 113 | + |
| 114 | +# pylint: disable=missing-class-docstring |
| 115 | +class TestDailies: |
| 116 | + test_vcr = vcr.VCR( |
| 117 | + serializer='yaml', |
| 118 | + cassette_library_dir="/tmp/throwaway", |
| 119 | + record_mode='none' |
| 120 | + ) |
| 121 | + |
| 122 | + # pylint: disable=redefined-outer-name, unused-argument, too-many-locals, too-few-public-methods |
| 123 | + @pytest.mark.parametrize("mock_web_calls", [case1()], indirect=True) |
| 124 | + @pytest.mark.parametrize("pickle_in", [empty_pickle()], indirect=True) |
| 125 | + def test(self, |
| 126 | + fake_config_file, |
| 127 | + mock_web_calls): |
| 128 | + # pylint: enable=redefined-outer-name, unused-argument |
| 129 | + |
| 130 | + # set default response |
| 131 | + response = mock({'status': 200, 'ok': True}, spec=requests.Response) |
| 132 | + |
| 133 | + # mock out post to Habitica |
| 134 | + when(requests).post(...).thenReturn(response) |
| 135 | + |
| 136 | + # mock out put to Habitica |
| 137 | + when(requests).put(...).thenReturn(response) |
| 138 | + |
| 139 | + # mock out web call to get id |
| 140 | + hab_task = {'text': 'Some test task', 'priority': '', 'attribute': '', |
| 141 | + 'type': 'todo', '_id': 'a94e8f46-5c14-f14a-f189-e669e239730a', |
| 142 | + 'completed': False, 'alias': '96935939', 'date': '12/27/2024, 00:00:00'} |
| 143 | + hab_val2 = {"data": hab_task} |
| 144 | + |
| 145 | + response2 = mock({'status': 200, 'ok': True}, spec=requests.Response) |
| 146 | + task_url = 'https://habitica.com/api/v3/tasks/8296278113' |
| 147 | + when(requests).get(headers={'url': 'https://habitica.com', |
| 148 | + 'x-api-user': 'cd18fc9f-b649-4384-932a-f3bda6fe8102', |
| 149 | + 'x-api-key': '18f22441-2c87-6d8e-fb2a-3fa670837b5a'}, |
| 150 | + url=task_url).thenReturn(response2) |
| 151 | + when(response2).json().thenReturn(hab_val2) |
| 152 | + |
| 153 | + # mock dump of pickle file |
| 154 | + pkl_out = mock() |
| 155 | + pkl_file = mock() |
| 156 | + when2(open, ...).thenCallOriginalImplementation() |
| 157 | + when2(open, 'oneWay_matchDict.pkl', 'wb').thenReturn(pkl_file) |
| 158 | + when(pickle).Pickler(...).thenReturn(pkl_out) |
| 159 | + when(pkl_out).dump(...) |
| 160 | + |
| 161 | + # using get_all_habtasks() which contains requests.get(), uses the monkeypatch |
| 162 | + with self.test_vcr.use_cassette("null.yaml"): |
| 163 | + sync_todoist_to_habitica() |
| 164 | + |
| 165 | + # verify post request |
| 166 | + '''the_url = captor(ANY(str)) |
| 167 | + the_data = captor(ANY(dict)) |
| 168 | + the_headers = captor(ANY(dict)) |
| 169 | + verify(requests, times=1).post(url='https://habitica.com/api/v3/tasks/user/', |
| 170 | + data=arg_that(verify_post_request), |
| 171 | + headers=the_headers) |
| 172 | + # check_headers(the_headers.value)''' |
| 173 | + |
| 174 | + # verify put request |
| 175 | + '''the_url = captor(ANY(str)) |
| 176 | + verify(requests, times=1).put(headers=the_headers, url=the_url, data=the_data)''' |
| 177 | + # check_headers(the_headers.value) |
| 178 | + # verify_put_request(the_url, the_data) |
| 179 | + |
| 180 | + # verify pickle dump |
| 181 | + dump_dict = captor(ANY(dict)) |
| 182 | + verify(pkl_out, times=1).dump(dump_dict) |
| 183 | + verify_pickle_dump(dump_dict) |
0 commit comments