basic workspace model and repository implementation

This commit is contained in:
dandds 2018-08-16 09:51:35 -04:00 committed by richard-dds
parent e1ffd8fc56
commit ef153f5226
6 changed files with 139 additions and 11 deletions

View File

@ -0,0 +1,37 @@
"""add workspaces table
Revision ID: 4be312655ceb
Revises: 05d6272bdb43
Create Date: 2018-08-16 09:25:19.888549
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision = '4be312655ceb'
down_revision = '05d6272bdb43'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('workspaces',
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False),
sa.Column('request_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('task_order_id', sa.Integer(), nullable=False),
sa.Column('name', sa.String(), nullable=True),
sa.ForeignKeyConstraint(['request_id'], ['requests.id'], ),
sa.ForeignKeyConstraint(['task_order_id'], ['task_order.id'], ),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('name')
)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('workspaces')
# ### end Alembic commands ###

View File

@ -1,23 +1,44 @@
from sqlalchemy.orm.exc import NoResultFound
from atst.database import db
from atst.domain.exceptions import NotFoundError
from atst.models.workspace import Workspace
class Workspaces(object): class Workspaces(object):
MOCK_WORKSPACES = [ # will a request have a TO association?
{ # do we automatically create an entry for the request.creator in the
"name": "Unclassified IaaS and PaaS for Defense Digital Service (DDS)", # workspace_roles table?
"id": "5966187a-eff9-44c3-aa15-4de7a65ac7ff",
"task_order": {"number": 123456}, @classmethod
"user_count": 23, def create(cls, request, task_order, name=None):
} name = name or request.id
] return Workspace(request=request, task_order=task_order, name=name)
@classmethod @classmethod
def get(cls, workspace_id): def get(cls, workspace_id):
return cls.MOCK_WORKSPACES[0] try:
workspace = db.session.query(Workspace).filter_by(id=workspace_id).one()
except NoResultFound:
raise NotFoundError("workspace")
return workspace
@classmethod @classmethod
def get_many(cls): def get_by_request(cls, request):
return cls.MOCK_WORKSPACES try:
workspace = db.session.query(Workspace).filter_by(request=request).one()
except NoResultFound:
raise NotFoundError("workspace")
return workspace
class Projects(object): class Projects(object):
def __init__(self):
pass
@classmethod @classmethod
def create(cls, creator_id, body): def create(cls, creator_id, body):
pass pass
@ -67,6 +88,9 @@ class Projects(object):
class Members(object): class Members(object):
def __init__(self):
pass
@classmethod @classmethod
def create(cls, creator_id, body): def create(cls, creator_id, body):
pass pass

View File

@ -10,3 +10,4 @@ from .user import User
from .workspace_role import WorkspaceRole from .workspace_role import WorkspaceRole
from .pe_number import PENumber from .pe_number import PENumber
from .task_order import TaskOrder from .task_order import TaskOrder
from .workspace import Workspace

19
atst/models/workspace.py Normal file
View File

@ -0,0 +1,19 @@
from sqlalchemy import Column, ForeignKey, String
from sqlalchemy.orm import relationship
from atst.models import Base
from atst.models.types import Id
class Workspace(Base):
__tablename__ = "workspaces"
id = Id()
request_id = Column(ForeignKey("requests.id"), nullable=False)
request = relationship("Request")
task_order_id = Column(ForeignKey("task_order.id"), nullable=False)
task_order = relationship("TaskOrder")
name = Column(String, unique=True)

View File

@ -0,0 +1,36 @@
import pytest
from uuid import uuid4
from atst.domain.exceptions import NotFoundError
from atst.domain.workspaces import Workspaces
from tests.factories import WorkspaceFactory, RequestFactory, TaskOrderFactory
def test_can_create_workspace():
request = RequestFactory.create()
to = TaskOrderFactory.create()
workspace = Workspaces.create(request, to)
assert workspace.request == request
assert workspace.task_order == to
assert workspace.name == request.id
workspace = Workspaces.create(request, to, name="frugal-whale")
assert workspace.name == "frugal-whale"
def test_can_get_workspace():
workspace = WorkspaceFactory.create()
found = Workspaces.get(workspace.id)
assert workspace == found
def test_nonexistent_workspace_raises():
with pytest.raises(NotFoundError):
Workspaces.get(uuid4())
def test_can_get_workspace_by_request():
workspace = WorkspaceFactory.create()
found = Workspaces.get_by_request(workspace.request)
assert workspace == found

View File

@ -10,6 +10,7 @@ from atst.models.pe_number import PENumber
from atst.models.task_order import TaskOrder from atst.models.task_order import TaskOrder
from atst.models.user import User from atst.models.user import User
from atst.models.role import Role from atst.models.role import Role
from atst.models.workspace import Workspace
from atst.models.request_status_event import RequestStatusEvent from atst.models.request_status_event import RequestStatusEvent
from atst.domain.roles import Roles from atst.domain.roles import Roles
@ -102,3 +103,13 @@ class PENumberFactory(factory.alchemy.SQLAlchemyModelFactory):
class TaskOrderFactory(factory.alchemy.SQLAlchemyModelFactory): class TaskOrderFactory(factory.alchemy.SQLAlchemyModelFactory):
class Meta: class Meta:
model = TaskOrder model = TaskOrder
class WorkspaceFactory(factory.alchemy.SQLAlchemyModelFactory):
class Meta:
model = Workspace
request = factory.SubFactory(RequestFactory)
task_order = factory.SubFactory(TaskOrderFactory)
# name it the same as the request ID by default
name = factory.LazyAttribute(lambda w: w.request.id)