Merge pull request #112 from danieldupriest/policy-tests
Implemented tests for all policy file rules and fixed more policy bugs
This commit is contained in:
commit
86055b38e2
4 changed files with 95 additions and 17 deletions
|
@ -1,8 +1,11 @@
|
||||||
from datetime import date
|
import datetime
|
||||||
|
|
||||||
#### Classes for policy, sections. Do not edit these.
|
#### Classes for policy, sections. Do not edit these.
|
||||||
#####################################################
|
#####################################################
|
||||||
|
|
||||||
|
def to_date(iso8601):
|
||||||
|
return datetime.datetime.strptime(iso8601, "%Y-%m-%d")
|
||||||
|
|
||||||
class Policy():
|
class Policy():
|
||||||
"""
|
"""
|
||||||
Represents the policy for the company/organization.
|
Represents the policy for the company/organization.
|
||||||
|
@ -127,17 +130,17 @@ def lowest_fare_rule(report, fields):
|
||||||
maximum = lowest_fare + 350
|
maximum = lowest_fare + 350
|
||||||
else:
|
else:
|
||||||
maximum = lowest_fare + 600
|
maximum = lowest_fare + 600
|
||||||
if fields['preferred_fare'] > maximum:
|
if fields['preferred_flight_fare'] > maximum:
|
||||||
return "For the lowest fare you have provided, your maximum in-policy fare amount is {} USD.".format(maximum)
|
return "For the lowest fare you have provided, your maximum in-policy fare amount is {} USD.".format(maximum)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
planning_section.add_rule(title="Lowest fare check", rule=lowest_fare_rule)
|
planning_section.add_rule(title="Lowest fare check", rule=lowest_fare_rule)
|
||||||
|
|
||||||
def departure_date_limit_rule(report, fields):
|
def departure_date_limit_rule(report, fields):
|
||||||
days_to_departure = date(fields['departure_date']) - date(fields['screenshot_date'])
|
days_to_departure = to_date(fields['departure_date']) - to_date(fields['screenshot_date'])
|
||||||
if days_to_departure < 14:
|
if days_to_departure < datetime.timedelta(days=14):
|
||||||
return "Flights must be booked at least 14 days in advance."
|
return "Flights must be booked at least 14 days in advance."
|
||||||
if days_to_departure > 365:
|
if days_to_departure > datetime.timedelta(days=365):
|
||||||
return "Flights must be booked no more than 365 days in advance."
|
return "Flights must be booked no more than 365 days in advance."
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -173,9 +176,9 @@ def actual_fare_limit_rule(report, fields):
|
||||||
flight_section.add_rule(title="Fare limits", rule=actual_fare_limit_rule)
|
flight_section.add_rule(title="Fare limits", rule=actual_fare_limit_rule)
|
||||||
|
|
||||||
def request_date_rule(report, fields):
|
def request_date_rule(report, fields):
|
||||||
now = date.today()
|
now = datetime.datetime.now()
|
||||||
last_travel = date(fields['return_date'])
|
last_travel = to_date(fields['return_date'])
|
||||||
if now - last_travel > 90:
|
if now - last_travel > datetime.timedelta(days=90):
|
||||||
return "Reimbursement requests must be made within 90 days of the last day of travel."
|
return "Reimbursement requests must be made within 90 days of the last day of travel."
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -198,9 +201,9 @@ lodging_section = Section(
|
||||||
)
|
)
|
||||||
|
|
||||||
def nightly_rate_check(report, fields):
|
def nightly_rate_check(report, fields):
|
||||||
checkin_date = date(fields['check_in_date'])
|
check_in_date = to_date(fields['check_in_date'])
|
||||||
checkout_date = date(fields['check_out_date'])
|
check_out_date = to_date(fields['check_out_date'])
|
||||||
duration = checkout_date - checkin_date
|
duration = (check_out_date - check_in_date).days
|
||||||
if fields['cost'] > duration * fields['per_diem_rate']:
|
if fields['cost'] > duration * fields['per_diem_rate']:
|
||||||
return "The average nightly rate cannot exceed the U.S. GSA rate."
|
return "The average nightly rate cannot exceed the U.S. GSA rate."
|
||||||
return None
|
return None
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
from policy import pol
|
|
||||||
|
|
||||||
print(pol)
|
|
81
back/backend/test_policy.py
Normal file
81
back/backend/test_policy.py
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
from django.test import TestCase
|
||||||
|
from .policy import pol
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
|
class PolicyTests(TestCase):
|
||||||
|
report = {"key":"value"}
|
||||||
|
|
||||||
|
def test_general_section_pre_post_trip_check(self):
|
||||||
|
fields = {'after_trip':True}
|
||||||
|
result = pol.sections[0].rules[0]['rule'](self.report, fields)
|
||||||
|
self.assertEqual(result, "If you have already take the trip your request will require special approval by the administrator. You may skip the following 'Pre-trip Planning' section.")
|
||||||
|
|
||||||
|
def test_pre_flight_section_fare_limit_domestic(self):
|
||||||
|
fields = {'preferred_flight_fare':751,'international_flight':False}
|
||||||
|
result = pol.sections[1].rules[0]['rule'](self.report, fields)
|
||||||
|
self.assertEqual(result, "Fares for domestic flights over 750 USD require Conservancy pre-approval, even if other policy conditions have been met.")
|
||||||
|
|
||||||
|
def test_pre_flight_section_fare_limit_international(self):
|
||||||
|
fields = {'preferred_flight_fare':1651,'international_flight':True}
|
||||||
|
result = pol.sections[1].rules[0]['rule'](self.report, fields)
|
||||||
|
self.assertEqual(result, "Fares for international flights over 1,650 USD require Conservancy pre-approval, even if other policy conditions have been met.")
|
||||||
|
|
||||||
|
def test_pre_flight_section_lowest_fare_check_less_than_zero(self):
|
||||||
|
fields = {'lowest_fare_duration':10,'preferred_flight_duration':11,'lowest_fare':100,'preferred_flight_fare':1000}
|
||||||
|
result = pol.sections[1].rules[1]['rule'](self.report, fields)
|
||||||
|
self.assertEqual(result, "For the lowest fare you have provided, your maximum in-policy fare amount is 200 USD.")
|
||||||
|
|
||||||
|
def test_pre_flight_section_lowest_fare_check_less_than_three(self):
|
||||||
|
fields = {'lowest_fare_duration':10,'preferred_flight_duration':8,'lowest_fare':100,'preferred_flight_fare':1000}
|
||||||
|
result = pol.sections[1].rules[1]['rule'](self.report, fields)
|
||||||
|
self.assertEqual(result, "For the lowest fare you have provided, your maximum in-policy fare amount is 200 USD.")
|
||||||
|
|
||||||
|
def test_pre_flight_section_lowest_fare_check_less_than_six(self):
|
||||||
|
fields = {'lowest_fare_duration':10,'preferred_flight_duration':5,'lowest_fare':100,'preferred_flight_fare':1000}
|
||||||
|
result = pol.sections[1].rules[1]['rule'](self.report, fields)
|
||||||
|
self.assertEqual(result, "For the lowest fare you have provided, your maximum in-policy fare amount is 300 USD.")
|
||||||
|
|
||||||
|
def test_pre_flight_section_lowest_fare_check_less_than_ten(self):
|
||||||
|
fields = {'lowest_fare_duration':10,'preferred_flight_duration':2,'lowest_fare':100,'preferred_flight_fare':1000}
|
||||||
|
result = pol.sections[1].rules[1]['rule'](self.report, fields)
|
||||||
|
self.assertEqual(result, "For the lowest fare you have provided, your maximum in-policy fare amount is 450 USD.")
|
||||||
|
|
||||||
|
def test_pre_flight_section_lowest_fare_check_other(self):
|
||||||
|
fields = {'lowest_fare_duration':12,'preferred_flight_duration':1,'lowest_fare':100,'preferred_flight_fare':1000}
|
||||||
|
result = pol.sections[1].rules[1]['rule'](self.report, fields)
|
||||||
|
self.assertEqual(result, "For the lowest fare you have provided, your maximum in-policy fare amount is 700 USD.")
|
||||||
|
|
||||||
|
def test_pre_flight_section_departure_date_too_late(self):
|
||||||
|
fields = {'departure_date':'2019-03-13','screenshot_date':'2019-03-01'}
|
||||||
|
result = pol.sections[1].rules[2]['rule'](self.report, fields)
|
||||||
|
self.assertEqual(result, "Flights must be booked at least 14 days in advance.")
|
||||||
|
|
||||||
|
def test_pre_flight_section_departure_date_too_early(self):
|
||||||
|
fields = {'departure_date':'2020-03-10','screenshot_date':'2019-03-01'}
|
||||||
|
result = pol.sections[1].rules[2]['rule'](self.report, fields)
|
||||||
|
self.assertEqual(result, "Flights must be booked no more than 365 days in advance.")
|
||||||
|
|
||||||
|
def test_flight_info_section_fare_limit_domestic(self):
|
||||||
|
fields = {'fare':751,'international_flight':False}
|
||||||
|
result = pol.sections[2].rules[0]['rule'](self.report, fields)
|
||||||
|
self.assertEqual(result, "Fares for domestic flights over 750 USD require Conservancy pre-approval, even if other policy conditions have been met.")
|
||||||
|
|
||||||
|
def test_flight_info_section_fare_limit_international(self):
|
||||||
|
fields = {'fare':1651,'international_flight':True}
|
||||||
|
result = pol.sections[2].rules[0]['rule'](self.report, fields)
|
||||||
|
self.assertEqual(result, "Fares for international flights over 1,650 USD require Conservancy pre-approval, even if other policy conditions have been met.")
|
||||||
|
|
||||||
|
def test_flight_info_section_request_date(self):
|
||||||
|
fields = {'return_date':'2018-01-01'}
|
||||||
|
result = pol.sections[2].rules[1]['rule'](self.report, fields)
|
||||||
|
self.assertEqual(result, "Reimbursement requests must be made within 90 days of the last day of travel.")
|
||||||
|
|
||||||
|
def test_hotels_lodging_section_average_nightly_rate(self):
|
||||||
|
fields = {'check_in_date':'2019-03-01','check_out_date':'2019-03-11','cost':1100,'per_diem_rate':100}
|
||||||
|
result = pol.sections[3].rules[0]['rule'](self.report, fields)
|
||||||
|
self.assertEqual(result, "The average nightly rate cannot exceed the U.S. GSA rate.")
|
||||||
|
|
||||||
|
def test_other_expenses_section_per_diem_check(self):
|
||||||
|
fields = {'rate':100,'full_days':3,'partial_days':2,'cost':451}
|
||||||
|
result = pol.sections[5].rules[0]['rule'](self.report, fields)
|
||||||
|
self.assertEqual(result, "You may only request a maximum of 450.0 USD for the rate and trip duration provided.")
|
|
@ -1,3 +0,0 @@
|
||||||
from django.test import TestCase
|
|
||||||
|
|
||||||
# Create your tests here.
|
|
Loading…
Reference in a new issue