def setUp(self): self.staff_user = UserFactory() group = Group.objects.get(name=CompanyUser.GROUP_NAME) self.staff_user.groups.add(group) self.staff_user.save() self.company = CompanyFactory() self.company.save() self.admin = CompanyUserFactory(user=self.staff_user, company=self.company) self.admin.save() self.microsite = MicrositeFactory(company=self.company) self.microsite.save() self.client = TestClient() self.client.login_user(self.staff_user) self.candidate_user = UserFactory(email="*****@*****.**") SavedSearchFactory(user=self.candidate_user, url='http://test.jobs/search?q=django', label='test Jobs') self.candidate_user.save() for i in range(5): # Create 5 new users user = UserFactory(email='*****@*****.**' % i) for search in SEARCH_OPTS: # Create 15 new searches and assign three per user SavedSearchFactory(user=user, url='http://test.jobs/search?q=%s' % search, label='%s Jobs' % search)
class MessageViewTests(TestCase): def setUp(self): self.user = UserFactory() self.message = Message(subject='subject', body='body', message_type='success') self.message.save() for group in Group.objects.all(): self.message.group.add(group.pk) self.message.save() self.messageInfo = MessageInfo(user=User.objects.get(id=1), message=self.message) self.messageInfo.save() self.client = TestClient() self.client.login_user(self.user) def test_user_post_mark_message_read(self): resp = self.client.post(reverse('read'), data={ 'name': 'message-' + str(self.message.id) + '-' + str(self.user.id) }, follow=True) m = MessageInfo.objects.get(user=self.user, message=self.message) self.assertTrue(m.read) self.assertTrue(m.read_at)
def setUp(self): super(MySearchViewTests, self).setUp() self.client = TestClient() self.user = UserFactory() self.client.login_user(self.user) self.new_form_data = { 'url': 'www.my.jobs/jobs', 'feed': 'http://www.my.jobs/jobsfeed/rss?', 'label': 'Jobs Label', 'email': self.user.email, 'frequency': 'D', 'is_active': 'True', 'sort_by': 'Relevance', } self.new_digest_data = { 'is_active': 'True', 'user': self.user, 'email': self.user.email, 'frequency': 'M', 'day_of_month': 1, } self.new_form = forms.SavedSearchForm(user=self.user, data=self.new_form_data) self.r = Replacer() self.r.replace('urllib2.urlopen', return_file)
def setUp(self): self.user = UserFactory() self.client = TestClient() create_api_key(User, instance=self.user, created=True) self.data = {'email': '*****@*****.**', 'username': self.user.email, 'api_key': self.user.api_key.key }
def setUp(self): self.user = UserFactory() self.auth_callback_url = 'https://secure.my.jobs/account' self.auth_callback = '?auth_callback=%s' % self.auth_callback_url self.key_qs = '%s&key=%s' self.client = TestClient() self.client.login_user(self.user)
def setUp(self): super(MyJobsHelpersTests, self).setUp() self.user = UserFactory() self.client = TestClient() self.login_params = { 'username': '******', 'password': '******', 'action': 'login' }
def setUp(self): super(SavedSearchResourceTests, self).setUp() self.user = UserFactory() self.client = TestClient() self.data = {'email':'*****@*****.**', 'url':'www.my.jobs/jobs'} create_api_key(User, instance=self.user, created=True) self.credentials = (self.user.email, self.user.api_key.key) self.r = Replacer() self.r.replace('urllib2.urlopen', return_file)
def setUp(self): self.user = UserFactory() self.message = Message(subject='subject', body='body', message_type='success') self.message.save() for group in Group.objects.all(): self.message.group.add(group.pk) self.message.save() self.messageInfo = MessageInfo(user=User.objects.get(id=1), message=self.message) self.messageInfo.save() self.client = TestClient() self.client.login_user(self.user)
def test_not_disabled(self): """ An anonymous user who provides the :verify-email: query string or user with is_disabled set to True should be redirected to the home page. An anonymous user who does not should see a 404. A user with is_active set to False should proceed to their destination. """ client = TestClient() user = UserFactory() #Anonymous user resp = client.get(reverse('view_profile')) path = resp.request.get('PATH_INFO') self.assertRedirects(resp, reverse('home') + '?next=' + path) # This is ugly, but it is an artifact of the way Django redirects # users who fail the `user_passes_test` decorator. qs = '?verify-email=%s' % user.email next_qs = '?next=' + urlquote('/profile/view/%s' % qs) # Anonymous user navigates to url with :verify-email: in query string resp = client.get(reverse('view_profile') + qs) # Old path + qs is urlquoted and added to the url as the :next: param self.assertRedirects(resp, "http://testserver/" + next_qs) # Active user client.login_user(user) resp = client.get(reverse('view_profile')) self.assertTrue(resp.status_code, 200) #Disabled user user.is_disabled = True user.save() resp = client.get(reverse('view_profile')) self.assertRedirects(resp, "http://testserver/?next=/profile/view/")
class MyJobsHelpersTests(TestCase): def setUp(self): super(MyJobsHelpersTests, self).setUp() self.user = UserFactory() self.client = TestClient() self.login_params = { 'username': '******', 'password': '******', 'action': 'login' } def test_login_dont_remember_me(self): self.assertEqual(Session.objects.count(), 0) response = self.client.post(reverse('home'), data=self.login_params) self.assertEqual(Session.objects.count(), 1) session = Session.objects.all()[0] session_dict = session.get_decoded() user_id = session_dict['_auth_user_id'] self.assertEqual(user_id, self.user.id) # session.expire_date is tz aware; datetime.datetime.now is naive # It probably isn't worth it to bring in pytz just for tests now = datetime.datetime.now(session.expire_date.tzinfo) diff = session.expire_date - now # Due to the delay between the post at the top of this test # and reaching this line, this can't be an assertEquals; self.assertTrue(880 <= diff.total_seconds() <= 900) def test_login_remember_me(self): self.assertEqual(Session.objects.count(), 0) self.login_params['remember_me'] = True response = self.client.post(reverse('home'), data=self.login_params) self.assertEqual(Session.objects.count(), 1) session = Session.objects.all()[0] session_dict = session.get_decoded() user_id = session_dict['_auth_user_id'] self.assertEqual(user_id, self.user.id) weeks = (datetime.datetime.now() + datetime.timedelta(days=14)) # Session expiration should be two weeks from now - comparing number # of days should be good enough self.assertEqual(session.expire_date.toordinal(), weeks.toordinal())
class MyJobsHelpersTests(TestCase): def setUp(self): super(MyJobsHelpersTests, self).setUp() self.user = UserFactory() self.client = TestClient() self.login_params = {'username': '******', 'password': '******', 'action': 'login'} def test_login_dont_remember_me(self): self.assertEqual(Session.objects.count(), 0) response = self.client.post(reverse('home'), data=self.login_params) self.assertEqual(Session.objects.count(), 1) session = Session.objects.all()[0] session_dict = session.get_decoded() user_id = session_dict['_auth_user_id'] self.assertEqual(user_id, self.user.id) # session.expire_date is tz aware; datetime.datetime.now is naive # It probably isn't worth it to bring in pytz just for tests now = datetime.datetime.now(session.expire_date.tzinfo) diff = session.expire_date - now # Due to the delay between the post at the top of this test # and reaching this line, this can't be an assertEquals; self.assertTrue(880 <= diff.total_seconds() <= 900) def test_login_remember_me(self): self.assertEqual(Session.objects.count(), 0) self.login_params['remember_me'] = True response = self.client.post(reverse('home'), data=self.login_params) self.assertEqual(Session.objects.count(), 1) session = Session.objects.all()[0] session_dict = session.get_decoded() user_id = session_dict['_auth_user_id'] self.assertEqual(user_id, self.user.id) weeks = (datetime.datetime.now() + datetime.timedelta(days=14)) # Session expiration should be two weeks from now - comparing number # of days should be good enough self.assertEqual(session.expire_date.toordinal(), weeks.toordinal())
def setUp(self): super(MyJobsHelpersTests, self).setUp() self.user = UserFactory() self.client = TestClient() self.login_params = {'username': '******', 'password': '******', 'action': 'login'}
def test_not_disabled(self): """ An anonymous user who provides the :verify-email: query string or user with is_disabled set to True should be redirected to the home page. An anonymous user who does not should see a 404. A user with is_active set to False should proceed to their destination. """ client = TestClient() user = UserFactory() #Anonymous user resp = client.get(reverse('view_profile')) path = resp.request.get('PATH_INFO') self.assertRedirects(resp, reverse('home')+'?next='+path) # This is ugly, but it is an artifact of the way Django redirects # users who fail the `user_passes_test` decorator. qs = '?verify-email=%s' % user.email next_qs = '?next=' + urlquote('/profile/view/%s' % qs) # Anonymous user navigates to url with :verify-email: in query string resp = client.get(reverse('view_profile') + qs) # Old path + qs is urlquoted and added to the url as the :next: param self.assertRedirects(resp, "http://testserver/" + next_qs) # Active user client.login_user(user) resp = client.get(reverse('view_profile')) self.assertTrue(resp.status_code, 200) #Disabled user user.is_disabled = True user.save() resp = client.get(reverse('view_profile')) self.assertRedirects(resp, "http://testserver/?next=/profile/view/")
def test_is_active(self): """ A user with is_active set to False should be redirected to the home page, while a user with is_active set to True should proceed to their destination. """ client = TestClient() user = UserFactory() quoted_email = urllib.quote(user.email) # Active user client.login_user(user) resp = client.get(reverse('saved_search_main')) self.assertTrue(resp.status_code, 200) # Inactive user user.is_active = False user.save() resp = client.get(reverse('saved_search_main')) self.assertRedirects(resp, "http://testserver/?next=/saved-search/view/")
def setUp(self): """ These tests use the default backend, since we know it's available; that needs to have ``ACCOUNT_ACTIVATION_DAYS`` set. """ super(RegistrationViewTests, self).setUp() self.client = TestClient() self.old_activation = getattr(settings, 'ACCOUNT_ACTIVATION_DAYS', None) if self.old_activation is None: settings.ACCOUNT_ACTIVATION_DAYS = 7 # pragma: no cover self.data = { 'email': '*****@*****.**', 'password1': 'swordfish', 'password2': 'swordfish', 'action': 'register' } self.client.post(reverse('home'), data=self.data) self.user = User.objects.get(email=self.data['email'])
class MessageViewTests(TestCase): def setUp(self): self.user = UserFactory() self.message = Message(subject='subject', body='body', message_type='success') self.message.save() for group in Group.objects.all(): self.message.group.add(group.pk) self.message.save() self.messageInfo = MessageInfo(user=User.objects.get(id=1), message=self.message) self.messageInfo.save() self.client = TestClient() self.client.login_user(self.user) def test_user_post_mark_message_read(self): resp = self.client.post(reverse('read'), data={'name': 'message-'+str(self.message.id) + '-'+str(self.user.id)}, follow=True) m = MessageInfo.objects.get(user=self.user, message=self.message) self.assertTrue(m.read) self.assertTrue(m.read_at)
def setUp(self): """ These tests use the default backend, since we know it's available; that needs to have ``ACCOUNT_ACTIVATION_DAYS`` set. """ super(RegistrationViewTests, self).setUp() self.client = TestClient() self.old_activation = getattr(settings, 'ACCOUNT_ACTIVATION_DAYS', None) if self.old_activation is None: settings.ACCOUNT_ACTIVATION_DAYS = 7 # pragma: no cover self.data = {'email': '*****@*****.**', 'password1': 'swordfish', 'password2': 'swordfish', 'action': 'register'} self.client.post(reverse('home'), data=self.data) self.user = User.objects.get(email=self.data['email'])
class UserResourceTests(TestCase): def setUp(self): self.user = UserFactory() self.client = TestClient() create_api_key(User, instance=self.user, created=True) self.data = { 'email': '*****@*****.**', 'username': self.user.email, 'api_key': self.user.api_key.key } def make_response(self, data): url = '/api/v1/user/' response = self.client.get(url, data) return response def test_create_new_user(self): response = self.make_response(self.data) content = json.loads(response.content) self.assertEqual(content, { 'user_created': True, 'email': '*****@*****.**' }) self.assertEqual(response.status_code, 200) self.assertEqual(User.objects.count(), 2) user = User.objects.get(email=self.data['email']) def test_no_email(self): self.data['email'] = '' response = self.make_response(self.data) content = json.loads(response.content) self.assertEqual(response.status_code, 200) self.assertEqual(content['email'], 'No email provided') def test_existing_user(self): for email in [self.user.email, self.user.email.upper()]: self.data['email'] = email response = self.make_response(self.data) content = json.loads(response.content) self.assertEqual(response.status_code, 200) self.assertFalse(content['user_created']) self.assertEqual(content['email'].lower(), '*****@*****.**')
class UserResourceTests(TestCase): def setUp(self): self.user = UserFactory() self.client = TestClient() create_api_key(User, instance=self.user, created=True) self.data = {'email': '*****@*****.**', 'username': self.user.email, 'api_key': self.user.api_key.key } def make_response(self, data): url = '/api/v1/user/' response = self.client.get(url, data) return response def test_create_new_user(self): response = self.make_response(self.data) content = json.loads(response.content) self.assertEqual(content, {'user_created':True, 'email':'*****@*****.**'}) self.assertEqual(response.status_code, 200) self.assertEqual(User.objects.count(), 2) user = User.objects.get(email=self.data['email']) def test_no_email(self): self.data['email'] = '' response = self.make_response(self.data) content = json.loads(response.content) self.assertEqual(response.status_code, 200) self.assertEqual(content['email'], 'No email provided') def test_existing_user(self): for email in [self.user.email, self.user.email.upper()]: self.data['email'] = email response = self.make_response(self.data) content = json.loads(response.content) self.assertEqual(response.status_code, 200) self.assertFalse(content['user_created']) self.assertEqual(content['email'].lower(), '*****@*****.**')
def test_group_status(self): """ Should return True if user.groups contains the group specified and False if it does not. """ client = TestClient() user = UserFactory() user.groups.all().delete() for group in Group.objects.all(): # Makes a list of all group names, excluding the one that the # user will be a member of names = map(lambda group: group.name, Group.objects.filter(~Q(name=group.name))) user.groups.add(group.pk) user.save() for name in names: self.assertFalse(User.objects.is_group_member(user, name)) self.assertTrue(User.objects.is_group_member(user, group.name)) user.groups.all().delete()
def setUp(self): self.user = UserFactory() self.name = PrimaryNameFactory(user=self.user) self.client = TestClient()
class AccountFormTests(TestCase): def setUp(self): self.user = UserFactory() self.name = PrimaryNameFactory(user=self.user) self.client = TestClient() def test_password_form(self): invalid_data = [ { 'data': {'password': '******', 'new_password1': 'newpassword', 'new_password2': 'newpassword'}, u'errors': [['password', [u"Wrong password."]]]}, { 'data': {'password': '******', 'new_password1': 'newpassword', 'new_password2': 'notnewpassword'}, u'errors': [[u'new_password2', [u'The new password fields did not match.']], [u'new_password1', [u'The new password fields did not match.']]], }, ] for item in invalid_data: form = ChangePasswordForm(user=self.user, data=item['data']) self.failIf(form.is_valid()) self.assertEqual(form.errors[item[u'errors'][0][0]], item[u'errors'][0][1]) form = ChangePasswordForm(user=self.user,data={'password': '******', 'new_password1': 'anothersecret', 'new_password2': 'anothersecret'}) self.failUnless(form.is_valid()) form.save() self.failUnless(self.user.check_password('anothersecret')) def test_no_name_account_form(self): """ Leaving both the first and last name fields blank produces a valid save. It also deletes the primary name object from the Name model. """ data = {"gravatar": "*****@*****.**", "user": self.user} form = EditAccountForm(data, **{'user':self.user}) self.assertTrue(form.is_valid()) form.save(self.user) self.assertEqual(Name.objects.count(), 0) def test_both_names_account_form(self): """ Filling out both name fields produces a valid save. """ data = {"given_name": "Alicia", "family_name": "Smith", "gravatar": "*****@*****.**"} form = EditAccountForm(data, **{'user':self.user}) self.assertTrue(form.is_valid()) def test_partial_name_account_form(self): """ Filling out only the first name or only the last name produces an error. """ data = {"given_name": "Alicia", "gravatar": "*****@*****.**", "user": self.user} form = EditAccountForm(data, **{'user':self.user}) self.assertFalse(form.is_valid()) self.assertEqual(form.errors['family_name'][0], "Both a first and last name required.") def test_gravatar_email_list(self): """ Dropdowns for selecting the user's preferred Gravatar email should be the only dropdowns that include "Do not use Gravatar" as an option - others should default to the user's primary email address. """ self.client.login_user(self.user) response = self.client.get(reverse('edit_communication')) soup = BeautifulSoup(response.content) options = soup.select('#id_digest_email option') self.assertEqual(len(options), 1) self.assertTrue(self.user.gravatar in options[0]) response = self.client.get(reverse('edit_basic')) soup = BeautifulSoup(response.content) options = soup.select('#id_gravatar option') self.assertEqual(len(options), 2) self.assertTrue('Do not use Gravatar' in options[0]) self.assertTrue(self.user.gravatar in options[1])
class MySearchViewTests(TestCase): def setUp(self): super(MySearchViewTests, self).setUp() self.client = TestClient() self.user = UserFactory() self.client.login_user(self.user) self.new_form_data = { 'url': 'www.my.jobs/jobs', 'feed': 'http://www.my.jobs/jobsfeed/rss?', 'label': 'Jobs Label', 'email': self.user.email, 'frequency': 'D', 'is_active': 'True', 'sort_by': 'Relevance', } self.new_digest_data = { 'is_active': 'True', 'user': self.user, 'email': self.user.email, 'frequency': 'M', 'day_of_month': 1, } self.new_form = forms.SavedSearchForm(user=self.user, data=self.new_form_data) self.r = Replacer() self.r.replace('urllib2.urlopen', return_file) def tearDown(self): self.r.restore() def test_search_main(self): response = self.client.get(reverse('saved_search_main')) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'mysearches/saved_search_main.html') self.failUnless(isinstance(response.context['form'], forms.DigestForm)) self.failUnless(isinstance(response.context['add_form'], forms.SavedSearchForm)) def test_save_new_search_form(self): response = self.client.post(reverse('save_search_form'), data=self.new_form_data, HTTP_X_REQUESTED_WITH='XMLHttpRequest') self.assertEqual(response.status_code, 200) self.assertEqual(response.content, '') def test_save_new_search_invalid(self): del self.new_form_data['frequency'] response = self.client.post(reverse('save_search_form'), data=self.new_form_data, HTTP_X_REQUESTED_WITH='XMLHttpRequest') self.assertEqual(response.status_code, 200) self.assertEqual(json.loads(response.content).keys(), ['frequency']) def test_get_edit_page(self): self.new_form.save() search_id = self.new_form.instance.id response = self.client.get( reverse('edit_search')+'?id=%s' % search_id) self.assertEqual(response.status_code, 200) self.assertEqual(self.new_form.instance, response.context['form'].instance) self.assertTemplateUsed(response, 'mysearches/saved_search_edit.html') search_id += 1 response = self.client.get( reverse('edit_search')+'id=%s' % search_id) self.assertEqual(response.status_code, 404) def test_save_edit_form(self): self.new_form.save() search_id = self.new_form.instance.id self.new_form_data['frequency'] = 'W' self.new_form_data['day_of_week'] = 1 self.new_form_data['url'] = 'www.my.jobs/search?' self.new_form_data['search_id'] = search_id new_form = forms.SavedSearchForm(user=self.user, data=self.new_form_data) response = self.client.post(reverse('save_search_form'), data=self.new_form_data, HTTP_X_REQUESTED_WITH='XMLHttpRequest') self.assertEqual(response.status_code, 200) self.assertEqual(response.content, '') del self.new_form_data['frequency'] response = self.client.post(reverse('save_search_form'), data=self.new_form_data, HTTP_X_REQUESTED_WITH='XMLHttpRequest') self.assertEqual(response.status_code, 200) self.assertEqual(json.loads(response.content).keys(), ['frequency']) def test_validate_url(self): response = self.client.post(reverse('validate_url'), data={'url': self.new_form_data['url']}, HTTP_X_REQUESTED_WITH='XMLHttpRequest') self.assertEqual(response.status_code, 200) data = {'rss_url': 'http://www.my.jobs/jobs/feed/rss', 'feed_title': 'Jobs', 'url_status': 'valid'} self.assertEqual(json.loads(response.content), data) response = self.client.post(reverse('validate_url'), data={'url': 'google.com'}, HTTP_X_REQUESTED_WITH='XMLHttpRequest') self.assertEqual(response.status_code, 200) self.assertEqual(json.loads(response.content), {'url_status': 'not valid'}) def test_save_digest_form(self): response = self.client.post(reverse('save_digest_form'), self.new_digest_data, HTTP_X_REQUESTED_WITH='XMLHttpRequest') self.assertEqual(response.status_code, 200) self.assertEqual(response.content, '') del self.new_digest_data['email'] response = self.client.post(reverse('save_digest_form'), self.new_digest_data, HTTP_X_REQUESTED_WITH='XMLHttpRequest') self.assertEqual(response.status_code, 200) self.assertEqual(response.content, '{"email": ["This field is required."]}') def test_unsubscribe_owned_search(self): """ Unsubscribing an owned saved search should result in that search being deactivated """ search = SavedSearchFactory(user=self.user) self.assertTrue(search.is_active) response = self.client.get(reverse('unsubscribe')+'?id=%s' % search.id) search = models.SavedSearch.objects.get(id=search.id) self.assertFalse(search.is_active) self.assertTemplateUsed(response, 'mysearches/saved_search_disable.html') def test_unsubscribe_unowned_search(self): """ Attempting to unsubscribe using a search that isn't yours should result in nothing happening to the search """ user = UserFactory(email='*****@*****.**') search = SavedSearchFactory(user=user) response = self.client.get(reverse('unsubscribe')+'?id=%s' % search.id) search = models.SavedSearch.objects.get(id=search.id) self.assertTrue(search.is_active) self.assertEqual(response.status_code, 404) def test_unsubscribe_digest(self): """ Unsubscribing a saved search digest should result in all of the owner's saved searches being disabled """ digest = SavedSearchDigestFactory(user=self.user) searches = [] for url in ['www.my.jobs/search?q=python', 'jobs.jobs/search?q=django']: searches.append(SavedSearchFactory(url=url, user=self.user)) for search in searches: self.assertTrue(search.is_active) response = self.client.get(reverse('unsubscribe')+'?id=digest') searches = list(models.SavedSearch.objects.all()) for search in searches: self.assertFalse(search.is_active) self.assertTemplateUsed(response, 'mysearches/saved_search_disable.html') self.assertEqual(response.status_code, 200) def test_anonymous_unsubscribe(self): search = SavedSearchFactory(user=self.user) Session.objects.all().delete() # Navigating to the 'unsubscribe' page while logged out... response = self.client.get( reverse('unsubscribe')+'?id='+str(search.id)) path = response.request.get('PATH_INFO') + "?id=" + str(search.id) self.assertRedirects(response, reverse('home')+'?next='+path) # or with the wrong email address... response = self.client.get( reverse('unsubscribe') + '?id='+str( search.id)+'&[email protected]') # results in being redirected to the login page and the searches # remaining unchanged self.assertRedirects(response, reverse('home')) search = models.SavedSearch.objects.get(id=search.id) self.assertTrue(search.is_active) response = self.client.get( reverse('unsubscribe') + '?id=%s&verify-email=%s' % ( search.id, self.user.email)) search = models.SavedSearch.objects.get(id=search.id) self.assertFalse(search.is_active) def test_delete_owned_search(self): search = SavedSearchFactory(user=self.user) self.assertEqual(models.SavedSearch.objects.count(), 1) response = self.client.get( reverse('delete_saved_search')+'?id=%s' % search.id) self.assertEqual(models.SavedSearch.objects.count(), 0) self.assertRedirects(response, reverse( 'saved_search_main_query')+'?d='+str(urllib2.quote( search.label.title()))) def test_delete_unowned_search(self): """ Attempting to delete a search that isn't yours should result in nothing happening to the search """ user = UserFactory(email='*****@*****.**') search = SavedSearchFactory(user=user) response = self.client.get( reverse('delete_saved_search')+'?id=%s' % search.id) self.assertEqual(models.SavedSearch.objects.count(), 1) self.assertEqual(response.status_code, 404) def test_delete_owned_searches_by_digest(self): """ Deleting with a saved search digest should result in all of the user's saved searches being deleted """ digest = SavedSearchDigestFactory(user=self.user) searches = [] for url in ['www.my.jobs/search?q=python', 'jobs.jobs/search?q=django']: searches.append(SavedSearchFactory(url=url, user=self.user)) self.assertEqual(models.SavedSearch.objects.count(), 2) response = self.client.get(reverse('delete_saved_search')+'?id=digest') self.assertEqual(models.SavedSearch.objects.count(), 0) self.assertRedirects(response, reverse( 'saved_search_main_query')+'?d=all') def test_anonymous_delete_searches(self): search = SavedSearchFactory(user=self.user) Session.objects.all().delete() # Navigating to the 'delete saved search' page while logged out... response = self.client.get( reverse('delete_saved_search')+'?id='+str(search.id)) path = response.request.get('PATH_INFO') + "?id=" + str(search.id) self.assertRedirects(response, reverse('home')+'?next='+path) self.assertEqual(models.SavedSearch.objects.count(), 1) # or with the wrong email address... response = self.client.get( reverse('delete_saved_search')+'?id='+str( search.id)+'&[email protected]') # results in being redirected to the login page and no searches being # deleted self.assertRedirects(response, reverse('home')) self.assertEqual(models.SavedSearch.objects.count(), 1) response = self.client.get( reverse('delete_saved_search')+'?id=%s&verify-email=%s' % ( search.id, self.user.email)) self.assertEqual(models.SavedSearch.objects.count(), 0) # assertRedirects follows any redirect and waits for a 200 status code; # anonymous users will always redirect, never returning a 200. self.client.login_user(self.user) self.assertRedirects(response, reverse( 'saved_search_main_query')+'?d='+str(urllib2.quote( search.label.title())))
class MyProfileViewsTests(TestCase): def setUp(self): super(MyProfileViewsTests, self).setUp() self.user = UserFactory() self.client = TestClient() self.client.login_user(self.user) self.name = PrimaryNameFactory(user=self.user) def test_edit_profile(self): """ Going to the edit_profile view generates a list of existing profile items in the main content section and a list of profile sections that don't have data filled out in the sidebar. """ resp = self.client.get(reverse('view_profile')) soup = BeautifulSoup(resp.content) item_id = Name.objects.all()[0].id # The existing name object should be rendered on the main content # section self.assertIsNotNone( soup.find('tr', id='name-' + str(item_id) + '-item')) # profile-section contains the name of a profile section that has no # information filled out yet and shows up in the sidebar self.assertTrue(soup.findAll('tr', {'class': 'profile-section'})) def test_handle_form_get_new(self): """ Invoking the handle_form view without an id parameter returns an empty form with the correct form id """ resp = self.client.get(reverse('handle_form'), data={'module': 'Name'}) self.assertTemplateUsed(resp, 'myprofile/profile_form.html') soup = BeautifulSoup(resp.content) self.assertEquals(soup.form.attrs['id'], 'profile-unit-form') with self.assertRaises(KeyError): soup.find('input', id='id_name-given_name').attrs['value'] def test_handle_form_get_existing(self): """ Invoking the handle_form view with and id paraemeter returns a form filled out with the corresponding profile/ID combination """ resp = self.client.get(reverse('handle_form'), data={ 'module': 'Name', 'id': self.name.id }) self.assertTemplateUsed(resp, 'myprofile/profile_form.html') soup = BeautifulSoup(resp.content) self.assertEquals(soup.form.attrs['id'], 'profile-unit-form') self.assertEquals( soup.find('input', id='id_name-given_name').attrs['value'], 'Alice') self.assertEquals( soup.find('input', id='id_name-family_name').attrs['value'], 'Smith') self.assertEquals( soup.find('input', id='id_name-primary').attrs['checked'], 'checked') def test_handle_form_post_new_valid(self): """ Invoking the handle_form view as a POST request for a new item creates that object in the database and returns the item snippet to be rendered on the page. """ resp = self.client.post(reverse('handle_form'), data={ 'module': 'Name', 'id': 'new', 'given_name': 'Susy', 'family_name': 'Smith' }) self.assertRedirects(resp, reverse('view_profile')) self.assertEqual( Name.objects.filter(given_name='Susy', family_name='Smith').count(), 1) def test_handle_form_post_invalid(self): """ Invoking the handle_form view as a POST request with an invalid form returns the list of form errors. """ resp = self.client.post(reverse('handle_form'), data={ 'module': 'Name', 'id': 'new', 'given_name': 'Susy' }, HTTP_X_REQUESTED_WITH='XMLHttpRequest') self.assertEqual(json.loads(resp.content), {u'family_name': [u'This field is required.']}) def test_handle_form_post_existing_valid(self): """ Invoking the handle_form view as a POST request for an existing item updates that item and returns the update item snippet. """ resp = self.client.post(reverse('handle_form'), data={ 'module': 'Name', 'id': self.name.id, 'given_name': 'Susy', 'family_name': 'Smith' }) self.assertRedirects(resp, reverse('view_profile')) self.assertEqual( Name.objects.filter(given_name='Susy', family_name='Smith').count(), 1) def test_handle_form_redirect_summary(self): """ When a user has a summary already if they try to make a new summary handle form should redirect the user to edit the summary they already have. User is only allowed one summary per account. """ summary_instance = SummaryFactory(user=self.user) summary_instance.save() resp = self.client.get(reverse('handle_form'), data={'module': 'Summary'}) self.assertRedirects( resp, reverse('handle_form') + '?id=%s&module=Summary' % summary_instance.id) def test_delete_item(self): """ Invoking the delete_item view deletes the item and returns the 'Deleted!' HttpResponse """ resp = self.client.post( reverse('delete_item') + '?item=' + str(self.name.id)) self.assertEqual(resp.content, '') self.assertEqual(Name.objects.filter(id=self.name.id).count(), 0) def test_add_duplicate_primary_email(self): """ Attempting to add a secondary email with a value equal to the user's current primary email results in an error. Due to how the instance is constructed, this validation is form-level rather than model-level. """ resp = self.client.post(reverse('handle_form'), data={ 'module': 'SecondaryEmail', 'id': 'new', 'email': self.user.email }, HTTP_X_REQUESTED_WITH='XMLHttpRequest') self.assertEqual(json.loads(resp.content), {u'email': [u'This email is already registered.']})
class SavedSearchResourceTests(TestCase): def setUp(self): super(SavedSearchResourceTests, self).setUp() self.user = UserFactory() self.client = TestClient() self.data = {'email':'*****@*****.**', 'url':'www.my.jobs/jobs'} create_api_key(User, instance=self.user, created=True) self.credentials = (self.user.email, self.user.api_key.key) self.r = Replacer() self.r.replace('urllib2.urlopen', return_file) def tearDown(self): self.r.restore() def make_response(self, data): """ The tests in this section use the following block of code a lot. This makes it somewhat easier to make modifications if something must change Inputs: :data: dict containing the data to be posted to the saved search api endpoint :credentials: api user's email and api key; used to authenticate the transaction """ url = '/api/v1/savedsearch/' response = self.client.get(url, data) return response def test_new_search_existing_user(self): for data in [('*****@*****.**', 'www.my.jobs/search?q=django'), ('*****@*****.**', 'www.my.jobs/search?q=python')]: self.data['email'] = data[0] self.data['url'] = data[1] self.data['username'] = self.user.email self.data['api_key'] = self.user.api_key.key response = self.make_response(self.data) self.assertEqual(response.status_code, 200) search = SavedSearch.objects.all()[0] self.assertEqual(search.user, self.user) content = json.loads(response.content) self.assertEqual(len(content), 3) self.assertTrue(content['new_search']) self.assertEqual(SavedSearch.objects.filter(user=self.user).count(), 2) self.data['url'] = 'http://www.my.jobs/jobs' response = self.make_response(self.data) for search in SavedSearch.objects.all(): self.assertTrue('www.my.jobs' in search.notes) def test_new_search_new_user(self): self.data['email'] = '*****@*****.**' self.data['username'] = self.user.email self.data['api_key'] = self.user.api_key.key response = self.make_response(self.data) self.assertEqual(response.status_code, 200) self.assertEqual(SavedSearch.objects.count(), 0) self.assertEqual(User.objects.count(), 1) content = json.loads(response.content) self.assertEqual(content['email'], 'No user with email %s exists' % \ self.data['email']) self.assertEqual(len(content), 1) def test_new_search_secondary_email(self): SecondaryEmail.objects.create(user=self.user, email='*****@*****.**') self.data['email'] = '*****@*****.**' self.data['username'] = self.user.email self.data['api_key'] = self.user.api_key.key response = self.make_response(self.data) self.assertEqual(response.status_code, 200) self.assertEqual(SavedSearch.objects.count(), 1) self.assertEqual(User.objects.count(), 1) search = SavedSearch.objects.all()[0] self.assertEqual(search.user, self.user) self.assertEqual(search.email, '*****@*****.**') content = json.loads(response.content) self.assertEqual(len(content), 3) def test_new_search_invalid_url(self): self.data['url'] = 'google.com' self.data['username'] = self.user.email self.data['api_key'] = self.user.api_key.key response = self.make_response(self.data) self.assertEqual(response.status_code, 200) content = json.loads(response.content) self.assertEqual(len(content), 1) self.assertEqual(content['url'], 'This is not a valid .JOBS feed') self.assertEqual(SavedSearch.objects.count(), 0) def test_new_search_no_url(self): del self.data['url'] self.data['username'] = self.user.email self.data['api_key'] = self.user.api_key.key response = self.make_response(self.data) self.assertEqual(response.status_code, 200) content = json.loads(response.content) self.assertEqual(len(content), 1) self.assertEqual(content['url'], 'No .JOBS feed provided') self.assertEqual(SavedSearch.objects.count(), 0) def test_no_email(self): del self.data['email'] self.data['username'] = self.user.email self.data['api_key'] = self.user.api_key.key response = self.make_response(self.data) self.assertEqual(response.status_code, 200) content = json.loads(response.content) self.assertEqual(len(content), 1) self.assertEqual(content['email'], 'No email provided') self.assertEqual(SavedSearch.objects.count(), 0) def test_no_auth(self): response = self.make_response(self.data) self.assertEqual(response.status_code, 401) self.assertEqual(response.content, '') self.assertEqual(SavedSearch.objects.count(), 0) def test_invalid_auth(self): headers = [(self.user.email, 'invalid_key'), ('*****@*****.**', self.user.api_key.key), ('*****@*****.**', 'invalid_key')] for header in headers: self.data['username'] = header[0] self.data['api_key'] = header[1] response = self.make_response(self.data) self.assertEqual(response.status_code, 401) self.assertEqual(response.content, '') self.assertEqual(SavedSearch.objects.count(), 0) def test_existing_search(self): self.data['username'] = self.user.email self.data['api_key'] = self.user.api_key.key response = self.make_response(self.data) self.assertEqual(response.status_code, 200) content = json.loads(response.content) self.assertEqual(content['new_search'], True) for email in [self.user.email, self.user.email.upper()]: self.data['email'] = email response = self.make_response(self.data) content = json.loads(response.content) self.assertEqual(len(content), 3) self.assertFalse(content['new_search']) self.assertEqual(SavedSearch.objects.count(), 1)
class MyProfileViewsTests(TestCase): def setUp(self): super(MyProfileViewsTests, self).setUp() self.user = UserFactory() self.client = TestClient() self.client.login_user(self.user) self.name = PrimaryNameFactory(user=self.user) def test_edit_profile(self): """ Going to the edit_profile view generates a list of existing profile items in the main content section and a list of profile sections that don't have data filled out in the sidebar. """ resp = self.client.get(reverse('view_profile')) soup = BeautifulSoup(resp.content) item_id = Name.objects.all()[0].id # The existing name object should be rendered on the main content # section self.assertIsNotNone(soup.find('tr', id='name-' + str(item_id) + '-item')) # profile-section contains the name of a profile section that has no # information filled out yet and shows up in the sidebar self.assertTrue(soup.findAll('tr', {'class': 'profile-section'})) def test_handle_form_get_new(self): """ Invoking the handle_form view without an id parameter returns an empty form with the correct form id """ resp = self.client.get(reverse('handle_form'), data={'module': 'Name'}) self.assertTemplateUsed(resp, 'myprofile/profile_form.html') soup = BeautifulSoup(resp.content) self.assertEquals(soup.form.attrs['id'], 'profile-unit-form') with self.assertRaises(KeyError): soup.find('input', id='id_name-given_name').attrs['value'] def test_handle_form_get_existing(self): """ Invoking the handle_form view with and id paraemeter returns a form filled out with the corresponding profile/ID combination """ resp = self.client.get(reverse('handle_form'), data={'module': 'Name', 'id': self.name.id}) self.assertTemplateUsed(resp, 'myprofile/profile_form.html') soup = BeautifulSoup(resp.content) self.assertEquals(soup.form.attrs['id'], 'profile-unit-form') self.assertEquals(soup.find('input', id='id_name-given_name') .attrs['value'], 'Alice') self.assertEquals(soup.find('input', id='id_name-family_name') .attrs['value'], 'Smith') self.assertEquals(soup.find('input', id='id_name-primary') .attrs['checked'], 'checked') def test_handle_form_post_new_valid(self): """ Invoking the handle_form view as a POST request for a new item creates that object in the database and returns the item snippet to be rendered on the page. """ resp = self.client.post(reverse('handle_form'), data={'module': 'Name', 'id': 'new', 'given_name': 'Susy', 'family_name': 'Smith'}) self.assertRedirects(resp, reverse('view_profile')) self.assertEqual(Name.objects.filter(given_name='Susy', family_name='Smith').count(), 1) def test_handle_form_post_invalid(self): """ Invoking the handle_form view as a POST request with an invalid form returns the list of form errors. """ resp = self.client.post(reverse('handle_form'), data={'module': 'Name', 'id': 'new', 'given_name': 'Susy'}, HTTP_X_REQUESTED_WITH='XMLHttpRequest') self.assertEqual(json.loads(resp.content), {u'family_name': [u'This field is required.']}) def test_handle_form_post_existing_valid(self): """ Invoking the handle_form view as a POST request for an existing item updates that item and returns the update item snippet. """ resp = self.client.post(reverse('handle_form'), data={'module': 'Name', 'id': self.name.id, 'given_name': 'Susy', 'family_name': 'Smith'}) self.assertRedirects(resp, reverse('view_profile')) self.assertEqual(Name.objects.filter(given_name='Susy', family_name='Smith').count(), 1) def test_handle_form_redirect_summary(self): """ When a user has a summary already if they try to make a new summary handle form should redirect the user to edit the summary they already have. User is only allowed one summary per account. """ summary_instance = SummaryFactory(user=self.user) summary_instance.save() resp = self.client.get(reverse('handle_form'), data={'module': 'Summary'}) self.assertRedirects(resp, reverse( 'handle_form')+'?id=%s&module=Summary' % summary_instance.id) def test_delete_item(self): """ Invoking the delete_item view deletes the item and returns the 'Deleted!' HttpResponse """ resp = self.client.post(reverse('delete_item')+'?item='+str(self.name.id)) self.assertEqual(resp.content, '') self.assertEqual(Name.objects.filter(id=self.name.id).count(), 0) def test_add_duplicate_primary_email(self): """ Attempting to add a secondary email with a value equal to the user's current primary email results in an error. Due to how the instance is constructed, this validation is form-level rather than model-level. """ resp = self.client.post(reverse('handle_form'), data={'module': 'SecondaryEmail', 'id': 'new', 'email': self.user.email}, HTTP_X_REQUESTED_WITH='XMLHttpRequest') self.assertEqual(json.loads(resp.content), {u'email': [u'This email is already registered.']})
class RegistrationViewTests(TestCase): """ Test the registration views. """ def setUp(self): """ These tests use the default backend, since we know it's available; that needs to have ``ACCOUNT_ACTIVATION_DAYS`` set. """ super(RegistrationViewTests, self).setUp() self.client = TestClient() self.old_activation = getattr(settings, 'ACCOUNT_ACTIVATION_DAYS', None) if self.old_activation is None: settings.ACCOUNT_ACTIVATION_DAYS = 7 # pragma: no cover self.data = {'email': '*****@*****.**', 'password1': 'swordfish', 'password2': 'swordfish', 'action': 'register'} self.client.post(reverse('home'), data=self.data) self.user = User.objects.get(email=self.data['email']) def test_valid_activation(self): """ Test that the ``activate`` view properly handles a valid activation (in this case, based on the default backend's activation window). """ profile = ActivationProfile.objects.get(user__email=self.user.email) response = self.client.get(reverse('registration_activate', args=[profile.activation_key])) self.assertEqual(response.status_code, 200) self.failUnless(User.objects.get(email=self.user.email).is_active) def test_anonymous_activation(self): """ Test that the ``activate`` view properly handles activation when the user to be activated is not currently logged in. """ self.client.post(reverse('auth_logout')) profile = ActivationProfile.objects.get(user__email=self.user.email) response = self.client.get(reverse('registration_activate', args=[profile.activation_key]) + '?verify-email=%s' % self.user.email) self.assertEqual(response.status_code, 200) self.assertContains(response, self.data['email']) def test_invalid_activation(self): """ Test that the ``activate`` view properly handles an invalid activation (in this case, based on the default backend's activation window). """ expired_profile = ActivationProfile.objects.get(user=self.user) expired_profile.sent -= datetime.timedelta( days=settings.ACCOUNT_ACTIVATION_DAYS) expired_profile.save() response = self.client.get(reverse('registration_activate', args=[expired_profile.activation_key])) self.assertEqual(response.status_code, 200) self.assertNotEqual(response.context['activated'], expired_profile.activation_key_expired()) self.failIf(User.objects.get(email=self.user.email).is_active) def test_resend_activation(self): x, created = User.objects.create_inactive_user( **{'email': '*****@*****.**', 'password1': 'secret'}) self.client.login_user(x) self.assertEqual(len(mail.outbox), 1) resp = self.client.get(reverse('resend_activation')) self.assertEqual(resp.status_code, 200) # one email sent for creating an inactive user, another one for resend self.assertEqual(len(mail.outbox), 2) def test_resend_activation_with_secondary_emails(self): user, created = User.objects.create_inactive_user( **{'email': '*****@*****.**', 'password1': 'secret'}) self.assertEqual(ActivationProfile.objects.count(), 1) self.client.login_user(user) self.client.get(reverse('resend_activation')) self.assertEqual(len(mail.outbox), 2) SecondaryEmail.objects.create(user=user, email='*****@*****.**') self.assertEqual(len(mail.outbox), 3) self.assertEqual(ActivationProfile.objects.count(), 2) self.client.get(reverse('resend_activation')) self.assertEqual(len(mail.outbox), 4)
class RegistrationViewTests(TestCase): """ Test the registration views. """ def setUp(self): """ These tests use the default backend, since we know it's available; that needs to have ``ACCOUNT_ACTIVATION_DAYS`` set. """ super(RegistrationViewTests, self).setUp() self.client = TestClient() self.old_activation = getattr(settings, 'ACCOUNT_ACTIVATION_DAYS', None) if self.old_activation is None: settings.ACCOUNT_ACTIVATION_DAYS = 7 # pragma: no cover self.data = { 'email': '*****@*****.**', 'password1': 'swordfish', 'password2': 'swordfish', 'action': 'register' } self.client.post(reverse('home'), data=self.data) self.user = User.objects.get(email=self.data['email']) def test_valid_activation(self): """ Test that the ``activate`` view properly handles a valid activation (in this case, based on the default backend's activation window). """ profile = ActivationProfile.objects.get(user__email=self.user.email) response = self.client.get( reverse('registration_activate', args=[profile.activation_key])) self.assertEqual(response.status_code, 200) self.failUnless(User.objects.get(email=self.user.email).is_active) def test_anonymous_activation(self): """ Test that the ``activate`` view properly handles activation when the user to be activated is not currently logged in. """ self.client.post(reverse('auth_logout')) profile = ActivationProfile.objects.get(user__email=self.user.email) response = self.client.get( reverse('registration_activate', args=[profile.activation_key]) + '?verify-email=%s' % self.user.email) self.assertEqual(response.status_code, 200) self.assertContains(response, self.data['email']) def test_invalid_activation(self): """ Test that the ``activate`` view properly handles an invalid activation (in this case, based on the default backend's activation window). """ expired_profile = ActivationProfile.objects.get(user=self.user) expired_profile.sent -= datetime.timedelta( days=settings.ACCOUNT_ACTIVATION_DAYS) expired_profile.save() response = self.client.get( reverse('registration_activate', args=[expired_profile.activation_key])) self.assertEqual(response.status_code, 200) self.assertNotEqual(response.context['activated'], expired_profile.activation_key_expired()) self.failIf(User.objects.get(email=self.user.email).is_active) def test_resend_activation(self): x, created = User.objects.create_inactive_user(**{ 'email': '*****@*****.**', 'password1': 'secret' }) self.client.login_user(x) self.assertEqual(len(mail.outbox), 1) resp = self.client.get(reverse('resend_activation')) self.assertEqual(resp.status_code, 200) # one email sent for creating an inactive user, another one for resend self.assertEqual(len(mail.outbox), 2) def test_resend_activation_with_secondary_emails(self): user, created = User.objects.create_inactive_user(**{ 'email': '*****@*****.**', 'password1': 'secret' }) self.assertEqual(ActivationProfile.objects.count(), 1) self.client.login_user(user) self.client.get(reverse('resend_activation')) self.assertEqual(len(mail.outbox), 2) SecondaryEmail.objects.create(user=user, email='*****@*****.**') self.assertEqual(len(mail.outbox), 3) self.assertEqual(ActivationProfile.objects.count(), 2) self.client.get(reverse('resend_activation')) self.assertEqual(len(mail.outbox), 4)
class AccountFormTests(TestCase): def setUp(self): self.user = UserFactory() self.name = PrimaryNameFactory(user=self.user) self.client = TestClient() def test_password_form(self): invalid_data = [ { 'data': { 'password': '******', 'new_password1': 'newpassword', 'new_password2': 'newpassword' }, u'errors': [['password', [u"Wrong password."]]] }, { 'data': { 'password': '******', 'new_password1': 'newpassword', 'new_password2': 'notnewpassword' }, u'errors': [[ u'new_password2', [u'The new password fields did not match.'] ], [ u'new_password1', [u'The new password fields did not match.'] ]], }, ] for item in invalid_data: form = ChangePasswordForm(user=self.user, data=item['data']) self.failIf(form.is_valid()) self.assertEqual(form.errors[item[u'errors'][0][0]], item[u'errors'][0][1]) form = ChangePasswordForm(user=self.user, data={ 'password': '******', 'new_password1': 'anothersecret', 'new_password2': 'anothersecret' }) self.failUnless(form.is_valid()) form.save() self.failUnless(self.user.check_password('anothersecret')) def test_no_name_account_form(self): """ Leaving both the first and last name fields blank produces a valid save. It also deletes the primary name object from the Name model. """ data = {"gravatar": "*****@*****.**", "user": self.user} form = EditAccountForm(data, **{'user': self.user}) self.assertTrue(form.is_valid()) form.save(self.user) self.assertEqual(Name.objects.count(), 0) def test_both_names_account_form(self): """ Filling out both name fields produces a valid save. """ data = { "given_name": "Alicia", "family_name": "Smith", "gravatar": "*****@*****.**" } form = EditAccountForm(data, **{'user': self.user}) self.assertTrue(form.is_valid()) def test_partial_name_account_form(self): """ Filling out only the first name or only the last name produces an error. """ data = { "given_name": "Alicia", "gravatar": "*****@*****.**", "user": self.user } form = EditAccountForm(data, **{'user': self.user}) self.assertFalse(form.is_valid()) self.assertEqual(form.errors['family_name'][0], "Both a first and last name required.") def test_gravatar_email_list(self): """ Dropdowns for selecting the user's preferred Gravatar email should be the only dropdowns that include "Do not use Gravatar" as an option - others should default to the user's primary email address. """ self.client.login_user(self.user) response = self.client.get(reverse('edit_communication')) soup = BeautifulSoup(response.content) options = soup.select('#id_digest_email option') self.assertEqual(len(options), 1) self.assertTrue(self.user.gravatar in options[0]) response = self.client.get(reverse('edit_basic')) soup = BeautifulSoup(response.content) options = soup.select('#id_gravatar option') self.assertEqual(len(options), 2) self.assertTrue('Do not use Gravatar' in options[0]) self.assertTrue(self.user.gravatar in options[1])
class MyDashboardViewsTests(TestCase): def setUp(self): self.staff_user = UserFactory() group = Group.objects.get(name=CompanyUser.GROUP_NAME) self.staff_user.groups.add(group) self.staff_user.save() self.company = CompanyFactory() self.company.save() self.admin = CompanyUserFactory(user=self.staff_user, company=self.company) self.admin.save() self.microsite = MicrositeFactory(company=self.company) self.microsite.save() self.client = TestClient() self.client.login_user(self.staff_user) self.candidate_user = UserFactory(email="*****@*****.**") SavedSearchFactory(user=self.candidate_user, url='http://test.jobs/search?q=django', label='test Jobs') self.candidate_user.save() for i in range(5): # Create 5 new users user = UserFactory(email='*****@*****.**' % i) for search in SEARCH_OPTS: # Create 15 new searches and assign three per user SavedSearchFactory(user=user, url='http://test.jobs/search?q=%s' % search, label='%s Jobs' % search) def test_number_of_searches_and_users_is_correct(self): response = self.client.post( reverse('dashboard')+'?company='+str(self.company.id), {'microsite': 'test.jobs'}) soup = BeautifulSoup(response.content) # 10 searches total, two rows per search self.assertEqual(len(soup.select('#row-link-table tr')), 20) old_search = SavedSearch.objects.all()[0] old_search.created_on -= timedelta(days=31) old_search.save() response = self.client.post( reverse('dashboard')+'?company='+str(self.company.id), {'microsite': 'test.jobs'}) soup = BeautifulSoup(response.content) self.assertEqual(len(soup.select('#row-link-table tr')), 20) # Tests to see if redirect from /candidates/ goes to candidates/view/ def test_redirect_to_candidates_views_default_page(self): response = self.client.post('/candidates/') # response returns HttpResponsePermanentRedirect which returns a 301 # status code instead of the normal 302 redirect status code self.assertRedirects(response, '/candidates/view/', status_code=301, target_status_code=200) response = self.client.post(reverse('dashboard')) self.assertEqual(response.status_code, 200) soup = BeautifulSoup(response.content) company_name = soup.find('h1') company_name = company_name.next self.assertEqual(company_name, self.company.name) # Eventually these opted-in/out will be changed to # track if user is part of company's activity feed def test_candidate_has_opted_in(self): response = self.client.post( reverse('candidate_information', )+'?company='+str(self.company.id)+'&user='******'candidate_information', )+'?company='+str(self.company.id)+'&user='******'candidate_information', )+'?company='+str(self.company.id)+'&user='******'div', {'id': 'candidate-content'}).findAll( 'a', {'class': 'accordion-toggle'}) info = soup.find('div', {'id': 'candidate-content'}).findAll('li') self.assertEqual(len(titles), 6) self.assertEqual(len(info), 16) self.assertEqual(response.status_code, 200) def test_candidate_page_load_without_profileunits_with_activites(self): response = self.client.post( reverse('candidate_information', )+'?company='+str(self.company.id)+'&user='******'div', {'id': 'candidate-content'}).findAll( 'a', {'class': 'accordion-toggle'}) info = soup.find('div', {'id': 'candidate-content'}).findAll('li') self.assertEqual(len(titles), 1) self.assertEqual(len(info), 3) self.assertEqual(response.status_code, 200) def test_candidate_page_load_without_profileunits_and_activites(self): saved_search = SavedSearch.objects.get(user=self.candidate_user) saved_search.delete() response = self.client.post( reverse('candidate_information', )+'?company='+str(self.company.id)+'&user='******'div', {'id': 'candidate-content'}) self.assertFalse(info) self.assertEqual(response.status_code, 404) def test_export_csv(self): response = self.client.post( reverse('export_candidates')+'?company=' + str(self.company.id)+'&ex-t=csv') self.assertTrue(response.content) self.assertEqual(response.status_code, 200) def test_export_pdf(self): response = self.client.post( reverse('export_candidates')+'?company=' + str(self.company.id)+'&ex-t=pdf') self.assertTrue(response.content.index('PDF')) self.assertEqual(response.templates[0].name, 'mydashboard/export/candidate_listing.html') self.assertEqual(response.status_code, 200) def test_export_xml(self): response = self.client.post( reverse('export_candidates')+'?company=' + str(self.company.id)+'&ex-t=xml') self.assertTrue(response.content.index('candidates')) self.assertEqual(response.status_code, 200) def test_export_json(self): response = self.client.post( reverse('export_candidates')+'?company=' + str(self.company.id)+'&ex-t=json') self.assertTrue(response.content.index('candidates')) self.assertEqual(response.status_code, 200)
def setUp(self): super(MyProfileViewsTests, self).setUp() self.user = UserFactory() self.client = TestClient() self.client.login_user(self.user) self.name = PrimaryNameFactory(user=self.user)
class MySignOn(TestCase): def setUp(self): self.user = UserFactory() self.auth_callback_url = 'https://secure.my.jobs/account' self.auth_callback = '?auth_callback=%s' % self.auth_callback_url self.key_qs = '%s&key=%s' self.client = TestClient() self.client.login_user(self.user) def test_anonymous_auth(self): """ Anonymous users must first login before being redirected. This redirection happens automatically if JavaScript is disabled. JSON is returned and the redirect takes place via JavaScript otherwise. """ login_data = {'username': self.user.email, 'password': '******', 'auth_callback': self.auth_callback_url, 'action': 'login'} self.client.logout() self.assertEqual(AuthorizedClient.objects.count(), 0) self.assertTrue(self.client.session.get('key') is None) response = self.client.post(reverse('sso_authorize'), login_data) self.assertEqual(AuthorizedClient.objects.count(), 1) self.assertTrue(self.client.session.get('key') is not None) self.assertEqual(response.get('Location'), self.auth_callback_url + '?key=%s' % self.client.session.get('key')) self.client.logout() response = self.client.post(reverse('sso_authorize'), login_data, HTTP_X_REQUESTED_WITH='XMLHttpRequest') content = json.loads(response.content) self.assertEqual(content['url'], self.auth_callback_url + '?key=%s' % self.client.session['key']) def test_authenticated_auth(self): """ Users who are already logged in can simply click a button to authorize a given site and are then redirected to the given callback url. If a given user has already authorized a given site and that site provides the key that it was given, this redirect is automatic. """ self.assertEqual(AuthorizedClient.objects.count(), 0) self.assertTrue(self.client.session.get('key') is None) response = self.client.post(reverse('sso_authorize'), {'auth_callback': self.auth_callback_url, 'action': 'authorize'}) self.assertEqual(self.user.authorizedclient_set.count(), 1) self.assertTrue(self.client.session.get('key') is not None) self.assertEqual(response.get('Location'), self.auth_callback_url + '?key=%s' % self.client.session.get('key')) good_qs = self.key_qs % (self.auth_callback, self.client.session.get('key')) response = self.client.get(reverse('sso_authorize') + good_qs) self.assertEqual(response.get('Location'), self.auth_callback_url + '?key=%s' % self.client.session.get('key')) def test_bad_key(self): """ Providing a bad key will always cause the user to have to log back into their account. Bad keys are defined as providing a key that doesn't match the user's current key or providing a key when the user doesn't currently have a key defined. """ # no key no_key = self.key_qs % (self.auth_callback, AuthorizedClient.create_key(self.user)) response = self.client.get(reverse('sso_authorize') + no_key) self.assertEqual(AuthorizedClient.objects.count(), 0) # Ensure that user was logged out response = self.client.get(reverse('view_profile')) path = response.request.get('PATH_INFO') self.assertRedirects(response, reverse('home')+'?next='+path) # wrong key self.client.login_user(self.user) session = self.client.session session['key'] = AuthorizedClient.create_key(self.user) session.save() # key is a hex string; we can invalidate it by taking a substring wrong_key = self.key_qs % (self.auth_callback, AuthorizedClient.create_key(self.user)[:-1]) AuthorizedClientFactory(user=self.user) response = self.client.get(reverse('sso_authorize') + wrong_key) # Ensure that user was logged out again response = self.client.get(reverse('view_profile')) path = response.request.get('PATH_INFO') self.assertRedirects(response, reverse('home')+'?next='+path)
class MyDashboardViewsTests(TestCase): def setUp(self): self.staff_user = UserFactory() group = Group.objects.get(name=CompanyUser.GROUP_NAME) self.staff_user.groups.add(group) self.staff_user.save() self.company = CompanyFactory() self.company.save() self.admin = CompanyUserFactory(user=self.staff_user, company=self.company) self.admin.save() self.microsite = MicrositeFactory(company=self.company) self.microsite.save() self.client = TestClient() self.client.login_user(self.staff_user) self.candidate_user = UserFactory(email="*****@*****.**") SavedSearchFactory(user=self.candidate_user, url='http://test.jobs/search?q=django', label='test Jobs') self.candidate_user.save() for i in range(5): # Create 5 new users user = UserFactory(email='*****@*****.**' % i) for search in SEARCH_OPTS: # Create 15 new searches and assign three per user SavedSearchFactory(user=user, url='http://test.jobs/search?q=%s' % search, label='%s Jobs' % search) def test_number_of_searches_and_users_is_correct(self): response = self.client.post( reverse('dashboard') + '?company=' + str(self.company.id), {'microsite': 'test.jobs'}) soup = BeautifulSoup(response.content) # 10 searches total, two rows per search self.assertEqual(len(soup.select('#row-link-table tr')), 20) old_search = SavedSearch.objects.all()[0] old_search.created_on -= timedelta(days=31) old_search.save() response = self.client.post( reverse('dashboard') + '?company=' + str(self.company.id), {'microsite': 'test.jobs'}) soup = BeautifulSoup(response.content) self.assertEqual(len(soup.select('#row-link-table tr')), 20) # Tests to see if redirect from /candidates/ goes to candidates/view/ def test_redirect_to_candidates_views_default_page(self): response = self.client.post('/candidates/') # response returns HttpResponsePermanentRedirect which returns a 301 # status code instead of the normal 302 redirect status code self.assertRedirects(response, '/candidates/view/', status_code=301, target_status_code=200) response = self.client.post(reverse('dashboard')) self.assertEqual(response.status_code, 200) soup = BeautifulSoup(response.content) company_name = soup.find('h1') company_name = company_name.next self.assertEqual(company_name, self.company.name) # Eventually these opted-in/out will be changed to # track if user is part of company's activity feed def test_candidate_has_opted_in(self): response = self.client.post( reverse('candidate_information', ) + '?company=' + str(self.company.id) + '&user='******'candidate_information', ) + '?company=' + str(self.company.id) + '&user='******'candidate_information', ) + '?company=' + str(self.company.id) + '&user='******'div', { 'id': 'candidate-content' }).findAll('a', {'class': 'accordion-toggle'}) info = soup.find('div', {'id': 'candidate-content'}).findAll('li') self.assertEqual(len(titles), 6) self.assertEqual(len(info), 16) self.assertEqual(response.status_code, 200) def test_candidate_page_load_without_profileunits_with_activites(self): response = self.client.post( reverse('candidate_information', ) + '?company=' + str(self.company.id) + '&user='******'div', { 'id': 'candidate-content' }).findAll('a', {'class': 'accordion-toggle'}) info = soup.find('div', {'id': 'candidate-content'}).findAll('li') self.assertEqual(len(titles), 1) self.assertEqual(len(info), 3) self.assertEqual(response.status_code, 200) def test_candidate_page_load_without_profileunits_and_activites(self): saved_search = SavedSearch.objects.get(user=self.candidate_user) saved_search.delete() response = self.client.post( reverse('candidate_information', ) + '?company=' + str(self.company.id) + '&user='******'div', {'id': 'candidate-content'}) self.assertFalse(info) self.assertEqual(response.status_code, 404) def test_export_csv(self): response = self.client.post( reverse('export_candidates') + '?company=' + str(self.company.id) + '&ex-t=csv') self.assertTrue(response.content) self.assertEqual(response.status_code, 200) def test_export_pdf(self): response = self.client.post( reverse('export_candidates') + '?company=' + str(self.company.id) + '&ex-t=pdf') self.assertTrue(response.content.index('PDF')) self.assertEqual(response.templates[0].name, 'mydashboard/export/candidate_listing.html') self.assertEqual(response.status_code, 200) def test_export_xml(self): response = self.client.post( reverse('export_candidates') + '?company=' + str(self.company.id) + '&ex-t=xml') self.assertTrue(response.content.index('candidates')) self.assertEqual(response.status_code, 200) def test_export_json(self): response = self.client.post( reverse('export_candidates') + '?company=' + str(self.company.id) + '&ex-t=json') self.assertTrue(response.content.index('candidates')) self.assertEqual(response.status_code, 200)