Example #1
0
def test_deleted_src_tasks():
    src_tasks = []
    dst = random_task()
    dst_tasks = [dst]
    ss = MockTaskService(src_tasks)
    ds = MockTaskService(dst_tasks)
    map = TaskMap()

    # we need to create a mapping between a src task and dst, but leave
    # the source task out of the source service
    src = random_task()
    map.map(src, dst)

    sync = TaskSync(ss, ds, map)

    # preconditions
    assert len(ss.tasks) == 0
    assert len(ds.tasks) == 1
    assert dst.status == SyncStatus.unchanged

    sync.synchronise()

    # the task list lengths should not be changed
    assert len(ss.tasks) == 0
    assert len(ds.tasks) == 1

    # dst should now be flagged as deleted
    assert dst.status == SyncStatus.deleted
Example #2
0
def test_missing_mapped_destination_tasks_src_complete():
    """ Tests expected behaviours on mapped tasks that are missing in
    the destination.
    """
    src = random_task()
    src.completed = True
    src_tasks = [src]
    src_svc = MockTaskService(src_tasks)

    dst = random_task()
    dst_tasks = []
    dst_svc = MockTaskService(dst_tasks)

    map = TaskMap()

    # create the pre-existing mapping
    map.map(src, dst)

    # preconditions
    assert len(map.get_all_src_keys()) == 1
    assert map.get_dst_id(src.id) == dst.id
    assert map.get_src_id(dst.id) == src.id

    TaskSync(src_svc, dst_svc, map).synchronise()

    assert len(dst_svc.tasks) == 0
Example #3
0
def test_new_tasks_are_mapped():
    src_tasks = [random_task()]
    dst_tasks = []
    src = MockTaskService(src_tasks)
    dst = MockTaskService(dst_tasks)
    map = TaskMap()
    sync = TaskSync(src, dst, map)

    # preconditions
    assert len(map.get_all_src_keys()) == 0

    sync.synchronise()

    assert len(map.get_all_src_keys()) == 1
    assert src_tasks[0].id in map.get_all_src_keys()
    assert map.get_dst_id(src_tasks[0].id) == dst_tasks[0].id
Example #4
0
def test_missing_mapped_destination_tasks_src_not_complete():
    """ Tests expected behaviours on mapped tasks that are missing in
    the destination.
    """
    src = random_task()
    src.completed = False
    src_tasks = [src]
    src_svc = MockTaskService(src_tasks)

    dst = random_task()
    dst_tasks = []
    dst_svc = MockTaskService(dst_tasks)

    map = TaskMap()

    # create the pre-existing mapping
    map.map(src, dst)

    # preconditions
    assert len(map.get_all_src_keys()) == 1
    assert map.get_dst_id(src.id) == dst.id
    assert map.get_src_id(dst.id) == src.id

    TaskSync(src_svc, dst_svc, map).synchronise()

    assert dst.id != dst_svc.tasks[0].id
    assert len(map.get_all_src_keys()) == 1, "should still be just one mapping"
    assert not map.try_get_src_id(dst.id), "old dst should be unmapped"
    assert map.get_dst_id(src.id) != dst.id, "src should be mapped to something else"
    assert dst_svc.tasks[0].status == SyncStatus.new, "should be flagged as a new task"
    assert len(dst_svc.tasks) == 1
Example #5
0
def test_new_completed_tasks_are_not_updated_when_last_mod_older_than_last_sync():
    last_sync = datetime(2016, 8, 15, tzinfo=pytz.utc)
    src = random_task(
        completed=True,
        last_modified=last_sync - timedelta(days=2))
    src_tasks = [src]
    src_svc = MockTaskService(src_tasks)
    dst_svc = MockTaskService([])

    TaskSync(src_svc, dst_svc, TaskMap(), last_sync=last_sync).synchronise()

    assert len(dst_svc.persisted_tasks) == 0
Example #6
0
def test_new_completed_tasks_are_updated_when_last_mod_newer_than_last_sync():
    last_sync = datetime(2016, 8, 15, tzinfo=pytz.utc)
    src_mod_date = last_sync + timedelta(hours=2)
    src = random_task(completed=True, last_modified=src_mod_date)
    src_tasks = [src]
    src_svc = MockTaskService(src_tasks)
    dst_svc = MockTaskService([])

    TaskSync(src_svc, dst_svc, TaskMap(), last_sync=last_sync).synchronise()

    assert len(dst_svc.persisted_tasks) == 1
    assert dst_svc.tasks[0].status == SyncStatus.new
Example #7
0
def test_new_completed_tasks():
    src = random_task(completed=True)
    src_tasks = [src]
    src_svc = MockTaskService(src_tasks)
    dst_tasks = []
    dst_svc = MockTaskService(dst_tasks)
    map = TaskMap()
    TaskSync(src_svc, dst_svc, map).synchronise()

    assert len(dst_svc.tasks) == 1
    assert dst_svc.tasks[0].completed
    assert dst_svc.tasks[0].status == SyncStatus.new
Example #8
0
def test_existing_tasks_are_updated():
    src = random_task()
    src.difficulty = Difficulty.hard
    src.attribute = CharacterAttribute.strength
    src_tasks = [src]
    src_svc = MockTaskService(src_tasks)
    dst = random_task()
    dst.description = 'something different'
    dst.difficulty = Difficulty.medium
    dst.attribute = CharacterAttribute.constitution
    dst_tasks = [dst]
    dst_svc = MockTaskService(dst_tasks)

    # precondition tests
    assert src.id != dst.id
    assert src.status == SyncStatus.unchanged
    assert dst.name != src.name
    assert dst.attribute != src.attribute
    assert dst.difficulty != src.difficulty
    assert dst.status == SyncStatus.unchanged
    assert dst.description != src.description
    map = TaskMap()
    map.map(src, dst)

    sync = TaskSync(src_svc, dst_svc, map)
    sync.synchronise()

    assert len(dst_svc.persisted_tasks) == 1
    actual = dst_svc.persisted_tasks[0]
    assert actual.id == dst.id, "id not changed"
    assert actual.id != src.id, "id not changed"
    assert actual.name == src.name
    assert actual.attribute == src.attribute
    assert actual.difficulty == src.difficulty
    assert actual.completed == src.completed
    assert actual.status == SyncStatus.updated
    assert actual.description == src.description
    assert actual.completed == src.completed
Example #9
0
def test_new_tasks():
    src_tasks = [random_task() for x in range(3)]
    dst_tasks = []
    src = MockTaskService(src_tasks)
    dst = MockTaskService(dst_tasks)
    map = TaskMap()
    sync = TaskSync(src, dst, map)
    sync.synchronise()

    assert len(dst.persisted_tasks) == len(src_tasks)
    for d in dst.persisted_tasks:
        assert d.status == SyncStatus.new
        assert d in dst_tasks
        assert map.try_get_src_id(d.id)

    for s in src.get_all_tasks():
        dst_id = map.try_get_dst_id(s.id)
        assert dst_id
        d = dst.get_task(dst_id)
        assert s.name == d.name
        assert s.description == d.description
        assert s.completed == d.completed
        assert s.difficulty == d.difficulty
        assert s.attribute == d.attribute
Example #10
0
def test_remove_orphan_mappings():
    src_tasks = [random_task()]
    dst_tasks = []
    ss = MockTaskService(src_tasks)
    ds = MockTaskService(dst_tasks)
    map = TaskMap()

    # add a few task mappings that won't exist in either source or destination
    map.map(random_task(), random_task())
    map.map(random_task(), random_task())
    map.map(random_task(), random_task())

    TaskSync(ss, ds, map).synchronise(clean_orphans=True)

    # We now expect just one mapping for the new src task
    all_mappings = map.get_all_src_keys()
    assert len(all_mappings) == 1
    assert map.get_dst_id(src_tasks[0].id)
Example #11
0
def test_completion_of_existing_mapped_tasks():
    src = random_task(completed=True)
    src_tasks = [src]
    src_svc = MockTaskService(src_tasks)

    dst = random_task()
    # make dst the same in all but the completed flag
    dst.copy_fields(dst)
    dst.completed = False
    dst_tasks = [dst]
    dst_svc = MockTaskService(dst_tasks)

    map = TaskMap()
    map.map(src, dst)

    assert not dst_svc.tasks[0].completed

    TaskSync(src_svc, dst_svc, map).synchronise()

    assert len(dst_svc.tasks) == 1
    assert dst_svc.tasks[0].completed
    assert dst_svc.tasks[0].status == SyncStatus.updated
Example #12
0
def test_new_existing_tasks_are_updated():
    last_sync = datetime(2016, 8, 15, tzinfo=pytz.utc)
    # make the src modified date newer than the last sync
    src_mod_date = last_sync + timedelta(minutes=2)
    dst_mod_date = last_sync + timedelta(minutes=1)
    src = random_task(last_modified=src_mod_date)
    src_tasks = [src]
    src_svc = MockTaskService(src_tasks)

    dst = random_task(last_modified=dst_mod_date)
    dst_tasks = [dst]
    dst_svc = MockTaskService(dst_tasks)

    map = TaskMap()
    map.map(src, dst)

    # preconditions
    assert dst.status == SyncStatus.unchanged

    TaskSync(src_svc, dst_svc, map).synchronise()

    assert len(dst_svc.persisted_tasks) == 1
    assert dst.status == SyncStatus.updated
Example #13
0
    def update(self):
        """ This update method will be called once on every update cycle,
        with the frequency determined by the value returned from
        `update_interval_minutes()`.

        If a plugin implements a single-shot function, then update should
        return `False`.

        Returns: bool: True if further updates are required; False if the plugin
        is finished and the application should shut down.
        """
        # retrieve the boards to sync
        boards = self.__tc.list_boards(board_filter='open')
        sync_boards = [
            b for b in boards if b.name in self.__boards]

        self.__ensure_labels_exist(sync_boards)

        # Build a list of sync lists by matching the sync
        # list names in each board
        sync_lists = []
        done_lists = []
        for b in sync_boards:
            for l in b.open_lists():
                if l.name in self._config.trello_lists:
                    sync_lists.append(l)
                elif l.name in self._config.trello_done_lists:
                    done_lists.append(l)

        # some additional information on the source boards and lists
        message = 'Syncing the following lists'
        for l in sync_lists:
            message += '\n   {0}.{1}'.format(l.board.name, l.name)
        message += '\nTreating cards in the following lists as completed'
        for l in done_lists:
            message += '\n   {0}.{1}'.format(l.board.name, l.name)
        logging.getLogger(__name__).debug(message)

        # Load the task map from disk
        task_map = TaskMap(self.__task_map_file)

        # Create the services
        source_service = TrelloTaskService(
            self.__tc,
            sync_lists,
            done_lists,
            self.__boards)

        # synchronise
        sync = TaskSync(
            source_service,
            self.__habitica_task_service,
            task_map,
            last_sync=self.__data.last_sync,
            sync_description=self._config.trello_sync_description)

        stats = sync.synchronise(clean_orphans=False)

        self.__notify(stats)

        # Checkpoint the sync data
        self.__data.last_sync = sync.last_sync
        if not self.dry_run:
            task_map.persist(self.__task_map_file)
            self.__save_persistent_data()

        # return False if finished, and True to be updated again.
        return True