From e99ddd491aa3519904bf3c0ccc4a69bf7e19e738 Mon Sep 17 00:00:00 2001 From: richard-dds Date: Tue, 7 Aug 2018 21:03:27 -0400 Subject: [PATCH] Create Request.creator relationship - Rename creator_id to user_id --- .../05d6272bdb43_rename_request_creator_.py | 43 ++++++++++++++++ atst/domain/requests.py | 6 +-- atst/models/request.py | 8 +-- atst/routes/requests/index.py | 2 +- atst/routes/requests/jedi_request_flow.py | 2 +- tests/domain/test_requests.py | 4 +- tests/factories.py | 51 ++++++++++--------- tests/models/test_requests.py | 9 +++- 8 files changed, 89 insertions(+), 36 deletions(-) create mode 100644 alembic/versions/05d6272bdb43_rename_request_creator_.py diff --git a/alembic/versions/05d6272bdb43_rename_request_creator_.py b/alembic/versions/05d6272bdb43_rename_request_creator_.py new file mode 100644 index 00000000..c8a3966e --- /dev/null +++ b/alembic/versions/05d6272bdb43_rename_request_creator_.py @@ -0,0 +1,43 @@ +"""rename request creator + +Revision ID: 05d6272bdb43 +Revises: 77b065750596 +Create Date: 2018-08-07 20:21:22.559283 + +""" +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +# revision identifiers, used by Alembic. +revision = '05d6272bdb43' +down_revision = '77b065750596' +branch_labels = None +depends_on = None + + +def upgrade(): + db = op.get_bind() + + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('requests', sa.Column('user_id', postgresql.UUID(as_uuid=True), nullable=True)) + op.create_foreign_key('requests_user_id_fk', 'requests', 'users', ['user_id'], ['id']) + # ### end Alembic commands ### + + db.execute("UPDATE requests SET user_id = creator") + + op.alter_column('requests', 'user_id', nullable=False) + op.drop_column('requests', 'creator') + + + +def downgrade(): + db = op.get_bind() + + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('requests', sa.Column('creator', postgresql.UUID(), autoincrement=False, nullable=True)) + op.drop_constraint('requests_user_id_fk', 'requests', type_='foreignkey') + # ### end Alembic commands ### + + db.execute("UPDATE requests SET creator = user_id") + op.drop_column('requests', 'user_id') diff --git a/atst/domain/requests.py b/atst/domain/requests.py index e7b64e5d..f9127aa9 100644 --- a/atst/domain/requests.py +++ b/atst/domain/requests.py @@ -58,10 +58,10 @@ class Requests(object): return request @classmethod - def get_many(cls, creator_id=None): + def get_many(cls, creator=None): filters = [] - if creator_id: - filters.append(Request.creator == creator_id) + if creator: + filters.append(Request.creator == creator) requests = ( db.session.query(Request) diff --git a/atst/models/request.py b/atst/models/request.py index 66e5bf1e..4e7a2832 100644 --- a/atst/models/request.py +++ b/atst/models/request.py @@ -1,6 +1,6 @@ -from sqlalchemy import Column, func +from sqlalchemy import Column, func, ForeignKey from sqlalchemy.types import DateTime -from sqlalchemy.dialects.postgresql import JSONB, UUID +from sqlalchemy.dialects.postgresql import JSONB from sqlalchemy.orm import relationship from atst.models import Base @@ -11,13 +11,15 @@ class Request(Base): __tablename__ = "requests" id = Id() - creator = Column(UUID(as_uuid=True)) time_created = Column(DateTime(timezone=True), server_default=func.now()) body = Column(JSONB) status_events = relationship( "RequestStatusEvent", backref="request", order_by="RequestStatusEvent.sequence" ) + user_id = Column(ForeignKey("users.id"), nullable=False) + creator = relationship("User") + @property def status(self): return self.status_events[-1].new_status diff --git a/atst/routes/requests/index.py b/atst/routes/requests/index.py index 7e098b47..15ab8fee 100644 --- a/atst/routes/requests/index.py +++ b/atst/routes/requests/index.py @@ -28,7 +28,7 @@ def requests_index(): ): requests = Requests.get_many() else: - requests = Requests.get_many(creator_id=g.current_user.id) + requests = Requests.get_many(creator=g.current_user) mapped_requests = [map_request(g.current_user, r) for r in requests] diff --git a/atst/routes/requests/jedi_request_flow.py b/atst/routes/requests/jedi_request_flow.py index e750a9e0..af08251b 100644 --- a/atst/routes/requests/jedi_request_flow.py +++ b/atst/routes/requests/jedi_request_flow.py @@ -124,5 +124,5 @@ class JEDIRequestFlow(object): if self.request_id: Requests.update(self.request_id, request_data) else: - request = Requests.create(self.current_user.id, request_data) + request = Requests.create(self.current_user, request_data) self.request_id = request.id diff --git a/tests/domain/test_requests.py b/tests/domain/test_requests.py index 1d696097..68835138 100644 --- a/tests/domain/test_requests.py +++ b/tests/domain/test_requests.py @@ -5,7 +5,7 @@ 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 +from tests.factories import RequestFactory, UserFactory @pytest.fixture(scope="function") @@ -25,7 +25,7 @@ def test_nonexistent_request_raises(): def test_new_request_has_started_status(): - request = Requests.create(uuid4(), {}) + request = Requests.create(UserFactory.build(), {}) assert request.status == RequestStatus.STARTED diff --git a/tests/factories.py b/tests/factories.py index dc68eb5c..af5f6971 100644 --- a/tests/factories.py +++ b/tests/factories.py @@ -9,31 +9,6 @@ from atst.models.user import User 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=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 @@ -50,3 +25,29 @@ class UserFactory(factory.alchemy.SQLAlchemyModelFactory): first_name = "Fake" last_name = "User" atat_role = factory.SubFactory(RoleFactory) + + +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=RequestStatus.STARTED + ) + creator = factory.SubFactory(UserFactory) + + +class PENumberFactory(factory.alchemy.SQLAlchemyModelFactory): + class Meta: + model = PENumber + + +class TaskOrderFactory(factory.alchemy.SQLAlchemyModelFactory): + class Meta: + model = TaskOrder diff --git a/tests/models/test_requests.py b/tests/models/test_requests.py index a1990a35..90038d4e 100644 --- a/tests/models/test_requests.py +++ b/tests/models/test_requests.py @@ -1,4 +1,4 @@ -from tests.factories import RequestFactory +from tests.factories import RequestFactory, UserFactory from atst.domain.requests import Requests, RequestStatus @@ -19,3 +19,10 @@ def test_pending_ccpo_approval_requires_ccpo(): request = Requests.set_status(request, RequestStatus.PENDING_CCPO_APPROVAL) assert Requests.action_required_by(request) == "ccpo" + + +def test_request_has_creator(): + user = UserFactory.create() + request = RequestFactory.create(creator=user) + + assert request.creator == user