예제 #1
0
    def test_check_post(self):
        """
        Will test that check_post returns the correct value with various
        combinations.

        Note: Bare with this one it is quite tedious.
        """
        # Create two test users
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')
        # Create a post
        post1 = create_post(user1, 'user1', 'Test post')
        # check_post should be True when user 1 creates post 1
        self.assertTrue(check_post(user1, post1))
        # check_post should be false, user 2 didn't create post 1
        self.assertFalse(check_post(user2, post1))
        # Create a couple of comments
        comment1 = create_post(user1, 'user1', 'Test comment', post1)
        comment2 = create_post(user2, 'user2', 'Test comment', post1)

        # Ensure the check_post is fine for all
        self.assertTrue(check_post(user1, post1, comment1))
        # This does not look correct but is. See backend.py@check_post
        self.assertTrue(check_post(user1, post1, comment1))

        # Ensure the function isn't broken on comments
        self.assertFalse(check_post(user2, post1, comment1))
        self.assertFalse(check_post(user1, K.NIL_VALUE, comment1))
        self.assertFalse(check_post(user2, K.NIL_VALUE, comment2))
예제 #2
0
    def test_get_posts(self):
        """
        Test users post list works correctly
        """
        # Create test user
        user1 = create_account('user1', '*****@*****.**', 'Password')
        # Ensure the users post list is empty
        self.assertEqual(len(get_posts(user1).items), 0)

        # Create a few test posts, ensure they appears in the users list
        post1 = create_post(user1, 'user1', 'Test post 1')
        post2 = create_post(user1, 'user1', 'Test post 2')
        create_post(user1, 'user1', 'Test post 3')
        self.assertEqual(len(get_posts(user1).items), 3)
        self.assertEqual(get_posts(user1).total, 3)

        # Delete one of the posts and ensure that it does not appear in the
        # list.
        delete_post(post1)

        # Ensure the above is now correct with post1 missing
        self.assertEqual(len(get_posts(user1).items), 2)
        self.assertEqual(get_posts(user1).total, 2)

        # Delete a post from MongoDB with the driver
        m.db.posts.remove({'_id': post2})
        # Ensure the above is now correct with post2 missing
        self.assertEqual(len(get_posts(user1).items), 1)
        self.assertEqual(get_posts(user1).total, 1)
예제 #3
0
    def test_get_feed(self):
        """
        Attempt to get a users feed under certain circumstances.
        """
        # Get test user
        user1 = create_account('user1', '*****@*****.**', 'Password')
        # Ensure an empty feed is returned. Remember these are paginations
        self.assertEqual(len(get_feed(user1).items), 0)
        # Ensure a users own post is added to thier feed
        post1 = create_post(user1, 'user1', 'Test post')
        # Ensure the list is the correct length
        self.assertEqual(len(get_feed(user1).items), 1)
        self.assertEqual(get_feed(user1).total, 1)
        # Ensure the item is in Redis
        self.assertIn(post1, r.zrange(K.USER_FEED.format(user1), 0, -1))

        # Create a second user, make 1 follow them, make then post and ensure
        # that the new users post appears in user 1s feed
        user2 = create_account('user2', '*****@*****.**', 'Password')
        follow_user(user1, user2)

        post2 = create_post(user2, 'user2', 'Test post')
        # Check user 1's feed for the next item
        self.assertEqual(len(get_feed(user1).items), 2)
        self.assertEqual(get_feed(user1).total, 2)
        # Ensure the item is in Redis
        self.assertIn(post2, r.zrange(K.USER_FEED.format(user1), 0, -1))
        # Delete user 2 and ensure user 1's feed cleans itself
        delete_account(user2)
        self.assertEqual(len(get_feed(user1).items), 1)
        self.assertEqual(get_feed(user1).total, 1)
        # Ensure the item is not in Redis
        self.assertNotIn(post2, r.zrange(K.USER_FEED.format(user1), 0, -1))
예제 #4
0
    def test_get_posts(self):
        """
        Test users post list works correctly
        """
        # Create test user
        user1 = create_account('user1', '*****@*****.**', 'Password')
        # Ensure the users post list is empty
        self.assertEqual(len(get_posts(user1).items), 0)

        # Create a few test posts, ensure they appears in the users list
        post1 = create_post(user1, 'user1', 'Test post 1')
        post2 = create_post(user1, 'user1', 'Test post 2')
        create_post(user1, 'user1', 'Test post 3')
        self.assertEqual(len(get_posts(user1).items), 3)
        self.assertEqual(get_posts(user1).total, 3)

        # Delete one of the posts and ensure that it does not appear in the
        # list.
        delete_post(post1)

        # Ensure the above is now correct with post1 missing
        self.assertEqual(len(get_posts(user1).items), 2)
        self.assertEqual(get_posts(user1).total, 2)

        # Delete a post from MongoDB with the driver
        m.db.posts.remove({'_id': post2})
        # Ensure the above is now correct with post2 missing
        self.assertEqual(len(get_posts(user1).items), 1)
        self.assertEqual(get_posts(user1).total, 1)
예제 #5
0
    def test_check_post(self):
        """
        Will test that check_post returns the correct value with various
        combinations.

        Note: Bare with this one it is quite tedious.
        """
        # Create two test users
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')
        # Create a post
        post1 = create_post(user1, 'user1', 'Test post')
        # check_post should be True when user 1 creates post 1
        self.assertTrue(check_post(user1, post1))
        # check_post should be false, user 2 didn't create post 1
        self.assertFalse(check_post(user2, post1))
        # Create a couple of comments
        comment1 = create_post(user1, 'user1', 'Test comment', post1)
        comment2 = create_post(user2, 'user2', 'Test comment', post1)

        # Ensure the check_post is fine for all
        self.assertTrue(check_post(user1, post1, comment1))
        # This does not look correct but is. See backend.py@check_post
        self.assertTrue(check_post(user1, post1, comment1))

        # Ensure the function isn't broken on comments
        self.assertFalse(check_post(user2, post1, comment1))
        self.assertFalse(check_post(user1, K.NIL_VALUE, comment1))
        self.assertFalse(check_post(user2, K.NIL_VALUE, comment2))
예제 #6
0
    def test_get_feed(self):
        """
        Attempt to get a users feed under certain circumstances.
        """
        # Get test user
        user1 = create_account('user1', '*****@*****.**', 'Password')
        # Ensure an empty feed is returned. Remember these are paginations
        self.assertEqual(len(get_feed(user1).items), 0)
        # Ensure a users own post is added to thier feed
        post1 = create_post(user1, 'user1', 'Test post')
        # Ensure the list is the correct length
        self.assertEqual(len(get_feed(user1).items), 1)
        self.assertEqual(get_feed(user1).total, 1)
        # Ensure the item is in Redis
        self.assertIn(post1, r.zrange(K.USER_FEED.format(user1), 0, -1))

        # Create a second user, make 1 follow them, make then post and ensure
        # that the new users post appears in user 1s feed
        user2 = create_account('user2', '*****@*****.**', 'Password')
        follow_user(user1, user2)

        post2 = create_post(user2, 'user2', 'Test post')
        # Check user 1's feed for the next item
        self.assertEqual(len(get_feed(user1).items), 2)
        self.assertEqual(get_feed(user1).total, 2)
        # Ensure the item is in Redis
        self.assertIn(post2, r.zrange(K.USER_FEED.format(user1), 0, -1))
        # Delete user 2 and ensure user 1's feed cleans itself
        delete_account(user2)
        self.assertEqual(len(get_feed(user1).items), 1)
        self.assertEqual(get_feed(user1).total, 1)
        # Ensure the item is not in Redis
        self.assertNotIn(post2, r.zrange(K.USER_FEED.format(user1), 0, -1))
예제 #7
0
    def test_search(self):
        """Make sure users can actually find things on the site."""
        # Create test user
        user1 = create_account('user1', '*****@*****.**', 'Password')
        # Ensure that the user can be found
        self.assertEqual(len(search('user1').items), 1)
        self.assertEqual(search('user1').total, 1)
        # Ensure partial match
        self.assertEqual(len(search('use').items), 1)
        self.assertEqual(search('use').total, 1)
        # Ensure nothing return if no user
        self.assertEqual(len(search('user2').items), 0)
        self.assertEqual(search('user2').total, 0)
        # Ensure no partial if incorrect
        self.assertEqual(len(search('bob').items), 0)
        self.assertEqual(search('bob').total, 0)

        # Create a second test user and a post with a hashtag and
        # ensure both show in the results.
        user2 = create_account('user2', '*****@*****.**', 'Password')
        # Create the post as user1 as we are going to delete user2
        create_post(user1, 'user1', '#user2')
        # Ensure the new user can be found
        self.assertEqual(len(search('user2').items), 2)
        self.assertEqual(search('user2').total, 2)
        # Ensure partial match returns both test1/2 users
        self.assertEqual(len(search('use').items), 3)
        self.assertEqual(search('use').total, 3)

        # Delete the account user2 and try searching again
        # Only the hashtag should show
        delete_account(user2)
        self.assertEqual(search('user2').total, 1)
예제 #8
0
    def test_dump_account(self):
        """
        Test dump_account. We will create some posts and comments and check all
        this data appears in the dumps

        Remember that ALL data coming out of Redis is a string. We are not
        going to convert each type. EVERYTHING IS A STRING
        """
        user1 = create_user('user1', '*****@*****.**', 'Password')

        # Dump the account so that we can test :D
        data = dump_account(user1)

        # Check we got some data
        self.assertIsNotNone(data)
        # Ensure that we can see the data in the 'user' key
        self.assertEqual('user1', data['user']['username'])
        self.assertEqual('0', data['user']['active'])
        # Check that uid and password have been scrubbed
        self.assertEqual('<UID>', data['user']['uid'])
        self.assertEqual('<PASSWORD HASH>', data['user']['password'])
        # Ensure posts and comments are None
        self.assertEqual([], data['posts'])
        self.assertEqual([], data['comments'])

        # Create some posts as the user and check they are in the dumps
        post1 = create_post(user1, 'Post 1')
        post2 = create_post(user1, 'Post 2')
        post3 = create_post(user1, 'Post 3')

        data = dump_account(user1)
        self.assertIsNotNone(data)
        # Ensure that the posts are there
        self.assertNotEqual([], data['posts'])
        self.assertEqual('Post 1', data['posts'][2]['body'])
        self.assertEqual('Post 2', data['posts'][1]['body'])
        self.assertEqual('Post 3', data['posts'][0]['body'])
        # Ensure there is no a uid in the post
        self.assertEqual('<UID>', data['posts'][0]['uid'])

        # Create some comments on the above posts and re-dump
        comment1 = create_comment(user1, post1, 'Comment 1')
        comment2 = create_comment(user1, post1, 'Comment 2')
        comment3 = create_comment(user1, post2, 'Comment 3')
        comment4 = create_comment(user1, post3, 'Comment 4')

        # Re-dump the database
        data = dump_account(user1)
        self.assertNotEqual([], data['comments'])
        # Check that all 4 comments have been dumped

        self.assertEqual('Comment 1', data['comments'][3]['body'])
        self.assertEqual('Comment 2', data['comments'][2]['body'])
        self.assertEqual('Comment 3', data['comments'][1]['body'])
        self.assertEqual('Comment 4', data['comments'][0]['body'])

        # Testing running dump account with a non-existant user
        self.assertIsNone(dump_account(K.NIL_VALUE))
예제 #9
0
    def test_create_post(self):
        """Tests creating and getting a post

        """
        # Create a user to test creating post
        user1 = create_account('user1', '*****@*****.**', 'Password')
        # Create post
        post1 = create_post(user1, 'user1', 'Test post')
        # Check the post actually exists
        self.assertIsNotNone(post1)

        # Check that all the hash members are what we expect
        post = get_post(post1)
        self.assertIsNotNone(post)
        self.assertEqual(post.get('_id'), post1)
        self.assertEqual(post.get('user_id'), user1)
        self.assertEqual(post.get('body'), 'Test post')
        self.assertEqual(post.get('score'), 0)
        self.assertEqual(post.get('comment_count'), 0)
        # Check the memebers we don't know the answer to
        self.assertIsNotNone(post.get('created'))
        self.assertNotIn('upload', post)

        # Ensure this post is the users feed (populate_feed)
        self.assertIn(post1, r.zrange(K.USER_FEED.format(user1), 0, -1))

        # Testing getting post with invalid arguments
        # Test getting a post that does not exist
        self.assertIsNone(get_post(K.NIL_VALUE))

        # Create a post with an image
        image = io.BytesIO(open('tests/upload_test_files/otter.jpg').read())
        post2 = create_post(user1, 'user1', 'Test post #2', upload=image)

        self.assertIsNotNone(post2)

        post = get_post(post2)
        self.assertIn('upload', post)
        self.assertIsNotNone(post.get('upload'))

        image = io.BytesIO(open('tests/upload_test_files/otter.gif').read())
        post3 = create_post(user1, 'user1', 'Test post #2', upload=image)

        self.assertIsNotNone(post3)

        post = get_post(post3)
        self.assertIn('upload', post)
        self.assertIn('upload_animated', post)
        self.assertIsNotNone(post.get('upload'))
        self.assertIsNotNone(post.get('upload_animated'))

        # Create a post with a broken image, ensure it's handled correctly
        image = io.BytesIO()
        post4 = create_post(user1, 'user1', 'Test post #3', upload=image)
        self.assertIsNone(post4)
        post4 = get_post(post4)
        self.assertIsNone(post4)
예제 #10
0
    def test_delete_account_posts_replies(self):
        """Do all posts and replies get removed on deletion of account?

        """
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')

        post1 = create_post(user1, 'user1', 'Test post')
        post2 = create_post(user2, 'user2', 'Test post')

        # Create multiple comments on both posts
        comment1 = create_post(user1, 'user1', "Test comment", post1)
        create_post(user1, 'user1', "Test comment", post1)
        create_post(user1, 'user1', "Test comment", post1)
        create_post(user1, 'user1', "Test comment", post2)

        delete_account(user1)

        # All posts created by user1 and the replies on those post, gone?
        self.assertIsNone(m.db.posts.find_one({'_id': post1}))
        self.assertIsNone(m.db.posts.find_one({'reply_to': post1}))

        # Ensure the reply is gone
        self.assertIsNone(m.db.posts.find_one({'_id': comment1}))

        # Is feed empty?
        self.assertFalse(r.lrange(K.USER_FEED.format(user1), 0, -1))
예제 #11
0
    def test_delete_account_posts_replies(self):
        """Do all posts and replies get removed on deletion of account?

        """
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')

        post1 = create_post(user1, 'user1', 'Test post')
        post2 = create_post(user2, 'user2', 'Test post')

        # Create multiple comments on both posts
        comment1 = create_post(user1, 'user1', "Test comment", post1)
        create_post(user1, 'user1', "Test comment", post1)
        create_post(user1, 'user1', "Test comment", post1)
        create_post(user1, 'user1', "Test comment", post2)

        delete_account(user1)

        # All posts created by user1 and the replies on those post, gone?
        self.assertIsNone(m.db.posts.find_one({'_id': post1}))
        self.assertIsNone(m.db.posts.find_one({'reply_to': post1}))

        # Ensure the reply is gone
        self.assertIsNone(m.db.posts.find_one({'_id': comment1}))

        # Is feed empty?
        self.assertFalse(r.lrange(K.USER_FEED.format(user1), 0, -1))
예제 #12
0
    def test_create_reply(self):
        """Test that a reply can be made on a post

        """
        user1 = create_account('user1', '*****@*****.**', 'Password')
        # Create a second test user to test commenting on someone else post
        user2 = create_account('user2', '*****@*****.**', 'Password')
        # Create post
        post1 = create_post(user1, 'user1', 'Test post')
        # Create comment
        reply1 = create_post(user1, 'user1', 'Test comment', post1)
        # Check the comment was created
        self.assertIsNotNone(get_post(reply1))
        # Create a comment by the second user
        reply2 = create_post(user2, 'user1', 'Test comment', post1)
        # Check the comment was created
        self.assertIsNotNone(get_post(reply2))

        # Check the comment hash has the data we expect, we will do this with
        # comment1
        comment = get_post(reply1)
        self.assertIsNotNone(comment)
        self.assertEqual(comment.get('_id'), reply1)
        self.assertEqual(comment.get('user_id'), user1)
        self.assertEqual(comment.get('reply_to'), post1)
        self.assertEqual(comment.get('body'), 'Test comment')
        self.assertEqual(comment.get('score'), 0)
        self.assertIsNotNone(comment.get('created'))
        self.assertNotIn('upload', comment)

        # Create a post with an image
        image = io.BytesIO(open('tests/upload_test_files/otter.jpg').read())
        reply1 = create_post(user1,
                             'user1',
                             'Test post #2',
                             reply_to=post1,
                             upload=image)

        self.assertIsNotNone(reply1)

        comment = get_post(reply1)
        self.assertIn('upload', comment)
        self.assertIsNotNone(comment.get('upload'))

        # Create a post with a broken image, ensure it's handled correctly
        image = io.BytesIO()
        reply2 = create_post(user1,
                             'user1',
                             'Test post #3',
                             reply_to=post1,
                             upload=image)
        self.assertIsNone(reply2)
        comment = get_post(reply2)
        self.assertIsNone(comment)
예제 #13
0
파일: test_dashboard.py 프로젝트: pjuu/pjuu
    def test_flag_control(self):
        """Ensure flagged posts appear in the dashboard"""
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')

        # Make user1 OP
        bite(user1)
        activate(user1)

        post1 = create_post(user2, 'user2', 'post1')
        post2 = create_post(user2, 'user2', 'post2')

        comment1 = create_post(user2, 'user2', 'comment1', post1)
        comment2 = create_post(user2, 'user2', 'comment2', post1)

        # Flag all the posts
        flag_post(user1, post1)
        flag_post(user1, post2)
        flag_post(user1, comment1)
        flag_post(user1, comment2)

        self.client.post(url_for('auth.signin'), data={
            'username': '******',
            'password': '******'
        })
        resp = self.client.get(url_for('dashboard.dashboard'))

        s = '{0} - <a href="{1}">{2}</a>: <a href="{3}">{4}</a> ' + \
            '[<a href="{5}">Unflag</a>]'

        self.assertIn(s.format(
            1,
            url_for('users.profile',
                    username='******'),
            'user2',
            url_for('posts.view_post',
                    username='******',
                    post_id=post1),
            post1,
            url_for('posts.unflag_post', post_id=post1)
        ), resp.data)

        self.assertIn(s.format(
            1,
            url_for('users.profile',
                    username='******'),
            'user2',
            url_for('posts.view_post',
                    username='******',
                    post_id=post1),
            comment1,
            url_for('posts.unflag_post', post_id=comment1)
        ) + ' (comment)', resp.data)
예제 #14
0
    def test_remove_from_feed(self):
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')
        # Activate
        activate(user1)

        follow_user(user1, user2)

        post = create_post(user2, 'user2', 'User 2, is here')

        # Check that the post appears in the users feed
        resp = self.client.post(url_for('auth.signin'),
                                data={
                                    'username': '******',
                                    'password': '******'
                                },
                                follow_redirects=True)

        self.assertIn('User 2, is here', resp.data)
        self.assertIn('remove:post:{}'.format(post), resp.data)

        # Hide the post
        resp = self.client.post(url_for('users.remove_from_feed',
                                        post_id=post),
                                follow_redirects=True)

        self.assertNotIn('User 2, is here', resp.data)
        self.assertNotIn('remove:post:{}'.format(post), resp.data)
        self.assertIn('Message has been removed from feed', resp.data)

        # Can a user remove their own post?
        post = create_post(user1, 'user1', 'User 1, is here')

        # The user should not see a hide button though
        resp = self.client.get(url_for('users.feed'))
        self.assertIn('User 1, is here', resp.data)
        self.assertNotIn('remove:post:{}'.format(post), resp.data)

        # Ensure the URL hides the post
        resp = self.client.post(url_for('users.remove_from_feed',
                                        post_id=post),
                                follow_redirects=True)

        self.assertNotIn('User 1, is here', resp.data)
        self.assertIn('Message has been removed from feed', resp.data)

        # Ensure removing a post that is not in your feed does not displau a
        # flash message
        resp = self.client.post(url_for('users.remove_from_feed', post_id=''),
                                follow_redirects=True)

        self.assertNotIn('Message has been removed from feed', resp.data)
예제 #15
0
    def test_remove_from_feed(self):
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')
        # Activate
        activate(user1)

        follow_user(user1, user2)

        post = create_post(user2, 'user2', 'User 2, is here')

        # Check that the post appears in the users feed
        resp = self.client.post(url_for('auth.signin'), data={
            'username': '******',
            'password': '******'
        }, follow_redirects=True)

        self.assertIn('User 2, is here', resp.data)
        self.assertIn('remove:post:{}'.format(post), resp.data)

        # Hide the post
        resp = self.client.post(url_for('users.remove_from_feed',
                                        post_id=post),
                                follow_redirects=True)

        self.assertNotIn('User 2, is here', resp.data)
        self.assertNotIn('remove:post:{}'.format(post), resp.data)
        self.assertIn('Message has been removed from feed', resp.data)

        # Can a user remove their own post?
        post = create_post(user1, 'user1', 'User 1, is here')

        # The user should not see a hide button though
        resp = self.client.get(url_for('users.feed'))
        self.assertIn('User 1, is here', resp.data)
        self.assertNotIn('remove:post:{}'.format(post), resp.data)

        # Ensure the URL hides the post
        resp = self.client.post(url_for('users.remove_from_feed',
                                        post_id=post),
                                follow_redirects=True)

        self.assertNotIn('User 1, is here', resp.data)
        self.assertIn('Message has been removed from feed', resp.data)

        # Ensure removing a post that is not in your feed does not displau a
        # flash message
        resp = self.client.post(url_for('users.remove_from_feed',
                                        post_id=''),
                                follow_redirects=True)

        self.assertNotIn('Message has been removed from feed', resp.data)
예제 #16
0
    def test_get_posts_pagination_sizes(self):
        """Ensure get_posts works with various pagination sizes"""
        user1 = create_account('user1', '*****@*****.**', 'Password')

        # Create loads of posts
        for i in xrange(100):
            create_post(user1, 'user1', 'Test post {}'.format(i))

        FEED_ITEMS_PER_PAGE = app.config.get('FEED_ITEMS_PER_PAGE')

        self.assertEqual(len(get_posts(user1).items), FEED_ITEMS_PER_PAGE)
        self.assertEqual(len(get_posts(user1, per_page=25).items), 25)
        self.assertEqual(len(get_posts(user1, per_page=50).items), 50)
        self.assertEqual(len(get_posts(user1, per_page=100).items), 100)
예제 #17
0
    def test_get_posts_pagination_sizes(self):
        """Ensure get_posts works with various pagination sizes"""
        user1 = create_account('user1', '*****@*****.**', 'Password')

        # Create loads of posts
        for i in xrange(100):
            create_post(user1, 'user1', 'Test post {}'.format(i))

        FEED_ITEMS_PER_PAGE = app.config.get('FEED_ITEMS_PER_PAGE')

        self.assertEqual(len(get_posts(user1).items), FEED_ITEMS_PER_PAGE)
        self.assertEqual(len(get_posts(user1, per_page=25).items), 25)
        self.assertEqual(len(get_posts(user1, per_page=50).items), 50)
        self.assertEqual(len(get_posts(user1, per_page=100).items), 100)
예제 #18
0
    def test_approved_feed_population(self):
        """Ensure only approved users get approved posts but in there feed."""
        # Create a user to test creating post
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')
        user3 = create_account('user3', '*****@*****.**', 'Password')

        follow_user(user2, user1)
        follow_user(user3, user1)
        approve_user(user1, user2)

        create_post(user1, 'user1', 'Test post', permission=K.PERM_APPROVED)

        self.assertEqual(len(get_feed(user2).items), 1)
        self.assertEqual(len(get_feed(user3).items), 0)
예제 #19
0
    def test_create_reply(self):
        """Test that a reply can be made on a post

        """
        user1 = create_account('user1', '*****@*****.**', 'Password')
        # Create a second test user to test commenting on someone else post
        user2 = create_account('user2', '*****@*****.**', 'Password')
        # Create post
        post1 = create_post(user1, 'user1', 'Test post')
        # Create comment
        reply1 = create_post(user1, 'user1', 'Test comment', post1)
        # Check the comment was created
        self.assertIsNotNone(get_post(reply1))
        # Create a comment by the second user
        reply2 = create_post(user2, 'user1', 'Test comment', post1)
        # Check the comment was created
        self.assertIsNotNone(get_post(reply2))

        # Check the comment hash has the data we expect, we will do this with
        # comment1
        comment = get_post(reply1)
        self.assertIsNotNone(comment)
        self.assertEqual(comment.get('_id'), reply1)
        self.assertEqual(comment.get('user_id'), user1)
        self.assertEqual(comment.get('reply_to'), post1)
        self.assertEqual(comment.get('body'), 'Test comment')
        self.assertEqual(comment.get('score'), 0)
        self.assertIsNotNone(comment.get('created'))
        self.assertNotIn('upload', comment)

        # Create a post with an image
        image = io.BytesIO(open('tests/upload_test_files/otter.jpg').read())
        reply1 = create_post(user1, 'user1', 'Test post #2', reply_to=post1,
                             upload=image)

        self.assertIsNotNone(reply1)

        comment = get_post(reply1)
        self.assertIn('upload', comment)
        self.assertIsNotNone(comment.get('upload'))

        # Create a post with a broken image, ensure it's handled correctly
        image = io.BytesIO()
        reply2 = create_post(user1, 'user1', 'Test post #3', reply_to=post1,
                             upload=image)
        self.assertIsNone(reply2)
        comment = get_post(reply2)
        self.assertIsNone(comment)
예제 #20
0
    def test_avatars_hashtag_search(self):
        """Ensure user avatars appear when searching for posts with a hashtag
        """
        user1 = create_account('user1', '*****@*****.**', 'Password')
        # Activate it
        activate(user1)

        # Signin
        self.client.post(url_for('auth.signin'), data={
            'username': '******',
            'password': '******'
        })

        # Ensure user avatar appear in the search when searching for hashtags
        image = io.BytesIO(open('tests/upload_test_files/otter.jpg').read())

        self.client.post(url_for('users.settings_profile'), data={
            'upload': (image, 'otter.png')
        }, follow_redirects=True)

        # Get the user so we can see if the avatar is appearing
        user = get_user(user1)

        # Create a post to search for
        post1 = create_post(user1, 'user1', 'Hello #pjuuie\'s')

        resp = self.client.get(url_for('users.search', query='#pjuuie'))
        self.assertIn('<!-- list:post:%s -->' % post1, resp.data)
        self.assertIn(url_for('posts.get_upload', filename=user.get('avatar')),
                      resp.data)
예제 #21
0
    def test_get_feed_pagination_sizes(self):
        """Ensure that getting the feed at different pagination sizes work"""
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')
        follow_user(user1, user2)

        # Create lots of posts so they apear in user1's feed.
        for i in xrange(101):
            create_post(user2, 'user2', 'Post {}'.format(i))

        FEED_ITEMS_PER_PAGE = app.config.get('FEED_ITEMS_PER_PAGE')

        self.assertEqual(len(get_feed(user1).items), FEED_ITEMS_PER_PAGE)
        self.assertEqual(len(get_feed(user1, per_page=25).items), 25)
        self.assertEqual(len(get_feed(user1, per_page=50).items), 50)
        self.assertEqual(len(get_feed(user1, per_page=100).items), 100)
예제 #22
0
    def test_avatars_hashtag_search(self):
        """Ensure user avatars appear when searching for posts with a hashtag
        """
        user1 = create_account('user1', '*****@*****.**', 'Password')
        # Activate it
        activate(user1)

        # Signin
        self.client.post(url_for('auth.signin'),
                         data={
                             'username': '******',
                             'password': '******'
                         })

        # Ensure user avatar appear in the search when searching for hashtags
        image = io.BytesIO(open('tests/upload_test_files/otter.jpg').read())

        self.client.post(url_for('users.settings_profile'),
                         data={'upload': (image, 'otter.png')},
                         follow_redirects=True)

        # Get the user so we can see if the avatar is appearing
        user = get_user(user1)

        # Create a post to search for
        post1 = create_post(user1, 'user1', 'Hello #pjuuie\'s')

        resp = self.client.get(url_for('users.search', query='#pjuuie'))
        self.assertIn('<!-- list:post:%s -->' % post1, resp.data)
        self.assertIn(url_for('posts.get_upload', filename=user.get('avatar')),
                      resp.data)
예제 #23
0
    def test_approved_feed_population(self):
        """Ensure only approved users get approved posts but in there feed."""
        # Create a user to test creating post
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')
        user3 = create_account('user3', '*****@*****.**', 'Password')

        follow_user(user2, user1)
        follow_user(user3, user1)
        approve_user(user1, user2)

        create_post(user1, 'user1', 'Test post',
                    permission=K.PERM_APPROVED)

        self.assertEqual(len(get_feed(user2).items), 1)
        self.assertEqual(len(get_feed(user3).items), 0)
예제 #24
0
    def test_get_upload(self):
        """Tests the simple wrapper around ``lib.uploads.get_upload``

        """
        user1 = create_account('user1', '*****@*****.**', 'Password')
        activate(user1)

        # Create the post with an upload to get
        image = io.BytesIO(open('tests/upload_test_files/otter.jpg').read())
        post1 = create_post(user1, 'user1', 'Test post', upload=image)
        self.assertIsNotNone(post1)

        post = get_post(post1)

        # Try and get the post and ensure we are redirected because we are not
        # logged in
        resp = self.client.get(url_for('posts.get_upload',
                                       filename=post.get('upload')))
        self.assertEqual(resp.status_code, 302)

        # Log in as user1 and get the upload
        resp = self.client.post(url_for('auth.signin'), data={
            'username': '******',
            'password': '******'
        }, follow_redirects=True)
        self.assertEqual(resp.status_code, 200)

        resp = self.client.get(url_for('posts.get_upload',
                                       filename=post.get('upload')))
        self.assertEqual(resp.status_code, 200)
        self.assertEqual(resp.headers['Content-Type'], 'image/png')
예제 #25
0
    def test_get_feed_pagination_sizes(self):
        """Ensure that getting the feed at different pagination sizes work"""
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')
        follow_user(user1, user2)

        # Create lots of posts so they apear in user1's feed.
        for i in xrange(101):
            create_post(user2, 'user2', 'Post {}'.format(i))

        FEED_ITEMS_PER_PAGE = app.config.get('FEED_ITEMS_PER_PAGE')

        self.assertEqual(len(get_feed(user1).items), FEED_ITEMS_PER_PAGE)
        self.assertEqual(len(get_feed(user1, per_page=25).items), 25)
        self.assertEqual(len(get_feed(user1, per_page=50).items), 50)
        self.assertEqual(len(get_feed(user1, per_page=100).items), 100)
예제 #26
0
    def test_get_comments(self):
        """
        Ensure a posts comments are stored correctly in post:$pid:comments list
        """
        # Create two test users
        user1 = create_user('user1', '*****@*****.**', 'Password')
        user2 = create_user('user2', '*****@*****.**', 'Password')
        # Ensure the comment lists are empty
        self.assertEqual(len(get_comments(user1).items), 0)
        self.assertEqual(len(get_comments(user2).items), 0)
        # Create a post for each user and a comment on each for both user
        post1 = create_post(user1, 'Test post')
        post2 = create_post(user2, 'Test post')
        comment1 = create_comment(user1, post1, 'Test comment')
        comment2 = create_comment(user1, post2, 'Test comment')
        comment3 = create_comment(user2, post1, 'Test comment')
        comment4 = create_comment(user2, post2, 'Test comment')
        # Ensure each comment appears in each users list
        self.assertEqual(len(get_comments(post1).items), 2)
        self.assertEqual(len(get_comments(post2).items), 2)
        # Ensure the totals are correct
        self.assertEqual(get_comments(post1).total, 2)
        self.assertEqual(get_comments(post2).total, 2)
        # Ensure the ids are in the Redis lists
        self.assertIn(comment1, r.lrange(K.POST_COMMENTS.format(post1), 0, -1))
        self.assertIn(comment2, r.lrange(K.POST_COMMENTS.format(post2), 0, -1))
        self.assertIn(comment3, r.lrange(K.POST_COMMENTS.format(post1), 0, -1))
        self.assertIn(comment4, r.lrange(K.POST_COMMENTS.format(post2), 0, -1))

        # Delete 1 comment from post1 and ensure it does not exist
        delete_comment(comment1)
        # Check that is has gone
        self.assertEqual(len(get_comments(post1).items), 1)
        self.assertEqual(get_comments(post1).total, 1)
        # Ensure it is missing from Redis
        self.assertNotIn(comment1,
                         r.lrange(K.POST_COMMENTS.format(user1), 0, -1))

        # Delete a comment from inside Redis. This will trigger the self
        # cleaning list feature. We call these orphaned cids.
        r.delete(K.COMMENT.format(comment2))
        # Check that it has gone when get_comments is called
        self.assertEqual(len(get_comments(post2).items), 1)
        self.assertEqual(get_comments(post2).total, 1)
        # Ensure it is missing from Redis
        self.assertNotIn(comment2,
                         r.lrange(K.POST_COMMENTS.format(user1), 0, -1))
예제 #27
0
    def test_permission_setting(self):
        """Test that a post can have correct permissions set"""
        user1 = create_account('user1', '*****@*****.**', 'Password')

        # Create post with each permission
        post1 = create_post(user1, 'user1', 'Test post', permission=0)
        post2 = create_post(user1, 'user1', 'Test post', permission=1)
        post3 = create_post(user1, 'user1', 'Test post', permission=2)

        post = get_post(post1)
        self.assertEqual(post.get('permission'), 0)

        post = get_post(post2)
        self.assertEqual(post.get('permission'), 1)

        post = get_post(post3)
        self.assertEqual(post.get('permission'), 2)
예제 #28
0
    def test_permission_setting(self):
        """Test that a post can have correct permissions set"""
        user1 = create_account('user1', '*****@*****.**', 'Password')

        # Create post with each permission
        post1 = create_post(user1, 'user1', 'Test post', permission=0)
        post2 = create_post(user1, 'user1', 'Test post', permission=1)
        post3 = create_post(user1, 'user1', 'Test post', permission=2)

        post = get_post(post1)
        self.assertEqual(post.get('permission'), 0)

        post = get_post(post2)
        self.assertEqual(post.get('permission'), 1)

        post = get_post(post3)
        self.assertEqual(post.get('permission'), 2)
예제 #29
0
    def test_create_post(self):
        """Tests creating and getting a post

        """
        # Create a user to test creating post
        user1 = create_account('user1', '*****@*****.**', 'Password')
        # Create post
        post1 = create_post(user1, 'user1', 'Test post')
        # Check the post actually exists
        self.assertIsNotNone(post1)

        # Check that all the hash members are what we expect
        post = get_post(post1)
        self.assertIsNotNone(post)
        self.assertEqual(post.get('_id'), post1)
        self.assertEqual(post.get('user_id'), user1)
        self.assertEqual(post.get('body'), 'Test post')
        self.assertEqual(post.get('score'), 0)
        self.assertEqual(post.get('comment_count'), 0)
        # Check the memebers we don't know the answer to
        self.assertIsNotNone(post.get('created'))
        self.assertNotIn('upload', post)

        # Ensure this post is the users feed (populate_feed)
        self.assertIn(post1, r.zrange(K.USER_FEED.format(user1), 0, -1))

        # Testing getting post with invalid arguments
        # Test getting a post that does not exist
        self.assertIsNone(get_post(K.NIL_VALUE))

        # Create a post with an image
        image = io.BytesIO(open('tests/upload_test_files/otter.jpg').read())
        post2 = create_post(user1, 'user1', 'Test post #2', upload=image)

        self.assertIsNotNone(post2)

        post = get_post(post2)
        self.assertIn('upload', post)
        self.assertIsNotNone(post.get('upload'))

        # Create a post with a broken image, ensure it's handled correctly
        image = io.BytesIO()
        post3 = create_post(user1, 'user1', 'Test post #3', upload=image)
        self.assertIsNone(post3)
        post3 = get_post(post3)
        self.assertIsNone(post3)
예제 #30
0
    def test_get_posts(self):
        """
        Test users post list works correctly
        """
        # Create test user
        user1 = create_user('user1', '*****@*****.**', 'Password')
        # Ensure the users post list is empty
        self.assertEqual(len(get_posts(user1).items), 0)

        # Create a few test posts, ensure they appears in the users list
        post1 = create_post(user1, 'Test post 1')
        post2 = create_post(user1, 'Test post 2')
        post3 = create_post(user1, 'Test post 3')
        self.assertEqual(len(get_posts(user1).items), 3)
        self.assertEqual(get_posts(user1).total, 3)

        # Ensure the post ids are in the Redis list
        self.assertIn(post1, r.lrange(K.USER_POSTS.format(user1), 0, -1))
        self.assertIn(post2, r.lrange(K.USER_POSTS.format(user1), 0, -1))
        self.assertIn(post3, r.lrange(K.USER_POSTS.format(user1), 0, -1))

        # Delete one of the posts and ensure that it does not appear in the
        # list.
        delete_post(post1)

        # Ensure the above is now correct with post1 missing
        self.assertEqual(len(get_posts(user1).items), 2)
        self.assertEqual(get_posts(user1).total, 2)

        # Ensure the post ids are in the Redis list and post1 is NOT
        self.assertNotIn(post1, r.lrange(K.USER_POSTS.format(user1), 0, -1))
        self.assertIn(post2, r.lrange(K.USER_POSTS.format(user1), 0, -1))
        self.assertIn(post3, r.lrange(K.USER_POSTS.format(user1), 0, -1))

        # Delete a post from inside Redis. This will trigger the self cleaning
        # list feature. We call these orphaned pids
        r.delete(K.POST.format(post2))
        # Ensure the above is now correct with post2 missing
        self.assertEqual(len(get_posts(user1).items), 1)
        self.assertEqual(get_posts(user1).total, 1)

        # Ensure the post ids are not in the Redis list and post1 is NOT
        self.assertNotIn(post1, r.lrange(K.USER_POSTS.format(user1), 0, -1))
        self.assertNotIn(post2, r.lrange(K.USER_POSTS.format(user1), 0, -1))
        self.assertIn(post3, r.lrange(K.USER_POSTS.format(user1), 0, -1))
예제 #31
0
    def test_alerts(self):
        """
        Unlike the test_alerts() definition in the users package this just
        tests that TaggingAlert and CommentingAlert are generated in the right
        situation
        """
        # Create 3 test users
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')
        user3 = create_account('user3', '*****@*****.**', 'Password')
        # No need to activate the accounts

        activate(user1)
        activate(user2)
        activate(user3)

        # User1 tag user2 in a post
        post1 = create_post(user1, 'user1', 'Hello @user2')

        # Get alerts for test2 and check that it is correct
        alert = get_alerts(user2).items[0]
        self.assertTrue(isinstance(alert, TaggingAlert))
        self.assertEqual(alert.user['username'], 'user1')
        self.assertEqual(alert.user['email'], '*****@*****.**')
        self.assertIn('tagged you in a', alert.prettify())

        # Have user2 comment on a the post and check that user1 has the alert
        create_post(user2, 'user2', 'Hello', post1)
        # User 1 should now have a commenting alert from user2
        alert = get_alerts(user1).items[0]
        self.assertTrue(isinstance(alert, CommentingAlert))
        self.assertEqual(alert.user['username'], 'user2')
        self.assertEqual(alert.user['email'], '*****@*****.**')
        # Please remember that prettify requires a uid to format it to
        self.assertIn('commented on a', alert.prettify(user1))
        self.assertIn('you posted', alert.prettify(user1))

        # Create a comment as user3 so they become subscribed
        create_post(user3, 'user3', 'Hello', post1)

        # Check that if user1 posts a comment user2 get a tagging alert
        create_post(user1, 'user1', 'Hello', post1)
        # Check alerts for user2
        alert = get_alerts(user2).items[0]
        self.assertTrue(isinstance(alert, CommentingAlert))
        self.assertIn('you were tagged in', alert.prettify(user2))
        # Check alerts for user3
        alert = get_alerts(user3).items[0]
        self.assertTrue(isinstance(alert, CommentingAlert))
        self.assertIn('you commented on', alert.prettify(user3))

        # To check that an invalid subscription reason returns the generic
        # reason. This should not happen on the site.
        # Manually change the score in Redis to a high number
        r.zincrby(K.POST_SUBSCRIBERS.format(post1), user3, 100)
        # Check the new prettify message
        alert = get_alerts(user3).items[0]
        self.assertTrue(isinstance(alert, CommentingAlert))
        self.assertIn('you are subscribed to', alert.prettify(user3))
예제 #32
0
    def test_alerts(self):
        """
        Unlike the test_alerts() definition in the users package this just
        tests that TaggingAlert and CommentingAlert are generated in the right
        situation
        """
        # Create 3 test users
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')
        user3 = create_account('user3', '*****@*****.**', 'Password')
        # No need to activate the accounts

        activate(user1)
        activate(user2)
        activate(user3)

        # User1 tag user2 in a post
        post1 = create_post(user1, 'user1', 'Hello @user2')

        # Get alerts for test2 and check that it is correct
        alert = get_alerts(user2).items[0]
        self.assertTrue(isinstance(alert, TaggingAlert))
        self.assertEqual(alert.user['username'], 'user1')
        self.assertEqual(alert.user['email'], '*****@*****.**')
        self.assertIn('tagged you in a', alert.prettify())

        # Have user2 comment on a the post and check that user1 has the alert
        create_post(user2, 'user2', 'Hello', post1)
        # User 1 should now have a commenting alert from user2
        alert = get_alerts(user1).items[0]
        self.assertTrue(isinstance(alert, CommentingAlert))
        self.assertEqual(alert.user['username'], 'user2')
        self.assertEqual(alert.user['email'], '*****@*****.**')
        # Please remember that prettify requires a uid to format it to
        self.assertIn('commented on a', alert.prettify(user1))
        self.assertIn('you posted', alert.prettify(user1))

        # Create a comment as user3 so they become subscribed
        create_post(user3, 'user3', 'Hello', post1)

        # Check that if user1 posts a comment user2 get a tagging alert
        create_post(user1, 'user1', 'Hello', post1)
        # Check alerts for user2
        alert = get_alerts(user2).items[0]
        self.assertTrue(isinstance(alert, CommentingAlert))
        self.assertIn('you were tagged in', alert.prettify(user2))
        # Check alerts for user3
        alert = get_alerts(user3).items[0]
        self.assertTrue(isinstance(alert, CommentingAlert))
        self.assertIn('you commented on', alert.prettify(user3))

        # To check that an invalid subscription reason returns the generic
        # reason. This should not happen on the site.
        # Manually change the score in Redis to a high number
        r.zincrby(K.POST_SUBSCRIBERS.format(post1), user3, 100)
        # Check the new prettify message
        alert = get_alerts(user3).items[0]
        self.assertTrue(isinstance(alert, CommentingAlert))
        self.assertIn('you are subscribed to', alert.prettify(user3))
예제 #33
0
    def test_flag_control(self):
        """Ensure flagged posts appear in the dashboard"""
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')

        # Make user1 OP
        bite(user1)
        activate(user1)

        post1 = create_post(user2, 'user2', 'post1')
        post2 = create_post(user2, 'user2', 'post2')

        comment1 = create_post(user2, 'user2', 'comment1', post1)
        comment2 = create_post(user2, 'user2', 'comment2', post1)

        # Flag all the posts
        flag_post(user1, post1)
        flag_post(user1, post2)
        flag_post(user1, comment1)
        flag_post(user1, comment2)

        self.client.post(url_for('auth.signin'),
                         data={
                             'username': '******',
                             'password': '******'
                         })
        resp = self.client.get(url_for('dashboard.dashboard'))

        s = '{0} - <a href="{1}">{2}</a>: <a href="{3}">{4}</a> ' + \
            '[<a href="{5}">Unflag</a>]'

        self.assertIn(
            s.format(
                1, url_for('users.profile', username='******'), 'user2',
                url_for('posts.view_post', username='******', post_id=post1),
                post1, url_for('posts.unflag_post', post_id=post1)), resp.data)

        self.assertIn(
            s.format(
                1, url_for('users.profile', username='******'), 'user2',
                url_for('posts.view_post', username='******', post_id=post1),
                comment1, url_for('posts.unflag_post', post_id=comment1)) +
            ' (comment)', resp.data)
예제 #34
0
    def test_get_hashtagged_posts_pagination_sizes(self):
        """Ensure the correct number of hashtagged posts are returned when
        pagination sizes have been changed.
        """
        user1 = create_account('user1', '*****@*****.**', 'Password')

        # Create loads of posts
        for i in xrange(100):
            create_post(user1, 'user1', 'Test post {} #test'.format(i))

        FEED_ITEMS_PER_PAGE = app.config.get('FEED_ITEMS_PER_PAGE')

        self.assertEqual(len(get_hashtagged_posts('test').items),
                         FEED_ITEMS_PER_PAGE)
        self.assertEqual(len(get_hashtagged_posts('test', per_page=25).items),
                         25)
        self.assertEqual(len(get_hashtagged_posts('test', per_page=50).items),
                         50)
        self.assertEqual(len(get_hashtagged_posts('test', per_page=100).items),
                         100)
예제 #35
0
    def test_get_hashtagged_posts_pagination_sizes(self):
        """Ensure the correct number of hashtagged posts are returned when
        pagination sizes have been changed.
        """
        user1 = create_account('user1', '*****@*****.**', 'Password')

        # Create loads of posts
        for i in xrange(100):
            create_post(user1, 'user1', 'Test post {} #test'.format(i))

        FEED_ITEMS_PER_PAGE = app.config.get('FEED_ITEMS_PER_PAGE')

        self.assertEqual(
            len(get_hashtagged_posts('test').items), FEED_ITEMS_PER_PAGE)
        self.assertEqual(
            len(get_hashtagged_posts('test', per_page=25).items), 25)
        self.assertEqual(
            len(get_hashtagged_posts('test', per_page=50).items), 50)
        self.assertEqual(
            len(get_hashtagged_posts('test', per_page=100).items), 100)
예제 #36
0
    def test_back_feed(self):
        """Test the back feed feature, once a user follows another user it
        places their latest 5 posts on their feed. They will be in chronologic
        order.

        I know that ``back_feed()`` is a posts feature but it is triggered on
        follow.

        """
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')

        # Create 6 test posts ('Test 1' shouldn't be back fed)
        post1 = create_post(user1, 'user1', 'Test 1')
        post2 = create_post(user1, 'user1', 'Test 2')
        post3 = create_post(user1, 'user1', 'Test 3')
        post4 = create_post(user1, 'user1', 'Test 4')
        post5 = create_post(user1, 'user1', 'Test 5')
        post6 = create_post(user1, 'user1', 'Test 6')

        follow_user(user2, user1)

        # Check that the posts are in the feed (we can do this in Redis)
        feed = r.zrevrange(k.USER_FEED.format(user2), 0, -1)

        self.assertNotIn(post1, feed)
        self.assertIn(post2, feed)
        self.assertIn(post3, feed)
        self.assertIn(post4, feed)
        self.assertIn(post5, feed)
        self.assertIn(post6, feed)
예제 #37
0
    def test_advanced_search(self):
        """Cover using the `@` and `#` modifiers to limit
        the search type.
        """
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')

        create_post(user1, 'user1', '#pjuu #user2')
        create_post(user2, 'user2', '#pjuu #user1')

        for i in range(1, 101):
            create_post(user1, 'user1', '#pagination{}'.format(i))

        # Try come basic search terms
        self.assertEqual(search('user').total, 4)
        self.assertEqual(search('user1').total, 2)
        self.assertEqual(search('user2').total, 2)
        self.assertEqual(search('pjuu').total, 2)

        # Users only
        self.assertEqual(search('@user').total, 2)
        self.assertEqual(search('@user1').total, 1)
        # erroneous spacing doesn't matter
        self.assertEqual(search('@    us').total, 2)

        # Posts only
        self.assertEqual(search('#user').total, 2)
        self.assertEqual(search('#user1').total, 1)
        self.assertEqual(search('#pjuu').total, 2)

        # Test pagination in search
        self.assertEqual(len(search('#pagination', 1, 50).items), 50)
        self.assertEqual(len(search('#pagination', 2, 50).items), 50)
예제 #38
0
    def test_stats(self):
        """Ensure the ``pjuu.posts`` exposed stats are correct

        """
        stats = dict(get_stats())

        self.assertEqual(stats.get('Total posts'), 0)
        self.assertEqual(stats.get('Total uploads'), 0)
        self.assertIsNone(stats.get('Last post'))

        user1 = create_account('user1', '*****@*****.**', 'Password')

        post1 = create_post(user1, 'user1', 'Test post 1')
        create_post(user1, 'user1', 'Test reply 1', post1)

        image = io.BytesIO(open('tests/upload_test_files/otter.jpg').read())
        create_post(user1, 'user1', 'Test post #2', upload=image)

        stats = dict(get_stats())
        self.assertEqual(stats.get('Total posts'), 3)
        self.assertEqual(stats.get('Total uploads'), 1)
        self.assertIsNotNone(stats.get('Last post'))
예제 #39
0
    def test_stats(self):
        """Ensure the ``pjuu.posts`` exposed stats are correct

        """
        stats = dict(get_stats())

        self.assertEqual(stats.get('Total posts'), 0)
        self.assertEqual(stats.get('Total uploads'), 0)
        self.assertIsNone(stats.get('Last post'))

        user1 = create_account('user1', '*****@*****.**', 'Password')

        post1 = create_post(user1, 'user1', 'Test post 1')
        create_post(user1, 'user1', 'Test reply 1', post1)

        image = io.BytesIO(open('tests/upload_test_files/otter.jpg').read())
        create_post(user1, 'user1', 'Test post #2', upload=image)

        stats = dict(get_stats())
        self.assertEqual(stats.get('Total posts'), 3)
        self.assertEqual(stats.get('Total uploads'), 1)
        self.assertIsNotNone(stats.get('Last post'))
예제 #40
0
    def test_xhr_decorators(self):
        """Ensure we get a 403 if we XHR request something we need to logged
        in for.
        """
        user1 = create_account("user1", "*****@*****.**", "Password")
        post1 = create_post(user1, "user1", "Test")
        activate(user1)

        resp = self.client.post(
            url_for("posts.upvote", username="******", post_id=post1), headers=[("X-Requested-With", "XMLHttpRequest")]
        )

        self.assertEqual(resp.status_code, 403)
예제 #41
0
    def test_delete_account_posts_comments(self):
        """
        Test delete_account()

        Posts and comments: Ensure all posts and comments are gone.

        Note: This is not a full test of the posts system. See posts/test.py
        """
        # Create test user
        user1 = create_user('user1', '*****@*****.**', 'Password')
        # Second user to test deletion from user:1:comments
        user2 = create_user('user2', '*****@*****.**', 'Password')
        # Create a post as both users
        post1 = create_post(user1, "Test post")
        post2 = create_post(user2, "Test post")
        # Create multiple comments on both posts
        # Post 1
        comment1 = create_comment(user1, post1, "Test comment")
        comment2 = create_comment(user1, post1, "Test comment")
        # Post 2
        comment3 = create_comment(user1, post2, "Test comment")
        comment4 = create_comment(user1, post2, "Test comment")

        # Delete the account
        delete_account(user1)

        # Ensure the Post, its comment list and votes has gone
        self.assertFalse(r.hgetall(K.POST.format(post1)))
        self.assertFalse(r.lrange(K.POST_COMMENTS.format(post1), 0, -1))
        # Ensure the Comment is gone
        self.assertFalse(r.hgetall(K.COMMENT.format(comment1)))
        # Assert feed is empty
        self.assertFalse(r.lrange(K.USER_FEED.format(user1), 0, -1))
        # Assert posts is empty
        self.assertFalse(r.lrange(K.USER_POSTS.format(user1), 0, -1))
        # Assert comments is empty
        self.assertFalse(r.lrange(K.USER_COMMENTS.format(user1), 0, -1))
예제 #42
0
    def test_get_replies(self):
        """Test getting all replies for a post

        """
        # Create two test users
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')
        # Create a post for each user and a comment on each for both user
        post1 = create_post(user1, 'user1', 'Test post')
        post2 = create_post(user2, 'user2', 'Test post')
        # Ensure the comment lists are empty
        self.assertEqual(len(get_replies(post1).items), 0)
        self.assertEqual(len(get_replies(post2).items), 0)

        reply1 = create_post(user1, 'user1', 'Test comment', post1)
        reply2 = create_post(user1, 'user1', 'Test comment', post2)
        reply3 = create_post(user2, 'user2', 'Test comment', post1)
        reply4 = create_post(user2, 'user2', 'Test comment', post2)
        # Ensure each comment appears in each users list
        self.assertEqual(len(get_replies(post1).items), 2)
        self.assertEqual(len(get_replies(post2).items), 2)
        # Ensure the totals are correct
        self.assertEqual(get_replies(post1).total, 2)
        self.assertEqual(get_replies(post2).total, 2)
        # Ensure comments are in MongoDB
        comment_ids = \
            [doc['_id'] for doc in m.db.posts.find({'reply_to': post1})]
        self.assertIn(reply1, comment_ids)
        self.assertIn(reply3, comment_ids)
        comment_ids = \
            [doc['_id'] for doc in m.db.posts.find({'reply_to': post2})]
        self.assertIn(reply2, comment_ids)
        self.assertIn(reply4, comment_ids)

        # Delete 1 comment from post1 and ensure it does not exist
        delete_post(reply1)
        # Check that is has gone
        self.assertEqual(len(get_replies(post1).items), 1)
        self.assertEqual(get_replies(post1).total, 1)
예제 #43
0
    def test_get_replies(self):
        """Test getting all replies for a post

        """
        # Create two test users
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')
        # Create a post for each user and a comment on each for both user
        post1 = create_post(user1, 'user1', 'Test post')
        post2 = create_post(user2, 'user2', 'Test post')
        # Ensure the comment lists are empty
        self.assertEqual(len(get_replies(post1).items), 0)
        self.assertEqual(len(get_replies(post2).items), 0)

        reply1 = create_post(user1, 'user1', 'Test comment', post1)
        reply2 = create_post(user1, 'user1', 'Test comment', post2)
        reply3 = create_post(user2, 'user2', 'Test comment', post1)
        reply4 = create_post(user2, 'user2', 'Test comment', post2)
        # Ensure each comment appears in each users list
        self.assertEqual(len(get_replies(post1).items), 2)
        self.assertEqual(len(get_replies(post2).items), 2)
        # Ensure the totals are correct
        self.assertEqual(get_replies(post1).total, 2)
        self.assertEqual(get_replies(post2).total, 2)
        # Ensure comments are in MongoDB
        comment_ids = \
            [doc['_id'] for doc in m.db.posts.find({'reply_to': post1})]
        self.assertIn(reply1, comment_ids)
        self.assertIn(reply3, comment_ids)
        comment_ids = \
            [doc['_id'] for doc in m.db.posts.find({'reply_to': post2})]
        self.assertIn(reply2, comment_ids)
        self.assertIn(reply4, comment_ids)

        # Delete 1 comment from post1 and ensure it does not exist
        delete_post(reply1)
        # Check that is has gone
        self.assertEqual(len(get_replies(post1).items), 1)
        self.assertEqual(get_replies(post1).total, 1)
예제 #44
0
    def test_votes(self):
        """
        Test that the voting mechanism will adjust the relevant score counters
        on users, posts and comments, etc...
        """
        # Create three test users
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')
        user3 = create_account('user3', '*****@*****.**', 'Password')

        # Create a post by user 1
        post1 = create_post(user1, 'user1', 'Test post')

        # Get user 3 to downvote
        self.assertEqual(vote_post(user3, post1, amount=-1), -1)
        # Ensure post score has been adjusted
        self.assertEqual(get_post(post1).get('score'), -1)
        # Ensure user score has been adjusted
        self.assertEqual(get_user(user1).get('score'), -1)

        # Check that a user can reverse their vote within TIMEOUT
        self.assertEqual(vote_post(user3, post1, amount=-1), 0)
        self.assertEqual(get_post(post1).get('score'), 0)
        self.assertEqual(get_user(user1).get('score'), 0)

        # Get user 2 to upvote
        self.assertEqual(vote_post(user2, post1), 1)
        # Ensure post score has been adjusted
        self.assertEqual(get_post(post1).get('score'), 1)
        # Ensure user score has been adjusted
        self.assertEqual(get_user(user1).get('score'), 1)

        # Ensure user 1 can not vote on there own post
        self.assertRaises(CantVoteOnOwn, lambda: vote_post(user1, post1))
        # Ensure the scores have not been adjusted
        self.assertEqual(get_post(post1).get('score'), 1)
        self.assertEqual(get_user(user1).get('score'), 1)

        # Ensure the user has voted
        self.assertTrue(has_voted(user2, post1))

        # Check that a user can reverse their vote within TIMEOUT
        self.assertEqual(vote_post(user2, post1), 0)
        self.assertEqual(get_post(post1).get('score'), 0)
        self.assertEqual(get_user(user1).get('score'), 0)

        # Ensure the user has voted
        self.assertFalse(has_voted(user2, post1))

        # Check that the score reflects an opposite vote within TIMEOUT
        self.assertEqual(vote_post(user2, post1, 1), 1)
        self.assertEqual(get_post(post1).get('score'), 1)
        self.assertEqual(get_user(user1).get('score'), 1)

        self.assertTrue(has_voted(user2, post1))

        self.assertEqual(vote_post(user2, post1, -1), -1)
        self.assertEqual(get_post(post1).get('score'), -1)
        self.assertEqual(get_user(user1).get('score'), -1)

        self.assertTrue(has_voted(user2, post1))

        # Check that a user can not reverse there vote after the TIMEOUT
        self.assertRaises(
            AlreadyVoted, lambda: vote_post(user2, post1, -1,
                                            timestamp() + K.VOTE_TIMEOUT + 1))

        self.assertRaises(
            AlreadyVoted, lambda: vote_post(user2, post1, 1,
                                            timestamp() + K.VOTE_TIMEOUT + 1))

        # Repeat the same tests on a comment
        # Create a comment by user 1
        comment1 = create_post(user1, 'user1', 'Test comment', post1)

        # Let's cheat and set user1's score back to 0
        m.db.users.update({'_id': user1}, {'$set': {'score': 0}})

        # Get user 3 to downvote
        self.assertEqual(vote_post(user3, comment1, amount=-1), -1)
        # Ensure post score has been adjusted
        self.assertEqual(get_post(comment1).get('score'), -1)
        self.assertEqual(get_user(user1).get('score'), -1)

        # Reverse user3's vote just so it's not confusing
        self.assertEqual(vote_post(user3, comment1, amount=-1), 0)
        self.assertEqual(get_post(comment1).get('score'), 0)
        self.assertEqual(get_user(user1).get('score'), 0)

        # Ensure user 1 can not vote on there own comment
        self.assertRaises(CantVoteOnOwn, lambda: vote_post(user1, comment1))
        # Ensure post score has been adjusted
        self.assertEqual(get_post(comment1).get('score'), 0)
        # Ensure user score has been adjusted
        self.assertEqual(get_user(user1).get('score'), 0)

        # Get user 2 to upvote
        self.assertEqual(vote_post(user2, comment1), 1)
        # Ensure post score has been adjusted
        self.assertEqual(get_post(comment1).get('score'), 1)
        # Ensure user score has been adjusted
        self.assertEqual(get_user(user1).get('score'), 1)

        self.assertTrue(has_voted(user2, comment1))

        # Check that a user can reverse their vote within TIMEOUT
        self.assertEqual(vote_post(user2, comment1), 0)
        self.assertEqual(get_post(comment1).get('score'), 0)
        self.assertEqual(get_user(user1).get('score'), 0)

        self.assertFalse(has_voted(user2, comment1))

        # Check that the score reflects an opposite vote within TIMEOUT
        self.assertEqual(vote_post(user2, comment1, -1), -1)
        self.assertEqual(get_post(comment1).get('score'), -1)
        self.assertEqual(get_user(user1).get('score'), -1)

        self.assertTrue(has_voted(user2, comment1))

        self.assertEqual(vote_post(user2, comment1, 1), 1)
        self.assertEqual(get_post(comment1).get('score'), 1)
        self.assertEqual(get_user(user1).get('score'), 1)

        self.assertTrue(has_voted(user2, comment1))

        # Check that a user can not reverse there vote after the TIMEOUT
        self.assertRaises(
            AlreadyVoted, lambda: vote_post(user2, comment1, -1,
                                            timestamp() + K.VOTE_TIMEOUT + 1))

        self.assertRaises(
            AlreadyVoted, lambda: vote_post(user2, comment1, 1,
                                            timestamp() + K.VOTE_TIMEOUT + 1))
예제 #45
0
    def test_subscriptions(self):
        """
        Test the backend subscription system.

        This includes subscribe(), unsubscribe() and is_subscribed().

        This will also test the correct subscriptions after a post, comment or
        tagging.
        """
        # Create a couple of test accounts
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')
        user3 = create_account('user3', '*****@*****.**', 'Password')

        activate(user1)
        activate(user2)
        activate(user3)

        # Post as user 1 and ensure user 1 exists in Redis
        post1 = create_post(user1, 'user1', 'Test post 1')
        self.assertIsNotNone(r.zrank(K.POST_SUBSCRIBERS.format(post1), user1))

        # Even though it is exactly the same as the above ensure that
        # is_subscribed() returns True
        self.assertTrue(is_subscribed(user1, post1))
        # Lets ensure this actually fails! And see if user2 is a subscriber
        self.assertFalse(is_subscribed(user2, post1))

        # Ensure that the REASON (zset score) is set to the correct value
        self.assertEqual(r.zscore(K.POST_SUBSCRIBERS.format(post1), user1),
                         SubscriptionReasons.POSTER)

        # Post a comment as user 1 and ensure the reason does NOT changes
        create_post(user1, 'user1', 'Test comment', post1)

        # Ensure our reason did not change
        # If we were not subscribed we would be given reason 2 (COMMENTER)
        self.assertNotEqual(r.zscore(K.POST_SUBSCRIBERS.format(post1), user1),
                            SubscriptionReasons.COMMENTER)

        # Test unsubscribe
        self.assertTrue(unsubscribe(user1, post1))
        # Ensure that is_subscribed shows correct
        self.assertFalse(is_subscribed(user1, post1))
        # Test that if we unsubscribe again we get a False result
        self.assertFalse(unsubscribe(user1, post1))
        # Check that unsubscribing some that was never subscribed returns false
        self.assertFalse(unsubscribe(user2, post1))

        # Let's test that commenting subscribes us to the post with the correct
        # reason. Try tag yourself at the same time
        create_post(user1, 'user1', 'Test comment @user1', post1)

        # Ensure we are subscribed
        self.assertTrue(is_subscribed(user1, post1))

        # Check that our reason HAS changed
        self.assertEqual(r.zscore(K.POST_SUBSCRIBERS.format(post1), user1),
                         SubscriptionReasons.COMMENTER)

        # Create a comment as test2 and ensure this user becomes subscribed for
        # the same reason
        create_post(user2, 'user2', 'Test comment', post1)
        self.assertTrue(is_subscribed(user2, post1))
        self.assertEqual(r.zscore(K.POST_SUBSCRIBERS.format(post1), user2),
                         SubscriptionReasons.COMMENTER)

        # Create a new post as test1 and tag test2 and test3 in it
        # ensure all 3 are subscribed and test2 and test3 have the correct
        # reason.
        # Also try and tag ourselves this should have no affect
        # Try tagging someone that does not even exist
        post2 = create_post(user1, 'user1',
                            'Test post @user1 @user2 @user3 @user4')
        self.assertTrue(is_subscribed(user2, post2))
        self.assertTrue(is_subscribed(user3, post2))
        self.assertEqual(r.zscore(K.POST_SUBSCRIBERS.format(post2), user2),
                         SubscriptionReasons.TAGEE)
        self.assertEqual(r.zscore(K.POST_SUBSCRIBERS.format(post2), user3),
                         SubscriptionReasons.TAGEE)

        # Test tagging user 3 in a comment on post1. This ensures that tags
        # in comments do work.
        create_post(user2, 'user2', 'Test comment @user3', post1)
        self.assertTrue(is_subscribed(user3, post1))
        self.assertEqual(r.zscore(K.POST_SUBSCRIBERS.format(post1), user3),
                         SubscriptionReasons.TAGEE)

        # Unsubscribe user2 and user3
        self.assertTrue(unsubscribe(user2, post2))
        self.assertFalse(is_subscribed(user2, post2))
        self.assertTrue(unsubscribe(user3, post2))
        self.assertFalse(is_subscribed(user3, post2))

        # Ensure that subscribe doe not happen when it is not a valid post
        self.assertFalse(
            subscribe(user1, K.NIL_VALUE, SubscriptionReasons.POSTER))
예제 #46
0
    def test_feed_profile(self):
        """
        Feed has been tested else where. This is just a formal test of this.
        We will post a lot of posts as 2 users so we can trigger pagination
        etc, etc.
        """
        # Create 2 users and have them follow each other
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')
        activate(user1)
        activate(user2)
        follow_user(user1, user2)
        follow_user(user2, user1)

        # Both users are now following each other. Let's create 30 posts as
        # each user this will trigger a couple of Pagination pages on the feeds
        # and also trigger a page on the profile
        # We need to store a list of the pids since UUIDs became available
        posts = []
        for i in range(0, 51):
            posts.append(create_post(user1, 'user1', 'User 1, Post %d!' % i))
            posts.append(create_post(user2, 'user1', 'User 2, Post %d!' % i))
        # We now have 60 posts on each feed

        # Try and visit the feed when not logged in
        # There is no flash message to check.
        resp = self.client.get(url_for('users.feed'))
        self.assertEqual(resp.status_code, 302)

        # Log in as user 1 and check that they can see a couple of posts on the
        # first page
        resp = self.client.post(url_for('auth.signin'),
                                data={
                                    'username': '******',
                                    'password': '******'
                                },
                                follow_redirects=True)
        # This sends us too / (feed) by defaults
        self.assertEqual(resp.status_code, 200)
        self.assertIn('User 1, Post 50!', resp.data)
        self.assertIn('User 2, Post 50!', resp.data)
        # Makre sure posts more than 25 ago (default pagination break)
        self.assertNotIn('User 1, Post 1!', resp.data)
        self.assertNotIn('User 2, Post 1!', resp.data)
        # Check the pagination button for next is there are not prev
        self.assertIn('<!-- pagination:older -->', resp.data)
        self.assertIn('<!-- pagination:oldest -->', resp.data)
        self.assertNotIn('<!-- pagination:newer -->', resp.data)
        self.assertNotIn('<!-- pagination:newerest -->', resp.data)

        # Let's go to page 2 in the pagination and check there are posts there
        resp = self.client.get(url_for('users.feed', page=2))

        # Check some posts are there and are not there
        self.assertIn('User 1, Post 30!', resp.data)
        self.assertIn('User 2, Post 30!', resp.data)
        self.assertNotIn('User 1, Post 10!', resp.data)
        self.assertNotIn('User 2, Post 5!', resp.data)
        # Check that both pagination buttons are there
        self.assertIn('<!-- pagination:older -->', resp.data)
        self.assertIn('<!-- pagination:oldest -->', resp.data)
        self.assertIn('<!-- pagination:newer -->', resp.data)
        self.assertIn('<!-- pagination:newest -->', resp.data)

        # Let's go back to the first page
        resp = self.client.get(url_for('users.feed'))
        # We will delete one post and ensure that is goes missing
        self.assertIn('User 1, Post 50!', resp.data)
        # We won't check that the delete button belong to the above post
        # put we will check that there is at least one delete button
        self.assertIn('<!-- delete:post:', resp.data)
        # Delete the post
        resp = self.client.post(url_for('posts.delete_post',
                                        username='******',
                                        post_id=posts[100],
                                        next=url_for('users.feed')),
                                follow_redirects=True)
        self.assertEqual(resp.status_code, 200)
        self.assertIn('User 1, Post 49!', resp.data)
        self.assertNotIn('User 1, Post 50!', resp.data)

        # Check you can not go to a profile for a non-existant user
        resp = self.client.get(url_for('users.profile', username='******'))
        self.assertEqual(resp.status_code, 404)
예제 #47
0
    def test_delete(self):
        """
        Tests delete_post() does what it should.
        This will in turn test delete_comments() as this will be triggered when
        a post is deleted.
        """
        # Create three test users
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')

        # Create a post
        post1 = create_post(user1, 'user1', 'Test post')
        # Create multiple comments
        reply1 = create_post(user1, 'user1', 'Test comment 1', post1)
        reply2 = create_post(user2, 'user2', 'Test comment 2', post1)
        reply3 = create_post(user1, 'user1', 'Test comment 3', post1)
        reply4 = create_post(user2, 'user2', 'Test comment 4', post1)

        # Check the comment count on post1 is correct
        self.assertEqual(get_post(post1).get('comment_count'), 4)

        # Test deleting one comment
        # This function does not actually test to see if the user has the
        # the rights to delete the post. This should be tested in the frontend
        # Check a comment can be deleted
        self.assertIsNone(delete_post(reply4))

        # Check that getting the comment returns None
        self.assertIsNone(get_post(reply4))

        # Ensure the comment count on post1 is correct
        self.assertEqual(get_post(post1).get('comment_count'), 3)

        # Delete the post. This should delete all the comments, we will check
        self.assertIsNone(delete_post(post1))
        # Check that the post does not exist
        self.assertIsNone(get_post(post1))
        # Check that non of the comments exist
        self.assertIsNone(get_post(reply1))
        self.assertIsNone(get_post(reply2))
        self.assertIsNone(get_post(reply3))

        # Test deleting posts with uploads
        # Ensuring that the images are gone.
        # The actual deleting is tested in 'test_uploads.py'
        image = io.BytesIO(open('tests/upload_test_files/otter.jpg').read())
        post1 = create_post(user1, 'user1', 'Test post #2', upload=image)
        self.assertIsNotNone(post1)
        post1_filename = get_post(post1).get('upload')

        # Reset the file position in the image
        image.seek(0)
        reply1 = create_post(user1, 'user1', 'Test comment 1', post1,
                             upload=image)
        self.assertIsNotNone(reply1)
        reply1_filename = get_post(reply1).get('upload')

        image.seek(0)
        reply2 = create_post(user2, 'user2', 'Test comment 2', post1,
                             upload=image)
        self.assertIsNotNone(reply2)
        reply2_filename = get_post(reply2).get('upload')

        # Create GridFS file checker
        grid = gridfs.GridFS(m.db, 'uploads')

        # Check that each file exists
        self.assertTrue(grid.exists({'filename': post1_filename}))
        self.assertTrue(grid.exists({'filename': reply1_filename}))
        self.assertTrue(grid.exists({'filename': reply2_filename}))

        self.assertIsNone(delete_post(post1))

        # Check that all the files no longer exist
        self.assertFalse(grid.exists({'filename': post1_filename}))
        self.assertFalse(grid.exists({'filename': reply1_filename}))
        self.assertFalse(grid.exists({'filename': reply2_filename}))
예제 #48
0
    def test_votes(self):
        """
        Test that the voting mechanism will adjust the relevant score counters
        on users, posts and comments, etc...
        """
        # Create three test users
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')
        user3 = create_account('user3', '*****@*****.**', 'Password')

        # Create a post by user 1
        post1 = create_post(user1, 'user1', 'Test post')

        # Get user 3 to downvote, this will test that the user can not go
        # negative yet the post can
        self.assertIsNone(vote_post(user3, post1, amount=-1))
        # Ensure post score has been adjusted
        self.assertEqual(get_post(post1).get('score'), -1)
        # Ensure user score has NOT been adjusted
        self.assertEqual(get_user(user1).get('score'), 0)

        # Get user 2 to upvote
        self.assertIsNone(vote_post(user2, post1))
        # Ensure post score has been adjusted
        self.assertEqual(get_post(post1).get('score'), 0)
        # Ensure user score has been adjusted
        self.assertEqual(get_user(user1).get('score'), 1)

        # Ensure user 1 can not vote on there own post
        self.assertRaises(CantVoteOnOwn, lambda: vote_post(user1, post1))
        # Ensure the scores have not been adjusted
        self.assertEqual(get_post(post1).get('score'), 0)
        self.assertEqual(get_user(user1).get('score'), 1)

        # Check to see if a user can vote twice on a post
        self.assertRaises(AlreadyVoted, lambda: vote_post(user2, post1))
        # Ensure the scores have not been adjusted
        self.assertEqual(get_post(post1).get('score'), 0)
        self.assertEqual(get_user(user1).get('score'), 1)

        # Repeat the same tests on a comment
        # Create a comment by user 1
        comment1 = create_post(user1, 'user1', 'Test comment', post1)

        # Let's cheat and set user1's score back to 0 so we can check it will
        # not be lowered in the user3 downvote
        m.db.users.update({'_id': user1},
                          {'$set': {'score': 0}})

        # Get user 3 to downvote
        self.assertIsNone(vote_post(user3, comment1, amount=-1))
        # Ensure post score has been adjusted
        self.assertEqual(get_post(comment1)['score'], -1)
        # Ensure user score has NOT been adjusted
        self.assertEqual(get_user(user1)['score'], 0)

        # Get user 2 to upvote
        self.assertIsNone(vote_post(user2, comment1))
        # Ensure post score has been adjusted
        self.assertEqual(get_post(comment1).get('score'), 0)
        # Ensure user score has been adjusted
        self.assertEqual(get_user(user1).get('score'), 1)

        # Ensure user 1 can not vote on there own comment
        self.assertRaises(CantVoteOnOwn, lambda: vote_post(user1, comment1))
        # Ensure post score has been adjusted
        self.assertEqual(get_post(comment1).get('score'), 0)
        # Ensure user score has been adjusted
        self.assertEqual(get_user(user1).get('score'), 1)

        # Check to see if a user can vote twice on a comment
        self.assertRaises(AlreadyVoted, lambda: vote_post(user2, comment1))
        # Ensure post score has been adjusted
        self.assertEqual(get_post(comment1).get('score'), 0)
        # Ensure user score has been adjusted
        self.assertEqual(get_user(user1).get('score'), 1)
예제 #49
0
    def test_dump_account(self):
        """Can a user get their data?

        """
        user1 = create_account('user1', '*****@*****.**', 'Password')
        activate(user1)

        data = dump_account(user1)
        self.assertIsNotNone(data)

        # Got data?
        self.assertEqual('user1', data['user']['username'])
        self.assertTrue(data['user']['active'])

        # Has sensitive data been removed?
        self.assertEqual('<UID>', data['user']['_id'])
        self.assertEqual('<PASSWORD HASH>', data['user']['password'])

        self.assertEqual([], data['posts'])

        # Can they dump posts?
        post1 = create_post(user1, 'user1', 'Post 1')
        post2 = create_post(user1, 'user1', 'Post 2')
        post3 = create_post(user1, 'user1', 'Post 3')

        data = dump_account(user1)
        self.assertIsNotNone(data)

        self.assertNotEqual([], data['posts'])
        self.assertEqual('Post 1', data['posts'][2]['body'])
        self.assertEqual('Post 2', data['posts'][1]['body'])
        self.assertEqual('Post 3', data['posts'][0]['body'])

        self.assertEqual('<UID>', data['posts'][0]['user_id'])

        # What about replies?
        create_post(user1, 'user1', 'Comment 1', post1)
        create_post(user1, 'user1', 'Comment 2', post1)
        create_post(user1, 'user1', 'Comment 3', post2)
        create_post(user1, 'user1', 'Comment 4', post3)

        data = dump_account(user1)
        self.assertNotEqual([], data['posts'])

        self.assertEqual('Comment 1', data['posts'][3]['body'])
        self.assertEqual('Comment 2', data['posts'][2]['body'])
        self.assertEqual('Comment 3', data['posts'][1]['body'])
        self.assertEqual('Comment 4', data['posts'][0]['body'])
        # Senstive data?
        self.assertEqual('<UID>', data['posts'][0]['user_id'])

        # Testing running dump account with a non-existent user
        self.assertIsNone(dump_account(K.NIL_VALUE))

        # Test that user id's a hidden in mentions
        user2 = create_account('user2', '*****@*****.**', 'Password')
        activate(user2)

        user3 = create_account('user3', '*****@*****.**', 'Password')
        activate(user3)

        post1 = create_post(user1, 'user1', 'Hello @user2')
        post_json = json.dumps(dump_account(user1))
        self.assertNotIn(user2, post_json)

        post2 = create_post(user1, 'user1', 'Hello @user2 and @user3')
        post_json = json.dumps(dump_account(user1))
        self.assertNotIn(user2, post_json)
        self.assertNotIn(user3, post_json)
예제 #50
0
    def test_subscriptions(self):
        """
        Test the backend subscription system.

        This includes subscribe(), unsubscribe() and is_subscribed().

        This will also test the correct subscriptions after a post, comment or
        tagging.
        """
        # Create a couple of test accounts
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')
        user3 = create_account('user3', '*****@*****.**', 'Password')

        # Post as user 1 and ensure user 1 exists in Redis
        post1 = create_post(user1, 'user1', 'Test post 1')
        self.assertIsNotNone(r.zrank(K.POST_SUBSCRIBERS.format(post1), user1))

        # Even though it is exactly the same as the above ensure that
        # is_subscribed() returns True
        self.assertTrue(is_subscribed(user1, post1))
        # Lets ensure this actually fails! And see if user2 is a subscriber
        self.assertFalse(is_subscribed(user2, post1))

        # Ensure that the REASON (zset score) is set to the correct value
        self.assertEqual(r.zscore(K.POST_SUBSCRIBERS.format(post1), user1),
                         SubscriptionReasons.POSTER)

        # Post a comment as user 1 and ensure the reason does NOT changes
        create_post(user1, 'user1', 'Test comment', post1)

        # Ensure our reason did not change
        # If we were not subscribed we would be given reason 2 (COMMENTER)
        self.assertNotEqual(r.zscore(K.POST_SUBSCRIBERS.format(post1), user1),
                            SubscriptionReasons.COMMENTER)

        # Test unsubscribe
        self.assertTrue(unsubscribe(user1, post1))
        # Ensure that is_subscribed shows correct
        self.assertFalse(is_subscribed(user1, post1))
        # Test that if we unsubscribe again we get a False result
        self.assertFalse(unsubscribe(user1, post1))
        # Check that unsubscribing some that was never subscribed returns false
        self.assertFalse(unsubscribe(user2, post1))

        # Let's test that commenting subscribes us to the post with the correct
        # reason. Try tag yourself at the same time
        create_post(user1, 'user1', 'Test comment @user1', post1)

        # Ensure we are subscribed
        self.assertTrue(is_subscribed(user1, post1))

        # Check that our reason HAS changed
        self.assertEqual(r.zscore(K.POST_SUBSCRIBERS.format(post1), user1),
                         SubscriptionReasons.COMMENTER)

        # Create a comment as test2 and ensure this user becomes subscribed for
        # the same reason
        create_post(user2, 'user2', 'Test comment', post1)
        self.assertTrue(is_subscribed(user2, post1))
        self.assertEqual(r.zscore(K.POST_SUBSCRIBERS.format(post1), user2),
                         SubscriptionReasons.COMMENTER)

        # Create a new post as test1 and tag test2 and test3 in it
        # ensure all 3 are subscribed and test2 and test3 have the correct
        # reason.
        # Also try and tag ourselves this should have no affect
        # Try tagging someone that does not even exist
        post2 = create_post(user1, 'user1',
                            'Test post @user1 @user2 @user3 @user4')
        self.assertTrue(is_subscribed(user2, post2))
        self.assertTrue(is_subscribed(user3, post2))
        self.assertEqual(r.zscore(K.POST_SUBSCRIBERS.format(post2), user2),
                         SubscriptionReasons.TAGEE)
        self.assertEqual(r.zscore(K.POST_SUBSCRIBERS.format(post2), user3),
                         SubscriptionReasons.TAGEE)

        # Test tagging user 3 in a comment on post1. This ensures that tags
        # in comments do work.
        create_post(user2, 'user2', 'Test comment @user3', post1)
        self.assertTrue(is_subscribed(user3, post1))
        self.assertEqual(r.zscore(K.POST_SUBSCRIBERS.format(post1), user3),
                         SubscriptionReasons.TAGEE)

        # Unsubscribe user2 and user3
        self.assertTrue(unsubscribe(user2, post2))
        self.assertFalse(is_subscribed(user2, post2))
        self.assertTrue(unsubscribe(user3, post2))
        self.assertFalse(is_subscribed(user3, post2))

        # Ensure that subscribe doe not happen when it is not a valid post
        self.assertFalse(subscribe(user1, K.NIL_VALUE,
                                   SubscriptionReasons.POSTER))
예제 #51
0
    def test_feed_profile(self):
        """
        Feed has been tested else where. This is just a formal test of this.
        We will post a lot of posts as 2 users so we can trigger pagination
        etc, etc.
        """
        # Create 2 users and have them follow each other
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')
        activate(user1)
        activate(user2)
        follow_user(user1, user2)
        follow_user(user2, user1)

        # Both users are now following each other. Let's create 30 posts as
        # each user this will trigger a couple of Pagination pages on the feeds
        # and also trigger a page on the profile
        # We need to store a list of the pids since UUIDs became available
        posts = []
        for i in range(0, 51):
            posts.append(create_post(user1, 'user1', 'User 1, Post %d!' % i))
            posts.append(create_post(user2, 'user1', 'User 2, Post %d!' % i))
        # We now have 60 posts on each feed

        # Try and visit the feed when not logged in
        # There is no flash message to check.
        resp = self.client.get(url_for('users.feed'))
        self.assertEqual(resp.status_code, 302)

        # Log in as user 1 and check that they can see a couple of posts on the
        # first page
        resp = self.client.post(url_for('auth.signin'), data={
            'username': '******',
            'password': '******'
        }, follow_redirects=True)
        # This sends us too / (feed) by defaults
        self.assertEqual(resp.status_code, 200)
        self.assertIn('User 1, Post 50!', resp.data)
        self.assertIn('User 2, Post 50!', resp.data)
        # Makre sure posts more than 25 ago (default pagination break)
        self.assertNotIn('User 1, Post 1!', resp.data)
        self.assertNotIn('User 2, Post 1!', resp.data)
        # Check the pagination button for next is there are not prev
        self.assertIn('<!-- pagination:older -->', resp.data)
        self.assertIn('<!-- pagination:oldest -->', resp.data)
        self.assertNotIn('<!-- pagination:newer -->', resp.data)
        self.assertNotIn('<!-- pagination:newerest -->', resp.data)

        # Let's go to page 2 in the pagination and check there are posts there
        resp = self.client.get(url_for('users.feed', page=2))

        # Check some posts are there and are not there
        self.assertIn('User 1, Post 30!', resp.data)
        self.assertIn('User 2, Post 30!', resp.data)
        self.assertNotIn('User 1, Post 10!', resp.data)
        self.assertNotIn('User 2, Post 5!', resp.data)
        # Check that both pagination buttons are there
        self.assertIn('<!-- pagination:older -->', resp.data)
        self.assertIn('<!-- pagination:oldest -->', resp.data)
        self.assertIn('<!-- pagination:newer -->', resp.data)
        self.assertIn('<!-- pagination:newest -->', resp.data)

        # Let's go back to the first page
        resp = self.client.get(url_for('users.feed'))
        # We will delete one post and ensure that is goes missing
        self.assertIn('User 1, Post 50!', resp.data)
        # We won't check that the delete button belong to the above post
        # put we will check that there is at least one delete button
        self.assertIn('<!-- delete:post:', resp.data)
        # Delete the post
        resp = self.client.post(url_for('posts.delete_post', username='******',
                                post_id=posts[100], next=url_for(
                                    'users.feed')),
                                follow_redirects=True)
        self.assertEqual(resp.status_code, 200)
        self.assertIn('User 1, Post 49!', resp.data)
        self.assertNotIn('User 1, Post 50!', resp.data)

        # Check you can not go to a profile for a non-existant user
        resp = self.client.get(url_for('users.profile', username='******'))
        self.assertEqual(resp.status_code, 404)
예제 #52
0
    def test_delete(self):
        """
        Tests delete_post() does what it should.
        This will in turn test delete_comments() as this will be triggered when
        a post is deleted.
        """
        # Create three test users
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')

        # Create a post
        post1 = create_post(user1, 'user1', 'Test post')
        # Create multiple comments
        reply1 = create_post(user1, 'user1', 'Test comment 1', post1)
        reply2 = create_post(user2, 'user2', 'Test comment 2', post1)
        reply3 = create_post(user1, 'user1', 'Test comment 3', post1)
        reply4 = create_post(user2, 'user2', 'Test comment 4', post1)

        # Check the comment count on post1 is correct
        self.assertEqual(get_post(post1).get('comment_count'), 4)

        # Test deleting one comment
        # This function does not actually test to see if the user has the
        # the rights to delete the post. This should be tested in the frontend
        # Check a comment can be deleted
        self.assertIsNone(delete_post(reply4))

        # Check that getting the comment returns None
        self.assertIsNone(get_post(reply4))

        # Ensure the comment count on post1 is correct
        self.assertEqual(get_post(post1).get('comment_count'), 3)

        # Delete the post. This should delete all the comments, we will check
        self.assertIsNone(delete_post(post1))
        # Check that the post does not exist
        self.assertIsNone(get_post(post1))
        # Check that non of the comments exist
        self.assertIsNone(get_post(reply1))
        self.assertIsNone(get_post(reply2))
        self.assertIsNone(get_post(reply3))

        # Test deleting posts with uploads
        # Ensuring that the images are gone.
        # The actual deleting is tested in 'test_uploads.py'
        image = io.BytesIO(open('tests/upload_test_files/otter.jpg').read())
        post1 = create_post(user1, 'user1', 'Test post #2', upload=image)
        self.assertIsNotNone(post1)
        post1_filename = get_post(post1).get('upload')

        # Reset the file position in the image
        image.seek(0)
        reply1 = create_post(user1,
                             'user1',
                             'Test comment 1',
                             post1,
                             upload=image)
        self.assertIsNotNone(reply1)
        reply1_filename = get_post(reply1).get('upload')

        image.seek(0)
        reply2 = create_post(user2,
                             'user2',
                             'Test comment 2',
                             post1,
                             upload=image)
        self.assertIsNotNone(reply2)
        reply2_filename = get_post(reply2).get('upload')

        # Create GridFS file checker
        grid = gridfs.GridFS(m.db, 'uploads')

        # Check that each file exists
        self.assertTrue(grid.exists({'filename': post1_filename}))
        self.assertTrue(grid.exists({'filename': reply1_filename}))
        self.assertTrue(grid.exists({'filename': reply2_filename}))

        self.assertIsNone(delete_post(post1))

        # Check that all the files no longer exist
        self.assertFalse(grid.exists({'filename': post1_filename}))
        self.assertFalse(grid.exists({'filename': reply1_filename}))
        self.assertFalse(grid.exists({'filename': reply2_filename}))
예제 #53
0
    def test_permissions(self):
        """Ensure only users with the correct permissions can see posts"""
        user1 = create_account('user1', '*****@*****.**', 'Password')
        activate(user1)
        post1 = create_post(user1, 'user1', 'Test public', permission=0)
        post2 = create_post(user1, 'user1', 'Test pjuu', permission=1)
        post3 = create_post(user1, 'user1', 'Test approved', permission=2)

        resp = self.client.get(url_for('users.profile', username='******'))
        self.assertIn('Test public', resp.data)
        self.assertNotIn('Test pjuu', resp.data)
        self.assertNotIn('Test approved', resp.data)

        resp = self.client.get(
            url_for('posts.view_post', username='******', post_id=post1))
        self.assertEqual(resp.status_code, 200)

        resp = self.client.get(
            url_for('posts.view_post', username='******', post_id=post2))
        self.assertEqual(resp.status_code, 403)

        resp = self.client.get(
            url_for('posts.view_post', username='******', post_id=post3))
        self.assertEqual(resp.status_code, 403)

        # Create a user and check we can see the Pjuu-wide post
        user2 = create_account('user2', '*****@*****.**', 'Password')
        activate(user2)

        self.client.post(url_for('auth.signin'),
                         data={
                             'username': '******',
                             'password': '******'
                         })
        resp = self.client.get(url_for('users.profile', username='******'))
        self.assertIn('Test public', resp.data)
        self.assertIn('Test pjuu', resp.data)
        self.assertNotIn('Test approved', resp.data)

        resp = self.client.get(
            url_for('posts.view_post', username='******', post_id=post1))
        self.assertEqual(resp.status_code, 200)

        resp = self.client.get(
            url_for('posts.view_post', username='******', post_id=post2))
        self.assertEqual(resp.status_code, 200)

        resp = self.client.get(
            url_for('posts.view_post', username='******', post_id=post3))
        self.assertEqual(resp.status_code, 403)

        # Have user1 approve user2 and ensure he can see all posts
        # User2 needs to be following user1
        follow_user(user2, user1)
        approve_user(user1, user2)
        self.assertTrue(is_approved(user1, user2))

        resp = self.client.get(url_for('users.profile', username='******'))
        self.assertIn('Test public', resp.data)
        self.assertIn('Test pjuu', resp.data)
        self.assertIn('Test approved', resp.data)

        resp = self.client.get(
            url_for('posts.view_post', username='******', post_id=post1))
        self.assertEqual(resp.status_code, 200)

        resp = self.client.get(
            url_for('posts.view_post', username='******', post_id=post2))
        self.assertEqual(resp.status_code, 200)

        resp = self.client.get(
            url_for('posts.view_post', username='******', post_id=post3))
        self.assertEqual(resp.status_code, 200)