diff --git a/rest_framework/routers.py b/rest_framework/routers.py index 850bb408e..7bbfc12ec 100644 --- a/rest_framework/routers.py +++ b/rest_framework/routers.py @@ -68,16 +68,18 @@ class RouteTree: been set or if the path doesn't exist. """ routes = self.routes + parent_path = [] for part in path: if part not in routes: - # TODO: invalid path error message - raise KeyError('') - routes = routes[path].routes + on_path = (' on path %s' % parent_path) if len(parent_path) > 0 else '' + raise KeyError('Parent route "%s"%s was not registred' % (part, on_path)) + parent_path.append(part) + routes = routes[part].routes if name in routes: - # TODO: route name already exists error message - raise KeyError('') + on_path = (' on path %s' % path) if len(path) > 0 else '' + raise KeyError('Route "%s" already set%s' % (name, on_path)) routes[name] = self.Node({}, value) diff --git a/tests/test_routers.py b/tests/test_routers.py index f45039f80..351a0f61e 100644 --- a/tests/test_routers.py +++ b/tests/test_routers.py @@ -10,7 +10,7 @@ from django.test import TestCase, override_settings from rest_framework import permissions, serializers, viewsets from rest_framework.decorators import detail_route, list_route from rest_framework.response import Response -from rest_framework.routers import DefaultRouter, SimpleRouter +from rest_framework.routers import DefaultRouter, RouteTree, SimpleRouter from rest_framework.test import APIRequestFactory factory = APIRequestFactory() @@ -89,6 +89,53 @@ class BasicViewSet(viewsets.ViewSet): return Response({'method': 'link2'}) +class TestRouteTree(TestCase): + def setUp(self): + self.tree = RouteTree() + + def test_set(self): + """ + Should set the value for the given name and path. + """ + self.tree.set(1, [], 'A') + self.tree.set(2, ['A'], 'B') + self.tree.set(3, ['A', 'B'], 'C') + + root = self.tree.routes + self.assertEqual(list(root.keys()), ['A']) + self.assertEqual(root['A'].value, 1) + self.assertEqual(list(root['A'].routes.keys()), ['B']) + self.assertEqual(root['A'].routes['B'].value, 2) + self.assertEqual(list(root['A'].routes['B'].routes.keys()), ['C']) + self.assertEqual(root['A'].routes['B'].routes['C'].value, 3) + + def test_set_invalid(self): + """ + A KeyError should be raised for an invalid name or path. + """ + self.tree.set(1, [], 'A') + self.tree.set(2, ['A'], 'B') + + with self.assertRaises(KeyError): + self.tree.set(5, ['A', 'B', 'C', 'C'], 'E') + + with self.assertRaises(KeyError): + self.tree.set(20, ['A'], 'B') + + def test_get(self): + """ + Should return a list of (name, value) for each node on + the path. + """ + self.tree.set(1, [], 'A') + self.tree.set(2, ['A'], 'B') + self.tree.set(3, ['A', 'B'], 'C') + + self.assertEqual(self.tree.get(['A', 'B'], 'C'), [ + ('A', 1), ('B', 2), ('C', 3) + ]) + + class TestSimpleRouter(TestCase): def setUp(self): self.router = SimpleRouter()