From ec4d538eb70bfe89784b7b9fbc265125d5abecd3 Mon Sep 17 00:00:00 2001 From: HustleRRR Date: Sat, 30 Oct 2021 16:48:07 +0530 Subject: [PATCH 1/2] fixed bugs for scraper_utils in codechef app --- codedigger/codechef/cron.py | 20 +---- codedigger/codechef/model_utils.py | 17 ++--- codedigger/codechef/scraper.py | 4 +- codedigger/codechef/scraper_utils.py | 21 ++++-- .../test_fixtures/model_utils_fixture.py | 17 ----- .../test_fixtures/scraper_utils_fixture.py | 74 +++++++++---------- codedigger/codechef/tests/test_model_utils.py | 21 ------ codedigger/codechef/tests/test_scraper.py | 8 +- 8 files changed, 69 insertions(+), 113 deletions(-) delete mode 100644 codedigger/codechef/test_fixtures/model_utils_fixture.py delete mode 100644 codedigger/codechef/tests/test_model_utils.py diff --git a/codedigger/codechef/cron.py b/codedigger/codechef/cron.py index aa85517..e9a8709 100644 --- a/codedigger/codechef/cron.py +++ b/codedigger/codechef/cron.py @@ -1,20 +1,8 @@ -from .model_utils import create_or_update_codechefContest,create_or_update_codechefProblem -from .models import CodechefContest,CodechefContestProblems from problem.models import Problem -from .scraper_utils import ContestData,ProblemData,getContestDivision -from .scraper import contestScraper,problemScraper,divisionScraper - - -def OffsetLoader(contest_type): - - requested_contests = [] - for i in range(0, 60, 20): #offset {0, 20, 40} for multiple pages of contests. - contests_data = contestScraper(i, contest_type) - - for contests in contests_data['contests']: - requested_contests.append(contests) - - return requested_contests +from codechef.models import CodechefContest,CodechefContestProblems +from codechef.scraper import contestScraper,problemScraper,divisionScraper +from codechef.scraper_utils import ContestData,ProblemData,getContestDivision,OffsetLoader +from codechef.model_utils import create_or_update_codechefContest,create_or_update_codechefProblem def update_AllContests(): diff --git a/codedigger/codechef/model_utils.py b/codedigger/codechef/model_utils.py index 92e681b..695dd45 100644 --- a/codedigger/codechef/model_utils.py +++ b/codedigger/codechef/model_utils.py @@ -1,34 +1,31 @@ from datetime import datetime - -from .models import CodechefContest -from .models import CodechefContest, CodechefContestProblems from problem.models import Problem -from codechef.scraper import contestScraper, problemScraper, divisionScraper -from codechef.scraper_utils import OffsetLoader, getContestDivision, ContestData, ProblemData +from codechef.models import CodechefContest, CodechefContestProblems +from codechef.scraper_utils import ContestData, ProblemData def create_or_update_codechefProblem(contestId): problemdata = ProblemData(contestId) for problem in problemdata: - Prob = Problem.get_or_create(name=problem['Name'], + Prob = Problem.objects.get_or_create(name=problem['Name'], prob_id=problem['ProblemCode'], url=problem['ProblemURL'], contest_id=problem['ContestId'], platform=problem['Platform']) cont = CodechefContest.objects.get_or_create( - contestId=Problem['ContestCode'], ) - codechefProb = CodechefContestProblems.get_or_create(contest=cont, + contestId=problem['ContestId'], ) + codechefProb = CodechefContestProblems.objects.get_or_create(contest=cont, problem=Prob) def create_or_update_codechefContest(contest): - contestDate = datetime.strptime(contest['contest_start_date'], + contestDate = datetime.strptime(contest["StartTime"], "%d %B %Y %H:%M:%S") cont = CodechefContest.objects.get_or_create( name=contest['Name'], contestId=contest['ContestCode'], duration=contest['Duration'], - StartTime=contestDate, + startTime=contestDate, url=contest['ContestURL']) diff --git a/codedigger/codechef/scraper.py b/codedigger/codechef/scraper.py index 5ae7b7b..f0942e4 100644 --- a/codedigger/codechef/scraper.py +++ b/codedigger/codechef/scraper.py @@ -7,7 +7,7 @@ def divisionScraper(contest_id): - contest_url = "https://www.codechef.com/api/contests/" + contest_id + contest_url = f"https://www.codechef.com/api/contests/{contest_id}" contest_req = requests.get(contest_url) if contest_req.status_code != 200: raise ValidationException( @@ -33,7 +33,7 @@ def contestScraper(offset, contest_type): def problemScraper(contest_code): - query_problem_url = f"https://www.codechef.com/api/contests/" + contest_code + query_problem_url = f"https://www.codechef.com/api/contests/{contest_code}" # Query URL might change in future. problem_data = requests.get(query_problem_url) if problem_data.status_code != 200: diff --git a/codedigger/codechef/scraper_utils.py b/codedigger/codechef/scraper_utils.py index 649c43d..b45f896 100644 --- a/codedigger/codechef/scraper_utils.py +++ b/codedigger/codechef/scraper_utils.py @@ -1,10 +1,22 @@ + +import os, json, django import requests from bs4 import BeautifulSoup from time import sleep -import os, json, django from user.exception import ValidationException -from codechef.scraper import contestScraper, problemScraper, divisionScraper -from codechef.cron import OffsetLoader +from codechef.scraper import problemScraper + + +def OffsetLoader(contest_type): + + requested_contests = [] + for i in range(0, 60, 20): #offset {0, 20, 40} for multiple pages of contests. + contests_data = contestScraper(i, contest_type) + + for contests in contests_data['contests']: + requested_contests.append(contests) + + return requested_contests def getContestDivision(contest_id): @@ -78,6 +90,3 @@ def ProblemData(contest_code): all_problems.append(finalProblemData) return (all_problems) - -xd = ProblemData("COOK117B") -print(xd) diff --git a/codedigger/codechef/test_fixtures/model_utils_fixture.py b/codedigger/codechef/test_fixtures/model_utils_fixture.py deleted file mode 100644 index caeba42..0000000 --- a/codedigger/codechef/test_fixtures/model_utils_fixture.py +++ /dev/null @@ -1,17 +0,0 @@ -codechef_contest = { - "Name": contest['contest_name'], - "ContestCode": contest_id, - "Duration": contest['contest_duration'], - "StartTime": contest_updated_date, - 'ContestURL': "https://www.codechef.com/" + contest_id -} - -codechef_problem = [ - {'Name': 'Lift Requests', 'ProblemCode': 'LIFTME', 'ProblemURL': 'https://www.codechef.com/COOK117B/problems/LIFTME', 'ContestId': 'COOK117B', 'Platform': 'C'}, - {'Name': 'Inversions in Permutations', 'ProblemCode': 'KPERM', 'ProblemURL': 'https://www.codechef.com/COOK117B/problems/KPERM', 'ContestId': 'COOK117B', 'Platform': 'C'}, - {'Name': 'Matrix Decomposition', 'ProblemCode': 'MATBREAK', 'ProblemURL': 'https://www.codechef.com/COOK117B/problems/MATBREAK', 'ContestId': 'COOK117B', 'Platform': 'C'}, - {'Name': 'Simple Operations', 'ProblemCode': 'MINOPS', 'ProblemURL': 'https://www.codechef.com/COOK117B/problems/MINOPS', 'ContestId': 'COOK117B', 'Platform': 'C'}, - {'Name': 'The Gifting Problem', 'ProblemCode': 'KARRAY', 'ProblemURL': 'https://www.codechef.com/COOK117B/problems/KARRAY', 'ContestId': 'COOK117B', 'Platform': 'C'}, - {'Name': 'Tower Counting', 'ProblemCode': 'TOWCNT', 'ProblemURL': 'https://www.codechef.com/COOK117B/problems/TOWCNT', 'ContestId': 'COOK117B', 'Platform': 'C'}, - {'Name': 'Maximum GCD Subset', 'ProblemCode': 'TREESUB', 'ProblemURL': 'https://www.codechef.com/COOK117B/problems/TREESUB', 'ContestId': 'COOK117B', 'Platform': 'C'} -] diff --git a/codedigger/codechef/test_fixtures/scraper_utils_fixture.py b/codedigger/codechef/test_fixtures/scraper_utils_fixture.py index 099f5c0..fe1e01a 100644 --- a/codedigger/codechef/test_fixtures/scraper_utils_fixture.py +++ b/codedigger/codechef/test_fixtures/scraper_utils_fixture.py @@ -1,4 +1,4 @@ -contestResult = {{ +contestResult = { "status": "success", "user": { "username": "" @@ -11,143 +11,143 @@ "name": "Mininum XOR over Tree", "type": "3", "successful_submissions": "43", - "allow_submission": false, + "allow_submission": False, "accuracy": 1.4099999999999999, "problem_url": "\/problems\/XORMIN", "submit_url": "\/submit\/XORMIN", "status_url": "\/status\/XORMIN", "category_name": "main", - "is_direct_submittable": false + "is_direct_submittable": False }, "KLPM": { "code": "KLPM", "name": "Kira Loves Palindromes", "type": "3", "successful_submissions": "156", - "allow_submission": false, + "allow_submission": False, "accuracy": 3.6000000000000001, "problem_url": "\/problems\/KLPM", "submit_url": "\/submit\/KLPM", "status_url": "\/status\/KLPM", "category_name": "main", - "is_direct_submittable": false + "is_direct_submittable": False }, "CHEFOFR": { "code": "CHEFOFR", "name": "Offer for Chef", "type": "3", "successful_submissions": "11", - "allow_submission": false, + "allow_submission": False, "accuracy": 20.27, "problem_url": "\/problems\/CHEFOFR", "submit_url": "\/submit\/CHEFOFR", "status_url": "\/status\/CHEFOFR", "category_name": "unscored", - "is_direct_submittable": false + "is_direct_submittable": False }, "SUBREM": { "code": "SUBREM", "name": "Subtree Removal", "type": "3", "successful_submissions": "1063", - "allow_submission": false, + "allow_submission": False, "accuracy": 8.5399999999999991, "problem_url": "\/problems\/SUBREM", "submit_url": "\/submit\/SUBREM", "status_url": "\/status\/SUBREM", "category_name": "main", - "is_direct_submittable": false + "is_direct_submittable": False }, "SJ1": { "code": "SJ1", "name": "Playing with Numbers", "type": "3", "successful_submissions": "699", - "allow_submission": false, + "allow_submission": False, "accuracy": 9.7599999999999998, "problem_url": "\/problems\/SJ1", "submit_url": "\/submit\/SJ1", "status_url": "\/status\/SJ1", "category_name": "main", - "is_direct_submittable": false + "is_direct_submittable": False }, "STRCH": { "code": "STRCH", "name": "Friend or Girlfriend", "type": "3", "successful_submissions": "6690", - "allow_submission": false, + "allow_submission": False, "accuracy": 22.969999999999999, "problem_url": "\/problems\/STRCH", "submit_url": "\/submit\/STRCH", "status_url": "\/status\/STRCH", "category_name": "main", - "is_direct_submittable": false + "is_direct_submittable": False }, "FENCE": { "code": "FENCE", "name": "Fencing", "type": "3", "successful_submissions": "3951", - "allow_submission": false, + "allow_submission": False, "accuracy": 18.210000000000001, "problem_url": "\/problems\/FENCE", "submit_url": "\/submit\/FENCE", "status_url": "\/status\/FENCE", "category_name": "main", - "is_direct_submittable": false + "is_direct_submittable": False }, "MAXREM": { "code": "MAXREM", "name": "Maximum Remaining", "type": "3", "successful_submissions": "10068", - "allow_submission": false, + "allow_submission": False, "accuracy": 26.25, "problem_url": "\/problems\/MAXREM", "submit_url": "\/submit\/MAXREM", "status_url": "\/status\/MAXREM", "category_name": "main", - "is_direct_submittable": false + "is_direct_submittable": False }, "EDGY": { "code": "EDGY", "name": "Edgy", "type": "3", "successful_submissions": "2", - "allow_submission": false, + "allow_submission": False, "accuracy": 4.3499999999999996, "problem_url": "\/problems\/EDGY", "submit_url": "\/submit\/EDGY", "status_url": "\/status\/EDGY", "category_name": "unscored", - "is_direct_submittable": false + "is_direct_submittable": False }, "RECTARAN": { "code": "RECTARAN", "name": "Moving Rectangles (Challenge)", "type": "2", "successful_submissions": "44", - "allow_submission": false, + "allow_submission": False, "accuracy": 36.539999999999999, "problem_url": "\/problems\/RECTARAN", "submit_url": "\/submit\/RECTARAN", "status_url": "\/status\/RECTARAN", "category_name": "main", - "is_direct_submittable": false + "is_direct_submittable": False }, "SONIQUE": { "code": "SONIQUE", "name": "Sonya and Queries", "type": "3", "successful_submissions": "0", - "allow_submission": false, + "allow_submission": False, "accuracy": 0, "problem_url": "\/problems\/SONIQUE", "submit_url": "\/submit\/SONIQUE", "status_url": "\/status\/SONIQUE", "category_name": "unscored", - "is_direct_submittable": false + "is_direct_submittable": False } }, "banner": @@ -170,7 +170,7 @@ "locked": [] }, "todos": [], - "stats": null, + "stats": 0, "partial_scores": { "CHEFOFR": [{ "score": "100", @@ -246,27 +246,27 @@ "count": "1" }] }, - "isRanklistFrozen": false, - "rank_and_score": null, - "is_a_parent_contest": false, - "is_contest_elements_visible": true, - "is_OTP_required": false, - "isUserRegisteredForTeam": false, + "isRanklistFrozen": False, + "rank_and_score": 0, + "is_a_parent_contest": False, + "is_contest_elements_visible": True, + "is_OTP_required": False, + "isUserRegisteredForTeam": False, "is_linked_problems_contest": "0", - "custom_contest_page_title": null, - "custom_contest_page_meta_desc": null, + "custom_contest_page_title": 0, + "custom_contest_page_meta_desc": 0, "ttl": 60, "scorable_heading": "Scorable Problems for Division 2", "scorable_message": "", "non_scorable_heading": "Non Scorable Problems for Practice", "non_scorable_message": "

The following problems are NOT part of the contest<\/b>, and will not be counted towards your rankings and ratings. These are problems from the other Division(s), made available for you to practice. Click here<\/a> to know more. They will be considered for plagiarism though.<\/p>", - "is_registration_enabled_contest": false, - "is_flexi_time_contest": false, + "is_registration_enabled_contest": False, + "is_flexi_time_contest": False, "duration": "14400", - "is_proctored": false, - "autoRefresh": true -}} + "is_proctored": False, + "autoRefresh": True +} problemResult = [{ 'Name': 'The Wave', diff --git a/codedigger/codechef/tests/test_model_utils.py b/codedigger/codechef/tests/test_model_utils.py deleted file mode 100644 index f697d43..0000000 --- a/codedigger/codechef/tests/test_model_utils.py +++ /dev/null @@ -1,21 +0,0 @@ -from .test_setup import TestSetUp -from .models import CodechefContest, CodechefContestProblems -from problem.models import Problem -from codechef.model_utils import create_or_update_codechefContest,create_or_update_codechefProblem -from codechef.test_fixtures.model_utils_fixture import (codechef_contest,codechef_problem) - -class TestModelUtils(self): - def test_CreateContest(self): - newContest = create_or_update_codechefContest(codechef_contest) - contest = CodechefContest.objects.filter(contestId = codechef_contest['ContestCode']) - self.assertEqual(contest.exists(), True) - self.assertEqual(contest.url, codechef_contest['ContestURL']) - self.assertEqual(contest.startTime, codechef_contest['StartTime']) - - - def test_CreateProblem(self): - newProblem = create_or_update_codechefProblem(codechef_problem) - firstProb = codechef_problem[0] - problem = CodechefContest.objects.filter(contestId = firstProb['ContestId']) - self.assertEqual(problem.exists(), True) - self.assertEqual(len(problem),len(codechef_problem)) \ No newline at end of file diff --git a/codedigger/codechef/tests/test_scraper.py b/codedigger/codechef/tests/test_scraper.py index cbd3431..577658d 100644 --- a/codedigger/codechef/tests/test_scraper.py +++ b/codedigger/codechef/tests/test_scraper.py @@ -6,13 +6,13 @@ class TestScraper(TestSetUp): def test_problemScraper(self): - code = "APRIL19B" + code = "COOK117B" output_result = problemScraper(code) - self.assertEqual(output_result.has_key("status"),true,"Couldn't fetch status result in problemScraper") + self.assertEqual("status" in output_result,True,"Status code not found in problemScraper") self.assertEqual(output_result["status"],"success","Failed status in problemScraper") - self.assertEqual(output_result.has_key("code"),True,"problemScraper doesn't contain the contest code") - self.assertEqual(output_result.has_key("problems"),True,"problemScraper doesn't have the problem info") + self.assertEqual("code" in output_result,True,"problemScraper doesn't contain the contest code") + self.assertEqual("problems" in output_result,True,"problemScraper doesn't have the problem info") def test_ProblemData(self): From 667072c37ef47eb6512a3d1a00f17f59821830fe Mon Sep 17 00:00:00 2001 From: HustleRRR Date: Sat, 6 Nov 2021 22:03:03 +0530 Subject: [PATCH 2/2] Failing test on test_model_utils --- .../codechef/migrations/0001_initial.py | 30 +++++-------------- .../0002_codechefcontestproblems_problemid.py | 19 ------------ ...emove_codechefcontestproblems_problemid.py | 17 ----------- codedigger/codechef/model_utils.py | 15 +++++----- codedigger/codechef/models.py | 5 ++-- .../test_fixtures/model_utils_fixture.py | 17 +++++++++++ codedigger/codechef/tests/test_model_utils.py | 23 ++++++++++++++ 7 files changed, 57 insertions(+), 69 deletions(-) delete mode 100644 codedigger/codechef/migrations/0002_codechefcontestproblems_problemid.py delete mode 100644 codedigger/codechef/migrations/0003_remove_codechefcontestproblems_problemid.py create mode 100644 codedigger/codechef/test_fixtures/model_utils_fixture.py create mode 100644 codedigger/codechef/tests/test_model_utils.py diff --git a/codedigger/codechef/migrations/0001_initial.py b/codedigger/codechef/migrations/0001_initial.py index c687acb..b8f7e96 100644 --- a/codedigger/codechef/migrations/0001_initial.py +++ b/codedigger/codechef/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 3.1.4 on 2021-10-13 10:11 +# Generated by Django 3.1.4 on 2021-11-06 16:17 from django.db import migrations, models import django.db.models.deletion @@ -16,36 +16,20 @@ class Migration(migrations.Migration): migrations.CreateModel( name='CodechefContest', fields=[ - ('id', - models.AutoField(auto_created=True, - primary_key=True, - serialize=False, - verbose_name='ID')), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=200)), ('contestId', models.CharField(db_index=True, max_length=10)), ('duration', models.IntegerField(blank=True, null=True)), - ('startTime', - models.CharField(blank=True, max_length=100, null=True)), - ('division', - models.CharField(blank=True, max_length=5, null=True)), - ('url', models.CharField(blank=True, max_length=200, - null=True)), + ('startTime', models.DateTimeField(blank=True, null=True)), + ('url', models.CharField(blank=True, max_length=200, null=True)), ], ), migrations.CreateModel( name='CodechefContestProblems', fields=[ - ('id', - models.AutoField(auto_created=True, - primary_key=True, - serialize=False, - verbose_name='ID')), - ('contest', - models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, - to='codechef.codechefcontest')), - ('problem', - models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, - to='problem.problem')), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('contest', models.ForeignKey(blank=True, on_delete=django.db.models.deletion.CASCADE, to='codechef.codechefcontest')), + ('problem', models.ForeignKey(blank=True, on_delete=django.db.models.deletion.CASCADE, to='problem.problem')), ], ), ] diff --git a/codedigger/codechef/migrations/0002_codechefcontestproblems_problemid.py b/codedigger/codechef/migrations/0002_codechefcontestproblems_problemid.py deleted file mode 100644 index 406dad2..0000000 --- a/codedigger/codechef/migrations/0002_codechefcontestproblems_problemid.py +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Django 3.1.4 on 2021-10-13 11:22 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('codechef', '0001_initial'), - ] - - operations = [ - migrations.AddField( - model_name='codechefcontestproblems', - name='problemid', - field=models.CharField(db_index=True, default=1, max_length=50), - preserve_default=False, - ), - ] diff --git a/codedigger/codechef/migrations/0003_remove_codechefcontestproblems_problemid.py b/codedigger/codechef/migrations/0003_remove_codechefcontestproblems_problemid.py deleted file mode 100644 index 9cf382b..0000000 --- a/codedigger/codechef/migrations/0003_remove_codechefcontestproblems_problemid.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 3.1.4 on 2021-10-13 11:47 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('codechef', '0002_codechefcontestproblems_problemid'), - ] - - operations = [ - migrations.RemoveField( - model_name='codechefcontestproblems', - name='problemid', - ), - ] diff --git a/codedigger/codechef/model_utils.py b/codedigger/codechef/model_utils.py index 695dd45..aa20913 100644 --- a/codedigger/codechef/model_utils.py +++ b/codedigger/codechef/model_utils.py @@ -7,19 +7,20 @@ def create_or_update_codechefProblem(contestId): problemdata = ProblemData(contestId) for problem in problemdata: - Prob = Problem.objects.get_or_create(name=problem['Name'], + Prob, created = Problem.objects.get_or_create(name=problem['Name'], prob_id=problem['ProblemCode'], url=problem['ProblemURL'], - contest_id=problem['ContestId'], + contest_id=contestId, platform=problem['Platform']) - cont = CodechefContest.objects.get_or_create( - contestId=problem['ContestId'], ) - codechefProb = CodechefContestProblems.objects.get_or_create(contest=cont, - problem=Prob) + # Prob.name = problem['Name'] + # Prob.url = problem['ProblemURL'] + # Prob.contest_id = contestId + cont = CodechefContest.objects.get(contestId=problem['ContestId']) + codechefProb = CodechefContestProblems.objects.get_or_create(contest = cont, problem = Prob) def create_or_update_codechefContest(contest): - contestDate = datetime.strptime(contest["StartTime"], + contestDate = datetime.strptime(contest['StartTime'], "%d %B %Y %H:%M:%S") cont = CodechefContest.objects.get_or_create( name=contest['Name'], diff --git a/codedigger/codechef/models.py b/codedigger/codechef/models.py index 39b0ef7..9b6ff07 100644 --- a/codedigger/codechef/models.py +++ b/codedigger/codechef/models.py @@ -17,9 +17,8 @@ def __str__(self): class CodechefContestProblems(models.Model): - - contest = models.ForeignKey(CodechefContest, on_delete=models.CASCADE) - problem = models.ForeignKey(Problem, on_delete=models.CASCADE) + contest = models.ForeignKey(CodechefContest, blank = True,on_delete=models.CASCADE) + problem = models.ForeignKey(Problem, blank = True,on_delete=models.CASCADE) def __str__(self): return self.problem.prob_id diff --git a/codedigger/codechef/test_fixtures/model_utils_fixture.py b/codedigger/codechef/test_fixtures/model_utils_fixture.py new file mode 100644 index 0000000..8f0b540 --- /dev/null +++ b/codedigger/codechef/test_fixtures/model_utils_fixture.py @@ -0,0 +1,17 @@ +codechef_contest = { + "Name": "July Cook-Off 2021", + "ContestCode": "COOK131B", + "Duration": 165, + "StartTime": "28 July 2021 20:00:00", + "ContestURL": "https://www.codechef.com/COOK131B" +} + +codechef_problem = [ + {'Name': 'Lift Requests', 'ProblemCode': 'LIFTME', 'ProblemURL': 'https://www.codechef.com/COOK117B/problems/LIFTME', 'ContestId': 'COOK117B', 'Platform': 'C'}, + {'Name': 'Inversions in Permutations', 'ProblemCode': 'KPERM', 'ProblemURL': 'https://www.codechef.com/COOK117B/problems/KPERM', 'ContestId': 'COOK117B', 'Platform': 'C'}, + {'Name': 'Matrix Decomposition', 'ProblemCode': 'MATBREAK', 'ProblemURL': 'https://www.codechef.com/COOK117B/problems/MATBREAK', 'ContestId': 'COOK117B', 'Platform': 'C'}, + {'Name': 'Simple Operations', 'ProblemCode': 'MINOPS', 'ProblemURL': 'https://www.codechef.com/COOK117B/problems/MINOPS', 'ContestId': 'COOK117B', 'Platform': 'C'}, + {'Name': 'The Gifting Problem', 'ProblemCode': 'KARRAY', 'ProblemURL': 'https://www.codechef.com/COOK117B/problems/KARRAY', 'ContestId': 'COOK117B', 'Platform': 'C'}, + {'Name': 'Tower Counting', 'ProblemCode': 'TOWCNT', 'ProblemURL': 'https://www.codechef.com/COOK117B/problems/TOWCNT', 'ContestId': 'COOK117B', 'Platform': 'C'}, + {'Name': 'Maximum GCD Subset', 'ProblemCode': 'TREESUB', 'ProblemURL': 'https://www.codechef.com/COOK117B/problems/TREESUB', 'ContestId': 'COOK117B', 'Platform': 'C'} +] diff --git a/codedigger/codechef/tests/test_model_utils.py b/codedigger/codechef/tests/test_model_utils.py new file mode 100644 index 0000000..0bb4537 --- /dev/null +++ b/codedigger/codechef/tests/test_model_utils.py @@ -0,0 +1,23 @@ +from .test_setup import TestSetUp +from codechef.models import CodechefContest, CodechefContestProblems +from problem.models import Problem +from codechef.model_utils import create_or_update_codechefContest,create_or_update_codechefProblem +from codechef.test_fixtures.model_utils_fixture import (codechef_contest,codechef_problem) +from datetime import datetime + +class TestModelUtils(TestSetUp): + def test_CreateContest(self): + newContest = create_or_update_codechefContest(codechef_contest) + contestDate = datetime.strptime(codechef_contest["StartTime"],"%d %B %Y %H:%M:%S") + contest = CodechefContest.objects.get(contestId = codechef_contest["ContestCode"]) + self.assertEqual(contest.url, codechef_contest["ContestURL"]) + self.assertEqual(contest.contestId, 'COOK131B') + + + def test_CreateProblem(self): + create_or_update_codechefContest(codechef_contest) + create_or_update_codechefProblem('COOK131B') + problemModel = Problem.objects.get(prob_id = codechef_problem[0]['ProblemCode']) + firstProbCode = codechef_problem[0]['ProblemCode'] + codechefProblem = CodechefContestProblems.objects.get(problem = problemModel) + self.assertEqual(codechefProblem.problem.prob_id, 'LIFTME') \ No newline at end of file