From 49b9fca79399c2a5fb82dd94de5d7b52516a2062 Mon Sep 17 00:00:00 2001 From: richard-dds Date: Tue, 7 Aug 2018 16:41:47 -0400 Subject: [PATCH] Use Enum for request statuses --- atst/domain/requests.py | 13 +++---------- atst/models/request.py | 1 + atst/models/request_status_event.py | 14 +++++++++++--- tests/domain/test_requests.py | 9 +++++---- tests/factories.py | 14 +++++--------- 5 files changed, 25 insertions(+), 26 deletions(-) diff --git a/atst/domain/requests.py b/atst/domain/requests.py index 17ceb9b0..4c1d7bef 100644 --- a/atst/domain/requests.py +++ b/atst/domain/requests.py @@ -1,9 +1,9 @@ -from enum import Enum from sqlalchemy import exists, and_ from sqlalchemy.orm.exc import NoResultFound from sqlalchemy.orm.attributes import flag_modified -from atst.models import Request, RequestStatusEvent +from atst.models.request import Request +from atst.models.request_status_event import RequestStatusEvent, RequestStatus from atst.database import db from .exceptions import NotFoundError @@ -27,13 +27,6 @@ def deep_merge(source, destination: dict): return _deep_merge(source, dict(destination)) -class RequestStatus(Enum): - STARTED = "started" - PENDING_FINANCIAL_VERIFICATION = "pending_financial_verification" - PENDING_CCPO_APPROVAL = "pending_ccpo_approval" - APPROVED = "approved" - - class Requests(object): AUTO_APPROVE_THRESHOLD = 1000000 @@ -118,7 +111,7 @@ class Requests(object): @classmethod def set_status(cls, request: Request, status: RequestStatus): - status_event = RequestStatusEvent(new_status=status.value) + status_event = RequestStatusEvent(new_status=status) request.status_events.append(status_event) return request diff --git a/atst/models/request.py b/atst/models/request.py index 36b9b77c..147d28f1 100644 --- a/atst/models/request.py +++ b/atst/models/request.py @@ -24,3 +24,4 @@ class Request(Base): def set_status(self, status): self.status_events.append(status) + diff --git a/atst/models/request_status_event.py b/atst/models/request_status_event.py index 4f65a2ec..7eec2716 100644 --- a/atst/models/request_status_event.py +++ b/atst/models/request_status_event.py @@ -1,5 +1,6 @@ -from sqlalchemy import Column, func, ForeignKey -from sqlalchemy.types import DateTime, String, BigInteger +from enum import Enum, auto +from sqlalchemy import Column, func, ForeignKey, Enum as SQLAEnum +from sqlalchemy.types import DateTime, BigInteger from sqlalchemy.schema import Sequence from sqlalchemy.dialects.postgresql import UUID @@ -7,11 +8,18 @@ from atst.models import Base from atst.models.types import Id +class RequestStatus(Enum): + STARTED = auto() + PENDING_FINANCIAL_VERIFICATION = auto() + PENDING_CCPO_APPROVAL = auto() + APPROVED = auto() + + class RequestStatusEvent(Base): __tablename__ = "request_status_events" id = Id() - new_status = Column(String()) + new_status = Column(SQLAEnum(RequestStatus)) time_created = Column(DateTime(timezone=True), server_default=func.now()) request_id = Column( UUID(as_uuid=True), ForeignKey("requests.id", ondelete="CASCADE") diff --git a/tests/domain/test_requests.py b/tests/domain/test_requests.py index 14c4127e..1d696097 100644 --- a/tests/domain/test_requests.py +++ b/tests/domain/test_requests.py @@ -3,6 +3,7 @@ from uuid import uuid4 from atst.domain.exceptions import NotFoundError from atst.domain.requests import Requests +from atst.models.request_status_event import RequestStatus from tests.factories import RequestFactory @@ -25,25 +26,25 @@ def test_nonexistent_request_raises(): def test_new_request_has_started_status(): request = Requests.create(uuid4(), {}) - assert request.status == "started" + assert request.status == RequestStatus.STARTED def test_auto_approve_less_than_1m(new_request): new_request.body = {"details_of_use": {"dollar_value": 999999}} request = Requests.submit(new_request) - assert request.status == "pending_financial_verification" + assert request.status == RequestStatus.PENDING_FINANCIAL_VERIFICATION def test_dont_auto_approve_if_dollar_value_is_1m_or_above(new_request): new_request.body = {"details_of_use": {"dollar_value": 1000000}} request = Requests.submit(new_request) - assert request.status == "pending_ccpo_approval" + assert request.status == RequestStatus.PENDING_CCPO_APPROVAL def test_dont_auto_approve_if_no_dollar_value_specified(new_request): new_request.body = {"details_of_use": {}} request = Requests.submit(new_request) - assert request.status == "pending_ccpo_approval" + assert request.status == RequestStatus.PENDING_CCPO_APPROVAL diff --git a/tests/factories.py b/tests/factories.py index 65395479..dc68eb5c 100644 --- a/tests/factories.py +++ b/tests/factories.py @@ -1,7 +1,8 @@ import factory from uuid import uuid4 -from atst.models import Request, RequestStatusEvent +from atst.models.request import Request +from atst.models.request_status_event import RequestStatusEvent, RequestStatus from atst.models.pe_number import PENumber from atst.models.task_order import TaskOrder from atst.models.user import User @@ -9,34 +10,31 @@ from atst.models.role import Role class RequestStatusFactory(factory.alchemy.SQLAlchemyModelFactory): - class Meta: model = RequestStatusEvent class RequestFactory(factory.alchemy.SQLAlchemyModelFactory): - class Meta: model = Request id = factory.Sequence(lambda x: uuid4()) - status_events = factory.RelatedFactory(RequestStatusFactory, "request", new_status="started") + status_events = factory.RelatedFactory( + RequestStatusFactory, "request", new_status=RequestStatus.STARTED + ) class PENumberFactory(factory.alchemy.SQLAlchemyModelFactory): - class Meta: model = PENumber class TaskOrderFactory(factory.alchemy.SQLAlchemyModelFactory): - class Meta: model = TaskOrder class RoleFactory(factory.alchemy.SQLAlchemyModelFactory): - class Meta: model = Role @@ -44,7 +42,6 @@ class RoleFactory(factory.alchemy.SQLAlchemyModelFactory): class UserFactory(factory.alchemy.SQLAlchemyModelFactory): - class Meta: model = User @@ -53,4 +50,3 @@ class UserFactory(factory.alchemy.SQLAlchemyModelFactory): first_name = "Fake" last_name = "User" atat_role = factory.SubFactory(RoleFactory) -