def test_solved_n_position(self): """ Test that solved_n_position does not count staff or inactive users """ staff_user = get_user_model().objects.create_user('teacher', password='******', is_staff=True, is_active=True) inactive_user = get_user_model().objects.create_user('inactive', password='******', is_staff=False, is_active=False) user = get_user_model().objects.create_user('normal', password='******', is_staff=False, is_active=True) collection = Collection(name_md='ABC', description_md='blablabla') collection.clean() collection.save() create = 'CREATE TABLE tabla (xx NUMBER);' solution = 'SELECT * FROM tabla' problem = SelectProblem(title_md='Example', text_md='Enunciado', create_sql=create, insert_sql="", collection=collection, solution=solution) problem.clean() problem.save() sub1 = Submission(code='nada', verdict_code=VerdictCode.AC, user=staff_user, problem=problem) sub2 = Submission(code='nada', verdict_code=VerdictCode.AC, user=inactive_user, problem=problem) sub3 = Submission(code='nada', verdict_code=VerdictCode.AC, user=user, problem=problem) for sub in (sub1, sub2, sub3): sub.clean() sub.save() # First non-staff active user to solve the problem is 'user' self.assertEqual(problem.solved_first(), user) self.assertIsNone(problem.solved_second()) self.assertIsNone(problem.solved_third()) # Non-active or staff users are not counted in solved_position self.assertIsNone(problem.solved_position(staff_user)) self.assertIsNone(problem.solved_position(inactive_user)) self.assertEqual(problem.solved_position(user), 1)
def test_select(self): """Tests for SelectProblem.judge()""" collection = Collection() collection.save() create = '''CREATE TABLE "Nombre Club" ( CIF CHAR(9) PRIMARY KEY, -- No puede ser NULL Nombre VARCHAR2(40) NOT NULL UNIQUE, Sede VARCHAR2(30) NOT NULL, Num_Socios NUMBER(10,0) NOT NULL, CONSTRAINT NumSociosPositivos CHECK (Num_Socios >= 0) );''' insert = '''INSERT INTO "Nombre Club" VALUES ('11111111X', 'Real Madrid CF', 'Concha Espina', 70000); INSERT INTO "Nombre Club" VALUES ('11111112X', 'Futbol Club Barcelona', 'Aristides Maillol', 80000); INSERT INTO "Nombre Club" VALUES ('11111113X', 'PSG', 'Rue du Commandant Guilbaud', 1000);''' solution = 'SELECT * FROM "Nombre Club";' oracle = OracleExecutor.get() problem = SelectProblem(title_md='Test Select', text_md='bla bla bla', create_sql=create, insert_sql=insert, collection=collection, author=None, check_order=False, solution=solution) problem.clean() # Needed to compute extra HTML fields and solutions problem.save() # Time-limit tle = SELECT_TLE too_many_rows = 'select * from dual connect by level <= 1001;' too_many_cols = 'select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from dual;' self.assert_executor_exception(lambda: problem.judge(tle, oracle), OracleStatusCode.TLE_USER_CODE) self.assert_executor_exception(lambda: problem.judge(too_many_rows, oracle), OracleStatusCode.TLE_USER_CODE) self.assert_executor_exception(lambda: problem.judge(too_many_cols, oracle), OracleStatusCode.TLE_USER_CODE) # Validation error (only one statement supported) self.assert_executor_exception(lambda: problem.judge('', oracle), OracleStatusCode.NUMBER_STATEMENTS) self.assert_executor_exception(lambda: problem.judge('SELECT * FROM "Nombre Club"; SELECT * FROM "Nombre Club"', oracle), OracleStatusCode.NUMBER_STATEMENTS) # Runtime error self.assert_executor_exception(lambda: problem.judge('SELECT * from "Nombre ClubE"', oracle), OracleStatusCode.EXECUTE_USER_CODE) self.assert_executor_exception(lambda: problem.judge('SELECT * from Club', oracle), OracleStatusCode.EXECUTE_USER_CODE) self.assert_executor_exception(lambda: problem.judge('SELECT * FROM', oracle), OracleStatusCode.EXECUTE_USER_CODE) # Correct solution self.assertEqual(problem.judge(solution, oracle)[0], VeredictCode.AC) self.assertEqual(problem.judge('SELECT CIF, NOmbre, Sede, Num_Socios FROM "Nombre Club"', oracle)[0], VeredictCode.AC) self.assertEqual(problem.judge('SELECT * FROM "Nombre Club" ORDER BY Num_Socios ASC', oracle)[0], VeredictCode.AC) # Incorrect solution self.assertEqual(problem.judge('SELECT CIF FROM "Nombre Club"', oracle)[0], VeredictCode.WA) self.assertEqual(problem.judge('SELECT * FROM "Nombre Club" WHERE Num_Socios < 50000', oracle)[0], VeredictCode.WA)
def create_select_problem(collection, name='Ejemplo'): """ Creates and stores a Select Problem """ create = 'CREATE TABLE test (n NUMBER);' insert = "INSERT INTO test VALUES (901)" solution = 'SELECT * FROM test' problem = SelectProblem(title_md=name, text_md='texto largo', create_sql=create, insert_sql=insert, collection=collection, solution=solution) problem.clean() problem.save() return problem
def test_table_with_date(self): """Check that DATEs are correctly stored and retrived from the DB, and comparing them to a new obtained value works as expected""" collection = Collection() collection.save() create = 'CREATE TABLE test (day DATE);' insert = "INSERT INTO test VALUES (TO_DATE('2003/07/09', 'yyyy/mm/dd'))" solution = 'SELECT * FROM test' problem = SelectProblem(title_md='Dates', text_md='Example with dates', create_sql=create, insert_sql=insert, collection=collection, solution=solution) problem.clean() problem.save() oracle = OracleExecutor.get() veredict, _ = problem.judge(solution, oracle) self.assertEqual(veredict, VeredictCode.AC) veredict, _ = problem.judge("SELECT TO_DATE('2003/07/09', 'yyyy/mm/dd') AS day FROM dual", oracle) self.assertEqual(veredict, VeredictCode.AC)
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_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_problem_collection_stats(self): """Methods that compute statistics in collections and problems""" collection = Collection(name_md='ABC', description_md='blablabla') collection.clean() collection.save() self.assertTrue('ABC' in str(collection)) user_model = django.contrib.auth.get_user_model() 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', create_sql=create, insert_sql=insert, collection=collection, solution=solution) problem2 = SelectProblem(title_md='Dates', text_md='Example with dates', create_sql=create, insert_sql=insert, collection=collection, solution=solution) problem3 = SelectProblem(title_md='Dates', text_md='Example with dates', create_sql=create, insert_sql=insert, collection=collection, solution=solution) user1 = user_model.objects.create_user(username='******', email='*****@*****.**', password='******') user2 = user_model.objects.create_user(username='******', email='*****@*****.**', password='******') problem1.clean() problem1.save() problem2.clean() problem2.save() problem3.clean() problem3.save() user1.save() user2.save() sub1 = Submission(code='nada', veredict_code=VeredictCode.WA, user=user1, problem=problem1) sub2 = Submission(code='nada', veredict_code=VeredictCode.AC, user=user1, problem=problem1) sub3 = Submission(code='nada', veredict_code=VeredictCode.TLE, user=user1, problem=problem1) sub4 = Submission(code='nada', veredict_code=VeredictCode.RE, user=user1, problem=problem1) sub5 = Submission(code='nada', veredict_code=VeredictCode.VE, user=user1, problem=problem1) sub6 = Submission(code='nada', veredict_code=VeredictCode.IE, user=user1, problem=problem1) self.assertTrue('WA' in str(sub1)) self.assertTrue('AC' in str(sub2)) for sub in [sub1, sub2, sub3, sub4, sub5, sub6]: sub.save() # Problem solved self.assertTrue(problem1.solved_by_user(user1)) self.assertFalse(problem1.solved_by_user(user2)) self.assertFalse(problem2.solved_by_user(user1)) self.assertFalse(problem2.solved_by_user(user2)) # Number of submissions self.assertEqual(problem1.num_submissions_by_user(user1), 6) self.assertEqual(problem1.num_submissions_by_user(user2), 0) self.assertEqual(problem2.num_submissions_by_user(user1), 0) self.assertEqual(problem2.num_submissions_by_user(user2), 0) # Problems in collection self.assertEqual(collection.problems().count(), 3) self.assertEqual(collection.num_problems(), 3) # Numbers of problems solved by a user self.assertEqual(collection.num_solved_by_user(user1), 1) self.assertEqual(collection.num_solved_by_user(user2), 0)
def test_podium(self): """Test the correct performance of the podium""" collection = Collection(name_md='ABC', description_md='blablabla') collection.clean() collection.save() self.assertIn('ABC', str(collection)) user_model = django.contrib.auth.get_user_model() 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', create_sql=create, insert_sql=insert, collection=collection, solution=solution) problem2 = SelectProblem(title_md='Dates', text_md='Example with dates', create_sql=create, insert_sql=insert, collection=collection, solution=solution) user1 = user_model.objects.create_user(username='******', email='*****@*****.**', password='******') user2 = user_model.objects.create_user(username='******', email='*****@*****.**', password='******') user3 = user_model.objects.create_user(username='******', email='*****@*****.**', password='******') user4 = user_model.objects.create_user(username='******', email='*****@*****.**', password='******') problem1.clean() problem1.save() problem2.clean() problem2.save() user1.save() user2.save() user3.save() self.assertIsNone(problem1.solved_first()) self.assertIsNone(problem1.solved_second()) self.assertIsNone(problem1.solved_third()) sub1 = Submission(code='nada', veredict_code=VeredictCode.WA, user=user1, problem=problem1) sub2 = Submission(code='nada', veredict_code=VeredictCode.IE, user=user1, problem=problem1) sub3 = Submission(code='nada', veredict_code=VeredictCode.TLE, user=user1, problem=problem1) sub4 = Submission(code='nada', veredict_code=VeredictCode.RE, user=user1, problem=problem1) sub5 = Submission(code='nada', veredict_code=VeredictCode.VE, user=user1, problem=problem1) for sub in [sub1, sub2, sub3, sub4, sub5]: sub.save() self.assertIsNone(problem1.solved_first()) self.assertIsNone(problem1.solved_second()) self.assertIsNone(problem1.solved_third()) Submission(code='nada', veredict_code=VeredictCode.AC, user=user1, problem=problem1).save() self.assertEqual(problem1.solved_first(), user1) self.assertIsNone(problem1.solved_second()) self.assertIsNone(problem1.solved_third()) Submission(code='nada', veredict_code=VeredictCode.AC, user=user1, problem=problem1).save() Submission(code='nada', veredict_code=VeredictCode.AC, user=user1, problem=problem1).save() self.assertEqual(problem1.solved_first(), user1) self.assertIsNone(problem1.solved_second()) self.assertIsNone(problem1.solved_third()) Submission(code='nada', veredict_code=VeredictCode.AC, user=user2, problem=problem1).save() self.assertEqual(problem1.solved_first(), user1) self.assertEqual(problem1.solved_second(), user2) self.assertIsNone(problem1.solved_third()) Submission(code='nada', veredict_code=VeredictCode.AC, user=user1, problem=problem1).save() Submission(code='nada', veredict_code=VeredictCode.AC, user=user3, problem=problem1).save() self.assertEqual(problem1.solved_first(), user1) self.assertEqual(problem1.solved_second(), user2) self.assertEqual(problem1.solved_third(), user3) Submission(code='nada', veredict_code=VeredictCode.AC, user=user1, problem=problem1).save() Submission(code='nada', veredict_code=VeredictCode.AC, user=user1, problem=problem1).save() Submission(code='nada', veredict_code=VeredictCode.AC, user=user4, problem=problem1).save() self.assertEqual(problem1.solved_first(), user1) self.assertEqual(problem1.solved_second(), user2) self.assertEqual(problem1.solved_third(), user3) self.assertIsNone(problem2.solved_first()) self.assertIsNone(problem2.solved_second()) self.assertIsNone(problem2.solved_third())
def test_judge_multiple_db(self): """Test multiple db select problems""" curr_path = os.path.dirname(__file__) zip_select_multiple_db_path = os.path.join(curr_path, self.ZIP_FOLDER, self.SELECT_MULTIPLE_DB_OK) select_multiple_db_problem = SelectProblem( zipfile=zip_select_multiple_db_path) select_multiple_db_problem.clean() self.assertEqual(len(select_multiple_db_problem.insert_sql_list()), 3) collection = Collection(name_md='ABC', description_md='blablabla') collection.clean() collection.save() self.assertTrue('ABC' in str(collection)) create = '''CREATE TABLE Club( CIF CHAR(9) PRIMARY KEY, -- No puede ser NULL Nombre VARCHAR2(40) NOT NULL, Sede VARCHAR2(30) NOT NULL, Num_Socios NUMBER(10,0) NOT NULL, CONSTRAINT NumSociosPositivos CHECK (Num_Socios >= 0) ); CREATE TABLE Persona( NIF CHAR(9) PRIMARY KEY, Nombre VARCHAR2(20) NOT NULL );''' insert = '''INSERT INTO Club VALUES ('11111111X', 'Madrid', 'A', 70000); -- @new data base@ INSERT INTO Club VALUES ('11111111X', 'Madrid', 'A', 70000); INSERT INTO Club VALUES ('11111112X', 'Futbol Club Barcelona', 'A', 80000); INSERT INTO Club VALUES ('11111113X', 'Paris Saint-Germain Football Club', 'C', 1000); INSERT INTO Persona VALUES ('00000001X', 'Peter Johnoson'); -- @new data base@ INSERT INTO Club VALUES ('11111111X', 'Madrid', 'A', 70000); INSERT INTO Club VALUES ('11111112X', 'Madrid', 'B', 80000); INSERT INTO Club VALUES ('11111114X', 'Futbol Club Barcelona', 'B', 80000); INSERT INTO Club VALUES ('11111115X', 'Paris Saint-Germain Football Club', 'C', 1000); INSERT INTO Persona VALUES ('00000001X', 'Peter Johnoson');''' solution = "SELECT Sede, Nombre FROM Club WHERE CIF = '11111111X' and Nombre ='Madrid';" oracle = OracleExecutor.get() problem = SelectProblem(title_md='Test Multiple db Select', text_md='bla', create_sql=create, insert_sql=insert, collection=collection, author=None, check_order=False, solution=solution) problem.clean() problem.save() self.assertEqual(problem.judge(solution, oracle)[0], VeredictCode.AC) self.assertEqual( problem.judge( "SELECT Sede, Nombre FROM Club WHERE Nombre ='Madrid';", oracle)[0], VeredictCode.WA) self.assertEqual( problem.judge("SELECT Sede, Nombre FROM Club;", oracle)[0], VeredictCode.WA) html = problem.judge( "SELECT Sede, Nombre FROM Club WHERE CIF = '11111111X' and Nombre ='Madrid';", oracle)[1] soup = BeautifulSoup(html, 'html.parser') # Dont show db if code is correct self.assertIsNone(soup.find(id="bd")) html = problem.judge( "SELECT Sede, Nombre FROM Club WHERE CIF = '11111117X';", oracle)[1] soup = BeautifulSoup(html, 'html.parser') # Dont show db if code is wrong in the first db self.assertIsNone(soup.find(id="bd")) html = problem.judge("SELECT Sede, Nombre FROM Club;", oracle)[1] soup = BeautifulSoup(html, 'html.parser') # Show second db if code is correct in the first db but not in the second db self.assertEqual( soup.find(id="bd").find('p').find('strong').string, "Base de datos utilizada para la ejecución de tu código SQL:") self.assertEqual( soup.find(id="bd").find_all('thead')[0].find_all('th')[0].string, "CIF") self.assertEqual( soup.find(id="bd").find_all('thead')[0].find_all('th')[1].string, "NOMBRE") self.assertEqual(len(soup.find(id="bd").find_all('thead')), 2) self.assertEqual( soup.find(id="bd").find_all('thead')[1].find_all('th')[0].string, "NIF") self.assertEqual( soup.find(id="bd").find_all('tbody')[0].find_all('tr')[1].find_all( 'td')[0].string, "11111112X") self.assertEqual( soup.find(id="bd").find_all('tbody')[0].find_all('tr')[1].find_all( 'td')[2].string, "A") self.assertEqual( len(soup.find(id="bd").find_all('tbody')[0].find_all('tr')), 3) html = problem.judge( "SELECT Sede, Nombre FROM Club WHERE Nombre ='Madrid';", oracle)[1] soup = BeautifulSoup(html, 'html.parser') # Show third db if code is correct in the first and second dbs but not in the third db self.assertEqual( soup.find(id="bd").find('p').find('strong').string, "Base de datos utilizada para la ejecución de tu código SQL:") self.assertEqual( soup.find(id="bd").find_all('thead')[0].find_all('th')[0].string, "CIF") self.assertEqual( soup.find(id="bd").find_all('thead')[0].find_all('th')[1].string, "NOMBRE") self.assertEqual( soup.find(id="bd").find_all('tbody')[0].find_all('tr')[1].find_all( 'td')[0].string, "11111112X") self.assertEqual( soup.find(id="bd").find_all('tbody')[0].find_all('tr')[1].find_all( 'td')[2].string, "B") self.assertEqual( len(soup.find(id="bd").find_all('tbody')[0].find_all('tr')), 4)
def test_achievements_submit(self): """Test to show correct message when obtain an achievement""" client = Client() collection = create_collection('Colleccion de prueba XYZ') select_problem = create_select_problem(collection, 'SelectProblem ABC DEF') user = create_user('5555', 'tamara') ach_submission = NumSubmissionsProblemsAchievementDefinition( name={"es": 'Un envio'}, description={"es": 'Envia una solucion para un problema'}, num_problems=1, num_submissions=1) ach_submission.save() ach_submissions = NumSubmissionsProblemsAchievementDefinition( name={"es": 'Tres envios'}, description={"es": 'Envia tres soluciones de un problema'}, num_problems=1, num_submissions=3) ach_submissions.save() ach_type = NumSolvedTypeAchievementDefinition( name={"es": 'Es select'}, description={"es": 'Resuelve un problema SELECT'}, num_problems=1, problem_type=ProblemType.SELECT.name) client.login(username='******', password='******') submit_select_url = reverse('judge:submit', args=[select_problem.pk]) # The user submits one solution and obtains the first achievement response = client.post(submit_select_url, {'code': 'MAL'}, follow=True) # Validation Error, too short obtained_achieve = ObtainedAchievement.objects.filter(user=user) self.assertIn(obtained_achieve[0].achievement_definition.name['es'], response.json()['achievements']) # The user submits a new solution and does not receive any achievement response = client.post(submit_select_url, {'code': 'MAL'}, follow=True) # Validation Error, too short self.assertNotIn('achievements', response.json()) # The user makes another submission and obtain two achievements ach_type.save() curr_path = os.path.dirname(__file__) zip_select_path = os.path.join(curr_path, ParseTest.ZIP_FOLDER, ParseTest.SELECT_OK) collection = create_collection('Coleccion 1') select = SelectProblem(zipfile=zip_select_path, collection=collection) select.clean() select.save() submit_url = reverse('judge:submit', args=[select.pk]) response = client.post(submit_url, {'code': select.solution}, follow=True) obtained_achieve = ObtainedAchievement.objects.filter(user=user) self.assertIn(obtained_achieve[1].achievement_definition.name['es'], response.json()['achievements']) self.assertIn(obtained_achieve[2].achievement_definition.name['es'], response.json()['achievements']) # The user submits a new solution and does not receive any achievement response = client.post(submit_select_url, {'code': 'MAL'}, follow=True) # Validation Error, too short self.assertNotIn('achievements', response.json())