Skip to content
Open

Dev #27

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 13 additions & 14 deletions mathstack/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@

from api import models as api_models
from django.contrib.auth.signals import user_logged_in
from django.core.exceptions import ObjectDoesNotExist
from django.db import models
from django.dispatch import receiver


class BooleanQuestion(models.Model):
""" A model for storing YES/NO math questions
"""
DIVISORS = [2, 3, 4, 5, 6, 9]
LOWER = 10
UPPER = 5000

MODULUS = "MODULUS"
OP_CHOICES = [(MODULUS, "%")]
operand1 = models.IntegerField()
Expand All @@ -18,7 +21,7 @@ class BooleanQuestion(models.Model):
correct_answer = models.BooleanField()

def __str__(self):
return "{} {} {} == 0".format(self.operand1, self.operator, self.operand2)
return "{} {} {} == 0".format(self.operand1, self.get_operator_display(), self.operand2)

def save(self, *args, **kwargs):
self.correct_answer = self.compute_answer()
Expand All @@ -37,17 +40,14 @@ def compute_answer(self):

@staticmethod
def get_divisor():
DIVISORS = [2, 3, 4, 5, 6, 9]
return random.choice(DIVISORS)
return random.choice(BooleanQuestion.DIVISORS)

@staticmethod
def generate_question():
""" Method to generate a random math question and update the ActiveQuestion accordingly.
Presently generates divisibility questions only.
"""
LOWER = 10
UPPER = 5000
op1 = random.randint(LOWER, UPPER)
op1 = random.randint(BooleanQuestion.LOWER, BooleanQuestion.UPPER)
op2 = BooleanQuestion.get_divisor()
q = BooleanQuestion.objects.create(operand1=op1, operand2=op2, operator=BooleanQuestion.MODULUS)
return q
Expand Down Expand Up @@ -106,10 +106,9 @@ def __str__(self):

@receiver(user_logged_in)
def populate_active_question(sender, user, request, **kwargs):
pass
# if hasattr(user, 'student'):
# # check for an existing `ActiveQuestion`
# q = ActiveQuestion.objects.filter(student=user.student).first()
# if not q:
# ActiveQuestion.objects.create(
# student=user.student, question=BooleanQuestion.generate_question())
if hasattr(user, 'student'):
# check for an existing `ActiveQuestion`
q = ActiveQuestion.objects.filter(student=user.student).first()
if not q:
ActiveQuestion.objects.create(
student=user.student, question=BooleanQuestion.generate_question())
2 changes: 1 addition & 1 deletion mathstack/tests/test_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ class LoggedInStudentTestCase(TestCase): # the base class -- contains no tests

def setUp(self):
self.user = UserFactory()
self.teacher = StudentFactory(user=self.user)
self.student = StudentFactory(user=self.user)
self.client = Client()
self.client.login(username=self.user.username, password=PASSWORD)
46 changes: 46 additions & 0 deletions mathstack/tests/test_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
""" test_models.py for the MATHSTACK app

To run these tests, from an activated virtualenv run this command:

python manage.py test --keepdb
"""

from django.test import TestCase

from mathstack import models as mathstack_models
import mathstack.tests.factories as mathstack_factories


class TestBooleanQuestion(TestCase):

def setUp(self):
super(TestBooleanQuestion, self).setUp()
self.question = mathstack_factories.BooleanQuestionFactory()

def test_str(self):
self.assertEqual('1000 % 5 == 0', str(self.question))

def test_compute_answer(self):
answer = self.question.compute_answer()
self.assertTrue(answer, '{} should be True'.format(self.question))

def test_compute_answer_invalid_operator(self):
question = mathstack_factories.BooleanQuestionFactory()
question.operator = '/'

try:
question.compute_answer()
self.fail('Should not be able to compute answer for invalid operator')
except RuntimeError as e:
self.assertEqual("Unknown question operator '/'.", str(e))

def test_get_divisor(self):
divisor = mathstack_models.BooleanQuestion.get_divisor()
self.assertIn(divisor, mathstack_models.BooleanQuestion.DIVISORS)

def test_generate_question(self):
question = mathstack_models.BooleanQuestion.generate_question()
self.assertGreaterEqual(question.operand1, mathstack_models.BooleanQuestion.LOWER)
self.assertLess(question.operand1, mathstack_models.BooleanQuestion.UPPER)
self.assertEqual(question.operator, mathstack_models.BooleanQuestion.MODULUS)
self.assertIn(question.operand2, mathstack_models.BooleanQuestion.DIVISORS)
32 changes: 32 additions & 0 deletions mathstack/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"""

from django.shortcuts import reverse
from api.tests import factories as api_factories
import mathstack.tests.factories as mathstack_factories
from mathstack.tests.test_helpers import LoggedInStudentTestCase

Expand All @@ -17,9 +18,40 @@ def setUp(self):
self.url = reverse("bool_answer_create")
self.active_q = mathstack_factories.ActiveQuestionFactory()

def test_bool_answer_create_get_not_student(self):
user = api_factories.UserFactory()
self.client.login(username=user.username, password=api_factories.PASSWORD)

response = self.client.get(self.url)

self.assertEqual(404, response.status_code)

def test_bool_answer_create_get(self):
response = self.client.get(self.url)

self.assertContains(
response,
"<h1>Math Practice Page</h1>")

def test_bool_answer_create_post(self):
data = {
}

original_active_question_id = self.student.activequestion_set.first().id
num_answers_before = self.student.booleananswer_set.count()

response = self.client.post(self.url, data=data, follow=True)

self.assertEqual(200, response.status_code)
self.assertEqual([('/math/div/', 302)], response.redirect_chain)

updated_active_question = self.student.activequestion_set.first()
num_answers_after = self.student.booleananswer_set.count()
self.assertEqual(num_answers_after, num_answers_before + 1)
self.assertNotEqual(original_active_question_id,
updated_active_question.question.id,
"Question should be updated when answer is submitted")

self.assertContains(
response,
"<h1>Math Practice Page</h1>")
4 changes: 2 additions & 2 deletions mathstack/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ class StudentOnlyMixin(LoginRequiredMixin):
def get_context_data(self, **kwargs):
context = super(StudentOnlyMixin, self).get_context_data(**kwargs)

#if not hasattr(self.request.user, "student") or self.request.user.student is None:
# raise Http404()
if not hasattr(self.request.user, "student") or self.request.user.student is None:
raise Http404()
return context


Expand Down