Add /lots/ find method returning nested lots
This commit is contained in:
parent
8ebf9ba501
commit
7e4a0981a1
|
@ -1,13 +1,14 @@
|
|||
import uuid
|
||||
from typing import Set
|
||||
from collections import deque
|
||||
from typing import List, Set
|
||||
|
||||
import marshmallow as ma
|
||||
from flask import request
|
||||
from flask import jsonify, request
|
||||
from teal.resource import View
|
||||
|
||||
from ereuse_devicehub.db import db
|
||||
from ereuse_devicehub.resources.device.models import Device
|
||||
from ereuse_devicehub.resources.lot.models import Lot
|
||||
from ereuse_devicehub.resources.lot.models import Lot, Path
|
||||
|
||||
|
||||
class LotView(View):
|
||||
|
@ -25,6 +26,49 @@ class LotView(View):
|
|||
lot = Lot.query.filter_by(id=id).one() # type: Lot
|
||||
return self.schema.jsonify(lot)
|
||||
|
||||
def find(self, args: dict):
|
||||
"""Returns all lots as required for DevicehubClient::
|
||||
|
||||
[
|
||||
{title: 'lot1',
|
||||
nodes: [{title: 'child1', nodes:[]}]
|
||||
]
|
||||
"""
|
||||
nodes = []
|
||||
for model in Path.query: # type: Path
|
||||
path = deque(model.path.path.split('.'))
|
||||
self._p(nodes, path)
|
||||
return jsonify({
|
||||
'items': nodes,
|
||||
'url': request.path
|
||||
})
|
||||
|
||||
def _p(self, nodes: List[dict], path: deque):
|
||||
"""Recursively creates the nested lot structure.
|
||||
|
||||
Every recursive step consumes path (a deque of lot_id),
|
||||
trying to find it as the value of id in nodes, otherwise
|
||||
it adds itself. Then moves to the node's children.
|
||||
"""
|
||||
lot_id = uuid.UUID(path.popleft().replace('_', '-'))
|
||||
try:
|
||||
# does lot_id exist already in node?
|
||||
node = next(part for part in nodes if lot_id == part['id'])
|
||||
except StopIteration:
|
||||
lot = Lot.query.filter_by(id=lot_id).one()
|
||||
node = {
|
||||
'id': lot_id,
|
||||
'title': lot.name,
|
||||
'url': lot.url.to_text(),
|
||||
'closed': lot.closed,
|
||||
'updated': lot.updated,
|
||||
'created': lot.created,
|
||||
'nodes': []
|
||||
}
|
||||
nodes.append(node)
|
||||
if path:
|
||||
self._p(node['nodes'], path)
|
||||
|
||||
|
||||
class LotBaseChildrenView(View):
|
||||
"""Base class for adding / removing children devices and
|
||||
|
|
|
@ -122,7 +122,7 @@ def test_lot_multiple_parents():
|
|||
|
||||
|
||||
@pytest.mark.usefixtures(conftest.auth_app_context.__name__)
|
||||
def test_lot_unite_graphs():
|
||||
def test_lot_unite_graphs_and_find():
|
||||
"""Adds and removes children uniting already existing graphs.
|
||||
|
||||
1 3
|
||||
|
@ -220,7 +220,12 @@ def test_post_add_children_view(user: UserClient):
|
|||
assert parent['children'][0]['id'] == child['id']
|
||||
child, _ = user.get(res=Lot, item=child['id'])
|
||||
assert child['parents'][0]['id'] == parent['id']
|
||||
return child['id']
|
||||
|
||||
lots = user.get(res=Lot)[0]['items']
|
||||
assert len(lots) == 1
|
||||
assert lots[0]['title'] == 'Parent'
|
||||
assert len(lots[0]['nodes']) == 1
|
||||
assert lots[0]['nodes'][0]['title'] == 'Child'
|
||||
|
||||
|
||||
def test_lot_post_add_remove_device_view(app: Devicehub, user: UserClient):
|
||||
|
|
Reference in a new issue