Add /lots/ find method returning nested lots
This commit is contained in:
parent
8ebf9ba501
commit
7e4a0981a1
|
@ -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
|
||||||
|
|
|
@ -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):
|
||||||
|
|
Reference in a new issue