def test_save_question_attempt_success_false(self): self.login_user() user = User.objects.get(id=1) check_achievement_conditions(user.profile) question = Question.objects.get(slug='program-question-1') attempt_one_resp = self.client.post( '/ajax/save_question_attempt/', data={'question': question.pk, 'user_input': 'test', 'test_cases': {1: {'passed': True}}}, content_type='application/json', HTTP_X_REQUESTED_WITH='XMLHttpRequest' ) self.assertEqual(200, attempt_one_resp.status_code) self.assertJSONEqual( str(attempt_one_resp.content, encoding='utf8'), {'success': True, 'curr_points': 50, 'point_diff': 0, 'achievements': ''} ) attempt_two_resp = self.client.post( '/ajax/save_question_attempt/', data={'question': question.pk, 'user_input': 'test', 'test_cases': {1: {'passed': True}}}, content_type='application/json', HTTP_X_REQUESTED_WITH='XMLHttpRequest' ) self.assertEqual(200, attempt_two_resp.status_code) self.assertJSONEqual( str(attempt_two_resp.content, encoding='utf8'), {'success': False, 'message': 'Attempt not saved, same as previous attempt.'} )
def test_doesnt_award_twice_create_account(self): user = User.objects.get(pk=1) achievement = Achievement.objects.get(id_name="create-account") Earned.objects.create(profile=user.profile, achievement=achievement) check_achievement_conditions(user.profile) earned = Earned.objects.filter(profile=user.profile, achievement=achievement) self.assertEqual(len(earned), 1)
def test_not_award_solve_1_on_incorrect_attempt(self): user = User.objects.get(pk=1) question = Question.objects.create(title="Test question", question_text="Print hello world") Attempt.objects.create(profile=user.profile, question=question, passed_tests=False, user_code='') check_achievement_conditions(user.profile) achievement = Achievement.objects.get(id_name="questions-solved-1") earned = Earned.objects.filter(profile=user.profile, achievement=achievement) self.assertEqual(len(earned), 0)
def test_check_achievement_conditions(self): generate_attempts() user = User.objects.get(id=1) self.assertEqual(user.profile.earned_achievements.count(), 0) check_achievement_conditions(user.profile) earned_achievements = user.profile.earned_achievements self.assertTrue(earned_achievements.filter(id_name='create-account').exists()) self.assertTrue(earned_achievements.filter(id_name='attempts-made-1').exists()) self.assertTrue(earned_achievements.filter(id_name='attempts-made-5').exists()) self.assertTrue(earned_achievements.filter(id_name='questions-solved-1').exists()) self.assertTrue(earned_achievements.filter(id_name='consecutive-days-2').exists())
def test_check_achievement_conditions_questions_solved_does_not_exist(self): Achievement.objects.filter(id_name__contains="questions-solved").delete() generate_attempts() user = User.objects.get(id=1) check_achievement_conditions(user.profile) earned_achievements = user.profile.earned_achievements self.assertTrue(earned_achievements.filter(id_name='create-account').exists()) self.assertTrue(earned_achievements.filter(id_name='attempts-made-1').exists()) self.assertTrue(earned_achievements.filter(id_name='attempts-made-5').exists()) self.assertTrue(earned_achievements.filter(id_name='consecutive-days-2').exists()) # All questions-solved badges have been deleted and should not exist self.assertFalse(earned_achievements.filter(id_name='questions-solved-1').exists())
def test_check_achievement_conditions_question_already_solved(self): generate_attempts() user = User.objects.get(id=1) self.assertEqual(user.profile.earned_achievements.count(), 0) check_achievement_conditions(user.profile) self.assertEqual(user.profile.earned_achievements.count(), 5) question = Question.objects.get(slug='program-question-1') # generate two more correct attempts for the SAME question # this would put the total number of correct submissions at 5 # but since it's for the SAME question, it does not contribute to the questions solved achievement Attempt.objects.create(profile=user.profile, question=question, passed_tests=True) Attempt.objects.create(profile=user.profile, question=question, passed_tests=True) check_achievement_conditions(user.profile) earned_achievements = user.profile.earned_achievements self.assertFalse(earned_achievements.filter(id_name='questions-solved-5').exists())
def test_context_object(self): user = User.objects.get(id=1) check_achievement_conditions(user.profile) # make sure a program question has been answered resp = self.client.get('/questions/create/') self.assertEqual(resp.status_code, 200) self.assertEqual( resp.context['question_types'], [ {'name': 'Program', 'count': 1, 'unanswered_count': 0}, {'name': 'Function', 'count': 1, 'unanswered_count': 1}, {'name': 'Parsons', 'count': 1, 'unanswered_count': 1}, {'name': 'Debugging', 'count': 1, 'unanswered_count': 1}, ] )
def save_question_attempt(request): """Save user's attempt for a question. If the attempt is successful: add points if these haven't already been added. Args: request (Request): AJAX request from user. Returns: JSON response with result. """ result = { 'success': False, } if request.is_ajax(): if request.user.is_authenticated: request_json = json.loads(request.body.decode('utf-8')) profile = request.user.profile question = Question.objects.get(pk=request_json['question']) user_code = request_json['user_input'] # If same as previous attempt, don't save to database previous_attempt = Attempt.objects.filter( profile=profile, question=question, ).order_by('-datetime').first() if not previous_attempt or user_code != previous_attempt.user_code: test_cases = request_json['test_cases'] total_tests = len(test_cases) total_passed = 0 for test_case in test_cases.values(): if test_case['passed']: total_passed += 1 attempt = Attempt.objects.create( profile=profile, question=question, user_code=user_code, passed_tests=total_passed == total_tests, ) # Create test case attempt objects for test_case_id, test_case_data in test_cases.items(): test_case = TestCase.objects.get(pk=test_case_id) TestCaseAttempt.objects.create( attempt=attempt, test_case=test_case, passed=test_case_data['passed'], ) result['success'] = True points_before = profile.points points = add_points(question, profile, attempt) achievements = check_achievement_conditions(profile) points_after = profile.points result['curr_points'] = points result['point_diff'] = points_after - points_before result['achievements'] = achievements else: result['success'] = False result[ 'message'] = 'Attempt not saved, same as previous attempt.' return JsonResponse(result)
def test_profile_starts_with_create_account_achievement(self): user = User.objects.get(id=1) check_achievement_conditions(user.profile) achievement = Achievement.objects.get(id_name="create-account") earned = Earned.objects.filter(profile=user.profile, achievement=achievement) self.assertEqual(len(earned), 1)
def test_consecutive_days_2_earnt(self): user = User.objects.get(id=1) check_achievement_conditions(user.profile) achievement = Achievement.objects.get(id_name="consecutive-days-2") consec_days_earned = Earned.objects.filter(profile=user.profile, achievement=achievement) self.assertEqual(len(consec_days_earned), 1)
def test_attempts_made_1_earnt(self): user = User.objects.get(id=1) check_achievement_conditions(user.profile) achievement = Achievement.objects.get(id_name="attempts-made-1") attempts1_earned = Earned.objects.filter(profile=user.profile, achievement=achievement) self.assertEqual(len(attempts1_earned), 1)
def test_questions_solved_1_earnt(self): user = User.objects.get(id=1) check_achievement_conditions(user.profile) achievement = Achievement.objects.get(id_name="questions-solved-1") qs1_earned = Earned.objects.filter(profile=user.profile, achievement=achievement) self.assertEqual(len(qs1_earned), 1)
def test_adding_unknown_achievement_doesnt_break(self): Achievement.objects.create(id_name="notrealachievement", display_name="test", description="test") user = User.objects.get(pk=1) check_achievement_conditions(user.profile)