basic workspace model and repository implementation
This commit is contained in:
parent
e1ffd8fc56
commit
ef153f5226
37
alembic/versions/4be312655ceb_add_workspaces_table.py
Normal file
37
alembic/versions/4be312655ceb_add_workspaces_table.py
Normal 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 ###
|
@ -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):
|
||||
MOCK_WORKSPACES = [
|
||||
{
|
||||
"name": "Unclassified IaaS and PaaS for Defense Digital Service (DDS)",
|
||||
"id": "5966187a-eff9-44c3-aa15-4de7a65ac7ff",
|
||||
"task_order": {"number": 123456},
|
||||
"user_count": 23,
|
||||
}
|
||||
]
|
||||
# will a request have a TO association?
|
||||
# do we automatically create an entry for the request.creator in the
|
||||
# workspace_roles table?
|
||||
|
||||
@classmethod
|
||||
def create(cls, request, task_order, name=None):
|
||||
name = name or request.id
|
||||
return Workspace(request=request, task_order=task_order, name=name)
|
||||
|
||||
@classmethod
|
||||
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
|
||||
def get_many(cls):
|
||||
return cls.MOCK_WORKSPACES
|
||||
def get_by_request(cls, request):
|
||||
try:
|
||||
workspace = db.session.query(Workspace).filter_by(request=request).one()
|
||||
except NoResultFound:
|
||||
raise NotFoundError("workspace")
|
||||
|
||||
return workspace
|
||||
|
||||
|
||||
class Projects(object):
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def create(cls, creator_id, body):
|
||||
pass
|
||||
@ -67,6 +88,9 @@ class Projects(object):
|
||||
|
||||
class Members(object):
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def create(cls, creator_id, body):
|
||||
pass
|
||||
|
@ -10,3 +10,4 @@ from .user import User
|
||||
from .workspace_role import WorkspaceRole
|
||||
from .pe_number import PENumber
|
||||
from .task_order import TaskOrder
|
||||
from .workspace import Workspace
|
||||
|
19
atst/models/workspace.py
Normal file
19
atst/models/workspace.py
Normal 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)
|
36
tests/domain/test_workspaces.py
Normal file
36
tests/domain/test_workspaces.py
Normal 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
|
@ -10,6 +10,7 @@ from atst.models.pe_number import PENumber
|
||||
from atst.models.task_order import TaskOrder
|
||||
from atst.models.user import User
|
||||
from atst.models.role import Role
|
||||
from atst.models.workspace import Workspace
|
||||
from atst.models.request_status_event import RequestStatusEvent
|
||||
from atst.domain.roles import Roles
|
||||
|
||||
@ -102,3 +103,13 @@ class PENumberFactory(factory.alchemy.SQLAlchemyModelFactory):
|
||||
class TaskOrderFactory(factory.alchemy.SQLAlchemyModelFactory):
|
||||
class Meta:
|
||||
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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user