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))
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))
def test_followers_and_unfollowers_pagination_sizes(self): """Ensure that the followers and unfollowers feeds are correct if changing the feed size. """ users = [] # Creae 101 users (0 - 100) for i in xrange(101): users.append(create_account('user{}'.format(i), 'user{}@pjuu.com'.format(i), 'Password')) # Make user0 follow all users and visa versa for i in xrange(1, 101): follow_user(users[0], users[i]) follow_user(users[i], users[0]) FEED_ITEMS_PER_PAGE = app.config.get('FEED_ITEMS_PER_PAGE') # Check that the correct amount of users come back for follower and # following self.assertEqual(len(get_followers(users[0]).items), FEED_ITEMS_PER_PAGE) self.assertEqual(len(get_followers(users[0], per_page=25).items), 25) self.assertEqual(len(get_followers(users[0], per_page=50).items), 50) self.assertEqual(len(get_followers(users[0], per_page=100).items), 100) self.assertEqual(len(get_following(users[0]).items), FEED_ITEMS_PER_PAGE) self.assertEqual(len(get_following(users[0], per_page=25).items), 25) self.assertEqual(len(get_following(users[0], per_page=50).items), 50) self.assertEqual(len(get_following(users[0], per_page=100).items), 100)
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)
def test_delete_account_followers_following(self): """ Test delete_account() Followers & Following: Ensures that all data related to followers is removed during account deletion Note: This is not a full test of the users system. See users/test.py """ # Create test users user1 = create_user('user1', '*****@*****.**', 'Password') user2 = create_user('user2', '*****@*****.**', 'Password') # Make users follow each other self.assertTrue(follow_user(user1, user2)) self.assertTrue(follow_user(user2, user1)) # Ensure the uid's are in the relevant sorted sets 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 test account 1 delete_account(user1) # Ensure the lists are empty 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))
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)
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)
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)
def test_alerts_pagination_sizes(self): """Check that the correct number of alerts are generated""" # Create 2 test users user1 = create_account('user1', '*****@*****.**', 'Password') user2 = create_account('user2', '*****@*****.**', 'Password') # Generate lots of following alerts for i in xrange(101): follow_user(user2, user1) unfollow_user(user2, user1) ALERT_ITEMS_PER_PAGE = app.config.get('ALERT_ITEMS_PER_PAGE') self.assertEqual(len(get_alerts(user1).items), ALERT_ITEMS_PER_PAGE) self.assertEqual(len(get_alerts(user1, per_page=25).items), 25) self.assertEqual(len(get_alerts(user1, per_page=50).items), 50) self.assertEqual(len(get_alerts(user1, per_page=100).items), 100)
def follow(username): """Follow a user.""" redirect_url = handle_next(request, url_for('users.following', username=current_user.get('username'))) user_id = get_uid(username) # If we don't get a uid from the username the page doesn't exist if user_id is None: abort(404) # Unfollow user, ensure the user doesn't unfollow themself if user_id != current_user.get('_id'): if follow_user(current_user.get('_id'), user_id): flash('You have started following %s' % username, 'success') else: flash('You can\'t follow/unfollow yourself', 'information') return redirect(redirect_url)
def follow(username): """Follow a user.""" redirect_url = handle_next( request, url_for('users.following', username=current_user.get('username'))) user_id = get_uid(username) # If we don't get a uid from the username the page doesn't exist if user_id is None: abort(404) # Unfollow user, ensure the user doesn't unfollow themself if user_id != current_user.get('_id'): if follow_user(current_user.get('_id'), user_id): flash('You have started following %s' % username, 'success') else: flash('You can\'t follow/unfollow yourself', 'information') return redirect(redirect_url)
def test_approved_unapproved_is_approved(self): """Ensure a user can approve and unapprove a follower. Also test the checking of this state""" user1 = create_account('user1', '*****@*****.**', 'Password') user2 = create_account('user2', '*****@*****.**', 'Password') user3 = create_account('user3', '*****@*****.**', 'Password') # User should not be following a user self.assertFalse(is_approved(user1, user2)) # User can't approve a user he is not following self.assertFalse(approve_user(user1, user2)) # Follow wrong way round. The user to be approved must follow you follow_user(user1, user2) self.assertFalse(approve_user(user1, user2)) self.assertFalse(is_approved(user1, user2)) # Correct way round follow_user(user2, user1) self.assertTrue(approve_user(user1, user2)) self.assertTrue(is_approved(user1, user2)) # Try an un-approved a non follower self.assertFalse(is_approved(user1, user3)) self.assertFalse(unapprove_user(user1, user3)) # Try and un-approve a non approved follower follow_user(user3, user1) self.assertFalse(is_approved(user1, user3)) self.assertFalse(unapprove_user(user1, user3)) # Un-approve an approved folloer self.assertTrue(is_approved(user1, user2)) self.assertTrue(unapprove_user(user1, user2)) self.assertFalse(is_approved(user1, user2)) # Ensure a user is un-approved if they stop following you # and you had approved them self.assertTrue(approve_user(user1, user2)) self.assertTrue(is_approved(user1, user2)) unfollow_user(user2, user1) self.assertFalse(is_approved(user1, user2))
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)
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)
def test_approve_unapprove(self): """Ensure the user can approve and un-approve users""" user1 = create_account('user1', '*****@*****.**', 'Password') user2 = create_account('user2', '*****@*****.**', 'Password') user3 = create_account('user3', '*****@*****.**', 'Password') activate(user1) activate(user2) activate(user3) # User 2 is the only user following user1 follow_user(user2, user1) resp = self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }) resp = self.client.get(url_for('users.followers', username='******'), follow_redirects=True) self.assertIn('<!-- list:user:%s -->' % user2, resp.data) self.assertIn(url_for('users.approve', username='******'), resp.data) # Approve user2 resp = self.client.post(url_for('users.approve', username='******'), follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn(url_for('users.unapprove', username='******'), resp.data) # Unapprove user2 resp = self.client.post(url_for('users.unapprove', username='******'), follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn(url_for('users.approve', username='******'), resp.data) # Try to unapprove user2 again resp = self.client.post(url_for('users.unapprove', username='******'), follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('You can\'t untrust a user who is not trusted', resp.data) # Try and approve a user who is not following you resp = self.client.post(url_for('users.approve', username='******'), follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('You can\'t trust a user who is not following you', resp.data) # Try again but you are following the user (wont-work) follow_user(user1, user3) resp = self.client.post(url_for('users.approve', username='******'), follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('You can\'t trust a user who is not following you', resp.data) # Try and approve yourself resp = self.client.post(url_for('users.approve', username='******'), follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('You should already trust yourself ;-P', resp.data) # Try and unapprove self resp = self.client.post(url_for('users.unapprove', username='******'), follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('You can\'t untrust your self', resp.data) # Try and approve/unapprove a user that doesn't exist resp = self.client.post(url_for('users.approve', username='******'), follow_redirects=True) self.assertEqual(resp.status_code, 404) resp = self.client.post(url_for('users.unapprove', username='******'), follow_redirects=True) self.assertEqual(resp.status_code, 404)
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)
def test_alerts(self): """Check that alerts are displayed properly in the frontend.""" # Create two test users user1 = create_account('user1', '*****@*****.**', 'Password') user2 = create_account('user2', '*****@*****.**', 'Password') user3 = create_account('user3', '*****@*****.**', 'Password') # Activate activate(user1) activate(user2) activate(user3) # Try an visit i-has-alerts when not logged in resp = self.client.get(url_for('users.new_alerts')) self.assertEqual(resp.status_code, 403) # Login as user1 self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }) # Get I has alerts and check that it is false resp = self.client.get(url_for('users.new_alerts')) # Check the JSON response self.assertEqual(resp.status_code, 200) self.assertEqual(json.loads(resp.data).get('new_alerts'), 0) # Ensure that /alerts returns nothing resp = self.client.get(url_for('users.alerts')) self.assertNotIn('list:alert', resp.data) self.assertIn('Empty', resp.data) # Get user2 to follow user1 follow_user(user2, user1) # Ensure that /i-has-alerts is correct resp = self.client.get(url_for('users.new_alerts')) # Check the JSON response self.assertEqual(resp.status_code, 200) self.assertEqual(json.loads(resp.data).get('new_alerts'), 1) # Ensure the count goes up correctly follow_user(user3, user1) resp = self.client.get(url_for('users.new_alerts')) # Check the JSON response self.assertEqual(resp.status_code, 200) self.assertEqual(json.loads(resp.data).get('new_alerts'), 2) resp = self.client.get(url_for('users.alerts')) # We don't know the alert ID but we can check that one is there by # looking for the comment in test mode self.assertIn('list:alert:', resp.data) self.assertNotIn('Empty', resp.data) # Check test2's name is there self.assertIn('user2', resp.data) # Check that the prettify message from FollowAlert is there self.assertIn('has started following you', resp.data) # We have now checked the alerts, ensure that i-has-alerts is False resp = self.client.get(url_for('users.new_alerts')) # Check the JSON response self.assertEqual(resp.status_code, 200) self.assertEqual(json.loads(resp.data).get('new_alerts'), 0) # Check that we can delete the alert # Get the both alert ids from the backend function alert1 = get_alerts(user1).items[0].alert_id alert2 = get_alerts(user1).items[1].alert_id # Check that we don't get a message if there was no alert to delete resp = self.client.get(url_for('users.delete_alert', alert_id=k.NIL_VALUE), follow_redirects=True) self.assertNotIn('Alert has been hidden', resp.data) # Delete both alerts resp = self.client.get(url_for('users.delete_alert', alert_id=alert1), follow_redirects=True) self.assertIn('Alert has been hidden', resp.data) self.assertNotIn('<!-- list:alert:{} -->'.format(alert1), resp.data) self.assertIn('<!-- list:alert:{} -->'.format(alert2), resp.data) # Check when the last alert is deleted we get an empty list resp = self.client.get(url_for('users.delete_alert', alert_id=alert2), follow_redirects=True) self.assertIn('Alert has been hidden', resp.data) # Check that there are also no alerts now self.assertIn('Empty', resp.data)
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)
def test_post(self): """ Test that we can post too Pjuu. """ # Lets ensure we can't GET the /post endpoint # You should not be able to GET this resouce but you will not see this # until you are signed in. This should simply redirect us to login resp = self.client.get(url_for('post')) self.assertEqual(resp.status_code, 302) # Lets ensure we can't POST to /post when logged out # As above we should simply be redirected resp = self.client.post(url_for('post'), data={ 'body': 'Test post' }) self.assertEqual(resp.status_code, 302) # Let's create a user an login user1 = create_user('user1', '*****@*****.**', 'Password') # Activate the account self.assertTrue(activate(user1)) # Log the user in resp = self.client.post(url_for('signin'), data={ 'username': '******', 'password': '******' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) # We are now logged in :) Let's ensure we can't GET the /post endpoint resp = self.client.get(url_for('post')) self.assertEqual(resp.status_code, 405) # Lets post a test post # Because we are not passing a next query param we will be redirected # to /test (users profile) after this post resp = self.client.post(url_for('post'), data={ 'body': 'Test post' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) # Let's ensure our new post appears in the output self.assertIn('Test post', resp.data) # We should be on the posts view as we did not pass a next qs self.assertIn('<!-- author post -->', resp.data) # Let's post again but this time lets redirect ourselves back to feed. # We will ensure both posts exist in the feed resp = self.client.post(url_for('post', next=url_for('feed')), data={ 'body': 'Second test post' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) # Let's ensure both posts are their self.assertIn('Test post', resp.data) self.assertIn('Second test post', resp.data) # The post endpoint also handles populating followers feeds. We will # create a couple of users (in the backend, we will not test the # frontend here). user2 = create_user('user2', '*****@*****.**', 'Password') activate(user2) follow_user(user2, user1) user3 = create_user('user3', '*****@*****.**', 'Password') activate(user3) follow_user(user3, user1) # Create a post as user 1, we will then log out and ensure these posts # appear in the other users lists resp = self.client.post(url_for('post', next=url_for('feed')), data={ 'body': 'Hello followers' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) # Let's ensure all posts are their self.assertIn('Test post', resp.data) self.assertIn('Second test post', resp.data) self.assertIn('Hello followers', resp.data) # Let's ensure the post form is their self.assertIn('<!-- author post -->', resp.data) # We are using the test client so lets log out properly self.client.get(url_for('signout')) # Log in as test2 and ensure the post is in their feed resp = self.client.post(url_for('signin'), data={ 'username': '******', 'password': '******' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('Hello followers', resp.data) # Log out self.client.get(url_for('signout')) # Log in as test3 and ensure the post in their feed resp = self.client.post(url_for('signin'), data={ 'username': '******', 'password': '******' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('Hello followers', resp.data) # Log out self.client.get(url_for('signout')) # Sign back in as user1 so that we can keep testing resp = self.client.post(url_for('signin'), data={ 'username': '******', 'password': '******' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) # Back to testing. Let's ensure that users can post unicode text # I copied this Chinese text from a header file on my Mac. I do not # know what it means, I just need the characters resp = self.client.post(url_for('post', next=url_for('feed')), data={ 'body': '光铸钥匙' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) # Let's ensure all posts are their self.assertIn('Test post', resp.data) self.assertIn('Second test post', resp.data) self.assertIn('Hello followers', resp.data) self.assertIn('光铸钥匙', resp.data) # Check that a muted user can not create a post # Mute out user mute(user1) resp = self.client.post(url_for('post', next=url_for('feed')), data={ 'body': 'Muting test' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) # Let's ensure the warning is there self.assertIn('You have been silenced!', resp.data) self.assertNotIn('Muting test', resp.data) # Un-mute the user and try and post the same thing self.assertTrue(mute(user1, False)) resp = self.client.post(url_for('post', next=url_for('feed')), data={ 'body': 'Muting test' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) # Let's ensure the warning is there self.assertNotIn('You have been silenced!', resp.data) self.assertIn('Muting test', resp.data) # Try and post to many characters resp = self.client.post(url_for('post', next=url_for('feed')), data={ 'body': ('testtesttesttesttesttesttesttesttesttesttesttesttesttest' 'testtesttesttesttesttesttesttesttesttesttesttesttesttest' 'testtesttesttesttesttesttesttesttesttesttesttesttesttest' 'testtesttesttesttesttesttesttesttesttesttesttesttesttest' 'testtesttesttesttesttesttesttesttesttesttesttesttesttest' 'testtesttesttesttest') }, follow_redirects=True) self.assertIn('Posts can not be larger than 255 characters', resp.data)
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)
def test_post(self): """ Test that we can post too Pjuu. """ # Lets ensure we can't GET the /post endpoint # You should not be able to GET this resouce but you will not see this # until you are signed in. This should simply redirect us to login resp = self.client.get(url_for('posts.post')) self.assertEqual(resp.status_code, 302) # Lets ensure we can't POST to /post when logged out # As above we should simply be redirected resp = self.client.post(url_for('posts.post'), data={ 'body': 'Test post' }) self.assertEqual(resp.status_code, 302) # Let's create a user an login user1 = create_account('user1', '*****@*****.**', 'Password') # Activate the account self.assertTrue(activate(user1)) # Log the user in 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 :) Let's ensure we can't GET the /post endpoint resp = self.client.get(url_for('posts.post')) self.assertEqual(resp.status_code, 405) # Lets post a test post # Because we are not passing a next query param we will be redirected # to /test (users profile) after this post resp = self.client.post(url_for('posts.post'), data={ 'body': 'Test post' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) # Let's ensure our new post appears in the output self.assertIn('Test post', resp.data) # We should be on the posts view as we did not pass a next qs self.assertIn('<!-- author post -->', resp.data) # Let's post again but this time lets redirect ourselves back to feed. # We will ensure both posts exist in the feed resp = self.client.post(url_for('posts.post', next=url_for('users.feed')), data={ 'body': 'Second test post' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) # Let's ensure both posts are their self.assertIn('Test post', resp.data) self.assertIn('Second test post', resp.data) # The post endpoint also handles populating followers feeds. We will # create a couple of users (in the backend, we will not test the # frontend here). user2 = create_account('user2', '*****@*****.**', 'Password') activate(user2) follow_user(user2, user1) user3 = create_account('user3', '*****@*****.**', 'Password') activate(user3) follow_user(user3, user1) # Create a post as user 1, we will then log out and ensure these posts # appear in the other users lists resp = self.client.post(url_for('posts.post', next=url_for('users.feed')), data={ 'body': 'Hello followers' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) # Let's ensure all posts are their self.assertIn('Test post', resp.data) self.assertIn('Second test post', resp.data) self.assertIn('Hello followers', resp.data) # Let's ensure the post form is their self.assertIn('<!-- author post -->', resp.data) # We are using the test client so lets log out properly self.client.get(url_for('auth.signout')) # Log in as test2 and ensure the post is in their feed resp = self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('Hello followers', resp.data) # Log out self.client.get(url_for('auth.signout')) # Log in as test3 and ensure the post in their feed resp = self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('Hello followers', resp.data) # Log out self.client.get(url_for('auth.signout')) # Sign back in as user1 so that we can keep testing resp = self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) # Back to testing. Let's ensure that users can post unicode text # I copied this Chinese text from a header file on my Mac. I do not # know what it means, I just need the characters resp = self.client.post(url_for('posts.post', next=url_for('users.feed')), data={ 'body': '光铸钥匙' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) # Let's ensure all posts are their self.assertIn('Test post', resp.data) self.assertIn('Second test post', resp.data) self.assertIn('Hello followers', resp.data) self.assertIn('光铸钥匙', resp.data) # Check that a muted user can not create a post # Mute out user mute(user1) resp = self.client.post(url_for('posts.post', next=url_for('users.feed')), data={ 'body': 'Muting test' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) # Let's ensure the warning is there self.assertIn('You have been silenced!', resp.data) self.assertNotIn('Muting test', resp.data) # Un-mute the user and try and post the same thing self.assertTrue(mute(user1, False)) resp = self.client.post(url_for('posts.post', next=url_for('users.feed')), data={ 'body': 'Muting test' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) # Let's ensure the warning is there self.assertNotIn('You have been silenced!', resp.data) self.assertIn('Muting test', resp.data) # Try and post to many characters resp = self.client.post(url_for('posts.post', next=url_for('users.feed')), data={ 'body': ('P' * (MAX_POST_LENGTH + 1)) }, follow_redirects=True) self.assertIn('Posts can not be larger than ' '{0} characters'.format(MAX_POST_LENGTH), resp.data) # Test that we can post 500 unicode characters resp = self.client.post(url_for('posts.post', next=url_for('users.feed')), data={ 'body': ('光' * (MAX_POST_LENGTH)) }, follow_redirects=True) self.assertNotIn('Posts can not be larger than ' '{0} characters'.format(MAX_POST_LENGTH), resp.data) # Test that we can not post more than MAX_POST_LENGTH unicode # characters resp = self.client.post(url_for('posts.post', next=url_for('users.feed')), data={ 'body': ('光' * (MAX_POST_LENGTH + 1)) }, follow_redirects=True) self.assertIn('Posts can not be larger than ' '{0} characters'.format(MAX_POST_LENGTH), resp.data) # Ensure that posting an image with no text still doesn't allow it image = io.BytesIO(open('tests/upload_test_files/otter.jpg').read()) resp = self.client.post( url_for('posts.post'), data={ 'body': '', 'upload': (image, 'otter.jpg') }, follow_redirects=True ) self.assertEqual(resp.status_code, 200) self.assertIn('A message is required.', resp.data) # Test posting with an image image = io.BytesIO(open('tests/upload_test_files/otter.jpg').read()) resp = self.client.post( url_for('posts.post'), data={ 'body': 'Test upload', 'upload': (image, 'otter.jpg') }, follow_redirects=True ) self.assertEqual(resp.status_code, 200) # Goto the users feed an ensure the post is there resp = self.client.get(url_for('users.feed')) self.assertEqual(resp.status_code, 200) # So that we can check the data is in the templates, upload a post # in the backend and ensure it appears where it should image = io.BytesIO(open('tests/upload_test_files/otter.png').read()) post1 = create_post(user1, 'user1', 'Test post', upload=image) self.assertIsNotNone(post1) post = get_post(post1) resp = self.client.get(url_for('users.feed')) self.assertIn('<!-- upload:post:%s -->' % post1, resp.data) self.assertIn('<img src="%s"/>' % url_for('posts.get_upload', filename=post.get('upload')), resp.data) # Although the below belongs in `test_view_post` we are just going to # check it here for simplicity resp = self.client.get(url_for('posts.view_post', username='******', post_id=post1)) self.assertIn('<!-- upload:post:%s -->' % post1, resp.data) self.assertIn('<img src="%s"/>' % url_for('posts.get_upload', filename=post.get('upload')), resp.data)
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)