Skip to content

Commit

Permalink
Continued to improve reminder test coverage.
Browse files Browse the repository at this point in the history
  • Loading branch information
pint-sized committed Apr 29, 2024
1 parent a18918d commit 5aed1e6
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 32 deletions.
14 changes: 13 additions & 1 deletion taskbridge/reminders/model/remindercontainer.py
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,8 @@ def sync_container_deletions(discovered_local: List[LocalList], discovered_remot
# Sync local deletions to remote
if fail == "fail_retrieve":
helpers.DATA_LOCATION = Path("/")
else:
helpers.DATA_LOCATION = Path.home() / "Library" / "Application Support" / "TaskBridge"
try:
with closing(sqlite3.connect(helpers.db_folder())) as connection:
connection.row_factory = sqlite3.Row
Expand All @@ -518,6 +520,8 @@ def sync_container_deletions(discovered_local: List[LocalList], discovered_remot
# Empty table
if fail == "fail_delete":
helpers.DATA_LOCATION = Path("/")
else:
helpers.DATA_LOCATION = Path.home() / "Library" / "Application Support" / "TaskBridge"
try:
with closing(sqlite3.connect(helpers.db_folder())) as connection:
connection.row_factory = sqlite3.Row
Expand Down Expand Up @@ -655,10 +659,16 @@ def sync_reminder_deletions(fail: str = None) -> tuple[bool, str] | tuple[bool,
return False, message

for container in ReminderContainer.CONTAINER_LIST:
if not container.sync:
continue
success, data = container.load_local_reminders()
if not success or fail == "fail_load_local":
return False, 'Failed to load local reminders: {}'.format(data)
success, data = container.load_remote_reminders()
if not fail == "fail_load_remote":
success, data = container.load_remote_reminders()
else:
success = False
data = "Explicitly set to fail to load reminders"
if not success or fail == "fail_load_remote":
return False, 'Failed to load remote reminders: {}'.format(data)

Expand Down Expand Up @@ -689,6 +699,8 @@ def sync_reminder_deletions(fail: str = None) -> tuple[bool, str] | tuple[bool,
# Empty table
if fail == "fail_db":
helpers.DATA_LOCATION = Path("/")
else:
helpers.DATA_LOCATION = Path.home() / "Library" / "Application Support" / "TaskBridge"
try:
with closing(sqlite3.connect(helpers.db_folder())) as connection:
connection.row_factory = sqlite3.Row
Expand Down
28 changes: 23 additions & 5 deletions tests/test_reminder.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import datetime
import os
import json
from pathlib import Path

import pytest
import caldav
Expand All @@ -19,6 +20,7 @@


class TestReminder:
CALDAV_CONNECTED: bool = False

@staticmethod
def __create_reminder_from_local() -> Reminder:
Expand Down Expand Up @@ -60,19 +62,35 @@ def __create_reminder_from_remote() -> Reminder:
return reminder

@staticmethod
def __connect_caldav():
conf_file = helpers.settings_folder() / 'conf.json'
def __connect_caldav(fail: bool = False, test_caldav: bool = True):
if TestReminder.CALDAV_CONNECTED and not fail:
TestReminder.CALDAV_CONNECTED = False
return

if test_caldav:
conf_file = Path(os.path.abspath(os.path.dirname(__file__))) / "conf.json"
else:
conf_file = helpers.settings_folder() / 'conf.json'
if not os.path.exists(conf_file):
assert False, "Failed to load configuration file."
with open(helpers.settings_folder() / 'conf.json', 'r') as fp:
assert False, "Failed to load configuration file at {}".format(conf_file)

with open(conf_file, 'r') as fp:
settings = json.load(fp)

ReminderController.CALDAV_USERNAME = settings['caldav_username']
ReminderController.CALDAV_URL = settings['caldav_url']
ReminderController.CALDAV_HEADERS = {}
ReminderController.CALDAV_PASSWORD = keyring.get_password("TaskBridge", "CALDAV-PWD")

if fail:
ReminderController.CALDAV_PASSWORD = 'bogus'
elif test_caldav:
ReminderController.CALDAV_PASSWORD = config('TEST_CALDAV_PASSWORD')
else:
ReminderController.CALDAV_PASSWORD = keyring.get_password("TaskBridge", "CALDAV-PWD")

ReminderController.TO_SYNC = settings['reminder_sync']
ReminderController.connect_caldav()
TestReminder.CALDAV_CONNECTED = True

def test_create_from_local(self):
uuid = "x-apple-id://1234-5678-9012"
Expand Down
84 changes: 58 additions & 26 deletions tests/test_remindercontainer.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,18 @@ class TestReminderContainer:
@staticmethod
def __connect_caldav(fail: bool = False, test_caldav: bool = True):
if TestReminderContainer.CALDAV_CONNECTED and not fail:
TestReminderContainer.CALDAV_CONNECTED = False
return

if fail:
helpers.CALDAV_PRINCIPAL = None
TestReminderContainer.CALDAV_CONNECTED = False

if test_caldav:
conf_file = os.getcwd() + "/conf.json"
conf_file = Path(os.path.abspath(os.path.dirname(__file__))) / "conf.json"
else:
conf_file = helpers.settings_folder() / 'conf.json'
if not os.path.exists(conf_file):
assert False, "Failed to load configuration file."
assert False, "Failed to load configuration file at {}".format(conf_file)

with open(conf_file, 'r') as fp:
settings = json.load(fp)
Expand Down Expand Up @@ -71,6 +74,12 @@ def __create_reminder_from_local() -> Reminder:
reminder = Reminder.create_from_local(values)
return reminder

@staticmethod
def __reset_state() -> None:
helpers.DRY_RUN = False
TestReminderContainer.__connect_caldav()
helpers.DATA_LOCATION = Path.home() / "Library" / "Application Support" / "TaskBridge"

# noinspection SpellCheckingInspection
@staticmethod
def __create_reminder_from_remote() -> Reminder:
Expand Down Expand Up @@ -115,13 +124,15 @@ def __get_sync_container() -> ReminderContainer:

@pytest.mark.skipif(TEST_ENV != 'local', reason="Requires CalDAV credentials")
def test_load_caldav_calendars(self):
TestReminderContainer.__connect_caldav()
TestReminderContainer.__reset_state()
success, remote_calendars = ReminderContainer.load_caldav_calendars()
assert success is True
assert len(remote_calendars) > 0

@pytest.mark.skipif(TEST_ENV != 'local', reason="Requires Mac system with iCloud")
def test_load_local_lists(self):
TestReminderContainer.__reset_state()

success, local_lists = ReminderContainer.load_local_lists()
assert success is True
assert len(local_lists) > 0
Expand All @@ -132,6 +143,8 @@ def test_load_local_lists(self):

@pytest.mark.skipif(TEST_ENV != 'local', reason="Requires Mac system with iCloud")
def test_count_local_completed(self):
TestReminderContainer.__reset_state()

success, data = ReminderContainer.count_local_completed()
assert success is True
assert isinstance(data, int)
Expand All @@ -142,12 +155,16 @@ def test_count_local_completed(self):

@pytest.mark.skipif(TEST_ENV != 'local', reason="Requires Mac system with iCloud")
def test_delete_local_completed(self):
TestReminderContainer.__reset_state()

success, data = ReminderContainer.delete_local_completed()
assert success is True
success, count = ReminderContainer.count_local_completed()
assert count == 0

def test_assoc_list_local_remote(self):
TestReminderContainer.__reset_state()

mock_local = [LocalList("sync_me"), LocalList("do_not_sync_me")]
mock_remote = [RemoteCalendar(calendar_name="sync_me"), RemoteCalendar(calendar_name="do_not_sync_me")]
mock_sync = ['sync_me']
Expand All @@ -167,6 +184,8 @@ def test_assoc_list_local_remote(self):
ReminderContainer.CONTAINER_LIST.clear()

def test_assoc_list_remote_local(self):
TestReminderContainer.__reset_state()

mock_local = [LocalList("sync_me"), LocalList("do_not_sync_me")]
mock_remote = [RemoteCalendar(calendar_name="sync_me"), RemoteCalendar(calendar_name="do_not_sync_me")]
mock_sync = ['sync_me']
Expand Down Expand Up @@ -194,8 +213,8 @@ def test_assoc_list_remote_local(self):

@pytest.mark.skipif(TEST_ENV != 'local', reason="Requires Mac system with iCloud and CalDAV credentials")
def test_create_linked_containers(self):
helpers.DRY_RUN = False
TestReminderContainer.__connect_caldav()
TestReminderContainer.__reset_state()

mock_local = [LocalList("sync_me"),
LocalList("do_not_sync_me"),
LocalList("Reminders"),
Expand Down Expand Up @@ -242,6 +261,8 @@ def test_create_linked_containers(self):

@pytest.mark.skipif(TEST_ENV != 'local', reason="Requires local filesystem.")
def test_seed_container_table(self):
TestReminderContainer.__reset_state()

ReminderContainer.seed_container_table()
try:
with closing(sqlite3.connect(helpers.db_folder())) as connection:
Expand All @@ -264,6 +285,8 @@ def test_seed_container_table(self):

@pytest.mark.skipif(TEST_ENV != 'local', reason="Requires local filesystem.")
def test_persist_containers(self):
TestReminderContainer.__reset_state()

ReminderContainer(LocalList("sync_me"), RemoteCalendar(calendar_name="sync_me"), True)
ReminderContainer(LocalList("do_not_sync_me"), RemoteCalendar(calendar_name="do_not_sync_me"), False)
ReminderContainer.persist_containers()
Expand Down Expand Up @@ -301,6 +324,8 @@ def test_persist_containers(self):

@pytest.mark.skipif(TEST_ENV != 'local', reason="Requires local filesystem.")
def test_seed_reminder_table(self):
TestReminderContainer.__reset_state()

ReminderContainer.seed_reminder_table()
try:
with closing(sqlite3.connect(helpers.db_folder())) as connection:
Expand All @@ -324,6 +349,8 @@ def test_seed_reminder_table(self):

@pytest.mark.skipif(TEST_ENV != 'local', reason="Requires local filesystem.")
def test_persist_reminders(self):
TestReminderContainer.__reset_state()

container = ReminderContainer(LocalList("sync_me"), RemoteCalendar(calendar_name="sync_me"), True)
local_reminder = Reminder("local_uuid", "local_name", None, datetime.datetime.now(),
None, None, None, None, False)
Expand Down Expand Up @@ -368,8 +395,7 @@ def test_persist_reminders(self):

@pytest.mark.skipif(TEST_ENV != 'local', reason="Requires CalDAV credentials")
def test__delete_remote_containers(self):
helpers.DRY_RUN = False
TestReminderContainer.__connect_caldav()
TestReminderContainer.__reset_state()

# Create a remote container
to_delete = RemoteCalendar(calendar_name='DELETE_ME')
Expand Down Expand Up @@ -410,7 +436,7 @@ def test__delete_remote_containers(self):

@pytest.mark.skipif(TEST_ENV != 'local', reason="Requires Mac system with iCloud")
def test__delete_local_containers(self):
helpers.DRY_RUN = False
TestReminderContainer.__reset_state()

# Create a local container
to_delete = LocalList('DELETE_ME')
Expand Down Expand Up @@ -452,9 +478,7 @@ def test__delete_local_containers(self):

@pytest.mark.skipif(TEST_ENV != 'local', reason="Requires Mac system with iCloud and CalDAV credentials")
def test_sync_container_deletions(self):
helpers.DRY_RUN = False
TestReminderContainer.__connect_caldav()
helpers.DATA_LOCATION = Path.home() / "Library" / "Application Support" / "TaskBridge"
TestReminderContainer.__reset_state()

for run in range(4):
fail = None
Expand Down Expand Up @@ -533,6 +557,7 @@ def test_sync_container_deletions(self):
assert remote_presence is None

# Clean Up
TestReminderContainer.__reset_state()
ReminderContainer.CONTAINER_LIST.clear()
try:
with closing(sqlite3.connect(helpers.db_folder())) as connection:
Expand All @@ -546,7 +571,7 @@ def test_sync_container_deletions(self):

@pytest.mark.skipif(TEST_ENV != 'local', reason="Requires Mac system with iCloud and CalDAV credentials")
def test__delete_remote_reminders(self):
helpers.DRY_RUN = False
TestReminderContainer.__reset_state()

sync_container = TestReminderContainer.__get_sync_container()

Expand Down Expand Up @@ -612,7 +637,7 @@ def test__delete_remote_reminders(self):

@pytest.mark.skipif(TEST_ENV != 'local', reason="Requires Mac system with iCloud and CalDAV credentials")
def test__delete_local_reminders(self):
helpers.DRY_RUN = False
TestReminderContainer.__reset_state()

sync_container = TestReminderContainer.__get_sync_container()

Expand Down Expand Up @@ -679,7 +704,8 @@ def test__delete_local_reminders(self):

@pytest.mark.skipif(TEST_ENV != 'local', reason="Requires Mac system with iCloud")
def test_get_saved_reminders(self):
helpers.DRY_RUN = False
TestReminderContainer.__reset_state()

sync_container = TestReminderContainer.__get_sync_container()

# Create a local reminder
Expand Down Expand Up @@ -716,9 +742,7 @@ def test_get_saved_reminders(self):

@pytest.mark.skipif(TEST_ENV != 'local', reason="Requires Mac system with iCloud and CalDAV credentials")
def test_sync_reminder_deletions(self):
helpers.DRY_RUN = False
TestReminderContainer.__connect_caldav()
helpers.DATA_LOCATION = Path.home() / "Library" / "Application Support" / "TaskBridge"
TestReminderContainer.__reset_state()

tests = [None, 'fail_seed', 'fail_load_local', 'fail_load_remote', 'fail_get_saved', 'fail_db']
for run in range(6):
Expand All @@ -745,7 +769,7 @@ def test_sync_reminder_deletions(self):
assert False, 'Failed to create remote reminder.'
success, data = to_delete_remote.upsert_local(sync_container)
if not success:
assert False, 'Failed to create remote task.'
assert False, 'Failed to create local task.'

# Refresh the container with the new reminders, sync, and persist
sync_container.load_local_reminders()
Expand Down Expand Up @@ -791,6 +815,7 @@ def test_sync_reminder_deletions(self):
assert remote_presence is None

# Clean Up
TestReminderContainer.__reset_state()
delete_reminder_script = reminderscript.delete_reminder_script
helpers.run_applescript(delete_reminder_script, synced_local.uuid)
remote_object = sync_container.remote_calendar.cal_obj.search(todo=True, uid=to_delete_remote.uuid)
Expand All @@ -809,7 +834,8 @@ def test_sync_reminder_deletions(self):

@pytest.mark.skipif(TEST_ENV != 'local', reason="Requires Mac system with iCloud")
def test_load_local_reminders(self):
helpers.DRY_RUN = False
TestReminderContainer.__reset_state()

sync_container = TestReminderContainer.__get_sync_container()

# Create a local reminder
Expand Down Expand Up @@ -842,7 +868,8 @@ def test_load_local_reminders(self):

@pytest.mark.skipif(TEST_ENV != 'local', reason="Requires CalDAV credentials")
def test_load_remote_reminders(self):
helpers.DRY_RUN = False
TestReminderContainer.__reset_state()

sync_container = TestReminderContainer.__get_sync_container()

# Create a remote reminder
Expand All @@ -868,7 +895,8 @@ def test_load_remote_reminders(self):

@pytest.mark.skipif(TEST_ENV != 'local', reason="Requires Mac system with iCloud and CalDAV credentials")
def test_sync_local_reminders_to_remote(self):
helpers.DRY_RUN = False
TestReminderContainer.__reset_state()

sync_container = TestReminderContainer.__get_sync_container()

fail = None
Expand Down Expand Up @@ -918,7 +946,8 @@ def test_sync_local_reminders_to_remote(self):

@pytest.mark.skipif(TEST_ENV != 'local', reason="Requires Mac system with iCloud and CalDAV credentials")
def test_sync_remote_reminders_to_local(self):
helpers.DRY_RUN = False
TestReminderContainer.__reset_state()

sync_container = TestReminderContainer.__get_sync_container()

fail = None
Expand Down Expand Up @@ -968,7 +997,8 @@ def test_sync_remote_reminders_to_local(self):

@pytest.mark.skipif(TEST_ENV != 'local', reason="Requires Mac system with iCloud and CalDAV credentials")
def test_sync_reminders(self):
helpers.DRY_RUN = False
TestReminderContainer.__reset_state()

sync_container = TestReminderContainer.__get_sync_container()

fail = None
Expand Down Expand Up @@ -1056,8 +1086,8 @@ def test___repr__(self):

@pytest.mark.skipif(TEST_ENV != 'local', reason="Requires Mac system with iCloud and CalDAV credentials")
def test_disconnected_caldav(self):
helpers.DRY_RUN = False
TestReminderContainer.__connect_caldav(True)
TestReminderContainer.__reset_state()
TestReminderContainer.__connect_caldav(fail=True)
ReminderContainer.CONTAINER_LIST.clear()

# Fail to load remote calendars
Expand Down Expand Up @@ -1099,6 +1129,8 @@ def test_disconnected_caldav(self):

@pytest.mark.skipif(TEST_ENV != 'local', reason="Requires Mac system with iCloud and CalDAV credentials")
def test_unavailable_db(self):
TestReminderContainer.__reset_state()

helpers.DATA_LOCATION = Path("/")

success, data = ReminderContainer.seed_container_table()
Expand Down

0 comments on commit 5aed1e6

Please sign in to comment.