atst/tests/domain/test_task_orders.py
graham-dds 108f65f928 Use pendulum for datetime operations when possible
Currently, we use both Python's built-in datetime library and Pendulum
to do datetime operations. For the sake of consistency, we should try to
stick to one library for datetimes. We could have used either, but
Pendulum has a more ergonomic API, so I decided to go with it when
possible.

The places where were we didn't / couldn't replace datetime are:
- checking instances of datetimes. Pendulum's objects are subclasses of
  python native datetime objects, so it's still useful to import
  datetime in those cases of using is_instance()
- WTForms date validators expect datetime style string formats --
  Pendulum has its own format for formatting/ parsing strings. As such,
  our custom validator DateRange needs to use datetime.stptime() to
  account for this format.
2020-02-17 10:38:52 -05:00

200 lines
6.6 KiB
Python

import pytest
import pendulum
from decimal import Decimal
from atst.domain.exceptions import AlreadyExistsError
from atst.domain.task_orders import TaskOrders
from atst.models import Attachment
from atst.models.task_order import TaskOrder, SORT_ORDERING, Status
from tests.factories import TaskOrderFactory, CLINFactory, PortfolioFactory
def test_create_adds_clins():
portfolio = PortfolioFactory.create()
clins = [
{
"jedi_clin_type": "JEDI_CLIN_1",
"number": "12312",
"start_date": pendulum.date(2020, 1, 1),
"end_date": pendulum.date(2021, 1, 1),
"obligated_amount": Decimal("5000"),
"total_amount": Decimal("10000"),
},
{
"jedi_clin_type": "JEDI_CLIN_1",
"number": "12312",
"start_date": pendulum.date(2020, 1, 1),
"end_date": pendulum.date(2021, 1, 1),
"obligated_amount": Decimal("5000"),
"total_amount": Decimal("10000"),
},
]
task_order = TaskOrders.create(
portfolio_id=portfolio.id,
number="0123456789",
clins=clins,
pdf={"filename": "sample.pdf", "object_name": "1234567"},
)
assert len(task_order.clins) == 2
def test_update_adds_clins():
task_order = TaskOrderFactory.create(number="1231231234")
to_number = task_order.number
clins = [
{
"jedi_clin_type": "JEDI_CLIN_1",
"number": "12312",
"start_date": pendulum.date(2020, 1, 1),
"end_date": pendulum.date(2021, 1, 1),
"obligated_amount": Decimal("5000"),
"total_amount": Decimal("10000"),
},
{
"jedi_clin_type": "JEDI_CLIN_1",
"number": "12312",
"start_date": pendulum.date(2020, 1, 1),
"end_date": pendulum.date(2021, 1, 1),
"obligated_amount": Decimal("5000"),
"total_amount": Decimal("10000"),
},
]
task_order = TaskOrders.create(
portfolio_id=task_order.portfolio_id,
number="0000000000",
clins=clins,
pdf={"filename": "sample.pdf", "object_name": "1234567"},
)
assert task_order.number != to_number
assert len(task_order.clins) == 2
def test_update_does_not_duplicate_clins():
task_order = TaskOrderFactory.create(
number="3453453456123", create_clins=[{"number": "123"}, {"number": "456"}]
)
clins = [
{
"jedi_clin_type": "JEDI_CLIN_1",
"number": "123",
"start_date": pendulum.date(2020, 1, 1),
"end_date": pendulum.date(2021, 1, 1),
"obligated_amount": Decimal("5000"),
"total_amount": Decimal("10000"),
},
{
"jedi_clin_type": "JEDI_CLIN_1",
"number": "111",
"start_date": pendulum.date(2020, 1, 1),
"end_date": pendulum.date(2021, 1, 1),
"obligated_amount": Decimal("5000"),
"total_amount": Decimal("10000"),
},
]
task_order = TaskOrders.update(
task_order_id=task_order.id,
number="0000000000000",
clins=clins,
pdf={"filename": "sample.pdf", "object_name": "1234567"},
)
assert len(task_order.clins) == 2
for clin in task_order.clins:
assert clin.number != "456"
def test_delete_task_order_with_clins(session):
task_order = TaskOrderFactory.create(
create_clins=[{"number": 1}, {"number": 2}, {"number": 3}]
)
TaskOrders.delete(task_order.id)
assert not session.query(
session.query(TaskOrder).filter_by(id=task_order.id).exists()
).scalar()
def test_task_order_sort_by_status():
today = pendulum.today()
yesterday = today.subtract(days=1)
future = today.add(days=100)
initial_to_list = [
# Draft
TaskOrderFactory.create(pdf=None),
TaskOrderFactory.create(pdf=None),
TaskOrderFactory.create(pdf=None),
# Active
TaskOrderFactory.create(
signed_at=yesterday,
clins=[CLINFactory.create(start_date=yesterday, end_date=future)],
),
# Upcoming
TaskOrderFactory.create(
signed_at=yesterday,
clins=[CLINFactory.create(start_date=future, end_date=future)],
),
# Expired
TaskOrderFactory.create(
signed_at=yesterday,
clins=[CLINFactory.create(start_date=yesterday, end_date=yesterday)],
),
TaskOrderFactory.create(
signed_at=yesterday,
clins=[CLINFactory.create(start_date=yesterday, end_date=yesterday)],
),
# Unsigned
TaskOrderFactory.create(
clins=[CLINFactory.create(start_date=today, end_date=today)]
),
]
sorted_by_status = TaskOrders.sort_by_status(initial_to_list)
assert len(sorted_by_status["Draft"]) == 4
assert len(sorted_by_status["Active"]) == 1
assert len(sorted_by_status["Upcoming"]) == 1
assert len(sorted_by_status["Expired"]) == 2
with pytest.raises(KeyError):
sorted_by_status["Unsigned"]
assert list(sorted_by_status.keys()) == [status.value for status in SORT_ORDERING]
def test_create_enforces_unique_number():
portfolio = PortfolioFactory.create()
number = "1234567890123"
assert TaskOrders.create(portfolio.id, number, [], None)
with pytest.raises(AlreadyExistsError):
TaskOrders.create(portfolio.id, number, [], None)
def test_update_enforces_unique_number():
task_order = TaskOrderFactory.create()
dupe_task_order = TaskOrderFactory.create()
with pytest.raises(AlreadyExistsError):
TaskOrders.update(dupe_task_order.id, task_order.number, [], None)
def test_allows_alphanumeric_number():
portfolio = PortfolioFactory.create()
valid_to_numbers = ["1234567890123", "ABC1234567890"]
for number in valid_to_numbers:
assert TaskOrders.create(portfolio.id, number, [], None)
def test_get_for_send_task_order_files():
new_to = TaskOrderFactory.create(create_clins=[{}])
updated_to = TaskOrderFactory.create(
create_clins=[{"last_sent_at": pendulum.datetime(2020, 2, 1)}],
pdf_last_sent_at=pendulum.datetime(2020, 1, 1),
)
sent_to = TaskOrderFactory.create(
create_clins=[{"last_sent_at": pendulum.datetime(2020, 1, 1)}],
pdf_last_sent_at=pendulum.datetime(2020, 1, 1),
)
updated_and_new_task_orders = TaskOrders.get_for_send_task_order_files()
assert len(updated_and_new_task_orders) == 2
assert sent_to not in updated_and_new_task_orders
assert updated_to in updated_and_new_task_orders
assert new_to in updated_and_new_task_orders