bgneal@463: """
bgneal@463: View tests for the bio application.
bgneal@463: 
bgneal@463: """
bgneal@767: from io import BytesIO
bgneal@767: import os
bgneal@767: 
bgneal@463: from django.contrib.auth.models import User
bgneal@463: from django.test import TestCase
bgneal@463: from django.core.urlresolvers import reverse, NoReverseMatch
bgneal@768: from django.core import mail
bgneal@463: 
bgneal@767: from PIL import Image
bgneal@767: 
bgneal@768: from bio.models import UserProfile, UserProfileFlag
bgneal@767: 
bgneal@463: 
bgneal@463: class MemberSearchTest(TestCase):
bgneal@463: 
bgneal@463:     USERNAME = u'John'
bgneal@463: 
bgneal@463:     def setUp(self):
bgneal@463:         user = User.objects.create_user(self.USERNAME, '', 'password')
bgneal@463:         user.save()
bgneal@463: 
bgneal@463:         self.username = 'test_user'
bgneal@463:         self.pw = 'password'
bgneal@463:         self.user = User.objects.create_user(self.username, '', self.pw)
bgneal@463:         self.user.save()
bgneal@463:         self.assertTrue(self.client.login(username=self.username,
bgneal@463:             password=self.pw))
bgneal@463: 
bgneal@463:     def tearDown(self):
bgneal@463:         self.client.logout()
bgneal@463: 
bgneal@463:     def testValidName(self):
bgneal@463:         """
bgneal@463:         Test a valid username.
bgneal@463:         """
bgneal@463: 
bgneal@769:         response = self.client.get(reverse('bio-member_search'),
bgneal@463:                             {'username': self.USERNAME},
bgneal@463:                             follow=True)
bgneal@463: 
bgneal@463:         self.assertEqual(len(response.redirect_chain), 1)
bgneal@463:         if response.redirect_chain:
bgneal@463:             self.assertEqual(response.redirect_chain[0][0],
bgneal@463:                     'http://testserver' + reverse('bio-view_profile',
bgneal@463:                         kwargs={'username': self.USERNAME}))
bgneal@463:             self.assertEqual(response.redirect_chain[0][1], 302)
bgneal@463: 
bgneal@463:         self.assertEqual(response.status_code, 200)
bgneal@463: 
bgneal@463:     def testInvalidName(self):
bgneal@463:         """
bgneal@463:         Test a invalid username.
bgneal@463:         """
bgneal@463: 
bgneal@769:         response = self.client.get(reverse('bio-member_search'),
bgneal@463:                             {'username': self.USERNAME + '!'})
bgneal@463: 
bgneal@463:         self.assertEqual(response.status_code, 200)
bgneal@463:         self.assertContains(response, "That username does not exist.")
bgneal@463: 
bgneal@463:     def testTrailingSpace(self):
bgneal@463:         """
bgneal@463:         Test a username with a trailing space.
bgneal@463:         """
bgneal@463: 
bgneal@463:         try:
bgneal@769:             response = self.client.get(reverse('bio-member_search'),
bgneal@463:                                 {'username': self.USERNAME + ' '},
bgneal@463:                                 follow=True)
bgneal@463:         except NoReverseMatch:
bgneal@463:             self.fail('bit by a MySQL bug?')
bgneal@463: 
bgneal@463:         self.assertEqual(len(response.redirect_chain), 1)
bgneal@463:         if response.redirect_chain:
bgneal@463:             self.assertEqual(response.redirect_chain[0][0],
bgneal@463:                     'http://testserver' + reverse('bio-view_profile',
bgneal@463:                         kwargs={'username': self.USERNAME}))
bgneal@463:             self.assertEqual(response.redirect_chain[0][1], 302)
bgneal@463: 
bgneal@463:         self.assertEqual(response.status_code, 200)
bgneal@765: 
bgneal@765: 
bgneal@765: class AnonMemberListTest(TestCase):
bgneal@765: 
bgneal@765:     def _test_login_required(self, list_by):
bgneal@765: 
bgneal@765:         member_list_url = reverse('bio-member_list', kwargs={'type': list_by})
bgneal@765:         response = self.client.get(member_list_url, follow=True)
bgneal@765:         login_url = reverse('accounts-login') + '?next=' + member_list_url
bgneal@765:         self.assertRedirects(response, login_url)
bgneal@765: 
bgneal@765:     def test_login_required(self):
bgneal@765:         self._test_login_required('user')
bgneal@765:         self._test_login_required('date')
bgneal@765: 
bgneal@765: 
bgneal@765: class MemberListTest(TestCase):
bgneal@765: 
bgneal@765:     def setUp(self):
bgneal@765:         u1 = User.objects.create_user('paul', '', 'pw')
bgneal@765:         u1.save()
bgneal@765:         u2 = User.objects.create_user('eddie', '', 'pw')
bgneal@765:         u2.save()
bgneal@765: 
bgneal@765:         self.user = u1
bgneal@765:         self.client.login(username=u1.username, password='pw')
bgneal@765: 
bgneal@765:     def _test_get(self, list_by, page=None, code=200):
bgneal@765: 
bgneal@765:         member_list_url = reverse('bio-member_list', kwargs={'type': list_by})
bgneal@765:         if page is not None:
bgneal@765:             member_list_url += '?page=%d' % page
bgneal@765:         response = self.client.get(member_list_url)
bgneal@765:         self.assertEqual(response.status_code, code)
bgneal@765: 
bgneal@765:     def test_get(self):
bgneal@765:         self._test_get('user')
bgneal@765:         self._test_get('date')
bgneal@765:         self._test_get('user', page=1)
bgneal@765:         self._test_get('date', page=1)
bgneal@765: 
bgneal@765:     def test_invalid_page(self):
bgneal@765:         self._test_get('user', page=99, code=404)
bgneal@765:         self._test_get('date', page=99, code=404)
bgneal@765: 
bgneal@765: 
bgneal@766: class ProfileTest(TestCase):
bgneal@765: 
bgneal@765:     def setUp(self):
bgneal@765:         u1 = User.objects.create_user('paul', '', 'pw')
bgneal@765:         u1.save()
bgneal@765:         u2 = User.objects.create_user('eddie', '', 'pw')
bgneal@765:         u2.save()
bgneal@765: 
bgneal@767:     def tearDown(self):
bgneal@767:         profile = UserProfile.objects.get(user__username='paul')
bgneal@767:         if profile.avatar:
bgneal@767:             os.remove(profile.avatar.path)
bgneal@767: 
bgneal@766:     def test_anon_my_profile(self):
bgneal@765:         my_url = reverse('bio-me')
bgneal@765:         response = self.client.get(my_url)
bgneal@765:         login_url = reverse('accounts-login') + '?next=' + my_url
bgneal@765:         self.assertRedirects(response, login_url)
bgneal@765: 
bgneal@766:     def test_authenticated_my_profile(self):
bgneal@765:         self.client.login(username='paul', password='pw')
bgneal@765:         response = self.client.get(reverse('bio-me'))
bgneal@765:         self.assertEqual(response.status_code, 200)
bgneal@766: 
bgneal@766:     def test_anon_other_profile(self):
bgneal@766:         url = reverse('bio-view_profile', kwargs={'username': 'eddie'})
bgneal@766:         response = self.client.get(url)
bgneal@766:         login_url = reverse('accounts-login') + '?next=' + url
bgneal@766:         self.assertRedirects(response, login_url)
bgneal@766: 
bgneal@766:     def test_authenticated_other_profile(self):
bgneal@766:         self.client.login(username='paul', password='pw')
bgneal@766:         url = reverse('bio-view_profile', kwargs={'username': 'eddie'})
bgneal@766:         response = self.client.get(url)
bgneal@766:         self.assertEqual(response.status_code, 200)
bgneal@766: 
bgneal@766:     def test_view_profile_as_me_redirects(self):
bgneal@766:         self.client.login(username='paul', password='pw')
bgneal@766:         url = reverse('bio-view_profile', kwargs={'username': 'paul'})
bgneal@766:         response = self.client.get(url)
bgneal@766:         self.assertRedirects(response, reverse('bio-me'))
bgneal@766: 
bgneal@766:     def test_edit_anon(self):
bgneal@766:         url = reverse('bio-edit_profile')
bgneal@766:         response = self.client.get(url)
bgneal@766:         login_url = reverse('accounts-login') + '?next=' + url
bgneal@766:         self.assertRedirects(response, login_url)
bgneal@766: 
bgneal@766:     def test_edit_profile(self):
bgneal@766:         self.client.login(username='paul', password='pw')
bgneal@766:         url = reverse('bio-edit_profile')
bgneal@766:         response = self.client.get(url)
bgneal@766:         self.assertEqual(response.status_code, 200)
bgneal@766: 
bgneal@766:         # Save some new data. We don't exhaustively test every field.
bgneal@766:         response = self.client.post(url, {
bgneal@766:             'first_name': 'Paul',
bgneal@766:             'last_name': 'Johnson',
bgneal@766:             'email': 'pjmoto@example.com',
bgneal@766:             'occupation': 'Surf Guitar Pioneer',
bgneal@766:             'profile_text': 'Wrote Mr. Moto at age 15.',
bgneal@766:             'submit_button': 'Save',
bgneal@766:         })
bgneal@766:         self.assertRedirects(response, reverse('bio-me'))
bgneal@766: 
bgneal@766:         u = User.objects.get(username='paul')
bgneal@766:         self.assertEqual(u.first_name, 'Paul')
bgneal@766:         self.assertEqual(u.last_name, 'Johnson')
bgneal@766:         self.assertEqual(u.email, 'pjmoto@example.com')
bgneal@789:         profile = u.profile
bgneal@766:         self.assertEqual(profile.occupation, 'Surf Guitar Pioneer')
bgneal@766:         self.assertEqual(profile.profile_text, 'Wrote Mr. Moto at age 15.')
bgneal@767: 
bgneal@767:     def test_avatar_change(self):
bgneal@767:         self.client.login(username='paul', password='pw')
bgneal@767:         url = reverse('bio-change_avatar')
bgneal@767:         response = self.client.get(url)
bgneal@767:         self.assertEqual(response.status_code, 200)
bgneal@767: 
bgneal@767:         # Create an in-memory image for a dummy avatar
bgneal@767:         file_obj = BytesIO()
bgneal@767:         image = Image.new('RGBA', size=(100, 100))
bgneal@767:         image.save(file_obj, 'png')
bgneal@767:         file_obj.name = 'avatar.png'
bgneal@767:         file_obj.seek(0)
bgneal@767: 
bgneal@767:         response = self.client.post(url, {'avatar_file': file_obj}, follow=True)
bgneal@767:         self.assertRedirects(response, reverse('bio-me'))
bgneal@767: 
bgneal@768:         profile = UserProfile.objects.get(user__username='paul')
bgneal@768:         self.assertTrue(profile.avatar.path)
bgneal@768:         self.assertTrue(profile.avatar.name)
bgneal@768:         self.assertTrue(os.path.exists(profile.avatar.path))
bgneal@768: 
bgneal@768:     def test_flag_profile_get(self):
bgneal@768:         paul = User.objects.get(username='paul')
bgneal@768:         eddie = User.objects.get(username='eddie')
bgneal@768:         url = reverse('bio-flag_profile', args=[eddie.pk])
bgneal@768: 
bgneal@768:         # not logged in, wrong request method:
bgneal@768:         response = self.client.get(url)
bgneal@768:         self.assertEqual(response.status_code, 405)
bgneal@768: 
bgneal@768:         # logged in, wrong request method
bgneal@768:         self.client.login(username='paul', password='pw')
bgneal@768:         response = self.client.get(url)
bgneal@768:         self.assertEqual(response.status_code, 405)
bgneal@768: 
bgneal@768:         # logged out, right request method
bgneal@768:         self.client.logout()
bgneal@768:         response = self.client.post(url)
bgneal@768:         self.assertEqual(response.status_code, 200)
bgneal@768:         self.assertEqual(UserProfileFlag.objects.all().count(), 0)
bgneal@768: 
bgneal@768:         # logged in, right request method
bgneal@768:         self.client.login(username='paul', password='pw')
bgneal@768:         response = self.client.post(url)
bgneal@768:         self.assertEqual(response.status_code, 200)
bgneal@768:         self.assertEqual(UserProfileFlag.objects.all().count(), 1)
bgneal@768: 
bgneal@768:         flag = UserProfileFlag.objects.first()
bgneal@768:         self.assertEqual(flag.user, paul)
bgneal@789:         self.assertEqual(flag.profile, eddie.profile)
bgneal@768: 
bgneal@768:         self.assertEqual(len(mail.outbox), 1)
bgneal@768:         self.assertTrue('A Profile Has Been Flagged' in mail.outbox[0].subject)