Skip to content
This repository was archived by the owner on Jul 16, 2020. It is now read-only.

Commit fedf99d

Browse files
committed
handle empty schedule listings gracefully; bump versions
1 parent 818ca3c commit fedf99d

File tree

6 files changed

+198
-4
lines changed

6 files changed

+198
-4
lines changed

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "unofficial-umdearborn-catalog-api",
3-
"version": "0.3.0",
3+
"version": "0.3.1",
44
"description": "Unofficial course catalog APIs for the University of Michigan-Dearborn",
55
"main": "./dist/src/library.js",
66
"typings": "./src/library.ts",

src/parsers/schedule-listing.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,9 @@ const emptySectionResult: SectionTableParseResult = {
8181
times: [],
8282
};
8383

84-
function parseSectionElement(body: HTMLTableRowElement) {
84+
function parseSectionElement(body: HTMLTableRowElement | undefined | null) {
85+
if (!body) { return emptySectionResult; }
86+
8587
const sectionTBody = body.querySelector('.datadisplaytable > tbody');
8688
if (!sectionTBody) { return emptySectionResult; }
8789

swagger.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
openapi: 3.0.0
22
info:
33
title: Unofficial UMDearborn Catalog API
4-
version: 0.3.0
4+
version: 0.3.1
55
components:
66
schemas:
77
term:
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/transitional.dtd">
2+
<HTML lang="en">
3+
<head>
4+
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
5+
<LINK REL="stylesheet" HREF="/css/web_defaultapp.css" TYPE="text/css">
6+
<LINK REL="stylesheet" HREF="/css/web_defaultprint.css" TYPE="text/css" media="print">
7+
<link rel="stylesheet" type="text/css" href="/css/app-overrides.css">
8+
<link rel="stylesheet" type="text/css" href="/css/common-platform.css">
9+
<link rel="stylesheet" type="text/css" href="/css/common-controls.css">
10+
<LINK REL="stylesheet" type="text/css" href="/css/jquery/jquery.autocomplete.css">
11+
<LINK REL="stylesheet" type="text/css" href="/css/cascade.css">
12+
<!--[if IE 6]><link href="/css/ie6.css" rel="stylesheet" type="text/css"><![endif]-->
13+
<!--[if IE 7]><link href="/css/ie7.css" rel="stylesheet" type="text/css"><![endif]-->
14+
<!--[if IE 8]><link href="/css/ie8.css" rel="stylesheet" type="text/css"><![endif]-->
15+
<LINK REL="stylesheet" type="text/css" href="/css/cascade-print.css" media="print">
16+
<script type="text/javascript" src="/js/jquery-1.6.1.min.js"></script>
17+
<script type="text/javascript" src="/js/jquery/jquery.includeMany-1.2.0.js"></script>
18+
<script type="text/javascript" src="/js/jquery/jquery.history.js"></script>
19+
<script type="text/javascript" src="/js/jquery/jquery-ui-personalized-1.5.3.js"></script>
20+
<script type="text/javascript" src="/js/jquery/jquery.colorpicker.js"></script>
21+
<script type="text/javascript" src="/js/jquery/jquery.autocomplete.js"></script>
22+
<script type="text/javascript" src="/js/jquery/jquery.form.js"></script>
23+
<script type="text/javascript" src="/js/jquery/json2xml.js"></script>
24+
<script type="text/javascript" src="/js/jquery/jquery.jsonp-2.1.3.min.js"></script>
25+
<script type="text/javascript" src="/js/serviceProperties.js"></script>
26+
<script type="text/javascript" src="/js/common-controls-min.js"></script>
27+
<script type="text/javascript" src="/js/common-integrate-min.js"></script>
28+
<script type="text/javascript" src="/js/common-navigation-min.js"></script>
29+
<script type="text/javascript" src="/js/common-platform-min.js"></script>
30+
<script type="text/javascript" src="/js/cascade-utils-min.js"></script>
31+
<script type="text/javascript" src="/js/cascade-controls-min.js"></script>
32+
<script type="text/javascript" src="/js/udcxml-service-min.js"></script>
33+
<script type="text/javascript" src="/js/cascade-parser-min.js"></script>
34+
<script type="text/javascript" src="/js/cascade-ext-min.js"></script>
35+
<title>Class Schedule Listing</title>
36+
<meta http-equiv="Content-Script-Type" name="Default_Script_Language" content="text/javascript">
37+
<SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript">
38+
<!-- Hide JavaScript from older browsers
39+
window.onunload = function() {submitcount=0;}
40+
var submitcount=0;
41+
function checkSubmit() {
42+
if (submitcount == 0)
43+
{
44+
submitcount++;
45+
return true;
46+
}
47+
else
48+
{
49+
alert("Your changes have already been submitted.");
50+
return false;
51+
}
52+
}
53+
// End script hiding -->
54+
</SCRIPT>
55+
<SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript">
56+
<!-- Hide JavaScript from older browsers
57+
// Function to open a window
58+
function windowOpen(window_url) {
59+
helpWin = window.open(window_url,'','toolbar=yes,status=no,scrollbars=yes,menubar=yes,resizable=yes,directories=no,location=no,width=350,height=400');
60+
if (document.images) {
61+
if (helpWin) helpWin.focus()
62+
}
63+
}
64+
// End script hiding -->
65+
</SCRIPT>
66+
<SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript">
67+
<!-- Hide JavaScript from older browsers
68+
var level_depth = "0";
69+
var userDetails = "";
70+
var wcMessage = "";
71+
var locale_val = "AMERICAN_AMERICA";
72+
var locale_lang = "en_US";
73+
var help_width= "450";
74+
var help_height = "500";
75+
// End script hiding -->
76+
</SCRIPT>
77+
</head>
78+
<body>
79+
<div id="headerImage">
80+
<img src="/wtlgifs/UMD_header_logo.gif" CLASS="headerImg" TITLE="" NAME="UMD Wordmark" HSPACE=0 VSPACE=0 BORDER=0 HEIGHT=78 WIDTH=550 />
81+
</div>
82+
<div class="headerwrapperdiv">
83+
<div class="pageheaderdiv1">
84+
<a href="#main_content" onMouseover="window.status='Go to Main Content'; return true" onMouseout="window.status=''; return true" OnFocus="window.status='Go to Main Content'; return true" onBlur="window.status=''; return true" class="skiplinks">Go to Main Content</a>
85+
<h1>Univ. of Mich. Dearborn (BANP)</h1></DIV><div class="headerlinksdiv">
86+
</DIV>
87+
<table CLASS="plaintable" SUMMARY="This table displays Menu Items and Banner Search textbox."
88+
WIDTH="100%">
89+
<tr>
90+
<TD CLASS="pldefault">
91+
<div class="headerlinksdiv2">
92+
&nbsp;
93+
</div>
94+
</TD>
95+
<TD CLASS="pldefault"><p class="rightaligntext"></p>
96+
<SPAN class="pageheaderlinks">
97+
<a href="/wtlhelp/twbhhelp.htm" accesskey="H" onClick="popup = window.open('/wtlhelp/twbhhelp.htm', 'PopupPage','height=500,width=450,scrollbars=yes,resizable=yes'); return false" target="_blank" onMouseOver="window.status=''; return true" onMouseOut="window.status=''; return true"onFocus="window.status=''; return true" onBlur="window.status=''; return true" class="submenulinktext2">HELP</a>
98+
|
99+
<a href="twbkwbis.P_Logout" accesskey="3" class="submenulinktext2">EXIT</a>
100+
</span>
101+
</TD>
102+
</tr>
103+
</table>
104+
</DIV>
105+
<div class="pagetitlediv">
106+
<table CLASS="plaintable" SUMMARY="This table displays title and static header displays."
107+
WIDTH="100%">
108+
<tr>
109+
<TD CLASS="pldefault">
110+
<h2>Class Schedule Listing</h2>
111+
</TD>
112+
<TD CLASS="pldefault">
113+
&nbsp;
114+
</TD>
115+
<TD CLASS="pldefault"><p class="rightaligntext"></p>
116+
<div class="staticheaders">
117+
Fall 2017<br>
118+
09-FEB-2018<br>
119+
</div>
120+
</TD>
121+
</tr>
122+
<tr>
123+
<TD class="bg3" width="100%" colSpan=3><img src="/wtlgifs/web_transparent.gif" alt="Transparent Image" CLASS="headerImg" TITLE="Transparent Image" NAME="web_transparent" HSPACE=0 VSPACE=0 BORDER=0 HEIGHT=3 WIDTH=10 /></TD>
124+
</tr>
125+
</table>
126+
<a name="main_content"></a>
127+
</DIV>
128+
<div class="pagebodydiv">
129+
<!-- ** END OF twbkwbis.P_OpenDoc ** -->
130+
<br />
131+
132+
<input type="hidden" name="sel_crn" value="dummy" />
133+
<input type="hidden" name="assoc_term_in" value="dummy" />
134+
<input type="hidden" name="ADD_BTN" value="dummy" />
135+
</table>
136+
<br />
137+
<table CLASS="plaintable" summary="This layout table holds message information">
138+
<tr>
139+
<TD CLASS="pldefault">
140+
&nbsp;
141+
</TD>
142+
<TD CLASS="pldefault">
143+
No classes were found that meet your search criteria
144+
<br />
145+
</TD>
146+
</tr>
147+
</table>
148+
<br />
149+
<table CLASS="datadisplaytable" summary="This is for formatting of the bottom links." WIDTH="50%">
150+
<tr>
151+
<TD CLASS="ntdefault">
152+
<a href="javascript:history.go(-1)" onMouseOver="window.status='Return to Previous'; return true" onFocus="window.status='Return to Previous'; return true" onMouseOut="window.status=''; return true"onBlur="window.status=''; return true">Return to Previous</a>
153+
</TD>
154+
</tr>
155+
</table>
156+
157+
<!-- ** START OF twbkwbis.P_CloseDoc ** -->
158+
<table CLASS="plaintable" SUMMARY="This is table displays line separator at end of the page."
159+
WIDTH="100%" cellSpacing=0 cellPadding=0 border=0><tr><TD class="bgtabon" width="100%" colSpan=2><img src="/wtlgifs/web_transparent.gif" alt="Transparent Image" CLASS="headerImg" TITLE="Transparent Image" NAME="web_transparent" HSPACE=0 VSPACE=0 BORDER=0 HEIGHT=3 WIDTH=10 /></TD></tr></table>
160+
<a href="#top" onMouseover="window.status='Skip to top of page'; return true" onMouseout="window.status=''; return true" OnFocus="window.status='Skip to top of page'; return true" onBlur="window.status=''; return true" class="skiplinks">Skip to top of page</a>
161+
</DIV>
162+
<div class="footerafterdiv">
163+
164+
</DIV>
165+
<div class="globalafterdiv">
166+
167+
</DIV>
168+
<div class="globalfooterdiv">
169+
170+
</DIV>
171+
<div class="pagefooterdiv">
172+
<SPAN class="releasetext">Release: 8.7.2</SPAN>
173+
</DIV>
174+
<div class="poweredbydiv">
175+
</DIV>
176+
<DIV class="div1"></DIV>
177+
<DIV class="div2"></DIV>
178+
<DIV class="div3"></DIV>
179+
<DIV class="div4"></DIV>
180+
<DIV class="div5"></DIV>
181+
<DIV class="div6"></DIV>
182+
<div class="banner_copyright"></div>
183+
</body>
184+
</html>

test/parsers/schedule-listing.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ const scheduleListingsHtml = fs.readFileSync(
99
const scheduleListingsHtmlWithNoMeetingTimes = fs.readFileSync(
1010
path.resolve(__dirname, '../example-pages/schedule-listing-with-no-meeting-times.html')
1111
).toString();
12+
const scheduleListingsHtmlEmpty = fs.readFileSync(
13+
path.resolve(__dirname, '../example-pages/schedule-listing-empty.html')
14+
).toString();
1215

1316
describe(`schedule listing parser`, function () {
1417
it(`parsers 'schedule-listings.html'`, function () {
@@ -115,4 +118,9 @@ describe(`schedule listing parser`, function () {
115118

116119
expect(result).to.deep.equal(expectedResult);
117120
});
121+
122+
it(`should handle empty schedule listings gracefully`, function () {
123+
const result = parseScheduleListing(scheduleListingsHtmlEmpty);
124+
expect(result).to.be.empty;
125+
});
118126
});

0 commit comments

Comments
 (0)