Add /lots/ find method returning nested lots

This commit is contained in:
Xavier Bustamante Talavera 2018-10-05 18:57:35 +02:00
parent 8ebf9ba501
commit 7e4a0981a1
2 changed files with 54 additions and 5 deletions

View file

@ -1,13 +1,14 @@
import uuid import uuid
from typing import Set from collections import deque
from typing import List, Set
import marshmallow as ma import marshmallow as ma
from flask import request from flask import jsonify, request
from teal.resource import View from teal.resource import View
from ereuse_devicehub.db import db from ereuse_devicehub.db import db
from ereuse_devicehub.resources.device.models import Device 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): class LotView(View):
@ -25,6 +26,49 @@ class LotView(View):
lot = Lot.query.filter_by(id=id).one() # type: Lot lot = Lot.query.filter_by(id=id).one() # type: Lot
return self.schema.jsonify(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): class LotBaseChildrenView(View):
"""Base class for adding / removing children devices and """Base class for adding / removing children devices and

View file

@ -122,7 +122,7 @@ def test_lot_multiple_parents():
@pytest.mark.usefixtures(conftest.auth_app_context.__name__) @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. """Adds and removes children uniting already existing graphs.
1 3 1 3
@ -220,7 +220,12 @@ def test_post_add_children_view(user: UserClient):
assert parent['children'][0]['id'] == child['id'] assert parent['children'][0]['id'] == child['id']
child, _ = user.get(res=Lot, item=child['id']) child, _ = user.get(res=Lot, item=child['id'])
assert child['parents'][0]['id'] == parent['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): def test_lot_post_add_remove_device_view(app: Devicehub, user: UserClient):