Example #1
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))
Example #2
0
    def test_search(self):
        """
        Make sure users can actually find each other.

        This will need a lot more work once we add in a proper search facility
        rather than just the Redis KEYS command
        """
        # Create test user
        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
        user2 = create_account('user2', '*****@*****.**', 'Password')
        # Ensure the new user can be found
        self.assertEqual(len(search('user2').items), 1)
        self.assertEqual(search('user2').total, 1)
        # Ensure partial match returns both test1/2 users
        self.assertEqual(len(search('use').items), 2)
        self.assertEqual(search('use').total, 2)

        # Delete the account test 2 and try searching again
        # Adding in this test as it has stung us before
        delete_account(user2)
        self.assertEqual(search('test2').total, 0)
Example #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))
Example #4
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)
Example #5
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))
Example #6
0
    def test_delete_account_followers_following(self):
        """Does the users social graph go on deletion of account?

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

        # Friends :)
        self.assertTrue(follow_user(user1, user2))
        self.assertTrue(follow_user(user2, user1))

        # Ensure Redis's sorted sets are correct
        self.assertIn(user2, r.zrange(K.USER_FOLLOWERS.format(user1), 0, -1))
        self.assertIn(user2, r.zrange(K.USER_FOLLOWING.format(user1), 0, -1))
        self.assertIn(user1, r.zrange(K.USER_FOLLOWERS.format(user2), 0, -1))
        self.assertIn(user1, r.zrange(K.USER_FOLLOWING.format(user2), 0, -1))

        delete_account(user1)

        # Ensure sorted sets are emptied
        self.assertNotIn(user2, r.zrange(K.USER_FOLLOWERS.format(user1), 0,
                                         -1))
        self.assertNotIn(user2, r.zrange(K.USER_FOLLOWING.format(user1), 0,
                                         -1))
        self.assertNotIn(user1, r.zrange(K.USER_FOLLOWERS.format(user2), 0,
                                         -1))
        self.assertNotIn(user1, r.zrange(K.USER_FOLLOWING.format(user2), 0,
                                         -1))
Example #7
0
    def test_delete_account_followers_following(self):
        """Does the users social graph go on deletion of account?

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

        # Friends :)
        self.assertTrue(follow_user(user1, user2))
        self.assertTrue(follow_user(user2, user1))

        # Ensure Redis's sorted sets are correct
        self.assertIn(user2, r.zrange(K.USER_FOLLOWERS.format(user1), 0, -1))
        self.assertIn(user2, r.zrange(K.USER_FOLLOWING.format(user1), 0, -1))
        self.assertIn(user1, r.zrange(K.USER_FOLLOWERS.format(user2), 0, -1))
        self.assertIn(user1, r.zrange(K.USER_FOLLOWING.format(user2), 0, -1))

        delete_account(user1)

        # Ensure sorted sets are emptied
        self.assertNotIn(user2, r.zrange(K.USER_FOLLOWERS.format(user1),
                                         0, -1))
        self.assertNotIn(user2, r.zrange(K.USER_FOLLOWING.format(user1),
                                         0, -1))
        self.assertNotIn(user1, r.zrange(K.USER_FOLLOWERS.format(user2),
                                         0, -1))
        self.assertNotIn(user1, r.zrange(K.USER_FOLLOWING.format(user2),
                                         0, -1))
Example #8
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))
Example #9
0
    def test_alertmanager(self):
        """
        Test the alert manager.

        Similar to the above a very simple test. Will check that it can alert
        users and one can be created.
        """
        # Create our alert manager
        am = AlertManager()

        # Try and load a non-existant alert
        self.assertIsNone(am.get(k.NIL_VALUE))

        # Try and alert on something which is not an alert
        self.assertRaises(ValueError, lambda: am.alert('ALERT', k.NIL_VALUE))

        # Test that alerting a single users does not work, they need to be
        # iterable
        # Create an alert
        alert = BaseAlert(k.NIL_VALUE)
        self.assertRaises(TypeError, lambda: am.alert(alert, 1))

        # Create a couple of users
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')

        # Ensure the length of user1's alert feed is 0
        self.assertEqual(r.zcard(k.USER_ALERTS.format(user1)), 0)

        # Create an alert from user2
        alert = BaseAlert(user2)
        # Alert user1
        am.alert(alert, [user1])

        # Ensure the length of user1's alert feed is 1
        self.assertEqual(r.zcard(k.USER_ALERTS.format(user1)), 1)

        # Get alerts for user1, user Redis directly
        alerts = r.zrange(k.USER_ALERTS.format(user1), 0, 0)
        # Get the alert from alerts
        alert = am.get(alerts[0])
        self.assertIsNotNone(alert)
        self.assertEqual(alert.user.get('username'), 'user2')
        self.assertEqual(alert.user.get('email'), '*****@*****.**')

        # Delete test2 and ensure getting the alert returns None
        delete_account(user2)
        alert = am.get(alerts[0])
        self.assertIsNone(alert)
Example #10
0
    def test_alertmanager(self):
        """
        Test the alert manager.

        Similar to the above a very simple test. Will check that it can alert
        users and one can be created.
        """
        # Create our alert manager
        am = AlertManager()

        # Try and load a non-existant alert
        self.assertIsNone(am.get(K.NIL_VALUE))

        # Try and alert on something which is not an alert
        self.assertRaises(ValueError, lambda: am.alert('ALERT', K.NIL_VALUE))

        # Test that alerting a single users does not work, they need to be
        # iterable
        # Create an alert
        alert = BaseAlert(K.NIL_VALUE)
        self.assertRaises(TypeError, lambda: am.alert(alert, 1))

        # Create a couple of users
        user1 = create_user('user1', '*****@*****.**', 'Password')
        user2 = create_user('user2', '*****@*****.**', 'Password')

        # Ensure the length of user1's alert feed is 0
        self.assertEqual(r.zcard(K.USER_ALERTS.format(user1)), 0)

        # Create an alert from user2
        alert = BaseAlert(user2)
        # Alert user1
        am.alert(alert, [user1])

        # Ensure the length of user1's alert feed is 1
        self.assertEqual(r.zcard(K.USER_ALERTS.format(user1)), 1)

        # Get alerts for user1, user Redis directly
        alerts = r.zrange(K.USER_ALERTS.format(user1), 0, 0)
        # Get the alert from alerts
        alert = am.get(alerts[0])
        self.assertIsNotNone(alert)
        self.assertEqual(alert.get_username(), 'user2')
        self.assertEqual(alert.get_email(), '*****@*****.**')

        # Delete test2 and ensure getting the alert returns None
        delete_account(user2)
        alert = am.get(alerts[0])
        self.assertIsNone(alert)
Example #11
0
    def test_delete_account_basic(self):
        """Does the basic data go when a user delete their account?

        ..note: Just checks the auth part.

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

        delete_account(user1)

        self.assertIsNone(get_user(user1))
        self.assertIsNone(get_uid_username('user1'))
        self.assertIsNone(get_uid_email('*****@*****.**'))

        self.assertFalse(authenticate('user1', 'Password'))
        self.assertIsNone(get_uid_username('user1'))
        self.assertIsNone(get_uid_email('*****@*****.**'))
Example #12
0
    def test_delete_account_basic(self):
        """Does the basic data go when a user delete their account?

        ..note: Just checks the auth part.

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

        delete_account(user1)

        self.assertIsNone(get_user(user1))
        self.assertIsNone(get_uid_username('user1'))
        self.assertIsNone(get_uid_email('*****@*****.**'))

        self.assertFalse(authenticate('user1', 'Password'))
        self.assertIsNone(get_uid_username('user1'))
        self.assertIsNone(get_uid_email('*****@*****.**'))
Example #13
0
    def test_signup_activate(self):
        """
        Tests the signup and activate endpoint inside Pjuu.

        There are some limitations to this! We can not test e-mail sending as
        this will not be available on Travis.
        """
        # Test that we can GET the signup page
        resp = self.client.get(url_for('auth.signup'))
        # We should get a 200 with an error message if we were not successful
        self.assertEqual(resp.status_code, 200)

        # Lets attempt to create a new account. This should return a 302 to
        # /signin with a little message displayed to activate your account
        resp = self.client.post(url_for('auth.signup'), data={
            'username': '******',
            'email': '*****@*****.**',
            'password': '******',
            'password2': 'Password'
        }, follow_redirects=True)
        self.assertEqual(resp.status_code, 200)
        self.assertIn('Yay! You\'ve signed up', resp.data)

        # We are in testing mode so we can get the auth token from the response
        # this is in the headers as X-Pjuu-Token
        token = resp.headers.get('X-Pjuu-Token')
        self.assertIsNotNone(token)
        # Try and actiavte our account
        resp = self.client.get(url_for('auth.activate', token=token),
                               follow_redirects=True)
        self.assertEqual(resp.status_code, 200)
        self.assertIn('Your account has now been activated', resp.data)

        # Try and activate the account again. We should get a 302 to /signin
        # and a flash message informing up that the account is already active
        resp = self.client.get(url_for('auth.activate', token=token),
                               follow_redirects=True)
        self.assertEqual(resp.status_code, 200)
        self.assertIn('Invalid token', resp.data)

        # Try and signup with the same user and ensure we get the correct resp
        # and error codes. We will also put mismatch passwords in just to test
        # that all forms throw the correct error
        resp = self.client.post(url_for('auth.signup'), data={
            'username': '******',
            'email': '*****@*****.**',
            'password': '******',
            'password2': 'PasswordPassword'
        }, follow_redirects=True)
        self.assertEqual(resp.status_code, 200)
        # Ensure there is an overall form error
        self.assertIn('Oh no! There are errors in your form', resp.data)
        # Ensure the form elements actually throw there own errors
        self.assertIn('User name already in use', resp.data)
        self.assertIn('E-mail address already in use', resp.data)
        self.assertIn('Passwords must match', resp.data)

        # Try a few scenarios with email addresses we are not happy about.
        resp = self.client.post(url_for('auth.signup'), data={
            'username': '******',
            'email': 'user1#[email protected]',
            'password': '******',
            'password2': 'Password'
        }, follow_redirects=True)
        self.assertEqual(resp.status_code, 200)
        # Ensure there is an overall form error
        self.assertIn('Oh no! There are errors in your form', resp.data)
        self.assertIn('Invalid email address', resp.data)

        # Ensure that we CAN signup with a + in the name. This is a hate of
        # mine. Not being able to namespace my e-mail addresses
        resp = self.client.post(url_for('auth.signup'), data={
            'username': '******',
            'email': '*****@*****.**',
            'password': '******',
            'password2': 'Password'
        }, follow_redirects=True)
        self.assertEqual(resp.status_code, 200)
        self.assertIn('Yay! You\'ve signed up', resp.data)

        # Log in to Pjuu so that we can make sure we can not get back to signup
        resp = self.client.post(url_for('auth.signin'), data={
            'username': '******',
            'password': '******'
        }, follow_redirects=True)
        self.assertEqual(resp.status_code, 200)
        # We are now logged in lets try and go to signup and ensure we get
        # redirected back to feed
        resp = self.client.get(url_for('auth.signup'))
        self.assertEqual(resp.status_code, 302)
        # Why we are logged in lets ensure we can't get to activate
        resp = self.client.get(url_for('auth.activate', token=token))
        self.assertEqual(resp.status_code, 302)

        # Lets delete the account and then try and reactivate
        delete_account(get_uid_username('user1'))
        resp = self.client.get(url_for('auth.activate', token=token),
                               follow_redirects=True)
        self.assertEqual(resp.status_code, 200)
        self.assertIn('Invalid token', resp.data)
Example #14
0
    def test_follow_unfollow_get_followers_following_is_following(self):
        """
        Test everything about following. There is not that much to it to
        deserve 3 seperate methods.
        """
        # Create two test users
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')
        # Ensure is_following() is false atm
        self.assertFalse(is_following(user1, user2))
        self.assertFalse(is_following(user2, user1))
        # Ensure user 1 can follow user 2
        self.assertTrue(follow_user(user1, user2))
        # Ensure the user can't follow them again
        self.assertFalse(follow_user(user1, user2))
        # And visa-versa
        self.assertTrue(follow_user(user2, user1))
        # Ensre the user can't follow them again
        self.assertFalse(follow_user(user2, user1))
        # Ensure the id's are in the Redis sorted sets, followers and following
        self.assertIn(user2, r.zrange(k.USER_FOLLOWING.format(user1), 0, -1))
        self.assertIn(user2, r.zrange(k.USER_FOLLOWERS.format(user1), 0, -1))
        self.assertIn(user1, r.zrange(k.USER_FOLLOWING.format(user2), 0, -1))
        self.assertIn(user1, r.zrange(k.USER_FOLLOWERS.format(user2), 0, -1))
        # Ensure the get_followers and get_following functions return
        # the correct data
        self.assertEqual(len(get_following(user1).items), 1)
        self.assertEqual(len(get_following(user1).items), 1)
        self.assertEqual(len(get_following(user2).items), 1)
        self.assertEqual(len(get_following(user2).items), 1)
        # Ensure the totals are correct
        self.assertEqual(get_following(user1).total, 1)
        self.assertEqual(get_followers(user1).total, 1)
        self.assertEqual(get_following(user2).total, 1)
        self.assertEqual(get_followers(user2).total, 1)

        # Make sure is_following() returns correctly
        self.assertTrue(is_following(user1, user2))
        self.assertTrue(is_following(user2, user1))

        # User 1 unfollow user 2 and ensure the sorted sets are updated
        self.assertTrue(unfollow_user(user1, user2))
        self.assertNotIn(user2,
                         r.zrange(k.USER_FOLLOWING.format(user1), 0, -1))
        self.assertNotIn(user1,
                         r.zrange(k.USER_FOLLOWERS.format(user2), 0, -1))

        # Ensure the user can't unfollow the user again
        self.assertFalse(unfollow_user(user1, user2))
        # Ensure is_following shows correctly
        self.assertFalse(is_following(user1, user2))

        # Test what happens when we delete an account.

        # Ensure user 2 is still following user1
        self.assertTrue(is_following(user2, user1))

        # This should clean
        delete_account(user1)

        # Ensure this has cleaned user2 following list
        self.assertFalse(is_following(user2, user1))

        # Ensure get_followers and get_following return the correct value for
        # user2
        self.assertEqual(len(get_following(user2).items), 0)
        # Ensure the totals are correct
        self.assertEqual(get_following(user2).total, 0)
        self.assertEqual(get_followers(user2).total, 0)
        # Make sure is_following() returns correctly
        self.assertFalse(is_following(user1, user2))
        self.assertFalse(is_following(user2, user1))

        # I don't want to play with the above testing to much. I am adding
        # in a test for self cleaning lists. I am going to reset this test
        # case by manually flushing the Redis database :)
        r.flushdb()
        # Back to normal, I don't like artificially uping the number of tests.

        # Test the self cleaning lists in case there is an issue with Redis
        # during an account deletion. We need 2 new users.
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')

        # Follow each other.
        self.assertTrue(follow_user(user1, user2))
        self.assertTrue(follow_user(user2, user1))

        # Manually delete user1
        m.db.users.remove({'_id': user1})

        # Ensure user1 appears in both user2's followers and following lists
        self.assertIn(user1, r.zrange(k.USER_FOLLOWERS.format(user2), 0, -1))
        self.assertIn(user1, r.zrange(k.USER_FOLLOWING.format(user2), 0, -1))

        # Ensure if we actuallt get the lists from the backend functions user1
        # is not there
        self.assertEqual(get_followers(user2).total, 0)
        self.assertEqual(get_following(user2).total, 0)
Example #15
0
    def test_alerts(self):
        """
        Tests for the 2 functions which are used on the side to get alerts and
        also test FollowAlert from here.
        """
        # Create 2 test users
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')

        # Ensure that get_alerts pagination object is empty
        self.assertEqual(get_alerts(user1).total, 0)
        self.assertEqual(len(get_alerts(user1).items), 0)

        # Get user 2 to follow user 1
        follow_user(user2, user1)

        # Check that i_has_alerts is True
        self.assertTrue(new_alerts(user1))

        # Ensure that there is an alert in the get_alerts
        self.assertEqual(get_alerts(user1).total, 1)
        self.assertEqual(len(get_alerts(user1).items), 1)

        # Check that i_has_alerts is False, we have read them with get_alerts
        self.assertFalse(new_alerts(user1))

        # Get the alert and check that the alert is the follow alert
        alert = get_alerts(user1).items[0]
        self.assertTrue(isinstance(alert, FollowAlert))
        # Also check it's still a BaseAlert
        self.assertTrue(isinstance(alert, BaseAlert))
        # Check its from test2
        self.assertEqual(alert.user.get('username'), 'user2')
        self.assertEqual(alert.user.get('email'), '*****@*****.**')
        self.assertIn('has started following you', alert.prettify())

        # Delete test2 and ensure we get no alerts
        delete_account(user2)

        # Ensure the alert is still inside Redis
        self.assertEqual(r.zcard(k.USER_ALERTS.format(user1)), 1)

        # Get the alerts, should be none and should also clear the alert from
        # Redis
        self.assertEqual(get_alerts(user1).total, 0)
        self.assertEqual(len(get_alerts(user1).items), 0)
        self.assertEqual(r.zcard(k.USER_ALERTS.format(user1)), 0)

        # Do the same as above to ensure we can delete an alert ourselves
        # Create another user
        user3 = create_account('user3', '*****@*****.**', 'Password')

        follow_user(user1, user3)

        # Check the alerts are there
        alert = get_alerts(user3).items[0]
        self.assertTrue(isinstance(alert, FollowAlert))
        # Also check it's still a BaseAlert
        self.assertTrue(isinstance(alert, BaseAlert))
        # Check its from test2
        self.assertEqual(alert.user.get('username'), 'user1')
        self.assertEqual(alert.user.get('email'), '*****@*****.**')
        self.assertIn('has started following you', alert.prettify())

        # Delete the alert with aid from the alert
        delete_alert(user3, alert.alert_id)

        # Get the alerts and ensure the list is empty
        self.assertEqual(get_alerts(user3).total, 0)
        self.assertEqual(len(get_alerts(user3).items), 0)
        self.assertEqual(r.zcard(k.USER_ALERTS.format(user3)), 0)

        # Unfollow the user3 and then follow them again
        unfollow_user(user1, user3)
        follow_user(user1, user3)

        alert = get_alerts(user3).items[0]
        self.assertIn('has started following you', alert.prettify())

        # Manually delete the alert
        r.delete(k.ALERT.format(alert.alert_id))

        # Get the alerts again and ensure the length is 0
        # Ensure that the alert is not pulled down
        alerts = get_alerts(user3)
        self.assertEqual(len(alerts.items), 0)

        # Get alerts for a non-existant user
        # This will not fail but will have an empty pagination
        alerts = get_alerts(k.NIL_VALUE)
        self.assertEqual(len(alerts.items), 0)
Example #16
0
    def test_avatars(self):
        """Can a user set there own avatar?"""
        # Create a test user
        user1 = create_account('user1', '*****@*****.**', 'Password')
        # Activate it
        activate(user1)

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

        # Check default avatar is present
        resp = self.client.get(url_for('users.settings_profile',
                               username='******'))
        self.assertIn('<!-- user:avatar:default -->', resp.data)
        self.assertIn(url_for('static', filename='img/otter_avatar.png'),
                      resp.data)

        # Check the avatar for the default
        # We can't inspect it
        user = get_user(user1)
        resp = self.client.get(url_for('static',
                                       filename='img/otter_avatar.png'))
        self.assertEqual(resp.status_code, 200)

        # Get the users object to check some things
        user = get_user(user1)

        # User shouldn't have an avatar
        self.assertIsNone(user.get('avatar'))

        # Create the file
        image = io.BytesIO(open('tests/upload_test_files/otter.jpg').read())

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

        user = get_user(user1)

        self.assertIsNotNone(user.get('avatar'))
        self.assertIn('<!-- user:avatar:{} -->'.format(user.get('avatar')),
                      resp.data)

        grid = gridfs.GridFS(m.db, collection='uploads')
        self.assertEqual(grid.find({'filename': user.get('avatar')}).count(),
                         1)

        resp = self.client.get(url_for('posts.get_upload',
                               filename=user.get('avatar')))
        self.assertEqual(resp.status_code, 200)

        # upload another and ensure there is only one in GridFs
        image = io.BytesIO(open('tests/upload_test_files/otter.jpg').read())

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

        user = get_user(user1)
        self.assertEqual(grid.find({'filename': user.get('avatar')}).count(),
                         1)

        # This is technically an auth test but if we delete the account we can
        # ensure the avatar is removed.
        delete_account(user1)
        self.assertEqual(grid.find({'filename': user.get('avatar')}).count(),
                         0)
Example #17
0
    def test_search(self):
        """
        Ensure the search works and users are shown correctly.
        """
        # Let's try and access the endpoint feature when we are not logged in
        # We should not be able to see it
        resp = self.client.get('users.search', follow_redirects=True)
        self.assertIn('You need to be logged in to view that', resp.data)

        # We need some users with usernames different enough that we can test
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')
        user3 = create_account('joe', '*****@*****.**', 'Password')
        user4 = create_account('ant', '*****@*****.**', 'Password')
        user5 = create_account('fil', '*****@*****.**', 'Password')
        # Activate some of the accounts.
        activate(user1)
        activate(user2)
        activate(user3)
        activate(user4)

        # Let's sign in!
        # We will sign in as joe this time as that is me :)
        self.client.post('signin', data={
            'username': '******',
            'password': '******'
        })

        # Let's check we see the correct thing on the search page when there
        # is no search
        resp = self.client.get(url_for('users.search'))
        self.assertIn('<!-- author search -->', resp.data)
        self.assertNotIn('<h1>Results:', resp.data)

        # Lets search for ourselves
        resp = self.client.get(url_for('users.search', query='joe'))
        self.assertIn('<!-- list:user:%s -->' % user3, resp.data)

        # Lets check that this is case-insensitive
        resp = self.client.get(url_for('users.search', query='JOE'))
        self.assertIn('<!-- list:user:%s -->' % user3, resp.data)

        # Lets try this partially
        resp = self.client.get(url_for('users.search', query='j'))
        self.assertIn('<!-- list:user:%s -->' % user3, resp.data)

        # Lets check we see two users if two match
        resp = self.client.get(url_for('users.search', query='user'))
        self.assertIn('<!-- list:user:%s -->' % user1, resp.data)
        self.assertIn('<!-- list:user:%s -->' % user2, resp.data)

        # Lets check to see if inactive users show up. THEY SHOULD
        resp = self.client.get(url_for('users.search', query='fil'))
        self.assertNotIn('<!-- list:user:%s -->' % user5, resp.data)

        # Lets check that we can find ant because we are going to delete him
        # to ensure he goes! This has caused issues on the live site
        resp = self.client.get(url_for('users.search', query='ant'))
        self.assertIn('<!-- list:user:%s -->' % user4, resp.data)

        # Lets check that we can find ant because we are going to delete him
        # to ensure he goes! This has caused issues on the live site
        resp = self.client.get(url_for('users.search', query='ant'))
        self.assertIn('<!-- list:user:%s -->' % user4, resp.data)

        # We will just backend delete the account.
        delete_account(user4)
        # Account is gone, lets ensure this has gone
        resp = self.client.get(url_for('users.search', query='ant'))
        self.assertNotIn('<!-- list:user:%s -->' % user4, resp.data)
Example #18
0
    def test_signup_activate(self):
        """Tests the signup and activate endpoint inside Pjuu.

        There are some limitations to this! We can not test e-mail sending as
        this will not be available on Travis.
        """
        # Test that we can GET the signup page
        resp = self.client.get(url_for('auth.signup'))
        # We should get a 200 with an error message if we were not successful
        self.assertEqual(resp.status_code, 200)

        # Lets attempt to create a new account. This should return a 302 to
        # /signin with a little message displayed to activate your account
        resp = self.client.post(url_for('auth.signup'),
                                data={
                                    'username': '******',
                                    'email': '*****@*****.**',
                                    'password': '******',
                                },
                                follow_redirects=True)
        self.assertEqual(resp.status_code, 200)
        self.assertIn('Yay! You\'ve signed up', resp.data)

        # We are in testing mode so we can get the auth token from the response
        # this is in the headers as X-Pjuu-Token
        token = resp.headers.get('X-Pjuu-Token')
        self.assertIsNotNone(token)
        # Try and actiavte our account
        resp = self.client.get(url_for('auth.activate', token=token),
                               follow_redirects=True)
        self.assertEqual(resp.status_code, 200)
        self.assertIn('Your account has now been activated', resp.data)

        # Try and activate the account again. We should get a 302 to /signin
        # and a flash message informing up that the account is already active
        resp = self.client.get(url_for('auth.activate', token=token),
                               follow_redirects=True)
        self.assertEqual(resp.status_code, 200)
        self.assertIn('Invalid token', resp.data)

        # Try and signup with the same user and ensure we get the correct resp
        # and error codes
        resp = self.client.post(url_for('auth.signup'),
                                data={
                                    'username': '******',
                                    'email': '*****@*****.**',
                                    'password': '******',
                                },
                                follow_redirects=True)
        self.assertEqual(resp.status_code, 200)
        # Ensure there is an overall form error
        self.assertIn('Oh no! There are errors in your form', resp.data)
        # Ensure the form elements actually throw there own errors
        self.assertIn('User name already in use', resp.data)
        self.assertIn('E-mail address already in use', resp.data)

        # Try a few scenarios with email addresses we are not happy about.
        resp = self.client.post(url_for('auth.signup'),
                                data={
                                    'username': '******',
                                    'email': 'user1#[email protected]',
                                    'password': '******',
                                },
                                follow_redirects=True)
        self.assertEqual(resp.status_code, 200)
        # Ensure there is an overall form error
        self.assertIn('Oh no! There are errors in your form', resp.data)
        self.assertIn('Invalid email address', resp.data)

        # Ensure that we CAN signup with a + in the name. This is a hate of
        # mine. Not being able to namespace my e-mail addresses
        resp = self.client.post(url_for('auth.signup'),
                                data={
                                    'username': '******',
                                    'email': '*****@*****.**',
                                    'password': '******',
                                },
                                follow_redirects=True)
        self.assertEqual(resp.status_code, 200)
        self.assertIn('Yay! You\'ve signed up', resp.data)

        # Log in to Pjuu so that we can make sure we can not get back to signup
        resp = self.client.post(url_for('auth.signin'),
                                data={
                                    'username': '******',
                                    'password': '******'
                                },
                                follow_redirects=True)
        self.assertEqual(resp.status_code, 200)
        # We are now logged in lets try and go to signup and ensure we get
        # redirected back to feed
        resp = self.client.get(url_for('auth.signup'))
        self.assertEqual(resp.status_code, 302)
        # Why we are logged in lets ensure we can't get to activate
        resp = self.client.get(url_for('auth.activate', token=token))
        self.assertEqual(resp.status_code, 302)

        # Lets delete the account and then try and reactivate
        delete_account(get_uid_username('user1'))
        resp = self.client.get(url_for('auth.activate', token=token),
                               follow_redirects=True)
        self.assertEqual(resp.status_code, 200)
        self.assertIn('Invalid token', resp.data)
Example #19
0
    def test_search(self):
        """Ensure the search works and users are shown correctly."""
        # Let's try and access the endpoint feature when we are not logged in
        # We should not be able to see it
        resp = self.client.get(url_for('users.search'), follow_redirects=True)
        self.assertIn('You need to be logged in to view that', resp.data)

        # We need some users with usernames different enough that we can test
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')
        user3 = create_account('joe', '*****@*****.**', 'Password')
        user4 = create_account('ant', '*****@*****.**', 'Password')
        user5 = create_account('fil', '*****@*****.**', 'Password')
        # Activate some of the accounts.
        activate(user1)
        activate(user2)
        activate(user3)
        activate(user4)

        # Let's sign in!
        # We will sign in as joe this time as that is me :)
        self.client.post('signin',
                         data={
                             'username': '******',
                             'password': '******'
                         })

        # Let's check we see the correct thing on the search page when there
        # is no search
        resp = self.client.get(url_for('users.search'))
        self.assertIn('<!-- author search -->', resp.data)
        self.assertNotIn('<h1>Results:', resp.data)

        # Lets search for ourselves
        resp = self.client.get(url_for('users.search', query='joe'))
        self.assertIn('<!-- list:user:%s -->' % user3, resp.data)

        # Lets check that this is case-insensitive
        resp = self.client.get(url_for('users.search', query='JOE'))
        self.assertIn('<!-- list:user:%s -->' % user3, resp.data)

        # Lets try this partially
        resp = self.client.get(url_for('users.search', query='j'))
        self.assertIn('<!-- list:user:%s -->' % user3, resp.data)

        # Lets check we see two users if two match
        resp = self.client.get(url_for('users.search', query='user'))
        self.assertIn('<!-- list:user:%s -->' % user1, resp.data)
        self.assertIn('<!-- list:user:%s -->' % user2, resp.data)

        # Lets check to see if inactive users show up. THEY SHOULD
        resp = self.client.get(url_for('users.search', query='fil'))
        self.assertNotIn('<!-- list:user:%s -->' % user5, resp.data)

        # Lets check that we can find ant because we are going to delete him
        # to ensure he goes! This has caused issues on the live site
        resp = self.client.get(url_for('users.search', query='ant'))
        self.assertIn('<!-- list:user:%s -->' % user4, resp.data)

        # Lets check that we can find ant because we are going to delete him
        # to ensure he goes! This has caused issues on the live site
        resp = self.client.get(url_for('users.search', query='ant'))
        self.assertIn('<!-- list:user:%s -->' % user4, resp.data)

        # We will just backend delete the account.
        delete_account(user4)
        # Account is gone, lets ensure this has gone
        resp = self.client.get(url_for('users.search', query='ant'))
        self.assertNotIn('<!-- list:user:%s -->' % user4, resp.data)
Example #20
0
    def test_avatars(self):
        """Can a user set there own avatar?"""
        # Create a test user
        user1 = create_account('user1', '*****@*****.**', 'Password')
        # Activate it
        activate(user1)

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

        # Check default avatar is present
        resp = self.client.get(
            url_for('users.settings_profile', username='******'))
        self.assertIn('<!-- user:avatar:default -->', resp.data)
        self.assertIn(url_for('static', filename='img/otter_avatar.png'),
                      resp.data)

        # Check the avatar for the default
        # We can't inspect it
        user = get_user(user1)
        resp = self.client.get(
            url_for('static', filename='img/otter_avatar.png'))
        self.assertEqual(resp.status_code, 200)

        # Get the users object to check some things
        user = get_user(user1)

        # User shouldn't have an avatar
        self.assertIsNone(user.get('avatar'))

        # Create the file
        image = io.BytesIO(open('tests/upload_test_files/otter.jpg').read())

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

        user = get_user(user1)

        self.assertIsNotNone(user.get('avatar'))
        self.assertIn('<!-- user:avatar:{} -->'.format(user.get('avatar')),
                      resp.data)

        grid = gridfs.GridFS(m.db, collection='uploads')
        self.assertEqual(
            grid.find({
                'filename': user.get('avatar')
            }).count(), 1)

        resp = self.client.get(
            url_for('posts.get_upload', filename=user.get('avatar')))
        self.assertEqual(resp.status_code, 200)

        # upload another and ensure there is only one in GridFs
        image = io.BytesIO(open('tests/upload_test_files/otter.jpg').read())

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

        user = get_user(user1)
        self.assertEqual(
            grid.find({
                'filename': user.get('avatar')
            }).count(), 1)

        # This is technically an auth test but if we delete the account we can
        # ensure the avatar is removed.
        delete_account(user1)
        self.assertEqual(
            grid.find({
                'filename': user.get('avatar')
            }).count(), 0)