From 822aa50f70e08207f1db039d28aa4f58596a0774 Mon Sep 17 00:00:00 2001 From: Manny Date: Sun, 9 Jun 2024 03:06:10 -0400 Subject: [PATCH 01/33] Added a couple Hillman library features Tells the user how many reservations are in the Hillman library, and also tells the user what rooms and times are reserved in the Hillman library. --- pittapi/lab.py | 45 ++++++++++++++++++++++++++++++++++++++++----- pittapi/shuttle.py | 1 + 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/pittapi/lab.py b/pittapi/lab.py index b95fe93..46f03a2 100644 --- a/pittapi/lab.py +++ b/pittapi/lab.py @@ -24,11 +24,15 @@ import requests import urllib3 -URL = "https://pitt-keyserve-prod.univ.pitt.edu/maps/std/avail.json" +LABS_URL = "https://pitt-keyserve-prod.univ.pitt.edu/maps/std/avail.json" +HILLMAN_URL = "https://pitt.libcal.com/spaces/bookings/search?lid=917&gid=1558&eid=0&seat=0&d=1&customDate=&q=&daily=0&draw=1&order%5B0%5D%5Bcolumn%5D=1&order%5B0%5D%5Bdir%5D=asc&start=0&length=25&search%5Bvalue%5D=&_=1717907260661" """ -Lab API is insecure for some reason (it's offical Pitt one +Lab API is insecure for some reason (it's official Pitt one so no concern), just doing this to supress warnings + +Lab API now supports some additional features, supporting some aspects of fetching Hillman data, such as reserved times +and total amount of reservations """ urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) @@ -53,7 +57,7 @@ def _fetch_labs(): labs = {} # get the full lab data from API - resp = requests.get(URL, verify=False) + resp = requests.get(LABS_URL, verify=False) resp = resp.json() data = resp["results"]["states"] @@ -64,14 +68,14 @@ def _fetch_labs(): return labs -def get_status(): +def get_lab_status(): """Returns a list with status and amount of open machines.""" # get the list of all the labs (plus open status) at other statuses = [] labs = _fetch_labs() # get all the different labs + printers at all Pitt campuses - resp = requests.get(URL, verify=False) + resp = requests.get(LABS_URL, verify=False) resp = resp.json() data = resp["results"]["divs"] @@ -89,3 +93,34 @@ def get_status(): } ) return statuses + + +def hillman_total_reserved(): + """Returns a simple count dictionary of the total amount of reserved rooms appointments""" + count = {} + resp = requests.get(HILLMAN_URL) + resp = resp.json() + total_records = resp["recordsTotal"] + + count["Total Hillman Reservations"] = total_records + return count + + +def reserved_hillman_times(): + """Returns a dictionary with of reserved rooms of the Hillman with their respective times""" + bookings = {} + + resp = requests.get(HILLMAN_URL) + resp = resp.json() + data = resp["data"] + + if data is None: + return bookings + + for reservation in data: + from_time = reservation["from"] + to_time = reservation["to"] + roomName = reservation["itemName"] + bookings[roomName] = [from_time, to_time] + + return bookings \ No newline at end of file diff --git a/pittapi/shuttle.py b/pittapi/shuttle.py index 8fcf8c7..552acae 100644 --- a/pittapi/shuttle.py +++ b/pittapi/shuttle.py @@ -23,6 +23,7 @@ sess = requests.session() +def get_map_vehicle_points(api_key: str = "8882812681") -> Dict[str, Any]: def get_map_vehicle_points(api_key: str = "8882812681") -> Dict[str, Any]: """Return the map location for all active vehicles.""" payload = {"ApiKey": api_key} From b935689b047051bea32d91050319e463e328cf36 Mon Sep 17 00:00:00 2001 From: Manny Date: Sun, 9 Jun 2024 14:18:05 -0400 Subject: [PATCH 02/33] fixed a bug with reservations pulling; moved reservations functions to library module --- pittapi/lab.py | 34 +--------------------------------- pittapi/library.py | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 33 deletions(-) diff --git a/pittapi/lab.py b/pittapi/lab.py index 46f03a2..851d059 100644 --- a/pittapi/lab.py +++ b/pittapi/lab.py @@ -25,7 +25,6 @@ import urllib3 LABS_URL = "https://pitt-keyserve-prod.univ.pitt.edu/maps/std/avail.json" -HILLMAN_URL = "https://pitt.libcal.com/spaces/bookings/search?lid=917&gid=1558&eid=0&seat=0&d=1&customDate=&q=&daily=0&draw=1&order%5B0%5D%5Bcolumn%5D=1&order%5B0%5D%5Bdir%5D=asc&start=0&length=25&search%5Bvalue%5D=&_=1717907260661" """ Lab API is insecure for some reason (it's official Pitt one @@ -92,35 +91,4 @@ def get_lab_status(): "in_use": in_use } ) - return statuses - - -def hillman_total_reserved(): - """Returns a simple count dictionary of the total amount of reserved rooms appointments""" - count = {} - resp = requests.get(HILLMAN_URL) - resp = resp.json() - total_records = resp["recordsTotal"] - - count["Total Hillman Reservations"] = total_records - return count - - -def reserved_hillman_times(): - """Returns a dictionary with of reserved rooms of the Hillman with their respective times""" - bookings = {} - - resp = requests.get(HILLMAN_URL) - resp = resp.json() - data = resp["data"] - - if data is None: - return bookings - - for reservation in data: - from_time = reservation["from"] - to_time = reservation["to"] - roomName = reservation["itemName"] - bookings[roomName] = [from_time, to_time] - - return bookings \ No newline at end of file + return statuses \ No newline at end of file diff --git a/pittapi/library.py b/pittapi/library.py index 2bd6a7d..7d9c535 100644 --- a/pittapi/library.py +++ b/pittapi/library.py @@ -32,6 +32,9 @@ "&sort=rank&tab=Everything&vid=01PITT_INST:01PITT_INST" ) +STUDY_ROOMS_URL = "https://pitt.libcal.com/spaces/bookings/search?lid=917&gid=1558&eid=0&seat=0&d=1&customDate=&q=&daily=0&draw=1&order%5B0%5D%5Bcolumn%5D=1&order%5B0%5D%5Bdir%5D=asc&start=0&length=25&search%5Bvalue%5D=&_=1717907260661" + + QUERY_START = "&q=any,contains," sess = requests.session() @@ -131,3 +134,37 @@ def _extract_facets( ) return facets + +def hillman_total_reserved(): + """Returns a simple count dictionary of the total amount of reserved rooms appointments""" + count = {} + resp = requests.get(STUDY_ROOMS_URL) + resp = resp.json() + # Total records is kept track of by default in the JSON + total_records = resp["recordsTotal"] + + # Note: this must align with the amount of entries in reserved times function; renamed for further clarification + count["Total Hillman Reservations"] = total_records + return count + + +def reserved_hillman_times(): + """Returns a list of dictionaries of reserved rooms of the Hillman with their respective times""" + bookings = [] + + resp = requests.get(STUDY_ROOMS_URL) + resp = resp.json() + data = resp["data"] + + if data is None: + return bookings + + # Note: there can be multiple reservations in the same room, hence why we must use a list of maps, and cannot just use a singular map + for reservation in data: + bookings.append( + { + "Room": reservation["itemName"], + "Reserved": [reservation["from"], reservation["to"]] + } + ) + return bookings \ No newline at end of file From ea0d2c5018ed03f6597696b2e876ce25d8db6a9b Mon Sep 17 00:00:00 2001 From: Manny Date: Sun, 9 Jun 2024 14:26:30 -0400 Subject: [PATCH 03/33] revert lab back --- pittapi/lab.py | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/pittapi/lab.py b/pittapi/lab.py index 851d059..5a5efa4 100644 --- a/pittapi/lab.py +++ b/pittapi/lab.py @@ -24,14 +24,11 @@ import requests import urllib3 -LABS_URL = "https://pitt-keyserve-prod.univ.pitt.edu/maps/std/avail.json" +URL = "https://pitt-keyserve-prod.univ.pitt.edu/maps/std/avail.json" """ -Lab API is insecure for some reason (it's official Pitt one +Lab API is insecure for some reason (it's offical Pitt one so no concern), just doing this to supress warnings - -Lab API now supports some additional features, supporting some aspects of fetching Hillman data, such as reserved times -and total amount of reservations """ urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) @@ -51,12 +48,13 @@ class Lab(NamedTuple): linux: int """ + def _fetch_labs(): """Fetches dictionary of status of all labs.""" labs = {} # get the full lab data from API - resp = requests.get(LABS_URL, verify=False) + resp = requests.get(URL, verify=False) resp = resp.json() data = resp["results"]["states"] @@ -67,14 +65,14 @@ def _fetch_labs(): return labs -def get_lab_status(): +def get_status(): """Returns a list with status and amount of open machines.""" # get the list of all the labs (plus open status) at other statuses = [] labs = _fetch_labs() # get all the different labs + printers at all Pitt campuses - resp = requests.get(LABS_URL, verify=False) + resp = requests.get(URL, verify=False) resp = resp.json() data = resp["results"]["divs"] @@ -83,12 +81,5 @@ def get_lab_status(): if key["name"] in labs: total = key["total"] in_use = key["active"] - statuses.append( - { - "location": key["name"], - "isOpen": labs[key["name"]], - "total": total, - "in_use": in_use - } - ) + statuses.append({"location": key["name"], "isOpen": labs[key["name"]], "total": total, "in_use": in_use}) return statuses \ No newline at end of file From 0455c9d8c2a27760d7d489249748d269d928e3d6 Mon Sep 17 00:00:00 2001 From: Manny Date: Sun, 9 Jun 2024 14:34:40 -0400 Subject: [PATCH 04/33] revert lab --- pittapi/lab.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/pittapi/lab.py b/pittapi/lab.py index 5a5efa4..d4b8e7d 100644 --- a/pittapi/lab.py +++ b/pittapi/lab.py @@ -81,5 +81,12 @@ def get_status(): if key["name"] in labs: total = key["total"] in_use = key["active"] - statuses.append({"location": key["name"], "isOpen": labs[key["name"]], "total": total, "in_use": in_use}) + statuses.append( + { + "location": key["name"], + "isOpen": labs[key["name"]], + "total": total, + "in_use": in_use} + ) + return statuses \ No newline at end of file From 12e9c85bde9ba23d9a9cd8957c2d1e7b3981d6fb Mon Sep 17 00:00:00 2001 From: Manny Date: Sun, 9 Jun 2024 14:37:50 -0400 Subject: [PATCH 05/33] Update lab.py --- pittapi/lab.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pittapi/lab.py b/pittapi/lab.py index d4b8e7d..eb8015d 100644 --- a/pittapi/lab.py +++ b/pittapi/lab.py @@ -86,7 +86,8 @@ def get_status(): "location": key["name"], "isOpen": labs[key["name"]], "total": total, - "in_use": in_use} + "in_use": in_use + } ) return statuses \ No newline at end of file From 8d830adeb602b8c9950672dcfa4314bada05e9ae Mon Sep 17 00:00:00 2001 From: Manny Date: Sun, 9 Jun 2024 14:53:56 -0400 Subject: [PATCH 06/33] revert lab again --- pittapi/shuttle.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pittapi/shuttle.py b/pittapi/shuttle.py index 552acae..8fcf8c7 100644 --- a/pittapi/shuttle.py +++ b/pittapi/shuttle.py @@ -23,7 +23,6 @@ sess = requests.session() -def get_map_vehicle_points(api_key: str = "8882812681") -> Dict[str, Any]: def get_map_vehicle_points(api_key: str = "8882812681") -> Dict[str, Any]: """Return the map location for all active vehicles.""" payload = {"ApiKey": api_key} From a16f11896bb45860ccccef2922faca9b41ec271f Mon Sep 17 00:00:00 2001 From: Manny Date: Sun, 9 Jun 2024 19:03:10 -0400 Subject: [PATCH 07/33] Ran black to format correctly --- black | 0 pittapi/__init__.py | 1 + pittapi/cal.py | 20 +++- pittapi/course.py | 5 +- pittapi/lab.py | 4 +- pittapi/laundry.py | 2 +- pittapi/library.py | 5 +- pittapi/people.py | 5 +- pittapi/sports.py | 68 +++++++------ pittapi/textbook.py | 10 +- setup.py | 72 +++++-------- tests/__init__.py | 2 +- tests/course_test.py | 156 ++++++++++++++++------------ tests/dining_test.py | 65 +++++++----- tests/laundry_test.py | 24 +++-- tests/library_test.py | 6 +- tests/mocks/course_mocks.py | 101 ++++++------------ tests/news_test.py | 1 + tests/people_test.py | 48 +++++---- tests/shuttle_test.py | 18 ++-- tests/sports_test.py | 109 ++++++++------------ tests/status_test.py | 13 ++- tests/textbook_test.py | 197 +++++++++++++++++++++--------------- 23 files changed, 485 insertions(+), 447 deletions(-) create mode 100644 black diff --git a/black b/black new file mode 100644 index 0000000..e69de29 diff --git a/pittapi/__init__.py b/pittapi/__init__.py index da4a95d..9b83b5f 100644 --- a/pittapi/__init__.py +++ b/pittapi/__init__.py @@ -16,6 +16,7 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. """ + import requests from requests.packages.urllib3.exceptions import InsecureRequestWarning diff --git a/pittapi/cal.py b/pittapi/cal.py index 1efac20..38144d5 100644 --- a/pittapi/cal.py +++ b/pittapi/cal.py @@ -29,11 +29,21 @@ class Event(NamedTuple): meta: str -ACADEMIC_CALENDAR_URL: str = "https://25livepub.collegenet.com/calendars/pitt-academic-calendar.json" -GRADES_CALENDAR_URL: str = "https://25livepub.collegenet.com/calendars/pitt-grades-calendar.json" -ENROLLMENT_CALENDAR_URL: str = "https://25livepub.collegenet.com/calendars/pitt-enrollment-calendar.json" -COURSE_CALENDAR_URL: str = "https://25livepub.collegenet.com/calendars/pitt-courseclass-calendar.json" -GRADUATION_CALENDAR_URL: str = "https://25livepub.collegenet.com/calendars/pitt-graduation-calendar.json" +ACADEMIC_CALENDAR_URL: str = ( + "https://25livepub.collegenet.com/calendars/pitt-academic-calendar.json" +) +GRADES_CALENDAR_URL: str = ( + "https://25livepub.collegenet.com/calendars/pitt-grades-calendar.json" +) +ENROLLMENT_CALENDAR_URL: str = ( + "https://25livepub.collegenet.com/calendars/pitt-enrollment-calendar.json" +) +COURSE_CALENDAR_URL: str = ( + "https://25livepub.collegenet.com/calendars/pitt-courseclass-calendar.json" +) +GRADUATION_CALENDAR_URL: str = ( + "https://25livepub.collegenet.com/calendars/pitt-graduation-calendar.json" +) def _fetch_calendar_events(url: str) -> List[Event]: diff --git a/pittapi/course.py b/pittapi/course.py index 0aa74d5..50e6fc5 100644 --- a/pittapi/course.py +++ b/pittapi/course.py @@ -34,6 +34,7 @@ TERM_REGEX = "2\d\d[147]" VALID_TERMS = re.compile(TERM_REGEX) + class Instructor(NamedTuple): name: str email: Optional[str] = None @@ -91,6 +92,7 @@ class Course(NamedTuple): course_id: str course_title: str + class CourseDetails(NamedTuple): course: Course course_description: Optional[str] = None @@ -100,6 +102,7 @@ class CourseDetails(NamedTuple): attributes: List[Attribute] = None sections: Optional[List[Section]] = None + class Subject(NamedTuple): subject_code: str courses: Dict[str, Course] @@ -227,7 +230,7 @@ def get_course_details( subject_code=subject, course_number=course, course_id=internal_course_id, - course_title=course_title + course_title=course_title, ), course_description=course_description, credit_range=credit_range, diff --git a/pittapi/lab.py b/pittapi/lab.py index eb8015d..355b745 100644 --- a/pittapi/lab.py +++ b/pittapi/lab.py @@ -86,8 +86,8 @@ def get_status(): "location": key["name"], "isOpen": labs[key["name"]], "total": total, - "in_use": in_use + "in_use": in_use, } ) - return statuses \ No newline at end of file + return statuses diff --git a/pittapi/laundry.py b/pittapi/laundry.py index bea5207..50a8367 100644 --- a/pittapi/laundry.py +++ b/pittapi/laundry.py @@ -63,7 +63,7 @@ def get_status_simple(building_name: str) -> Dict[str, str]: -> SUTH_WEST """ laundry_info = _get_laundry_info(building_name) - freeWashers, freeDryers, totalWashers, totalDryers = 0,0,0,0 + freeWashers, freeDryers, totalWashers, totalDryers = 0, 0, 0, 0 for obj in laundry_info["objects"]: if obj["type"] == "washFL": diff --git a/pittapi/library.py b/pittapi/library.py index 7d9c535..aa01cff 100644 --- a/pittapi/library.py +++ b/pittapi/library.py @@ -135,6 +135,7 @@ def _extract_facets( return facets + def hillman_total_reserved(): """Returns a simple count dictionary of the total amount of reserved rooms appointments""" count = {} @@ -164,7 +165,7 @@ def reserved_hillman_times(): bookings.append( { "Room": reservation["itemName"], - "Reserved": [reservation["from"], reservation["to"]] + "Reserved": [reservation["from"], reservation["to"]], } ) - return bookings \ No newline at end of file + return bookings diff --git a/pittapi/people.py b/pittapi/people.py index 6009dd9..b009beb 100644 --- a/pittapi/people.py +++ b/pittapi/people.py @@ -16,6 +16,7 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. """ + from requests_html import HTMLSession from typing import List, Dict from parse import compile @@ -66,7 +67,7 @@ def get_person(query: str) -> List[Dict[str, str]]: session = HTMLSession() resp = session.post(PEOPLE_SEARCH_URL, data=payload) if resp.text.__contains__("Too many people matched your criteria."): - return [{"ERROR":"Too many people matched your criteria."}] # Return an error + return [{"ERROR": "Too many people matched your criteria."}] # Return an error elements = resp.html.xpath("/html/div/section") result = [] for entry in elements: @@ -75,5 +76,5 @@ def get_person(query: str) -> List[Dict[str, str]]: _parse_segments(person, segments) result.append(person) if result == []: - return [{"ERROR":"No one found."}] # Return an error + return [{"ERROR": "No one found."}] # Return an error return result diff --git a/pittapi/sports.py b/pittapi/sports.py index 5b561af..01c0a16 100644 --- a/pittapi/sports.py +++ b/pittapi/sports.py @@ -19,7 +19,9 @@ import requests -FOOTBALL_URL = "http://site.api.espn.com/apis/site/v2/sports/football/college-football/teams/pitt" +FOOTBALL_URL = ( + "http://site.api.espn.com/apis/site/v2/sports/football/college-football/teams/pitt" +) MENS_BASKETBALL_URL = "http://site.api.espn.com/apis/site/v2/sports/basketball/mens-college-basketball/teams/pittsburgh" @@ -47,7 +49,10 @@ def get_next_mens_basketball_game() -> dict: status = None if next_game["competitions"][0]["status"]["type"]["name"] == "STATUS_FINAL": status = "GAME_COMPLETE" - elif next_game["competitions"][0]["status"]["type"]["name"] == "STATUS_IN_PROGRESS": + elif ( + next_game["competitions"][0]["status"]["type"]["name"] + == "STATUS_IN_PROGRESS" + ): status = "IN_PROGRESS" if next_game["competitions"][0]["competitors"][0]["id"] == 221: opponent = next_game["competitions"][0]["competitors"][0] @@ -56,28 +61,26 @@ def get_next_mens_basketball_game() -> dict: opponent = next_game["competitions"][0]["competitors"][1] homeaway = next_game["competitions"][0]["competitors"][1]["homeAway"] return { - "timestamp" : next_game["date"], - "opponent" : { - "id" : opponent["team"]["id"], - "school" : opponent["team"]["nickname"], - "name" : opponent["team"]["displayName"] + "timestamp": next_game["date"], + "opponent": { + "id": opponent["team"]["id"], + "school": opponent["team"]["nickname"], + "name": opponent["team"]["displayName"], }, - "home_away" : homeaway, - "location" : { - "full_name" : next_game["competitions"][0]["venue"]["fullName"], - "address" : next_game["competitions"][0]["venue"]["address"] + "home_away": homeaway, + "location": { + "full_name": next_game["competitions"][0]["venue"]["fullName"], + "address": next_game["competitions"][0]["venue"]["address"], }, - "status" : status + "status": status, } except IndexError: # IndexError occurs when a next game on the schedule is not present - return { - "status" : "NO_GAME_SCHEDULED" - } + return {"status": "NO_GAME_SCHEDULED"} def get_mens_basketball_standings() -> str: - """returns a string describing the placement of the men's basketball team. eg: '14th in ACC' """ + """returns a string describing the placement of the men's basketball team. eg: '14th in ACC'""" basketball_data = _get_mens_basketball_data() return_value = basketball_data["team"]["standingSummary"] @@ -107,7 +110,10 @@ def get_next_football_game() -> dict: status = None if next_game["competitions"][0]["status"]["type"]["name"] == "STATUS_FINAL": status = "GAME_COMPLETE" - elif next_game["competitions"][0]["status"]["type"]["name"] == "STATUS_IN_PROGRESS": + elif ( + next_game["competitions"][0]["status"]["type"]["name"] + == "STATUS_IN_PROGRESS" + ): status = "IN_PROGRESS" if next_game["competitions"][0]["competitors"][0]["id"] == 221: opponent = next_game["competitions"][0]["competitors"][1] @@ -116,35 +122,35 @@ def get_next_football_game() -> dict: opponent = next_game["competitions"][0]["competitors"][0] homeaway = next_game["competitions"][0]["competitors"][1]["homeAway"] return { - "timestamp" : next_game["date"], - "opponent" : { - "id" : opponent["team"]["id"], - "school" : opponent["team"]["nickname"], - "name" : opponent["team"]["displayName"] + "timestamp": next_game["date"], + "opponent": { + "id": opponent["team"]["id"], + "school": opponent["team"]["nickname"], + "name": opponent["team"]["displayName"], }, - "home_away" : homeaway, - "location" : { - "full_name" : next_game["competitions"][0]["venue"]["fullName"], - "address" : next_game["competitions"][0]["venue"]["address"] + "home_away": homeaway, + "location": { + "full_name": next_game["competitions"][0]["venue"]["fullName"], + "address": next_game["competitions"][0]["venue"]["address"], }, - "status" : status + "status": status, } except IndexError: # IndexError occurs when a next game on the schedule is not present - return { - "status" : "NO_GAME_SCHEDULED" - } + return {"status": "NO_GAME_SCHEDULED"} def get_football_standings() -> str: - """returns a string describing the placement of the football team. eg: '14th in ACC' """ + """returns a string describing the placement of the football team. eg: '14th in ACC'""" football_data = _get_football_data() return_value = football_data["team"]["standingSummary"] return return_value + def _get_mens_basketball_data() -> dict: return requests.get(MENS_BASKETBALL_URL).json() + def _get_football_data() -> dict: return requests.get(FOOTBALL_URL).json() diff --git a/pittapi/textbook.py b/pittapi/textbook.py index 80cbb3e..5698f2f 100644 --- a/pittapi/textbook.py +++ b/pittapi/textbook.py @@ -242,9 +242,9 @@ def _validate_term(term: str) -> str: def _validate_course(course: str) -> str: """Validates course is a four digit number, - otherwise adds zero(s) to create four digit number or, - raises an exception. - """ + otherwise adds zero(s) to create four digit number or, + raises an exception. + """ if len(course) > 4 or not course.isdigit(): raise ValueError("Invalid course number") elif len(course) == 4: @@ -280,8 +280,8 @@ def find(data, value): def _extract_id(response, course: str, instructor: str, section: str) -> str: """Gathers sections from departments and finds course id by - instructor name or section number. - """ + instructor name or section number. + """ sections = _find_sections(response.json(), course) error = 0 try: diff --git a/setup.py b/setup.py index 8d83009..6ee30e2 100644 --- a/setup.py +++ b/setup.py @@ -6,6 +6,7 @@ # Always prefer setuptools over distutils from setuptools import setup, find_packages + # To use a consistent encoding from codecs import open from os import path @@ -13,97 +14,76 @@ here = path.abspath(path.dirname(__file__)) # Get the long description from the README file -with open(path.join(here, 'README.rst'), encoding='utf-8') as f: +with open(path.join(here, "README.rst"), encoding="utf-8") as f: long_description = f.read() setup( - name='pittapi', - + name="pittapi", # Versions should comply with PEP440. For a discussion on single-sourcing # the version across setup.py and the project code, see # https://packaging.python.org/en/latest/single_source_version.html - version='1.0.0', - - description='An API to get data from Pitt and Pitt-related applications.', + version="1.0.0", + description="An API to get data from Pitt and Pitt-related applications.", long_description=long_description, - # The project's main homepage. - url='https://github.com/Pitt-CSC/PittAPI', - + url="https://github.com/Pitt-CSC/PittAPI", # Author details - author='University of Pittsburgh Computer Science Club', - author_email='pittcsc@gmail.com', - + author="University of Pittsburgh Computer Science Club", + author_email="pittcsc@gmail.com", # Choose your license - license='GPLv2', - + license="GPLv2", # See https://pypi.python.org/pypi?%3Aaction=list_classifiers classifiers=[ # How mature is this project? Common values are # 3 - Alpha # 4 - Beta # 5 - Production/Stable - 'Development Status :: 4 - Beta', - + "Development Status :: 4 - Beta", # Indicate who your project is intended for - 'Intended Audience :: Developers', - 'Topic :: Software Development :: Build Tools', - + "Intended Audience :: Developers", + "Topic :: Software Development :: Build Tools", # Pick your license as you wish (should match "license" above) - 'License :: OSI Approved :: GNU General Public License v2 (GPLv2)', - + "License :: OSI Approved :: GNU General Public License v2 (GPLv2)", # Specify the Python versions you support here. In particular, ensure # that you indicate whether you support Python 2, Python 3 or both. - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", ], - # What does your project relate to? - keywords='api open-data university-of-pittsburgh pittsburgh pitt', - + keywords="api open-data university-of-pittsburgh pittsburgh pitt", # You can just specify the packages manually here if your project is # simple. Or you can use find_packages(). - packages=find_packages(exclude=['docs', 'tests']), - + packages=find_packages(exclude=["docs", "tests"]), # Alternatively, if you want to distribute just a my_module.py, uncomment # this: # py_modules=["my_module"], - # List run-time dependencies here. These will be installed by pip when # your project is installed. For an analysis of "install_requires" vs pip's # requirements files see: # https://packaging.python.org/en/latest/requirements.html install_requires=[ - 'BeautifulSoup4', - 'Requests', - 'requests_html', - 'grequests', - 'lxml', - 'parse', + "BeautifulSoup4", + "Requests", + "requests_html", + "grequests", + "lxml", + "parse", ], - # List additional groups of dependencies here (e.g. development # dependencies). You can install these using the following syntax, # for example: # $ pip install -e .[dev,test] extras_require={ - 'test': [ - 'timeout-decorator', - 'nose', - 'nose-cov', - 'nose-timer' - ], + "test": ["timeout-decorator", "nose", "nose-cov", "nose-timer"], }, - # If there are data files included in your packages that need to be # installed, specify them here. If using Python 2.6 or less, then these # have to be included in MANIFEST.in as well. # package_data={ # 'sample': ['package_data.dat'], # }, - # Although 'package_data' is the preferred approach, in some case you may # need to place data files outside of your packages. See: # http://docs.python.org/3.4/distutils/setupscript.html#installing-additional-files # noqa diff --git a/tests/__init__.py b/tests/__init__.py index 7bd539f..05531a0 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -19,4 +19,4 @@ import warnings -warnings.simplefilter('ignore') +warnings.simplefilter("ignore") diff --git a/tests/course_test.py b/tests/course_test.py index daa79d3..c4485b4 100644 --- a/tests/course_test.py +++ b/tests/course_test.py @@ -21,99 +21,125 @@ from unittest.mock import MagicMock from pittapi import course -from pittapi.course import Attribute, Component, Course, CourseDetails, Instructor, Meeting, Section, SectionDetails, Subject -from tests.mocks.course_mocks import mocked_subject_data, mocked_courses_data, mocked_courses_data_invalid, mocked_course_info_data, mocked_course_sections_data, mocked_section_details_data +from pittapi.course import ( + Attribute, + Component, + Course, + CourseDetails, + Instructor, + Meeting, + Section, + SectionDetails, + Subject, +) +from tests.mocks.course_mocks import ( + mocked_subject_data, + mocked_courses_data, + mocked_courses_data_invalid, + mocked_course_info_data, + mocked_course_sections_data, + mocked_section_details_data, +) + class CourseTest(unittest.TestCase): def setUp(self): course._get_subjects = MagicMock(return_value=mocked_subject_data) - course._get_section_details = MagicMock(return_value=mocked_section_details_data) + course._get_section_details = MagicMock( + return_value=mocked_section_details_data + ) def test_validate_term(self): # If convert to string self.assertTrue(isinstance(course._validate_term(2191), str)) - self.assertEqual(course._validate_term(2191), '2191') - self.assertEqual(course._validate_term('2191'), '2191') + self.assertEqual(course._validate_term(2191), "2191") + self.assertEqual(course._validate_term("2191"), "2191") - self.assertRaises(ValueError, course._validate_term, '214') - self.assertRaises(ValueError, course._validate_term, '1111') - self.assertRaises(ValueError, course._validate_term, '12345') + self.assertRaises(ValueError, course._validate_term, "214") + self.assertRaises(ValueError, course._validate_term, "1111") + self.assertRaises(ValueError, course._validate_term, "12345") def test_validate_subject(self): - self.assertEqual(course._validate_subject('CS'), 'CS') + self.assertEqual(course._validate_subject("CS"), "CS") - self.assertRaises(ValueError, course._validate_subject, 'foobar') + self.assertRaises(ValueError, course._validate_subject, "foobar") def test_validate_course(self): - self.assertEqual(course._validate_course(7), '0007') - self.assertEqual(course._validate_course(449), '0449') - self.assertEqual(course._validate_course(1501), '1501') + self.assertEqual(course._validate_course(7), "0007") + self.assertEqual(course._validate_course(449), "0449") + self.assertEqual(course._validate_course(1501), "1501") - self.assertEqual(course._validate_course('7'), '0007') - self.assertEqual(course._validate_course('0007'), '0007') - self.assertEqual(course._validate_course('449'), '0449') - self.assertEqual(course._validate_course('1501'), '1501') + self.assertEqual(course._validate_course("7"), "0007") + self.assertEqual(course._validate_course("0007"), "0007") + self.assertEqual(course._validate_course("449"), "0449") + self.assertEqual(course._validate_course("1501"), "1501") self.assertRaises(ValueError, course._validate_course, -1) self.assertRaises(ValueError, course._validate_course, 0) - self.assertRaises(ValueError, course._validate_course, '') - self.assertRaises(ValueError, course._validate_course, 'A00') - self.assertRaises(ValueError, course._validate_course, 'Hello') - self.assertRaises(ValueError, course._validate_course, '10000') + self.assertRaises(ValueError, course._validate_course, "") + self.assertRaises(ValueError, course._validate_course, "A00") + self.assertRaises(ValueError, course._validate_course, "Hello") + self.assertRaises(ValueError, course._validate_course, "10000") def test_get_subject_courses(self): course._get_subject_courses = MagicMock(return_value=mocked_courses_data) - subject_courses = course.get_subject_courses('CS') + subject_courses = course.get_subject_courses("CS") - course._get_subject_courses.assert_called_once_with('CS') + course._get_subject_courses.assert_called_once_with("CS") self.assertTrue(isinstance(subject_courses, Subject)) self.assertEqual(len(subject_courses.courses), 1) - self.assertTrue('0007' in subject_courses.courses) - test_course = subject_courses.courses['0007'] + self.assertTrue("0007" in subject_courses.courses) + test_course = subject_courses.courses["0007"] self.assertTrue(isinstance(test_course, Course)) def test_get_subject_courses_invalid(self): - course._get_subject_courses = MagicMock(return_value=mocked_courses_data_invalid) + course._get_subject_courses = MagicMock( + return_value=mocked_courses_data_invalid + ) self.assertRaises(ValueError, course.get_subject_courses, "nonsense") course._get_subject_courses.assert_not_called() def test_get_course_details(self): - course._get_course_id = MagicMock(return_value='105611') + course._get_course_id = MagicMock(return_value="105611") course._get_course_info = MagicMock(return_value=mocked_course_info_data) - course._get_course_sections = MagicMock(return_value=mocked_course_sections_data) + course._get_course_sections = MagicMock( + return_value=mocked_course_sections_data + ) - course_sections = course.get_course_details('2231', 'CS', '0007') + course_sections = course.get_course_details("2231", "CS", "0007") self.assertTrue(isinstance(course_sections, CourseDetails)) self.assertTrue(isinstance(course_sections.course, Course)) course_obj = course_sections.course - self.assertEqual(course_obj.subject_code, 'CS') - self.assertEqual(course_obj.course_number, '0007') - self.assertEqual(course_obj.course_id, '105611') - self.assertEqual(course_obj.course_title, 'INTRO TO COMPUTER PROGRAMMING') + self.assertEqual(course_obj.subject_code, "CS") + self.assertEqual(course_obj.course_number, "0007") + self.assertEqual(course_obj.course_id, "105611") + self.assertEqual(course_obj.course_title, "INTRO TO COMPUTER PROGRAMMING") self.assertEqual(len(course_sections.sections), 1) test_attribute = course_sections.attributes[0] self.assertTrue(isinstance(test_attribute, Attribute)) - self.assertEqual(test_attribute.attribute, 'DSGE') - self.assertEqual(test_attribute.attribute_description, '*DSAS General Ed. Requirements') - self.assertEqual(test_attribute.value, 'ALG') + self.assertEqual(test_attribute.attribute, "DSGE") + self.assertEqual( + test_attribute.attribute_description, "*DSAS General Ed. Requirements" + ) + self.assertEqual(test_attribute.value, "ALG") - self.assertEqual(test_attribute.value_description, 'Algebra') + self.assertEqual(test_attribute.value_description, "Algebra") test_section = course_sections.sections[0] self.assertTrue(isinstance(test_section, Section)) - self.assertEqual(test_section.term, '2231') - self.assertEqual(test_section.session, 'Academic Term') - self.assertEqual(test_section.section_number, '1000') - self.assertEqual(test_section.class_number, '27815') - self.assertEqual(test_section.section_type, 'REC') - self.assertEqual(test_section.status, 'Open') + self.assertEqual(test_section.term, "2231") + self.assertEqual(test_section.session, "Academic Term") + self.assertEqual(test_section.section_number, "1000") + self.assertEqual(test_section.class_number, "27815") + self.assertEqual(test_section.section_type, "REC") + self.assertEqual(test_section.status, "Open") self.assertEqual(len(test_section.instructors), 1) self.assertEqual(len(test_section.meetings), 1) @@ -134,38 +160,40 @@ def test_get_course_details(self): self.assertEqual(test_instructor.name, "Robert Fishel") def test_get_section_details(self): - course._get_section_details = MagicMock(return_value=mocked_section_details_data) + course._get_section_details = MagicMock( + return_value=mocked_section_details_data + ) - section_details = course.get_section_details('2231', '27815') + section_details = course.get_section_details("2231", "27815") self.assertTrue(isinstance(section_details, Section)) - self.assertEqual(section_details.term, '2231') - self.assertEqual(section_details.session, 'Academic Term') - self.assertEqual(section_details.class_number, '27815') - self.assertEqual(section_details.section_type, 'REC') - self.assertEqual(section_details.status, 'Open') + self.assertEqual(section_details.term, "2231") + self.assertEqual(section_details.session, "Academic Term") + self.assertEqual(section_details.class_number, "27815") + self.assertEqual(section_details.section_type, "REC") + self.assertEqual(section_details.status, "Open") self.assertIsNone(section_details.instructors) test_meeting = section_details.meetings[0] self.assertTrue(isinstance(test_meeting, Meeting)) - self.assertEqual(test_meeting.days, 'Fr') - self.assertEqual(test_meeting.start_time, '10:00AM') - self.assertEqual(test_meeting.end_time, '10:50AM') - self.assertEqual(test_meeting.start_date, '08/29/2022') - self.assertEqual(test_meeting.end_date, '12/09/2022') + self.assertEqual(test_meeting.days, "Fr") + self.assertEqual(test_meeting.start_time, "10:00AM") + self.assertEqual(test_meeting.end_time, "10:50AM") + self.assertEqual(test_meeting.start_date, "08/29/2022") + self.assertEqual(test_meeting.end_date, "12/09/2022") test_instructor = test_meeting.instructors[0] self.assertTrue(isinstance(test_instructor, Instructor)) - self.assertEqual(test_instructor.name, 'Robert Fishel') - self.assertEqual(test_instructor.email, 'rmf105@pitt.edu') + self.assertEqual(test_instructor.name, "Robert Fishel") + self.assertEqual(test_instructor.email, "rmf105@pitt.edu") test_details = section_details.details self.assertTrue(isinstance(test_details, SectionDetails)) - self.assertEqual(test_details.units, '0 units') - self.assertEqual(test_details.class_capacity, '28') - self.assertEqual(test_details.enrollment_total, '24') - self.assertEqual(test_details.enrollment_available, '4') - self.assertEqual(test_details.wait_list_capacity, '50') - self.assertEqual(test_details.wait_list_total, '7') - self.assertEqual(test_details.valid_to_enroll, 'T') + self.assertEqual(test_details.units, "0 units") + self.assertEqual(test_details.class_capacity, "28") + self.assertEqual(test_details.enrollment_total, "24") + self.assertEqual(test_details.enrollment_available, "4") + self.assertEqual(test_details.wait_list_capacity, "50") + self.assertEqual(test_details.wait_list_total, "7") + self.assertEqual(test_details.valid_to_enroll, "T") self.assertIsNone(test_details.combined_section_numbers) diff --git a/tests/dining_test.py b/tests/dining_test.py index 49d1b14..c12f3a8 100644 --- a/tests/dining_test.py +++ b/tests/dining_test.py @@ -26,47 +26,66 @@ from pittapi import dining -SAMPLE_PATH = Path() / 'tests' / 'samples' +SAMPLE_PATH = Path() / "tests" / "samples" class DiningTest(unittest.TestCase): def __init__(self, *args, **kwargs): unittest.TestCase.__init__(self, *args, **kwargs) - with (SAMPLE_PATH / 'dining_schedule.json').open() as f: + with (SAMPLE_PATH / "dining_schedule.json").open() as f: self.dining_schedule_data = json.load(f) - with (SAMPLE_PATH / 'dining_locations.json').open() as f: + with (SAMPLE_PATH / "dining_locations.json").open() as f: self.dining_locations_data = json.load(f) - with (SAMPLE_PATH / 'dining_menu.json').open() as f: + with (SAMPLE_PATH / "dining_menu.json").open() as f: self.dining_menu_data = json.load(f) - @responses.activate def test_get_locations(self): - responses.add(responses.GET, - "https://api.dineoncampus.com/v1/locations/status?site_id=5e6fcc641ca48e0cacd93b04&platform=", - json=self.dining_locations_data, status=200) + responses.add( + responses.GET, + "https://api.dineoncampus.com/v1/locations/status?site_id=5e6fcc641ca48e0cacd93b04&platform=", + json=self.dining_locations_data, + status=200, + ) self.assertIsInstance(dining.get_locations(), dict) @responses.activate def test_get_location_hours(self): - responses.add(responses.GET, - "https://api.dineoncampus.com/v1/locations/weekly_schedule?site_id=5e6fcc641ca48e0cacd93b04&date=%222024-04-12%22", - json=self.dining_schedule_data, status=200) - - self.assertIsInstance(dining.get_location_hours("The Eatery", datetime.datetime(2024, 4, 12)), dict) + responses.add( + responses.GET, + "https://api.dineoncampus.com/v1/locations/weekly_schedule?site_id=5e6fcc641ca48e0cacd93b04&date=%222024-04-12%22", + json=self.dining_schedule_data, + status=200, + ) + + self.assertIsInstance( + dining.get_location_hours("The Eatery", datetime.datetime(2024, 4, 12)), + dict, + ) @responses.activate def test_get_location_menu(self): - responses.add(responses.GET, - "https://api.dineoncampus.com/v1/locations/status?site_id=5e6fcc641ca48e0cacd93b04&platform=", - json=self.dining_locations_data, status=200) - responses.add(responses.GET, - "https://api.dineoncampus.com/v1/location/610b1f78e82971147c9f8ba5/periods?platform=0&date=24-04-12", - json=self.dining_menu_data, status=200) - responses.add(responses.GET, - "https://api.dineoncampus.com/v1/location/610b1f78e82971147c9f8ba5/periods/659daa4d351d53068df67835?platform=0&date=24-04-12", - json=self.dining_menu_data, status=200) - locations = dining.get_location_menu("The Eatery", datetime.datetime(2024, 4, 12), "Breakfast") + responses.add( + responses.GET, + "https://api.dineoncampus.com/v1/locations/status?site_id=5e6fcc641ca48e0cacd93b04&platform=", + json=self.dining_locations_data, + status=200, + ) + responses.add( + responses.GET, + "https://api.dineoncampus.com/v1/location/610b1f78e82971147c9f8ba5/periods?platform=0&date=24-04-12", + json=self.dining_menu_data, + status=200, + ) + responses.add( + responses.GET, + "https://api.dineoncampus.com/v1/location/610b1f78e82971147c9f8ba5/periods/659daa4d351d53068df67835?platform=0&date=24-04-12", + json=self.dining_menu_data, + status=200, + ) + locations = dining.get_location_menu( + "The Eatery", datetime.datetime(2024, 4, 12), "Breakfast" + ) self.assertIsInstance(locations, dict) diff --git a/tests/laundry_test.py b/tests/laundry_test.py index 15025d3..28fe61d 100644 --- a/tests/laundry_test.py +++ b/tests/laundry_test.py @@ -25,39 +25,41 @@ from pittapi import laundry -SAMPLE_PATH = Path() / 'tests' / 'samples' +SAMPLE_PATH = Path() / "tests" / "samples" TEST_BUILDING = "SUTH_EAST" class LaundryTest(unittest.TestCase): def __init__(self, *args, **kwargs): unittest.TestCase.__init__(self, *args, **kwargs) - with open(SAMPLE_PATH / 'laundry_mock_response.json', 'r') as file: + with open(SAMPLE_PATH / "laundry_mock_response.json", "r") as file: self.mock_data = json.load(file) @responses.activate def test_get_status_simple(self): responses.add( responses.GET, - 'https://www.laundryview.com/api/currentRoomData?school_desc_key=197&location=' + laundry.LOCATION_LOOKUP[TEST_BUILDING], + "https://www.laundryview.com/api/currentRoomData?school_desc_key=197&location=" + + laundry.LOCATION_LOOKUP[TEST_BUILDING], json=self.mock_data, - status=200 + status=200, ) status = laundry.get_status_simple(TEST_BUILDING) self.assertIsInstance(status, dict) - self.assertEqual(status['building'], TEST_BUILDING) - self.assertEqual(status['free_washers'], 7) - self.assertEqual(status['free_dryers'], 2) - self.assertEqual(status['total_washers'], 10) - self.assertEqual(status['total_dryers'], 10) + self.assertEqual(status["building"], TEST_BUILDING) + self.assertEqual(status["free_washers"], 7) + self.assertEqual(status["free_dryers"], 2) + self.assertEqual(status["total_washers"], 10) + self.assertEqual(status["total_dryers"], 10) @responses.activate def test_get_status_detailed(self): responses.add( responses.GET, - 'https://www.laundryview.com/api/currentRoomData?school_desc_key=197&location=' + laundry.LOCATION_LOOKUP[TEST_BUILDING], + "https://www.laundryview.com/api/currentRoomData?school_desc_key=197&location=" + + laundry.LOCATION_LOOKUP[TEST_BUILDING], json=self.mock_data, - status=200 + status=200, ) status = laundry.get_status_detailed(TEST_BUILDING) self.assertIsInstance(status, list) diff --git a/tests/library_test.py b/tests/library_test.py index bde179c..9e5d0f5 100644 --- a/tests/library_test.py +++ b/tests/library_test.py @@ -25,13 +25,13 @@ from pittapi import library -SAMPLE_PATH = Path() / 'tests' / 'samples' +SAMPLE_PATH = Path() / "tests" / "samples" class LibraryTest(unittest.TestCase): def __init__(self, *args, **kwargs): unittest.TestCase.__init__(self, *args, **kwargs) - with (SAMPLE_PATH / 'library_mock_response_water.json').open() as f: + with (SAMPLE_PATH / "library_mock_response_water.json").open() as f: self.library_query = json.load(f) @responses.activate @@ -40,7 +40,7 @@ def test_get_documents(self): responses.GET, library.LIBRARY_URL + library.QUERY_START + "water", json=self.library_query, - status=200 + status=200, ) query_result = library.get_documents("water") self.assertIsInstance(query_result, dict) diff --git a/tests/mocks/course_mocks.py b/tests/mocks/course_mocks.py index aafc59a..04a2317 100644 --- a/tests/mocks/course_mocks.py +++ b/tests/mocks/course_mocks.py @@ -1,18 +1,11 @@ -mocked_subject_data = { - "subjects" : [ - { - "subject" : "CS", - "descr" : "Computer Science" - } - ] -} +mocked_subject_data = {"subjects": [{"subject": "CS", "descr": "Computer Science"}]} mocked_courses_data = { - "courses" : [ + "courses": [ { "catalog_nbr": "0007", "descr": "INTRODUCTION TO COMPUTER PROGRAMMING", - "crse_id": "105611" + "crse_id": "105611", } ] } @@ -31,28 +24,22 @@ "rqmnt_designtn": "", "effdt": "2018-06-30", "components": [ - { - "descr": "Lecture", - "optional": "N" - }, - { - "descr": "Recitation", - "optional": "N" - } + {"descr": "Lecture", "optional": "N"}, + {"descr": "Recitation", "optional": "N"}, ], "attributes": [ { "crse_attribute": "DSGE", "crse_attribute_descr": "*DSAS General Ed. Requirements", "crse_attribute_value": "ALG", - "crse_attribute_value_descr": "Algebra" + "crse_attribute_value_descr": "Algebra", }, { "crse_attribute": "DSGE", "crse_attribute_descr": "*DSAS General Ed. Requirements", "crse_attribute_value": "QFR", - "crse_attribute_value_descr": "Quant.-Formal Reasoning" - } + "crse_attribute_value_descr": "Quant.-Formal Reasoning", + }, ], "offerings": [ { @@ -70,32 +57,26 @@ { "strm": "2224", "descr": "Spring Term 2021-2022", - "default_term": False + "default_term": False, }, { "strm": "2227", "descr": "Summer Term 2021-2022", - "default_term": False + "default_term": False, }, { "strm": "2231", "descr": "Fall Term 2022-2023", - "default_term": True - } + "default_term": True, + }, ], "enrollable_terms": [ - { - "strm": "2224" - }, - { - "strm": "2227" - }, - { - "strm": "2231" - } - ] + {"strm": "2224"}, + {"strm": "2227"}, + {"strm": "2231"}, + ], } - ] + ], } } @@ -131,12 +112,7 @@ "end_dt": "12/09/2022", "units": "0", "topic": "", - "instructors": [ - { - "name": "Robert Fishel", - "email": "rmf105@pitt.edu" - } - ], + "instructors": [{"name": "Robert Fishel", "email": "rmf105@pitt.edu"}], "section_type": "REC", "meetings": [ { @@ -145,12 +121,12 @@ "end_time": "10.50.00.000000-05:00", "start_dt": "08/29/2022", "end_dt": "12/09/2022", - "instructor": "Robert Fishel" + "instructor": "Robert Fishel", } ], - "reserve_caps": [] + "reserve_caps": [], } - ] + ], } mocked_section_details_data = { @@ -181,7 +157,7 @@ "campus_code": "PIT", "location": "Pittsburgh Campus", "topic": "", - "class_components": "
Lecture Required, Recitation Required
" + "class_components": '
Lecture Required, Recitation Required
', }, "meetings": [ { @@ -191,17 +167,12 @@ "meeting_time_end": "10:50AM", "bldg_cd": "SENSQ", "meeting_topic": "TBA", - "instructors": [ - { - "name": "Robert Fishel", - "email": "rmf105@pitt.edu" - } - ], + "instructors": [{"name": "Robert Fishel", "email": "rmf105@pitt.edu"}], "start_date": "08/29/2022", "end_date": "12/09/2022", "topic": "TBA", "show_topic": False, - "date_range": "08/29/2022 - 12/09/2022" + "date_range": "08/29/2022 - 12/09/2022", } ], "enrollment_information": { @@ -209,21 +180,18 @@ "drop_consent": "", "enroll_requirements": "", "requirement_desig": "", - "class_attributes": "DSAS Algebra General Ed. Requirement \rDSAS Quant.-Formal Reason General Ed. Requirement \rAsian Studies" + "class_attributes": "DSAS Algebra General Ed. Requirement \rDSAS Quant.-Formal Reason General Ed. Requirement \rAsian Studies", }, "class_availability": { "class_capacity": "28", "enrollment_total": "24", "enrollment_available": 4, "wait_list_capacity": "50", - "wait_list_total": "7" + "wait_list_total": "7", }, "reserve_caps": [], "is_combined": False, - "notes": { - "class_notes": "", - "subject_notes": "" - }, + "notes": {"class_notes": "", "subject_notes": ""}, "catalog_descr": { "crse_catalog_description": "This is a first course in computer science programming. It is recommended for those students intending to major in computer science who do not have the required background for cs 0401. It may also be of interest to students majoring in one of the social sciences or humanities. The focus of the course is on problem analysis and the development of algorithms and computer programs in a modern high-level language." }, @@ -231,14 +199,11 @@ "txb_none": "N", "txb_status": "P", "txb_special_instructions": "", - "textbooks_message": "Textbooks to be determined" + "textbooks_message": "Textbooks to be determined", }, - "valid_to_enroll": "T" - }, - "class_enroll_info": { - "last_enrl_dt_passed": False, - "is_related": True + "valid_to_enroll": "T", }, + "class_enroll_info": {"last_enrl_dt_passed": False, "is_related": True}, "additionalLinks": [], "cfg": { "is_related": False, @@ -272,12 +237,12 @@ "show_topic": False, "show_add_to_wish_list": False, "wish_list_enabled": False, - "show_actions": True + "show_actions": True, }, "messages": { "shareLink": "Copy link to share the class with friends.", "shareSocial": "Or share on social media networks.", "reserveInfo": "Seats in this class have been reserved for students for the specified programs, majors or groups listed below. Reserved seats are subject to change without notice.", - "noMeetingInfo": "No meeting info found" - } + "noMeetingInfo": "No meeting info found", + }, } diff --git a/tests/news_test.py b/tests/news_test.py index aec2f66..e4aef05 100644 --- a/tests/news_test.py +++ b/tests/news_test.py @@ -21,6 +21,7 @@ from pittapi import news + @unittest.skip class NewsTest(unittest.TestCase): def test_get_news_default(self): diff --git a/tests/people_test.py b/tests/people_test.py index 616599f..7ca7f3a 100644 --- a/tests/people_test.py +++ b/tests/people_test.py @@ -21,8 +21,7 @@ import responses from pittapi import people -RAMIREZ_TEST_DATA = ( - ''' +RAMIREZ_TEST_DATA = """
@@ -66,10 +65,9 @@
- ''') + """ -TOO_MANY_TEST_DATA = ( - ''' +TOO_MANY_TEST_DATA = """
Too many people matched your criteria. Please try searching by username, phone, email, or by enclosing your @@ -81,10 +79,9 @@
- ''') + """ -NONE_FOUND_TEST_DATA = ( - ''' +NONE_FOUND_TEST_DATA = """
- ''') + """ class PeopleTest(unittest.TestCase): @responses.activate def test_people_get_person(self): - responses.add(responses.POST, people.PEOPLE_SEARCH_URL, - body=RAMIREZ_TEST_DATA, status=200) + responses.add( + responses.POST, people.PEOPLE_SEARCH_URL, body=RAMIREZ_TEST_DATA, status=200 + ) ans = people.get_person("John C Ramirez") self.assertIsInstance(ans, list) - self.assertTrue(ans[0]['name'] == "Ramirez, John C") - self.assertTrue(ans[0]['office_phone'] == "(412) 624-8441") + self.assertTrue(ans[0]["name"] == "Ramirez, John C") + self.assertTrue(ans[0]["office_phone"] == "(412) 624-8441") @responses.activate def test_people_get_person_too_many(self): - responses.add(responses.POST, people.PEOPLE_SEARCH_URL, - body=TOO_MANY_TEST_DATA, status=200) + responses.add( + responses.POST, + people.PEOPLE_SEARCH_URL, + body=TOO_MANY_TEST_DATA, + status=200, + ) ans = people.get_person("Smith") - self.assertIsInstance(ans,list) - self.assertEqual(ans, [{"ERROR":"Too many people matched your criteria."}]) + self.assertIsInstance(ans, list) + self.assertEqual(ans, [{"ERROR": "Too many people matched your criteria."}]) @responses.activate def test_people_get_person_none(self): - responses.add(responses.POST, people.PEOPLE_SEARCH_URL, - body=NONE_FOUND_TEST_DATA, status=200) + responses.add( + responses.POST, + people.PEOPLE_SEARCH_URL, + body=NONE_FOUND_TEST_DATA, + status=200, + ) ans = people.get_person("Lebron Iverson James Jordan Kobe") - self.assertIsInstance(ans,list) - self.assertEqual(ans, [{"ERROR":"No one found."}]) + self.assertIsInstance(ans, list) + self.assertEqual(ans, [{"ERROR": "No one found."}]) diff --git a/tests/shuttle_test.py b/tests/shuttle_test.py index 6dba8bf..e8a0855 100644 --- a/tests/shuttle_test.py +++ b/tests/shuttle_test.py @@ -28,9 +28,9 @@ class ShuttleTest(unittest.TestCase): def test_get_map_vehicle_points(self): responses.add( method=responses.GET, - url='http://www.pittshuttle.com/Services/JSONPRelay.svc/GetMapVehiclePoints?ApiKey=8882812681', + url="http://www.pittshuttle.com/Services/JSONPRelay.svc/GetMapVehiclePoints?ApiKey=8882812681", json=[{}, {}, {}], - status=200 + status=200, ) self.assertIsInstance(shuttle.get_map_vehicle_points(), list) @@ -38,9 +38,9 @@ def test_get_map_vehicle_points(self): def test_get_route_stop_arrivals(self): responses.add( method=responses.GET, - url='http://www.pittshuttle.com/Services/JSONPRelay.svc/GetRouteStopArrivals?ApiKey=8882812681&TimesPerStopString=1', + url="http://www.pittshuttle.com/Services/JSONPRelay.svc/GetRouteStopArrivals?ApiKey=8882812681&TimesPerStopString=1", json=[{}, {}, {}], - status=200 + status=200, ) self.assertIsInstance(shuttle.get_route_stop_arrivals(), list) @@ -48,20 +48,20 @@ def test_get_route_stop_arrivals(self): def test_vehicle_route_stop_estimates(self): responses.add( method=responses.GET, - url='http://www.pittshuttle.com/Services/JSONPRelay.svc/GetVehicleRouteStopEstimates?vehicleIdStrings=25&quantity=4', + url="http://www.pittshuttle.com/Services/JSONPRelay.svc/GetVehicleRouteStopEstimates?vehicleIdStrings=25&quantity=4", json=[{"Estimates": [{}, {}, {}, {}]}], - status=200 + status=200, ) stop_estimates = shuttle.get_vehicle_route_stop_estimates(25, 4) self.assertIsInstance(stop_estimates, list) - self.assertEqual(len(stop_estimates[0]['Estimates']), 4) + self.assertEqual(len(stop_estimates[0]["Estimates"]), 4) @responses.activate def test_get_routes(self): responses.add( method=responses.GET, - url='http://www.pittshuttle.com/Services/JSONPRelay.svc/GetRoutesForMap?ApiKey=8882812681', + url="http://www.pittshuttle.com/Services/JSONPRelay.svc/GetRoutesForMap?ApiKey=8882812681", json=[{}, {}, {}], - status=200 + status=200, ) self.assertIsInstance(shuttle.get_routes(), list) diff --git a/tests/sports_test.py b/tests/sports_test.py index bb6deb3..a4c5115 100644 --- a/tests/sports_test.py +++ b/tests/sports_test.py @@ -19,23 +19,24 @@ from pittapi import sports + class LibraryTest(unittest.TestCase): def setUp(self): mocked_basketball_data = { - "team" : { + "team": { "id": "221", "record": { "items": [ { "description": "Overall Record", "type": "total", - "summary": "11-21" + "summary": "11-21", }, { "description": "Home Record", "type": "home", "summary": "9-11", - } + }, ] }, "nextEvent": [ @@ -45,49 +46,42 @@ def setUp(self): { "venue": { "fullName": "Barclays Center", - "address": { - "city": "Brooklyn", - "state": "NY" - } + "address": {"city": "Brooklyn", "state": "NY"}, }, "competitors": [ { "id": "221", - "homeAway" : "home", - "team" : { + "homeAway": "home", + "team": { "id": "221", "location": "Pittsburgh", "nickname": "Pittsburgh", "abbreviation": "PITT", - "displayName": "Pittsburgh Panthers" - } + "displayName": "Pittsburgh Panthers", + }, }, { "id": "103", "homeAway": "away", - "team" : { + "team": { "id": "103", "location": "Boston College", "nickname": "Boston College", "abbreviation": "BC", - "displayName": "Boston College Eagles" - } - } + "displayName": "Boston College Eagles", + }, + }, ], - "status": { - "type": { - "name": "STATUS_FINAL" - } - } + "status": {"type": {"name": "STATUS_FINAL"}}, } - ] + ], } ], - "standingSummary": "12th in ACC" + "standingSummary": "12th in ACC", } } mocked_football_data = { - "team" : { + "team": { "id": "221", "name": "Pittsburgh", "record": { @@ -95,13 +89,13 @@ def setUp(self): { "description": "Overall Record", "type": "total", - "summary": "10-2" + "summary": "10-2", }, { "description": "Home Record", "type": "home", "summary": "5-2", - } + }, ] }, "nextEvent": [ @@ -113,74 +107,61 @@ def setUp(self): { "venue": { "fullName": "Bank of America Stadium", - "address": { - "city": "Charlotte", - "state": "NC" - } + "address": {"city": "Charlotte", "state": "NC"}, }, "competitors": [ { "id": "221", - "homeAway" : "away", - "team" : { + "homeAway": "away", + "team": { "id": "221", "location": "Pittsburgh", "nickname": "Pittsburgh", "abbreviation": "PITT", - "displayName": "Pittsburgh Panthers" - } + "displayName": "Pittsburgh Panthers", + }, }, { "id": "104", "homeAway": "away", - "team" : { + "team": { "id": "103", "location": "Wake Forest", "nickname": "Wake Forest", "abbreviation": "WAKE", - "displayName": "Wake Forest Deamon Deacons" - } - } + "displayName": "Wake Forest Deamon Deacons", + }, + }, ], - "status": { - "type": { - "name": "STATUS_IN_PROGRESS" - } - } + "status": {"type": {"name": "STATUS_IN_PROGRESS"}}, } - ] + ], } ], - "standingSummary": "1st in ACC - Coastal" + "standingSummary": "1st in ACC - Coastal", } } - sports._get_mens_basketball_data = MagicMock(return_value=mocked_basketball_data) + sports._get_mens_basketball_data = MagicMock( + return_value=mocked_basketball_data + ) sports._get_football_data = MagicMock(return_value=mocked_football_data) def test_get_mens_basketball_record(self): self.assertEqual("11-21", sports.get_mens_basketball_record()) def test_get_mens_basketball_record_offseason(self): - offseason_data = { - "team": { - "id": "221", - "record": {} - } - } + offseason_data = {"team": {"id": "221", "record": {}}} sports._get_mens_basketball_data = MagicMock(return_value=offseason_data) - self.assertEqual("There's no record right now.", sports.get_mens_basketball_record()) + self.assertEqual( + "There's no record right now.", sports.get_mens_basketball_record() + ) def test_get_football_record(self): self.assertEqual("10-2", sports.get_football_record()) def test_get_football_record_offseason(self): - offseason_data = { - "team": { - "id": "221", - "record": {} - } - } + offseason_data = {"team": {"id": "221", "record": {}}} sports._get_football_data = MagicMock(return_value=offseason_data) self.assertEqual("There's no record right now.", sports.get_football_record()) @@ -210,11 +191,7 @@ def test_get_next_football_game(self): self.assertNotEqual("NO_GAME_SCHEDULED", next_game_details["status"]) def test_get_next_mens_basketball_game_offseason(self): - offseason_data = { - "team": { - "nextEvent": [] - } - } + offseason_data = {"team": {"nextEvent": []}} sports._get_mens_basketball_data = MagicMock(return_value=offseason_data) next_game_details = sports.get_next_mens_basketball_game() @@ -223,11 +200,7 @@ def test_get_next_mens_basketball_game_offseason(self): self.assertEqual("NO_GAME_SCHEDULED", next_game_details["status"]) def test_get_next_football_game_offseason(self): - offseason_data = { - "team": { - "nextEvent": [] - } - } + offseason_data = {"team": {"nextEvent": []}} sports._get_football_data = MagicMock(return_value=offseason_data) next_game_details = sports.get_next_football_game() diff --git a/tests/status_test.py b/tests/status_test.py index 69c33d8..28d2794 100644 --- a/tests/status_test.py +++ b/tests/status_test.py @@ -25,18 +25,21 @@ from pittapi import status -SAMPLE_PATH = Path() / 'tests' / 'samples' +SAMPLE_PATH = Path() / "tests" / "samples" class StatusTest(unittest.TestCase): def __init__(self, *args, **kwargs): unittest.TestCase.__init__(self, *args, **kwargs) - with (SAMPLE_PATH / 'status.json').open() as f: + with (SAMPLE_PATH / "status.json").open() as f: self.status_data = json.load(f) @responses.activate def test_get_status(self): - responses.add(responses.GET, - 'https://status.pitt.edu/index.json', - json=self.status_data, status=200) + responses.add( + responses.GET, + "https://status.pitt.edu/index.json", + json=self.status_data, + status=200, + ) self.assertIsInstance(status.get_status(), dict) diff --git a/tests/textbook_test.py b/tests/textbook_test.py index e28aca3..c007565 100644 --- a/tests/textbook_test.py +++ b/tests/textbook_test.py @@ -25,8 +25,8 @@ from pittapi import textbook -TERM = '1000' -SAMPLE_PATH = Path() / 'tests' / 'samples' +TERM = "1000" +SAMPLE_PATH = Path() / "tests" / "samples" print(SAMPLE_PATH.absolute()) @@ -36,147 +36,186 @@ def __init__(self, *args, **kwargs): unittest.TestCase.__init__(self, *args, **kwargs) self.validate_term = textbook._validate_term self.validate_course = textbook._validate_course - with (SAMPLE_PATH /'textbook_courses_CS.json').open() as f: + with (SAMPLE_PATH / "textbook_courses_CS.json").open() as f: self.cs_data = json.load(f) - with (SAMPLE_PATH / 'textbook_courses_STAT.json').open() as f: + with (SAMPLE_PATH / "textbook_courses_STAT.json").open() as f: self.stat_data = json.load(f) @responses.activate def test_textbook_get_textbook(self): - responses.add(responses.GET, 'http://pitt.verbacompare.com/compare/courses/?id=22457&term_id=1000', - json=self.cs_data, status=200) + responses.add( + responses.GET, + "http://pitt.verbacompare.com/compare/courses/?id=22457&term_id=1000", + json=self.cs_data, + status=200, + ) instructor_test = textbook.get_textbook( - term=TERM, - department='CS', - course='445', - instructor='GARRISON III' + term=TERM, department="CS", course="445", instructor="GARRISON III" ) section_test = textbook.get_textbook( - term=TERM, - department='CS', - course='445', - section='1030' + term=TERM, department="CS", course="445", section="1030" ) self.assertIsInstance(instructor_test, list) self.assertIsInstance(section_test, list) @responses.activate def test_textbook_get_textbooks(self): - responses.add(responses.GET, 'http://pitt.verbacompare.com/compare/courses/?id=22457&term_id=1000', - json=self.cs_data, status=200) - responses.add(responses.GET, 'http://pitt.verbacompare.com/compare/courses/?id=22594&term_id=1000', - json=self.stat_data, status=200) + responses.add( + responses.GET, + "http://pitt.verbacompare.com/compare/courses/?id=22457&term_id=1000", + json=self.cs_data, + status=200, + ) + responses.add( + responses.GET, + "http://pitt.verbacompare.com/compare/courses/?id=22594&term_id=1000", + json=self.stat_data, + status=200, + ) multi_book_test = textbook.get_textbooks( term=TERM, courses=[ - {'department': 'STAT', 'course': '1000', 'instructor': 'WANG'}, - {'department': 'CS', 'course': '445', 'section': '1030'}]) + {"department": "STAT", "course": "1000", "instructor": "WANG"}, + {"department": "CS", "course": "445", "section": "1030"}, + ], + ) self.assertIsInstance(multi_book_test, list) @responses.activate def test_get_textbook_invalid_term(self): - responses.add(responses.GET, 'http://pitt.verbacompare.com/compare/courses/?id=22457&term_id=1000', - json=self.cs_data, status=200) - self.assertRaises(TypeError, textbook.get_textbook, '0000', 'CS', '401') + responses.add( + responses.GET, + "http://pitt.verbacompare.com/compare/courses/?id=22457&term_id=1000", + json=self.cs_data, + status=200, + ) + self.assertRaises(TypeError, textbook.get_textbook, "0000", "CS", "401") @responses.activate def test_get_textbook_invalid_subject(self): # TODO(@azharichenko): Added better subject verification in future update - responses.add(responses.GET, 'http://pitt.verbacompare.com/compare/courses/?id=22457&term_id=1000', - json=self.cs_data, status=200) - self.assertRaises(ValueError, textbook.get_textbook, TERM, 'Computer Science', '000', 'EXIST', None) + responses.add( + responses.GET, + "http://pitt.verbacompare.com/compare/courses/?id=22457&term_id=1000", + json=self.cs_data, + status=200, + ) + self.assertRaises( + ValueError, + textbook.get_textbook, + TERM, + "Computer Science", + "000", + "EXIST", + None, + ) @responses.activate def test_get_textbook_invalid_instructor(self): - responses.add(responses.GET, 'http://pitt.verbacompare.com/compare/courses/?id=22457&term_id=1000', - json=self.cs_data, status=200) - self.assertRaises(LookupError, textbook.get_textbook, TERM, 'CS', '447', 'EXIST', None) + responses.add( + responses.GET, + "http://pitt.verbacompare.com/compare/courses/?id=22457&term_id=1000", + json=self.cs_data, + status=200, + ) + self.assertRaises( + LookupError, textbook.get_textbook, TERM, "CS", "447", "EXIST", None + ) @responses.activate def test_get_textbook_invalid_section(self): - responses.add(responses.GET, 'http://pitt.verbacompare.com/compare/courses/?id=22457&term_id=1000', - json=self.cs_data, status=200) - self.assertRaises(LookupError, textbook.get_textbook, TERM, 'CS', '401', None, '9999') + responses.add( + responses.GET, + "http://pitt.verbacompare.com/compare/courses/?id=22457&term_id=1000", + json=self.cs_data, + status=200, + ) + self.assertRaises( + LookupError, textbook.get_textbook, TERM, "CS", "401", None, "9999" + ) @responses.activate def test_get_textbook_invalid_section_and_instructor(self): - responses.add(responses.GET, 'http://pitt.verbacompare.com/compare/courses/?id=22457&term_id=1000', - json=self.cs_data, status=200) - self.assertRaises(TypeError, textbook.get_textbook, TERM, 'CS', '401', None, None) - + responses.add( + responses.GET, + "http://pitt.verbacompare.com/compare/courses/?id=22457&term_id=1000", + json=self.cs_data, + status=200, + ) + self.assertRaises( + TypeError, textbook.get_textbook, TERM, "CS", "401", None, None + ) def test_term_validation(self): self.assertEqual(self.validate_term(TERM), TERM) def test_term_validation_invalid(self): - self.assertRaises(ValueError, self.validate_term, '1') - self.assertRaises(ValueError, self.validate_term, 'a') - self.assertRaises(ValueError, self.validate_term, '100') - self.assertRaises(ValueError, self.validate_term, '10000') + self.assertRaises(ValueError, self.validate_term, "1") + self.assertRaises(ValueError, self.validate_term, "a") + self.assertRaises(ValueError, self.validate_term, "100") + self.assertRaises(ValueError, self.validate_term, "10000") def test_validate_course_correct_input(self): - self.assertEqual(self.validate_course('0000'), '0000') - self.assertEqual(self.validate_course('0001'), '0001') - self.assertEqual(self.validate_course('0012'), '0012') - self.assertEqual(self.validate_course('0123'), '0123') - self.assertEqual(self.validate_course('1234'), '1234') - self.assertEqual(self.validate_course('9999'), '9999') + self.assertEqual(self.validate_course("0000"), "0000") + self.assertEqual(self.validate_course("0001"), "0001") + self.assertEqual(self.validate_course("0012"), "0012") + self.assertEqual(self.validate_course("0123"), "0123") + self.assertEqual(self.validate_course("1234"), "1234") + self.assertEqual(self.validate_course("9999"), "9999") def test_validate_course_improper_input(self): - self.assertEqual(self.validate_course('0'), '0000') - self.assertEqual(self.validate_course('1'), '0001') - self.assertEqual(self.validate_course('12'), '0012') - self.assertEqual(self.validate_course('123'), '0123') + self.assertEqual(self.validate_course("0"), "0000") + self.assertEqual(self.validate_course("1"), "0001") + self.assertEqual(self.validate_course("12"), "0012") + self.assertEqual(self.validate_course("123"), "0123") def test_validate_course_incorrect_input(self): - self.assertRaises(ValueError, self.validate_course, '') - self.assertRaises(ValueError, self.validate_course, '00000') - self.assertRaises(ValueError, self.validate_course, '11111') - self.assertRaises(ValueError, self.validate_course, 'hi') + self.assertRaises(ValueError, self.validate_course, "") + self.assertRaises(ValueError, self.validate_course, "00000") + self.assertRaises(ValueError, self.validate_course, "11111") + self.assertRaises(ValueError, self.validate_course, "hi") def test_construct_query(self): construct = textbook._construct_query - course_query = 'compare/courses/?id=9999&term_id=1111' - book_query = 'compare/books?id=9999' + course_query = "compare/courses/?id=9999&term_id=1111" + book_query = "compare/books?id=9999" - self.assertEqual(construct('courses', '9999', '1111'), course_query) - self.assertEqual(construct('books', '9999'), book_query) + self.assertEqual(construct("courses", "9999", "1111"), course_query) + self.assertEqual(construct("books", "9999"), book_query) def test_find_item(self): - find = textbook._find_item('id', 'key', 'test') + find = textbook._find_item("id", "key", "test") test_data = [ - {'id': 1, 'key': 1}, - {'id': 2, 'key': 4}, - {'id': 3, 'key': 9}, - {'id': 4, 'key': 16}, - {'id': 5, 'key': 25} + {"id": 1, "key": 1}, + {"id": 2, "key": 4}, + {"id": 3, "key": 9}, + {"id": 4, "key": 16}, + {"id": 5, "key": 25}, ] for i in range(1, 6): - self.assertEqual(find(test_data, i), i ** 2) + self.assertEqual(find(test_data, i), i**2) self.assertRaises(LookupError, find, test_data, 6) @responses.activate def test_extract_id(self): - responses.add(responses.GET, 'http://pitt.verbacompare.com/compare/courses/?id=22457&term_id=1000', - json=self.cs_data, status=201) + responses.add( + responses.GET, + "http://pitt.verbacompare.com/compare/courses/?id=22457&term_id=1000", + json=self.cs_data, + status=201, + ) def test_filter_dictionary(self): - test_dict = { - 'a': 1, - 'b': 2, - 'c': 3 - } - test_key = ['a', 'c'] + test_dict = {"a": 1, "b": 2, "c": 3} + test_key = ["a", "c"] self.assertEqual( - textbook._filter_dictionary( - test_dict, test_key), {'a': 1, 'c': 3} + textbook._filter_dictionary(test_dict, test_key), {"a": 1, "c": 3} ) - - - def test_invalid_department_code(self): - self.assertRaises(ValueError, textbook.get_textbook, TERM, 'TEST', '000', 'EXIST', None) + self.assertRaises( + ValueError, textbook.get_textbook, TERM, "TEST", "000", "EXIST", None + ) From ad50360ec1adec6b908b1add871a86177ddcf5d5 Mon Sep 17 00:00:00 2001 From: Manny McGrail <152332440+ghosteau@users.noreply.github.com> Date: Sun, 9 Jun 2024 22:26:28 -0400 Subject: [PATCH 08/33] Update pittapi/course.py Co-authored-by: Tianyi Zheng --- pittapi/course.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pittapi/course.py b/pittapi/course.py index b67fe00..63471e1 100644 --- a/pittapi/course.py +++ b/pittapi/course.py @@ -215,16 +215,12 @@ def get_course_details(term: Union[str, int], subject: str, course: Union[str, i ) return CourseDetails( -<<<<<<< HEAD course=Course( subject_code=subject, course_number=course, course_id=internal_course_id, course_title=course_title, ), -======= - course=Course(subject_code=subject, course_number=course, course_id=internal_course_id, course_title=course_title), ->>>>>>> 5707e24e2f881755bb429b3b1a0f2245940b46d6 course_description=course_description, credit_range=credit_range, requisites=requisites, From d43e9861d0dea3f822525931c3d3530692e9db9e Mon Sep 17 00:00:00 2001 From: Manny McGrail <152332440+ghosteau@users.noreply.github.com> Date: Mon, 10 Jun 2024 01:12:02 -0400 Subject: [PATCH 09/33] Delete black --- black | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 black diff --git a/black b/black deleted file mode 100644 index e69de29..0000000 From 4b27e5e6656252f13dbd95cf7f0ae5046d27387d Mon Sep 17 00:00:00 2001 From: Manny McGrail <152332440+ghosteau@users.noreply.github.com> Date: Mon, 10 Jun 2024 01:24:46 -0400 Subject: [PATCH 10/33] Update course_test.py --- tests/course_test.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/tests/course_test.py b/tests/course_test.py index 7c9c235..1f6083e 100644 --- a/tests/course_test.py +++ b/tests/course_test.py @@ -21,7 +21,6 @@ from unittest.mock import MagicMock from pittapi import course -<<<<<<< HEAD from pittapi.course import ( Attribute, Component, @@ -33,9 +32,7 @@ SectionDetails, Subject, ) -======= -from pittapi.course import Attribute, Component, Course, CourseDetails, Instructor, Meeting, Section, SectionDetails, Subject ->>>>>>> 5707e24e2f881755bb429b3b1a0f2245940b46d6 + from tests.mocks.course_mocks import ( mocked_subject_data, mocked_courses_data, @@ -130,15 +127,11 @@ def test_get_course_details(self): test_attribute = course_sections.attributes[0] self.assertTrue(isinstance(test_attribute, Attribute)) self.assertEqual(test_attribute.attribute, "DSGE") -<<<<<<< HEAD self.assertEqual( test_attribute.attribute_description, "*DSAS General Ed. Requirements" ) -======= self.assertEqual(test_attribute.attribute_description, "*DSAS General Ed. Requirements") ->>>>>>> 5707e24e2f881755bb429b3b1a0f2245940b46d6 self.assertEqual(test_attribute.value, "ALG") - self.assertEqual(test_attribute.value_description, "Algebra") test_section = course_sections.sections[0] self.assertTrue(isinstance(test_section, Section)) From b4c764ffcddbc4c70e71fafe1890b0ea93a275cc Mon Sep 17 00:00:00 2001 From: Manny McGrail <152332440+ghosteau@users.noreply.github.com> Date: Mon, 10 Jun 2024 01:48:59 -0400 Subject: [PATCH 11/33] Update dining_test.py --- tests/dining_test.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/dining_test.py b/tests/dining_test.py index b278056..8ddda20 100644 --- a/tests/dining_test.py +++ b/tests/dining_test.py @@ -85,11 +85,6 @@ def test_get_location_menu(self): json=self.dining_menu_data, status=200, ) -<<<<<<< HEAD locations = dining.get_location_menu( "The Eatery", datetime.datetime(2024, 4, 12), "Breakfast" ) -======= - locations = dining.get_location_menu("The Eatery", datetime.datetime(2024, 4, 12), "Breakfast") ->>>>>>> 5707e24e2f881755bb429b3b1a0f2245940b46d6 - self.assertIsInstance(locations, dict) From d2c4144677011869e6c29b32ee98248278e56514 Mon Sep 17 00:00:00 2001 From: Manny McGrail <152332440+ghosteau@users.noreply.github.com> Date: Mon, 10 Jun 2024 01:52:46 -0400 Subject: [PATCH 12/33] Update library_test.py --- tests/library_test.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/library_test.py b/tests/library_test.py index e41f426..9e5d0f5 100644 --- a/tests/library_test.py +++ b/tests/library_test.py @@ -36,16 +36,12 @@ def __init__(self, *args, **kwargs): @responses.activate def test_get_documents(self): -<<<<<<< HEAD responses.add( responses.GET, library.LIBRARY_URL + library.QUERY_START + "water", json=self.library_query, status=200, ) -======= - responses.add(responses.GET, library.LIBRARY_URL + library.QUERY_START + "water", json=self.library_query, status=200) ->>>>>>> 5707e24e2f881755bb429b3b1a0f2245940b46d6 query_result = library.get_documents("water") self.assertIsInstance(query_result, dict) self.assertEqual(query_result["pages"], 10) From f7f7cd0ec6cff9ed0fffb8b3b7c3ba0abb085af1 Mon Sep 17 00:00:00 2001 From: Manny McGrail <152332440+ghosteau@users.noreply.github.com> Date: Mon, 10 Jun 2024 01:58:45 -0400 Subject: [PATCH 13/33] Update course_mocks.py --- tests/mocks/course_mocks.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/tests/mocks/course_mocks.py b/tests/mocks/course_mocks.py index 8222575..da4f518 100644 --- a/tests/mocks/course_mocks.py +++ b/tests/mocks/course_mocks.py @@ -1,7 +1,4 @@ -mocked_subject_data = {"subjects": [{"subject": "CS", "descr": "Computer Science"}]} - mocked_courses_data = { -<<<<<<< HEAD "courses": [ { "catalog_nbr": "0007", @@ -9,9 +6,7 @@ "crse_id": "105611", } ] -======= "courses": [{"catalog_nbr": "0007", "descr": "INTRODUCTION TO COMPUTER PROGRAMMING", "crse_id": "105611"}] ->>>>>>> 5707e24e2f881755bb429b3b1a0f2245940b46d6 } mocked_courses_data_invalid = {} @@ -27,14 +22,10 @@ "course_title": "INTRODUCTION TO COMPUTER PROGRAMMING", "rqmnt_designtn": "", "effdt": "2018-06-30", -<<<<<<< HEAD "components": [ {"descr": "Lecture", "optional": "N"}, {"descr": "Recitation", "optional": "N"}, ], -======= - "components": [{"descr": "Lecture", "optional": "N"}, {"descr": "Recitation", "optional": "N"}], ->>>>>>> 5707e24e2f881755bb429b3b1a0f2245940b46d6 "attributes": [ { "crse_attribute": "DSGE", @@ -62,7 +53,6 @@ "req_group": "", "planner_message": "You have no active career, so you can not add this course to a planner.", "open_terms": [ -<<<<<<< HEAD { "strm": "2224", "descr": "Spring Term 2021-2022", @@ -84,13 +74,6 @@ {"strm": "2227"}, {"strm": "2231"}, ], -======= - {"strm": "2224", "descr": "Spring Term 2021-2022", "default_term": False}, - {"strm": "2227", "descr": "Summer Term 2021-2022", "default_term": False}, - {"strm": "2231", "descr": "Fall Term 2022-2023", "default_term": True}, - ], - "enrollable_terms": [{"strm": "2224"}, {"strm": "2227"}, {"strm": "2231"}], ->>>>>>> 5707e24e2f881755bb429b3b1a0f2245940b46d6 } ], } From fb9db3b53d9e0c72a04d3759ce2e3aefac855bba Mon Sep 17 00:00:00 2001 From: Manny McGrail <152332440+ghosteau@users.noreply.github.com> Date: Mon, 10 Jun 2024 02:03:02 -0400 Subject: [PATCH 14/33] Update people_test.py --- tests/people_test.py | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/tests/people_test.py b/tests/people_test.py index ba3e699..a1980f6 100644 --- a/tests/people_test.py +++ b/tests/people_test.py @@ -109,14 +109,9 @@ class PeopleTest(unittest.TestCase): @responses.activate def test_people_get_person(self): -<<<<<<< HEAD responses.add( responses.POST, people.PEOPLE_SEARCH_URL, body=RAMIREZ_TEST_DATA, status=200 ) -======= - responses.add(responses.POST, people.PEOPLE_SEARCH_URL, body=RAMIREZ_TEST_DATA, status=200) ->>>>>>> 5707e24e2f881755bb429b3b1a0f2245940b46d6 - ans = people.get_person("John C Ramirez") self.assertIsInstance(ans, list) self.assertTrue(ans[0]["name"] == "Ramirez, John C") @@ -124,34 +119,24 @@ def test_people_get_person(self): @responses.activate def test_people_get_person_too_many(self): -<<<<<<< HEAD responses.add( responses.POST, people.PEOPLE_SEARCH_URL, body=TOO_MANY_TEST_DATA, status=200, ) -======= - responses.add(responses.POST, people.PEOPLE_SEARCH_URL, body=TOO_MANY_TEST_DATA, status=200) ->>>>>>> 5707e24e2f881755bb429b3b1a0f2245940b46d6 - ans = people.get_person("Smith") self.assertIsInstance(ans, list) self.assertEqual(ans, [{"ERROR": "Too many people matched your criteria."}]) @responses.activate def test_people_get_person_none(self): -<<<<<<< HEAD responses.add( responses.POST, people.PEOPLE_SEARCH_URL, body=NONE_FOUND_TEST_DATA, status=200, ) -======= - responses.add(responses.POST, people.PEOPLE_SEARCH_URL, body=NONE_FOUND_TEST_DATA, status=200) ->>>>>>> 5707e24e2f881755bb429b3b1a0f2245940b46d6 - ans = people.get_person("Lebron Iverson James Jordan Kobe") self.assertIsInstance(ans, list) self.assertEqual(ans, [{"ERROR": "No one found."}]) From c85481e9f659b450583ca9575d216319e0893b64 Mon Sep 17 00:00:00 2001 From: Manny McGrail <152332440+ghosteau@users.noreply.github.com> Date: Mon, 10 Jun 2024 02:12:32 -0400 Subject: [PATCH 15/33] Update sports_test.py --- tests/sports_test.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/tests/sports_test.py b/tests/sports_test.py index a13263e..a4c5115 100644 --- a/tests/sports_test.py +++ b/tests/sports_test.py @@ -27,15 +27,11 @@ def setUp(self): "id": "221", "record": { "items": [ -<<<<<<< HEAD { "description": "Overall Record", "type": "total", "summary": "11-21", }, -======= - {"description": "Overall Record", "type": "total", "summary": "11-21"}, ->>>>>>> 5707e24e2f881755bb429b3b1a0f2245940b46d6 { "description": "Home Record", "type": "home", @@ -48,14 +44,10 @@ def setUp(self): "date": "2022-03-08T19:00Z", "competitions": [ { -<<<<<<< HEAD "venue": { "fullName": "Barclays Center", "address": {"city": "Brooklyn", "state": "NY"}, }, -======= - "venue": {"fullName": "Barclays Center", "address": {"city": "Brooklyn", "state": "NY"}}, ->>>>>>> 5707e24e2f881755bb429b3b1a0f2245940b46d6 "competitors": [ { "id": "221", @@ -94,15 +86,11 @@ def setUp(self): "name": "Pittsburgh", "record": { "items": [ -<<<<<<< HEAD { "description": "Overall Record", "type": "total", "summary": "10-2", }, -======= - {"description": "Overall Record", "type": "total", "summary": "10-2"}, ->>>>>>> 5707e24e2f881755bb429b3b1a0f2245940b46d6 { "description": "Home Record", "type": "home", From 05e2e3e525ac72d6b4d79b9b0d4c58ec66e0f087 Mon Sep 17 00:00:00 2001 From: Manny McGrail <152332440+ghosteau@users.noreply.github.com> Date: Mon, 10 Jun 2024 02:19:00 -0400 Subject: [PATCH 16/33] Update status_test.py --- tests/status_test.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/status_test.py b/tests/status_test.py index 145ca08..28d2794 100644 --- a/tests/status_test.py +++ b/tests/status_test.py @@ -36,14 +36,10 @@ def __init__(self, *args, **kwargs): @responses.activate def test_get_status(self): -<<<<<<< HEAD responses.add( responses.GET, "https://status.pitt.edu/index.json", json=self.status_data, status=200, ) -======= - responses.add(responses.GET, "https://status.pitt.edu/index.json", json=self.status_data, status=200) ->>>>>>> 5707e24e2f881755bb429b3b1a0f2245940b46d6 self.assertIsInstance(status.get_status(), dict) From 29c41c967a149ac2c46a228ac16044f3b4016385 Mon Sep 17 00:00:00 2001 From: Manny McGrail <152332440+ghosteau@users.noreply.github.com> Date: Mon, 10 Jun 2024 02:23:25 -0400 Subject: [PATCH 17/33] Update textbook_test.py --- tests/textbook_test.py | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/tests/textbook_test.py b/tests/textbook_test.py index 118d08e..aa6dd82 100644 --- a/tests/textbook_test.py +++ b/tests/textbook_test.py @@ -44,7 +44,6 @@ def __init__(self, *args, **kwargs): @responses.activate def test_textbook_get_textbook(self): responses.add( -<<<<<<< HEAD responses.GET, "http://pitt.verbacompare.com/compare/courses/?id=22457&term_id=1000", json=self.cs_data, @@ -52,33 +51,22 @@ def test_textbook_get_textbook(self): ) instructor_test = textbook.get_textbook( term=TERM, department="CS", course="445", instructor="GARRISON III" -======= - responses.GET, "http://pitt.verbacompare.com/compare/courses/?id=22457&term_id=1000", json=self.cs_data, status=200 ->>>>>>> 5707e24e2f881755bb429b3b1a0f2245940b46d6 ) instructor_test = textbook.get_textbook(term=TERM, department="CS", course="445", instructor="GARRISON III") -<<<<<<< HEAD section_test = textbook.get_textbook( term=TERM, department="CS", course="445", section="1030" ) -======= - section_test = textbook.get_textbook(term=TERM, department="CS", course="445", section="1030") ->>>>>>> 5707e24e2f881755bb429b3b1a0f2245940b46d6 self.assertIsInstance(instructor_test, list) self.assertIsInstance(section_test, list) @responses.activate def test_textbook_get_textbooks(self): responses.add( -<<<<<<< HEAD responses.GET, "http://pitt.verbacompare.com/compare/courses/?id=22457&term_id=1000", json=self.cs_data, status=200, -======= - responses.GET, "http://pitt.verbacompare.com/compare/courses/?id=22457&term_id=1000", json=self.cs_data, status=200 ->>>>>>> 5707e24e2f881755bb429b3b1a0f2245940b46d6 ) responses.add( responses.GET, @@ -98,14 +86,10 @@ def test_textbook_get_textbooks(self): @responses.activate def test_get_textbook_invalid_term(self): responses.add( -<<<<<<< HEAD responses.GET, "http://pitt.verbacompare.com/compare/courses/?id=22457&term_id=1000", json=self.cs_data, status=200, -======= - responses.GET, "http://pitt.verbacompare.com/compare/courses/?id=22457&term_id=1000", json=self.cs_data, status=200 ->>>>>>> 5707e24e2f881755bb429b3b1a0f2245940b46d6 ) self.assertRaises(TypeError, textbook.get_textbook, "0000", "CS", "401") @@ -113,7 +97,6 @@ def test_get_textbook_invalid_term(self): def test_get_textbook_invalid_subject(self): # TODO(@azharichenko): Added better subject verification in future update responses.add( -<<<<<<< HEAD responses.GET, "http://pitt.verbacompare.com/compare/courses/?id=22457&term_id=1000", json=self.cs_data, @@ -128,12 +111,6 @@ def test_get_textbook_invalid_subject(self): "EXIST", None, ) -======= - responses.GET, "http://pitt.verbacompare.com/compare/courses/?id=22457&term_id=1000", json=self.cs_data, status=200 - ) - self.assertRaises(ValueError, textbook.get_textbook, TERM, "Computer Science", "000", "EXIST", None) ->>>>>>> 5707e24e2f881755bb429b3b1a0f2245940b46d6 - @responses.activate def test_get_textbook_invalid_instructor(self): responses.add( From 7e99d741ed1930f44401242ceb1999cf20b9526e Mon Sep 17 00:00:00 2001 From: Manny McGrail <152332440+ghosteau@users.noreply.github.com> Date: Mon, 10 Jun 2024 02:28:46 -0400 Subject: [PATCH 18/33] Update textbook_test.py --- tests/textbook_test.py | 37 +++---------------------------------- 1 file changed, 3 insertions(+), 34 deletions(-) diff --git a/tests/textbook_test.py b/tests/textbook_test.py index aa6dd82..c95f3e4 100644 --- a/tests/textbook_test.py +++ b/tests/textbook_test.py @@ -111,10 +111,10 @@ def test_get_textbook_invalid_subject(self): "EXIST", None, ) + @responses.activate def test_get_textbook_invalid_instructor(self): responses.add( -<<<<<<< HEAD responses.GET, "http://pitt.verbacompare.com/compare/courses/?id=22457&term_id=1000", json=self.cs_data, @@ -123,16 +123,10 @@ def test_get_textbook_invalid_instructor(self): self.assertRaises( LookupError, textbook.get_textbook, TERM, "CS", "447", "EXIST", None ) -======= - responses.GET, "http://pitt.verbacompare.com/compare/courses/?id=22457&term_id=1000", json=self.cs_data, status=200 - ) - self.assertRaises(LookupError, textbook.get_textbook, TERM, "CS", "447", "EXIST", None) ->>>>>>> 5707e24e2f881755bb429b3b1a0f2245940b46d6 - + @responses.activate def test_get_textbook_invalid_section(self): responses.add( -<<<<<<< HEAD responses.GET, "http://pitt.verbacompare.com/compare/courses/?id=22457&term_id=1000", json=self.cs_data, @@ -141,16 +135,10 @@ def test_get_textbook_invalid_section(self): self.assertRaises( LookupError, textbook.get_textbook, TERM, "CS", "401", None, "9999" ) -======= - responses.GET, "http://pitt.verbacompare.com/compare/courses/?id=22457&term_id=1000", json=self.cs_data, status=200 - ) - self.assertRaises(LookupError, textbook.get_textbook, TERM, "CS", "401", None, "9999") ->>>>>>> 5707e24e2f881755bb429b3b1a0f2245940b46d6 @responses.activate def test_get_textbook_invalid_section_and_instructor(self): responses.add( -<<<<<<< HEAD responses.GET, "http://pitt.verbacompare.com/compare/courses/?id=22457&term_id=1000", json=self.cs_data, @@ -159,11 +147,6 @@ def test_get_textbook_invalid_section_and_instructor(self): self.assertRaises( TypeError, textbook.get_textbook, TERM, "CS", "401", None, None ) -======= - responses.GET, "http://pitt.verbacompare.com/compare/courses/?id=22457&term_id=1000", json=self.cs_data, status=200 - ) - self.assertRaises(TypeError, textbook.get_textbook, TERM, "CS", "401", None, None) ->>>>>>> 5707e24e2f881755bb429b3b1a0f2245940b46d6 def test_term_validation(self): self.assertEqual(self.validate_term(TERM), TERM) @@ -204,7 +187,6 @@ def test_construct_query(self): def test_find_item(self): find = textbook._find_item("id", "key", "test") -<<<<<<< HEAD test_data = [ {"id": 1, "key": 1}, {"id": 2, "key": 4}, @@ -212,10 +194,7 @@ def test_find_item(self): {"id": 4, "key": 16}, {"id": 5, "key": 25}, ] -======= - test_data = [{"id": 1, "key": 1}, {"id": 2, "key": 4}, {"id": 3, "key": 9}, {"id": 4, "key": 16}, {"id": 5, "key": 25}] ->>>>>>> 5707e24e2f881755bb429b3b1a0f2245940b46d6 - + for i in range(1, 6): self.assertEqual(find(test_data, i), i**2) @@ -224,20 +203,15 @@ def test_find_item(self): @responses.activate def test_extract_id(self): responses.add( -<<<<<<< HEAD responses.GET, "http://pitt.verbacompare.com/compare/courses/?id=22457&term_id=1000", json=self.cs_data, status=201, -======= - responses.GET, "http://pitt.verbacompare.com/compare/courses/?id=22457&term_id=1000", json=self.cs_data, status=201 ->>>>>>> 5707e24e2f881755bb429b3b1a0f2245940b46d6 ) def test_filter_dictionary(self): test_dict = {"a": 1, "b": 2, "c": 3} test_key = ["a", "c"] -<<<<<<< HEAD self.assertEqual( textbook._filter_dictionary(test_dict, test_key), {"a": 1, "c": 3} ) @@ -246,9 +220,4 @@ def test_invalid_department_code(self): self.assertRaises( ValueError, textbook.get_textbook, TERM, "TEST", "000", "EXIST", None ) -======= self.assertEqual(textbook._filter_dictionary(test_dict, test_key), {"a": 1, "c": 3}) - - def test_invalid_department_code(self): - self.assertRaises(ValueError, textbook.get_textbook, TERM, "TEST", "000", "EXIST", None) ->>>>>>> 5707e24e2f881755bb429b3b1a0f2245940b46d6 From cb200d7a624f8c0e171ded5e45e0f1df55ccc877 Mon Sep 17 00:00:00 2001 From: Manny McGrail <152332440+ghosteau@users.noreply.github.com> Date: Mon, 10 Jun 2024 22:49:45 -0400 Subject: [PATCH 19/33] Update course_mocks.py --- tests/mocks/course_mocks.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/mocks/course_mocks.py b/tests/mocks/course_mocks.py index da4f518..bd1a788 100644 --- a/tests/mocks/course_mocks.py +++ b/tests/mocks/course_mocks.py @@ -1,3 +1,4 @@ +mocked_subject_data = {"subjects": [{"subject": "CS", "descr": "Computer Science"}]} mocked_courses_data = { "courses": [ { From 25cf627bc27c7e385e2714509fd36c2d79a07947 Mon Sep 17 00:00:00 2001 From: Manny McGrail <152332440+ghosteau@users.noreply.github.com> Date: Mon, 10 Jun 2024 23:32:53 -0400 Subject: [PATCH 20/33] Update dining_test.py --- tests/dining_test.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/dining_test.py b/tests/dining_test.py index 8ddda20..c12f3a8 100644 --- a/tests/dining_test.py +++ b/tests/dining_test.py @@ -88,3 +88,4 @@ def test_get_location_menu(self): locations = dining.get_location_menu( "The Eatery", datetime.datetime(2024, 4, 12), "Breakfast" ) + self.assertIsInstance(locations, dict) From ecd3d3e996eca9247d0f32eb4e3b0504e9240a93 Mon Sep 17 00:00:00 2001 From: Manny McGrail <152332440+ghosteau@users.noreply.github.com> Date: Mon, 10 Jun 2024 23:48:59 -0400 Subject: [PATCH 21/33] Update course_test.py --- tests/course_test.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/course_test.py b/tests/course_test.py index 1f6083e..65c792b 100644 --- a/tests/course_test.py +++ b/tests/course_test.py @@ -130,7 +130,6 @@ def test_get_course_details(self): self.assertEqual( test_attribute.attribute_description, "*DSAS General Ed. Requirements" ) - self.assertEqual(test_attribute.attribute_description, "*DSAS General Ed. Requirements") self.assertEqual(test_attribute.value, "ALG") self.assertEqual(test_attribute.value_description, "Algebra") test_section = course_sections.sections[0] From de7267d8b29da21b1df850d50458d30a61363b52 Mon Sep 17 00:00:00 2001 From: Manny McGrail <152332440+ghosteau@users.noreply.github.com> Date: Tue, 11 Jun 2024 00:10:02 -0400 Subject: [PATCH 22/33] Update textbook_test.py --- tests/textbook_test.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/textbook_test.py b/tests/textbook_test.py index c95f3e4..567f81d 100644 --- a/tests/textbook_test.py +++ b/tests/textbook_test.py @@ -220,4 +220,3 @@ def test_invalid_department_code(self): self.assertRaises( ValueError, textbook.get_textbook, TERM, "TEST", "000", "EXIST", None ) - self.assertEqual(textbook._filter_dictionary(test_dict, test_key), {"a": 1, "c": 3}) From b4650e5dd3fc50f69ef9abdd5de8bd9fb4c0f520 Mon Sep 17 00:00:00 2001 From: Manny McGrail <152332440+ghosteau@users.noreply.github.com> Date: Tue, 11 Jun 2024 00:12:48 -0400 Subject: [PATCH 23/33] Update course_mocks.py --- tests/mocks/course_mocks.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/mocks/course_mocks.py b/tests/mocks/course_mocks.py index bd1a788..9e0d4be 100644 --- a/tests/mocks/course_mocks.py +++ b/tests/mocks/course_mocks.py @@ -7,7 +7,6 @@ "crse_id": "105611", } ] - "courses": [{"catalog_nbr": "0007", "descr": "INTRODUCTION TO COMPUTER PROGRAMMING", "crse_id": "105611"}] } mocked_courses_data_invalid = {} From 6fa494b855ddd2b4f859ce199bf04c66fae9dcab Mon Sep 17 00:00:00 2001 From: Tianyi Zheng Date: Tue, 11 Jun 2024 02:21:24 -0700 Subject: [PATCH 24/33] Fix black errors --- pittapi/cal.py | 20 +++++--------------- pittapi/laundry.py | 4 +--- pittapi/library.py | 8 ++------ pittapi/news.py | 4 +--- pittapi/shuttle.py | 8 ++------ pittapi/sports.py | 14 +++----------- pittapi/textbook.py | 41 ++++++++--------------------------------- tests/course_test.py | 20 +++++--------------- tests/dining_test.py | 4 +--- tests/people_test.py | 4 +--- tests/sports_test.py | 8 ++------ tests/textbook_test.py | 34 ++++++++++------------------------ 12 files changed, 41 insertions(+), 128 deletions(-) diff --git a/pittapi/cal.py b/pittapi/cal.py index 38144d5..1efac20 100644 --- a/pittapi/cal.py +++ b/pittapi/cal.py @@ -29,21 +29,11 @@ class Event(NamedTuple): meta: str -ACADEMIC_CALENDAR_URL: str = ( - "https://25livepub.collegenet.com/calendars/pitt-academic-calendar.json" -) -GRADES_CALENDAR_URL: str = ( - "https://25livepub.collegenet.com/calendars/pitt-grades-calendar.json" -) -ENROLLMENT_CALENDAR_URL: str = ( - "https://25livepub.collegenet.com/calendars/pitt-enrollment-calendar.json" -) -COURSE_CALENDAR_URL: str = ( - "https://25livepub.collegenet.com/calendars/pitt-courseclass-calendar.json" -) -GRADUATION_CALENDAR_URL: str = ( - "https://25livepub.collegenet.com/calendars/pitt-graduation-calendar.json" -) +ACADEMIC_CALENDAR_URL: str = "https://25livepub.collegenet.com/calendars/pitt-academic-calendar.json" +GRADES_CALENDAR_URL: str = "https://25livepub.collegenet.com/calendars/pitt-grades-calendar.json" +ENROLLMENT_CALENDAR_URL: str = "https://25livepub.collegenet.com/calendars/pitt-enrollment-calendar.json" +COURSE_CALENDAR_URL: str = "https://25livepub.collegenet.com/calendars/pitt-courseclass-calendar.json" +GRADUATION_CALENDAR_URL: str = "https://25livepub.collegenet.com/calendars/pitt-graduation-calendar.json" def _fetch_calendar_events(url: str) -> List[Event]: diff --git a/pittapi/laundry.py b/pittapi/laundry.py index 50a8367..c63c32f 100644 --- a/pittapi/laundry.py +++ b/pittapi/laundry.py @@ -23,9 +23,7 @@ from bs4 import BeautifulSoup -BASE_URL = ( - "https://www.laundryview.com/api/currentRoomData?school_desc_key=197&location={}" -) +BASE_URL = "https://www.laundryview.com/api/currentRoomData?school_desc_key=197&location={}" LOCATION_LOOKUP = { "TOWERS": "2430136", diff --git a/pittapi/library.py b/pittapi/library.py index aa01cff..873f247 100644 --- a/pittapi/library.py +++ b/pittapi/library.py @@ -122,16 +122,12 @@ def _extract_documents(documents: List[Dict[str, Any]]) -> List[Dict[str, Any]]: return new_docs -def _extract_facets( - facet_fields: List[Dict[str, Any]] -) -> Dict[str, List[Dict[str, Any]]]: +def _extract_facets(facet_fields: List[Dict[str, Any]]) -> Dict[str, List[Dict[str, Any]]]: facets = {} # type: Dict[str,List[Dict[str,Any]]] for facet in facet_fields: facets[facet["display_name"]] = [] for count in facet["counts"]: - facets[facet["display_name"]].append( - {"value": count["value"], "count": count["count"]} - ) + facets[facet["display_name"]].append({"value": count["value"], "count": count["count"]}) return facets diff --git a/pittapi/news.py b/pittapi/news.py index 333d47e..ab4c957 100644 --- a/pittapi/news.py +++ b/pittapi/news.py @@ -37,9 +37,7 @@ def _load_n_items(feed: str, max_news_items: int): request_objs = [] for i in range(int(math.ceil(max_news_items / 10))): payload["start"] = i * 10 - request_objs.append( - grequests.get("https://m.pitt.edu/news/index.json", params=payload) - ) + request_objs.append(grequests.get("https://m.pitt.edu/news/index.json", params=payload)) responses = grequests.imap(request_objs) diff --git a/pittapi/shuttle.py b/pittapi/shuttle.py index 8fcf8c7..faeefe4 100644 --- a/pittapi/shuttle.py +++ b/pittapi/shuttle.py @@ -33,9 +33,7 @@ def get_map_vehicle_points(api_key: str = "8882812681") -> Dict[str, Any]: return response.json() -def get_route_stop_arrivals( - api_key: str = "8882812681", times_per_stop: int = 1 -) -> Dict[str, Any]: +def get_route_stop_arrivals(api_key: str = "8882812681", times_per_stop: int = 1) -> Dict[str, Any]: """Return stop arrival times for all vehicles.""" payload = {"ApiKey": api_key, "TimesPerStopString": times_per_stop} response = sess.get( @@ -45,9 +43,7 @@ def get_route_stop_arrivals( return response.json() -def get_vehicle_route_stop_estimates( - vehicle_id: str, quantity: int = 2 -) -> Dict[str, Any]: +def get_vehicle_route_stop_estimates(vehicle_id: str, quantity: int = 2) -> Dict[str, Any]: """Return {quantity} stop estimates for all active vehicles.""" payload = {"vehicleIdStrings": vehicle_id, "quantity": str(quantity)} response = sess.get( diff --git a/pittapi/sports.py b/pittapi/sports.py index 01c0a16..e70f8a7 100644 --- a/pittapi/sports.py +++ b/pittapi/sports.py @@ -19,9 +19,7 @@ import requests -FOOTBALL_URL = ( - "http://site.api.espn.com/apis/site/v2/sports/football/college-football/teams/pitt" -) +FOOTBALL_URL = "http://site.api.espn.com/apis/site/v2/sports/football/college-football/teams/pitt" MENS_BASKETBALL_URL = "http://site.api.espn.com/apis/site/v2/sports/basketball/mens-college-basketball/teams/pittsburgh" @@ -49,10 +47,7 @@ def get_next_mens_basketball_game() -> dict: status = None if next_game["competitions"][0]["status"]["type"]["name"] == "STATUS_FINAL": status = "GAME_COMPLETE" - elif ( - next_game["competitions"][0]["status"]["type"]["name"] - == "STATUS_IN_PROGRESS" - ): + elif next_game["competitions"][0]["status"]["type"]["name"] == "STATUS_IN_PROGRESS": status = "IN_PROGRESS" if next_game["competitions"][0]["competitors"][0]["id"] == 221: opponent = next_game["competitions"][0]["competitors"][0] @@ -110,10 +105,7 @@ def get_next_football_game() -> dict: status = None if next_game["competitions"][0]["status"]["type"]["name"] == "STATUS_FINAL": status = "GAME_COMPLETE" - elif ( - next_game["competitions"][0]["status"]["type"]["name"] - == "STATUS_IN_PROGRESS" - ): + elif next_game["competitions"][0]["status"]["type"]["name"] == "STATUS_IN_PROGRESS": status = "IN_PROGRESS" if next_game["competitions"][0]["competitors"][0]["id"] == 221: opponent = next_game["competitions"][0]["competitors"][1] diff --git a/pittapi/textbook.py b/pittapi/textbook.py index 5698f2f..5c4cd66 100644 --- a/pittapi/textbook.py +++ b/pittapi/textbook.py @@ -294,26 +294,15 @@ def _extract_id(response, course: str, instructor: str, section: str) -> str: return _find_course_id_by_instructor(sections, instructor.upper()) except LookupError: error += 2 - raise LookupError( - "Unable to find course by " + LOOKUP_ERRORS[error].format(section, instructor) - ) + raise LookupError("Unable to find course by " + LOOKUP_ERRORS[error].format(section, instructor)) def _extract_books(ids: List[str]) -> List[Dict[str, str]]: """Fetches a course's textbook information and returns a list of textbooks for the given course. """ - responses = grequests.imap( - [ - grequests.get(BASE_URL + _construct_query("books", section_id)) - for section_id in ids - ] - ) - books = [ - _filter_dictionary(book, KEYS) - for response in responses - for book in response.json() - ] + responses = grequests.imap([grequests.get(BASE_URL + _construct_query("books", section_id)) for section_id in ids]) + books = [_filter_dictionary(book, KEYS) for response in responses for book in response.json()] return books @@ -347,9 +336,7 @@ def _get_department_number(department_code: str) -> int: if department_number > 22462: department_number += 2 # between codes DSANE and EAS 2 id numbers are skipped. if department_number > 22580: - department_number += ( - 1 # between codes PUBSRV and REHSCI 1 id number is skipped. - ) + department_number += 1 # between codes PUBSRV and REHSCI 1 id number is skipped. return department_number @@ -359,10 +346,7 @@ def get_textbooks(term: str, courses: List[Dict[str, str]]) -> List[Dict[str, st responses = grequests.map( [ grequests.get( - BASE_URL - + _construct_query( - "courses", _get_department_number(department), _validate_term(term) - ), + BASE_URL + _construct_query("courses", _get_department_number(department), _validate_term(term)), timeout=10, ) for department in departments @@ -383,20 +367,11 @@ def get_textbooks(term: str, courses: List[Dict[str, str]]) -> List[Dict[str, st return _extract_books(section_ids) -def get_textbook( - term: str, department: str, course: str, instructor: str = None, section: str = None -) -> List[Dict[str, str]]: +def get_textbook(term: str, department: str, course: str, instructor: str = None, section: str = None) -> List[Dict[str, str]]: """Retrieves textbooks for a given course.""" has_section_or_instructor = (instructor is not None) or (section is not None) if not has_section_or_instructor: raise TypeError("get_textbook() is missing a instructor or section argument") - response = requests.get( - BASE_URL - + _construct_query( - "courses", _get_department_number(department), _validate_term(term) - ) - ) - section_id = _extract_id( - response, department + _validate_course(course), instructor, section - ) + response = requests.get(BASE_URL + _construct_query("courses", _get_department_number(department), _validate_term(term))) + section_id = _extract_id(response, department + _validate_course(course), instructor, section) return _extract_books([section_id]) diff --git a/tests/course_test.py b/tests/course_test.py index 65c792b..2858ca8 100644 --- a/tests/course_test.py +++ b/tests/course_test.py @@ -46,9 +46,7 @@ class CourseTest(unittest.TestCase): def setUp(self): course._get_subjects = MagicMock(return_value=mocked_subject_data) - course._get_section_details = MagicMock( - return_value=mocked_section_details_data - ) + course._get_section_details = MagicMock(return_value=mocked_section_details_data) def test_validate_term(self): # If convert to string @@ -98,9 +96,7 @@ def test_get_subject_courses(self): self.assertTrue(isinstance(test_course, Course)) def test_get_subject_courses_invalid(self): - course._get_subject_courses = MagicMock( - return_value=mocked_courses_data_invalid - ) + course._get_subject_courses = MagicMock(return_value=mocked_courses_data_invalid) self.assertRaises(ValueError, course.get_subject_courses, "nonsense") course._get_subject_courses.assert_not_called() @@ -108,9 +104,7 @@ def test_get_subject_courses_invalid(self): def test_get_course_details(self): course._get_course_id = MagicMock(return_value="105611") course._get_course_info = MagicMock(return_value=mocked_course_info_data) - course._get_course_sections = MagicMock( - return_value=mocked_course_sections_data - ) + course._get_course_sections = MagicMock(return_value=mocked_course_sections_data) course_sections = course.get_course_details("2231", "CS", "0007") @@ -127,9 +121,7 @@ def test_get_course_details(self): test_attribute = course_sections.attributes[0] self.assertTrue(isinstance(test_attribute, Attribute)) self.assertEqual(test_attribute.attribute, "DSGE") - self.assertEqual( - test_attribute.attribute_description, "*DSAS General Ed. Requirements" - ) + self.assertEqual(test_attribute.attribute_description, "*DSAS General Ed. Requirements") self.assertEqual(test_attribute.value, "ALG") self.assertEqual(test_attribute.value_description, "Algebra") test_section = course_sections.sections[0] @@ -160,9 +152,7 @@ def test_get_course_details(self): self.assertEqual(test_instructor.name, "Robert Fishel") def test_get_section_details(self): - course._get_section_details = MagicMock( - return_value=mocked_section_details_data - ) + course._get_section_details = MagicMock(return_value=mocked_section_details_data) section_details = course.get_section_details("2231", "27815") diff --git a/tests/dining_test.py b/tests/dining_test.py index c12f3a8..e6b96c4 100644 --- a/tests/dining_test.py +++ b/tests/dining_test.py @@ -85,7 +85,5 @@ def test_get_location_menu(self): json=self.dining_menu_data, status=200, ) - locations = dining.get_location_menu( - "The Eatery", datetime.datetime(2024, 4, 12), "Breakfast" - ) + locations = dining.get_location_menu("The Eatery", datetime.datetime(2024, 4, 12), "Breakfast") self.assertIsInstance(locations, dict) diff --git a/tests/people_test.py b/tests/people_test.py index a1980f6..45621fe 100644 --- a/tests/people_test.py +++ b/tests/people_test.py @@ -109,9 +109,7 @@ class PeopleTest(unittest.TestCase): @responses.activate def test_people_get_person(self): - responses.add( - responses.POST, people.PEOPLE_SEARCH_URL, body=RAMIREZ_TEST_DATA, status=200 - ) + responses.add(responses.POST, people.PEOPLE_SEARCH_URL, body=RAMIREZ_TEST_DATA, status=200) ans = people.get_person("John C Ramirez") self.assertIsInstance(ans, list) self.assertTrue(ans[0]["name"] == "Ramirez, John C") diff --git a/tests/sports_test.py b/tests/sports_test.py index a4c5115..979f822 100644 --- a/tests/sports_test.py +++ b/tests/sports_test.py @@ -141,9 +141,7 @@ def setUp(self): "standingSummary": "1st in ACC - Coastal", } } - sports._get_mens_basketball_data = MagicMock( - return_value=mocked_basketball_data - ) + sports._get_mens_basketball_data = MagicMock(return_value=mocked_basketball_data) sports._get_football_data = MagicMock(return_value=mocked_football_data) def test_get_mens_basketball_record(self): @@ -153,9 +151,7 @@ def test_get_mens_basketball_record_offseason(self): offseason_data = {"team": {"id": "221", "record": {}}} sports._get_mens_basketball_data = MagicMock(return_value=offseason_data) - self.assertEqual( - "There's no record right now.", sports.get_mens_basketball_record() - ) + self.assertEqual("There's no record right now.", sports.get_mens_basketball_record()) def test_get_football_record(self): self.assertEqual("10-2", sports.get_football_record()) diff --git a/tests/textbook_test.py b/tests/textbook_test.py index 567f81d..5f8b2b7 100644 --- a/tests/textbook_test.py +++ b/tests/textbook_test.py @@ -49,14 +49,10 @@ def test_textbook_get_textbook(self): json=self.cs_data, status=200, ) - instructor_test = textbook.get_textbook( - term=TERM, department="CS", course="445", instructor="GARRISON III" - ) + instructor_test = textbook.get_textbook(term=TERM, department="CS", course="445", instructor="GARRISON III") instructor_test = textbook.get_textbook(term=TERM, department="CS", course="445", instructor="GARRISON III") - section_test = textbook.get_textbook( - term=TERM, department="CS", course="445", section="1030" - ) + section_test = textbook.get_textbook(term=TERM, department="CS", course="445", section="1030") self.assertIsInstance(instructor_test, list) self.assertIsInstance(section_test, list) @@ -111,7 +107,7 @@ def test_get_textbook_invalid_subject(self): "EXIST", None, ) - + @responses.activate def test_get_textbook_invalid_instructor(self): responses.add( @@ -120,10 +116,8 @@ def test_get_textbook_invalid_instructor(self): json=self.cs_data, status=200, ) - self.assertRaises( - LookupError, textbook.get_textbook, TERM, "CS", "447", "EXIST", None - ) - + self.assertRaises(LookupError, textbook.get_textbook, TERM, "CS", "447", "EXIST", None) + @responses.activate def test_get_textbook_invalid_section(self): responses.add( @@ -132,9 +126,7 @@ def test_get_textbook_invalid_section(self): json=self.cs_data, status=200, ) - self.assertRaises( - LookupError, textbook.get_textbook, TERM, "CS", "401", None, "9999" - ) + self.assertRaises(LookupError, textbook.get_textbook, TERM, "CS", "401", None, "9999") @responses.activate def test_get_textbook_invalid_section_and_instructor(self): @@ -144,9 +136,7 @@ def test_get_textbook_invalid_section_and_instructor(self): json=self.cs_data, status=200, ) - self.assertRaises( - TypeError, textbook.get_textbook, TERM, "CS", "401", None, None - ) + self.assertRaises(TypeError, textbook.get_textbook, TERM, "CS", "401", None, None) def test_term_validation(self): self.assertEqual(self.validate_term(TERM), TERM) @@ -194,7 +184,7 @@ def test_find_item(self): {"id": 4, "key": 16}, {"id": 5, "key": 25}, ] - + for i in range(1, 6): self.assertEqual(find(test_data, i), i**2) @@ -212,11 +202,7 @@ def test_extract_id(self): def test_filter_dictionary(self): test_dict = {"a": 1, "b": 2, "c": 3} test_key = ["a", "c"] - self.assertEqual( - textbook._filter_dictionary(test_dict, test_key), {"a": 1, "c": 3} - ) + self.assertEqual(textbook._filter_dictionary(test_dict, test_key), {"a": 1, "c": 3}) def test_invalid_department_code(self): - self.assertRaises( - ValueError, textbook.get_textbook, TERM, "TEST", "000", "EXIST", None - ) + self.assertRaises(ValueError, textbook.get_textbook, TERM, "TEST", "000", "EXIST", None) From 5e0e14e57cb4096a5da8be6a533f5bc618eb1656 Mon Sep 17 00:00:00 2001 From: Manny McGrail <152332440+ghosteau@users.noreply.github.com> Date: Tue, 11 Jun 2024 07:12:45 -0400 Subject: [PATCH 25/33] Update library.py Co-authored-by: Tianyi Zheng --- pittapi/library.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/pittapi/library.py b/pittapi/library.py index 873f247..8e44bd7 100644 --- a/pittapi/library.py +++ b/pittapi/library.py @@ -147,21 +147,19 @@ def hillman_total_reserved(): def reserved_hillman_times(): """Returns a list of dictionaries of reserved rooms of the Hillman with their respective times""" - bookings = [] - resp = requests.get(STUDY_ROOMS_URL) resp = resp.json() data = resp["data"] if data is None: - return bookings + return [] # Note: there can be multiple reservations in the same room, hence why we must use a list of maps, and cannot just use a singular map - for reservation in data: - bookings.append( - { - "Room": reservation["itemName"], - "Reserved": [reservation["from"], reservation["to"]], - } - ) + bookings = [ + { + "Room": reservation["itemName"], + "Reserved": [reservation["from"], reservation["to"]], + } + for reservation in data + ] return bookings From fecd07e96d13337360ac78c3b9aed56daaef3121 Mon Sep 17 00:00:00 2001 From: Manny Date: Tue, 11 Jun 2024 21:45:40 -0400 Subject: [PATCH 26/33] Added type hints for new functions --- pittapi/library.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/pittapi/library.py b/pittapi/library.py index 8e44bd7..e5c19fd 100644 --- a/pittapi/library.py +++ b/pittapi/library.py @@ -19,7 +19,7 @@ import requests from html.parser import HTMLParser -from typing import Any, Dict, List +from typing import Any, Dict, List, Union LIBRARY_URL = ( "https://pitt.primo.exlibrisgroup.com/primaws/rest/pub/pnxs" @@ -132,7 +132,7 @@ def _extract_facets(facet_fields: List[Dict[str, Any]]) -> Dict[str, List[Dict[s return facets -def hillman_total_reserved(): +def hillman_total_reserved() -> Dict[str, int]: """Returns a simple count dictionary of the total amount of reserved rooms appointments""" count = {} resp = requests.get(STUDY_ROOMS_URL) @@ -144,8 +144,7 @@ def hillman_total_reserved(): count["Total Hillman Reservations"] = total_records return count - -def reserved_hillman_times(): +def reserved_hillman_times() -> List[Dict[str, Union[str, List[str]]]]: """Returns a list of dictionaries of reserved rooms of the Hillman with their respective times""" resp = requests.get(STUDY_ROOMS_URL) resp = resp.json() @@ -162,4 +161,4 @@ def reserved_hillman_times(): } for reservation in data ] - return bookings + return bookings \ No newline at end of file From 309237fa35fbe9434e52e9eebef8060538bd08ff Mon Sep 17 00:00:00 2001 From: Manny Date: Wed, 12 Jun 2024 20:27:07 -0400 Subject: [PATCH 27/33] Polished up formatting in library file - Added space at end of file - Enforced 2 spaces between functions --- pittapi/library.py | 3 ++- tests/library_test.py | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pittapi/library.py b/pittapi/library.py index e5c19fd..a9a28d7 100644 --- a/pittapi/library.py +++ b/pittapi/library.py @@ -144,6 +144,7 @@ def hillman_total_reserved() -> Dict[str, int]: count["Total Hillman Reservations"] = total_records return count + def reserved_hillman_times() -> List[Dict[str, Union[str, List[str]]]]: """Returns a list of dictionaries of reserved rooms of the Hillman with their respective times""" resp = requests.get(STUDY_ROOMS_URL) @@ -161,4 +162,4 @@ def reserved_hillman_times() -> List[Dict[str, Union[str, List[str]]]]: } for reservation in data ] - return bookings \ No newline at end of file + return bookings diff --git a/tests/library_test.py b/tests/library_test.py index 9e5d0f5..fed6def 100644 --- a/tests/library_test.py +++ b/tests/library_test.py @@ -27,6 +27,9 @@ SAMPLE_PATH = Path() / "tests" / "samples" +# Put path to Hillman Library Study Rooms mock response and run unit test +HILLMAN_STUDY_ROOMS_PATH = None + class LibraryTest(unittest.TestCase): def __init__(self, *args, **kwargs): @@ -45,4 +48,4 @@ def test_get_documents(self): query_result = library.get_documents("water") self.assertIsInstance(query_result, dict) self.assertEqual(query_result["pages"], 10) - self.assertEqual(len(query_result["docs"]), 10) + self.assertEqual(len(query_result["docs"]), 10) \ No newline at end of file From ce237fc83ae8bf9e5d75477591674d9370fc66cb Mon Sep 17 00:00:00 2001 From: Manny Date: Thu, 13 Jun 2024 00:33:11 -0400 Subject: [PATCH 28/33] Added unit tests for library module update I added unit tests for both of the new functions and updated the sample path variable. For some reason I was having issues with the original sample path, so I updated it so the testing works good for all functions in the library_test file now. --- tests/library_test.py | 53 ++++++++++++++++-- .../hillman_study_room_mock_response.json | 55 +++++++++++++++++++ 2 files changed, 103 insertions(+), 5 deletions(-) create mode 100644 tests/samples/hillman_study_room_mock_response.json diff --git a/tests/library_test.py b/tests/library_test.py index fed6def..8ec17f1 100644 --- a/tests/library_test.py +++ b/tests/library_test.py @@ -25,10 +25,7 @@ from pittapi import library -SAMPLE_PATH = Path() / "tests" / "samples" - -# Put path to Hillman Library Study Rooms mock response and run unit test -HILLMAN_STUDY_ROOMS_PATH = None +SAMPLE_PATH = Path(__file__).parent / "samples" class LibraryTest(unittest.TestCase): @@ -48,4 +45,50 @@ def test_get_documents(self): query_result = library.get_documents("water") self.assertIsInstance(query_result, dict) self.assertEqual(query_result["pages"], 10) - self.assertEqual(len(query_result["docs"]), 10) \ No newline at end of file + self.assertEqual(len(query_result["docs"]), 10) + + +class StudyRoomTest(unittest.TestCase): + def __init__(self, *args, **kwargs): + unittest.TestCase.__init__(self, *args, **kwargs) + with (SAMPLE_PATH / "hillman_study_room_mock_response.json").open() as f: + self.hillman_query = json.load(f) + + @responses.activate + def test_hillman_total_reserved(self): + responses.add( + responses.GET, + library.STUDY_ROOMS_URL, + json=self.hillman_query, + status=200 + ) + self.assertEqual(library.hillman_total_reserved(), {"Total Hillman Reservations": 4}) + + @responses.activate + def test_reserved_hillman_times(self): + responses.add( + responses.GET, + library.STUDY_ROOMS_URL, + json=self.hillman_query, + status=200 + ) + mock_answer = [ + { + "Room": "408 HL (Max. 5 persons) (Enclosed Room)", + "Reserved": ["2024-06-12 17:30:00", "2024-06-12 20:30:00"] + }, + { + "Room": "409 HL (Max. 5 persons) (Enclosed Room)", + "Reserved": ["2024-06-12 18:00:00", "2024-06-12 21:00:00"] + }, + { + "Room": "303 HL (Max. 5 persons) (Enclosed Room)", + "Reserved": ["2024-06-12 18:30:00", "2024-06-12 21:30:00"] + }, + { + "Room": "217 HL (Max. 10 persons) (Enclosed Room)", + "Reserved": ["2024-06-12 19:00:00", "2024-06-12 22:30:00"] + } + ] + + self.assertEqual(mock_answer, library.reserved_hillman_times()) diff --git a/tests/samples/hillman_study_room_mock_response.json b/tests/samples/hillman_study_room_mock_response.json new file mode 100644 index 0000000..34c04c8 --- /dev/null +++ b/tests/samples/hillman_study_room_mock_response.json @@ -0,0 +1,55 @@ +{ + "data": [ + { + "from": "2024-06-12 17:30:00", + "to": "2024-06-12 20:30:00", + "nickname": "H2P CLUB", + "itemId": 31053, + "itemName": "408 HL (Max. 5 persons) (Enclosed Room)", + "itemHasMoreInfo": true, + "categoryName": "Group Study Spaces", + "categoryUrl": "/spaces?lid=917&gid=1558", + "locationName": "Hillman Library", + "seatName": "" + }, + { + "from": "2024-06-12 18:00:00", + "to": "2024-06-12 21:00:00", + "nickname": "ria", + "itemId": 31055, + "itemName": "409 HL (Max. 5 persons) (Enclosed Room)", + "itemHasMoreInfo": true, + "categoryName": "Group Study Spaces", + "categoryUrl": "/spaces?lid=917&gid=1558", + "locationName": "Hillman Library", + "seatName": "" + }, + { + "from": "2024-06-12 18:30:00", + "to": "2024-06-12 21:30:00", + "nickname": "Leyla", + "itemId": 60964, + "itemName": "303 HL (Max. 5 persons) (Enclosed Room)", + "itemHasMoreInfo": true, + "categoryName": "Group Study Spaces", + "categoryUrl": "/spaces?lid=917&gid=1558", + "locationName": "Hillman Library", + "seatName": "" + }, + { + "from": "2024-06-12 19:00:00", + "to": "2024-06-12 22:30:00", + "nickname": "John 117", + "itemId": 146782, + "itemName": "217 HL (Max. 10 persons) (Enclosed Room)", + "itemHasMoreInfo": true, + "categoryName": "Group Study Spaces", + "categoryUrl": "/spaces?lid=917&gid=1558", + "locationName": "Hillman Library", + "seatName": "" + } + ], + "draw": 1, + "recordsTotal": 4, + "recordsFiltered": 4 +} From 433d00ff46304fa1afcc9e8e9cd4089d11969d90 Mon Sep 17 00:00:00 2001 From: Manny McGrail <152332440+ghosteau@users.noreply.github.com> Date: Thu, 13 Jun 2024 00:35:05 -0400 Subject: [PATCH 29/33] changed spacing for a line --- tests/library_test.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/library_test.py b/tests/library_test.py index 8ec17f1..275cbf1 100644 --- a/tests/library_test.py +++ b/tests/library_test.py @@ -90,5 +90,4 @@ def test_reserved_hillman_times(self): "Reserved": ["2024-06-12 19:00:00", "2024-06-12 22:30:00"] } ] - self.assertEqual(mock_answer, library.reserved_hillman_times()) From 32185c4bc1803421cd4bbbdcf6594b30ab8be904 Mon Sep 17 00:00:00 2001 From: Manny McGrail <152332440+ghosteau@users.noreply.github.com> Date: Thu, 13 Jun 2024 00:58:15 -0400 Subject: [PATCH 30/33] Update tests/library_test.py Co-authored-by: Tianyi Zheng --- tests/library_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/library_test.py b/tests/library_test.py index 275cbf1..8809e7b 100644 --- a/tests/library_test.py +++ b/tests/library_test.py @@ -60,7 +60,7 @@ def test_hillman_total_reserved(self): responses.GET, library.STUDY_ROOMS_URL, json=self.hillman_query, - status=200 + status=200, ) self.assertEqual(library.hillman_total_reserved(), {"Total Hillman Reservations": 4}) From a35cd6826ba52e681cc554c7f99c174e2f270f1d Mon Sep 17 00:00:00 2001 From: Manny McGrail <152332440+ghosteau@users.noreply.github.com> Date: Thu, 13 Jun 2024 00:58:33 -0400 Subject: [PATCH 31/33] Update tests/library_test.py Co-authored-by: Tianyi Zheng --- tests/library_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/library_test.py b/tests/library_test.py index 8809e7b..7d6ab16 100644 --- a/tests/library_test.py +++ b/tests/library_test.py @@ -70,7 +70,7 @@ def test_reserved_hillman_times(self): responses.GET, library.STUDY_ROOMS_URL, json=self.hillman_query, - status=200 + status=200, ) mock_answer = [ { From 0cea09fd4eb3d31e139271156aa8e97294c4c7d8 Mon Sep 17 00:00:00 2001 From: Manny McGrail <152332440+ghosteau@users.noreply.github.com> Date: Thu, 13 Jun 2024 00:58:45 -0400 Subject: [PATCH 32/33] Update tests/library_test.py Co-authored-by: Tianyi Zheng --- tests/library_test.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/library_test.py b/tests/library_test.py index 7d6ab16..b0cf888 100644 --- a/tests/library_test.py +++ b/tests/library_test.py @@ -75,19 +75,19 @@ def test_reserved_hillman_times(self): mock_answer = [ { "Room": "408 HL (Max. 5 persons) (Enclosed Room)", - "Reserved": ["2024-06-12 17:30:00", "2024-06-12 20:30:00"] + "Reserved": ["2024-06-12 17:30:00", "2024-06-12 20:30:00"], }, { "Room": "409 HL (Max. 5 persons) (Enclosed Room)", - "Reserved": ["2024-06-12 18:00:00", "2024-06-12 21:00:00"] + "Reserved": ["2024-06-12 18:00:00", "2024-06-12 21:00:00"], }, { "Room": "303 HL (Max. 5 persons) (Enclosed Room)", - "Reserved": ["2024-06-12 18:30:00", "2024-06-12 21:30:00"] + "Reserved": ["2024-06-12 18:30:00", "2024-06-12 21:30:00"], }, { "Room": "217 HL (Max. 10 persons) (Enclosed Room)", - "Reserved": ["2024-06-12 19:00:00", "2024-06-12 22:30:00"] - } + "Reserved": ["2024-06-12 19:00:00", "2024-06-12 22:30:00"], + }, ] self.assertEqual(mock_answer, library.reserved_hillman_times()) From eb0c45695e6995c7681e4774709ecadbeacee5af Mon Sep 17 00:00:00 2001 From: Tianyi Zheng Date: Wed, 12 Jun 2024 22:09:45 -0700 Subject: [PATCH 33/33] Update type hints --- pittapi/library.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pittapi/library.py b/pittapi/library.py index 790baa7..0692e13 100644 --- a/pittapi/library.py +++ b/pittapi/library.py @@ -17,9 +17,11 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. """ +from __future__ import annotations + import requests from html.parser import HTMLParser -from typing import Any, Dict, List, Union +from typing import Any LIBRARY_URL = ( "https://pitt.primo.exlibrisgroup.com/primaws/rest/pub/pnxs" @@ -132,7 +134,7 @@ def _extract_facets(facet_fields: list[dict[str, Any]]) -> dict[str, list[dict[s return facets -def hillman_total_reserved() -> Dict[str, int]: +def hillman_total_reserved() -> dict[str, int]: """Returns a simple count dictionary of the total amount of reserved rooms appointments""" count = {} resp = requests.get(STUDY_ROOMS_URL) @@ -145,7 +147,7 @@ def hillman_total_reserved() -> Dict[str, int]: return count -def reserved_hillman_times() -> List[Dict[str, Union[str, List[str]]]]: +def reserved_hillman_times() -> list[dict[str, str | list[str]]]: """Returns a list of dictionaries of reserved rooms of the Hillman with their respective times""" resp = requests.get(STUDY_ROOMS_URL) resp = resp.json()