예제 #1
0
    def test_delete_story(self):
        # This test uses mock_data
        story_id = 1
        # Verify that we can look up a story with tasks and events
        story = stories_api.story_get_simple(story_id)
        self.assertIsNotNone(story)
        tasks = tasks_api.task_get_all(story_id=story_id)
        self.assertEqual(len(tasks), 3)
        task_ids = [t.id for t in tasks]
        events = events_api.events_get_all(story_id=story_id)
        self.assertEqual(len(events), 3)
        event_ids = [e.id for e in events]

        # Delete the story
        stories_api.story_delete(story_id)
        story = stories_api.story_get_simple(story_id)
        self.assertIsNone(story)
        # Verify that the story's tasks were deleted
        tasks = tasks_api.task_get_all(story_id=story_id)
        self.assertEqual(len(tasks), 0)
        for tid in task_ids:
            task = tasks_api.task_get(task_id=tid)
            self.assertIsNone(task)
        # And the events
        events = events_api.events_get_all(story_id=story_id)
        self.assertEqual(len(events), 0)
        for eid in event_ids:
            event = events_api.event_get(event_id=eid)
            self.assertIsNone(event)
예제 #2
0
    def test_delete_story(self):
        # This test uses mock_data
        story_id = 1
        # Verify that we can look up a story with tasks and events
        story = stories_api.story_get_simple(story_id)
        self.assertIsNotNone(story)
        tasks = tasks_api.task_get_all(story_id=story_id)
        self.assertEqual(len(tasks), 3)
        task_ids = [t.id for t in tasks]
        events = events_api.events_get_all(story_id=story_id)
        self.assertEqual(len(events), 3)
        event_ids = [e.id for e in events]

        # Delete the story
        stories_api.story_delete(story_id)
        story = stories_api.story_get_simple(story_id)
        self.assertIsNone(story)
        # Verify that the story's tasks were deleted
        tasks = tasks_api.task_get_all(story_id=story_id)
        self.assertEqual(len(tasks), 0)
        for tid in task_ids:
            task = tasks_api.task_get(task_id=tid)
            self.assertIsNone(task)
        # And the events
        events = events_api.events_get_all(story_id=story_id)
        self.assertEqual(len(events), 0)
        for eid in event_ids:
            event = events_api.event_get(event_id=eid)
            self.assertIsNone(event)
예제 #3
0
    def get_all(self,
                story_id=None,
                marker=None,
                limit=None,
                sort_field='id',
                sort_dir='asc'):
        """Retrieve all comments posted under specified story.

        Example::

          curl https://my.example.org/api/v1/stories/11/comments

        :param story_id: Filter comments by story ID.
        :param marker: The resource id where the page should begin.
        :param limit: The number of comments to retrieve.
        :param sort_field: The name of the field to sort on.
        :param sort_dir: Sort direction for results (asc, desc).
        """
        current_user = request.current_user_id

        # Boundary check on limit.
        if limit is not None:
            limit = max(0, limit)

        # Resolve the marker record.
        marker_event = None
        if marker:
            event_query = \
                events_api.events_get_all(comment_id=marker,
                                          event_type=event_types.USER_COMMENT,
                                          current_user=current_user)
            if len(event_query) > 0:
                marker_event = event_query[0]

        events_count = events_api.events_get_count(
            story_id=story_id,
            event_type=event_types.USER_COMMENT,
            current_user=current_user)

        events = events_api.events_get_all(story_id=story_id,
                                           marker=marker_event,
                                           limit=limit,
                                           event_type=event_types.USER_COMMENT,
                                           sort_field=sort_field,
                                           sort_dir=sort_dir,
                                           current_user=current_user)

        comments = [
            comments_api.comment_get(event.comment_id) for event in events
        ]

        # Apply the query response headers.
        if limit:
            response.headers['X-Limit'] = str(limit)
        response.headers['X-Total'] = str(events_count)
        if marker_event:
            response.headers['X-Marker'] = str(marker)

        return [wmodels.Comment.from_db_model(comment) for comment in comments]
예제 #4
0
    def get_all(self, story_id=None, marker=None, limit=None, sort_field='id',
                sort_dir='asc'):
        """Retrieve all comments posted under specified story.

        Example::

          curl https://my.example.org/api/v1/stories/11/comments

        :param story_id: Filter comments by story ID.
        :param marker: The resource id where the page should begin.
        :param limit: The number of comments to retrieve.
        :param sort_field: The name of the field to sort on.
        :param sort_dir: Sort direction for results (asc, desc).
        """
        current_user = request.current_user_id

        # Boundary check on limit.
        if limit is not None:
            limit = max(0, limit)

        # Resolve the marker record.
        marker_event = None
        if marker:
            event_query = \
                events_api.events_get_all(comment_id=marker,
                                          event_type=event_types.USER_COMMENT,
                                          current_user=current_user)
            if len(event_query) > 0:
                marker_event = event_query[0]

        events_count = events_api.events_get_count(
            story_id=story_id,
            event_type=event_types.USER_COMMENT,
            current_user=current_user)

        events = events_api.events_get_all(story_id=story_id,
                                           marker=marker_event,
                                           limit=limit,
                                           event_type=event_types.USER_COMMENT,
                                           sort_field=sort_field,
                                           sort_dir=sort_dir,
                                           current_user=current_user)

        comments = [comments_api.comment_get(event.comment_id)
                    for event in events]

        # Apply the query response headers.
        if limit:
            response.headers['X-Limit'] = str(limit)
        response.headers['X-Total'] = str(events_count)
        if marker_event:
            response.headers['X-Marker'] = str(marker)

        return [wmodels.Comment.from_db_model(comment) for comment in comments]
예제 #5
0
    def get_all(self,
                story_id=None,
                event_type=None,
                marker=None,
                offset=None,
                limit=None,
                sort_field=None,
                sort_dir=None):
        """Retrieve all events that have happened under specified story.

        :param story_id: Filter events by story ID.
        :param event_type: A selection of event types to get.
        :param marker: The resource id where the page should begin.
        :param offset: The offset to start the page at.
        :param limit: The number of events to retrieve.
        :param sort_field: The name of the field to sort on.
        :param sort_dir: Sort direction for results (asc, desc).
        """

        # Boundary check on limit.
        if limit is not None:
            limit = max(0, limit)

        # Sanity check on event types.
        if event_type:
            for r_type in event_type:
                if r_type not in event_types.ALL:
                    msg = _('Invalid event_type requested. Event type must be '
                            'one of the following: %s')
                    msg = msg % (', '.join(event_types.ALL), )
                    abort(400, msg)

        # Resolve the marker record.
        marker_event = None
        if marker is not None:
            marker_event = events_api.event_get(marker)

        event_count = events_api.events_get_count(story_id=story_id,
                                                  event_type=event_type)
        events = events_api.events_get_all(story_id=story_id,
                                           event_type=event_type,
                                           marker=marker_event,
                                           offset=offset,
                                           limit=limit,
                                           sort_field=sort_field,
                                           sort_dir=sort_dir)

        # Apply the query response headers.
        if limit:
            response.headers['X-Limit'] = str(limit)
        response.headers['X-Total'] = str(event_count)
        if marker_event:
            response.headers['X-Marker'] = str(marker_event.id)
        if offset is not None:
            response.headers['X-Offset'] = str(offset)

        return [
            wmodels.TimeLineEvent.resolve_event_values(
                wmodels.TimeLineEvent.from_db_model(event)) for event in events
        ]
예제 #6
0
    def get_all(self, story_id=None, event_type=None, marker=None,
                offset=None, limit=None, sort_field=None, sort_dir=None):
        """Retrieve all events that have happened under specified story.

        Example::

          curl https://my.example.org/api/v1/stories/11/events

        :param story_id: Filter events by story ID.
        :param event_type: A selection of event types to get.
        :param marker: The resource id where the page should begin.
        :param offset: The offset to start the page at.
        :param limit: The number of events to retrieve.
        :param sort_field: The name of the field to sort on.
        :param sort_dir: Sort direction for results (asc, desc).
        """

        current_user = request.current_user_id

        # Boundary check on limit.
        if limit is not None:
            limit = max(0, limit)

        # Sanity check on event types.
        if event_type:
            for r_type in event_type:
                if r_type not in event_types.ALL:
                    msg = _('Invalid event_type requested. Event type must be '
                            'one of the following: %s')
                    msg = msg % (', '.join(event_types.ALL),)
                    abort(400, msg)

        # Resolve the marker record.
        marker_event = None
        if marker is not None:
            marker_event = events_api.event_get(marker)

        event_count = events_api.events_get_count(story_id=story_id,
                                                  event_type=event_type,
                                                  current_user=current_user)
        events = events_api.events_get_all(story_id=story_id,
                                           event_type=event_type,
                                           marker=marker_event,
                                           offset=offset,
                                           limit=limit,
                                           sort_field=sort_field,
                                           sort_dir=sort_dir,
                                           current_user=current_user)

        # Apply the query response headers.
        if limit:
            response.headers['X-Limit'] = str(limit)
        response.headers['X-Total'] = str(event_count)
        if marker_event:
            response.headers['X-Marker'] = str(marker_event.id)
        if offset is not None:
            response.headers['X-Offset'] = str(offset)

        return [wmodels.TimeLineEvent.resolve_event_values(
            wmodels.TimeLineEvent.from_db_model(event)) for event in events]
예제 #7
0
    def put(self, story_id, comment_id, comment_body):
        """Update an existing comment.

        :param story_id: A placeholder.
        :param comment_id: The id of a Comment to be updated.
        :param comment_body: An updated Comment.
        """

        comments_api.comment_get(comment_id)
        comment_author_id = events_api.events_get_all(
            comment_id=comment_id)[0].author_id
        if request.current_user_id != comment_author_id:
            abort(403, _("You are not allowed to update this comment."))

        updated_comment = comments_api.comment_update(
            comment_id, comment_body.as_dict(omit_unset=True))

        return wmodels.Comment.from_db_model(updated_comment)
예제 #8
0
def resolve_comments(event):
    event_info = {
        'comment_id': event.comment_id or None,
    }

    # Retrieve the content of the comment.
    comment = comments_api.comment_get(event.comment_id)
    event_info['comment_content'] = comment.content

    # Retrieve the story ID of the comment.
    timeline_events = timeline_api.events_get_all(comment_id=event.comment_id)
    if timeline_events:
        story = story_api.story_get(timeline_events[0].story_id)

        if story:
            event_info['story_id'] = story.id
            event_info['story_title'] = story.title

    return json.dumps(event_info)
예제 #9
0
    def put(self, story_id, comment_id, comment_body):
        """Update an existing comment.

        :param story_id: A placeholder.
        :param comment_id: The id of a Comment to be updated.
        :param comment_body: An updated Comment.
        """

        comments_api.comment_get(comment_id)
        comment_author_id = events_api.events_get_all(
            comment_id=comment_id)[0].author_id
        if request.current_user_id != comment_author_id:
            abort(403, _("You are not allowed to update this comment."))

        updated_comment = comments_api.comment_update(comment_id,
                                                      comment_body.as_dict(
                                                          omit_unset=True
                                                      ))

        return wmodels.Comment.from_db_model(updated_comment)
예제 #10
0
    def put(self, story_id, comment_id, comment_body):
        """Update an existing comment. This command is disabled by default.

        :param story_id: A placeholder.
        :param comment_id: The id of a Comment to be updated.
        :param comment_body: An updated Comment.
        """
        if not CONF.enable_editable_comments:
            abort(
                405,
                _("Editing of comments is disabled "
                  "by the server administrator."))

        comments_api.comment_get(comment_id)
        comment_author_id = events_api.events_get_all(
            comment_id=comment_id)[0].author_id
        if request.current_user_id != comment_author_id:
            abort(403, _("You are not allowed to update this comment."))

        updated_comment = comments_api.comment_update(
            comment_id, comment_body.as_dict(omit_unset=True))

        return wmodels.Comment.from_db_model(updated_comment)
예제 #11
0
    def put(self, story_id, comment_id, comment_body):
        """Update an existing comment. This command is disabled by default.

        :param story_id: A placeholder.
        :param comment_id: The id of a Comment to be updated.
        :param comment_body: An updated Comment.
        """
        if not CONF.enable_editable_comments:
            abort(405, _("Editing of comments is disabled "
                         "by the server administrator."))

        comments_api.comment_get(comment_id)
        comment_author_id = events_api.events_get_all(
            comment_id=comment_id)[0].author_id
        if request.current_user_id != comment_author_id:
            abort(403, _("You are not allowed to update this comment."))

        updated_comment = comments_api.comment_update(comment_id,
                                                      comment_body.as_dict(
                                                          omit_unset=True
                                                      ))

        return wmodels.Comment.from_db_model(updated_comment)
예제 #12
0
    def get_all(self,
                story_id=None,
                worklist_id=None,
                board_id=None,
                event_type=None,
                offset=None,
                limit=None,
                sort_field=None,
                sort_dir=None):
        """Retrieve a filtered list of all events.

        With no filters or limit set this will likely take a long time
        and return a very long list. Applying some filters is recommended.

        Example::

          curl https://my.example.org/api/v1/events

        :param story_id: Filter events by story ID.
        :param worklist_id: Filter events by worklist ID.
        :param board_id: Filter events by board ID.
        :param event_type: A selection of event types to get.
        :param offset: The offset to start the page at.
        :param limit: The number of events to retrieve.
        :param sort_field: The name of the field to sort on.
        :param sort_dir: Sort direction for results (asc, desc).
        """
        current_user = request.current_user_id

        # Boundary check on limit.
        if limit is not None:
            limit = max(0, limit)

        # Sanity check on event types.
        if event_type:
            for r_type in event_type:
                if r_type not in event_types.ALL:
                    msg = _('Invalid event_type requested. Event type must be '
                            'one of the following: %s')
                    msg = msg % (', '.join(event_types.ALL), )
                    abort(400, msg)

        events = events_api.events_get_all(story_id=story_id,
                                           worklist_id=worklist_id,
                                           board_id=board_id,
                                           event_type=event_type,
                                           sort_field=sort_field,
                                           sort_dir=sort_dir,
                                           current_user=current_user)

        # Apply the query response headers.
        if limit:
            response.headers['X-Limit'] = str(limit)
        if offset is not None:
            response.headers['X-Offset'] = str(offset)

        visible = [
            event for event in events
            if events_api.is_visible(event, current_user)
        ]

        if offset is None:
            offset = 0
        if limit is None:
            limit = len(visible)

        response.headers['X-Total'] = str(len(visible))

        return [
            wmodels.TimeLineEvent.resolve_event_values(
                wmodels.TimeLineEvent.from_db_model(event))
            for event in visible[offset:limit + offset]
        ]
예제 #13
0
    def get_all(self, story_id=None, worklist_id=None, board_id=None,
                event_type=None, offset=None, limit=None,
                sort_field=None, sort_dir=None):
        """Retrieve a filtered list of all events.

        With no filters or limit set this will likely take a long time
        and return a very long list. Applying some filters is recommended.

        Example::

          curl https://my.example.org/api/v1/events

        :param story_id: Filter events by story ID.
        :param worklist_id: Filter events by worklist ID.
        :param board_id: Filter events by board ID.
        :param event_type: A selection of event types to get.
        :param offset: The offset to start the page at.
        :param limit: The number of events to retrieve.
        :param sort_field: The name of the field to sort on.
        :param sort_dir: Sort direction for results (asc, desc).
        """
        current_user = request.current_user_id

        # Boundary check on limit.
        if limit is not None:
            limit = max(0, limit)

        # Sanity check on event types.
        if event_type:
            for r_type in event_type:
                if r_type not in event_types.ALL:
                    msg = _('Invalid event_type requested. Event type must be '
                            'one of the following: %s')
                    msg = msg % (', '.join(event_types.ALL),)
                    abort(400, msg)

        events = events_api.events_get_all(story_id=story_id,
                                           worklist_id=worklist_id,
                                           board_id=board_id,
                                           event_type=event_type,
                                           sort_field=sort_field,
                                           sort_dir=sort_dir,
                                           current_user=current_user)

        # Apply the query response headers.
        if limit:
            response.headers['X-Limit'] = str(limit)
        if offset is not None:
            response.headers['X-Offset'] = str(offset)

        visible = [event for event in events
                   if events_api.is_visible(event, current_user)]

        if offset is None:
            offset = 0
        if limit is None:
            limit = len(visible)

        response.headers['X-Total'] = str(len(visible))

        return [wmodels.TimeLineEvent.resolve_event_values(
                wmodels.TimeLineEvent.from_db_model(event))
                for event in visible[offset:limit + offset]]