Пример #1
0
    def delete(self, story_id):
        try:
            # get token from header
            token = self._get_token_from_header()

            # identify with token
            username = Token.identify(token)

            # get story by story_id
            story = Story.get_story(story_id)

            # if username is not the uploader return 403
            story_uploader = story["username"]
            self.logger.debug("At DELETE@/stories requesting user is {} and uploader is {}".format(
                username, story_uploader))
            if username != story_uploader:
                return ResponseBuilder.build_error_response("Story is not own", 403)

            # delete story
            deleted_story_obj = Story.delete_story(story_id)
            deleted_story_id = str(deleted_story_obj)

            # generate response
            output = {"target_story_id": deleted_story_id}

            # return response
            return ResponseBuilder.build_response(output)

        except (InvalidTokenException, ExpiredTokenException,
                StoryNotFoundException, MissingFieldException) as e:
            return ResponseBuilder.build_error_response(e.message, e.error_code)
Пример #2
0
    def test_delete_reaction_not_found(self):
        with patch.object(Persistence, "unset_on_one") as mocked_delete_reaction,\
             self.assertRaises(StoryReactionNotFoundException) as context:
            mocked_delete_reaction.side_effect = MagicMock(return_value=None)

            Story.delete_reaction(object_id_mock, "pedro")
        exc = context.exception
        self.assertEqual(exc.error_code, 404)
        self.assertEqual(exc.message, "Story reaction was not found")
Пример #3
0
def create_indexes():
    Logger(__name__).debug('Creating indexes for DB')

    # indexes for User
    User._get_coll().create_index("username")

    # indexes for Story
    Story._get_coll().create_index("username")

    # indexes for Comments
    StoryComment._get_coll().create_index("story_id")
Пример #4
0
    def test_get_story_not_found(self):
        with patch.object(Persistence, "get_one") as mocked_story_get, \
             self.assertRaises(StoryNotFoundException) as context:

            mocked_story_get.side_effect = MagicMock(return_value=None)

            mocked_story_id = object_id_mock

            Story.get_story(mocked_story_id)

        exc = context.exception
        self.assertEqual(exc.error_code, 404)
Пример #5
0
    def test_delete_story_not_found(self):
        with patch.object(Persistence, "delete_one") as mocked_delete_one,\
             self.assertRaises(StoryNotFoundException) as context,\
             patch.object(StoryComment, "delete_comments_on_story") as mocked_delete_comments:

            mocked_internal_story = dict(story_mock_private_with_reaction)
            mocked_internal_story["_id"] = object_id_mock

            mocked_delete_one.side_effect = MagicMock(return_value=None)
            mocked_delete_comments.side_effect = MagicMock()  # do nothing

            Story.delete_story(object_id_mock)
        exc = context.exception
        self.assertEqual(exc.error_code, 404)
        self.assertEqual(exc.message, "Story was not found")
Пример #6
0
    def post(self, story_id):
        try:
            # get token from header
            token = self._get_token_from_header()

            # identify with token
            username = Token.identify(token)

            # get data from request
            comment_text = self._get_comment_text_from_request()
            timestamp = self._get_timestamp_from_request()

            # sanitize data
            timestamp = InputSanitizer.sanitize_positive_integer(timestamp)

            # post reaction to story by story_id
            saved_comment = Story.comment_on_story(story_id, username, comment_text, timestamp)

            # generate response
            output = saved_comment

            # return response
            return ResponseBuilder.build_response(output)

        except (InvalidTokenException, ExpiredTokenException, InvalidFormatException,
                MissingFieldException, StoryNotFoundException) as e:
            return ResponseBuilder.build_error_response(e.message, e.error_code)
Пример #7
0
    def test_get_feed_data_from_one_story_object(self):
        with patch.object(StoryComment,
                          "get_comments_on_story") as mocked_get_comments:
            mocked_get_comments.side_effect = MagicMock(return_value=[])

            aux_story = dict(story_mock_private_with_reaction)
            aux_story["_id"] = object_id_mock

            reactions = [x for x in aux_story["reactions"].values()]

            expected_feed_data = {
                "story_id": object_id_mock,
                "title": aux_story['title'],
                "description": aux_story['description'],
                "likes": reactions.count(STORY_REACTION_LIKE),
                "dislikes": reactions.count(STORY_REACTION_DISLIKE),
                "funnies": reactions.count(STORY_REACTION_FUNNY),
                "borings": reactions.count(STORY_REACTION_BORING),
                "number of comments": len(aux_story['comments']),
                "location": aux_story['location'],
                "timestamp": aux_story['timestamp'],
                "is_private": aux_story['is_private'],
                "uploader": aux_story["username"]
            }

            self.assertEqual(Story._get_feed_story_data(aux_story),
                             expected_feed_data)
Пример #8
0
    def get(self, story_id):
        try:
            # get token from header
            token = self._get_token_from_header()

            # identify with token
            username = Token.identify(token)

            # get story by story_id
            story = Story.get_story(story_id)

            # if <username is not the uploader> and <story is private> and ...
            # ... <uploader and username are not friends> return 403

            is_private = story["is_private"]
            story_uploader = story["username"]
            self.logger.debug("At GET@/stories requesting user is {}, uploader is {} and story {} private".format(
                username, story_uploader, "is" if is_private else "is not"))
            if username != story_uploader and \
               InputSanitizer.sanitize_boolean(is_private) and \
               not Friendship.are_friends(username, story_uploader):
                return ResponseBuilder.build_error_response("Story is private", 403)

            # generate response

            # return response
            return ResponseBuilder.build_response(story)

        except (InvalidTokenException, MissingFieldException, ExpiredTokenException,
                StoryNotFoundException) as e:
            return ResponseBuilder.build_error_response(e.message, e.error_code)
Пример #9
0
    def test_get_stories_by_username_not_empty(self):
        with patch.object(Persistence, "get_many") as mocked_get_many,\
             patch.object(StoryComment, "get_comments_on_story") as mocked_get_comments,\
             patch.object(Story, "_serialize_story") as mocked_serialize:

            aux_timestamp = 123123
            aux_story1 = dict(story_mock_private_with_reaction)
            aux_story1["timestamp"] = aux_timestamp
            aux_story1["_id"] = object_id_mock

            aux_story2 = dict(aux_story1)
            aux_story2["timestamp"] = aux_timestamp + 1

            aux_story3 = dict(aux_story1)
            aux_story3["timestamp"] = aux_timestamp + 2

            unsorted_stories = [aux_story1, aux_story3, aux_story2]
            sorted_stories = [aux_story3, aux_story2, aux_story1]

            mocked_get_many.side_effect = MagicMock(
                return_value=unsorted_stories)
            mocked_get_comments.side_effect = MagicMock(return_value=[])
            mocked_serialize.side_effect = lambda x: x

            self.assertEqual(Story.get_stories_by_username("pepe"),
                             sorted_stories)
Пример #10
0
    def post(self, story_id):
        try:
            # get token from header
            token = self._get_token_from_header()

            # identify with token
            username = Token.identify(token)

            # get the reaction type
            reaction = self._get_reaction_from_request()
            reaction = InputSanitizer.sanitize_story_reaction(reaction)

            # post reaction to story by story_id
            saved_reaction = Story.react_to_story(story_id, username, reaction)

            # generate response
            output = {"reacting_user_id": username, "reaction": saved_reaction}

            # return response
            return ResponseBuilder.build_response(output)

        except (InvalidTokenException, ExpiredTokenException,
                InvalidFormatException, MissingFieldException,
                StoryNotFoundException) as e:
            return ResponseBuilder.build_error_response(
                e.message, e.error_code)
Пример #11
0
    def _build_profile_from_user(user_data, caller_username):
        # retrieve all stories uploaded by username
        friend_ids = [
            friend_id
            for friend_id, friendship_state in user_data["friends"].items()
            if friendship_state == "friends"
        ]

        # include privates only if caller username is a friend of target user or him/herself
        target_ids = friend_ids + [user_data["username"]]
        stories = Story.get_stories_by_username(user_data["username"],
                                                caller_username in target_ids)

        # return the profile
        return {
            # general data
            'username': user_data['username'],
            'profile_pic': user_data['profile_pic'],
            'name': user_data['name'],
            # stories uploaded
            'stories': stories,
            # interesting numbers
            'number of friends': len(friend_ids),
            'number of stories': len(stories)
        }
Пример #12
0
    def _format_feed_story(story_id):
        serialized_story = Story.get_story(story_id)
        uploader = serialized_story['username']
        profile_preview = User.get_profile_preview(uploader)

        serialized_story['name'] = profile_preview['name']
        serialized_story['profile_pic'] = profile_preview['profile_pic']
        return serialized_story
Пример #13
0
    def test_successful_save_new(self):
        with patch.object(Persistence, "insert_one") as mocked_story_insert:
            mocked_story_insert.side_effect = self.mocked_story_insert_one

            story_data = dict(story_data_mock_with_title_and_description)
            story_data['username'] = "******"

            self.assertEqual(Story.save_new(story_data), object_id_mock)
Пример #14
0
 def save_new_story(story_data):
     """Facade for Story.save_new, also checks that user indeed exists"""
     username = story_data['username']
     Logger(__name__).info(
         'Trying to save new story for user {}.'.format(username))
     # check user exists
     user = User._get_one({'username': username})
     if user is None:
         raise UserNotFoundException
     return Story.save_new(story_data)
Пример #15
0
    def _safe_delete_user(user):
        # delete from every friend
        username = user['username']
        for friend_name in user['friends']:
            friend_user = User._get_one({'username': friend_name})
            # if for any reason user didn't exist anymore, continue silently
            if friend_user is None:
                continue
            # friend_user['friends'].pop(username)
            entry = 'friends.' + username
            User._delete_field_by_username(friend_user['username'],
                                           {entry: ""})
        # delete every owned Story and (related Reactions and Comments? should they be deleted?)
        Story.delete_stories_from_user(username)
        Flash.delete_flashes_from_user(username)

        # now that the user is isolated, delete it
        User._delete_one(username)
        return username
Пример #16
0
    def test_successful_delete_reaction(self):
        with patch.object(Persistence,
                          "unset_on_one") as mocked_delete_reaction:
            mocked_delete_reaction.side_effect = MagicMock(
                return_value=story_mock_private_with_reaction)

            mocked_username, mocked_reaction = first_item_of_dict(
                story_mock_private_with_reaction["reactions"])

            self.assertEqual(
                Story.delete_reaction(object_id_mock, mocked_username),
                mocked_reaction)
Пример #17
0
    def test_successful_delete_story(self):
        with patch.object(Persistence, "delete_one") as mocked_delete_one,\
             patch.object(StoryComment, "delete_comments_on_story") as mocked_delete_comments:

            mocked_internal_story = dict(story_mock_private_with_reaction)
            mocked_internal_story["_id"] = object_id_mock

            mocked_delete_one.side_effect = MagicMock(
                return_value=mocked_internal_story)
            mocked_delete_comments.side_effect = MagicMock()  # do nothing

            self.assertEqual(Story.delete_story(object_id_mock),
                             object_id_mock)
Пример #18
0
    def test_successful_get_story_private(self):
        with patch.object(Persistence, "get_one") as mocked_story_get,\
             patch.object(StoryComment, "get_comments_on_story") as mocked_get_comments:
            # prepare special mock
            aux = story_mock_private_without_comments_or_reactions
            internal_story_mock = dict(aux)
            internal_story_mock["is_private"] = True
            internal_story_mock["timestamp"] = 1615456
            internal_story_mock["_id"] = aux['story_id']

            mocked_story_get.side_effect = MagicMock(
                return_value=internal_story_mock)
            mocked_story_id = aux['story_id']
            mocked_get_comments.side_effect = MagicMock(return_value=[])

            self.assertEqual(Story.get_story(mocked_story_id), aux)
Пример #19
0
    def _get_stories_feed_data(username, include_privates=False):
        """Formats stories uploaded by this user for easier use of the Feed Builder."""
        # get all stories feed data from username
        story_feed_blocks = Story.get_stories_feed_data_by_username(
            username, include_privates)

        # get user specific feed data
        user_feed_data = User._get_user_feed_data(username,
                                                  len(story_feed_blocks))

        # add them to story feed blocks
        [
            story_feed_block.update(user_feed_data)
            for story_feed_block in story_feed_blocks
        ]
        return story_feed_blocks
Пример #20
0
    def test_successful_post_reaction(self):
        with patch.object(Persistence, "update_one") as mocked_story_update,\
             patch.object(Persistence, "get_one") as mocked_get_one:
            aux = story_mock_private_with_reaction.copy()
            mocked_story_update.side_effect = MagicMock(
                return_value=story_mock_private_with_reaction)
            mocked_get_one.side_effect = MagicMock(
                return_value=object_id_mock
            )  # just a placeholder, not what it's actually expected

            mocked_story_id = object_id_mock
            mocked_username, mocked_reaction = first_item_of_dict(
                aux["reactions"])

            self.assertEqual(
                Story.react_to_story(mocked_story_id, mocked_username,
                                     mocked_reaction), mocked_reaction)
Пример #21
0
    def test_get_stories_by_username_empty(self):
        with patch.object(Persistence, "get_many") as mocked_get_many:
            mocked_get_many.side_effect = MagicMock(return_value=[])

            self.assertEqual(Story.get_stories_by_username("pepe"), [])