From 0d3f74c7556ebfe4323558c933eb0480a9cc3707 Mon Sep 17 00:00:00 2001 From: Charles Connell Date: Sun, 26 Jan 2014 15:31:38 -0500 Subject: [PATCH] Testing for karma events #306 --- karmaworld/apps/document_upload/tests.py | 30 +++-- karmaworld/apps/notes/models.py | 3 +- karmaworld/apps/notes/search.py | 25 +++- karmaworld/apps/notes/tests.py | 27 ++-- karmaworld/apps/users/tests.py | 159 +++++++++++++++++++++++ 5 files changed, 217 insertions(+), 27 deletions(-) create mode 100644 karmaworld/apps/users/tests.py diff --git a/karmaworld/apps/document_upload/tests.py b/karmaworld/apps/document_upload/tests.py index 88600f0..507718f 100644 --- a/karmaworld/apps/document_upload/tests.py +++ b/karmaworld/apps/document_upload/tests.py @@ -5,6 +5,7 @@ when you run "manage.py test". Replace this with more appropriate tests for your application. """ from django.contrib.sessions.backends.db import SessionStore +from django.http import HttpRequest from django.test import TestCase, Client from karmaworld.apps.courses.models import Course @@ -16,9 +17,6 @@ from karmaworld.apps.notes.models import find_orphan_notes TEST_USERNAME = 'alice' -class _FakeRequest: - def __init__(self, session): - self.session = session class ConversionTest(TestCase): @@ -84,8 +82,10 @@ class ConversionTest(TestCase): user=user) note = Note.objects.all()[0] self.assertEqual(note.user, user) - karma_event = NoteKarmaEvent.objects.all()[0] - self.assertEqual(karma_event.user, user) + try: + NoteKarmaEvent.objects.get(note=note, event_type=NoteKarmaEvent.UPLOAD) + except ObjectDoesNotExist: + self.fail("Karma event not created") def testSessionUserAssociation2(self): """If a user logs in after convert_raw_document has finished, @@ -100,11 +100,15 @@ class ConversionTest(TestCase): 'mimetype': 'text/plain'}) user = User(username=TEST_USERNAME) user.save() - find_orphan_notes(None, user=user, request=_FakeRequest(s)) + request = HttpRequest() + request.session = s + find_orphan_notes(None, user=user, request=request) note = Note.objects.all()[0] self.assertEqual(note.user, user) - karma_event = NoteKarmaEvent.objects.all()[0] - self.assertEqual(karma_event.user, user) + try: + NoteKarmaEvent.objects.get(note=note, event_type=NoteKarmaEvent.UPLOAD) + except ObjectDoesNotExist: + self.fail("Karma event not created") def testSessionUserAssociation3(self): """If a user logs in WHILE convert_raw_document is running, @@ -114,7 +118,9 @@ class ConversionTest(TestCase): s.save() user = User(username=TEST_USERNAME) user.save() - find_orphan_notes(None, user=user, request=_FakeRequest(s)) + request = HttpRequest() + request.session = s + find_orphan_notes(None, user=user, request=request) self.doConversionForPost({'fp_file': 'https://www.filepicker.io/api/file/S2lhT3INSFCVFURR2RV7', 'course': str(self.course.id), 'name': 'graph3.txt', @@ -123,5 +129,7 @@ class ConversionTest(TestCase): session=s) note = Note.objects.all()[0] self.assertEqual(note.user, user) - karma_event = NoteKarmaEvent.objects.all()[0] - self.assertEqual(karma_event.user, user) + try: + NoteKarmaEvent.objects.get(note=note, event_type=NoteKarmaEvent.UPLOAD) + except ObjectDoesNotExist: + self.fail("Karma event not created") diff --git a/karmaworld/apps/notes/models.py b/karmaworld/apps/notes/models.py index 309d202..eec394f 100644 --- a/karmaworld/apps/notes/models.py +++ b/karmaworld/apps/notes/models.py @@ -387,7 +387,8 @@ def note_delete_receiver(sender, **kwargs): index = SearchIndex() index.remove_note(note) - GenericKarmaEvent.create_event(note.user, note.name, GenericKarmaEvent.NOTE_DELETED) + if note.user: + GenericKarmaEvent.create_event(note.user, note.name, GenericKarmaEvent.NOTE_DELETED) class UserUploadMapping(models.Model): diff --git a/karmaworld/apps/notes/search.py b/karmaworld/apps/notes/search.py index d578f5d..3ae352d 100644 --- a/karmaworld/apps/notes/search.py +++ b/karmaworld/apps/notes/search.py @@ -4,6 +4,7 @@ import calendar import time +import uuid import indextank.client as itc import karmaworld.secret.indexden as secret @@ -51,12 +52,21 @@ class SearchIndex(object): __metaclass__ = Singleton - def __init__(self): - api_client = itc.ApiClient(secret.PRIVATE_URL) - if not api_client.get_index(secret.INDEX).exists(): - api_client.create_index(secret.INDEX, {'public_search': False}) + def __init__(self, testing=False): + if not testing: + self.setup() - self.index = api_client.get_index(secret.INDEX) + def setup(self, testing=False): + if testing: + self.index_name = uuid.uuid4().hex + else: + self.index_name = secret.INDEX + + self.api_client = itc.ApiClient(secret.PRIVATE_URL) + if not self.api_client.get_index(self.index_name).exists(): + self.api_client.create_index(self.index_name, {'public_search': False}) + + self.index = self.api_client.get_index(self.index_name) while not self.index.has_started(): time.sleep(0.5) @@ -67,6 +77,11 @@ class SearchIndex(object): # "Relevance" is a black box provided by IndexDen. self.index.add_function(0, 'relevance * log(doc.var[0])') + def delete_index(self): + """This is meant for test cases that want to clean up + after themselves.""" + self.api_client.delete_index(self.index_name) + @staticmethod def _tags_to_str(tags): return ' '.join([str(tag) for tag in tags.all()]) diff --git a/karmaworld/apps/notes/tests.py b/karmaworld/apps/notes/tests.py index c0daea3..c313c8d 100644 --- a/karmaworld/apps/notes/tests.py +++ b/karmaworld/apps/notes/tests.py @@ -4,12 +4,6 @@ """ """ import karmaworld.secret.indexden as secret -import uuid - -# This needs to happen before other things -# are imported to avoid putting test data -# in our production search index -secret.INDEX = uuid.uuid4().hex import datetime from django.test import TestCase @@ -18,9 +12,13 @@ from karmaworld.apps.notes.search import SearchIndex from karmaworld.apps.notes.models import Note from karmaworld.apps.courses.models import Course from karmaworld.apps.courses.models import School -import indextank.client as itc -class TestNoes(TestCase): +# Tell SearchIndex to put its entries +# in a separate index +secret.testing = True + + +class TestNotes(TestCase): def setUp(self): # create base values to test db representations @@ -50,12 +48,17 @@ class TestNoes(TestCase): self.note.text = "This is the plaintext version of a note. It's pretty cool. Alpaca." self.note.save() + @classmethod + def setUpClass(cls): + index = SearchIndex(testing=True) + index.setup(testing=True) + @classmethod def tearDownClass(cls): """Delete the test index that was automatically created by notes/search.py""" - api = itc.ApiClient(secret.PRIVATE_URL) - api.delete_index(secret.INDEX) + index = SearchIndex() + index.delete_index() def test_course_fkey(self): self.assertEqual(self.course, self.note.course) @@ -103,4 +106,8 @@ class TestNoes(TestCase): results = index.search('alpaca', self.note.course.id) self.assertIn(self.note.id, results.ordered_ids) + # Delete the note, see if it's removed from the index + self.note.delete() + results = index.search('alpaca') + self.assertNotIn(self.note.id, results.ordered_ids) diff --git a/karmaworld/apps/users/tests.py b/karmaworld/apps/users/tests.py new file mode 100644 index 0000000..d4e2b11 --- /dev/null +++ b/karmaworld/apps/users/tests.py @@ -0,0 +1,159 @@ +#!/usr/bin/env python +# -*- coding:utf8 -*- +# Copyright (C) 2013 FinalsClub Foundation +import datetime +from django.contrib.sessions.backends.db import SessionStore +from django.core.exceptions import ObjectDoesNotExist +from django.http import HttpRequest +from django.test import TestCase + +from django.contrib.auth.models import User +from karmaworld.apps.courses.views import flag_course +from karmaworld.apps.notes.models import Note +from karmaworld.apps.courses.models import Course +from karmaworld.apps.courses.models import School +from karmaworld.apps.notes.search import SearchIndex +from karmaworld.apps.notes.views import thank_note, flag_note, downloaded_note +from karmaworld.apps.users.models import NoteKarmaEvent, GenericKarmaEvent, CourseKarmaEvent, give_email_confirm_karma + + +class TestUsers(TestCase): + + def setUp(self): + # create base values to test db representations + self.now = datetime.datetime.utcnow() + + # create a school to satisfy course requirements + self.school = School() + self.school.name = 'Marshall College' + self.school.save() + + # create a course to test relationships + self.course = Course() + self.course.school = self.school + self.course.name = u'Archaeology 101' + self.course.save() + # override Course.save() appending an ID to the slug + self.course.slug = u'archaeology-101' + self.course.save() + + self.user1 = User(username='Alice') + self.user1.save() + + self.user2 = User(username='Bob') + self.user2.save() + + # create a note to test against + self.note = Note() + self.note.course = self.course + self.note.name = u"Lecture notes concerning the use of therefore ∴" + self.note.text = "This is the plaintext version of a note. It's pretty cool." + self.note.user = self.user1 + self.note.save() + + self.request1 = HttpRequest() + self.request1.user = self.user1 + self.request1.method = 'POST' + self.request1.META = {'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest'} + self.request1.session = SessionStore() + + self.request2 = HttpRequest() + self.request2.user = self.user2 + self.request2.method = 'POST' + self.request2.META = {'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest'} + self.request2.session = SessionStore() + + @classmethod + def setUpClass(cls): + index = SearchIndex(testing=True) + index.setup(testing=True) + + @classmethod + def tearDownClass(cls): + """Delete the test index that was automatically + created by notes/search.py""" + index = SearchIndex() + index.delete_index() + + def test_thank_own_note_karma(self): + """Make sure you don't get karma for thanking your own note""" + thank_note(self.request1, self.note.pk) + try: + NoteKarmaEvent.objects.get(note=self.note) + self.fail("You can't thank your own note") + except ObjectDoesNotExist: + pass + + def test_thank_anothers_note_karma(self): + """Get karma for having your note thanked""" + thank_note(self.request2, self.note.pk) + try: + NoteKarmaEvent.objects.get(note=self.note) + except ObjectDoesNotExist: + self.fail("Karma event not created") + + def test_note_deleted_karma(self): + """Lose karma if your note is deleted""" + thank_note(self.request2, self.note.pk) + self.note.delete() + try: + GenericKarmaEvent.objects.get(event_type=GenericKarmaEvent.NOTE_DELETED) + except ObjectDoesNotExist: + self.fail("Karma event not created") + try: + NoteKarmaEvent.objects.get(note=self.note) + self.fail("Karma event not deleted") + except ObjectDoesNotExist: + pass + + def test_note_give_flag_karma(self): + """Lose karma for flagging a note""" + flag_note(self.request2, self.note.pk) + try: + NoteKarmaEvent.objects.get(event_type=NoteKarmaEvent.GIVE_FLAG, user=self.user2) + except ObjectDoesNotExist: + self.fail("Karma event not created") + + def test_course_give_flag_karma(self): + """Lose karma for flagging a course""" + flag_course(self.request2, self.course.pk) + try: + CourseKarmaEvent.objects.get(event_type=CourseKarmaEvent.GIVE_FLAG, user=self.user2) + except ObjectDoesNotExist: + self.fail("Karma event not created") + + def test_note_get_flagged_karma(self): + """Lose karma for having your note flagged many times""" + flag_note(self.request2, self.note.pk) + flag_note(self.request2, self.note.pk) + flag_note(self.request2, self.note.pk) + flag_note(self.request2, self.note.pk) + flag_note(self.request2, self.note.pk) + flag_note(self.request2, self.note.pk) + try: + NoteKarmaEvent.objects.get(event_type=NoteKarmaEvent.GET_FLAGGED, user=self.user1) + except ObjectDoesNotExist: + self.fail("Karma event not created") + + def test_note_download_karma(self): + """You lose karma for downloading a note, person who uploaded it gains karma""" + downloaded_note(self.request2, self.note.pk) + try: + NoteKarmaEvent.objects.get(event_type=NoteKarmaEvent.DOWNLOADED_NOTE, user=self.user2) + except ObjectDoesNotExist: + self.fail("Karma event not created") + try: + NoteKarmaEvent.objects.get(event_type=NoteKarmaEvent.HAD_NOTE_DOWNLOADED, user=self.user1) + except ObjectDoesNotExist: + self.fail("Karma event not created") + + def test_email_confirm_karma(self): + class FakeEmailAddress: + user = self.user1 + email = self.user1.email + + give_email_confirm_karma(None, email_address=FakeEmailAddress()) + try: + GenericKarmaEvent.objects.get(event_type=GenericKarmaEvent.EMAIL_CONFIRMED, user=self.user1) + except ObjectDoesNotExist: + self.fail("Karma event not created") -- 2.25.1