diff --git a/poc/bin/kapow b/poc/bin/kapow index 2180c0c..342e249 100755 --- a/poc/bin/kapow +++ b/poc/bin/kapow @@ -274,7 +274,14 @@ def handle_route(entrypoint, command): def get_routes(app): async def _get_routes(request): """Return the list of registered routes.""" - return web.json_response(list(app.router)) + data = [{"index": idx, + "method": r.method, + "id": r.id, + "url_pattern": r.path, + "entrypoint": r.entrypoint, + "command": r.command} + for idx, r in enumerate(app["user_routes"])] + return web.json_response(data) return _get_routes @@ -340,7 +347,8 @@ def append_route(app): "url_pattern": route.path, "entrypoint": route.entrypoint, "command": route.command, - "index": len(app["user_routes"])-1}, status=201) + "index": len(app["user_routes"])-1}, + status=201) return _append_route @@ -348,10 +356,14 @@ def delete_route(app): async def _delete_route(request): """Delete the given Kapow! route.""" id = request.match_info["id"] - route = app.router._named_resources.pop(id) - app.router._resources.remove(route) - print(f'Route deleted {id}') - return web.json_response(id) + routes = [r for r in app["user_routes"] if r.id != id] + if len(routes) == len(app["user_routes"]): + return web.Response(status=404, reason="Not Found") + else: + app.change_routes(routes) + app["user_routes"] = routes + print(f'Route deleted {id}') + return web.Response(status=200, reason="OK") return _delete_route diff --git a/spec/test/features/control/delete/list_order.feature b/spec/test/features/control/delete/list_order.feature index efa232c..d3fb0c2 100644 --- a/spec/test/features/control/delete/list_order.feature +++ b/spec/test/features/control/delete/list_order.feature @@ -45,7 +45,7 @@ Feature: Routes auto-ordering after deleting in a Kapow! server. }, { "method": "GET", - "url_pattern": "/listDir/:dirname", + "url_pattern": "/listDir/{dirname}", "entrypoint": "/bin/sh -c", "command": "ls -la /request/params/dirname | response /body", "index": 2, @@ -128,7 +128,7 @@ Feature: Routes auto-ordering after deleting in a Kapow! server. }, { "method": "GET", - "url_pattern": "/listDir/:dirname", + "url_pattern": "/listDir/{dirname}", "entrypoint": "/bin/sh -c", "command": "ls -la /request/params/dirname | response /body", "index": 2, diff --git a/spec/test/features/control/insert/error_malformed.feature b/spec/test/features/control/insert/error_malformed.feature index c5951dd..9216577 100644 --- a/spec/test/features/control/insert/error_malformed.feature +++ b/spec/test/features/control/insert/error_malformed.feature @@ -20,6 +20,6 @@ Feature: Kapow! server reject insert requests with malformed JSON bodies. "id": "xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx" } """ - Then I get bad request as response code + Then I get 400 as response code And I get "Malformed JSON" as response reason phrase And I get an empty response body diff --git a/spec/test/features/control/insert/error_unprocessable.feature b/spec/test/features/control/insert/error_unprocessable.feature index 3a2f78f..390ff0e 100644 --- a/spec/test/features/control/insert/error_unprocessable.feature +++ b/spec/test/features/control/insert/error_unprocessable.feature @@ -16,16 +16,7 @@ Feature: Kapow! server reject insert responses with semantic errors. } """ Then I get 422 as response code - And I get "Missing Mandatory Field" as response reason phrase - And I get the following response body: - """ - { - "missing_mandatory_fields": [ - "url_pattern", - "method" - ] - } - """ + And I get "Invalid Route" as response reason phrase Scenario: Error because of wrong route specification. If a request contains an invalid expression in the @@ -43,24 +34,4 @@ Feature: Kapow! server reject insert responses with semantic errors. } """ Then I get 422 as response code - And I get "Invalid Route Spec" as response reason phrase - And I get an empty response body - - Scenario: Error because of wrong method value. - If a request contains an invalid value in the - method field the server responds with an error. - - Given I have a running Kapow! server - When I insert the route: - """ - { - "method": "SOMETIMES", - "url_pattern": "/", - "entrypoint": "/bin/sh -c", - "command": "ls -la / | response /body", - "index": 0 - } - """ - Then I get 422 as response code - And I get "Invalid Data Type" as response reason phrase - And I get an empty response body + And I get "Invalid Route" as response reason phrase diff --git a/spec/test/features/control/insert/list_order.feature b/spec/test/features/control/insert/list_order.feature index aa0dca2..058639f 100644 --- a/spec/test/features/control/insert/list_order.feature +++ b/spec/test/features/control/insert/list_order.feature @@ -24,8 +24,8 @@ Feature: Routes auto-ordering after inserting in a Kapow! server. "index": 0 } """ - Then I get 200 as response code - And I get "OK" as response reason phrase + Then I get 201 as response code + And I get "Created" as response reason phrase And I get the following response body: """ { @@ -61,7 +61,7 @@ Feature: Routes auto-ordering after inserting in a Kapow! server. }, { "method": "GET", - "url_pattern": "/listDir/:dirname", + "url_pattern": "/listDir/{dirname}", "entrypoint": "/bin/sh -c", "command": "ls -la /request/params/dirname | response /body", "index": 2, @@ -84,8 +84,8 @@ Feature: Routes auto-ordering after inserting in a Kapow! server. "index": 2 } """ - Then I get 200 as response code - And I get "OK" as response reason phrase + Then I get 201 as response code + And I get "Created" as response reason phrase And I get the following response body: """ { @@ -113,7 +113,7 @@ Feature: Routes auto-ordering after inserting in a Kapow! server. }, { "method": "GET", - "url_pattern": "/listDir/:dirname", + "url_pattern": "/listDir/{dirname}", "entrypoint": "/bin/sh -c", "command": "ls -la /request/params/dirname | response /body", "index": 1, @@ -145,8 +145,8 @@ Feature: Routes auto-ordering after inserting in a Kapow! server. "index": 1 } """ - Then I get 200 as response code - And I get "OK" as response reason phrase + Then I get 201 as response code + And I get "Created" as response reason phrase And I get the following response body: """ { @@ -182,7 +182,7 @@ Feature: Routes auto-ordering after inserting in a Kapow! server. }, { "method": "GET", - "url_pattern": "/listDir/:dirname", + "url_pattern": "/listDir/{dirname}", "entrypoint": "/bin/sh -c", "command": "ls -la /request/params/dirname | response /body", "index": 2, diff --git a/spec/test/features/control/insert/success.feature b/spec/test/features/control/insert/success.feature index 4d5fcff..4dfddf8 100644 --- a/spec/test/features/control/insert/success.feature +++ b/spec/test/features/control/insert/success.feature @@ -23,8 +23,8 @@ Feature: Insert new routes in Kapow! server. "index": 0 } """ - Then I get 200 as response code - And I get "OK" as response reason phrase + Then I get 201 as response code + And I get "Created" as response reason phrase And I get the following response body: """ { @@ -52,8 +52,8 @@ Feature: Insert new routes in Kapow! server. "index": 1 } """ - Then I get 200 as response code - And I get "OK" as response reason phrase + Then I get 201 as response code + And I get "Created" as response reason phrase And I get the following response body: """ { diff --git a/spec/test/features/control/list/success.feature b/spec/test/features/control/list/success.feature index e50b410..f2b221a 100644 --- a/spec/test/features/control/list/success.feature +++ b/spec/test/features/control/list/success.feature @@ -37,7 +37,7 @@ Feature: Listing routes in a Kapow! server }, { "method": "GET", - "url_pattern": "/listDir/:dirname", + "url_pattern": "/listDir/{dirname}", "entrypoint": "/bin/sh -c", "command": "ls -la /request/params/dirname | response /body", "index": 1, diff --git a/spec/test/features/steps/comparedict.py b/spec/test/features/steps/comparedict.py index 2ba6a81..cdf2887 100644 --- a/spec/test/features/steps/comparedict.py +++ b/spec/test/features/steps/comparedict.py @@ -31,16 +31,10 @@ def _(model, obj): @is_subset.register(list) @assert_same_type def _(model, 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) -@assert_same_type -def _(model, obj): - return model <= obj + for a, b in zip(model, obj): + if not is_subset(a, b): + raise ValueError(f"Non-matching list member {a!r} in {b!r}") + return True @is_subset.register(ANY) diff --git a/spec/test/features/steps/steps.py b/spec/test/features/steps/steps.py index d0e3d38..e877a7c 100644 --- a/spec/test/features/steps/steps.py +++ b/spec/test/features/steps/steps.py @@ -103,18 +103,8 @@ def step_impl(context): def step_impl(context): context.response.raise_for_status() - if not hasattr(context, 'table'): - raise RuntimeError("A table must be set for this step.") + assert is_subset(jsonexample.loads(context.text), context.response.json()) - for entry, row in zip(context.response.json(), context.table): - for header in row.headings: - assert header in entry, f"Response does not contain the key {header}" - if row[header] != '*': - assert entry[header] == row[header], f"Values mismatch" - -# -# -# @when('I append the route') def step_impl(context): @@ -145,7 +135,7 @@ def step_impl(context): @when('I delete the route with id "{id}"') def step_impl(context, id): - raise NotImplementedError('STEP: When I delete the route with id "xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx"') + context.response = requests.delete(f"{Env.KAPOW_CONTROLAPI_URL}/routes/{id}") @given('It has a route with id "{id}"') @@ -155,12 +145,9 @@ def step_impl(context, id): @when('I insert the route') def step_impl(context): - if not hasattr(context, 'table'): - raise RuntimeError("A table must be set for this step.") - - row = context.table[0] context.response = requests.put(f"{Env.KAPOW_CONTROLAPI_URL}/routes", - json={h: row[h] for h in row.headings}) + headers={"Content-Type": "application/json"}, + data=context.text) @when('I try to append with this malformed JSON document') @@ -172,21 +159,32 @@ def step_impl(context): data=context.text) -@when('I delete the first route inserted') -def step_impl(context): - raise NotImplementedError('STEP: When I delete the first route inserted') +# @when('I delete the first route') +# @when('I delete the first route inserted') +# def step_impl(context): +# routes = requests.get(f"{Env.KAPOW_CONTROLAPI_URL}/routes") +# id = routes.json()[0]["id"] +# context.response = requests.delete(f"{Env.KAPOW_CONTROLAPI_URL}/routes/{id}") + +# @when('I delete the last route inserted') +# def step_impl(context): +# routes = requests.get(f"{Env.KAPOW_CONTROLAPI_URL}/routes") +# id = routes.json()[-1]["id"] +# context.response = requests.delete(f"{Env.KAPOW_CONTROLAPI_URL}/routes/{id}") -@when('I delete the last route inserted') -def step_impl(context): - raise NotImplementedError('STEP: When I delete the last route inserted') - - -@when('I delete the second route inserted') -def step_impl(context): - raise NotImplementedError('STEP: When I delete the second route inserted') +@when('I delete the {order} route') +@when('I delete the {order} route inserted') +def step_impl(context, order): + idx = {"first": 0, "second": 1, "last": -1}.get(order) + routes = requests.get(f"{Env.KAPOW_CONTROLAPI_URL}/routes") + id = routes.json()[idx]["id"] + context.response = requests.delete(f"{Env.KAPOW_CONTROLAPI_URL}/routes/{id}") @when('I try to insert with this JSON document') def step_impl(context): - raise NotImplementedError('STEP: When I try to insert with this JSON document') + context.response = requests.put( + f"{Env.KAPOW_CONTROLAPI_URL}/routes", + headers={"Content-Type": "application/json"}, + data=context.text)