Repository: codeforpdx/recordexpungpdx
Issue: Birth year should default to an empty string

## Description
Birth year is not present on all case files and we're seeing some failures here: https://github.com/codeforpdx/recordexpungPDX/blob/master/src/backend/expungeservice/models/case.py#L7 

Need to update this so that Birth year defaults to an empty string when it is not present.

### This task is done when:
 - Create test case to expose bug (probably two tests: unit and functional)
 - Implement fix
 
<!---
Before submitting this issue:

- If someone is currently working on this issue, assign it to them
- Add labels as appropriate 
- Add this issue to our Record Expunge PDX Project

After the issue is created, visit https://github.com/codeforpdx/recordexpungPDX/projects/2 and add the issue to the appropriate column depending on its status. The issue should be moved across from left to right as it progresses.
--->


Changed files:
src/backend/tests/parser/test_record_parser.py, src/backend/expungeservice/models/case.py, src/backend/tests/models/test_case.py, src/backend/tests/fixtures/john_doe.py, src/backend/tests/factories/case_factory.py

diff --git a/src/backend/expungeservice/models/case.py b/src/backend/expungeservice/models/case.py
index 96776bd8..5ee858cb 100644
--- a/src/backend/expungeservice/models/case.py
+++ b/src/backend/expungeservice/models/case.py
@@ -4,8 +4,8 @@ from datetime import datetime
 class Case:
 
     def __init__(self, info, case_number, citation_number, date_location, type_status, charges, case_detail_link):
-        self.name, birth_year = info
-        self.birth_year = int(birth_year)
+        self.name = info[0]
+        self.birth_year = self._set_birth_year(info)
         self.case_number = case_number
         self.citation_number = citation_number[0] if citation_number else ""
         date, self.location = date_location
@@ -25,3 +25,10 @@ class Case:
 
     def closed(self):
         return self.current_status == 'Closed' or self.current_status == 'Inactive'
+
+    @staticmethod
+    def _set_birth_year(info):
+        if len(info) > 1:
+            return int(info[1])
+        else:
+            return ''
diff --git a/src/backend/tests/factories/case_factory.py b/src/backend/tests/factories/case_factory.py
index de8239de..6aa4bbb7 100644
--- a/src/backend/tests/factories/case_factory.py
+++ b/src/backend/tests/factories/case_factory.py
@@ -13,3 +13,19 @@ class CaseFactory:
                case_detail_link='?404'):
 
         return Case(info, case_number, citation_number, date_location, type_status, charges, case_detail_link)
+
+    @staticmethod
+    def build():
+        return {
+            'info': ['John Doe', '1990'],
+            'case_number': 'C0000',
+            'citation_number': None,
+            'date_location': ['1/1/1995', 'Multnomah'],
+            'type_status': ['Offense Misdemeanor', 'Closed'],
+            'charges': [],
+            'case_detail_link': '?404'
+                }
+
+    @staticmethod
+    def save(case):
+        return Case(**case)
\\ No newline at end of file
diff --git a/src/backend/tests/fixtures/john_doe.py b/src/backend/tests/fixtures/john_doe.py
index 99de1ffd..22eadcfa 100644
--- a/src/backend/tests/fixtures/john_doe.py
+++ b/src/backend/tests/fixtures/john_doe.py
@@ -45,3 +45,15 @@ class JohnDoe:
   </body>
 </html>
     '''
+
+    RECORD_WITH_MISSING_BIRTH_YEAR = '''
+<html>
+  <head>
+    <link rel="stylesheet" type="text/css" href="CSS/PublicAccess.css">
+  </head>
+  <body>
+    <?xml version="1.0" encoding="utf-8"?><table cellspacing="0" cellpadding="0" width="100%" border="0" style="table-layout: fixed; margin:0px; padding:0px;"><tr><td class="ssHeaderTitleBanner">Criminal, Traffic and Parking Case Records Search Results</td></tr></table><table cellspacing="0" cellpadding="0" width="100%" border="0" style="table-layout: fixed; margin:0px; padding:0px;"><tr><td bgcolor="#000000" height="20px"><table cellspacing="0" cellpadding="0" width="100%" border="0"><tr><td align="left" style="padding-left: 5px"><font size="1"><a class="ssBlackNavBarHyperlink" href="#MainContent">Skip to Main Content</a>&nbsp;<a class="ssBlackNavBarHyperlink" href="logout.aspx">Logout</a>&nbsp;<a class="ssBlackNavBarHyperlink" href="MyAccount.aspx?ReturnURL=default.aspx">My Account</a>&nbsp;<a class="ssBlackNavBarHyperlink" href="default.aspx">Search Menu</a>&nbsp;<a class="ssBlackNavBarHyperlink" href="Search.aspx?ID=100">Search Criminal, Traffic and Parking Case Records</a>&nbsp;<a class="ssBlackNavBarHyperlink" href="Search.aspx?ID=100&amp;RefineSearch=1">Refine Search</a>&nbsp;</font></td><td align="center" class="ssBlackNavBarLocation"></td><td align="right" style="padding-right: 10px"><table cellspacing="0" cellpadding="0" border="0"><tr><td class="ssBlackNavBarLocation">
+                          Location : All Locations</td><td><font size="1"><a class="ssBlackNavBarHyperlink" target="_blank" href="#">Help</a></font></td></tr></table></td></tr></table></td></tr></table><a id="MainContent" name="MainContent" tabindex="-1"></a><table border="0" cellpadding="0" cellspacing="0" width="100%" style="table-layout: fixed; font-size: 8pt; font-family: arial"><tr><td style="width:85px;"><b>Record Count: </b></td><td style="text-align:left;"><b>168</b></td></tr><tr><td id="SearchParamList" colspan="2"><b>Search By:</b> Defendant&nbsp;&nbsp;&nbsp;<b>Exact Name:</b> on&nbsp;&nbsp;&nbsp;<b>Party Search Mode:</b> Name&nbsp;&nbsp;&nbsp;<b>Last Name:</b> doe&nbsp;&nbsp;&nbsp;<b>First Name:</b> john&nbsp;&nbsp;&nbsp;<b>All</b> All&nbsp;&nbsp;&nbsp;<b>Sort By:</b> Filed Date&nbsp;&nbsp;&nbsp;</td></tr></table><table border="0" cellpadding="2" cellspacing="0" width="100%" style="font-size: 8pt; font-family: arial"><col width="15%" /><col width="15%" /><col width="15%" /><col width="15%" /><col width="15%" /><col width="25%" /><tr><th class="ssSearchResultHeader" nowrap="true"><b>Case Number</b></th><th class="ssSearchResultHeader" nowrap="true"><b>Citation Number</b></th><th class="ssSearchResultHeader" nowrap="true"><b>Defendant Info</b></th><th class="ssSearchResultHeader" nowrap="true"><b>Filed/Location</b></th><th class="ssSearchResultHeader" nowrap="true"><b>Type</b><b>/Status</b></th><th class="ssSearchResultHeader" nowrap="true"><table border="0" cellpadding="0" cellspacing="0" width="100%" style="table-layout: fixed; font-size: 8pt; font-family: arial"><tr><td><b>Charge(s)</b></td></tr></table></th></tr><tr height="3"><td colspan="6"></td></tr><tr><td nowrap="true" valign="top"><a href="CaseDetail.aspx?CaseID=X0001" style="color: blue">X0001</a></td><td nowrap="true" valign="top"><div style="overflow:hidden">C0001</div><div style="overflow:hidden">C0001</div><div style="overflow:hidden">C0001</div></td><td nowrap="true" valign="top"><div>Doe, John D</div><div>1943</div></td><td valign="top" nowrap="true"><div>03/23/1963</div><div>Multnomah</div></td><td valign="top" nowrap="true"><div>Offense Misdemeanor</div><div>Closed</div></td><td nowrap="true" valign="top"><table border="0" cellpadding="0" cellspacing="0" width="100%" style="table-layout: fixed; font-size: 8pt; font-family: arial"><tr><td style="vertical-align:top;">Attempt to Commit a Class C/Unclassified Felony</td></tr><tr><td style="vertical-align:top;">Drug Free Zone Variance</td></tr><tr><td style="vertical-align:top;">Criminal Trespass in the Second Degree</td></tr></table></td></tr><tr bgcolor="#EEEEEE"><td nowrap="true" valign="top"><a href="CaseDetail.aspx?CaseID=X0002" style="color: blue">X0002</a></td><td nowrap="true" valign="top"><div style="overflow:hidden">C0002</div><div style="overflow:hidden">C0002</div></td><td nowrap="true" valign="top"><div>Doe, John D</div><div>1943</div></td><td valign="top" nowrap="true"><div>04/11/1963</div><div>Multnomah</div></td><td valign="top" nowrap="true"><div>Offense Felony</div><div>Closed</div></td><td nowrap="true" valign="top"><table border="0" cellpadding="0" cellspacing="0" width="100%" style="table-layout: fixed; font-size: 8pt; font-family: arial"><tr><td style="vertical-align:top;">Poss Controlled Sub 2 (Reduced - to A Misdemeanor)</td></tr><tr><td style="vertical-align:top;">Drug Free Zone Variance</td></tr></table></td></tr><tr><td nowrap="true" valign="top"><a href="CaseDetail.aspx?CaseID=X0003" style="color: blue">X0003</a></td><td nowrap="true" valign="top"><div style="overflow:hidden"></div></td><td nowrap="true" valign="top"><div>Doe, John D</div><div></div></td><td valign="top" nowrap="true"><div>04/01/2012</div><div>Multnomah</div></td><td valign="top" nowrap="true"><div>Offense Misdemeanor</div><div>Open</div></td><td nowrap="true" valign="top"><table border="0" cellpadding="0" cellspacing="0" width="100%" style="table-layout: fixed; font-size: 8pt; font-family: arial"><tr><td style="vertical-align:top;">Poss Controlled Sub 2 (Reduced - to A Misdemeanor)</td></tr></table></td></tr></table>
+  </body>
+</html>
+    '''
diff --git a/src/backend/tests/models/test_case.py b/src/backend/tests/models/test_case.py
index c9aa384d..8ca8aafb 100644
--- a/src/backend/tests/models/test_case.py
+++ b/src/backend/tests/models/test_case.py
@@ -40,3 +40,14 @@ class TestCaseClosedMethod(unittest.TestCase):
     def test_it_returns_true_for_an_inactive_case(self):
         self.case.current_status = 'Inactive'
         assert self.case.closed() is True
+
+
+class TestBirthYearDefaultValue(unittest.TestCase):
+    def setUp(self):
+        self.case = CaseFactory.build()
+
+    def test_birth_year_defaults_to_empty_string(self):
+        self.case['info'] = ['John Doe']
+        case = CaseFactory.save(self.case)
+
+        assert case.birth_year == ''
diff --git a/src/backend/tests/parser/test_record_parser.py b/src/backend/tests/parser/test_record_parser.py
index 0a2c5c23..84c1bfbb 100644
--- a/src/backend/tests/parser/test_record_parser.py
+++ b/src/backend/tests/parser/test_record_parser.py
@@ -73,3 +73,14 @@ class TestEmptyRecord(unittest.TestCase):
         parser.feed(JohnDoe.BLANK_RECORD)
 
         assert len(parser.cases) == 0
+
+
+class TestRecordWithoutBirthYear(unittest.TestCase):
+
+    def test_it_assigns_birth_year(self):
+        parser = RecordParser()
+        parser.feed(JohnDoe.RECORD_WITH_MISSING_BIRTH_YEAR)
+
+        assert parser.cases[0].birth_year == 1943
+        assert parser.cases[1].birth_year == 1943
+        assert parser.cases[2].birth_year == ''