From 64f63aa0b653b57cd5e920b6010af191ed2f51ba Mon Sep 17 00:00:00 2001
From: Bob Mottram <bob@freedombone.net>
Date: Wed, 28 Jul 2021 10:35:21 +0100
Subject: [PATCH] Unit test for date conversion

---
 shares.py | 28 +++++++++++++---------------
 tests.py  | 13 ++++++++++++-
 utils.py  | 18 ++++++++++++++++++
 3 files changed, 43 insertions(+), 16 deletions(-)

diff --git a/shares.py b/shares.py
index 805427afb..ec76ce0e9 100644
--- a/shares.py
+++ b/shares.py
@@ -20,6 +20,8 @@ from posts import getPersonBox
 from session import postJson
 from session import postImage
 from session import createSession
+from utils import dateStringToSeconds
+from utils import dateSecondsToString
 from utils import getConfigParam
 from utils import getFullDomain
 from utils import validNickname
@@ -924,10 +926,8 @@ def sharesCatalogEndpoint(baseDir: str, httpPrefix: str,
                     if not re.match(matchPattern, description):
                         continue
 
-                expireDate = \
-                    datetime.datetime.fromtimestamp(item['expire'])
-                expireDateStr = expireDate.strftime("%Y-%m-%dT%H:%M:%SZ")
-
+                startDateStr = dateSecondsToString(item['published'])
+                expireDateStr = dateSecondsToString(item['expire'])
                 shareId = getValidSharedItemID(owner, item['displayName'])
                 if item['dfcId'].startswith('epicyon#'):
                     dfcId = "epicyon:" + item['dfcId'].split('#')[1]
@@ -938,7 +938,7 @@ def sharesCatalogEndpoint(baseDir: str, httpPrefix: str,
                     "@id": shareId,
                     "@type": "DFC:SuppliedProduct",
                     "DFC:hasType": dfcId,
-                    "DFC:startDate": item['published'],
+                    "DFC:startDate": startDateStr,
                     "DFC:expiryDate": expireDateStr,
                     "DFC:quantity": item['itemQty'],
                     "DFC:price": priceStr,
@@ -1280,15 +1280,13 @@ def _dfcToSharesFormat(catalogJson: {},
         if ':' not in item['DFC:hasType']:
             continue
 
-        try:
-            expiryTime = \
-                datetime.datetime.strptime(item['DFC:expiryDate'],
-                                           '%Y-%m-%dT%H:%M:%SZ')
-        except BaseException:
+        startTimeSec = dateStringToSeconds(item['DFC:startDate'])
+        if not startTimeSec:
             continue
-        durationSec = \
-            int((expiryTime - datetime.datetime(1970, 1, 1)).total_seconds())
-        if durationSec < currTime:
+        expiryTimeSec = dateStringToSeconds(item['DFC:expiryDate'])
+        if not expiryTimeSec:
+            continue
+        if expiryTimeSec < currTime:
             # has expired
             continue
 
@@ -1314,8 +1312,8 @@ def _dfcToSharesFormat(catalogJson: {},
             "itemType": itemType,
             "category": itemCategory,
             "location": "",
-            "published": item['DFC:startDate'],
-            "expire": durationSec,
+            "published": startTimeSec,
+            "expire": expiryTimeSec,
             "itemPrice": item['DFC:price'].split(' ')[0],
             "itemCurrency": item['DFC:price'].split(' ')[1]
         }
diff --git a/tests.py b/tests.py
index 25ac98858..313db4994 100644
--- a/tests.py
+++ b/tests.py
@@ -39,6 +39,8 @@ from follow import clearFollowers
 from follow import sendFollowRequestViaServer
 from follow import sendUnfollowRequestViaServer
 from siteactive import siteIsActive
+from utils import dateStringToSeconds
+from utils import dateSecondsToString
 from utils import validPassword
 from utils import userAgentDomain
 from utils import camelCaseSplit
@@ -4318,9 +4320,19 @@ def _testAuthorizeSharedItems():
     assert len(tokensJson['possum.domain']) == 0
 
 
+def _testDateConversions() -> None:
+    print('testDateConversions')
+    dateStr = "2021-05-16T14:37:41Z"
+    dateSec = dateStringToSeconds(dateStr)
+    dateStr2 = dateSecondsToString(dateSec)
+    assert dateStr == dateStr2
+
+
 def runAllTests():
     print('Running tests...')
     updateDefaultThemesList(os.getcwd())
+    _testFunctions()
+    _testDateConversions()
     _testAuthorizeSharedItems()
     _testValidPassword()
     _testGetLinksFromContent()
@@ -4328,7 +4340,6 @@ def runAllTests():
     _testLimitRepetedWords()
     _testLimitWordLengths()
     _testSwitchWords()
-    _testFunctions()
     _testUserAgentDomain()
     _testRoles()
     _testSkills()
diff --git a/utils.py b/utils.py
index b11334770..1bba33098 100644
--- a/utils.py
+++ b/utils.py
@@ -2634,3 +2634,21 @@ def isfloat(value):
         return True
     except ValueError:
         return False
+
+
+def dateStringToSeconds(dateStr: str) -> int:
+    """Converts a date string (eg "published") into seconds since epoch
+    """
+    try:
+        expiryTime = \
+            datetime.datetime.strptime(dateStr, '%Y-%m-%dT%H:%M:%SZ')
+    except BaseException:
+        return None
+    return int(datetime.datetime.timestamp(expiryTime))
+
+
+def dateSecondsToString(dateSec: int) -> str:
+    """Converts a date in seconds since epoch to a string
+    """
+    thisDate = datetime.datetime.fromtimestamp(dateSec)
+    return thisDate.strftime("%Y-%m-%dT%H:%M:%SZ")