def test_avatars_hashtag_search(self): """Ensure user avatars appear when searching for posts with a hashtag """ user1 = create_account('user1', '*****@*****.**', 'Password') # Activate it activate(user1) # Signin self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }) # Ensure user avatar appear in the search when searching for hashtags image = io.BytesIO(open('tests/upload_test_files/otter.jpg').read()) self.client.post(url_for('users.settings_profile'), data={'upload': (image, 'otter.png')}, follow_redirects=True) # Get the user so we can see if the avatar is appearing user = get_user(user1) # Create a post to search for post1 = create_post(user1, 'user1', 'Hello #pjuuie\'s') resp = self.client.get(url_for('users.search', query='#pjuuie')) self.assertIn('<!-- list:post:%s -->' % post1, resp.data) self.assertIn(url_for('posts.get_upload', filename=user.get('avatar')), resp.data)
def test_session_fixation(self): """Ensure if session is empty that a new session is given.""" user1 = create_account('user1', '*****@*****.**', 'Password') activate(user1) resp = self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }) session_id = None for header in resp.headers: if header[0] == 'Set-Cookie': session_id = parse_cookie(header[1])['session'] rs.delete(session_id) resp = self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }) # Find the Set-Cookie header so we can parse it and check the session # identifier has been updated for header in resp.headers: if header[0] == 'Set-Cookie': self.assertNotEqual(session_id, parse_cookie(header[1])['session'])
def test_avatars_hashtag_search(self): """Ensure user avatars appear when searching for posts with a hashtag """ user1 = create_account('user1', '*****@*****.**', 'Password') # Activate it activate(user1) # Signin self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }) # Ensure user avatar appear in the search when searching for hashtags image = io.BytesIO(open('tests/upload_test_files/otter.jpg').read()) self.client.post(url_for('users.settings_profile'), data={ 'upload': (image, 'otter.png') }, follow_redirects=True) # Get the user so we can see if the avatar is appearing user = get_user(user1) # Create a post to search for post1 = create_post(user1, 'user1', 'Hello #pjuuie\'s') resp = self.client.get(url_for('users.search', query='#pjuuie')) self.assertIn('<!-- list:post:%s -->' % post1, resp.data) self.assertIn(url_for('posts.get_upload', filename=user.get('avatar')), resp.data)
def test_get_upload(self): """Tests the simple wrapper around ``lib.uploads.get_upload`` """ user1 = create_account('user1', '*****@*****.**', 'Password') activate(user1) # Create the post with an upload to get image = io.BytesIO(open('tests/upload_test_files/otter.jpg').read()) post1 = create_post(user1, 'user1', 'Test post', upload=image) self.assertIsNotNone(post1) post = get_post(post1) # Try and get the post and ensure we are redirected because we are not # logged in resp = self.client.get(url_for('posts.get_upload', filename=post.get('upload'))) self.assertEqual(resp.status_code, 302) # Log in as user1 and get the upload resp = self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) resp = self.client.get(url_for('posts.get_upload', filename=post.get('upload'))) self.assertEqual(resp.status_code, 200) self.assertEqual(resp.headers['Content-Type'], 'image/png')
def test_surrounding_characters(self): """Can parse objects be in parenthesis""" user1 = create_account('user1', '*****@*****.**', 'Password1') activate(user1) links, mentions, hashtags = parse_post('(@user1), (pjuu.com), (#hash)') self.assertEqual(links[0]['link'], 'http://pjuu.com') self.assertEqual(mentions[0]['username'], 'user1') self.assertEqual(hashtags[0]['hashtag'], 'hash')
def test_unicode_character(self): """Do unicode characters break things.""" user1 = create_account('user1', '*****@*****.**', 'Password1') activate(user1) links, mentions, hashtags = parse_post('၍ @user1, ☂pjuu.com, 㒅 #hash') self.assertEqual(links[0]['link'], 'http://pjuu.com') self.assertEqual(mentions[0]['username'], 'user1') self.assertEqual(hashtags[0]['hashtag'], 'hash')
def test_mention_real_user(self): """Find a user mentions (user does exist)""" user1 = create_account('user1', '*****@*****.**', 'Password1') activate(user1) mentions = parse_mentions('@user1 @user2') self.assertEqual(len(mentions), 1) self.assertEqual(mentions[0]['username'], 'user1') self.assertEqual(mentions[0]['user_id'], user1) self.assertEqual(mentions[0]['span'], (0, 6))
def test_userflags(self): """Ensure user flags are set as expected. """ user1 = create_account('user1', '*****@*****.**', 'Password') self.assertIsNotNone(user1) # Not active by default self.assertFalse(get_user(user1).get('active')) # TTL should be set self.assertIsNotNone(get_user(user1).get('ttl')) # Activate self.assertTrue(activate(user1)) self.assertTrue(get_user(user1).get('active')) self.assertIsNone(get_user(user1).get('ttl')) # Deactivate self.assertTrue(activate(user1, False)) self.assertFalse(get_user(user1).get('active')) # Invalid self.assertFalse(activate(None)) self.assertFalse(activate(K.NIL_VALUE)) # Banning, not by default self.assertFalse(get_user(user1).get('banned')) # Ban self.assertTrue(ban(user1)) self.assertTrue(get_user(user1).get('banned')) # Un-ban self.assertTrue(ban(user1, False)) self.assertFalse(get_user(user1).get('banned')) # Invalid self.assertFalse(ban(None)) self.assertFalse(ban(K.NIL_VALUE)) # OP (Over powered or Operator?) Account should not be op self.assertFalse(get_user(user1).get('op')) # Bite self.assertTrue(bite(user1)) self.assertTrue(get_user(user1).get('op')) # Un-bite self.assertTrue(bite(user1, False)) self.assertFalse(get_user(user1).get('op')) # Invalid self.assertFalse(bite(None)) self.assertFalse(bite(K.NIL_VALUE)) # Muted, can't post, not by default self.assertFalse(get_user(user1).get('muted')) # Mute self.assertTrue(mute(user1)) self.assertTrue(get_user(user1).get('muted')) # Un-mute self.assertTrue(mute(user1, False)) self.assertFalse(get_user(user1).get('muted')) # Invalid self.assertFalse(mute(None)) self.assertFalse(mute(K.NIL_VALUE))
def test_delimited(self): """Ensure hashtags can be delimited""" hashtags = parse_hashtags('#pjuu\'s test') self.assertEqual(hashtags[0]['hashtag'], 'pjuu') user1 = create_account('user1', '*****@*****.**', 'Password1') activate(user1) mentions = parse_mentions('@user1\'s') self.assertEqual(mentions[0]['username'], 'user1') self.assertEqual(mentions[0]['user_id'], user1)
def test_flag_control(self): """Ensure flagged posts appear in the dashboard""" user1 = create_account('user1', '*****@*****.**', 'Password') user2 = create_account('user2', '*****@*****.**', 'Password') # Make user1 OP bite(user1) activate(user1) post1 = create_post(user2, 'user2', 'post1') post2 = create_post(user2, 'user2', 'post2') comment1 = create_post(user2, 'user2', 'comment1', post1) comment2 = create_post(user2, 'user2', 'comment2', post1) # Flag all the posts flag_post(user1, post1) flag_post(user1, post2) flag_post(user1, comment1) flag_post(user1, comment2) self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }) resp = self.client.get(url_for('dashboard.dashboard')) s = '{0} - <a href="{1}">{2}</a>: <a href="{3}">{4}</a> ' + \ '[<a href="{5}">Unflag</a>]' self.assertIn(s.format( 1, url_for('users.profile', username='******'), 'user2', url_for('posts.view_post', username='******', post_id=post1), post1, url_for('posts.unflag_post', post_id=post1) ), resp.data) self.assertIn(s.format( 1, url_for('users.profile', username='******'), 'user2', url_for('posts.view_post', username='******', post_id=post1), comment1, url_for('posts.unflag_post', post_id=comment1) ) + ' (comment)', resp.data)
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_xhr_decorators(self): """Ensure we get a 403 if we XHR request something we need to logged in for. """ user1 = create_account("user1", "*****@*****.**", "Password") post1 = create_post(user1, "user1", "Test") activate(user1) resp = self.client.post( url_for("posts.upvote", username="******", post_id=post1), headers=[("X-Requested-With", "XMLHttpRequest")] ) self.assertEqual(resp.status_code, 403)
def test_postify(self): """Test that postify renders posts correctly when the correct informations is attached. .. note: This is not intended to test the parsing but simply that what is parsed is rendered correctly. """ # We need a user to post as. user1 = create_account('user1', '*****@*****.**', 'Password') activate(user1) self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }) # Create a post with a user that does not exist there should be no # rendering involved resp = self.client.post(url_for('posts.post'), data={ 'body': 'Hello @joe' }, follow_redirects=True) self.assertIn('Hello @joe', resp.data) # Create another user and then tag them user2 = create_account('user2', '*****@*****.**', 'Password') activate(user2) resp = self.client.post(url_for('posts.post'), data={ 'body': 'Hello @user2' }, follow_redirects=True) self.assertIn('Hello <a href="{0}">@user2</a>'.format( url_for('users.profile', username='******')), resp.data) # Check a link resp = self.client.post(url_for('posts.post'), data={ 'body': 'Visit https://pjuu.com' }, follow_redirects=True) self.assertIn('Visit <a href="https://pjuu.com" target="_blank">' 'https://pjuu.com</a>', resp.data) # Test a hashtag resp = self.client.post(url_for('posts.post'), data={ 'body': 'Wow #hashtag' }, follow_redirects=True) self.assertIn('Wow <a href="{0}">#hashtag</a>'.format( url_for('posts.hashtags', hashtag='hashtag')), resp.data)
def test_logged_in(self): """Check the pages work when logged in """ # 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) # About resp = self.client.get(url_for('pages.about')) self.assertEqual(resp.status_code, 200) self.assertIn('<!-- menu: logged in -->', resp.data) self.assertIn('<h1>About Us</h1>', resp.data) # Terms resp = self.client.get(url_for('pages.terms')) self.assertEqual(resp.status_code, 200) self.assertIn('<!-- menu: logged in -->', resp.data) self.assertIn('<h1>Terms of Service</h1>', resp.data) # Privacy resp = self.client.get(url_for('pages.privacy')) self.assertEqual(resp.status_code, 200) self.assertIn('<!-- menu: logged in -->', resp.data) self.assertIn('<h1>Privacy</h1>', resp.data)
def test_dashboard_view(self): """Ensure basic stats show in dashboard""" user1 = create_account('user1', '*****@*****.**', 'Password') activate(user1) # Ensure we can't hit the endpoint not logged in # We WONT be redirected to login resp = self.client.get(url_for('dashboard.dashboard')) self.assertEqual(resp.status_code, 403) # Log in self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }) # Ensure we can't hit the endpoint if we are logged in but not op resp = self.client.get(url_for('dashboard.dashboard')) self.assertEqual(resp.status_code, 403) # Make the user OP bite(user1) # Check resp = self.client.get(url_for('dashboard.dashboard')) self.assertEqual(resp.status_code, 200) # Ensure there are some stats for the different libraries we expect # 'Server' is provided by the dashboard itself self.assertIn('Server', resp.data) # We can further check the 'Server' section as we need to anyway. self.assertIn('Hostname', resp.data) self.assertIn('Uname', resp.data) self.assertIn('Time UTC', resp.data) self.assertIn('Timestamp', resp.data) # Check the values we can self.assertIn(' '.join(os.uname()), resp.data) self.assertIn(socket.gethostname(), resp.data) # 'Auth' is provided by pjuu.auth self.assertIn('Auth', resp.data) # 'Posts' is provided by pjuu.posts self.assertIn('Posts', resp.data)
def test_hashtags(self): """Ensure the hashtags endpoint gives acts and gives the posts we expect. .. note: For parsing of these please see `test_posts_backend.py`. """ # Ensure you can't get to the end point when no logged in. resp = self.client.get(url_for('posts.hashtags', hashtag='test'), follow_redirects=True) self.assertIn('You need to be logged in to view that', resp.data) # Sign in user1 = create_account('user1', '*****@*****.**', 'Password') activate(user1) self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }, follow_redirects=True) # Check all conditions which will result in a 404 resp = self.client.get(url_for('posts.hashtags')) self.assertEqual(404, resp.status_code) resp = self.client.get(url_for('posts.hashtags', hashtag='')) self.assertEqual(404, resp.status_code) resp = self.client.get(url_for('posts.hashtags', hashtag='a')) self.assertEqual(404, resp.status_code) # Check what is there at the moment which it will just echo our valid # hashtag back at us resp = self.client.get(url_for('posts.hashtags', hashtag='pjuu')) self.assertEqual(200, resp.status_code) self.assertIn('<h1>Hashtag: pjuu</h1>', resp.data) self.assertIn('Empty', resp.data) # Create a post with a hash tag to ensure we can get it resp = self.client.post( url_for('posts.post', next=url_for('posts.hashtags', hashtag='ace')), data={ 'body': 'This is a new hashtag #ace' }, follow_redirects=True) self.assertIn('<h1>Hashtag: ace</h1>', resp.data) self.assertIn('This is a new hashtag <a href="{0}">#ace</a>'.format( url_for('posts.hashtags', hashtag='ace')), resp.data)
def test_session_fixation(self): """Ensure if session is empty that a new session is given.""" user1 = create_account("user1", "*****@*****.**", "Password") activate(user1) resp = self.client.post(url_for("auth.signin"), data={"username": "******", "password": "******"}) session_id = None for header in resp.headers: if header[0] == "Set-Cookie": session_id = parse_cookie(header[1])["session"] rs.delete(session_id) resp = self.client.post(url_for("auth.signin"), data={"username": "******", "password": "******"}) # Find the Set-Cookie header so we can parse it and check the session # identifier has been updated for header in resp.headers: if header[0] == "Set-Cookie": self.assertNotEqual(session_id, parse_cookie(header[1])["session"])
def test_flag_control(self): """Ensure flagged posts appear in the dashboard""" user1 = create_account('user1', '*****@*****.**', 'Password') user2 = create_account('user2', '*****@*****.**', 'Password') # Make user1 OP bite(user1) activate(user1) post1 = create_post(user2, 'user2', 'post1') post2 = create_post(user2, 'user2', 'post2') comment1 = create_post(user2, 'user2', 'comment1', post1) comment2 = create_post(user2, 'user2', 'comment2', post1) # Flag all the posts flag_post(user1, post1) flag_post(user1, post2) flag_post(user1, comment1) flag_post(user1, comment2) self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }) resp = self.client.get(url_for('dashboard.dashboard')) s = '{0} - <a href="{1}">{2}</a>: <a href="{3}">{4}</a> ' + \ '[<a href="{5}">Unflag</a>]' self.assertIn( s.format( 1, url_for('users.profile', username='******'), 'user2', url_for('posts.view_post', username='******', post_id=post1), post1, url_for('posts.unflag_post', post_id=post1)), resp.data) self.assertIn( s.format( 1, url_for('users.profile', username='******'), 'user2', url_for('posts.view_post', username='******', post_id=post1), comment1, url_for('posts.unflag_post', post_id=comment1)) + ' (comment)', resp.data)
def test_delete_account(self): """ Test deleting an account from the frontend """ # Attempt to get to the delete_account view when not logged in resp = self.client.get(url_for('auth.delete_account'), follow_redirects=True) # We will just ensure we have been redirected to /signin self.assertEqual(resp.status_code, 200) # We should see a message saying we need to signin self.assertIn('You need to be logged in to view that', resp.data) # 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) # Check that we can get to the delete_account page resp = self.client.get(url_for('auth.delete_account')) self.assertEqual(resp.status_code, 200) self.assertIn('This action is irreversible', resp.data) # Attempy to delete account. We are going to do this the other way # round. We will try and do it with an invalid password etc first. resp = self.client.post(url_for('auth.delete_account'), data={'password': '******'}, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('Oops! wrong password', resp.data) # That's all we can do to try and brake this. Let's delete our account resp = self.client.post(url_for('auth.delete_account'), data={'password': '******'}, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('Your account is being deleted', resp.data) # We are now back at signin. Let's check we can't login resp = self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }) self.assertEqual(resp.status_code, 200) self.assertIn('Invalid user name or password', resp.data)
def test_change_email(self): """Can a user change their e-mail? """ user1 = create_account('user1', '*****@*****.**', 'Password') # Test email lookup key self.assertEqual(get_uid_email('*****@*****.**'), None) activate(user1) self.assertEqual(get_uid_email('*****@*****.**'), user1) # Check correct email self.assertEqual(get_user(user1).get('email'), '*****@*****.**') # Change e-mail self.assertIsNotNone(change_email(user1, '*****@*****.**')) # Check new lookup key self.assertEqual(get_uid_email('*****@*****.**'), user1) # Check old lookup key has been nulled self.assertIsNone(get_uid_email('*****@*****.**'))
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), 0) self.assertEqual(search('user1').total, 0) # Users will not appear unless they are active. activate(user1) 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') activate(user2) # 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)
def test_advanced_search(self): """Cover using the `@` and `#` modifiers to limit the search type.""" user1 = create_account('user1', '*****@*****.**', 'Password') user2 = create_account('user2', '*****@*****.**', 'Password') # We have to activate the accounts to appear in the search activate(user1) activate(user2) create_post(user1, 'user1', '#pjuu #user2') create_post(user2, 'user2', '#pjuu #user1') for i in range(1, 101): create_post(user1, 'user1', '#pagination{}'.format(i)) # No user should appear because they are not active! self.assertEqual(search('user').total, 4) self.assertEqual(search('user1').total, 2) self.assertEqual(search('user2').total, 2) # Try come basic search terms self.assertEqual(search('user').total, 4) self.assertEqual(search('user1').total, 2) self.assertEqual(search('user2').total, 2) self.assertEqual(search('pjuu').total, 2) # Users only self.assertEqual(search('@user').total, 2) self.assertEqual(search('@user1').total, 1) # erroneous spacing doesn't matter self.assertEqual(search('@ us').total, 2) # Posts only self.assertEqual(search('#user').total, 2) self.assertEqual(search('#user1').total, 1) self.assertEqual(search('#pjuu').total, 2) # Test pagination in search self.assertEqual(len(search('#pagination', 1, 50).items), 50) self.assertEqual(len(search('#pagination', 2, 50).items), 50)
def test_settings_profile(self): """ Ensure users have the ability to see some information about there account and can change there about message """ # 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('settings_profile', follow_redirects=True) self.assertIn('You need to be logged in to view that', resp.data) # Create a test user user1 = create_account('user1', '*****@*****.**', 'Password') # Activate it activate(user1) # Signin self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }) # Go to our settings page and ensure everything is there resp = self.client.get(url_for('users.settings_profile')) self.assertIn('User Name: <b>user1</b>', resp.data) self.assertIn('E-mail address: <b>[email protected]</b>', resp.data) # Post to the form and update our about. We should also be this on # this page resp = self.client.post(url_for('users.settings_profile'), data={ 'about': 'Otters love fish!' }, follow_redirects=True) self.assertIn('Otters love fish!', resp.data) # Try posting a MASSIVE about ('Otter' * 100) resp = self.client.post(url_for('users.settings_profile'), data={ 'about': 'Otters' * 100 }, follow_redirects=True) # Check we get the form error self.assertIn('Oh no! There are errors in your form', resp.data) # Ensure the about did not change self.assertIn('Otters love fish!', resp.data)
def test_alerts(self): """ Unlike the test_alerts() definition in the users package this just tests that TaggingAlert and CommentingAlert are generated in the right situation """ # Create 3 test users user1 = create_account('user1', '*****@*****.**', 'Password') user2 = create_account('user2', '*****@*****.**', 'Password') user3 = create_account('user3', '*****@*****.**', 'Password') # No need to activate the accounts activate(user1) activate(user2) activate(user3) # User1 tag user2 in a post post1 = create_post(user1, 'user1', 'Hello @user2') # Get alerts for test2 and check that it is correct alert = get_alerts(user2).items[0] self.assertTrue(isinstance(alert, TaggingAlert)) self.assertEqual(alert.user['username'], 'user1') self.assertEqual(alert.user['email'], '*****@*****.**') self.assertIn('tagged you in a', alert.prettify()) # Have user2 comment on a the post and check that user1 has the alert create_post(user2, 'user2', 'Hello', post1) # User 1 should now have a commenting alert from user2 alert = get_alerts(user1).items[0] self.assertTrue(isinstance(alert, CommentingAlert)) self.assertEqual(alert.user['username'], 'user2') self.assertEqual(alert.user['email'], '*****@*****.**') # Please remember that prettify requires a uid to format it to self.assertIn('commented on a', alert.prettify(user1)) self.assertIn('you posted', alert.prettify(user1)) # Create a comment as user3 so they become subscribed create_post(user3, 'user3', 'Hello', post1) # Check that if user1 posts a comment user2 get a tagging alert create_post(user1, 'user1', 'Hello', post1) # Check alerts for user2 alert = get_alerts(user2).items[0] self.assertTrue(isinstance(alert, CommentingAlert)) self.assertIn('you were tagged in', alert.prettify(user2)) # Check alerts for user3 alert = get_alerts(user3).items[0] self.assertTrue(isinstance(alert, CommentingAlert)) self.assertIn('you commented on', alert.prettify(user3)) # To check that an invalid subscription reason returns the generic # reason. This should not happen on the site. # Manually change the score in Redis to a high number r.zincrby(K.POST_SUBSCRIBERS.format(post1), user3, 100) # Check the new prettify message alert = get_alerts(user3).items[0] self.assertTrue(isinstance(alert, CommentingAlert)) self.assertIn('you are subscribed to', alert.prettify(user3))
def test_delete_account(self): """ Test deleting an account from the frontend """ # Attempt to get to the delete_account view when not logged in resp = self.client.get(url_for('auth.delete_account'), follow_redirects=True) # We will just ensure we have been redirected to /signin self.assertEqual(resp.status_code, 200) # We should see a message saying we need to signin self.assertIn('You need to be logged in to view that', resp.data) # 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) # Check that we can get to the delete_account page resp = self.client.get(url_for('auth.delete_account')) self.assertEqual(resp.status_code, 200) self.assertIn('This action is irreversible', resp.data) # Attempy to delete account. We are going to do this the other way # round. We will try and do it with an invalid password etc first. resp = self.client.post(url_for('auth.delete_account'), data={ 'password': '******' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('Oops! wrong password', resp.data) # That's all we can do to try and brake this. Let's delete our account resp = self.client.post(url_for('auth.delete_account'), data={ 'password': '******' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('Your account is being deleted', resp.data) # We are now back at signin. Let's check we can't login resp = self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }) self.assertEqual(resp.status_code, 200) self.assertIn('Invalid user name or password', resp.data)
def test_tip_system(self): """Ensure tips show when they are set to and they can be hidden and reset as needs """ user1 = create_account('user1', '*****@*****.**', 'Password') activate(user1) self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }) # Ensure the tip shows for new users resp = self.client.get(url_for('users.feed')) self.assertIn('tip:welcome', resp.data) self.assertIn(url_for('users.hide_tip', tip_name='welcome'), resp.data) # Ensure we can hide the tip resp = self.client.post(url_for('users.hide_tip', tip_name='welcome'), follow_redirects=True) self.assertNotIn('tip:welcome', resp.data) self.assertNotIn(url_for('users.hide_tip', tip_name='welcome'), resp.data) # Ensure resetting the tips shows them again resp = self.client.post(url_for('users.reset_tips', tip_name='welcome', next=url_for('users.feed')), follow_redirects=True) self.assertIn('tip:welcome', resp.data) self.assertIn(url_for('users.hide_tip', tip_name='welcome'), resp.data) # Try and remove a tip that isn't valid resp = self.client.post(url_for('users.hide_tip', tip_name='cheese'), follow_redirects=True) self.assertEqual(resp.status_code, 404)
def test_dump_account(self): """ Simple check to make sure dump_account works in the views. Will simply check that a JSON response comes back. Don't worry this is pretty much a direct interface to the backend function of the same name. See BackendTestCase for more details. """ # Let's create a user an login user1 = create_account('user1', '*****@*****.**', 'Password') # Activate the account self.assertTrue(activate(user1)) # Attempt to acess the URL without being logged in resp = self.client.get(url_for('auth.dump_account')) self.assertEqual(resp.status_code, 302) # Log the user in resp = self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) # Check that a password confirmation is now required resp = self.client.get(url_for('auth.dump_account')) self.assertEqual(resp.status_code, 200) self.assertIn('This action will dump all of your data', resp.data) # Send password to the view resp = self.client.post(url_for('auth.dump_account'), data={'password': '******'}, follow_redirects=True) self.assertEqual(resp.status_code, 200) json_resp = json.loads(resp.data) self.assertEqual(json_resp['user']['username'], 'user1') # Test inputting the wrong password # Send password to the view resp = self.client.post(url_for('auth.dump_account'), data={'password': '******'}, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('Oops! wrong password', resp.data)
def test_dump_account(self): """ Simple check to make sure dump_account works in the views. Will simply check that a JSON response comes back. Don't worry this is pretty much a direct interface to the backend function of the same name. See BackendTestCase for more details. """ # Let's create a user an login user1 = create_account('user1', '*****@*****.**', 'Password') # Activate the account self.assertTrue(activate(user1)) # Attempt to acess the URL without being logged in resp = self.client.get(url_for('auth.dump_account')) self.assertEqual(resp.status_code, 302) # Log the user in resp = self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) # Check that a password confirmation is now required resp = self.client.get(url_for('auth.dump_account')) self.assertEqual(resp.status_code, 200) self.assertIn('This action will dump all of your data', resp.data) # Send password to the view resp = self.client.post(url_for('auth.dump_account'), data={ 'password': '******' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) json_resp = json.loads(resp.data) self.assertEqual(json_resp['user']['username'], 'user1') # Test inputting the wrong password # Send password to the view resp = self.client.post(url_for('auth.dump_account'), data={ 'password': '******' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('Oops! wrong password', resp.data)
def test_stats(self): """Ensure the ``pjuu.auth.stats``s exposed stats are correct. """ stats = dict(get_stats()) self.assertEqual(stats.get('Total users'), 0) self.assertEqual(stats.get('Total active users'), 0) self.assertEqual(stats.get('Total banned users'), 0) self.assertEqual(stats.get('Total muted users'), 0) self.assertEqual(stats.get('Total OP users'), 0) self.assertEqual(stats.get('Newest users'), []) create_account('user1', '*****@*****.**', 'Password') user2 = create_account('user2', '*****@*****.**', 'Password') activate(user2) user3 = create_account('user3', '*****@*****.**', 'Password') activate(user3) ban(user3) user4 = create_account('user4', '*****@*****.**', 'Password') activate(user4) mute(user4) user5 = create_account('user5', '*****@*****.**', 'Password') bite(user5) # Turn in to dict for easier checking. stats = dict(get_stats()) # URL string to ensure links are being added in to newest users self.assertEqual(stats.get('Total users'), 5) self.assertEqual(stats.get('Total active users'), 3) self.assertEqual(stats.get('Total banned users'), 1) self.assertEqual(stats.get('Total muted users'), 1) self.assertEqual(stats.get('Total OP users'), 1) user_list = ['user5', 'user4', 'user3', 'user2', 'user1'] newest_users = stats.get('Newest users') for i in xrange(len(newest_users)): self.assertIn(user_list[i], newest_users[i])
def test_change_confirm_email(self): """ Test changing your e-mail address from the frontend. This is the last function which uses Tokens. Note: We need to be logged in for this view to work. """ # Try going to the view without being logged in resp = self.client.get(url_for('auth.change_email'), follow_redirects=True) # We will just ensure we have been redirected to /signin self.assertEqual(resp.status_code, 200) # We should see a message saying we need to signin self.assertIn('You need to be logged in to view that', resp.data) # Let's create a user an login user1 = create_account('user1', '*****@*****.**', 'Password') # Activate the account self.assertTrue(activate(user1)) resp = self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) # Lets check to see that our current email is listed on the inital # settings page resp = self.client.get(url_for('users.settings_profile')) self.assertEqual(resp.status_code, 200) self.assertIn('*****@*****.**', resp.data) # Lets double check we can get the change_email page and attempt to # change our password. resp = self.client.get(url_for('auth.change_email')) self.assertEqual(resp.status_code, 200) # Try and change the e-mail address with an invalid password resp = self.client.post(url_for('auth.change_email'), data={ 'password': '', 'new_email': '*****@*****.**' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('Oh no! There are errors in your form', resp.data) # Attempt to change our e-mail resp = self.client.post(url_for('auth.change_email'), data={ 'password': '******', 'new_email': '*****@*****.**' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('We\'ve sent you an email, please confirm', resp.data) # Get the auth token token = resp.headers.get('X-Pjuu-Token') self.assertIsNotNone(token) # Confirm the email change resp = self.client.get(url_for('auth.confirm_email', token=token), follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('We\'ve updated your e-mail address', resp.data) # Let's ensure that our new e-mail appears on our profile page resp = self.client.get(url_for('users.settings_profile')) self.assertEqual(resp.status_code, 200) self.assertIn('*****@*****.**', resp.data) # Yey our email was updated # Lets just make sure we can't change our e-mail without a password resp = self.client.post(url_for('auth.change_email'), data={ 'password': '', 'new_email': '*****@*****.**' }, follow_redirects=True) self.assertIn('Oh no! There are errors in your form', resp.data) # Lets make sure the email doesn't change until the confirmation is # checked resp = self.client.post(url_for('auth.change_email'), data={ 'password': '******', 'new_email': '*****@*****.**' }, follow_redirects=True) self.assertIn('We\'ve sent you an email, please confirm', resp.data) resp = self.client.get(url_for('users.settings_profile')) self.assertNotIn('*****@*****.**', resp.data) # Try and change the e-mail address to one which is already in use resp = self.client.post(url_for('auth.change_email'), data={ 'password': '******', 'new_email': '*****@*****.**' }, follow_redirects=True) self.assertIn('E-mail address already in use', resp.data) # Check invalid token for confirm_email # Coverage resp = self.client.get(url_for('auth.confirm_email', token='token'), follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('Invalid token', resp.data)
def test_change_password(self): """ Test that users can change their own passwords when they are logged in """ # Try going to the view without being logged in resp = self.client.get(url_for('auth.change_password'), follow_redirects=True) # We will just ensure we have been redirected to /signin self.assertEqual(resp.status_code, 200) # We should see a message saying we need to signin self.assertIn('You need to be logged in to view that', resp.data) # 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) # Go to the change password page resp = self.client.get(url_for('auth.change_password')) self.assertEqual(resp.status_code, 200) # Attempt to change our password resp = self.client.post(url_for('auth.change_password'), data={ 'password': '******', 'new_password': '******', 'new_password2': 'NewPassword' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('We\'ve updated your password', resp.data) # Password was successfully changed # Lets try an change our password to one which is not a valid password resp = self.client.post(url_for('auth.change_password'), data={ 'password': '******', 'new_password': '******', 'new_password2': 'Pass' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('Password must be at least 6 characters long', resp.data) # Lets try an change our password but make them not match resp = self.client.post(url_for('auth.change_password'), data={ 'password': '******', 'new_password': '******', 'new_password2': 'OddPassword' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('Passwords must match', resp.data) # Lets try and change our pasword but provide a wrong current password resp = self.client.post(url_for('auth.change_password'), data={ 'password': '******', 'new_password': '******', 'new_password2': 'Password' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('Invalid password', resp.data)
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)
def test_signin_signout(self): """ These functions will test the signin and signout endpoints. We will use url_for so that we can change the URIs in the future. """ # Test that we can GET the signin page resp = self.client.get(url_for('auth.signin')) # We should get a 200 with an error message if we were not successful self.assertEqual(resp.status_code, 200) # There is no user in the system check that we can't authenticate resp = self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }) # We should get a 200 with an error message if we were not successful self.assertEqual(resp.status_code, 200) self.assertIn('Invalid user name or password', resp.data) # Why we are here we will just check that logging in doesn't raise an # issue if not logged in resp = self.client.get(url_for('auth.signout')) # We should be 302 redirected to /signin self.assertEqual(resp.status_code, 302) # There is nothing we can really check as we do not flash() as message # Create a test user and try loggin in, should fail as the user isn't # activated user1 = create_account('user1', '*****@*****.**', 'Password') resp = self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }) # We should get a 200 with an information message self.assertEqual(resp.status_code, 200) self.assertIn('Please activate your account', resp.data) # Activate account self.assertTrue(activate(user1)) resp = self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******', 'keep_signed_in': True }) # Check we are redirected self.assertEqual(resp.status_code, 302) # Log back out self.client.get(url_for('auth.signout')) # Test that the correct warning is shown if the user is banned self.assertTrue(ban(user1)) resp = self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }) # We should get a 200 with an information message self.assertEqual(resp.status_code, 200) self.assertIn('You\'re a very naughty boy!', resp.data) # Lets unban the user now so we can carry on self.assertTrue(ban(user1, False)) # Now the user is active and not banned actualy log in resp = self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('<h1>Feed</h1>', resp.data) # Attempt to try and get back to login when we are already logged in resp = self.client.get(url_for('auth.signin')) self.assertEqual(resp.status_code, 302) # Now we are logged in lets just ensure logout doesn't do anything daft # We should be redirected back to / resp = self.client.get(url_for('auth.signout'), follow_redirects=True) # We should have been 302 redirected to /signin self.assertEqual(resp.status_code, 200) self.assertIn('Successfully signed out', resp.data) # Lets try and cheat the system # Attempt invalid Password resp = self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }, follow_redirects=True) # We should get a 200 with an error message if we were not successful self.assertEqual(resp.status_code, 200) self.assertIn('Invalid user name or password', resp.data) # Attempt user does not exist resp = self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }) # We should get a 200 with an error message if we were not successful self.assertEqual(resp.status_code, 200) self.assertIn('Invalid user name or password', resp.data) # Log the user in and ensure they are logged out if there account # is banned during using the site and not just at login resp = self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('<h1>Feed</h1>', resp.data) # Lets go to another view, we will check out profile and look for our # username resp = self.client.get(url_for('users.settings_profile')) self.assertEqual(resp.status_code, 200) self.assertIn('*****@*****.**', resp.data) # Let's ban the user now self.assertTrue(ban(user1)) # Attempt to get to the feed resp = self.client.get(url_for('users.feed'), follow_redirects=True) # We should be redirected to signin with the standard message self.assertEqual(resp.status_code, 200) self.assertIn('You\'re a very naughty boy!', resp.data) # Adding test from form.validate() == False in signup # Coverage resp = self.client.post(url_for('auth.signin'), data={ 'username': '', 'password': '' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('Invalid user name or password', resp.data) # Log in with user1 and remove the session part way through resp = self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) # Find the Set-Cookie header so we can parse then delete it session_id = None for header in resp.headers: if header[0] == 'Set-Cookie': session_id = parse_cookie(header[1])['session'] rs.delete(session_id) resp = self.client.get(url_for('users.profile', username='******'), follow_redirects=True) self.assertIn('You need to be logged in to view that', resp.data) # Find the Set-Cookie header so we can parse it and check the session # identifier has been updated for header in resp.headers: if header[0] == 'Set-Cookie': self.assertNotEqual(session_id, parse_cookie(header[1])['session'])
def test_dump_account(self): """Can a user get their data? """ user1 = create_account('user1', '*****@*****.**', 'Password') activate(user1) data = dump_account(user1) self.assertIsNotNone(data) # Got data? self.assertEqual('user1', data['user']['username']) self.assertTrue(data['user']['active']) # Has sensitive data been removed? self.assertEqual('<UID>', data['user']['_id']) self.assertEqual('<PASSWORD HASH>', data['user']['password']) self.assertEqual([], data['posts']) # Can they dump posts? post1 = create_post(user1, 'user1', 'Post 1') post2 = create_post(user1, 'user1', 'Post 2') post3 = create_post(user1, 'user1', 'Post 3') data = dump_account(user1) self.assertIsNotNone(data) self.assertNotEqual([], data['posts']) self.assertEqual('Post 1', data['posts'][2]['body']) self.assertEqual('Post 2', data['posts'][1]['body']) self.assertEqual('Post 3', data['posts'][0]['body']) self.assertEqual('<UID>', data['posts'][0]['user_id']) # What about replies? create_post(user1, 'user1', 'Comment 1', post1) create_post(user1, 'user1', 'Comment 2', post1) create_post(user1, 'user1', 'Comment 3', post2) create_post(user1, 'user1', 'Comment 4', post3) data = dump_account(user1) self.assertNotEqual([], data['posts']) self.assertEqual('Comment 1', data['posts'][3]['body']) self.assertEqual('Comment 2', data['posts'][2]['body']) self.assertEqual('Comment 3', data['posts'][1]['body']) self.assertEqual('Comment 4', data['posts'][0]['body']) # Senstive data? self.assertEqual('<UID>', data['posts'][0]['user_id']) # Testing running dump account with a non-existent user self.assertIsNone(dump_account(K.NIL_VALUE)) # Test that user id's a hidden in mentions user2 = create_account('user2', '*****@*****.**', 'Password') activate(user2) user3 = create_account('user3', '*****@*****.**', 'Password') activate(user3) post1 = create_post(user1, 'user1', 'Hello @user2') post_json = json.dumps(dump_account(user1)) self.assertNotIn(user2, post_json) post2 = create_post(user1, 'user1', 'Hello @user2 and @user3') post_json = json.dumps(dump_account(user1)) self.assertNotIn(user2, post_json) self.assertNotIn(user3, post_json)
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_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)
def test_settings_profile(self): """Ensure users have the ability to see some information about there account and can change there about message and display options. """ # 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.settings_profile'), follow_redirects=True) self.assertIn('You need to be logged in to view that', resp.data) # Create a test user user1 = create_account('user1', '*****@*****.**', 'Password') # Activate it activate(user1) # Signin self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }) # If the user profile hasn't been saved the sort order should user = m.db.users.find_one({'username': '******'}) self.assertIsNone(user.get('reply_sort_order')) # Go to our settings page and ensure everything is there resp = self.client.get(url_for('users.settings_profile')) self.assertIn('<div class="content">user1</div>', resp.data) self.assertIn('<div class="content">[email protected]</div>', resp.data) # Post to the form and update our about. We should also be this on # this page resp = self.client.post(url_for('users.settings_profile'), data={'about': 'Otters love fish!'}, follow_redirects=True) self.assertIn('Otters love fish!', resp.data) # Try posting a MASSIVE about ('Otter' * 100) resp = self.client.post(url_for('users.settings_profile'), data={'about': 'Otters' * 100}, follow_redirects=True) # Check we get the form error self.assertIn('Oh no! There are errors in your form', resp.data) # Ensure the about did not change self.assertIn('Otters love fish!', resp.data) resp = self.client.post(url_for('users.settings_profile'), data={ 'about': 'Test display settings', 'hide_feed_images': True, }, follow_redirects=True) self.assertIn('Test display settings', resp.data) # Not sure it's good to check for a checked checkbox so test the user # account user = get_user(user1) self.assertTrue(user.get('hide_feed_images')) # Ensure you can unset it resp = self.client.post(url_for('users.settings_profile'), data={ 'about': 'Test display settings', }, follow_redirects=True) # Get the user again. This should have been updated from the database user = get_user(user1) self.assertFalse(user.get('hide_feed_images')) # Test setting a homepage and location works as expected resp = self.client.post(url_for('users.settings_profile'), data={ 'about': 'Test display settings', 'homepage': 'pjuu.com', 'location': 'England' }, follow_redirects=True) user = get_user(user1) self.assertEqual(user.get('homepage'), 'http://pjuu.com') self.assertEqual(user.get('location'), 'England') # Ensure you can't set an invalid URL resp = self.client.post(url_for('users.settings_profile'), data={ 'about': 'Test display settings', 'homepage': 'pjuu.cheese', }, follow_redirects=True) self.assertIn('Please ensure the home page is a valid URL or empty', resp.data) # Test a URL that doesn't need to be prefixed resp = self.client.post(url_for('users.settings_profile'), data={ 'about': 'Test display settings', 'homepage': 'https://pjuu.com', }, follow_redirects=True) user = get_user(user1) self.assertEqual(user.get('homepage'), 'https://pjuu.com') resp = self.client.post(url_for('users.settings_profile'), data={ 'homepage': 'https://pjuu.com', 'location': 'England', }, follow_redirects=True) # Ensure the users profile reflects the changes resp = self.client.get(url_for('users.profile', username='******')) self.assertIn('<i class="fa fa-map-marker fa-lg"></i> England', resp.data) self.assertIn( '<a href="https://pjuu.com"><i class="fa fa-globe fa-lg"></i></a>', resp.data) # If the view before has been saved the default is -1 (unchecked) user = m.db.users.find_one({'username': '******'}) self.assertEqual(user.get('reply_sort_order'), -1) resp = self.client.post(url_for('users.settings_profile'), data={ 'reply_sort_order': True, }, follow_redirects=True) user = m.db.users.find_one({'username': '******'}) self.assertEqual(user.get('reply_sort_order'), 1) # You can not post the field as thats classed as a True value resp = self.client.post(url_for('users.settings_profile'), data={'about': 'Test'}, follow_redirects=True) user = m.db.users.find_one({'username': '******'}) self.assertEqual(user.get('reply_sort_order'), -1)
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_subscriptions(self): """ Test the backend subscription system. This includes subscribe(), unsubscribe() and is_subscribed(). This will also test the correct subscriptions after a post, comment or tagging. """ # Create a couple of test accounts user1 = create_account('user1', '*****@*****.**', 'Password') user2 = create_account('user2', '*****@*****.**', 'Password') user3 = create_account('user3', '*****@*****.**', 'Password') activate(user1) activate(user2) activate(user3) # Post as user 1 and ensure user 1 exists in Redis post1 = create_post(user1, 'user1', 'Test post 1') self.assertIsNotNone(r.zrank(K.POST_SUBSCRIBERS.format(post1), user1)) # Even though it is exactly the same as the above ensure that # is_subscribed() returns True self.assertTrue(is_subscribed(user1, post1)) # Lets ensure this actually fails! And see if user2 is a subscriber self.assertFalse(is_subscribed(user2, post1)) # Ensure that the REASON (zset score) is set to the correct value self.assertEqual(r.zscore(K.POST_SUBSCRIBERS.format(post1), user1), SubscriptionReasons.POSTER) # Post a comment as user 1 and ensure the reason does NOT changes create_post(user1, 'user1', 'Test comment', post1) # Ensure our reason did not change # If we were not subscribed we would be given reason 2 (COMMENTER) self.assertNotEqual(r.zscore(K.POST_SUBSCRIBERS.format(post1), user1), SubscriptionReasons.COMMENTER) # Test unsubscribe self.assertTrue(unsubscribe(user1, post1)) # Ensure that is_subscribed shows correct self.assertFalse(is_subscribed(user1, post1)) # Test that if we unsubscribe again we get a False result self.assertFalse(unsubscribe(user1, post1)) # Check that unsubscribing some that was never subscribed returns false self.assertFalse(unsubscribe(user2, post1)) # Let's test that commenting subscribes us to the post with the correct # reason. Try tag yourself at the same time create_post(user1, 'user1', 'Test comment @user1', post1) # Ensure we are subscribed self.assertTrue(is_subscribed(user1, post1)) # Check that our reason HAS changed self.assertEqual(r.zscore(K.POST_SUBSCRIBERS.format(post1), user1), SubscriptionReasons.COMMENTER) # Create a comment as test2 and ensure this user becomes subscribed for # the same reason create_post(user2, 'user2', 'Test comment', post1) self.assertTrue(is_subscribed(user2, post1)) self.assertEqual(r.zscore(K.POST_SUBSCRIBERS.format(post1), user2), SubscriptionReasons.COMMENTER) # Create a new post as test1 and tag test2 and test3 in it # ensure all 3 are subscribed and test2 and test3 have the correct # reason. # Also try and tag ourselves this should have no affect # Try tagging someone that does not even exist post2 = create_post(user1, 'user1', 'Test post @user1 @user2 @user3 @user4') self.assertTrue(is_subscribed(user2, post2)) self.assertTrue(is_subscribed(user3, post2)) self.assertEqual(r.zscore(K.POST_SUBSCRIBERS.format(post2), user2), SubscriptionReasons.TAGEE) self.assertEqual(r.zscore(K.POST_SUBSCRIBERS.format(post2), user3), SubscriptionReasons.TAGEE) # Test tagging user 3 in a comment on post1. This ensures that tags # in comments do work. create_post(user2, 'user2', 'Test comment @user3', post1) self.assertTrue(is_subscribed(user3, post1)) self.assertEqual(r.zscore(K.POST_SUBSCRIBERS.format(post1), user3), SubscriptionReasons.TAGEE) # Unsubscribe user2 and user3 self.assertTrue(unsubscribe(user2, post2)) self.assertFalse(is_subscribed(user2, post2)) self.assertTrue(unsubscribe(user3, post2)) self.assertFalse(is_subscribed(user3, post2)) # Ensure that subscribe doe not happen when it is not a valid post self.assertFalse( subscribe(user1, K.NIL_VALUE, SubscriptionReasons.POSTER))
def test_create_user(self): """Check basic user creation stuffs. This also in turn tests check_username(), check_username_pattern(), check_email(), check_email_pattern(), get_username() and get_email(). """ user1 = create_account('user1', '*****@*****.**', 'Password') self.assertIsNotNone(user1) # Duplicate username self.assertIsNone(create_account('user1', '*****@*****.**', 'Password')) # Duplicate email self.assertIsNone(create_account('userX', '*****@*****.**', 'Password')) # Invalid username self.assertIsNone(create_account('u', '*****@*****.**', 'Password')) # Invalid email self.assertIsNone(create_account('userX', 'userX', 'Password')) # Reserved username self.assertIsNone(create_account('help', '*****@*****.**', 'Password')) # You can't get a UID for a non-activated user self.assertEqual(get_uid('user1'), None) activate(user1) self.assertEqual(get_uid('user1'), user1) self.assertEqual(get_uid('*****@*****.**'), user1) # Shouldn't work wiht invali users self.assertIsNone(get_user(K.NIL_VALUE)) # Ensure if works with a valid user self.assertIsNotNone(get_user(user1)) self.assertIsNotNone(type(get_user(user1))) self.assertEqual(type(get_user(user1)), dict) self.assertEqual(get_user(user1).get('username'), 'user1') self.assertEqual(get_user(user1).get('email'), '*****@*****.**') # Check get_uid_* with invalid entries self.assertIsNone(get_uid_username('testymctest')) self.assertIsNone(get_uid_email('*****@*****.**')) # With valid self.assertEqual(get_uid_username('user1'), user1) self.assertEqual(get_uid_email('*****@*****.**'), user1) # Create a new user to check the defaults user2 = create_account('user2', '*****@*****.**', 'Password') # Are values set as expected? user = get_user(user2) self.assertIsNotNone(user) self.assertEqual(user.get('_id'), user2) self.assertEqual(user.get('username'), 'user2') self.assertEqual(user.get('email'), '*****@*****.**') self.assertEqual(user.get('last_login'), -1) self.assertFalse(user.get('active')) self.assertFalse(user.get('banned')) self.assertFalse(user.get('op')) self.assertFalse(user.get('muted')) self.assertEqual(user.get('about'), '') self.assertEqual(user.get('score'), 0) self.assertEqual(user.get('alerts_last_checked'), -1) self.assertIsNotNone(user.get('ttl')) # Generated values, we don't know what they SHOULD be self.assertIsNotNone(user.get('password')) self.assertIsNotNone(user.get('created')) # Check user_exists works self.assertTrue(user_exists(user1)) # Check it fails when invalid value self.assertFalse(user_exists(K.NIL_VALUE))
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_follow_unfollow(self): """ Ensure users can follow and unfollow each other, also ensure that the followers and following pages show the correct value """ # Create 2 users and have them follow each other user1 = create_account('user1', '*****@*****.**', 'Password') user2 = create_account('user2', '*****@*****.**', 'Password') activate(user1) activate(user2) # Let's try and access the endpoints feature when we are not logged in # We should not be able to see it resp = self.client.post(url_for('users.follow', username='******'), follow_redirects=True) self.assertIn('You need to be logged in to view that', resp.data) resp = self.client.post(url_for('users.unfollow', username='******'), follow_redirects=True) self.assertIn('You need to be logged in to view that', resp.data) resp = self.client.get(url_for('users.following', username='******'), follow_redirects=True) self.assertIn('You need to be logged in to view that', resp.data) resp = self.client.get(url_for('users.followers', username='******'), follow_redirects=True) self.assertIn('You need to be logged in to view that', resp.data) # Ensure that test1 can follow and unfollow test2 # Signin resp = self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }, follow_redirects=True) self.assertIn('<h1>Feed</h1>', resp.data) # Try and see a non-existant users followers and following page resp = self.client.get(url_for('users.followers', username='******')) self.assertEqual(resp.status_code, 404) resp = self.client.get(url_for('users.following', username='******')) self.assertEqual(resp.status_code, 404) # Try follow and unfollow a non-existant user resp = self.client.post(url_for('users.follow', username='******')) self.assertEqual(resp.status_code, 404) resp = self.client.post(url_for('users.unfollow', username='******')) self.assertEqual(resp.status_code, 404) # Try follow and unfollow yourself resp = self.client.post(url_for('users.follow', username='******'), follow_redirects=True) self.assertIn('You can\'t follow/unfollow yourself', resp.data) resp = self.client.post(url_for('users.unfollow', username='******'), follow_redirects=True) self.assertIn('You can\'t follow/unfollow yourself', resp.data) # Visit test2 and ensure followers count is 0 resp = self.client.get(url_for('users.followers', username='******')) self.assertIn('<!-- followers:0 -->', resp.data) # Follow test2 # Ensure we pass a next variable to come back to test2's followers page resp = self.client.post(url_for('users.follow', username='******', next=url_for('users.followers', username='******')), follow_redirects=True) # Ensure the flash message has informed use we are following self.assertIn('You have started following user2', resp.data) # Ensure test2's followers count has been incremented self.assertIn('<!-- followers:1 -->', resp.data) # This should match inside a link (Test1 due to capitalization) # Not the best test but it works for now self.assertIn('<!-- list:user:%s -->' % user1, resp.data) # Attempt to follow test2 again resp = self.client.post(url_for('users.follow', username='******', next=url_for('users.followers', username='******')), follow_redirects=True) # Check we got no confirmation self.assertNotIn('You have started following test2', resp.data) # Check that the followers count has not incremented self.assertIn('<!-- followers:1 -->', resp.data) # Ensure test2 is in from YOUR (test1s) following page resp = self.client.get(url_for('users.following', username='******')) self.assertNotIn('<!-- list:user:%s -->' % user1, resp.data) # Unfollow test2 # Ensure that all the previous has been reversed resp = self.client.post(url_for('users.unfollow', username='******', next=url_for('users.followers', username='******')), follow_redirects=True) self.assertIn('You are no longer following user2', resp.data) self.assertIn('<!-- followers:0 -->', resp.data) # Check the list testing tag has gone self.assertNotIn('<!-- list:user:test1 -->', resp.data) # Attempt to unfollow the user again resp = self.client.post(url_for('users.unfollow', username='******', next=url_for('users.followers', username='******')), follow_redirects=True) self.assertNotIn('You are no longer following user2', resp.data) self.assertIn('<!-- followers:0 -->', resp.data) # Ensure test2 is missing from YOUR (test1s) following page resp = self.client.get(url_for('users.following', username='******')) self.assertNotIn('<!-- list:user:%s -->' % user2, resp.data)
def test_signin_signout(self): """ These functions will test the signin and signout endpoints. We will use url_for so that we can change the URIs in the future. """ # Test that we can GET the signin page resp = self.client.get(url_for('auth.signin')) # We should get a 200 with an error message if we were not successful self.assertEqual(resp.status_code, 200) # There is no user in the system check that we can't authenticate resp = self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }) # We should get a 200 with an error message if we were not successful self.assertEqual(resp.status_code, 200) self.assertIn('Invalid user name or password', resp.data) # Why we are here we will just check that logging in doesn't raise an # issue if not logged in resp = self.client.get(url_for('auth.signout')) # We should be 302 redirected to /signin self.assertEqual(resp.status_code, 302) # There is nothing we can really check as we do not flash() as message # Create a test user and try loggin in, should fail as the user isn't # activated user1 = create_account('user1', '*****@*****.**', 'Password') resp = self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }) # We should get a 200 with an information message self.assertEqual(resp.status_code, 200) self.assertIn('Please activate your account', resp.data) # Activate account self.assertTrue(activate(user1)) resp = self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******', 'keep_signed_in': True }, follow_redirects=True) # Check we are redirected self.assertEqual(resp.status_code, 200) self.assertIn("<title>Feed - Pjuu</title>", resp.data) # Log back out self.client.get(url_for('auth.signout')) # Test that the user has additional spaces striped from their names resp = self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******', 'keep_signed_in': True }, follow_redirects=True) # Check we are redirected self.assertEqual(resp.status_code, 200) self.assertIn("<title>Feed - Pjuu</title>", resp.data) # Log back out self.client.get(url_for('auth.signout')) # Test that the correct warning is shown if the user is banned self.assertTrue(ban(user1)) resp = self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }) # We should get a 200 with an information message self.assertEqual(resp.status_code, 200) self.assertIn('You\'re a very naughty boy!', resp.data) # Lets unban the user now so we can carry on self.assertTrue(ban(user1, False)) # Now the user is active and not banned actualy log in resp = self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('<h1>Feed</h1>', resp.data) # Attempt to try and get back to login when we are already logged in resp = self.client.get(url_for('auth.signin')) self.assertEqual(resp.status_code, 302) # Now we are logged in lets just ensure logout doesn't do anything daft # We should be redirected back to / resp = self.client.get(url_for('auth.signout'), follow_redirects=True) # We should have been 302 redirected to /signin self.assertEqual(resp.status_code, 200) self.assertIn('Successfully signed out', resp.data) # Lets try and cheat the system # Attempt invalid Password resp = self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }, follow_redirects=True) # We should get a 200 with an error message if we were not successful self.assertEqual(resp.status_code, 200) self.assertIn('Invalid user name or password', resp.data) # Attempt user does not exist resp = self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }) # We should get a 200 with an error message if we were not successful self.assertEqual(resp.status_code, 200) self.assertIn('Invalid user name or password', resp.data) # Log the user in and ensure they are logged out if there account # is banned during using the site and not just at login resp = self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('<h1>Feed</h1>', resp.data) # Lets go to another view, we will check out profile and look for our # username resp = self.client.get(url_for('users.settings_profile')) self.assertEqual(resp.status_code, 200) self.assertIn('*****@*****.**', resp.data) # Let's ban the user now self.assertTrue(ban(user1)) # Attempt to get to the feed resp = self.client.get(url_for('users.feed'), follow_redirects=True) # We should be redirected to signin with the standard message self.assertEqual(resp.status_code, 200) self.assertIn('You\'re a very naughty boy!', resp.data) # Adding test from form.validate() == False in signup # Coverage resp = self.client.post(url_for('auth.signin'), data={ 'username': '', 'password': '' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('Invalid user name or password', resp.data) # Log in with user1 and remove the session part way through resp = self.client.post(url_for('auth.signin'), data={ 'username': '******', 'password': '******' }, follow_redirects=True) self.assertEqual(resp.status_code, 200)
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)
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)