1
0
mirror of https://github.com/MarkParker5/STARK.git synced 2025-02-17 11:55:35 +02:00

refactor and test rooms, init house with hub

This commit is contained in:
MarkParker5 2022-06-21 00:04:46 +02:00
parent 7b8d177437
commit accfb6201a
No known key found for this signature in database
GPG Key ID: C87FA4BD47B5A169
9 changed files with 141 additions and 52 deletions

View File

View File

@ -1,6 +1,8 @@
from uuid import UUID
from fastapi import Depends
from sqlalchemy import select, delete
from sqlalchemy.ext.asyncio import AsyncSession
from SmartHome.API.models import House
from SmartHome.API.dependencies import database
@ -8,9 +10,23 @@ from . import schemas
class HouseManager:
def __init__(self, session = Depends(database.get_session)):
session: AsyncSession
def __init__(self, session = Depends(database.get_async_session)):
self.session = session
def get(self) -> House:
db = self.session
return db.query(House).one()
async def get(self) -> House:
db: AsyncSession = self.session
result = await db.scalars(select(House))
return result.first()
async def create(self, house_id: UUID) -> House:
db: AsyncSession = self.session
if house := await self.get():
await db.delete(house)
house = House(id = house_id)
db.add(house)
await db.commit()
return house

View File

@ -11,5 +11,5 @@ router = APIRouter(
)
@router.get('', response_model = House)
async def house_get(manager: HouseManager = Depends()):
async def get_house(manager: HouseManager = Depends()):
return manager.get()

View File

@ -2,7 +2,7 @@ from __future__ import annotations
from uuid import UUID
from fastapi import Depends
from sqlalchemy import select, update, delete
from sqlalchemy import select, update
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.exc import NoResultFound
@ -11,6 +11,7 @@ import config
from API import exceptions
from API.models import Hub
from API.dependencies import database
from API import endpoints
from . import schemas
@ -22,6 +23,9 @@ class HubManager:
async def init(self, create_hub: schemas.HubInit) -> Hub:
db: AsyncSession = self.session
house_manager = endpoints.house.HouseManager(db)
await house_manager.create(create_hub.house_id)
if hub := await self.get():
await db.delete(hub)
@ -30,7 +34,6 @@ class HubManager:
db.add(hub)
await db.commit()
await db.refresh(hub)
return hub

View File

@ -1,44 +1,61 @@
from uuid import UUID
from fastapi import Depends
from sqlalchemy import delete
from sqlalchemy import select, update, delete
from sqlalchemy.orm import selectinload
from sqlalchemy.ext.asyncio import AsyncSession
from SmartHome.API.models import Room
from SmartHome.API.dependencies import database
from API import exceptions
from API import endpoints
from API.models import Room
from API.dependencies import database
from . import schemas
class RoomsManager:
def __init__(self, session = Depends(database.get_session)):
session: AsyncSession
def __init__(self, session = Depends(database.get_async_session)):
self.session = session
def get(self, id: UUID) -> Room | None:
db = self.session
return db.get(Room, id)
# TODO: separate shallow get and deep fetch
async def get(self, id: UUID) -> Room | None:
db: AsyncSession = self.session
response = await db.scalars(
select(Room).where(Room.id == id).options(selectinload(Room.devices))
)
return response.first()
def create(self, create_room: schemas.PatchRoom) -> Room:
db = self.session
room = Room(name = create_room.name, house_id = create_room.house_id)
async def create(self, create_room: schemas.CreateRoom) -> Room:
db: AsyncSession = self.session
house = await endpoints.house.HouseManager(db).get()
if not house:
raise exceptions.not_initialized
room = Room(name = create_room.name, house_id = house.id, devices = [])
db.add(room)
db.commit()
db.refresh(room)
await db.commit()
return room
def update(self, room: schemas.Room):
db = self.session
async def update(self, room: schemas.Room):
db: AsyncSession = self.session
values = {key: value for key, value in room.dict().items() if key != 'id'}
db.execute(Room.__table__.update().values(values).filter_by(id = room.id))
db.commit()
await db.execute(update(Room).values(values).where(Room.id == room.id))
await db.commit()
def patch(self, id: UUID, room: schemas.PatchRoom):
db = self.session
values = {key: value for key, value in room.dict().items() if key != 'id' and value != None}
db.execute(Room.__table__.update().values(values).filter_by(id = id))
db.commit()
async def patch(self, id: UUID, room: schemas.PatchRoom):
db: AsyncSession = self.session
values = {key: value for key, value in room.dict().items() if value != None}
await db.execute(update(Room).values(**values))
await db.commit()
def delete(self, room_id: UUID):
db = self.session
room = self.get(room_id)
if room and room.house.owner_id == self.owner_id:
db.delete(room)
db.commit()
async def delete(self, room_id: UUID):
db: AsyncSession = self.session
room = await self.get(room_id)
if room: #TODO: and room.house.owner_id == self.user_id:
await db.delete(room)
await db.commit()
else:
raise exceptions.not_found

View File

@ -2,7 +2,7 @@ from uuid import UUID
from fastapi import APIRouter, Depends
from SmartHome.API import exceptions
from .RoomsManager import RoomsManager
from .schemas import Room, PatchRoom, PatchRoom
from .schemas import Room, CreateRoom, PatchRoom
router = APIRouter(
@ -10,27 +10,21 @@ router = APIRouter(
tags = ['room'],
)
@router.get('/{id}', response_model = Room)
async def room_get(id: UUID, manager: RoomsManager = Depends()):
room = manager.get(id)
@router.post('', response_model = Room)
async def create_room(room: CreateRoom, manager: RoomsManager = Depends()):
return await manager.create(room)
@router.get('/{id}', response_model = Room)
async def get_room(id: UUID, manager: RoomsManager = Depends()):
room = await manager.get(id)
if not room:
raise exceptions.not_found
return room
@router.post('', response_model = Room)
async def room_create(room: PatchRoom, manager: RoomsManager = Depends()):
return manager.create(room)
@router.put('')
async def room_put(room: Room, manager: RoomsManager = Depends()):
manager.update(room)
@router.patch('/{id}')
async def room_patch(id: UUID, room: PatchRoom, manager: RoomsManager = Depends()):
manager.patch(id, room)
async def patch_room(id: UUID, room: PatchRoom, manager: RoomsManager = Depends()):
await manager.patch(id, room)
@router.delete('/{id}')
async def room_delete(id: UUID, manager: RoomsManager = Depends()):
manager.delete(id)
async def delete_room(id: UUID, manager: RoomsManager = Depends()):
await manager.delete(id)

View File

@ -3,9 +3,12 @@ from pydantic import BaseModel
from ..device.schemas import Device
class PatchRoom(BaseModel):
class CreateRoom(BaseModel):
name: str
class PatchRoom(CreateRoom):
pass
class Room(BaseModel):
id: UUID
name: str

View File

@ -27,3 +27,8 @@ already_exist = HTTPException(
status_code = 400,
detail = 'Resource already exist'
)
not_initialized = HTTPException(
status_code = 400,
detail = 'Hub not initialized'
)

View File

@ -0,0 +1,51 @@
from tests.setup import *
id = uuid1()
room = {
'name': 'New Room',
'devices': []
}
def test_get_room_null():
response = client.get(f'/api/room/')
assert response.status_code == 405
assert response.json() == {'detail': 'Method Not Allowed'}
def test_get_room_404():
response = client.get(f'/api/room/{id}')
assert response.status_code == 404
assert response.json() == {'detail': 'Not found'}
def test_delete_room_404():
response = client.delete(f'/api/room/{id}')
assert response.status_code == 404
assert response.json() == {'detail': 'Not found'}
def test_create_room():
response = client.post(f'/api/room', json = room)
new_room = response.json()
assert response.status_code == 200
global id
id = new_room.get('id')
assert id
room['id'] = id
assert new_room == room
def test_get_room():
response = client.get(f'/api/room/{id}')
assert response.status_code == 200, id
assert response.json() == room
def test_patch_room():
room['name'] = 'Patched Room'
response = client.patch(f'/api/room/{id}', json = room)
assert response.status_code == 200
assert client.get(f'/api/room/{id}').json() == room
def test_delete_room():
response = client.delete(f'/api/room/{id}', json = room)
assert response.status_code == 200
def test_get_deleted_room():
test_get_room_404()