class CurrentRusheesTestCase(TenantTestCase): """ tests for the current rushees page """ def setUp(self): self.client = TenantClient(self.tenant) self.user = User.objects.create(username="******") self.client.force_login(self.user) self.rushee1 = Rushee.objects.create(name="first_rushee") self.rushee2 = Rushee.objects.create(name="second_rushee", cut=True) self.rushee3 = Rushee.objects.create(name="third_rushee") def test_current_rushees_template(self): """ tests that current rushees page displays with all rushees """ path = reverse('rush:current_rushees') response = self.client.post(path) self.assertContains( response, "<tr onclick=\"window.location='rushee" + str(self.rushee1.pk)) self.assertNotContains( response, "<tr onclick=\"window.location='rushee" + str(self.rushee2.pk)) self.assertContains( response, "<tr onclick=\"window.location='rushee" + str(self.rushee3.pk)) def test_current_rushees_with_filter(self): """ tests current rushees page with filter set """ session = self.client.session session['rushee_filter'] = dict(name='first') session.save() path = reverse('rush:current_rushees') response = self.client.post(path) self.assertContains( response, "<tr onclick=\"window.location='rushee" + str(self.rushee1.pk)) self.assertNotContains( response, "<tr onclick=\"window.location='rushee" + str(self.rushee2.pk)) self.assertNotContains( response, "<tr onclick=\"window.location='rushee" + str(self.rushee3.pk)) def test_current_rushees_with_cut(self): """ tests current rushees with cut filter set """ session = self.client.session session['rushee_filter'] = dict(cut=True) session.save() path = reverse('rush:current_rushees') response = self.client.post(path) self.assertContains( response, "<tr onclick=\"window.location='rushee" + str(self.rushee1.pk)) self.assertContains( response, "<tr onclick=\"window.location='rushee" + str(self.rushee2.pk)) self.assertContains( response, "<tr onclick=\"window.location='rushee" + str(self.rushee3.pk))
class BaseTenantTestCase(TenantTestCase): def setUp(self): self.client = TenantClient(self.tenant) self.user = mommy.make('auth.User', email='*****@*****.**') self.user.set_password('123456') self.user.save() self.client.post(reverse_lazy('tenant:login'), {'email': self.user.email, 'password': '******'}) mommy.make('provarme_dashboard.Setup', tx_shopify=1, tx_gateway=1, tx_antecipation=1, tx_tax=1, tx_iof=1, tx_cashback=1,)
class AuthenticationTestCase(TenantTestCase): def setUp(self): self.client = TenantClient(self.tenant) self.u = User.objects.create(username="******", is_superuser=True) self.client.force_login(self.u) # tests that logged in user can logout def test_logout_redirects_to_login(self): path = reverse('logout') response = self.client.post(path, follow=True) self.assertContains(response, 'Login') # gets template with signup form def test_signup_get_template(self): path = reverse('signup') response = self.client.get(path) self.assertContains(response, "Register") # tests that inactive users can activate with activate view def test_activate_view(self): user = User.objects.create(username="******", is_active="False") token = account_activation_token.make_token(user) path = reverse('activate', kwargs=dict(user_id=user.pk, token=token)) response = self.client.post(path) self.assertContains(response, "Your account has been verified!") # tests user that does not exist def test_activate_user_does_not_exist(self): user = User.objects.create(username="******", is_active="False") token = account_activation_token.make_token(user) path = reverse('activate', kwargs=dict(user_id=user.pk, token=token)) user.delete() response = self.client.post(path) self.assertContains(response, "Activation link is invalid") # tests invalid activation token def test_activate_user_invalid_token(self): user = User.objects.create(username="******", is_active="False") token = "999-99999999999999999999" path = reverse('activate', kwargs=dict(user_id=user.pk, token=token)) response = self.client.post(path) self.assertContains(response, "Activation link is invalid") # tests logout def test_logout(self): user = User.objects.create(username="******") self.client.force_login(user) path = reverse('logout') response = self.client.post(path, follow=True) self.assertContains(response, "Login")
def test_bulk_post_participation(self) -> None: self.set_tenant(0) user = self.users[0] first_contact = Contact.objects.create(email='*****@*****.**', first_name='First', last_name='Smith') second_contact = Contact.objects.create(email='*****@*****.**', first_name='Second', last_name='Smith') campaign = Campaign.objects.create(name='cool campaign', owner=user) t_client = TenantClient(self.get_current_tenant()) t_client.handler = ForceAuthClientHandler(enforce_csrf_checks=False) t_client.handler._force_user = user self.assertTrue(t_client.login(username=user.username, password='******'), 'Test user was not logged in') url = reverse.reverse('api:campaigns-contacts-list', args=[campaign.pk, ]) with modify_settings(ALLOWED_HOSTS={'append': self.get_current_tenant().domain_url}): response = t_client.post(url, json.dumps([ dict(contact=first_contact.id), dict(contact=second_contact.id), ]), content_type='application/json', ) self.assertEqual(response.status_code, status.HTTP_201_CREATED, str(response.content)) self.assertEqual(2, Participation.objects.filter( campaign=campaign, contact_id__in=(first_contact.id, second_contact.id,), ).count()) contacts = campaign.contacts.all() self.assertListEqual([first_contact, second_contact, ], list(contacts))
def test_email_stage_template_validation(self) -> None: self.set_tenant(0) user = self.users[0] campaign = Campaign.objects.create(name='some campaign', owner=user) step = Step.objects.create(campaign=campaign, start=datetime.time(9, 45), end=datetime.time(18, 30)) t_client = TenantClient(self.get_current_tenant()) t_client.handler = ForceAuthClientHandler(enforce_csrf_checks=False) t_client.handler._force_user = user self.assertTrue(t_client.login(username=user.username, password='******'), 'Test user was not logged in') url = reverse.reverse('api:campaigns-steps-email-list', args=[campaign.pk, step.pk, ]) with modify_settings(ALLOWED_HOSTS={'append': self.get_current_tenant().domain_url}): response = t_client.post(url, json.dumps(dict( subject='Hello good fellow', html_content='Some invalid email template to {{First name}}!', )), content_type='application/json', ) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST, str(response.content)) error_data = response.data self.assertTrue("Could not parse" in error_data['html_content'][0])
class RusheeRegisterTestCase(TenantTestCase): """ tests rushee register function """ def setUp(self): self.client = TenantClient(self.tenant) self.user = User.objects.create(username="******") self.client.force_login(self.user) self.event = RushEvent.objects.create(name='test_event', date='2001-01-01', time='00:00:00', round=1, new_rushees_allowed=True) self.form_data = { 'name': 'test_name', 'email': '*****@*****.**', 'year': '1', 'major': 'test_major', 'hometown': 'test_hometown', 'address': 'test_address', 'phone_number': '9999999999', 'in_person': True } def test_valid_form_register(self): """ tests register function when form is valid """ post_data = self.form_data self.assertTrue(RusheeForm(post_data).is_valid()) path = reverse('rush:register', kwargs=dict(event_id=self.event.pk)) self.client.post(path, post_data) self.assertTrue(Rushee.objects.get(name="test_name")) def test_invalid_form_register(self): """ tests register function when form is invalid """ post_data = self.form_data post_data['email'] = 'invalid email' form = RusheeForm(data=post_data) path = reverse('rush:register', kwargs=dict(event_id=self.event.pk)) response = self.client.post(path, post_data) test_response = HttpResponse(form.errors.as_data()) self.assertEqual(response.content, test_response.content) try: Rushee.objects.get(name='test_name') self.fail("Rushee was created when it shouldn't have been.") except Rushee.DoesNotExist: pass
class CustomSignUpFormTest(TenantTestCase): def setUp(self): pass def test_init(self): CustomSignupForm() def test_valid_data(self): form = CustomSignupForm({ 'username': "******", 'first_name': "firsttest", 'last_name': "Lasttest", 'access_code': "314159", 'password1': "password", 'password2': "password" }) self.assertTrue(form.is_valid()) def test_bad_access_codecoverage(self): """ Test that a sign up form with the wrong access code doesn't validate """ form = CustomSignupForm({ 'username': "******", 'first_name': "firsttest", 'last_name': "Lasttest", 'access_code': "wrongcode", 'password1': "password", 'password2': "password" }) self.assertFalse(form.is_valid()) with self.assertRaisesMessage(forms.ValidationError, "Access code unrecognized."): form.clean() def test_sign_up_via_post(self): self.client = TenantClient(self.tenant) form_data = { 'username': "******", 'first_name': "firsttest", 'last_name': "Lasttest", 'access_code': "314159", 'password1': "password", 'password2': "password" } response = self.client.post( reverse('account_signup'), form_data, follow=True, ) self.assertRedirects(response, reverse('quests:quests')) user = User.objects.get(username="******") self.assertEqual(user.first_name, "firsttest")
class ResourcesTestCaseRegular(TenantTestCase): def setUp(self): self.client = TenantClient(self.tenant) self.regular = User.objects.create(username="******") self.client.force_login(self.regular) self.path = reverse('resources') self.response = self.client.post(self.path) # tests that resources page exists with proper header def test_resources_page_exists(self): self.assertEqual(self.response.status_code, 200) self.assertContains(self.response, "Resources") # tests that admin options do not appear for users without admin privileges def test_regular_users(self): self.assertNotContains(self.response, "No Google Calendar loaded!") self.assertNotContains(self.response, "Upload File") self.assertNotContains(self.response, "Add link") self.assertNotContains(self.response, "modal")
class ResourcesAdminTestCase(TenantTestCase): def setUp(self): self.client = TenantClient(self.tenant) self.admin = User.objects.create(username="******", is_superuser=True, is_staff=True) self.client.force_login(self.admin) # tests that all admin options appear on the resources page def test_admin_controls(self): settings = getSettings() settings.calendar_embed = 'cal_link_here' settings.save() path = reverse('resources') response = self.client.post(path) self.assertContains(response, "Upload File") self.assertContains(response, "Add Link") self.assertContains(response, "modal") # tests resource file upload form def test_file_upload(self): file = SimpleUploadedFile("file.txt", b"file_content", content_type="text/plain") post_dict = {'name': 'filename', 'description': 'file description'} file_dict = {'file': file} form = UploadFileForm(post_dict, file_dict) self.assertTrue(form.is_valid()) # tests resource file upload function def test_file_upload_view(self): file = SimpleUploadedFile("file.txt", b"file_content", content_type="text/plain") post_dict = { 'name': 'filename', 'file': file, 'description': 'file description' } path = reverse('upload_file') response = self.client.post(path, post_dict, follow=True) self.assertContains(response, 'filename') # cleanup: need to delete the file or it stays forever ResourceFile.objects.get(pk=1).file.delete() # tests error messages in file upload form def test_file_upload_errors(self): post_dict = {'name': 'filename', 'description': 'file description'} path = reverse('upload_file') response = self.client.post(path, post_dict) self.assertContains(response, b'file') # tests remove file function def test_remove_file(self): file = SimpleUploadedFile("file.txt", b"file_content", content_type="text/plain") post_dict = { 'name': 'filename', 'file': file, 'description': 'file description' } path = reverse('upload_file') response = self.client.post(path, post_dict, follow=True) self.assertContains(response, 'filename') file_object = ResourceFile.objects.get(name='filename') path = reverse('remove_file', kwargs=dict(file_id=file_object.pk)) response = self.client.post(path, follow=True) self.assertContains(response, 'filename', count=1) # tests the add calendar function def test_add_calendar(self): path = reverse('addCal') post_dict = {'cal_embed_link': 'hyperlink'} response = self.client.post(path, post_dict, follow=True) settings = getSettings() self.assertEqual(settings.calendar_embed, 'hyperlink') # tests the remove calendar function def test_remove_calendar(self): settings = getSettings() settings.calendar_embed = 'hyperlink' settings.save() path = reverse('removeCal') response = self.client.post(path) settings.refresh_from_db() self.assertEqual(settings.calendar_embed, '') # tests the add_link views.py function def test_add_link_view(self): post_dict = { 'name': 'test', 'description': 'test description', 'url': 'https://www.google.com' } path = reverse('add_link') referer = reverse('resources') response = self.client.post(path, post_dict, HTTP_REFERER=referer, follow=True) self.assertContains(response, '<a href="https://www.google.com"') # tests the link form def test_add_link_form_valid(self): form_data = { 'name': 'test', 'description': 'test description', 'url': 'https://www.google.com' } form = LinkForm(data=form_data) self.assertTrue(form.is_valid) # tests when the link form is invalid def test_add_link_form_invalid(self): form_data = {} form = LinkForm(data=form_data) self.assertFalse(form.is_valid()) # tests that errors are returned when link form is invalid def test_add_link_form_errors(self): post_dict = {} path = reverse('add_link') response = self.client.post(path, post_dict) self.assertContains(response, 'nameurldescription') # tests remove link function def test_remove_link(self): ResourceLink.objects.create(name='test', description='test description', url='https://www.google.com') link_object = ResourceLink.objects.get(name='test') path = reverse('remove_link', kwargs=dict(link_id=link_object.pk)) referer = reverse('resources') response = self.client.post(path, HTTP_REFERER=referer, follow=True) self.assertFalse(ResourceLink.objects.all()) self.assertFalse(re.findall("<h4.*test</h4", str(response.content)))
class DeleteChapterEventsTestCase(TenantTestCase): """ tests deleting Chapter Events, both singularly and recursively """ def setUp(self): self.client = TenantClient(self.tenant) self.user = User.objects.create(username="******", is_superuser=True, is_staff=True) self.client.force_login(self.user) self.singular = ChapterEvent.objects.create_chapter_event( name="singular event", date=datetime.strptime("2020-07-20", "%Y-%m-%d").date(), time=datetime.now(), is_public=False, location="test") self.recurring = ChapterEvent.objects.create_chapter_event( name="recurring event", date=datetime.strptime("2020-07-20", "%Y-%m-%d").date(), time=datetime.now(), is_public=False, location="test", recurring='Daily', end_date=datetime.strptime("2020-07-25", "%Y-%m-%d").date()) def test_single_delete(self): """ tests deleting single event """ path = reverse('cal:delete_chapter_event', kwargs=dict(event_id=self.singular.pk)) referer = "%s?month=7&year=2020" % reverse('cal:index') response = self.client.post(path, HTTP_REFERER=referer, follow=True) self.assertNotContains(response, 'singular event') try: ChapterEvent.objects.get(id=self.singular.pk) self.fail('event matching query should have been deleted') except ChapterEvent.DoesNotExist: pass def test_recursive_delete_first(self): """ tests deleting multiple events recursively by deleting first """ path = reverse('cal:delete_chapter_event_recursive', kwargs=dict(event_id=self.recurring.pk)) referer = "%s?month=7&year=2020" % reverse('cal:index') response = self.client.post(path, HTTP_REFERER=referer, follow=True) self.assertNotContains(response, 'recurring event') try: ChapterEvent.objects.get(name='recurring event') self.fail('event matching query should have been deleted') except ChapterEvent.DoesNotExist: pass def test_recursive_delete_middle(self): """ tests deleting multiple events recursively by deleting non-first event """ event = ChapterEvent.objects.filter(name="recurring event")[1] path = reverse('cal:delete_chapter_event_recursive', kwargs=dict(event_id=event.pk)) referer = "%s?month=7&year=2020" % reverse('cal:index') response = self.client.post(path, HTTP_REFERER=referer, follow=True) self.assertNotContains(response, 'recurring event') try: ChapterEvent.objects.get(name='recurring event') self.fail('event matching query should have been deleted') except ChapterEvent.DoesNotExist: pass def test_single_delete_then_recursive(self): """ tests deleting the first element singularly, then the rest recursively """ event = ChapterEvent.objects.filter(name="recurring event")[0] path = reverse('cal:delete_chapter_event', kwargs=dict(event_id=event.pk)) referer = "%s?month=7&year=2020" % reverse('cal:index') response = self.client.post(path, HTTP_REFERER=referer, follow=True) new_first = ChapterEvent.objects.filter(name="recurring event")[0] path = reverse('cal:delete_chapter_event_recursive', kwargs=dict(event_id=new_first.pk)) response = self.client.post(path, HTTP_REFERER=referer, follow=True) self.assertNotContains(response, 'recurring event') try: ChapterEvent.objects.get(name='recurring event') self.fail('event matching query should have been deleted') except ChapterEvent.DoesNotExist: pass
class EventsTestCase(TenantTestCase): """ tests events and related functions """ def setUp(self): self.client = TenantClient(self.tenant) self.user = User.objects.create(username="******", is_superuser=True, is_staff=True) self.client.force_login(self.user) settings = getSettings() settings.rush_signin_active = True settings.save() self.rushee1 = Rushee.objects.create(name="first_rushee") self.rushee2 = Rushee.objects.create(name="second_rushee") self.event1 = RushEvent.objects.create(name='first_event', date='2001-01-01', time='00:00:00', round=1, new_rushees_allowed=True) self.event2 = RushEvent.objects.create(name='second_event', date='2001-01-02', time='00:00:00', round=1, new_rushees_allowed=False) def test_events_view(self): """ tests the view showing all rush events """ path = reverse('rush:events') response = self.client.post(path) self.assertContains(response, '<a href="/rush/events/' + str(self.event1.pk)) self.assertContains(response, '<a href="/rush/events/' + str(self.event2.pk)) def test_single_event_view(self): """ tests the view showing a single event """ path = reverse('rush:event', kwargs=dict(event_id=self.event1.pk)) response = self.client.post(path) self.assertContains(response, 'first_event') def test_event_attendance(self): """ tests that rushees in attendance are listed on event page """ self.event1.attendance.add(self.rushee1) self.event1.save() path = reverse('rush:event', kwargs=dict(event_id=self.event1.pk)) response = self.client.post(path) self.assertContains( response, "<tr onclick=\"window.location='/rush/rushee" + str(self.rushee1.pk)) def test_create_event_new_rushees(self): """ tests create_event view """ post_data = { 'name': 'third_event', 'date': '2001-01-03', 'time': '00:00:00', 'round': '1', 'location': 'test_location', 'new_rushees': ['true'], } path = reverse('rush:create_event') self.client.post(path, post_data) event = RushEvent.objects.get(name='third_event') self.assertTrue(event) path = reverse('rush:signin', kwargs=dict(event_id=event.pk)) response = self.client.post(path) self.assertContains(response, 'action="register') def test_create_event_no_new_rushees(self): """ tests create_event view when new rushees are not allowed """ post_data = { 'name': 'third_event', 'date': '2001-01-03', 'time': '00:00:00', 'round': '1', 'location': 'test_location', 'new_rushees': [], } path = reverse('rush:create_event') self.client.post(path, post_data) event = RushEvent.objects.get(name='third_event') self.assertTrue(event) path = reverse('rush:signin', kwargs=dict(event_id=event.pk)) response = self.client.post(path) self.assertContains(response, 'Click on your name to sign in.') def test_create_event_get(self): """ tests for 404 error when request method is not post """ path = reverse('rush:create_event') request = self.client.get(path) self.assertEqual(request.status_code, 404) def test_remove_event(self): """ tests remove event view function """ path = reverse('rush:remove_event', kwargs=dict(event_id=2)) request = self.client.post(path) try: rushee = RushEvent.objects.get(pk=2) self.fail("Rushee matching query should not exist") except RushEvent.DoesNotExist: pass def test_round_headers_for_events_list(self): """ tests that proper round headers appear on events page""" path = reverse('rush:events') response = self.client.get(path) self.assertContains(response, "<h4>Round 1</h4>") self.assertNotContains(response, "<h4>Round 2</h4>") def test_round_headers_split_rounds(self): """ tests that proper round headers appear even if they are separated by a round""" RushEvent.objects.create(name='first_event', date='2001-01-01', time='00:00:00', round=3, new_rushees_allowed=True) path = reverse('rush:events') response = self.client.get(path) self.assertContains(response, "<h4>Round 1</h4>") self.assertNotContains(response, "<h4>Round 2</h4>") self.assertContains(response, "<h4>Round 3</h4>")
class SigninTestCase(TenantTestCase): """ test cases for the signin module """ def setUp(self): self.client = TenantClient(self.tenant) self.user = User.objects.create(username="******") self.client.force_login(self.user) settings = getSettings() settings.rush_signin_active = True settings.save() self.rushee = Rushee.objects.create(name='test_rushee') self.event1 = RushEvent.objects.create(name='first_event', date='2001-01-01', time='00:00:00', round=1, new_rushees_allowed=True) self.event2 = RushEvent.objects.create(name='second_event', date='2001-01-02', time='00:00:00', round=1, new_rushees_allowed=False) def test_signin_page_first_event(self): """ tests that the signin view redirects to the first event by default """ path = reverse('rush:signin') response = self.client.post(path) self.assertContains(response, 'first_event') def test_signin_page_not_default_event(self): """ tests that the signin view directs to the correct event when parameter provided """ path = reverse('rush:signin', kwargs=dict(event_id=self.event2.pk)) response = self.client.post(path) self.assertContains(response, 'second_event') def test_signin_page_new_rushees_allowed(self): """ tests that when new rushees are allowed in an event, signin page appears differently """ path = reverse('rush:signin') response = self.client.post(path) self.assertContains(response, 'action="register') self.assertNotContains(response, 'Click on your name to sign in.') def test_signin_page_new_rushees_not_allowed(self): """ tests that when new rushees are not allowed in an event, signin page appears differently """ path = reverse('rush:signin', kwargs=dict(event_id=self.event2.pk)) response = self.client.post(path) self.assertContains(response, 'Click on your name to sign in.') self.assertNotContains(response, 'action="register') def test_rush_event_dropdown(self): """ tests that rush events appear as choices in the dropdown selector """ path = reverse('rush:signin') response = self.client.post(path) self.assertContains( response, '<a class="dropdown-item" href="signin' + str(self.event1.pk) + '">') self.assertContains( response, '<a class="dropdown-item" href="signin' + str(self.event2.pk) + '">') def test_click_to_signin_link(self): """ tests that rushees can click to signin to events """ path = reverse('rush:signin', kwargs=dict(event_id=self.event2.pk)) response = self.client.post(path) self.assertContains( response, "<tr onclick=\"window.location='/rush/attendance" + str(self.rushee.pk) + "/" + str(self.event2.pk) + "';") def test_attendance_view(self): """ tests the attendance view function """ path = reverse('rush:attendance', kwargs=dict(rushee_id=1, event_id=2)) response = self.client.post(path) self.assertTrue( RushEvent.objects.get(pk=2).attendance.get(name='test_rushee')) self.assertContains(response, "Thank you, test_rushee. You're good to go!")
class SubmissionViewTests(TenantTestCase): # includes some basic model data # fixtures = ['initial_data.json'] def setUp(self): self.client = TenantClient(self.tenant) User = get_user_model() # need a teacher and a student with known password so tests can log in as each, or could use force_login()? self.test_password = "******" # need a teacher before students can be created or the profile creation will fail when trying to notify self.test_teacher = User.objects.create_user('test_teacher', password=self.test_password, is_staff=True) self.test_student1 = User.objects.create_user('test_student', password=self.test_password) self.test_student2 = mommy.make(User) self.quest1 = mommy.make(Quest) self.quest2 = mommy.make(Quest) self.sub1 = mommy.make(QuestSubmission, user=self.test_student1, quest=self.quest1) self.sub2 = mommy.make(QuestSubmission, quest=self.quest1) self.sub3 = mommy.make(QuestSubmission, quest=self.quest2) def test_all_submission_page_status_codes_for_students(self): # log in a student success = self.client.login(username=self.test_student1.username, password=self.test_password) self.assertTrue(success) s1_pk = self.sub1.pk s2_pk = self.sub2.pk # Student's own submission self.assertEqual(self.client.get(reverse('quests:submission', args=[s1_pk])).status_code, 200) self.assertEqual(self.client.get(reverse('quests:drop', args=[s1_pk])).status_code, 200) self.assertEqual(self.client.get(reverse('quests:submission_past', args=[s1_pk])).status_code, 200) # Students shouldn't have access to these self.assertEqual(self.client.get(reverse('quests:flagged')).status_code, 302) # Student's own submission self.assertEqual(self.client.get(reverse('quests:skip', args=[s1_pk])).status_code, 404) self.assertEqual(self.client.get(reverse('quests:approve', args=[s1_pk])).status_code, 302) self.assertEqual(self.client.get(reverse('quests:submission_past', args=[s1_pk])).status_code, 200) self.assertEqual(self.client.get(reverse('quests:flag', args=[s1_pk])).status_code, 302) self.assertEqual(self.client.get(reverse('quests:unflag', args=[s1_pk])).status_code, 302) self.assertEqual(self.client.get(reverse('quests:complete', args=[s1_pk])).status_code, 404) # Not this student's submission self.assertEqual(self.client.get(reverse('quests:submission', args=[s2_pk])).status_code, 302) self.assertEqual(self.client.get(reverse('quests:drop', args=[s2_pk])).status_code, 302) self.assertEqual(self.client.get(reverse('quests:skip', args=[s2_pk])).status_code, 404) self.assertEqual(self.client.get(reverse('quests:submission_past', args=[s2_pk])).status_code, 302) self.assertEqual(self.client.get(reverse('quests:complete', args=[s2_pk])).status_code, 404) # Non existent submissions self.assertEqual(self.client.get(reverse('quests:submission', args=[0])).status_code, 404) self.assertEqual(self.client.get(reverse('quests:drop', args=[0])).status_code, 404) self.assertEqual(self.client.get(reverse('quests:skip', args=[0])).status_code, 404) self.assertEqual(self.client.get(reverse('quests:submission_past', args=[0])).status_code, 404) self.assertEqual(self.client.get(reverse('quests:complete', args=[0])).status_code, 404) # These Needs to be completed via POST self.assertEqual(self.client.get(reverse('quests:complete', args=[s1_pk])).status_code, 404) def test_all_submission_page_status_codes_for_teachers(self): # log in a teacher success = self.client.login(username=self.test_teacher.username, password=self.test_password) self.assertTrue(success) s1_pk = self.sub1.pk # s2_pk = self.sub2.pk self.assertEqual(self.client.get(reverse('quests:flagged')).status_code, 200) # View it self.assertEqual(self.client.get(reverse('quests:submission', args=[s1_pk])).status_code, 200) # Flag it # self.assertEqual(self.client.get(reverse('quests:flag', args=[s1_pk])).status_code, 200) self.assertRedirects( response=self.client.get(reverse('quests:flag', args=[s1_pk])), expected_url=reverse('quests:approvals'), ) # TODO Why does this fail? Why is self.sub1.flagged_by == None # self.assertEqual(self.sub1.flagged_by, self.test_teacher) # Unflag it self.assertRedirects( response=self.client.get(reverse('quests:unflag', args=[s1_pk])), expected_url=reverse('quests:approvals'), ) self.assertIsNone(self.sub1.flagged_by) # self.assertEqual(self.client.get(reverse('quests:drop', args=[s1_pk])).status_code, 200) self.assertEqual(self.client.get(reverse('quests:submission_past', args=[s1_pk])).status_code, 200) # Non existent submissions self.assertEqual(self.client.get(reverse('quests:submission', args=[0])).status_code, 404) self.assertEqual(self.client.get(reverse('quests:drop', args=[0])).status_code, 404) self.assertEqual(self.client.get(reverse('quests:skip', args=[0])).status_code, 404) self.assertEqual(self.client.get(reverse('quests:submission_past', args=[0])).status_code, 404) # These Needs to be completed via POST # self.assertEqual(self.client.get(reverse('quests:complete', args=[s1_pk])).status_code, 404) self.assertEqual(self.client.get(reverse('quests:skip', args=[s1_pk])).status_code, 302) self.assertEqual(self.client.get(reverse('quests:approve', args=[s1_pk])).status_code, 404) def test_student_quest_completion(self): # self.sub1 = mommy.make(QuestSubmission, user=self.test_student1, quest=self.quest1) # self.assertRedirects( # response=self.client.post(reverse('quests:complete', args=[self.sub1.id])), # expected_url=reverse('quests:quests'), # ) # TODO self.assertEqual(self.client.get(reverse('quests:complete', args=[s1_pk])).status_code, 404) pass def test_submission_when_quest_not_visible(self): """When a quest is hidden from students, they should still be able to to see their submission in a static way""" # log in a student success = self.client.login(username=self.test_student1.username, password=self.test_password) self.assertTrue(success) # Make quest invisible to students self.quest1.visible_to_students = False self.quest1.save() self.assertFalse(self.quest1.visible_to_students) # TODO: should redirect, not 404? self.assertEqual(self.client.get(reverse('quests:submission', args=[self.sub1.pk])).status_code, 404) def test_ajax_save_draft(self): # loging required for this view self.client.force_login(self.test_student1) quest = mommy.make(Quest, name="TestSaveDrafts") sub = mommy.make(QuestSubmission, quest=quest) draft_comment = "Test draft comment" # Send some draft data via the ajax view, which should save it. ajax_data = { 'comment': draft_comment, 'submission_id': sub.id, } response = self.client.post( reverse('quests:ajax_save_draft'), data=ajax_data, HTTP_X_REQUESTED_WITH='XMLHttpRequest', ) self.assertEqual(response.status_code, 200) self.assertEqual(response.json()['result'], "Draft saved") sub.refresh_from_db() self.assertEqual(draft_comment, sub.draft_text) # fAILS CUS MODEL DIDN'T SAVE! aRGH..
class VotingTestCase(TenantTestCase): """ tests voting functions """ def setUp(self): self.client = TenantClient(self.tenant) self.rushee = Rushee.objects.create(name="test_rushee", voting_open=True) self.user = User.objects.create(username="******", is_staff=True, is_superuser=True) self.client.force_login(self.user) def test_vote_function_y(self): referer = reverse('rush:rushee', kwargs=dict(num=self.rushee.pk)) path = reverse('rush:vote', kwargs=dict(rushee_id=self.rushee.pk, value='y')) self.client.post(path, HTTP_REFERER=referer, follow=True) self.rushee.refresh_from_db() self.assertEqual(self.rushee.y, 1) def test_vote_function_n(self): referer = reverse('rush:rushee', kwargs=dict(num=self.rushee.pk)) path = reverse('rush:vote', kwargs=dict(rushee_id=self.rushee.pk, value='n')) self.client.post(path, HTTP_REFERER=referer, follow=True) self.rushee.refresh_from_db() self.assertEqual(self.rushee.n, 1) def test_vote_function_a(self): referer = reverse('rush:rushee', kwargs=dict(num=self.rushee.pk)) path = reverse('rush:vote', kwargs=dict(rushee_id=self.rushee.pk, value='a')) self.client.post(path, HTTP_REFERER=referer, follow=True) self.rushee.refresh_from_db() self.assertEqual(self.rushee.a, 1) def test_vote_function_b(self): referer = reverse('rush:rushee', kwargs=dict(num=self.rushee.pk)) path = reverse('rush:vote', kwargs=dict(rushee_id=self.rushee.pk, value='b')) self.client.post(path, HTTP_REFERER=referer, follow=True) self.rushee.refresh_from_db() self.assertEqual(self.rushee.b, 1) self.assertTrue(self.rushee.blackball_list.get(username='******')) def test_voting_not_open(self): self.rushee.voting_open = False self.rushee.save() referer = reverse('rush:rushee', kwargs=dict(num=self.rushee.pk)) path = reverse('rush:vote', kwargs=dict(rushee_id=self.rushee.pk, value='y')) response = self.client.post(path, HTTP_REFERER=referer, follow=True) self.assertContains( response, "Vote was not cast, because voting is not open. Voting must be opened by an admin before votes will be recorded." ) def test_push_rushee(self): path = reverse('rush:push', kwargs=dict(rushee_id=self.rushee.pk)) self.client.post(path, follow=True) self.rushee.refresh_from_db() self.assertEqual(self.rushee.round, 2) def test_push_rushee_with_next(self): """ tests pushing rushee when next rushee exists """ Rushee.objects.create(name="test_rushee_2") path = reverse('rush:push', kwargs=dict(rushee_id=self.rushee.pk)) response = self.client.post(path, follow=True) self.assertContains(response, '<h1 class="display-4">test_rushee_2</h1>') def test_cut_rushee(self): path = reverse('rush:cut', kwargs=dict(rushee_id=self.rushee.pk)) self.client.post(path, follow=True) self.rushee.refresh_from_db() self.assertTrue(self.rushee.cut) def test_cut_rushee_with_next(self): """ tests cutting rushee when next rushee exists """ Rushee.objects.create(name="test_rushee_2") path = reverse('rush:cut', kwargs=dict(rushee_id=self.rushee.pk)) response = self.client.post(path, follow=True) self.assertContains(response, '<h1 class="display-4">test_rushee_2</h1>') def test_votepage(self): self.rushee.voting_open = False self.rushee.save() path = reverse('rush:votepage', kwargs=dict(rushee_id=self.rushee.pk)) self.client.post(path, follow=True) self.rushee.refresh_from_db() self.assertTrue(self.rushee.voting_open) def test_results(self): path = reverse('rush:results', kwargs=dict(rushee_id=self.rushee.pk)) self.client.post(path) self.rushee.refresh_from_db() self.assertFalse(self.rushee.voting_open) def test_reset(self): self.rushee.y = 1 self.rushee.n = 1 self.rushee.save() path = reverse('rush:reset', kwargs=dict(rushee_id=self.rushee.pk)) self.client.post(path) self.rushee.refresh_from_db() self.assertEqual(self.rushee.y, 0) self.assertEqual(self.rushee.n, 0)
class RusheeTestCase(TenantTestCase): """ Tests the basic parts of the rushee view and template """ def setUp(self): self.client = TenantClient(self.tenant) self.u = User.objects.create(username="******", is_staff=True) self.client.force_login(self.u) self.rushee = Rushee.objects.create(name="test") def test_rushee_personal_information(self): """ tests that personal information appears in template """ self.rushee.email = "*****@*****.**" self.rushee.save() path = reverse('rush:rushee', kwargs=dict(num=self.rushee.pk)) response = self.client.post(path) self.assertContains(response, '<td>test</td>') self.assertContains(response, '<td>[email protected]</td>') def test_rushee_comments_appear(self): """ tests that comments appear in template """ Comment.objects.create(name="first last", body="test comment", rushee=self.rushee) path = reverse('rush:rushee', kwargs=dict(num=self.rushee.pk)) response = self.client.post(path) self.assertContains(response, 'first last') self.assertContains(response, 'test comment') def test_post_comment(self): """ tests post_comment function """ post_data = {'body': 'this is a test comment'} path = reverse('rush:comment', kwargs=dict(rushee_id=self.rushee.pk)) referer = reverse('rush:rushee', kwargs=dict(num=self.rushee.pk)) response = self.client.post(path, post_data, HTTP_REFERER=referer, follow=True) self.assertContains(response, 'this is a test comment') def test_post_comment_form_errors(self): """ tests post_comment function with form errors """ post_data = {'body': 'x' * 281} path = reverse('rush:comment', kwargs=dict(rushee_id=self.rushee.pk)) referer = reverse('rush:rushee', kwargs=dict(num=self.rushee.pk)) response = self.client.post(path, post_data, HTTP_REFERER=referer, follow=True) self.assertEqual(response.content, b'Comment not recorded.') def test_remove_comment(self): """ tests remove_comment function """ comment = Comment.objects.create(name="first last", body="test comment", rushee=self.rushee) path = reverse('rush:remove_comment', kwargs=dict(comment_id=comment.pk)) referer = reverse('rush:rushee', kwargs=dict(num=self.rushee.pk)) response = self.client.post(path, HTTP_REFERER=referer, follow=True) self.assertNotContains(response, 'test comment') def test_endorse(self): """ tests endorse function """ path = reverse('rush:endorse', kwargs=dict(rushee_id=self.rushee.pk)) referer = reverse('rush:rushee', kwargs=dict(num=self.rushee.pk)) response = self.client.post(path, HTTP_REFERER=referer, follow=True) self.assertContains(response, "You have <b>endorsed</b> this rushee") def test_oppose(self): """ tests oppose function """ path = reverse('rush:oppose', kwargs=dict(rushee_id=self.rushee.pk)) referer = reverse('rush:rushee', kwargs=dict(num=self.rushee.pk)) response = self.client.post(path, HTTP_REFERER=referer, follow=True) self.assertContains(response, "You have <b>opposed</b> this rushee") def test_clear_endorsements(self): """ tests clear endorsements function """ self.rushee.endorsements.add(self.u) path = reverse('rush:clear_endorsement', kwargs=dict(rushee_id=self.rushee.pk)) referer = reverse('rush:rushee', kwargs=dict(num=self.rushee.pk)) response = self.client.post(path, HTTP_REFERER=referer, follow=True) self.assertNotContains(response, "You have <b>endorsed</b> this rushee")
class BadgeViewTests(ViewTestUtilsMixin, TenantTestCase): def setUp(self): self.client = TenantClient(self.tenant) # need a teacher and a student with known password so tests can log in as each, or could use force_login()? self.test_password = "******" # need a teacher before students can be created or the profile creation will fail when trying to notify self.test_teacher = User.objects.create_user( 'test_teacher', password=self.test_password, is_staff=True) self.test_student1 = User.objects.create_user( 'test_student', password=self.test_password) self.test_student2 = baker.make(User) # needed because BadgeAssertions use a default that might not exist yet self.sem = SiteConfig.get().active_semester self.test_badge = baker.make(Badge, ) self.test_badge_type = baker.make(BadgeType) self.test_assertion = baker.make(BadgeAssertion) def test_all_badge_page_status_codes_for_anonymous(self): ''' If not logged in then all views should redirect to home or admin page ''' b_pk = self.test_badge.pk a_pk = self.test_assertion.pk s_pk = self.test_student1.pk self.assertRedirectsLogin('badges:list') self.assertRedirectsLogin('badges:badge_detail', args=[b_pk]) self.assertRedirectsLogin('badges:badge_create') self.assertRedirectsAdmin('badges:badge_update', args=[b_pk]) self.assertRedirectsAdmin('badges:badge_copy', args=[b_pk]) self.assertRedirectsAdmin('badges:badge_delete', args=[b_pk]) self.assertRedirectsAdmin('badges:grant', args=[b_pk, s_pk]) self.assertRedirectsAdmin('badges:bulk_grant_badge', args=[b_pk]) self.assertRedirectsAdmin('badges:bulk_grant') self.assertRedirectsAdmin('badges:revoke', args=[a_pk]) def test_all_badge_page_status_codes_for_students(self): # log in a student success = self.client.login(username=self.test_student1.username, password=self.test_password) self.assertTrue(success) b_pk = self.test_badge.pk # a_pk = self.test_assertion.pk s_pk = self.test_student1.pk self.assert200('badges:list') self.assert200('badges:badge_detail', args=[b_pk]) # students shouldn't have access to these and should be redirected self.assertRedirectsQuests('badges:badge_create', follow=True), self.assertRedirectsAdmin('badges:badge_update', args=[b_pk]) self.assertRedirectsAdmin('badges:badge_copy', args=[b_pk]) self.assertRedirectsAdmin('badges:badge_delete', args=[b_pk]) self.assertRedirectsAdmin('badges:grant', args=[b_pk, s_pk]) self.assertRedirectsAdmin('badges:bulk_grant_badge', args=[b_pk]) self.assertRedirectsAdmin('badges:bulk_grant') self.assertRedirectsAdmin('badges:revoke', args=[s_pk]) def test_all_badge_page_status_codes_for_teachers(self): # log in a teacher success = self.client.login(username=self.test_teacher.username, password=self.test_password) self.assertTrue(success) b_pk = self.test_badge.pk a_pk = self.test_assertion.pk s_pk = self.test_student1.pk self.assert200('badges:list') self.assert200('badges:badge_detail', args=[b_pk]) self.assert200('badges:badge_create') self.assert200('badges:badge_update', args=[b_pk]) self.assert200('badges:badge_copy', args=[b_pk]) self.assert200('badges:badge_delete', args=[b_pk]) self.assert200('badges:grant', args=[b_pk, s_pk]) self.assert200('badges:bulk_grant_badge', args=[b_pk]) self.assert200('badges:bulk_grant') self.assert200('badges:revoke', args=[a_pk]) def test_badge_create(self): # log in a teacher success = self.client.login(username=self.test_teacher.username, password=self.test_password) self.assertTrue(success) form_data = { 'name': "badge test", 'xp': 5, 'content': "test content", 'badge_type': self.test_badge_type.id, 'author': self.test_teacher.id, 'import_id': uuid.uuid4() } response = self.client.post(reverse('badges:badge_create'), data=form_data) self.assertRedirects(response, reverse("badges:list")) # Get the newest object new_badge = Badge.objects.latest('datetime_created') self.assertEqual(new_badge.name, "badge test") def test_badge_copy(self): # log in a teacher success = self.client.login(username=self.test_teacher.username, password=self.test_password) self.assertTrue(success) form_data = { 'name': "badge copy test", 'xp': 5, 'content': "test content", 'badge_type': self.test_badge_type.id, 'author': self.test_teacher.id, 'import_id': uuid.uuid4() } response = self.client.post(reverse('badges:badge_copy', args=[self.test_badge.id]), data=form_data) self.assertRedirects(response, reverse("badges:list")) # Get the newest object new_badge = Badge.objects.latest('datetime_created') self.assertEqual(new_badge.name, "badge copy test") def test_assertion_create_and_delete(self): # log in a teacher success = self.client.login(username=self.test_teacher.username, password=self.test_password) self.assertTrue(success) # test: assertion_create() form_data = { 'badge': self.test_badge.id, 'user': self.test_student1.id } response = self.client.post(reverse('badges:grant', kwargs={ 'user_id': self.test_student1.id, 'badge_id': self.test_badge.id }), data=form_data) self.assertRedirects(response, reverse("badges:list")) new_assertion = BadgeAssertion.objects.latest('timestamp') self.assertEqual(new_assertion.user, self.test_student1) self.assertEqual(new_assertion.badge, self.test_badge) # test: assertion_delete() response = self.client.post( reverse('badges:revoke', args=[new_assertion.id]), ) self.assertRedirects( response, reverse("profiles:profile_detail", args=[self.test_student1.profile.id])) # shouldn't exist anymore now that we deleted it! with self.assertRaises(BadgeAssertion.DoesNotExist): BadgeAssertion.objects.get(id=new_assertion.id) def test_bulk_assertion_create(self): # log in a teacher success = self.client.login(username=self.test_teacher.username, password=self.test_password) self.assertTrue(success) # compare total granted before to after: badge_assertions_before = BadgeAssertion.objects.all().count() # this form uses students in the active semester, so need to give them a course in the active semester! baker.make('courses.CourseStudent', user=self.test_student1, semester=self.sem) baker.make('courses.CourseStudent', user=self.test_student2, semester=self.sem) form_data = { 'badge': self.test_badge.id, 'students': [self.test_student1.profile.id, self.test_student2.profile.id] } response = self.client.post(reverse('badges:bulk_grant'), data=form_data) self.assertRedirects(response, reverse("badges:list")) # we just bulk granted 2 badges, so there should be two more than before! badge_assertions_after = BadgeAssertion.objects.all().count() self.assertEqual(badge_assertions_after, badge_assertions_before + 2)
class RosterTestCase(TenantTestCase): def setUp(self): self.client = TenantClient(self.tenant) self.admin = User.objects.create(username="******", is_superuser=True, is_staff=True) self.client.force_login(self.admin) self.roster = Roster.objects.create(title="test_roster") # tests roster view function def test_roster_view(self): path = reverse('roster', kwargs=dict(roster_id=self.roster.pk)) response = self.client.get(path) self.assertContains(response, "test_roster</h1>") # tests roster appears in social view def test_roster_appears_in_social(self): path = reverse('social') response = self.client.get(path) self.assertContains(response, "test_roster</a>") # tests that rosters are paginated if more than 10 def test_roster_paginates_over_ten(self): for i in range(15): Roster.objects.create(title=str(i)) path = reverse('social') response = self.client.get(path) self.assertContains(response, "<a class=\"page-link\" href=\"?rosterspage") # tests edit_roster view function def test_edit_roster_view(self): path = reverse('edit_roster', kwargs=dict(roster_id=self.roster.pk)) referer = reverse('roster', kwargs=dict(roster_id=self.roster.pk)) post_data = {'updated_members': 'test1\ntest2\ntest3'} response = self.client.post(path, post_data, HTTP_REFERER=referer, follow=True) self.assertContains(response, "test1</td>") self.assertContains(response, "test2</td>") self.assertContains(response, "test3</td>") self.assertEqual(self.roster.members.count(), 3) # tests editing roster with duplicates def test_edit_roster_duplicates(self): path = reverse('edit_roster', kwargs=dict(roster_id=self.roster.pk)) referer = reverse('roster', kwargs=dict(roster_id=self.roster.pk)) # contains duplicate of test1 post_data = {'updated_members': 'test1\ntest2\ntest1'} response = self.client.post(path, post_data, HTTP_REFERER=referer, follow=True) self.assertContains( response, "The following name was not added to the roster, because it is a duplicate:</b> test1" ) self.assertEqual(self.roster.members.count(), 2) # tests edit roster with get request, should return 404 def test_edit_roster_get(self): path = reverse('edit_roster', kwargs=dict(roster_id=1)) response = self.client.get(path) self.assertEqual(response.status_code, 404) # tests remove_from_roster function def test_remove_from_roster(self): member = RosterMember.objects.create(name="test", roster=self.roster) path = reverse('remove_from_roster', kwargs=dict(roster_id=self.roster.pk, member_id=member.pk)) referer = reverse('roster', kwargs=dict(roster_id=self.roster.pk)) response = self.client.get(path, HTTP_REFERER=referer, follow=True) self.assertEqual(self.roster.members.count(), 0) self.assertNotContains(response, "test</td>") # test add_roster_to_events function def test_add_roster_to_events(self): path = reverse('add_roster_to_events', kwargs=dict(roster_id=1)) s = SocialEvent.objects.create() RosterMember.objects.create(name="test", roster=self.roster) referer = reverse('roster', kwargs=dict(roster_id=1)) # contains the name of all checked events, default name for an event is test post_data = {'event_checkboxes': 'test'} response = self.client.post(path, post_data, HTTP_REFERER=referer, follow=True) s.refresh_from_db() self.assertContains( response, "The members of this roster were successfully added to the following event:</b> test" ) self.assertEqual(s.list.count(), 1) # shouldn't behave differently, but shouldn't add duplicates to the event def test_add_roster_to_events(self): path = reverse('add_roster_to_events', kwargs=dict(roster_id=1)) s = SocialEvent.objects.create() Attendee.objects.create(name="test", user="******", event=s) RosterMember.objects.create(name="test", roster=self.roster) referer = reverse('roster', kwargs=dict(roster_id=1)) # contains the name of all checked events, default name for an event is test post_data = {'event_checkboxes': 'test'} response = self.client.post(path, post_data, HTTP_REFERER=referer, follow=True) s.refresh_from_db() self.assertContains( response, "The members of this roster were successfully added to the following event:</b> test" ) self.assertEqual(s.list.count(), 1) # test add_roster_to_events with get request, should return 404 def test_add_roster_to_events_get(self): path = reverse('add_roster_to_events', kwargs=dict(roster_id=1)) response = self.client.get(path) self.assertEqual(response.status_code, 404) # test save_as_roster view def test_save_as_roster(self): s = SocialEvent.objects.create() path = reverse('save_as_roster', kwargs=dict(event_id=s.pk)) Attendee.objects.create(name="test", user="******", event=s) post_data = {'roster_name': 'saved_roster'} referer = reverse('social_event', kwargs=dict(event_id=s.pk)) response = self.client.post(path, post_data, HTTP_REFERER=referer, follow=True) self.assertContains(response, "List successfully saved as roster: saved_roster") self.assertTrue(Roster.objects.get(title="saved_roster")) self.assertEqual( Roster.objects.get(title="saved_roster").members.count(), 1) self.assertTrue( Roster.objects.get(title="saved_roster").members.get(name="test")) # test save_as_roster view with get method, which should return 404 def test_save_as_roster_get(self): s = SocialEvent.objects.create() path = reverse('save_as_roster', kwargs=dict(event_id=s.pk)) response = self.client.get(path) self.assertEqual(response.status_code, 404) # tests create_roster function def test_create_roster(self): path = reverse('create_roster') post_data = { 'title': 'created_roster', 'members': 'test1\ntest2\ntest3' } referer = reverse('social') response = self.client.post(path, post_data, HTTP_REFERER=referer, follow=True) self.assertContains(response, "created_roster</a>") self.assertTrue(Roster.objects.get(title="created_roster")) self.assertEqual( Roster.objects.get(title="created_roster").members.count(), 3) # tests create_roster with duplicates def test_create_roster_duplicates(self): path = reverse('create_roster') post_data = { 'title': 'created_roster', 'members': 'test1\ntest2\ntest1' } referer = reverse('social') response = self.client.post(path, post_data, HTTP_REFERER=referer, follow=True) self.assertContains(response, "created_roster</a>") self.assertTrue(Roster.objects.get(title="created_roster")) self.assertEqual( Roster.objects.get(title="created_roster").members.count(), 2) # tests create_roster function under get request, should be 404 def test_create_roster_get(self): path = reverse('create_roster') response = self.client.get(path) self.assertEqual(response.status_code, 404) # tests remove_roster function def test_remove_roster(self): path = reverse('remove_roster', kwargs=dict(roster_id=self.roster.pk)) referer = reverse('social') response = self.client.post(path, HTTP_REFERER=referer, follow=True) self.assertNotContains(response, "test_roster</a>") self.assertFalse(Roster.objects.filter(id=1))
class SocialEventTestCase(TenantTestCase): def setUp(self): self.client = TenantClient(self.tenant) self.admin = User.objects.create(username="******", is_staff=True, is_superuser=True) self.client.force_login(self.admin) self.event = SocialEvent.objects.create() self.attendees = [] for i in range(1, 4): a = Attendee.objects.create(name="attendee" + str(i), user=self.admin, event=self.event) self.attendees.append(a) self.event.save() # tests remove_from_list feature to make sure attendees are removed from database and UI def test_remove_from_list(self): path = reverse('remove_from_list', kwargs=dict(event_id=self.event.pk, attendee_id=self.attendees[0].pk)) referer = reverse('social_event', kwargs=dict(event_id=self.event.pk)) response = self.client.post(path, HTTP_REFERER=referer, follow=True) self.assertFalse(Attendee.objects.filter(name="attendee1")) self.assertFalse( re.findall("<td.*>attendee1</td>", str(response.content))) self.assertTrue( re.findall("<td.*>attendee2</td>", str(response.content))) path = reverse('remove_from_list', kwargs=dict(event_id=self.event.pk, attendee_id=self.attendees[1].pk)) response = self.client.post(path, HTTP_REFERER=referer, follow=True) self.assertFalse(Attendee.objects.filter(name="attendee2")) self.assertFalse( re.findall("<td.*>attendee2</td>", str(response.content))) self.assertTrue( re.findall("<td.*>attendee3</td>", str(response.content))) # tests clear list feature def test_clear_list(self): path = reverse('clear_list', kwargs=dict(event_id=self.event.pk)) referer = reverse('social_event', kwargs=dict(event_id=self.event.pk)) response = self.client.post(path, HTTP_REFERER=referer, follow=True) content = str(response.content) self.assertFalse(re.findall("<td>attendee[1-3]</td>", content)) self.assertFalse(self.event.list.all()) # tests exporting a spreadsheet of attendees def test_export_xls(self): path = reverse('export_xls', kwargs=dict(event_id=self.event.pk)) response = self.client.post(path) self.assertEqual(response.get('Content-Type'), 'application/ms-excel') self.assertEqual( response.get('Content-Disposition'), 'attachment; filename=' + str(self.event.pk) + '_attendance.xls') # tests adding single duplicate name to the list def test_add_individual_duplicate(self): path = reverse('add_to_list', kwargs=dict(event_id=self.event.pk)) # should fail, because name is a duplicate post_data = {'multiple_names': '', 'name': 'attendee1'} referer = reverse('social_event', kwargs=dict(event_id=self.event.pk)) response = self.client.post(path, post_data, HTTP_REFERER=referer, follow=True) self.assertContains( response, " <b>The following name was not added to the list, because it is a duplicate:</b> attendee1" ) self.assertEqual(len(Attendee.objects.filter(name="attendee1")), 1) # tests adding multiple duplicate names to the list def test_add_multiple_duplicate(self): path = reverse('add_to_list', kwargs=dict(event_id=self.event.pk)) # should fail, because both names are duplicates post_data = {'multiple_names': 'attendee1\nattendee2', 'name': ''} referer = reverse('social_event', kwargs=dict(event_id=self.event.pk)) response = self.client.post(path, post_data, HTTP_REFERER=referer, follow=True) self.assertContains( response, " <b>The following name was not added to the list, because it is a duplicate:</b> attendee1" ) self.assertContains( response, " <b>The following name was not added to the list, because it is a duplicate:</b> attendee2" ) self.assertEqual(len(Attendee.objects.filter(name="attendee1")), 1) self.assertEqual(len(Attendee.objects.filter(name="attendee2")), 1) # tests adding multiple names where some are duplicates and some aren't def test_add_duplicates_and_new(self): path = reverse('add_to_list', kwargs=dict(event_id=self.event.pk)) # one should fail, one should work post_data = {'multiple_names': 'attendee1\nattendee5', 'name': ''} referer = reverse('social_event', kwargs=dict(event_id=self.event.pk)) response = self.client.post(path, post_data, HTTP_REFERER=referer, follow=True) self.assertContains( response, "<b>The following name was not added to the list, because it is a duplicate:</b> attendee1" ) self.assertNotContains( response, "<b>The following name was not added to the list, because it is a duplicate:</b> attendee2" ) self.assertEqual(len(Attendee.objects.filter(name="attendee1")), 1) self.assertEqual(len(Attendee.objects.filter(name="attendee2")), 1) # tests checking attendance feature def test_check_attendance(self): path = reverse('check_attendee') a = self.event.list.first() get_data = {'attendee_id': a.id} response = self.client.get(path, get_data) self.assertEqual(response.status_code, 200) self.assertJSONEqual(str(response.content, encoding='utf8'), {'attended': True}) a.refresh_from_db() self.assertTrue(a.attended) def test_uncheck_attendance(self): a = self.event.list.first() a.attended = True a.save() path = reverse('check_attendee') get_data = {'attendee_id': a.id} response = self.client.get(path, get_data) self.assertEqual(response.status_code, 200) self.assertJSONEqual(str(response.content, encoding='utf8'), {'attended': False}) a.refresh_from_db() self.assertFalse(a.attended) # tests refresh_attendees view for three attendees with attended=False def test_refresh_attendees_static(self): path = reverse('refresh_attendees') get_data = {'event_id': self.event.id} response = self.client.get(path, get_data) self.assertEqual(response.status_code, 200) # response should be false for all three attendees self.assertJSONEqual( str(response.content, encoding='utf8'), { str(self.attendees[0].pk): False, str(self.attendees[1].pk): False, str(self.attendees[2].pk): False }) # tests refresh_attendees view when status of attendee changes, to ensure change is propagated def test_refresh_attendees_dynamic(self): path = reverse('refresh_attendees') get_data = {'event_id': self.event.id} response = self.client.get(path, get_data) self.assertJSONEqual( str(response.content, encoding='utf8'), { str(self.attendees[0].pk): False, str(self.attendees[1].pk): False, str(self.attendees[2].pk): False }) # change one of the attendees, to see if the refresh changes the JSON response a = Attendee.objects.get(id=self.attendees[1].pk) a.attended = True a.save() response = self.client.get(path, get_data) self.assertJSONEqual( str(response.content, encoding='utf8'), { str(self.attendees[0].pk): False, str(self.attendees[1].pk): True, str(self.attendees[2].pk): False }) # test toggle_party_mode view def test_toggle_party_mode_view(self): # event.party_mode is initially false, request should make it true path = reverse('toggle_party_mode', kwargs=dict(event_id=self.event.pk)) response = self.client.post(path) self.event.refresh_from_db() self.assertTrue(self.event.party_mode) # sending request again should make event.party_mode false again response = self.client.post(path) self.event.refresh_from_db() self.assertFalse(self.event.party_mode) # test toggle_party_mode template def test_toggle_party_mode_template(self): # party mode should initially be false referer = reverse('social_event', kwargs=dict(event_id=self.event.pk)) response = self.client.post(referer) # when party mode is off, the label by the button should say off self.assertContains(response, "Party mode off") # the add to list form should be availiable self.assertContains(response, "Type Full Name Here") # the ajax script refreshing the list should not be linked self.assertFalse( re.findall('<script src=".*cross_off_list.js', str(response.content))) # the "attended" column of the list table should not be present self.assertNotContains(response, "Attended") # set party mode to true path = reverse('toggle_party_mode', kwargs=dict(event_id=self.event.pk)) response = self.client.post(path, HTTP_REFERER=referer, follow=True) # when party mode is on, the label by the button should say on self.assertContains(response, "Party mode on") # The attended column should be present self.assertContains(response, "Attended") # the ajax script refreshing the list should be linked self.assertTrue( re.findall('<script src=".*cross_off_list.js', str(response.content))) # the add to list form should not be available self.assertNotContains(response, "Type Full Name Here")
class AnnouncementsTestCase(TenantTestCase): def setUp(self): self.client = TenantClient(self.tenant) u = User.objects.create(username="******", is_staff=True, is_superuser=True) self.client.force_login(u) a = Announcement.objects.create(user=u) # tests that announcement is displayed on index def test_announcement_appears(self): path = reverse('index') response = self.client.post(path) self.assertContains(response, '<li class="list-group-item">') # tests that add announcement button appears def test_add_announcement_button_appears(self): path = reverse('index') response = self.client.post(path) self.assertContains(response, "Add Announcement") # tests that announcement form takes valid input def test_add_announcement_form(self): form_data = {"title": "form test", "body": "test body"} form = AnnouncementForm(data=form_data) self.assertTrue(form.is_valid()) # tests that announcement form doesn't take invalid input def test_add_announcement_form_invalid(self): form_data = {} form = AnnouncementForm(data=form_data) self.assertFalse(form.is_valid()) # tests announcement form view def test_add_announcement_view(self): path = reverse('add_announcement') referer = reverse('index') post_dict = { 'title': 'test', 'target': 'https://www.google.com', 'body': 'announcement body' } response = self.client.post(path, post_dict, HTTP_REFERER=referer, follow=True) self.assertContains(response, "announcement body") # tests announcement form view with invalid input def test_add_announcement_view_invalid(self): path = reverse('add_announcement') post_dict = {} referer = reverse('index') response = self.client.post(path, post_dict, HTTP_REFERER=referer, follow=True) self.assertContains( response, 'Announcement was not successfully posted, because of the following errors: This field is required. This field is required.' )
class CalendarTestCase(TenantTestCase): """ tests basic appearance and functionality of calendar """ def setUp(self): self.client = TenantClient(self.tenant) self.user = User.objects.create(username='******', is_superuser=True, is_staff=True) self.client.force_login(self.user) self.rush_event = RushEvent.objects.create(name="rush_test", date=datetime.strptime( "2020-07-20", "%Y-%m-%d").date(), time=datetime.now(), location="test") self.social_event = SocialEvent.objects.create(name="social_test", date=datetime.strptime( "2020-07-20", "%Y-%m-%d").date(), time=datetime.now(), location="test") self.chapter_event = ChapterEvent.objects.create_chapter_event( name="chapter_test", date=datetime.strptime("2020-07-20", "%Y-%m-%d").date(), time=datetime.now(), is_public=False, location="test") def test_calendar_template(self): """ tests that the current month appears by default """ today = datetime.today() path = reverse('cal:index') response = self.client.post(path) self.assertContains(response, today.month) def test_rush_event_appears(self): """ tests that rush events are appearing on calendar """ path = "%s?month=7&year=2020" % reverse('cal:index') response = self.client.post(path) self.assertContains(response, '<a href="/rush/events/' + str(self.rush_event.pk)) def test_social_event_appears(self): """ tests that social events are appearing on calendar """ path = "%s?month=7&year=2020" % reverse('cal:index') response = self.client.post(path) self.assertContains( response, '<a href="/social_event' + str(self.social_event.pk)) def test_chapter_event_appears(self): """ tests that chapter events are appearing on calendar """ path = "%s?month=7&year=2020" % reverse('cal:index') response = self.client.post(path) self.assertContains(response, 'chapter_test') def test_chapter_event_recurrence(self): """ tests that chapter events are recurring properly """ event = ChapterEvent.objects.create_chapter_event( name="recurrence_test", date=datetime.strptime("2020-07-20", "%Y-%m-%d").date(), time=datetime.now(), is_public=False, location="test", recurring='Daily', end_date=datetime.strptime("2020-07-21", "%Y-%m-%d").date()) path = "%s?month=7&year=2020" % reverse('cal:index') response = self.client.post(path) self.assertContains( response, 'recurrence_test', count=6 ) # 2 events on calendar, 2 modal titles, 2 in modal details def test_month_overlap(self): """ tests that going to next month from december will run back to january """ get_data = {'month': '13', 'year': '2020'} path = reverse('cal:index') response = self.client.get(path, get_data) self.assertContains(response, 'January 2021') def test_month_underlap(self): """ tests that going to previous month from january will run back to december """ get_data = {'month': '0', 'year': '2020'} path = reverse('cal:index') response = self.client.get(path, get_data) self.assertContains(response, 'December 2019') def test_create_chapter_event_valid(self): """ tests creating chapter event from form data """ post_data = { 'name': 'test_chapter_event_create', 'location': 'test', 'date': datetime.strptime("2020-07-20", "%Y-%m-%d").date(), 'time': '12:00', 'recurring': 'None', 'end_date': '' } path = reverse('cal:create_chapter_event') referer = "%s?month=7&year=2020" % reverse('cal:index') response = self.client.post(path, post_data, HTTP_REFERER=referer, follow=True) self.assertContains(response, 'test_chapter_event_create') def test_create_chapter_event_invalid(self): """ tests creating chapter event with invalid data """ post_data = { 'name': 'test_chapter_event_create_invalid', 'location': 'test', 'date': '', 'time': '12:00', 'recurring': 'None', 'end_date': '' } # date is a required field form = ChapterEventForm(post_data) self.assertFalse(form.is_valid()) path = reverse('cal:create_chapter_event') referer = "%s?month=7&year=2020" % reverse('cal:index') response = self.client.post(path, post_data, HTTP_REFERER=referer, follow=True) self.assertContains(response, b'date') def test_create_chapter_event_recurring_no_end(self): """ tests creating a chapter event with a recurrence set but no end date """ post_data = { 'name': 'test_chapter_event_create_invalid', 'location': 'test', 'date': datetime.strptime("2020-07-20", "%Y-%m-%d").date(), 'time': '12:00', 'recurring': 'Daily', 'end_date': '' } # end date is required if event is recurrent form = ChapterEventForm(post_data) self.assertFalse(form.is_valid()) path = reverse('cal:create_chapter_event') referer = "%s?month=7&year=2020" % reverse('cal:index') response = self.client.post(path, post_data, HTTP_REFERER=referer, follow=True) self.assertContains(response, b'end_date') def test_create_chapter_event_get(self): """ test using get method on create_chapter_event """ path = reverse('cal:create_chapter_event') referer = "%s?month=7&year=2020" % reverse('cal:index') response = self.client.get(path, HTTP_REFERER=referer, follow=True) self.assertEqual(response.status_code, 404)
class AnnouncementViewTests(TenantTestCase): def setUp(self): # need a teacher and a student with known password so tests can log in as each, or could use force_login()? self.client = TenantClient(self.tenant) self.test_password = "******" # need a teacher before students can be created or the profile creation will fail when trying to notify self.test_teacher = User.objects.create_user( 'test_teacher', password=self.test_password, is_staff=True) self.test_student1 = User.objects.create_user( 'test_student', password=self.test_password) self.test_student2 = mommy.make(User) self.test_announcement = mommy.make(Announcement, draft=False) self.ann_pk = self.test_announcement.pk def assertRedirectsHome(self, url_name, args=None): self.assertRedirects( response=self.client.get(reverse(url_name, args=args)), expected_url='%s?next=%s' % (reverse('home'), reverse(url_name, args=args)), ) def assertRedirectsAdmin(self, url_name, args=None): self.assertRedirects( response=self.client.get(reverse(url_name, args=args)), expected_url='{}?next={}'.format('/admin/login/', reverse(url_name, args=args)), ) def assert200(self, url_name, args=None): self.assertEqual( self.client.get(reverse(url_name, args=args)).status_code, 200) def test_all_announcement_page_status_codes_for_anonymous(self): ''' If not logged in then all views should redirect to home page or admin ''' # go home self.assertRedirectsHome('announcements:list') self.assertRedirectsHome('announcements:list2') self.assertRedirectsHome('announcements:comment', args=[1]) self.assertRedirectsHome('announcements:list', args=[1]) # go admin self.assertRedirectsAdmin('announcements:create') self.assertRedirectsAdmin('announcements:delete', args=[1]) self.assertRedirectsAdmin('announcements:update', args=[1]) self.assertRedirectsAdmin('announcements:copy', args=[1]) self.assertRedirectsAdmin('announcements:publish', args=[1]) def test_all_announcement_page_status_codes_for_students(self): # log in a student success = self.client.login(username=self.test_student1.username, password=self.test_password) self.assertTrue(success) # all_fields = self.test_announcement._meta.get_fields() # for field in all_fields: # print(field, getattr(self.test_announcement, field.name)) # students should have access to these: self.assertEqual( self.client.get(reverse('announcements:list')).status_code, 200) self.assertEqual( self.client.get(reverse('announcements:list2')).status_code, 200) self.assertEqual( self.client.get(reverse('announcements:list', args=[self.ann_pk])).status_code, 200) # Announcement from setup() should appear in the list self.assertContains(self.client.get(reverse('announcements:list')), self.test_announcement.title) comment_response_get = self.client.get( reverse('announcements:comment', args=[self.ann_pk])) self.assertEqual(comment_response_get.status_code, 404) # Comments via POST only # Posting a comment redirects to the announcement commented on self.assertRedirects( response=self.client.post( reverse('announcements:comment', args=[self.ann_pk])), expected_url=reverse('announcements:list', args=[self.ann_pk]), ) # These views should redirect to admin login self.assertRedirectsAdmin('announcements:create') self.assertRedirectsAdmin('announcements:delete', args=[1]) self.assertRedirectsAdmin('announcements:update', args=[1]) self.assertRedirectsAdmin('announcements:copy', args=[1]) self.assertRedirectsAdmin('announcements:publish', args=[1]) def test_all_announcement_page_status_codes_for_teachers(self): # log in a teacher success = self.client.login(username=self.test_teacher.username, password=self.test_password) self.assertTrue(success) self.assertEqual( self.client.get(reverse('announcements:list')).status_code, 200) self.assertEqual( self.client.get(reverse('announcements:list2')).status_code, 200) self.assertEqual( self.client.get(reverse('announcements:list', args=[self.ann_pk])).status_code, 200) # Announcement from setup() should appear in the list self.assertContains(self.client.get(reverse('announcements:list')), self.test_announcement.title) comment_response_get = self.client.get( reverse('announcements:comment', args=[self.ann_pk])) self.assertEqual(comment_response_get.status_code, 404) # Comments via POST only # Posting a comment redirects to the announcement commented on self.assertRedirects( response=self.client.post( reverse('announcements:comment', args=[self.ann_pk])), expected_url=reverse('announcements:list', args=[self.ann_pk]), ) # These staff views should work self.assert200('announcements:create') self.assert200('announcements:update', args=[self.ann_pk]) self.assert200('announcements:copy', args=[self.ann_pk]) self.assert200('announcements:delete', args=[self.ann_pk]) self.assertRedirects( response=self.client.post( reverse('announcements:publish', args=[self.ann_pk])), expected_url=reverse('announcements:list', args=[self.ann_pk]), ) def test_draft_announcement(self): draft_announcement = mommy.make(Announcement) # default is draft self.assertTrue(draft_announcement.draft) # log in a student success = self.client.login(username=self.test_student1.username, password=self.test_password) self.assertTrue(success) # Students shoudn't see draft announcements in the list self.assertNotContains(self.client.get(reverse('announcements:list')), draft_announcement.title) # set draft to false draft_announcement.draft = False draft_announcement.save() # Student can now see it self.assertContains(self.client.get(reverse('announcements:list')), draft_announcement.title) # @patch('announcements.views.publish_announcement.apply_async') def test_publish_announcement(self): draft_announcement = mommy.make(Announcement) # log in a teacher success = self.client.login(username=self.test_teacher.username, password=self.test_password) self.assertTrue(success) # draft announcement should appear with a link to publish it. TODO This is crude, should be checking HTML? publish_link = reverse('announcements:publish', args=[draft_announcement.pk]) self.assertContains(self.client.get(reverse('announcements:list')), publish_link) # publish the announcement self.assertRedirects( response=self.client.post( reverse('announcements:publish', args=[draft_announcement.pk])), expected_url=reverse('announcements:list', args=[draft_announcement.pk]), ) # Should probably mock the task in above code, but don't know how... # Fake mock...? draft_announcement.draft = False draft_announcement.save() # publish link for this announcement should no longer appear in the list: self.assertNotContains(self.client.get(reverse('announcements:list')), publish_link) def test_create_announcement_form_past_date_auto_publish(self): draft_announcement = mommy.make( Announcement, datetime_released=timezone.now() - timedelta(days=3), auto_publish=True, ) form = AnnouncementForm(data=model_to_dict(draft_announcement)) self.assertFalse(form.is_valid())
class SocialTestCase(TenantTestCase): def setUp(self): self.client = TenantClient(self.tenant) self.admin = User.objects.create(username="******", is_staff=True, is_superuser=True) self.client.force_login(self.admin) self.event = SocialEvent.objects.create() # tests that the social page exists with the proper header def test_social_home_template(self): path = reverse('social') response = self.client.post(path) self.assertEqual(response.status_code, 200) self.assertContains(response, "<h1>Social</h1>") # tests that events in the database appear on the social page def test_event_on_home_page(self): path = reverse('social') response = self.client.post(path) self.assertContains(response, '<a href="social_event' + str(self.event.pk)) # tests the create event function def test_create_event(self): path = reverse('create_social_event') form_data = { 'name': 'test_name', 'date': '2001-01-01', 'time': '12:00', 'location': "test_location" } form = SocialEventForm(form_data) self.assertTrue(form.is_valid) response = self.client.post(path, form_data, HTTP_REFERER=reverse('social'), follow=True) self.assertContains(response, 'test_name -- Jan. 1, 2001, noon') # tests that the page for an individual social event exists def test_social_event_page_exists(self): path = reverse('social_event', kwargs=dict(event_id=self.event.pk)) response = self.client.post(path) self.assertEqual(response.status_code, 200) # tests that the social event page populates with relevant data def test_social_event_page_populates(self): path = reverse('social_event', kwargs=dict(event_id=self.event.pk)) response = self.client.post(path) content = str(response.content) self.assertTrue(re.findall('<h1.*test</h1>', content)) self.assertContains(response, "Jan. 1, 2000, noon") # tests the remove_social_event function def test_remove_social_event(self): path = reverse('remove_social_event', kwargs=dict(event_id=self.event.pk)) response = self.client.post(path, HTTP_REFERER=reverse('social'), follow=True) self.assertNotContains(response, "test_name -- Jan. 1, 2001, noon") self.assertRaises(SocialEvent.DoesNotExist, SocialEvent.objects.get, id=1) # tests that the add_to_list function works with both individual and multiple input def test_add_to_list_individual_and_multiple(self): path = reverse('add_to_list', kwargs=dict(event_id=self.event.pk)) post_data = { 'multiple_names': 'many_name1\nmany_name2\nmany_name3', 'name': 'individual_name' } referer = reverse('social_event', kwargs=dict(event_id=self.event.pk)) response = self.client.post(path, post_data, HTTP_REFERER=referer) self.assertTrue(Attendee.objects.filter(name="many_name1")) self.assertTrue(Attendee.objects.filter(name="many_name2")) self.assertTrue(Attendee.objects.filter(name="many_name3")) self.assertTrue(Attendee.objects.filter(name="individual_name")) # tests that add_to_list function works with only individual input def test_add_to_list_individual(self): path = reverse('add_to_list', kwargs=dict(event_id=self.event.pk)) post_data = {'multiple_names': '', 'name': 'individual_name'} referer = reverse('social_event', kwargs=dict(event_id=self.event.pk)) response = self.client.post(path, post_data, HTTP_REFERER=referer) self.assertTrue(Attendee.objects.filter(name="individual_name")) self.assertFalse(Attendee.objects.filter(name="many_name")) # tests that add_to_list function works with only multiple-name input def test_add_to_list_multiple(self): path = reverse('add_to_list', kwargs=dict(event_id=self.event.pk)) post_data = { 'multiple_names': 'many_name1\nmany_name2\nmany_name3', 'name': '' } referer = reverse('social_event', kwargs=dict(event_id=self.event.pk)) response = self.client.post(path, post_data, HTTP_REFERER=referer) self.assertTrue(Attendee.objects.filter(name="many_name1")) self.assertTrue(Attendee.objects.filter(name="many_name2")) self.assertTrue(Attendee.objects.filter(name="many_name3")) self.assertFalse(Attendee.objects.filter(name="individual_name"))
class EditChapterEventTestCase(TenantTestCase): """ tests editing chapter events """ def setUp(self): self.client = TenantClient(self.tenant) self.user = User.objects.create(username="******", is_superuser=True, is_staff=True) self.client.force_login(self.user) self.singular = ChapterEvent.objects.create_chapter_event( name="singular event", date=datetime.strptime("2020-07-20", "%Y-%m-%d").date(), time=datetime.now(), is_public=False, location="test") self.recurring = ChapterEvent.objects.create_chapter_event( name="recurring event", date=datetime.strptime("2020-07-20", "%Y-%m-%d").date(), time=datetime.now(), is_public=False, location="test", recurring='Daily', end_date=datetime.strptime("2020-07-26", "%Y-%m-%d").date()) def test_edit_singular(self): """ tests editing singular event """ post_data = { 'name': 'new_singular_name', 'date': "2020-07-21", 'time': '12:00:00', 'location': 'new_location', 'recurring': 'None', 'end_date': '2020-07-21', 'action': 'singular', } path = reverse('cal:edit_chapter_event', kwargs=dict(event_id=self.singular.pk)) referer = "%s?month=7&year=2020" % reverse('cal:index') response = self.client.post(path, post_data, HTTP_REFERER=referer, follow=True) self.assertNotContains(response, "singular event") try: ChapterEvent.objects.get(name="singular event") self.fail('event should have been deleted') except ChapterEvent.DoesNotExist: pass def test_edit_recursive(self): """ tests editing multiple events at once """ post_data = { 'name': 'new_recursive_name', 'date': '2020-07-21', 'time': '12:00:00', 'location': 'new_location', 'recurring': 'Daily', 'end_date': '2020-07-23', 'action': 'recursive', } path = reverse('cal:edit_chapter_event', kwargs=dict(event_id=self.recurring.pk)) referer = "%s?month=7&year=2020" % reverse('cal:index') response = self.client.post(path, post_data, HTTP_REFERER=referer, follow=True) self.assertNotContains(response, "recurring event") self.assertContains(response, "new_recursive_name", count=9) try: ChapterEvent.objects.get(name="recurring event") self.fail('event should have been deleted') except ChapterEvent.DoesNotExist: pass def test_edit_single_of_recursive(self): """ tests editing a single event that is recursive """ post_data = { 'name': 'new_recursive_name', 'date': '2020-07-21', 'time': '12:00:00', 'location': 'new_location', 'recurring': 'Daily', 'end_date': '2020-07-26', 'action': 'singular', } event = ChapterEvent.objects.get( date=datetime.strptime("2020-07-21", "%Y-%m-%d").date()) path = reverse('cal:edit_chapter_event', kwargs=dict(event_id=event.pk)) referer = "%s?month=7&year=2020" % reverse('cal:index') response = self.client.post(path, post_data, HTTP_REFERER=referer, follow=True) self.assertContains(response, 'new_recursive_name', count=3) self.assertContains(response, 'recurring event', count=18) def test_edit_first_of_recursive(self): """ tests editing single event that is recursive, where other events use this as a base """ post_data = { 'name': 'new_recursive_name', 'date': '2020-07-21', 'time': '12:00:00', 'location': 'new_location', 'recurring': 'Daily', 'end_date': '2020-07-26', 'action': 'singular', } path = reverse('cal:edit_chapter_event', kwargs=dict(event_id=self.recurring.pk)) referer = "%s?month=7&year=2020" % reverse('cal:index') response = self.client.post(path, post_data, HTTP_REFERER=referer, follow=True) self.assertContains(response, "new_recursive_name", count=3) self.assertContains(response, "recurring event", count=18) def test_edit_chapter_event_get_request(self): """ test using get request on edit_chapter_event, should return 404 """ path = reverse('cal:edit_chapter_event', kwargs=dict(event_id=self.singular.pk)) referer = "%s?month=7&year=2020" % reverse('cal:index') response = self.client.get(path, HTTP_REFERER=referer, follow=True) self.assertEqual(response.status_code, 404)
class SignupTestCase(TenantTestCase): def setUp(self): self.client = TenantClient(self.tenant) self.form_data = { 'username': '******', 'email': '*****@*****.**', 'first_name': 'Test_first', 'last_name': 'Test_last', 'verification_key': '9999', 'password1': 'c0mpl#x_p@$$w0rd', 'password2': 'c0mpl#x_p@$$w0rd' } # tests that signup form accepts valid input def test_signup_form(self): form = SignupForm(self.form_data) self.assertTrue(form.is_valid()) # tests that form rejects passwords that are too simple def test_simple_password(self): self.form_data.update({ 'password1': 'password', 'password2': 'password' }) form = SignupForm(self.form_data) self.assertFalse(form.is_valid()) self.assertIn('This password is too common', form.errors['password2'][0]) # tests that form rejects passwords that don't match def test_passwords_not_match(self): self.form_data.update({ 'password1': 'password1', 'password2': 'password2' }) form = SignupForm(self.form_data) self.assertFalse(form.is_valid()) self.assertEqual("The two password fields didn't match.", form.errors['password2'][0]) # tests that form rejects usernames that are already in use def test_username_already_taken(self): User.objects.create(username="******") form = SignupForm(self.form_data) self.assertFalse(form.is_valid()) self.assertEqual("A user with that username already exists.", form.errors['username'][0]) # tests that the user is redirected to successful verification page def test_valid_input_template(self): post_data = self.form_data path = reverse('signup') response = self.client.post(path, post_data) self.assertContains(response, "Thank you for signing up for GreekRho") # tests that inactive users can activate with activate view def test_activate_view(self): user = User.objects.create(username="******", is_active="False") token = account_activation_token.make_token(user) path = reverse('activate', kwargs=dict(user_id=user.pk, token=token)) response = self.client.post(path) self.assertContains(response, "Your account has been verified!") # tests user that does not exist def test_activate_user_does_not_exist(self): user = User.objects.create(username="******", is_active="False") token = account_activation_token.make_token(user) path = reverse('activate', kwargs=dict(user_id=user.pk, token=token)) user.delete() response = self.client.post(path) self.assertContains(response, "Activation link is invalid") # tests invalid activation token def test_activate_user_invalid_token(self): user = User.objects.create(username="******", is_active="False") token = "999-99999999999999999999" path = reverse('activate', kwargs=dict(user_id=user.pk, token=token)) response = self.client.post(path) self.assertContains(response, "Activation link is invalid") # tests logout def test_logout(self): user = User.objects.create(username="******") self.client.force_login(user) path = reverse('logout') response = self.client.post(path, follow=True) self.assertContains(response, "Login") # tests forgot_credentials view under a get method def test_forgot_credentials_get(self): path = reverse('forgot_credentials') response = self.client.get(path) self.assertContains(response, "Forgot Credentials?") # tests forgot_credentials view under a post method def test_forgot_credentials_post(self): user = User.objects.create(username="******", email="*****@*****.**") post_data = {'email': '*****@*****.**'} path = reverse('forgot_credentials') response = self.client.post(path, post_data, HTTP_REFERER=path, follow=True) self.assertContains(response, "Email with password reset link has been sent.") # tests forgot_credentials view when email is not unique def test_forgot_credentials_common_email(self): user1 = User.objects.create(username="******", email="*****@*****.**") user2 = User.objects.create(username="******", email="*****@*****.**") post_data = {'email': '*****@*****.**'} path = reverse('forgot_credentials') response = self.client.post(path, post_data, HTTP_REFERER=path, follow=True) self.assertContains( response, "Multiple accounts exist with the same email address.") # tests forgot_credentials view when email does not exist def test_forgot_credentials_email_dne(self): post_data = {'email': '*****@*****.**'} path = reverse('forgot_credentials') response = self.client.post(path, post_data, HTTP_REFERER=path, follow=True) self.assertContains(response, "User with this email does not exist") # tests reset_password view under a get method def test_reset_password_view_get(self): user = User.objects.create(username="******", email="*****@*****.**") token = account_activation_token.make_token(user) path = reverse('reset_password', kwargs=dict(user_id=user.pk, token=token)) response = self.client.get(path) self.assertContains(response, "Reset Password") # tests reset_password view under a post method def test_reset_password_view_post(self): user = User.objects.create(username="******", email="*****@*****.**") user.set_password("originalpassword") user.save() token = account_activation_token.make_token(user) path = reverse('reset_password', kwargs=dict(user_id=user.pk, token=token)) post_data = { 'new_password1': 'testpassword', 'new_password2': 'testpassword' } response = self.client.post(path, post_data) user.refresh_from_db() self.assertContains(response, "Your password has been changed.") self.assertFalse(user.check_password("originalpassword")) self.assertTrue(user.check_password("testpassword")) # tests reset password with invalid token def test_reset_password_invalid_token(self): user = User.objects.create(username="******", email="*****@*****.**") token = '999-99999999999999999999' path = reverse('reset_password', kwargs=dict(user_id=user.pk, token=token)) response = self.client.get(path) self.assertContains(response, "Invalid token!") # tests reset password with passwords that don't match def test_reset_password_no_match(self): user = User.objects.create(username="******", email="*****@*****.**") user.set_password("originalpassword") user.save() token = account_activation_token.make_token(user) path = reverse('reset_password', kwargs=dict(user_id=user.pk, token=token)) post_data = { 'new_password1': 'testpassword1', 'new_password2': 'testpassword2' } response = self.client.post(path, post_data, HTTP_REFERER=path, follow=True) user.refresh_from_db() self.assertContains(response, "The two password fields") self.assertFalse(user.check_password('testpassword1')) self.assertFalse(user.check_password('testpassword2')) self.assertTrue(user.check_password("originalpassword")) def test_reset_password_common(self): user = User.objects.create(username="******", email="*****@*****.**") user.set_password("originalpassword") user.save() token = account_activation_token.make_token(user) path = reverse('reset_password', kwargs=dict(user_id=user.pk, token=token)) post_data = {'new_password1': 'password', 'new_password2': 'password'} response = self.client.post(path, post_data, HTTP_REFERER=path, follow=True) user.refresh_from_db() self.assertContains(response, "This password is too common") self.assertFalse(user.check_password('password')) self.assertTrue(user.check_password('originalpassword')) def test_reset_password_short(self): user = User.objects.create(username="******", email="*****@*****.**") user.set_password("originalpassword") user.save() token = account_activation_token.make_token(user) path = reverse('reset_password', kwargs=dict(user_id=user.pk, token=token)) post_data = {'new_password1': 'xyzabc', 'new_password2': 'xyzabc'} response = self.client.post(path, post_data, HTTP_REFERER=path, follow=True) user.refresh_from_db() self.assertContains(response, "This password is too short.") self.assertFalse(user.check_password('xyzabc')) self.assertTrue(user.check_password('originalpassword'))
class NotificationViewTests(ViewTestUtilsMixin, TenantTestCase): # includes some basic model data # fixtures = ['initial_data.json'] def setUp(self): self.client = TenantClient(self.tenant) # need a teacher and a student with known password so tests can log in as each, or could use force_login()? self.test_password = "******" # need a teacher before students can be created or the profile creation will fail when trying to notify self.test_teacher = User.objects.create_user('test_teacher', password=self.test_password, is_staff=True) self.test_student1 = User.objects.create_user('test_student', password=self.test_password) self.test_student2 = baker.make(User) def test_all_notification_page_status_codes_for_anonymous(self): ''' If not logged in then all views should redirect to home page ''' self.assertRedirectsLogin('notifications:list') self.assertRedirectsLogin('notifications:list_unread') self.assertRedirectsLogin('notifications:read', kwargs={'id': 1}) self.assertRedirectsLogin('notifications:read_all') self.assertRedirectsLogin('notifications:ajax') # this doesn't make sense. Should 404 self.assertRedirectsLogin('notifications:ajax_mark_read') # this doesn't make sense. Should 404 def test_all_notification_page_status_codes_for_students(self): # log in student1 success = self.client.login(username=self.test_student1.username, password=self.test_password) self.assertTrue(success) # Accessible views: self.assertEqual(self.client.get(reverse('notifications:list')).status_code, 200) self.assertEqual(self.client.get(reverse('notifications:list_unread')).status_code, 200) self.assertRedirects( response=self.client.get(reverse('notifications:read_all')), expected_url=reverse('notifications:list'), ) # Inaccessible views: self.assertEqual(self.client.get(reverse('notifications:ajax_mark_read')).status_code, 404) # requires AJAX self.assertEqual(self.client.get(reverse('notifications:ajax')).status_code, 404) # requires POST def test_all_notification_page_status_codes_for_teachers(self): # log in student1 success = self.client.login(username=self.test_teacher.username, password=self.test_password) self.assertTrue(success) # Accessible views: self.assertEqual(self.client.get(reverse('notifications:list')).status_code, 200) self.assertEqual(self.client.get(reverse('notifications:list_unread')).status_code, 200) self.assertRedirects( response=self.client.get(reverse('notifications:read_all')), expected_url=reverse('notifications:list'), ) # Inaccessible views: self.assertEqual(self.client.get(reverse('notifications:ajax_mark_read')).status_code, 404) # requires POST self.assertEqual(self.client.get(reverse('notifications:ajax')).status_code, 404) # requires POST def test_ajax_mark_read(self): """ Marks a Notification as read via Ajax (by setting unread = FALSE) """ # log in student1 success = self.client.login(username=self.test_student1.username, password=self.test_password) self.assertTrue(success) notification = baker.make('notifications.Notification', recipient=self.test_student1) # make sure it is unread self.assertTrue(notification.unread) # mark it as read via the view being tested ajax_data = { 'id': notification.id, } response = self.client.post( reverse('notifications:ajax_mark_read'), data=ajax_data, HTTP_X_REQUESTED_WITH='XMLHttpRequest', ) self.assertEqual(response.status_code, 200) def test_ajax(self): # log in student1 success = self.client.login(username=self.test_student1.username, password=self.test_password) self.assertTrue(success) response = self.client.post( reverse('notifications:ajax'), HTTP_X_REQUESTED_WITH='XMLHttpRequest', ) self.assertEqual(response.status_code, 200)
class AnnouncementViewTests(ViewTestUtilsMixin, TenantTestCase): def setUp(self): # need a teacher and a student with known password so tests can log in as each, or could use force_login()? self.client = TenantClient(self.tenant) self.test_password = "******" # need a teacher before students can be created or the profile creation will fail when trying to notify self.test_teacher = User.objects.create_user( 'test_teacher', password=self.test_password, is_staff=True) self.test_student1 = User.objects.create_user( 'test_student', password=self.test_password) self.test_student2 = baker.make(User) self.test_announcement = baker.make(Announcement, draft=False) self.ann_pk = self.test_announcement.pk def test_all_announcement_page_status_codes_for_anonymous(self): ''' If not logged in then all views should redirect to home page or admin ''' # go home self.assertRedirectsLogin('announcements:list') self.assertRedirectsLogin('announcements:list2') self.assertRedirectsLogin('announcements:comment', args=[1]) self.assertRedirectsLogin('announcements:list', args=[1]) # go admin self.assertRedirectsAdmin('announcements:create') self.assertRedirectsAdmin('announcements:delete', args=[1]) self.assertRedirectsAdmin('announcements:update', args=[1]) self.assertRedirectsAdmin('announcements:copy', args=[1]) self.assertRedirectsAdmin('announcements:publish', args=[1]) def test_all_announcement_page_status_codes_for_students(self): # log in a student success = self.client.login(username=self.test_student1.username, password=self.test_password) self.assertTrue(success) # all_fields = self.test_announcement._meta.get_fields() # for field in all_fields: # print(field, getattr(self.test_announcement, field.name)) # students should have access to these: self.assertEqual( self.client.get(reverse('announcements:list')).status_code, 200) self.assertEqual( self.client.get(reverse('announcements:list2')).status_code, 200) self.assertEqual( self.client.get(reverse('announcements:list', args=[self.ann_pk])).status_code, 200) # Announcement from setup() should appear in the list self.assertContains(self.client.get(reverse('announcements:list')), self.test_announcement.title) comment_response_get = self.client.get( reverse('announcements:comment', args=[self.ann_pk])) self.assertEqual(comment_response_get.status_code, 404) # Comments via POST only # Posting a comment redirects to the announcement commented on self.assertRedirects( response=self.client.post( reverse('announcements:comment', args=[self.ann_pk])), expected_url=reverse('announcements:list', args=[self.ann_pk]), ) # These views should redirect to admin login self.assertRedirectsAdmin('announcements:create') self.assertRedirectsAdmin('announcements:delete', args=[1]) self.assertRedirectsAdmin('announcements:update', args=[1]) self.assertRedirectsAdmin('announcements:copy', args=[1]) self.assertRedirectsAdmin('announcements:publish', args=[1]) def test_all_announcement_page_status_codes_for_teachers(self): # log in a teacher success = self.client.login(username=self.test_teacher.username, password=self.test_password) self.assertTrue(success) self.assert200('announcements:list') self.assert200('announcements:list2') self.assert200('announcements:list', args=[self.ann_pk]) # Announcement from setup() should appear in the list self.assertContains(self.client.get(reverse('announcements:list')), self.test_announcement.title) comment_response_get = self.client.get( reverse('announcements:comment', args=[self.ann_pk])) self.assertEqual(comment_response_get.status_code, 404) # Comments via POST only # Posting a comment redirects to the announcement commented on self.assertRedirects( response=self.client.post( reverse('announcements:comment', args=[self.ann_pk])), expected_url=reverse('announcements:list', args=[self.ann_pk]), ) # These staff views should work self.assert200('announcements:create') self.assert200('announcements:update', args=[self.ann_pk]) self.assert200('announcements:copy', args=[self.ann_pk]) self.assert200('announcements:delete', args=[self.ann_pk]) self.assertRedirects( response=self.client.post( reverse('announcements:publish', args=[self.ann_pk])), expected_url=reverse('announcements:list', args=[self.ann_pk]), ) def test_draft_announcement(self): draft_announcement = baker.make(Announcement) # default is draft self.assertTrue(draft_announcement.draft) # log in a student success = self.client.login(username=self.test_student1.username, password=self.test_password) self.assertTrue(success) # Students shoudn't see draft announcements in the list self.assertNotContains(self.client.get(reverse('announcements:list')), draft_announcement.title) # set draft to false draft_announcement.draft = False draft_announcement.save() # Student can now see it self.assertContains(self.client.get(reverse('announcements:list')), draft_announcement.title) # @patch('announcements.views.publish_announcement.apply_async') def test_publish_announcement(self): draft_announcement = baker.make(Announcement) # log in a teacher success = self.client.login(username=self.test_teacher.username, password=self.test_password) self.assertTrue(success) # draft announcement should appear with a link to publish it. TODO This is crude, should be checking HTML? publish_link = reverse('announcements:publish', args=[draft_announcement.pk]) self.assertContains(self.client.get(reverse('announcements:list')), publish_link) # publish the announcement self.assertRedirects( response=self.client.post( reverse('announcements:publish', args=[draft_announcement.pk])), expected_url=reverse('announcements:list', args=[draft_announcement.pk]), ) # Should probably mock the task in above code, but don't know how... # Fake mock...? draft_announcement.draft = False draft_announcement.save() # publish link for this announcement should no longer appear in the list: self.assertNotContains(self.client.get(reverse('announcements:list')), publish_link) def test_create_announcement_from_past_date_auto_publish(self): draft_announcement = baker.make( Announcement, datetime_released=timezone.now() - timedelta(days=3), auto_publish=True, ) form = AnnouncementForm(data=model_to_dict(draft_announcement)) self.assertFalse(form.is_valid()) def test_comment_on_announcement_by_student(self): # log in a student success = self.client.login(username=self.test_student1.username, password=self.test_password) self.assertTrue(success) form_data = { 'comment_text': "test comment", } response = self.client.post( reverse('announcements:comment', args=[self.test_announcement.id]), form_data) self.assertEqual(response.status_code, 404) # invalid submit button # make sure it was submitted with the 'comment_button' form_data['comment_button'] = True response = self.client.post(reverse('announcements:comment', args=[self.test_announcement.id]), data=form_data) # Empty comment strings should be replaced with blank string or we get an error # WHY? THIS SEEMS SILLY! THE FORM SHOULDN'T VALIDATE IF THERE IS NO COMMENT! # Old code not relevant any more? # form_data['comment_text'] = None # response = self.client.post( # reverse('announcements:comment', args=[self.test_announcement.id]), # data=form_data # ) # self.assertRedirects(response, self.test_announcement.get_absolute_url()) def test_copy_announcement(self): # log in a teacher success = self.client.login(username=self.test_teacher.username, password=self.test_password) self.assertTrue(success) # hit the view as a get request first, to load a copy of the announcement in the form response = self.client.get( reverse('announcements:copy', args=[self.test_announcement.id]), ) self.assertEqual(response.status_code, 200) # Don't know how to get the form data from the get request... # https://stackoverflow.com/questions/61532873/how-to-plug-the-reponse-of-a-django-view-get-request-into-the-same-view-as-a-pos # So, instead we'll manually create valid form data for post request: form_data = { 'title': "Copy test", 'content': "test content", 'datetime_released': "2006-10-25 14:30:59" # https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-DATETIME_INPUT_FORMATS } response = self.client.post(reverse('announcements:copy', args=[self.test_announcement.id]), data=form_data) # Get the newest announcement new_ann = Announcement.objects.latest('datetime_created') self.assertEqual(new_ann.title, "Copy test") # if successful, should redirect to the new announcement self.assertRedirects(response, new_ann.get_absolute_url())
class RusheeFilterTestCase(TenantTestCase): """ tests the filter function for the rushee template """ def setUp(self): self.client = TenantClient(self.tenant) self.u = User.objects.create(username="******") self.client.force_login(self.u) self.r1 = Rushee.objects.create(name="test1") self.r2 = Rushee.objects.create(name="test2") def test_next_rushee_button_no_filter(self): """ tests next button when the filter is not set """ path = reverse('rush:rushee', kwargs=dict(num=self.r1.pk)) response = self.client.post(path) self.assertContains( response, '<a href="/rush/rushee' + str(self.r2.pk) + '" id="next-rushee"') def test_next_rushee_filter(self): """ tests next button when filter is set """ session = self.client.session session['rushee_filter'] = dict(name='test1') session.save() path = reverse('rush:rushee', kwargs=dict(num=self.r1.pk)) response = self.client.post(path) self.assertNotContains( response, '<a href="/rush/rushee' + str(self.r2.pk) + '" id="next-rushee"') def test_prev_rushee_button_no_filter(self): """ tests previous button when filter is not set """ path = reverse('rush:rushee', kwargs=dict(num=self.r2.pk)) response = self.client.post(path) self.assertContains( response, '<a href="/rush/rushee' + str(self.r1.pk) + '" id="prev-rushee"') def test_prev_rushee_filter(self): """ tests previous button when the filter is set """ session = self.client.session session['rushee_filter'] = dict(name='test2') session.save() path = reverse('rush:rushee', kwargs=dict(num=self.r2.pk)) response = self.client.post(path) self.assertNotContains( response, '<a href="/rush/rushee' + str(self.r1.pk) + '" id="prev-rushee"') def test_cut_filter_on_next(self): """ tests the next button when the cut filter is set """ self.r2.cut = True self.r2.save() session = self.client.session session['rushee_filter'] = dict(cut=True) session.save() path = reverse('rush:rushee', kwargs=dict(num=self.r1.pk)) response = self.client.post(path) self.assertContains( response, '<a href="/rush/rushee' + str(self.r2.pk) + '" id="next-rushee"') def test_cut_filter_on_prev(self): """ tests the previous button when the cut filter is set """ self.r1.cut = True self.r1.save() session = self.client.session session['rushee_filter'] = dict(cut=True) session.save() path = reverse('rush:rushee', kwargs=dict(num=self.r2.pk)) response = self.client.post(path) self.assertContains( response, '<a href="/rush/rushee' + str(self.r1.pk) + '" id="prev-rushee"') def test_cut_filter_off_next(self): """ tests the next button when the cut filter is off """ self.r2.cut = True self.r2.save() path = reverse('rush:rushee', kwargs=dict(num=self.r1.pk)) response = self.client.post(path) self.assertNotContains( response, '<a href="/rush/rushee' + str(self.r2.pk) + '" id="next-rushee"') def test_cut_filter_off_prev(self): """ tests the previous button when the cut filter is off """ self.r1.cut = True self.r1.save() path = reverse('rush:rushee', kwargs=dict(num=self.r2.pk)) response = self.client.post(path) self.assertNotContains( response, '<a href="/rush/rushee' + str(self.r1.pk) + '" id="prev-rushee"') def test_set_filter(self): post_data = {'name': 'test'} path = reverse('rush:filter_rushees') self.client.post(path, post_data) session = self.client.session self.assertEqual(session['rushee_filter'], dict(name='test')) def test_set_filter_get(self): path = reverse('rush:filter_rushees') request = self.client.get(path) self.assertEqual(request.status_code, 404) def test_set_filter_empty(self): """ tests setting filter with empty post """ post_data = {} path = reverse('rush:filter_rushees') self.client.post(path, post_data) try: filter = self.client.session['rushee_filter'] self.fail("session['rushee_filter'] object should not exist") except KeyError: pass def test_set_filter_form_errors(self): """ tests setting filter with form errors - major is too long """ post_data = {'major': 'abcdefghijklmnopqrstuvwxyz'} path = reverse('rush:filter_rushees') response = self.client.post(path, post_data) self.assertEqual(response.content, b'major') def test_remove_filter(self): self.client.session['rushee_filter'] = dict(name='test') self.client.session.save() path = reverse('rush:clear_rushees_filter') self.client.post(path) try: filter = self.client.session['rushee_filter'] self.fail("session['rushee_filter'] object should not exist") except KeyError: pass