def test_imap_handle_folder_renames(db, default_account): monitor = ImapSyncMonitor(default_account) folder_names_and_roles = { ('INBOX', 'inbox'), ('[Gmail]/Todos', 'all'), ('[Gmail]/Basura', 'trash') } folders_renamed = { ('INBOX', 'inbox'), ('[Gmail]/All', 'all'), ('[Gmail]/Trash', 'trash') } original_raw_folders = [RawFolder(*args) for args in folder_names_and_roles] renamed_raw_folders = [RawFolder(*args) for args in folders_renamed] monitor.save_folder_names(db.session, original_raw_folders) assert len(db.session.query(Folder).filter( Folder.account_id == default_account.id).all()) == 3 monitor.save_folder_names(db.session, renamed_raw_folders) saved_folder_data = set( db.session.query(Folder.name, Folder.canonical_name).filter( Folder.account_id == default_account.id).all()) assert saved_folder_data == folders_renamed
def test_handle_trailing_whitespace(db, default_account): raw_folders = [ RawFolder('Miscellania', ''), RawFolder('Miscellania ', ''), RawFolder('Inbox', 'inbox') ] monitor = ImapSyncMonitor(default_account) monitor.save_folder_names(db.session, raw_folders) saved_folder_data = set( db.session.query(Folder.name, Folder.canonical_name).filter( Folder.account_id == default_account.id)) assert saved_folder_data == {('Miscellania', ''), ('Inbox', 'inbox')}
def test_folder_monitor_handles_mailsync_done(yahoo_account, monkeypatch): # test that the ImapFolderMonitor exits cleanly when MailsyncDone # is raised as part of the initial sync. monitor = ImapSyncMonitor(yahoo_account) # Override the folders from `prepare_sync` to simulate a folder which was # genuinely returned here but then immediately deleted. This triggers # MailsyncDone (see the previous test). folders = [('missing_folder', 0)] monitor.prepare_sync = lambda: folders # Try to start a sync engine for this folder. It should exit. monitor.start_new_folder_sync_engines() assert len(monitor.folder_monitors) == 0
def test_handle_trailing_whitespace(db, default_account): raw_folders = [ RawFolder('Miscellania', None), RawFolder('Miscellania ', None), RawFolder('Inbox', 'inbox') ] monitor = ImapSyncMonitor(default_account) monitor.save_folder_names(db.session, raw_folders) saved_folder_data = set( db.session.query(Folder.name, Folder.canonical_name).filter( Folder.account_id == default_account.id) ) assert saved_folder_data == {('Miscellania', None), ('Inbox', 'inbox')}
def test_folder_monitor_handles_mailsync_done(yahoo_account, monkeypatch): # test that the ImapFolderMonitor exits cleanly when MailsyncDone # is raised as part of the initial sync. monitor = ImapSyncMonitor(yahoo_account) # Override the folders from `prepare_sync` to simulate a folder which was # genuinely returned here but then immediately deleted. This triggers # MailsyncDone (see the previous test). folders = [('missing_folder', 0)] monitor.prepare_sync = lambda: folders # Try to start a sync engine for this folder. It should exit. monitor.start_new_folder_sync_engines(set()) assert len(monitor.folder_monitors) == 0
def test_imap_remote_delete(db, default_account): monitor = ImapSyncMonitor(default_account) folders = { ('All', 'inbox'), ('Trash', 'trash'), ('Applications', ''), } new_folders = { ('All', 'inbox'), ('Trash', 'trash') } original_raw_folders = [RawFolder(*args) for args in folders] new_raw_folders = [RawFolder(*args) for args in new_folders] monitor.save_folder_names(db.session, original_raw_folders) original_folders = db.session.query(Folder).filter( Folder.account_id == default_account.id).all() assert len(original_folders) == 3 for label in original_folders: assert label.category is not None original_categories = {f.canonical_name: f.category.display_name for f in original_folders} for folder in folders: display_name, role = folder assert original_categories[role] == display_name monitor.save_folder_names(db.session, new_raw_folders) saved_folder_data = set( db.session.query(Folder.name, Folder.canonical_name).filter( Folder.account_id == default_account.id).all()) assert saved_folder_data == new_folders renamed_folders = db.session.query(Folder).filter( Folder.account_id == default_account.id).all() for folder in renamed_folders: assert folder.category is not None renamed_categories = {f.canonical_name: f.category.display_name for f in renamed_folders} for folder in new_folders: display_name, role = folder assert renamed_categories[role] == display_name
def test_handle_folder_deletions(db, default_account): monitor = ImapSyncMonitor(default_account) folder_names_and_roles = { ('INBOX', 'inbox'), ('Miscellania', None), } raw_folders = [RawFolder(*args) for args in folder_names_and_roles] monitor.save_folder_names(db.session, raw_folders) assert len(db.session.query(Folder).filter( Folder.account_id == default_account.id).all()) == 2 monitor.save_folder_names(db.session, [RawFolder('INBOX', 'inbox')]) saved_folder_data = set( db.session.query(Folder.name, Folder.canonical_name).filter( Folder.account_id == default_account.id).all()) assert saved_folder_data == {('INBOX', 'inbox')}
def test_save_generic_folder_names(db, default_account): monitor = ImapSyncMonitor(default_account) folder_names_and_roles = { ('INBOX', 'inbox'), ('Sent Mail', 'sent'), ('Sent Messages', 'sent'), ('Drafts', 'drafts'), ('Miscellania', None), ('miscellania', None), ('Recipes', None), } raw_folders = [RawFolder(*args) for args in folder_names_and_roles] monitor.save_folder_names(db.session, raw_folders) saved_folder_data = set( db.session.query(Folder.name, Folder.canonical_name).filter( Folder.account_id == default_account.id).all()) assert saved_folder_data == folder_names_and_roles
def test_imap_save_generic_folder_names(db, default_account): monitor = ImapSyncMonitor(default_account) folder_names_and_roles = { ('INBOX', 'inbox'), ('Sent Mail', 'sent'), ('Sent Messages', 'sent'), ('Drafts', 'drafts'), ('Miscellania', ''), ('miscellania', ''), ('Recipes', ''), } raw_folders = [RawFolder(*args) for args in folder_names_and_roles] monitor.save_folder_names(db.session, raw_folders) saved_folder_data = set( db.session.query(Folder.name, Folder.canonical_name).filter( Folder.account_id == default_account.id).all()) assert saved_folder_data == folder_names_and_roles
def create_foldersyncstatuses(db, default_account): # Create a bunch of folder sync statuses. monitor = ImapSyncMonitor(default_account) folder_names_and_roles = { RawFolder("INBOX", "inbox"), RawFolder("Sent Mail", "sent"), RawFolder("Sent Messages", "sent"), RawFolder("Drafts", "drafts"), RawFolder("Miscellania", None), RawFolder("miscellania", None), RawFolder("Recipes", None), } monitor.save_folder_names(db.session, folder_names_and_roles) folders = db.session.query(Folder).filter_by(account_id=default_account.id) for folder in folders: add_imap_status_info_rows(folder.id, default_account.id, db.session) db.session.commit()
def __init__(self, *args, **kwargs): ImapSyncMonitor.__init__(self, *args, **kwargs) self.sync_engine_class = GmailFolderSyncEngine # We start a label refresh whenever we find a new labels # However, this is a pretty expensive operation, so we # use a semaphore to make sure we're not running multiple # LabelRenameHandlers for a single account. # This is a conservative choice which should be okay most # of the time. # We could have used something like a table to not start # a LabelRenameHandler for a label when another one is # already running, but in some cases it gives us better consistency # (e.g: I have a label A -> I rename to B, then to C but add some # labels back into A). # This is unlikely but worth getting right. # - karim self.label_rename_semaphore = Semaphore(value=1)
def create_foldersyncstatuses(db, default_account): # Create a bunch of folder sync statuses. monitor = ImapSyncMonitor(default_account) folder_names_and_roles = { RawFolder('INBOX', 'inbox'), RawFolder('Sent Mail', 'sent'), RawFolder('Sent Messages', 'sent'), RawFolder('Drafts', 'drafts'), RawFolder('Miscellania', None), RawFolder('miscellania', None), RawFolder('Recipes', None), } monitor.save_folder_names(db.session, folder_names_and_roles) folders = db.session.query(Folder).filter_by(account_id=default_account.id) for folder in folders: add_imap_status_info_rows(folder.id, default_account.id, db.session) db.session.commit()
def test_imap_remote_delete(db, default_account): monitor = ImapSyncMonitor(default_account) folders = { ('All', 'inbox'), ('Trash', 'trash'), ('Applications', ''), } new_folders = {('All', 'inbox'), ('Trash', 'trash')} original_raw_folders = [RawFolder(*args) for args in folders] new_raw_folders = [RawFolder(*args) for args in new_folders] monitor.save_folder_names(db.session, original_raw_folders) original_folders = db.session.query(Folder).filter( Folder.account_id == default_account.id).all() assert len(original_folders) == 3 for label in original_folders: assert label.category is not None original_categories = { f.canonical_name: f.category.display_name for f in original_folders } for folder in folders: display_name, role = folder assert original_categories[role] == display_name monitor.save_folder_names(db.session, new_raw_folders) saved_folder_data = set( db.session.query(Folder.name, Folder.canonical_name).filter( Folder.account_id == default_account.id).all()) assert saved_folder_data == new_folders renamed_folders = db.session.query(Folder).filter( Folder.account_id == default_account.id).all() for folder in renamed_folders: assert folder.category is not None renamed_categories = { f.canonical_name: f.category.display_name for f in renamed_folders } for folder in new_folders: display_name, role = folder assert renamed_categories[role] == display_name
def test_imap_handle_folder_renames(db, default_account): monitor = ImapSyncMonitor(default_account) folder_names_and_roles = {('INBOX', 'inbox'), ('[Gmail]/Todos', 'all'), ('[Gmail]/Basura', 'trash')} folders_renamed = {('INBOX', 'inbox'), ('[Gmail]/All', 'all'), ('[Gmail]/Trash', 'trash')} original_raw_folders = [ RawFolder(*args) for args in folder_names_and_roles ] renamed_raw_folders = [RawFolder(*args) for args in folders_renamed] monitor.save_folder_names(db.session, original_raw_folders) assert len( db.session.query(Folder).filter( Folder.account_id == default_account.id).all()) == 3 monitor.save_folder_names(db.session, renamed_raw_folders) saved_folder_data = set( db.session.query(Folder.name, Folder.canonical_name).filter( Folder.account_id == default_account.id).all()) assert saved_folder_data == folders_renamed
def __init__(self, *args, **kwargs): ImapSyncMonitor.__init__(self, *args, **kwargs) self.sync_engine_class = GmailFolderSyncEngine
def __init__(self, *args, **kwargs): kwargs['retry_fail_classes'] = [GmailSettingError] ImapSyncMonitor.__init__(self, *args, **kwargs) self.sync_engine_class = GmailFolderSyncEngine
def __init__(self, *args, **kwargs): kwargs['retry_fail_classes'] = [GmailSettingError] ImapSyncMonitor.__init__(self, *args, **kwargs) self.thread_download_lock = BoundedSemaphore(1) self.sync_engine_class = partial(GmailFolderSyncEngine, self.thread_download_lock)