diff --git a/poc/bin/kapow b/poc/bin/kapow index a0cde55..b1717ce 100755 --- a/poc/bin/kapow +++ b/poc/bin/kapow @@ -270,12 +270,14 @@ def handle_route(entrypoint, command): # Route Management # ######################################################################## + def get_routes(app): async def _get_routes(request): """Return the list of registered routes.""" return web.json_response(list(app.router)) return _get_routes + def insert_route(app): async def _insert_route(request): """Insert a new Kapow! route.""" @@ -289,7 +291,9 @@ def insert_route(app): assert index >= 0 route = KapowRoute(method=content["method"], path=content["url_pattern"], - name="ROUTE_" + str(uuid4()).replace('-', '_'), + id="ROUTE_" + str(uuid4()).replace('-', '_'), + entrypoint=content["entrypoint"], + command=content["command"], handler=handle_route(content["entrypoint"], content["command"])) app.change_routes((app["user_routes"][:index] @@ -300,9 +304,15 @@ def insert_route(app): else: app["user_routes"].insert(index, route) print(f'Route created {content["method"]} {content["url_pattern"]}') - return web.json_response(route.name, status=201) + return web.json_response({"id": route.id, + "method": route.method, + "url_pattern": route.path, + "entrypoint": route.entrypoint, + "command": route.command, + "index": index}, status=201) return _insert_route + def append_route(app): async def _append_route(request): """Append a new Kapow! route.""" @@ -314,7 +324,9 @@ def append_route(app): try: route = KapowRoute(method=content["method"], path=content["url_pattern"], - name="ROUTE_" + str(uuid4()).replace('-', '_'), + id="ROUTE_" + str(uuid4()).replace('-', '_'), + entrypoint=content["entrypoint"], + command=content["command"], handler=handle_route(content["entrypoint"], content["command"])) app.change_routes(app["user_routes"] + [route]) @@ -323,7 +335,12 @@ def append_route(app): else: app["user_routes"].append(route) print(f'Route created {content["method"]} {content["url_pattern"]}') - return web.json_response(route.name, status=201) + return web.json_response({"id": route.id, + "method": route.method, + "url_pattern": route.path, + "entrypoint": route.entrypoint, + "command": route.command, + "index": len(app["user_routes"])-1}, status=201) return _append_route @@ -390,7 +407,7 @@ class DynamicApplication(web.Application): router.add_route(route.method, route.path, route.handler, - name=route.name) + name=route.id) except Exception as exc: raise InvalidRouteError("Invalid route") from exc else: @@ -399,7 +416,13 @@ class DynamicApplication(web.Application): self._router.freeze() -KapowRoute = namedtuple('KapowRoute', ('method', 'path', 'name', 'handler')) +KapowRoute = namedtuple('KapowRoute', + ('method', + 'path', + 'id', + 'entrypoint', + 'command', + 'handler')) async def start_background_tasks(app): diff --git a/spec/test/features/control/append/success.feature b/spec/test/features/control/append/success.feature index a57662f..566f977 100644 --- a/spec/test/features/control/append/success.feature +++ b/spec/test/features/control/append/success.feature @@ -1,3 +1,4 @@ +@wip Feature: Append new routes in Kapow! server. Append routes allow users to configure the server. New routes are added to the list of existing routes. diff --git a/spec/test/features/steps/comparedict.py b/spec/test/features/steps/comparedict.py index 7b5f968..c720ee6 100644 --- a/spec/test/features/steps/comparedict.py +++ b/spec/test/features/steps/comparedict.py @@ -4,7 +4,7 @@ from functools import singledispatch def assert_same_type(f): def wrapper(a, b): if type(a) != type(b): - raise TypeError("Non-matching types") + raise TypeError(f"Non-matching types {a!r} != {b!r}") return f(a, b) return wrapper @@ -12,7 +12,10 @@ def assert_same_type(f): @singledispatch @assert_same_type def is_subset(model, obj): - return model == obj + if model == obj: + return True + else: + raise ValueError(f"Non-matching values {model!r} != {obj!r}") @is_subset.register(dict) @@ -20,16 +23,17 @@ def is_subset(model, obj): def _(model, obj): for key, value in model.items(): if key not in obj or not is_subset(value, obj[key]): - return False + raise ValueError(f"Non-matching dicts {model!r} != {obj!r}") return True @is_subset.register(list) @assert_same_type def _(model, obj): - if type(model) != type(obj): - raise TypeError("Non-matching types") - return is_subset(set(model), set(obj)) + if is_subset(set(model), set(obj)): + return True + else: + raise ValueError(f"Non-matching lists {model!r} != {obj!r}") @is_subset.register(set) diff --git a/spec/test/features/steps/steps.py b/spec/test/features/steps/steps.py index aa8ac84..e82d71a 100644 --- a/spec/test/features/steps/steps.py +++ b/spec/test/features/steps/steps.py @@ -134,10 +134,7 @@ def step_impl(context, reason): @then('I get the following response body') def step_impl(context): - for row in context.table: - for name, value in row.items(): - assert name in context.response.json(), f"Field {name} not present in {context.response.json()}" - assert set(json.loads(value)) == set(context.response.json()[name]) + assert is_subset(json.loads(context.text), context.response.json()) @then('I get an empty response body')