def test_discriminant_problem(self): """Test for the view of a discriminant problem""" client = Client() collection = create_collection('Colleccion de prueba XYZ') create_user('contra', 'moragues') client.login(username='******', password='******') disc_problem = create_discriminant_problem(False, collection) submit_discriminant_url = reverse('judge:submit', args=[disc_problem.pk]) # Checks that invalid INSERTs are mappet to RE response = client.post( submit_discriminant_url, {'code': 'INSERT INTO test_table_1 VALUES (a);'}, follow=True) self.assertEqual(response.json()['veredict'], VeredictCode.RE) response = client.post(submit_discriminant_url, {'code': 'INSERT INTO test_table_1 VALUES ()'}, follow=True) self.assertEqual(response.json()['veredict'], VeredictCode.RE) response = client.post(submit_discriminant_url, {'code': 'INSERT merienda;'}, follow=True) self.assertEqual(response.json()['veredict'], VeredictCode.RE) # Check a correct answer and an incorrect response = client.post( submit_discriminant_url, {'code': 'INSERT INTO test_table_1 VALUES (500)'}, follow=True) self.assertEqual(response.json()['veredict'], VeredictCode.AC) response = client.post( submit_discriminant_url, {'code': 'INSERT INTO test_table_1 VALUES (2021)'}, follow=True) self.assertEqual(response.json()['veredict'], VeredictCode.WA) problem_url = reverse('judge:problem', args=[disc_problem.pk]) response = client.get(problem_url, follow=True) self.assertIn('Consulta SQL errónea a depurar', response.content.decode('utf-8')) disc_problem = create_discriminant_problem(True, collection) submit_discriminant_url = reverse('judge:submit', args=[disc_problem.pk]) response = client.post( submit_discriminant_url, {'code': 'INSERT INTO test_table_1 VALUES (2000, 1990)'}, follow=True) self.assertEqual(response.json()['veredict'], VeredictCode.AC) response = client.post( submit_discriminant_url, {'code': 'INSERT INTO test_table_1 VALUES (2000, 2000)'}, follow=True) self.assertEqual(response.json()['veredict'], VeredictCode.WA) response = client.post( submit_discriminant_url, {'code': 'INSERT INTO test_table VALUES (2000, 2000)'}, follow=True) self.assertEqual(response.json()['veredict'], VeredictCode.RE) self.assertEqual(disc_problem.problem_type(), ProblemType.DISC)
def test_signal_update_achievement(self): """Test for check signals""" client = Client() user_michu = create_user('passwordmichu', 'michu') create_user('passwordimmobile', 'immobile') client.login(username='******', password='******') coll = create_collection('Coleccion de cartas') ach_podium = PodiumAchievementDefinition(name='Presidente del podio', description='Consigue ser el primero', num_problems=1, position=1) ach_collection = NumSolvedCollectionAchievementDefinition(name='Coleccionista', description='Resuelve 50\ problemas de esta coleccion', num_problems=50, collection=coll) ach_solved = NumSolvedAchievementDefinition(name='Resolvista', description='Resuelve 50 problemas', num_problems=50) ach_podium.save() ach_solved.save() ach_collection.save() problem = create_select_problem(coll, 'Problema') submit_select_url = reverse('judge:submit', args=[problem.pk]) client.post(submit_select_url, {'code': problem.solution}, follow=True) client.logout() client.login(username='******', password='******') client.post(submit_select_url, {'code': problem.solution}, follow=True) self.assertEqual(ObtainedAchievement.objects.filter(user=user_michu).count(), 0) ach_podium.position = 3 ach_collection.num_problems = 1 ach_solved.num_problems = 1 ach_podium.save() ach_solved.save() ach_collection.save() self.assertEqual(ObtainedAchievement.objects.filter(user=user_michu).count(), 3)
def test_ranking_language(self): """Test to check ranking language page""" client = Client() collection = create_collection('Colleccion de prueba XYZ') user = create_user('5555', 'pepe') client.login(username='******', password='******') group_a = create_group('1A') group_a.user_set.add(user) client.cookies.load({settings.LANGUAGE_COOKIE_NAME: 'en'}) ranking_url = reverse('judge:result', args=[collection.pk]) response = client.get(ranking_url, follow=True) self.assertIn('Group', response.content.decode('utf-8')) self.assertIn('User', response.content.decode('utf-8')) self.assertIn('Score', response.content.decode('utf-8')) self.assertIn('LEGEND', response.content.decode('utf-8')) self.assertIn('Solved', response.content.decode('utf-8')) self.assertIn('Sum of the first accepted submission of each exercise', response.content.decode('utf-8')) client.cookies.load({settings.LANGUAGE_COOKIE_NAME: 'es'}) ranking_url = reverse('judge:result', args=[collection.pk]) response = client.get(ranking_url, follow=True) self.assertIn('Grupo', response.content.decode('utf-8')) self.assertIn('Usuario', response.content.decode('utf-8')) self.assertIn('Puntuación', response.content.decode('utf-8')) self.assertIn('LEYENDA', response.content.decode('utf-8')) self.assertIn('Resueltos', response.content.decode('utf-8')) self.assertIn('Suma del primer envío aceptado de cada ejercicio', response.content.decode('utf-8'))
def test_trigger_problem_language(self): """Test to check if language in trigger problem page displays correctly""" curr_path = os.path.dirname(__file__) client = Client() zip_trigger_path = os.path.join(curr_path, ParseTest.ZIP_FOLDER, ParseTest.TRIGGER_OK) collection = create_collection('Colleccion de prueba XYZ') user = create_user('5555', 'pepe') problem = TriggerProblem(zipfile=zip_trigger_path, collection=collection, author=user) problem.clean() problem.save() client.login(username='******', password='******') client.cookies.load({settings.LANGUAGE_COOKIE_NAME: 'en'}) url = reverse('judge:problem', args=[problem.pk]) response = client.get(url, follow=True) self.assertIn('Executed statements', response.content.decode('utf-8')) self.assertIn('Expected result', response.content.decode('utf-8')) client.cookies.load({settings.LANGUAGE_COOKIE_NAME: 'es'}) url = reverse('judge:problem', args=[problem.pk]) response = client.get(url, follow=True) self.assertEqual(response.status_code, 200) self.assertIn('Sentencias ejecutadas', response.content.decode('utf-8')) self.assertIn('Resultado esperado', response.content.decode('utf-8'))
def test_plsql_correct(self): """Accepted submissions to function/procedure/trigger problem""" curr_path = os.path.dirname(__file__) zip_function_path = os.path.join(curr_path, ParseTest.ZIP_FOLDER, ParseTest.FUNCTION_OK) zip_proc_path = os.path.join(curr_path, ParseTest.ZIP_FOLDER, ParseTest.PROC_OK) zip_trigger_path = os.path.join(curr_path, ParseTest.ZIP_FOLDER, ParseTest.TRIGGER_OK) client = Client() collection = create_collection('Colleccion de prueba AAA') user = create_user('54522', 'antonio') client.login(username='******', password='******') function_problem = FunctionProblem(zipfile=zip_function_path, collection=collection, author=user) proc_problem = ProcProblem(zipfile=zip_proc_path, collection=collection, author=user) trigger_problem = TriggerProblem(zipfile=zip_trigger_path, collection=collection, author=user) for problem in [function_problem, proc_problem, trigger_problem]: problem.clean() problem.save() submit_url = reverse('judge:submit', args=[problem.pk]) response = client.post(submit_url, {'code': problem.solution}, follow=True) self.assertEqual(response.json()['veredict'], VeredictCode.AC)
def test_rejudge(self): """ Test that rejudge correctly detects submission whose verdict changes """ collection = create_collection("test collection") problem = create_select_problem(collection, "example") user = create_user(passwd='1111', username='******') subs = [ Submission(code=problem.solution, verdict_code=VerdictCode.IE, user=user, problem=problem), # IE->AC Submission(code='SELECT * FROM dual', verdict_code=VerdictCode.IE, user=user, problem=problem), # IE->WA Submission(code='SELECT * FRO dual', verdict_code=VerdictCode.IE, user=user, problem=problem), # IE->RE ] for sub in subs: sub.save() sub.creation_date = datetime.datetime(2020, 9, 15) # Sets an older date sub.save() file_desc, filename = mkstemp('_rejudge') os.close(file_desc) # To avoid problems when removing the file in Windows rejudge(VerdictCode.IE, filename, tests=True) with open(filename, 'r') as summary_file: summary = summary_file.read() self.assertIn('IE --> AC', summary) self.assertIn('IE --> WA', summary) self.assertIn('IE --> RE', summary) self.assertNotIn('IE --> IE', summary) os.remove(filename)
def test_load_hint(self): """Test to check if hints.md is loaded correctly""" curr_path = os.path.dirname(__file__) zip_dml_path = os.path.join(curr_path, self.ZIP_FOLDER, self.DML_HINTS) zip_function_path = os.path.join(curr_path, self.ZIP_FOLDER, self.FUNCTION_HINTS) zip_proc_path = os.path.join(curr_path, self.ZIP_FOLDER, self.PROC_HINTS) zip_trigger_path = os.path.join(curr_path, self.ZIP_FOLDER, self.TRIGGER_HINTS) zip_discriminant_path = os.path.join(curr_path, self.ZIP_FOLDER, self.DISCRIMINANT_HINTS) collection = create_collection('Coleccion 1') dml = DMLProblem(zipfile=zip_dml_path, collection=collection) function = FunctionProblem(zipfile=zip_function_path, collection=collection) proc = ProcProblem(zipfile=zip_proc_path, collection=collection) trigger = TriggerProblem(zipfile=zip_trigger_path, collection=collection) discriminant = DiscriminantProblem(zipfile=zip_discriminant_path, collection=collection) hints_expected1 = (3, 'descripcion pista 1') hints_expected2 = (5, 'descripcion pista 2') hints_expected3 = (10, 'descripcion pista 3') for problem in [dml, function, proc, trigger, discriminant]: problem.clean() problem.save() hints = Hint.objects.filter(problem=problem).order_by('num_submit') self.assertEqual(hints.count(), 3) self.assertEqual(hints_expected1[0], hints[0].num_submit) self.assertEqual(hints_expected1[1], hints[0].text_md) self.assertEqual(hints_expected2[0], hints[1].num_submit) self.assertEqual(hints_expected2[1], hints[1].text_md) self.assertEqual(hints_expected3[0], hints[2].num_submit) self.assertEqual(hints_expected3[1], hints[2].text_md)
def test_give_hint(self): """check the correct operation of the hints""" client = Client() user = create_user('2222', 'tamara') collection = create_collection('Colleccion de prueba TTT') problem = create_select_problem(collection, 'SelectProblem ABC DEF') description1 = '<div class="d-flex p-2">\n ' \ '<div class="bg-success h-40 w-25 text-center mb-1 border border-dark text-white ' \ 'justify-content-center align-self-center ">\n' \ ' Pista 1\n </div>\n <div class="text-center w-75">\n ' \ 'descripcion de la pista 1\n </div>\n</div>' description2 = '<div class="d-flex p-2">\n ' \ '<div class="bg-success h-40 w-25 text-center mb-1 border border-dark text-white ' \ 'justify-content-center align-self-center ">\n' \ ' Pista 2\n </div>\n <div class="text-center w-75">\n ' \ 'descripcion de la pista 2\n </div>\n</div>' create_hint(problem, 1, 3) hint2 = create_hint(problem, 2, 5) create_submission(problem, user, VerdictCode.WA, 'select *** from') create_submission(problem, user, VerdictCode.WA, 'select *** from') create_submission(problem, user, VerdictCode.WA, 'select *** from') create_submission(problem, user, VerdictCode.WA, 'select *** from') hint_url = reverse('judge:hint', args=[problem.pk]) client.login(username='******', password='******') # JSON with the first hint response = client.post(hint_url, follow=True) self.assertEqual(response.json()['hint'], description1) # JSON with the message that the next hint is not available num_error = Submission.objects.filter(problem=problem, user=user).count() num = hint2.num_submit - num_error msg = f'Número de envíos que faltan para obtener la siguiente pista: {num}.' response = client.post(hint_url, follow=True) self.assertEqual(response.json()['hint'], '') self.assertEqual(response.json()['msg'], msg) self.assertEqual(response.json()['more_hints'], True) # JSON with the last hint create_submission(problem, user, VerdictCode.WA, 'select *** from') mens = 'No hay más pistas disponibles para este ejercicio.' response = client.post(hint_url, follow=True) self.assertEqual(response.json()['hint'], description2) self.assertEqual(response.json()['msg'], mens) self.assertEqual(response.json()['more_hints'], False) # JSON if the problem don't have any hint problem_3 = create_select_problem(collection, 'SelectProblem 3 DEF ABC') hint_url_3 = reverse('judge:hint', args=[problem_3.pk]) client.post(hint_url_3, follow=False) self.assertEqual(response.json()['more_hints'], False) # Markdown to HTML hint_md = create_hint(problem, 3, 3) self.assertEqual(hint_md.get_text_html(), 'descripcion de la pista 3')
def test_show_hints(self): """Test to check the table of used hints of a user""" client = Client() user = create_user('2222', 'tamara') collection = create_collection('Colleccion de prueba TTT') problem = create_select_problem(collection, 'SelectProblem ABC DEF') problem_3 = create_select_problem(collection, 'SelectProblem 3 DEF ABC') client.login(username='******', password='******') hint = create_hint(problem, 1, 1) hint2 = create_hint(problem, 2, 1) hint3 = create_hint(problem_3, 3, 1) # The table is empty, the user has no used hint table_hint_url = reverse('judge:hints') response = client.get(table_hint_url, follow=True) self.assertIn(user.username, response.content.decode('utf-8')) self.assertNotIn('SelectProblem', response.content.decode('utf-8')) # The table contains the first hint used for first problem create_used_hint(hint, user) table_hint_url = reverse('judge:hints') response = client.get(table_hint_url, follow=True) self.assertIn(user.username, response.content.decode('utf-8')) self.assertIn('SelectProblem ABC DEF', response.content.decode('utf-8')) self.assertIn(hint.text_md, response.content.decode('utf-8')) self.assertNotIn(hint2.text_md, response.content.decode('utf-8')) self.assertNotIn('SelectProblem 3 ABC DEF', response.content.decode('utf-8')) self.assertNotIn(hint3.text_md, response.content.decode('utf-8')) # The table contains the second hint used for first problem create_used_hint(hint2, user) table_hint_url2 = reverse('judge:hints') response = client.get(table_hint_url2, follow=True) self.assertIn(user.username, response.content.decode('utf-8')) self.assertIn('SelectProblem ABC DEF', response.content.decode('utf-8')) self.assertIn(hint.text_md, response.content.decode('utf-8')) self.assertIn(hint2.text_md, response.content.decode('utf-8')) self.assertNotIn('SelectProblem 3 DEF ABC', response.content.decode('utf-8')) self.assertNotIn(hint3.text_md, response.content.decode('utf-8')) # The table contains the first hint used for second problem create_used_hint(hint3, user) table_hint_url3 = reverse('judge:hints') response = client.get(table_hint_url3, follow=True) self.assertIn(user.username, response.content.decode('utf-8')) self.assertIn('SelectProblem ABC DEF', response.content.decode('utf-8')) self.assertIn(hint.text_md, response.content.decode('utf-8')) self.assertIn(hint2.text_md, response.content.decode('utf-8')) self.assertIn('SelectProblem 3 DEF ABC', response.content.decode('utf-8')) self.assertIn(hint3.text_md, response.content.decode('utf-8'))
def test_signal_new_achievement(self): """Test for check signals""" client = Client() create_user('passwordmichu', 'michu') client.login(username='******', password='******') coll = create_collection('Coleccion de cartas') problem = create_select_problem(coll, 'Problema') submit_select_url = reverse('judge:submit', args=[problem.pk]) client.post(submit_select_url, {'code': problem.solution}, follow=True) create_an_achievement_of_each(coll) self.assertEqual(ObtainedAchievement.objects.all().count(), 5)
def test_hint_used(self): """Test to check the text of the used hints""" client = Client() user = create_user('2222', 'tamara') collection = create_collection('Colleccion de prueba TTT') problem = create_select_problem(collection, 'SelectProblem ABC DEF') client.login(username='******', password='******') hint = create_hint(problem, 1, 1) create_used_hint(hint, user) problem_url = reverse('judge:problem', args=[problem.pk]) response = client.get(problem_url, follow=True) self.assertIn(hint.text_md, response.content.decode('utf-8'))
def test_obtained_achievements_date(self): """Test if the dates of the obtained achievements are correct""" user = create_user('passwordmichu', 'michu') coll = create_collection('Coleccion de cartas') problem_1 = create_select_problem(coll, 'Problema 1') problem_2 = create_select_problem(coll, 'Problema 2') sub_1 = Submission(code='nada', veredict_code=VeredictCode.AC, user=user, problem=problem_1) sub_2 = Submission(code='nada', veredict_code=VeredictCode.AC, user=user, problem=problem_2) sub_1.save() sub_2.save() Submission.objects.filter(id=sub_1.id).update(creation_date=datetime(2006, 3, 5)) sub_1_u = Submission.objects.get(id=sub_1.id) Submission.objects.filter(id=sub_2.id).update(creation_date=datetime(2020, 3, 5)) sub_2_u = Submission.objects.get(id=sub_2.id) # Test NumSolvedAchievementDefinition ach_solved = NumSolvedAchievementDefinition(name='Resolvista', description='Resuelve 2 problemas', num_problems=2) ach_solved.save() date = ObtainedAchievement.objects.filter(user=user).values_list('obtained_date', flat=True) self.assertEqual(date[0], sub_2_u.creation_date) ach_solved.num_problems = 1 ach_solved.save() date = ObtainedAchievement.objects.filter(user=user).values_list('obtained_date', flat=True) self.assertEqual(date[0], sub_1_u.creation_date) ObtainedAchievement.objects.all().delete() # Test NumSolvedCollectionAchievementDefinition ach_coll = NumSolvedCollectionAchievementDefinition(name='Coleccionista', description='Resuelve 2 \ problemas de esta coleccion', num_problems=2, collection=coll) ach_coll.save() date = ObtainedAchievement.objects.filter(user=user).values_list('obtained_date', flat=True) self.assertEqual(date[0], sub_2_u.creation_date) ach_coll.num_problems = 1 ach_coll.save() date = ObtainedAchievement.objects.filter(user=user).values_list('obtained_date', flat=True) self.assertEqual(date[0], sub_1_u.creation_date) ObtainedAchievement.objects.all().delete() # Test PodiumAchievementDefinition ach_podium = PodiumAchievementDefinition(name='Presidente del podio', description='Consigue ser el primero', num_problems=2, position=1) ach_podium.save() date = ObtainedAchievement.objects.filter(user=user).values_list('obtained_date', flat=True) self.assertEqual(date[0], sub_2_u.creation_date) ach_podium.num_problems = 1 ach_podium.save() date = ObtainedAchievement.objects.filter(user=user).values_list('obtained_date', flat=True) self.assertEqual(date[0], sub_1_u.creation_date) ObtainedAchievement.objects.all().delete()
def test_incorrect_submit_get_achievement(self): """Test if an incorrect submission get an achievement""" client = Client() user = create_user('passwordmazepin', 'mazepin') coll = create_collection('Coleccion de cartas') problem = create_select_problem(coll, 'Problema') ach_submissions = NumSubmissionsProblemsAchievementDefinition(name='Un envio', description='Envia una solucion para un problema', num_problems=1, num_submissions=1) ach_submissions.save() client.login(username='******', password='******') submit_select_url = reverse('judge:submit', args=[problem.pk]) client.post(submit_select_url, {'code': 'MAL'}, follow=True) # Validation Error, too short self.assertEqual(ObtainedAchievement.objects.filter(user=user).count(), 1)
def test_get_podium_achievement(self): """Test if get correctly a podium achievement""" client = Client() podium_achievement = PodiumAchievementDefinition(name='Top 1', description='Se el primero', num_problems=1, position=1) podium_achievement.save() coll = create_collection('Test Podium') problem = create_select_problem(coll, 'Select 1') user = create_user('passwordmichu', 'michu') client.login(username='******', password='******') submit_select_url = reverse('judge:submit', args=[problem.pk]) client.post(submit_select_url, {'code': problem.solution}, follow=True) achievements_url = reverse('judge:achievements', args=[user.pk]) response = client.get(achievements_url, follow=True) self.assertIn('Fecha', response.content.decode('utf-8'))
def test_get_collection_achievement(self): """Test if get correctly a collection achievement""" client = Client() coll = create_collection('Test Solved') coll_achievement = NumSolvedCollectionAchievementDefinition(name='Solo 1', description='Acierta 1', num_problems=1, collection=coll) coll_achievement.save() problem = create_select_problem(coll, 'Select 1') user = create_user('passwordmichu', 'michu') client.login(username='******', password='******') submit_select_url = reverse('judge:submit', args=[problem.pk]) client.post(submit_select_url, {'code': problem.solution}, follow=True) achievements_url = reverse('judge:achievements', args=[user.pk]) response = client.get(achievements_url, follow=True) self.assertIn('Fecha', response.content.decode('utf-8'))
def test_same_hints(self): """Test when the user use all available hints""" client = Client() user = create_user('2222', 'tamara') collection = create_collection('Colleccion de prueba TTT') problem = create_select_problem(collection, 'SelectProblem ABC DEF') hint1 = create_hint(problem, 1, 3) hint2 = create_hint(problem, 2, 5) create_used_hint(hint1, user) create_used_hint(hint2, user) client.login(username='******', password='******') msg = 'No hay más pistas disponibles para este ejercicio.' hint_url = reverse('judge:hint', args=[problem.pk]) response = client.post(hint_url, follow=True) self.assertEqual(response.json()['msg'], msg)
def test_ranking_achievements(self): """Test if we can see the number of achievements that have an user at ranking""" client = Client() user = create_user('passwordmichu', 'michu') client.login(username='******', password='******') coll = create_collection('Coleccion de cartas') problem = create_select_problem(coll, 'Problema') create_an_achievement_of_each(coll) submit_select_url = reverse('judge:submit', args=[problem.pk]) client.post(submit_select_url, {'code': problem.solution}, follow=True) ranking_url = reverse('judge:result', args=[coll.pk]) group_a = create_group('1A') group_a.user_set.add(user) response = client.get(ranking_url, follow=True) self.assertIn('x5', response.content.decode('utf-8'))
def test_participation(self): """ Test the count of participating users in a group """ group = create_group('Grupo test') user1 = create_user(username='******', passwd='1111') user2 = create_user(username='******', passwd='1111') user3 = create_user(username='******', passwd='1111') user4 = create_user(username='******', passwd='1111') collection = create_collection('Test for statistics') problem = create_select_problem(collection, 'Dummy for statistics') for user in [user1, user2, user3, user4]: group.user_set.add(user) subs = [ Submission(verdict_code=VerdictCode.AC, user=user1, problem=problem), Submission(verdict_code=VerdictCode.WA, user=user2, problem=problem), Submission(verdict_code=VerdictCode.RE, user=user2, problem=problem), Submission(verdict_code=VerdictCode.TLE, user=user2, problem=problem), Submission(verdict_code=VerdictCode.VE, user=user1, problem=problem), Submission(verdict_code=VerdictCode.AC, user=user4, problem=problem), ] for sub in subs: sub.save() data = participation_per_group() expected = { 'Grupo test': { 'all': 4, 'acc': 2, 'participating': 3, 'avg': 2, 'stdev': 1.0, 'quantiles': '1 - 1.0 - 2.0 - 3.0 - 3', } } self.assertDictEqual(data, expected)
def test_give_hint(self): """check the correct operation of the hints""" client = Client() user = create_user('2222', 'tamara') collection = create_collection('Colleccion de prueba TTT') problem = create_select_problem(collection, 'SelectProblem ABC DEF') create_hint(problem, id_hint=1, num_submissions=3) create_hint(problem, id_hint=2, num_submissions=5) create_submission(problem, user, VerdictCode.WA, 'select *** from') create_submission(problem, user, VerdictCode.WA, 'select *** from') create_submission(problem, user, VerdictCode.WA, 'select *** from') create_submission(problem, user, VerdictCode.WA, 'select *** from') hint_url = reverse('judge:hint', args=[problem.pk]) client.login(username='******', password='******') # JSON with the first hint response = client.post(hint_url, follow=True) self.assertIn('Pista 1', response.json()['hint']) self.assertIn('descripcion de la pista 1', response.json()['hint']) # JSON with the message that the next hint is not available msg = 'Te falta 1 envío para desbloquear la siguiente pista' response = client.post(hint_url, follow=True) self.assertEqual(response.json()['hint'], '') self.assertEqual(response.json()['msg'], msg) self.assertEqual(response.json()['more_hints'], True) # JSON with the last hint create_submission(problem, user, VerdictCode.WA, 'select *** from') mens = 'No hay más pistas disponibles para este ejercicio.' response = client.post(hint_url, follow=True) self.assertIn('Pista 2', response.json()['hint']) self.assertIn('descripcion de la pista 2', response.json()['hint']) self.assertEqual(response.json()['msg'], mens) self.assertEqual(response.json()['more_hints'], False) # JSON if the problem don't have any hint problem_3 = create_select_problem(collection, 'SelectProblem 3 DEF ABC') hint_url_3 = reverse('judge:hint', args=[problem_3.pk]) client.post(hint_url_3, follow=False) self.assertEqual(response.json()['more_hints'], False) # Markdown to HTML hint_md = create_hint(problem, 3, 3) self.assertEqual(hint_md.get_text_html(), 'descripcion de la pista 3')
def test_long_hint(self): """Test to check if hints.md is loaded correctly to a SelectProblem. It checks both hints with one line and hints with several lines""" curr_path = os.path.dirname(__file__) zip_select_path = os.path.join(curr_path, self.ZIP_FOLDER, self.SELECT_HINTS) zip_select_pro_path = os.path.join(curr_path, self.ZIP_FOLDER, self.SELECT_HINTS_PRO) collection = create_collection('Coleccion 1') select = SelectProblem(zipfile=zip_select_path, collection=collection) select_pro = SelectProblem(zipfile=zip_select_pro_path, collection=collection) hints_expected1 = (3, 'descripcion pista 1') hints_expected2 = (5, 'descripcion pista 2') hints_expected3 = (10, 'descripcion pista 3') text_md = """Ten en **cuenta** que: * debes seleccionar las tablas * debes elegir cuidadosamente las columnas""" hits_expected_pro = (5, text_md) # Check hints loaded for SelectProblem select.clean() select.save() hints = Hint.objects.filter(problem=select).order_by('num_submit') self.assertEqual(hints.count(), 3) self.assertEqual(hints_expected1[0], hints[0].num_submit) self.assertEqual(hints_expected1[1], hints[0].text_md) self.assertEqual(hints_expected2[0], hints[1].num_submit) self.assertEqual(hints_expected2[1], hints[1].text_md) self.assertEqual(hints_expected3[0], hints[2].num_submit) self.assertEqual(hints_expected3[1], hints[2].text_md) # Check hints loaded for SelectProblem pro select_pro.clean() select_pro.save() hints = Hint.objects.filter(problem=select_pro).order_by('num_submit') self.assertEqual(hints.count(), 3) self.assertEqual(hints_expected1[0], hints[0].num_submit) self.assertEqual(hints_expected1[1], hints[0].text_md) self.assertEqual(hits_expected_pro[0], hints[1].num_submit) self.assertEqual(hits_expected_pro[1], hints[1].text_md) self.assertEqual(hints_expected3[0], hints[2].num_submit) self.assertEqual(hints_expected3[1], hints[2].text_md)
def test_select_no_output(self): """Test that SQL statements that produce no results generate WA in a SELECT problem because the schema is different""" client = Client() collection = create_collection('Colleccion de prueba XYZ') select_problem = create_select_problem(collection, 'SelectProblem ABC DEF') create_user('5555', 'pepe') client.login(username='******', password='******') stmts = [ "CREATE VIEW my_test(n) AS SELECT n FROM test;", "INSERT INTO test VALUES (89547);", ] submit_url_select = reverse('judge:submit', args=[select_problem.pk]) for stmt in stmts: response = client.post(submit_url_select, {'code': stmt}, follow=True) self.assertEqual(response.json()['veredict'], VeredictCode.WA) self.assertIn('Generado por tu código SQL: 0 columnas', response.json()['feedback'])
def test_validation_error(self): """Test messages obtained in submission that do not containt the correct number of statements""" client = Client() collection = create_collection('Colleccion de prueba XYZ') select_problem = create_select_problem(collection, 'SelectProblem ABC DEF') dml_problem = create_dml_problem(collection, 'DML Problem') create_user('5555', 'pepe') client.login(username='******', password='******') submit_url_select = reverse('judge:submit', args=[select_problem.pk]) submit_url_dml = reverse('judge:submit', args=[dml_problem.pk]) # JSON with VE and correct message for one SQL response = client.post( submit_url_select, {'code': f'{select_problem.solution}; {select_problem.solution}'}, follow=True) self.assertEqual(response.json()['veredict'], VeredictCode.VE) self.assertIn('exactamente 1 sentencia SQL', response.json()['message']) # JSON with VE and correct message for 1--3 SQL stmt = 'INSERT INTO test VALUES (25);' response = client.post(submit_url_dml, {'code': stmt}, follow=True) self.assertEqual(response.json()['veredict'], VeredictCode.VE) self.assertIn('entre 2 y 3 sentencias SQL', response.json()['message']) stmt = 'INSERT INTO test VALUES (25); INSERT INTO test VALUES (50); INSERT INTO test VALUES (75);' \ 'INSERT INTO test VALUES (100);' response = client.post(submit_url_dml, {'code': stmt}, follow=True) self.assertEqual(response.json()['veredict'], VeredictCode.VE) self.assertIn('entre 2 y 3 sentencias SQL', response.json()['message']) # JSON with VE and correct message for less than 10 characters stmt = 'holis' response = client.post(submit_url_dml, {'code': stmt}, follow=True) self.assertEqual(response.json()['veredict'], VeredictCode.VE) self.assertIn('tu solución no está vacía', response.json()['message'])
def test_get_solved_achievement(self): """Test if get correctly a solved achievement and check_user function""" client = Client() solved_achievement_1 = NumSolvedAchievementDefinition( name={"es": 'Solo 1'}, description={"es": 'Acierta 1'}, num_problems=1) solved_achievement_2 = NumSolvedAchievementDefinition( name={"es": 'Solo 2'}, description={"es": 'Acierta 2'}, num_problems=2) solved_achievement_1.save() solved_achievement_2.save() coll = create_collection('Test Solved') problem = create_select_problem(coll, 'Select 1') user = create_user('passwordmichu', 'michu') client.login(username='******', password='******') submit_select_url = reverse('judge:submit', args=[problem.pk]) client.post(submit_select_url, {'code': problem.solution}, follow=True) client.post(submit_select_url, {'code': problem.solution}, follow=True) achievements_url = reverse('judge:achievements', args=[user.pk]) response = client.get(achievements_url, follow=True) self.assertIn('Fecha', response.content.decode('utf-8')) self.assertIn('Logros pendientes', response.content.decode('utf-8'))
def test_all_submissions(self): """ Test the list [epoch, count] for different types of verdicts and days, and also the counter of submissions """ collection = create_collection('Test for statistics') problem = create_select_problem(collection, 'Dummy for statistics') user1 = create_user('0000', 'ana') user2 = create_user('0000', 'juan') subs = [ Submission(veredict_code=VeredictCode.AC, user=user1, problem=problem), Submission(veredict_code=VeredictCode.WA, user=user2, problem=problem), Submission(veredict_code=VeredictCode.RE, user=user2, problem=problem), Submission(veredict_code=VeredictCode.TLE, user=user2, problem=problem), Submission(veredict_code=VeredictCode.VE, user=user1, problem=problem), Submission(veredict_code=VeredictCode.AC, user=user2, problem=problem), ] dates = [ datetime(2020, 2, 12, 0, 0, 0, 0, tzinfo=pytz.utc), datetime(2020, 2, 12, 0, 0, 0, 0, tzinfo=pytz.utc), datetime(2020, 2, 15, 0, 0, 0, 0, tzinfo=pytz.utc), datetime(2020, 2, 15, 0, 0, 0, 0, tzinfo=pytz.utc), datetime(2020, 2, 16, 0, 0, 0, 0, tzinfo=pytz.utc), datetime(2020, 2, 20, 0, 0, 0, 0, tzinfo=pytz.utc), ] dates_epoch_ms = [int(date.timestamp()) * 1000 for date in dates] for (sub, date) in zip(subs, dates): sub.save() sub.creation_date = date sub.save() # Overwrites date, because it is automatically set to 'now' in the first save count_all = submissions_by_day() self.assertEqual(len(count_all), (dates[-1] - dates[0]).days + 1) # 9 days between first and last submission self.assertEqual(count_all[0], [dates_epoch_ms[0], 2]) # 2 submissions on 1st day (2020-2-12) self.assertEqual(count_all[1][1], 0) # 0 submissions on 2nd day self.assertEqual(count_all[2][1], 0) # 0 submissions on 3rd day self.assertEqual(count_all[3], [dates_epoch_ms[2], 2]) # 2 submissions on 4th day (2020-2-15) self.assertEqual(count_all[4], [dates_epoch_ms[4], 1]) # 1 submission on 5th day (2020-2-16) self.assertEqual(count_all[6][1], 0) # 0 submissions on 3rd day self.assertEqual(count_all[8], [dates_epoch_ms[5], 1]) # 1 submission on 9th day (2020-2-20) count_ac = submissions_by_day(verdict_code=VeredictCode.AC) self.assertEqual(len(count_ac), (dates[-1] - dates[0]).days + 1) # 9 days between first and last AC submission self.assertEqual(count_ac[0], [dates_epoch_ms[0], 1]) # 1 AC submissions on 1st day (2020-2-12) self.assertEqual(count_ac[1][1], 0) # 0 submissions on 2nd day self.assertEqual(count_ac[4][1], 0) # 0 submission on 5th day (2020-2-16) self.assertEqual(count_ac[8], [dates_epoch_ms[5], 1]) # 1 submission on 9th day (2020-2-20) count_wa = submissions_by_day(verdict_code=VeredictCode.WA) self.assertEqual(len(count_wa), 1) # Only one entry count_wa = submissions_by_day(verdict_code=VeredictCode.WA, start=dates_epoch_ms[0], end=dates_epoch_ms[-1]) self.assertEqual(len(count_wa), (dates[-1] - dates[0]).days + 1) # 9 days when forcing the start-end count_re = submissions_by_day(verdict_code=VeredictCode.RE) self.assertEqual(len(count_re), 1) # Only one entry count_re = submissions_by_day(verdict_code=VeredictCode.RE, start=dates_epoch_ms[0], end=dates_epoch_ms[-1]) self.assertEqual(len(count_re), (dates[-1] - dates[0]).days + 1) # 9 days when forcing the start-end self.assertEqual(count_re[0], [dates_epoch_ms[0], 0]) # 0 RE submissions on 1st day (2020-2-12) self.assertEqual(count_re[3], [dates_epoch_ms[2], 1]) # 1 submissions on 4th day self.assertEqual(count_re[8], [dates_epoch_ms[5], 0]) # 0 RE submission on 9th day (2020-2-20) # Test the counter of submissions sub_count = submission_count() self.assertEqual(sub_count['all'], 6) self.assertEqual(sub_count[VeredictCode.AC], 2) self.assertEqual(sub_count[VeredictCode.WA], 1) self.assertEqual(sub_count[VeredictCode.RE], 1) self.assertEqual(sub_count[VeredictCode.TLE], 1) self.assertEqual(sub_count[VeredictCode.VE], 1) self.assertEqual(sub_count[VeredictCode.IE], 0)
def test_download_ranking(self): """ Test to download excel of results """ client = Client() user = create_user('2222', 'tamara') teacher = create_superuser('1111', 'teacher') group_a = create_group('1A') group_a.user_set.add(user) start = first_day_of_course(datetime(2020, 9, 1)) end = datetime(2021, 3, 7).strftime('%Y-%m-%d') collection = create_collection('Coleccion 1') select_problem = create_select_problem(collection, 'SelectProblem ABC DEF') sub = Submission.objects.create(code='SELECT * FROM test where n = 1000', user=user, veredict_code=VeredictCode.WA, problem=select_problem) sub.save() Submission.objects.filter(id=sub.id).update(creation_date=datetime(2021, 3, 5)) client.login(username=teacher.username, password='******') url = reverse('judge:download_ranking', args=[collection.pk]) response = client.get(url, {'group': group_a.id, 'start': start, 'end': end}, follow=True) # Teacher download ranking self.assertEqual( response.get('Content-Disposition'), "attachment; filename=ranking.xlsx", ) self.assertEqual( response.get('Content-Type'), "application/xlsx" ) file = tempfile.NamedTemporaryFile(mode='w+b', buffering=-1, suffix='.xlsx') cont = response.content file.write(cont) work = openpyxl.load_workbook(file) book = work.active self.assertIn("Colección: " + collection.name_md, book.cell(row=1, column=1).value) self.assertIn("1A", book.cell(row=3, column=1).value) self.assertIn("1", book.cell(row=5, column=1).value) self.assertIn(user.username, book.cell(row=5, column=2).value) self.assertIn("0/1 (1)", book.cell(row=5, column=3).value) self.assertIn("0", book.cell(row=5, column=4).value) self.assertIn("0", book.cell(row=5, column=5).value) file.close() # Date or group invalid response = client.get(url, { 'group': group_a.id, 'start': start, 'end': ''}, follow=True) self.assertIn("Este campo es obligatorio", response.content.decode('utf-8')) response = client.get(url, { 'group': group_a.id, 'start': 'eee', 'end': end}, follow=True) self.assertIn("Introduzca una fecha válida", response.content.decode('utf-8')) response = client.get(url, { 'group': group_a.id, 'end': end}, follow=True) self.assertIn("Este campo es obligatorio", response.content.decode('utf-8')) response = client.get(url, {'group': '1A', 'start': start, 'end': end}, follow=True) self.assertIn('Introduzca un número entero', response.content.decode('utf-8')) # User can't download ranking client.logout() client.login(username=user.username, password='******') response = client.get(url, {'group': group_a.id, 'start': start, 'end': end}, follow=True) self.assertIn('Forbidden', response.content.decode('utf-8'))
def test_return_none(self): """Test if an user don't solve a problem, function solved_position return None""" user = create_user('passwordmichu', 'michu') coll = create_collection('Coleccion de cartas') problem = create_select_problem(coll, 'Problema') self.assertIsNone(problem.solved_position(user))
def test_feedback_language(self): """Test to check language in feedback""" client = Client() collection = create_collection('Colleccion de prueba XYZ') select_problem = create_select_problem(collection, 'SelectProblem ABC DEF') create_user('5555', 'pedro') client.login(username='******', password='******') expected = { 'header': [['Algo', "<class 'cx_Oracle.NUMBER'>"], ['name', "<class 'cx_Oracle.STRING'>"]], 'rows': [[1, 'a'], [2, 'b']] } obtained1 = { 'header': [['name', "<class 'cx_Oracle.STRING'>"], ['Algo', "<class 'cx_Oracle.NUMBER'>"]], 'rows': [['b', 2], ['a', 1]] } obtained2 = { 'header': [['Algo', "<class 'cx_Oracle.NUMBER'>"], ['name', "<class 'cx_Oracle.STRING'>"], ['name', "<class 'cx_Oracle.STRING'>"]], 'rows': [[1, 'a', 'a'], [2, 'b', 'b']] } select_problem = create_select_problem(collection, 'SelectProblem ABC DEF') client.cookies.load({settings.LANGUAGE_COOKIE_NAME: 'en'}) submit_url_select = reverse('judge:submit', args=[select_problem.pk]) response = client.post( submit_url_select, {'code': f'{select_problem.solution}; {select_problem.solution}'}, follow=True) self.assertIn('Exactly expected 1 SQL statement', response.content.decode('utf-8')) self.assertIn("Expected: 2 columns", compare_select_results(expected, obtained2, True)[1]) self.assertIn("Generated by your SQL code: 3 columns", compare_select_results(expected, obtained2, True)[1]) self.assertIn("Number of columns obtained:", compare_select_results(expected, obtained2, True)[1]) self.assertIn("name of the 1th column", compare_select_results(expected, obtained1, False)[1]) self.assertIn("Expected name: Algo", compare_select_results(expected, obtained1, False)[1]) self.assertIn("Generated name by your SQL code: name", compare_select_results(expected, obtained1, False)[1]) client.cookies.load({settings.LANGUAGE_COOKIE_NAME: 'es'}) submit_url_select = reverse('judge:submit', args=[select_problem.pk]) response = client.post( submit_url_select, {'code': f'{select_problem.solution}; {select_problem.solution}'}, follow=True) self.assertIn('Se esperaba exactamente 1 sentencia SQL', response.content.decode('utf-8')) self.assertIn("Esperado: 2 columnas", compare_select_results(expected, obtained2, True)[1]) self.assertIn("Generado por tu código SQL: 3 columnas", compare_select_results(expected, obtained2, True)[1]) self.assertIn("Número de columnas obtenidas:", compare_select_results(expected, obtained2, True)[1]) self.assertIn("nombre de la 1ª columna", compare_select_results(expected, obtained1, False)[1]) self.assertIn("Nombre esperado: Algo", compare_select_results(expected, obtained1, False)[1]) self.assertIn("Nombre generado por tu código SQL: name", compare_select_results(expected, obtained1, False)[1])
def test_signal_update_achievement(self): """Test for check signals""" # Create two users for test all the achievements. Two for the podium client = Client() user_michu = create_user('passwordmichu', 'michu') create_user('passwordimmobile', 'immobile') client.login(username='******', password='******') # Create the Collection for the achievement NumSolvedCollectionAchievementDefinition and Problem coll = create_collection('Coleccion de cartas') # Create PodiumAchievementDefinition ach_podium = PodiumAchievementDefinition(name='Presidente del podio', description='Consigue ser el primero', num_problems=1, position=1) ach_podium.save() # Create NumSolvedCollectionAchievementDefinition ach_collection = NumSolvedCollectionAchievementDefinition(name='Coleccionista', description='Resuelve 50\ problemas de esta coleccion', num_problems=50, collection=coll) ach_collection.save() # Create NumSolvedAchievementDefinition ach_solved = NumSolvedAchievementDefinition(name='Resolvista', description='Resuelve 50 problemas', num_problems=50) ach_solved.save() # Create NumSolvedTypeAchievementDefinition ach_type = NumSolvedTypeAchievementDefinition(name='Procedista', description='Resuelve un problema PROC', num_problems=1, problem_type=ProblemType.PROC.name) ach_type.save() # Create NumSubmissionsProblemsAchievementDefinition ach_submi_pro = NumSubmissionsProblemsAchievementDefinition(name='Muchos envios', description='Envia muchas soluciones', num_submissions=80, num_problems=1) ach_submi_pro.save() # Create problem and submit correct answer with "immobile" user, for make this the first to solve the problem problem = create_select_problem(coll, 'Problema') submit_select_url = reverse('judge:submit', args=[problem.pk]) client.post(submit_select_url, {'code': problem.solution}, follow=True) client.logout() # Login with "michu" and submit correct answer. All the checks will be with this user client.login(username='******', password='******') client.post(submit_select_url, {'code': problem.solution}, follow=True) # Whit this definitions our user "michu" don't have any achievement self.assertEqual(ObtainedAchievement.objects.filter(user=user_michu).count(), 0) # PodiumAchievementDefinition now only need to stay in podium # In this test our user "michu" stay at second position, that is why before he didn't have the achievement ach_podium.position = 3 ach_podium.save() # NumSolvedCollectionAchievementDefinition only needs one correct submission # In this test our user only have one correct submission, that is why before he didn't have the achievement ach_collection.num_problems = 1 ach_collection.save() # NumSolvedAchievementDefinition only needs one correct submission # In this test our user only have one correct submission, that is why before he didn't have the achievement ach_solved.num_problems = 1 ach_solved.save() # NumSolvedTypeAchievementDefinition change to type SELECT # In this test our user only resolved a SELECT type problem, not PROC. ach_type.problem_type = ProblemType.SELECT.name ach_type.save() # NumSubmissionsProblemsAchievementDefinition only needs one submission now ach_submi_pro.num_submissions = 1 ach_submi_pro.save() # Now our user "michu" have 5 achievements self.assertEqual(ObtainedAchievement.objects.filter(user=user_michu).count(), 5)
def test_collection_languages(self): """Test to check languages in collection list""" client = Client() collection = create_collection('Collection') create_user('5555', 'pepe') client.login(username='******', password='******') create = 'CREATE TABLE mytable (dd DATE);' insert = "INSERT INTO mytable VALUES (TO_DATE('2020/01/31', 'yyyy/mm/dd'))" solution = 'SELECT * FROM mytable' problem1 = SelectProblem(title_md='Dates', text_md='Example with dates', language="es", create_sql=create, insert_sql=insert, collection=collection, solution=solution) problem2 = SelectProblem(title_md='Dates', text_md='Example with dates', language="es", create_sql=create, insert_sql=insert, collection=collection, solution=solution) problem1.clean() problem1.save() problem2.clean() problem2.save() self.assertIn("es", collection.languages()) self.assertNotIn("en", collection.languages()) collections_url = reverse('judge:collections') html = client.get(collections_url, follow=True).content.decode('utf-8') soup = BeautifulSoup(html, 'html.parser') self.assertEqual( soup.find_all("div", {"class": "flags"})[0].find_all( "span", {"flag-icon"}), []) problem3 = SelectProblem(title_md='Dates', text_md='Example with dates', language="en", create_sql=create, insert_sql=insert, collection=collection, solution=solution) problem3.clean() problem3.save() self.assertIn("es", collection.languages()) self.assertIn("en", collection.languages()) collections_url = reverse('judge:collections') html = client.get(collections_url, follow=True).content.decode('utf-8') soup = BeautifulSoup(html, 'html.parser') self.assertEqual( len( soup.find_all("div", {"class": "flags"})[0].find_all( "span", {"flag-icon"})), 2) flags = soup.find_all("div", {"class": "flags"})[0].find_all( "span", {"flag-icon"})[0]['class'] flags.extend( soup.find_all("div", {"class": "flags"})[0].find_all( "span", {"flag-icon"})[1]['class']) self.assertIn("flag-icon-us", flags) self.assertIn("flag-icon-es", flags)
def test_achievement_language(self): """Test to check the correct language display of achievements""" client = Client() solved_achievement_1 = NumSolvedAchievementDefinition( name={ "es": 'Nombre1', "en": 'Name1' }, description={ "es": 'Descripción1', "en": 'Description1' }, num_problems=1) solved_achievement_2 = NumSolvedAchievementDefinition( name={ "es": 'Nombre2', "en": 'Name2' }, description={ "es": 'Descripción2', "en": 'Description2' }, num_problems=2) solved_achievement_3 = NumSolvedAchievementDefinition( name={"es": 'Nombre3'}, description={"es": 'Descripción3'}, num_problems=3) solved_achievement_1.save() solved_achievement_2.save() solved_achievement_3.save() coll = create_collection('Achievements') problem = create_select_problem(coll, 'Select1') user = create_user('5555', 'pepe') client.login(username='******', password='******') submit_select_url = reverse('judge:submit', args=[problem.pk]) client.post(submit_select_url, {'code': problem.solution}, follow=True) client.post(submit_select_url, {'code': problem.solution}, follow=True) client.cookies.load({settings.LANGUAGE_COOKIE_NAME: 'en'}) achievements_url = reverse('judge:achievements', args=[user.pk]) response = client.get(achievements_url, follow=True) self.assertIn('Date', response.content.decode('utf-8')) self.assertIn('Pending achievements', response.content.decode('utf-8')) self.assertIn('Name1', response.content.decode('utf-8')) self.assertIn('Name2', response.content.decode('utf-8')) self.assertIn('Nombre3', response.content.decode('utf-8')) self.assertIn('Description1', response.content.decode('utf-8')) self.assertIn('Description2', response.content.decode('utf-8')) self.assertIn('Descripción3', response.content.decode('utf-8')) client.cookies.load({settings.LANGUAGE_COOKIE_NAME: 'es'}) achievements_url = reverse('judge:achievements', args=[user.pk]) response = client.get(achievements_url, follow=True) self.assertIn('Fecha', response.content.decode('utf-8')) self.assertIn('Logros pendientes', response.content.decode('utf-8')) self.assertIn('Nombre1', response.content.decode('utf-8')) self.assertIn('Nombre2', response.content.decode('utf-8')) self.assertIn('Nombre3', response.content.decode('utf-8')) self.assertIn('Descripción1', response.content.decode('utf-8')) self.assertIn('Descripción2', response.content.decode('utf-8')) self.assertIn('Descripción3', response.content.decode('utf-8'))