def apply_suffix_patterns(urlpatterns, suffix_pattern, suffix_required):
    ret = []
    for urlpattern in urlpatterns:
        if isinstance(urlpattern, URLResolver):
            # Set of included URL patterns
            regex = get_regex_pattern(urlpattern)
            namespace = urlpattern.namespace
            app_name = urlpattern.app_name
            kwargs = urlpattern.default_kwargs
            # Add in the included patterns, after applying the suffixes
            patterns = apply_suffix_patterns(urlpattern.url_patterns,
                                             suffix_pattern, suffix_required)
            ret.append(
                url(regex, include((patterns, app_name), namespace), kwargs))
        else:
            # Regular URL pattern
            regex = get_regex_pattern(urlpattern).rstrip('$').rstrip(
                '/') + suffix_pattern
            view = urlpattern.callback
            kwargs = urlpattern.default_args
            name = urlpattern.name
            # Add in both the existing and the new urlpattern
            if not suffix_required:
                ret.append(urlpattern)
            ret.append(url(regex, view, kwargs, name))

    return ret
Esempio n. 2
0
    def test_nested_route(self):
        router = ExtendedSimpleRouter()
        (
            router.register(r'users', UserViewSet, 'user')
                  .register(r'groups', GroupViewSet, 'users-group', parents_query_lookups=['user'])
        )

        # test user list
        self.assertEqual(router.urls[0].name, 'user-list')
        self.assertEqual(get_regex_pattern(router.urls[0]), r'^users/$')

        # test user detail
        self.assertEqual(router.urls[1].name, 'user-detail')
        self.assertEqual(get_regex_pattern(router.urls[1]), r'^users/{0}/$'.format(self.get_lookup_regex('pk')))

        # test users group list
        self.assertEqual(router.urls[2].name, 'users-group-list')
        self.assertEqual(get_regex_pattern(router.urls[2]), r'^users/{0}/groups/$'.format(
                self.get_parent_lookup_regex('user')
            )
        )

        # test users group detail
        self.assertEqual(router.urls[3].name, 'users-group-detail')
        self.assertEqual(get_regex_pattern(router.urls[3]), r'^users/{0}/groups/{1}/$'.format(
                self.get_parent_lookup_regex('user'),
                self.get_lookup_regex('pk')
            ),
        )
def apply_suffix_patterns(urlpatterns, suffix_pattern, suffix_required):
    ret = []
    for urlpattern in urlpatterns:
        if isinstance(urlpattern, URLResolver):
            # Set of included URL patterns
            regex = get_regex_pattern(urlpattern)
            namespace = urlpattern.namespace
            app_name = urlpattern.app_name
            kwargs = urlpattern.default_kwargs
            # Add in the included patterns, after applying the suffixes
            patterns = apply_suffix_patterns(urlpattern.url_patterns,
                                             suffix_pattern,
                                             suffix_required)
            ret.append(url(regex, include((patterns, app_name), namespace), kwargs))
        else:
            # Regular URL pattern
            regex = get_regex_pattern(urlpattern).rstrip('$').rstrip('/') + suffix_pattern
            view = urlpattern.callback
            kwargs = urlpattern.default_args
            name = urlpattern.name
            # Add in both the existing and the new urlpattern
            if not suffix_required:
                ret.append(urlpattern)
            ret.append(url(regex, view, kwargs, name))

    return ret
Esempio n. 4
0
    def test_one_route(self):
        router = ExtendedSimpleRouter()
        router.register(r'users', UserViewSet, 'user')

        # test user list
        self.assertEqual(router.urls[0].name, 'user-list')
        self.assertEqual(get_regex_pattern(router.urls[0]), r'^users/$')

        # test user detail
        self.assertEqual(router.urls[1].name, 'user-detail')
        self.assertEqual(get_regex_pattern(router.urls[1]), r'^users/{0}/$'.format(self.get_lookup_regex('pk')))
Esempio n. 5
0
def apply_suffix_patterns(urlpatterns,
                          suffix_pattern,
                          suffix_required,
                          suffix_route=None):
    ret = []
    for urlpattern in urlpatterns:
        if isinstance(urlpattern, URLResolver):
            # Set of included URL patterns
            regex = get_regex_pattern(urlpattern)
            namespace = urlpattern.namespace
            app_name = urlpattern.app_name
            kwargs = urlpattern.default_kwargs
            # Add in the included patterns, after applying the suffixes
            patterns = apply_suffix_patterns(urlpattern.url_patterns,
                                             suffix_pattern, suffix_required,
                                             suffix_route)

            # if the original pattern was a RoutePattern we need to preserve it
            if is_route_pattern(urlpattern):
                assert path is not None
                route = str(urlpattern.pattern)
                new_pattern = path(route,
                                   include((patterns, app_name), namespace),
                                   kwargs)
            else:
                new_pattern = url(regex,
                                  include((patterns, app_name), namespace),
                                  kwargs)

            ret.append(new_pattern)
        else:
            # Regular URL pattern
            regex = get_regex_pattern(urlpattern).rstrip('$').rstrip(
                '/') + suffix_pattern
            view = urlpattern.callback
            kwargs = urlpattern.default_args
            name = urlpattern.name
            # Add in both the existing and the new urlpattern
            if not suffix_required:
                ret.append(urlpattern)

            # if the original pattern was a RoutePattern we need to preserve it
            if is_route_pattern(urlpattern):
                assert path is not None
                assert suffix_route is not None
                route = str(
                    urlpattern.pattern).rstrip('$').rstrip('/') + suffix_route
                new_pattern = path(route, view, kwargs, name)
            else:
                new_pattern = url(regex, view, kwargs, name)

            ret.append(new_pattern)

    return ret
 def get_all_view_names(self, urlpatterns, parent_regex=''):
     for pattern in urlpatterns:
         if isinstance(pattern, URLResolver):
             regex = '' if get_regex_pattern(
                 pattern) == "^" else get_regex_pattern(pattern)
             self.get_all_view_names(urlpatterns=pattern.url_patterns,
                                     parent_regex=parent_regex + regex)
         elif isinstance(pattern, URLPattern) and self._is_drf_view(
                 pattern) and not self._is_format_endpoint(pattern):
             api_endpoint = ApiEndpoint(pattern, parent_regex,
                                        self.drf_router)
             self.endpoints.append(api_endpoint)
    def get_api_endpoints(self, patterns=None, prefix=''):
        """
        Return a list of all available API endpoints by inspecting the URL conf.
        """
        if patterns is None:
            patterns = self.patterns

        api_endpoints = []

        for pattern in patterns:
            path_regex = prefix + get_regex_pattern(pattern)
            if isinstance(pattern, URLPattern):
                path = self.get_path_from_regex(path_regex)
                callback = pattern.callback
                if self.should_include_endpoint(path, callback):
                    for method in self.get_allowed_methods(callback):
                        endpoint = (path, method, callback)
                        api_endpoints.append(endpoint)

            elif isinstance(pattern, URLResolver):
                nested_endpoints = self.get_api_endpoints(
                    patterns=pattern.url_patterns,
                    prefix=path_regex
                )
                api_endpoints.extend(nested_endpoints)

        api_endpoints = sorted(api_endpoints, key=endpoint_ordering)

        return api_endpoints
    def get_api_endpoints(self, patterns=None, prefix=''):
        """
        Return a list of all available API endpoints by inspecting the URL conf.
        """
        if patterns is None:
            patterns = self.patterns

        api_endpoints = []

        for pattern in patterns:
            path_regex = prefix + get_regex_pattern(pattern)
            if isinstance(pattern, RegexURLPattern):
                path = self.get_path_from_regex(path_regex)
                callback = pattern.callback
                if self.should_include_endpoint(path, callback):
                    for method in self.get_allowed_methods(callback):
                        endpoint = (path, method, callback)
                        api_endpoints.append(endpoint)

            elif isinstance(pattern, RegexURLResolver):
                nested_endpoints = self.get_api_endpoints(
                    patterns=pattern.url_patterns, prefix=path_regex)
                api_endpoints.extend(nested_endpoints)

        api_endpoints = sorted(api_endpoints, key=endpoint_ordering)

        return api_endpoints
def apply_suffix_patterns(urlpatterns, suffix_pattern, suffix_required, suffix_route=None):
    ret = []
    for urlpattern in urlpatterns:
        if isinstance(urlpattern, URLResolver):
            # Set of included URL patterns
            regex = get_regex_pattern(urlpattern)
            namespace = urlpattern.namespace
            app_name = urlpattern.app_name
            kwargs = urlpattern.default_kwargs
            # Add in the included patterns, after applying the suffixes
            patterns = apply_suffix_patterns(urlpattern.url_patterns,
                                             suffix_pattern,
                                             suffix_required,
                                             suffix_route)

            # if the original pattern was a RoutePattern we need to preserve it
            if is_route_pattern(urlpattern):
                assert path is not None
                route = str(urlpattern.pattern)
                new_pattern = path(route, include((patterns, app_name), namespace), kwargs)
            else:
                new_pattern = url(regex, include((patterns, app_name), namespace), kwargs)

            ret.append(new_pattern)
        else:
            # Regular URL pattern
            regex = get_regex_pattern(urlpattern).rstrip('$').rstrip('/') + suffix_pattern
            view = urlpattern.callback
            kwargs = urlpattern.default_args
            name = urlpattern.name
            # Add in both the existing and the new urlpattern
            if not suffix_required:
                ret.append(urlpattern)

            # if the original pattern was a RoutePattern we need to preserve it
            if is_route_pattern(urlpattern):
                assert path is not None
                assert suffix_route is not None
                route = str(urlpattern.pattern).rstrip('$').rstrip('/') + suffix_route
                new_pattern = path(route, view, kwargs, name)
            else:
                new_pattern = url(regex, view, kwargs, name)

            ret.append(new_pattern)

    return ret
Esempio n. 10
0
    def test_nested_route_depth_3(self):
        router = ExtendedSimpleRouter()
        (router.register(r'users', UserViewSet, 'user').register(
            r'groups',
            GroupViewSet,
            'users-group',
            parents_query_lookups=['user']).register(r'permissions',
                                                     PermissionViewSet,
                                                     'users-groups-permission',
                                                     parents_query_lookups=[
                                                         'group__user',
                                                         'group',
                                                     ]))

        # test user list
        self.assertEqual(router.urls[0].name, 'user-list')
        self.assertEqual(get_regex_pattern(router.urls[0]), r'^users/$')

        # test user detail
        self.assertEqual(router.urls[1].name, 'user-detail')
        self.assertEqual(get_regex_pattern(router.urls[1]),
                         r'^users/{0}/$'.format(self.get_lookup_regex('pk')))

        # test users group list
        self.assertEqual(router.urls[2].name, 'users-group-list')
        self.assertEqual(
            get_regex_pattern(router.urls[2]), r'^users/{0}/groups/$'.format(
                self.get_parent_lookup_regex('user')))

        # test users group detail
        self.assertEqual(router.urls[3].name, 'users-group-detail')
        self.assertEqual(
            get_regex_pattern(router.urls[3]),
            r'^users/{0}/groups/{1}/$'.format(
                self.get_parent_lookup_regex('user'),
                self.get_lookup_regex('pk')),
        )

        # test users groups permission list
        self.assertEqual(router.urls[4].name, 'users-groups-permission-list')
        self.assertEqual(
            get_regex_pattern(router.urls[4]),
            r'^users/{0}/groups/{1}/permissions/$'.format(
                self.get_parent_lookup_regex('group__user'),
                self.get_parent_lookup_regex('group'),
            ))

        # test users groups permission detail
        self.assertEqual(router.urls[5].name, 'users-groups-permission-detail')
        self.assertEqual(
            get_regex_pattern(router.urls[5]),
            r'^users/{0}/groups/{1}/permissions/{2}/$'.format(
                self.get_parent_lookup_regex('group__user'),
                self.get_parent_lookup_regex('group'),
                self.get_lookup_regex('pk')),
        )
    def test_should_include_endpoint_excludes_correctly(self):
        """This is the specific method that should handle the exclusion"""
        inspector = EndpointEnumerator(self.patterns)

        # Not pretty. Mimics internals of EndpointEnumerator to put should_include_endpoint under test
        pairs = [(inspector.get_path_from_regex(get_regex_pattern(pattern)), pattern.callback)
                 for pattern in self.patterns]

        should_include = [
            inspector.should_include_endpoint(*pair) for pair in pairs
        ]

        expected = [False, False, True]

        assert should_include == expected
Esempio n. 12
0
    def test_should_include_endpoint_excludes_correctly(self):
        """This is the specific method that should handle the exclusion"""
        inspector = EndpointEnumerator(self.patterns)

        # Not pretty. Mimics internals of EndpointEnumerator to put should_include_endpoint under test
        pairs = [(inspector.get_path_from_regex(get_regex_pattern(pattern)),
                  pattern.callback) for pattern in self.patterns]

        should_include = [
            inspector.should_include_endpoint(*pair) for pair in pairs
        ]

        expected = [False, False, True]

        assert should_include == expected
Esempio n. 13
0
    def test_nested_route_depth_3(self):
        router = ExtendedSimpleRouter()
        (
            router.register(r'users', UserViewSet, 'user')
                  .register(r'groups', GroupViewSet, 'users-group', parents_query_lookups=['user'])
                  .register(r'permissions', PermissionViewSet, 'users-groups-permission', parents_query_lookups=[
                               'group__user',
                               'group',
                            ]
                  )
        )

        # test user list
        self.assertEqual(router.urls[0].name, 'user-list')
        self.assertEqual(get_regex_pattern(router.urls[0]), r'^users/$')

        # test user detail
        self.assertEqual(router.urls[1].name, 'user-detail')
        self.assertEqual(get_regex_pattern(router.urls[1]), r'^users/{0}/$'.format(self.get_lookup_regex('pk')))

        # test users group list
        self.assertEqual(router.urls[2].name, 'users-group-list')
        self.assertEqual(get_regex_pattern(router.urls[2]), r'^users/{0}/groups/$'.format(
                self.get_parent_lookup_regex('user')
            )
        )

        # test users group detail
        self.assertEqual(router.urls[3].name, 'users-group-detail')
        self.assertEqual(get_regex_pattern(router.urls[3]), r'^users/{0}/groups/{1}/$'.format(
                self.get_parent_lookup_regex('user'),
                self.get_lookup_regex('pk')
            ),
        )

        # test users groups permission list
        self.assertEqual(router.urls[4].name, 'users-groups-permission-list')
        self.assertEqual(get_regex_pattern(router.urls[4]), r'^users/{0}/groups/{1}/permissions/$'.format(
                self.get_parent_lookup_regex('group__user'),
                self.get_parent_lookup_regex('group'),
            )
        )

        # test users groups permission detail
        self.assertEqual(router.urls[5].name, 'users-groups-permission-detail')
        self.assertEqual(get_regex_pattern(router.urls[5]), r'^users/{0}/groups/{1}/permissions/{2}/$'.format(
                self.get_parent_lookup_regex('group__user'),
                self.get_parent_lookup_regex('group'),
                self.get_lookup_regex('pk')
            ),
        )
    def __get_allowed_methods__(self):
        viewset_methods = []
        if self.drf_router:
            for prefix, viewset, basename in self.drf_router.registry:
                if self.callback.cls != viewset:
                    continue

                lookup = self.drf_router.get_lookup_regex(viewset)
                routes = self.drf_router.get_routes(viewset)

                for route in routes:

                    # Only actions which actually exist on the viewset will be bound
                    mapping = self.drf_router.get_method_map(
                        viewset, route.mapping)
                    if not mapping:
                        continue

                    # Build the url pattern
                    regex = route.url.format(
                        prefix=prefix,
                        lookup=lookup,
                        trailing_slash=self.drf_router.trailing_slash)
                    if get_regex_pattern(self.pattern) == regex:
                        funcs, viewset_methods = zip(
                            *[(mapping[m], m.upper())
                              for m in self.callback.cls.http_method_names
                              if m in mapping])
                        viewset_methods = list(viewset_methods)
                        if len(set(funcs)) == 1:
                            self.docstring = inspect.getdoc(
                                getattr(self.callback.cls, funcs[0]))

        view_methods = [
            force_str(m).upper() for m in self.callback.cls.http_method_names
            if self.is_method_allowed(self.callback.cls, m)
        ]
        return sorted(viewset_methods + view_methods)
 def test_urls_limited_by_lookup_value_regex(self):
     expected = ['^notes/$', '^notes/(?P<uuid>[0-9a-f]{32})/$']
     for idx in range(len(expected)):
         assert expected[idx] == get_regex_pattern(self.urls[idx])
Esempio n. 16
0
def get_url_pattern_by_regex_pattern(patterns, pattern_string):
    # todo: test me
    for pattern in patterns:
        if get_regex_pattern(pattern) == pattern_string:
            return pattern
 def _is_format_endpoint(self, pattern):
     """
     Exclude endpoints with a "format" parameter
     """
     return '?P<format>' in get_regex_pattern(pattern)
 def __get_path__(self, parent_regex):
     regex = get_regex_pattern(self.pattern)
     if parent_regex:
         return "/{0}{1}".format(self.name_parent, simplify_regex(regex))
     return simplify_regex(regex)
Esempio n. 19
0
    def test_nested_route_depth_3_custom_regex(self):
        """
        Nested routes with over two level of depth should respect all parents'
        `lookup_value_regex` attribute.
        """
        router = ExtendedSimpleRouter()
        (
            router.register(r'users', CustomRegexUserViewSet, 'user')
                  .register(r'groups', CustomRegexGroupViewSet, 'users-group',
                            parents_query_lookups=['user'])
                  .register(r'permissions', CustomRegexPermissionViewSet,
                            'users-groups-permission', parents_query_lookups=[
                               'group__user',
                               'group',
                            ]
                  )
        )

        # custom regex configuration
        user_viewset_regex = CustomRegexUserViewSet.lookup_value_regex
        group_viewset_regex = CustomRegexGroupViewSet.lookup_value_regex
        perm_viewset_regex = CustomRegexPermissionViewSet.lookup_value_regex

        # test user list
        self.assertEqual(router.urls[0].name, 'user-list')
        self.assertEqual(get_regex_pattern(router.urls[0]), r'^users/$')

        # test user detail
        self.assertEqual(router.urls[1].name, 'user-detail')
        self.assertEqual(get_regex_pattern(router.urls[1]), r'^users/{0}/$'.format(
            self.get_custom_regex_lookup('pk', user_viewset_regex))
        )

        # test users group list
        self.assertEqual(router.urls[2].name, 'users-group-list')
        self.assertEqual(get_regex_pattern(router.urls[2]), r'^users/{0}/groups/$'.format(
                self.get_custom_regex_parent_lookup('user', user_viewset_regex)
            )
        )
        # test users group detail
        self.assertEqual(router.urls[3].name, 'users-group-detail')
        self.assertEqual(get_regex_pattern(router.urls[3]), r'^users/{0}/groups/{1}/$'.format(
                self.get_custom_regex_parent_lookup('user', user_viewset_regex),
                self.get_custom_regex_lookup('pk', group_viewset_regex)
            ),
        )
        # test users groups permission list
        self.assertEqual(router.urls[4].name, 'users-groups-permission-list')
        self.assertEqual(get_regex_pattern(router.urls[4]), r'^users/{0}/groups/{1}/permissions/$'.format(
                self.get_custom_regex_parent_lookup('group__user', user_viewset_regex),
                self.get_custom_regex_parent_lookup('group', group_viewset_regex),
            )
        )

        # test users groups permission detail
        self.assertEqual(router.urls[5].name, 'users-groups-permission-detail')
        self.assertEqual(get_regex_pattern(router.urls[5]), r'^users/{0}/groups/{1}/permissions/{2}/$'.format(
                self.get_custom_regex_parent_lookup('group__user', user_viewset_regex),
                self.get_custom_regex_parent_lookup('group', group_viewset_regex),
                self.get_custom_regex_lookup('pk', perm_viewset_regex)
            ),
        )
 def test_custom_lookup_url_kwarg_route(self):
     detail_route = kwarged_notes_router.urls[-1]
     detail_url_pattern = get_regex_pattern(detail_route)
     assert '^notes/(?P<text>' in detail_url_pattern
 def test_custom_lookup_field_route(self):
     detail_route = notes_router.urls[-1]
     detail_url_pattern = get_regex_pattern(detail_route)
     assert '<uuid>' in detail_url_pattern
 def test_custom_lookup_field_route(self):
     detail_route = notes_router.urls[-1]
     detail_url_pattern = get_regex_pattern(detail_route)
     assert '<uuid>' in detail_url_pattern
 def test_urls_limited_by_lookup_value_regex(self):
     expected = ['^notes/$', '^notes/(?P<uuid>[0-9a-f]{32})/$']
     for idx in range(len(expected)):
         assert expected[idx] == get_regex_pattern(self.urls[idx])
 def test_custom_lookup_url_kwarg_route(self):
     detail_route = kwarged_notes_router.urls[-1]
     detail_url_pattern = get_regex_pattern(detail_route)
     assert '^notes/(?P<text>' in detail_url_pattern
 def test_urls_can_have_trailing_slash_removed(self):
     expected = ['^notes$', '^notes/(?P<pk>[^/.]+)$']
     for idx in range(len(expected)):
         assert expected[idx] == get_regex_pattern(self.urls[idx])
 def test_urls_can_have_trailing_slash_removed(self):
     expected = ['^notes$', '^notes/(?P<pk>[^/.]+)$']
     for idx in range(len(expected)):
         assert expected[idx] == get_regex_pattern(self.urls[idx])