fix: verify date with TDD
- add tests for the function Signed-off-by: Ameya Shenoy <shenoy.ameya@gmail.com>
This commit is contained in:
parent
e7b0cdaf0c
commit
04d46d06b0
3 changed files with 76 additions and 10 deletions
|
|
@ -79,6 +79,12 @@ docker-compose exec backend python manage.py makemigrations
|
||||||
docker-compose exec backend python manage.py migrate
|
docker-compose exec backend python manage.py migrate
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- To run unit tests
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker-compose exec backend python manage.py test
|
||||||
|
```
|
||||||
|
|
||||||
Similarly all django commands can be run this way.
|
Similarly all django commands can be run this way.
|
||||||
|
|
||||||
## Endpoints
|
## Endpoints
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,40 @@
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
from unittest import mock
|
||||||
|
from app.utils import verify_date
|
||||||
|
import datetime
|
||||||
|
|
||||||
# Create your tests here.
|
# Create your tests here.
|
||||||
|
class StubDate(datetime.datetime):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestApp(TestCase):
|
||||||
|
"""Test app utils.
|
||||||
|
|
||||||
|
Publish time: datetime.datetime(2021, 2, 14, 12, 30)
|
||||||
|
"""
|
||||||
|
|
||||||
|
@mock.patch('app.utils.datetime.datetime', StubDate)
|
||||||
|
def test_today_before_publish_time(self):
|
||||||
|
StubDate.now = classmethod(lambda cls: datetime.datetime(2021, 2, 12, 8, 0, 0))
|
||||||
|
date, _ = verify_date('2021-02-14', '')
|
||||||
|
self.assertEqual(date.date(), datetime.datetime(2021, 2, 11).date())
|
||||||
|
|
||||||
|
@mock.patch('app.utils.datetime.datetime', StubDate)
|
||||||
|
def test_today_after_publish_time(self):
|
||||||
|
StubDate.now = classmethod(lambda cls: datetime.datetime(2021, 2, 12, 13, 0, 0))
|
||||||
|
date, _ = verify_date('2021-02-14', '')
|
||||||
|
self.assertEqual(date.date(), datetime.datetime(2021, 2, 12).date())
|
||||||
|
|
||||||
|
@mock.patch('app.utils.datetime.datetime', StubDate)
|
||||||
|
def test_weekend_returns_friday(self):
|
||||||
|
StubDate.now = classmethod(lambda cls: datetime.datetime(2021, 2, 14, 13, 0, 0))
|
||||||
|
date, _ = verify_date('2021-02-14', '')
|
||||||
|
self.assertEqual(date.date(), datetime.datetime(2021, 2, 12).date())
|
||||||
|
|
||||||
|
@mock.patch('app.utils.datetime.datetime', StubDate)
|
||||||
|
def test_a_future_date(self):
|
||||||
|
StubDate.now = classmethod(lambda cls: datetime.datetime(2021, 2, 15, 13, 0, 0))
|
||||||
|
date, _ = verify_date('2021-02-20', '')
|
||||||
|
self.assertEqual(date.date(), datetime.datetime(2021, 2, 15).date())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import csv
|
||||||
import json
|
import json
|
||||||
import datetime
|
import datetime
|
||||||
import logging
|
import logging
|
||||||
|
from typing import Tuple
|
||||||
|
|
||||||
from io import BytesIO, TextIOWrapper
|
from io import BytesIO, TextIOWrapper
|
||||||
from zipfile import ZipFile
|
from zipfile import ZipFile
|
||||||
|
|
@ -114,7 +115,10 @@ def populate_bhav_copy_data_into_postgres(data=None, date=None):
|
||||||
del data[0]
|
del data[0]
|
||||||
if date is None:
|
if date is None:
|
||||||
date = datetime.datetime.now().date()
|
date = datetime.datetime.now().date()
|
||||||
|
# data = stocks_csv_to_json(data)
|
||||||
for stock in data:
|
for stock in data:
|
||||||
|
# stock['date'] = date
|
||||||
|
# BhavCopyEquity.objects.get_or_create(**stock)
|
||||||
BhavCopyEquity.objects.get_or_create(
|
BhavCopyEquity.objects.get_or_create(
|
||||||
date=date,
|
date=date,
|
||||||
sc_code=int(stock[0]),
|
sc_code=int(stock[0]),
|
||||||
|
|
@ -156,17 +160,36 @@ def stocks_csv_to_json(data):
|
||||||
return stocks
|
return stocks
|
||||||
|
|
||||||
|
|
||||||
def verify_date(date, ret_message):
|
def verify_date(date, ret_message) -> Tuple[datetime.datetime, str]:
|
||||||
|
"""Verify current date.
|
||||||
|
|
||||||
|
Check current date and time and return the appropriate date. Also take care
|
||||||
|
of the following usecases
|
||||||
|
- if today before publish time return yesterdays data
|
||||||
|
- if today after publish time return todays data
|
||||||
|
- if a future date, return current day's data with time travel message
|
||||||
|
- if a weekend return Friday's data with custom message
|
||||||
|
"""
|
||||||
# Verify Date
|
# Verify Date
|
||||||
logger.info('Verifying date %s', date)
|
logger.info('Verifying date %s', date)
|
||||||
req_date = datetime.datetime.strptime(date, '%Y-%m-%d')
|
curr_datetime = datetime.datetime.now() - datetime.timedelta(hours=5, minutes=30)
|
||||||
# 18:00 IST == 12:30 UTC
|
req_datetime = datetime.datetime.strptime(date, '%Y-%m-%d')
|
||||||
today = datetime.datetime.now().replace(hour=12, minute=30, second=0, microsecond=0)
|
next_publish_time = curr_datetime.replace(hour=6, minute=0, second=0,
|
||||||
logger.info('Req Date: %s; Today: %s', req_date, today)
|
microsecond=0)
|
||||||
if req_date > today:
|
logger.info('Current IST Datetime: %s; Request Datetime: %s; Next Publish: %s',
|
||||||
|
curr_datetime, req_datetime, next_publish_time)
|
||||||
|
# Check for future date
|
||||||
|
if req_datetime.date() > curr_datetime.date():
|
||||||
ret_message = "Time travel not yet invented! Returning latest available data."
|
ret_message = "Time travel not yet invented! Returning latest available data."
|
||||||
req_date = today
|
req_datetime = curr_datetime
|
||||||
if req_date.date() == today.date() and req_date < today:
|
# Check for weekend
|
||||||
req_date = today - datetime.timedelta(days=1)
|
day_num = req_datetime.weekday()
|
||||||
return req_date, ret_message
|
if day_num in [5, 6]:
|
||||||
|
ret_message = "Markets are closed on weekends. Returning data for Friday."
|
||||||
|
req_datetime -= datetime.timedelta(days=day_num-4) # change req to Friday
|
||||||
|
# Check for day
|
||||||
|
if req_datetime.date() == curr_datetime.date() and curr_datetime < next_publish_time:
|
||||||
|
ret_message = "Today's data not yet published, returning yesterday's data."
|
||||||
|
req_datetime -= datetime.timedelta(days=1)
|
||||||
|
return req_datetime, ret_message
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue