# Path: ripozo/decorators.py
# class apimethod(object):
#     """
#     Decorator for declaring routes on a ripozo resource.
#     Any method in a ResourceBase subclass that is decorated
#     with this decorator will be exposed as an endpoint in
#     the greater application.  Although an apimethod can be
#     decorated with another apimethod, this is not recommended.
# 
#     Any method decorated with apimethod should return a ResourceBase
#     instance (or a subclass of it).
#     """
# 
#     def __init__(self, route='', endpoint=None, methods=None, no_pks=False, **options):
#         """
#         Initialize the decorator.  These are the options for the endpoint
#         that you are constructing.  It determines what url's will be
#         handled by the decorated method.
# 
#         .. code-block:: python
# 
#             class MyResource(ResourceBase):
#                 @apimethod(route='/myroute', methods=['POST', 'PUT']
#                 def my_method(cls, request):
#                     # ... Do something to handle the request and generate
#                     # the MyResource instance.
# 
#         :param str|unicode route: The route for endpoint.  This will
#             be appended to the base_url for the ResourceBase subclass
#             when constructing the actual route.
#         :param str|unicode endpoint: The name of the endpoint.  Defaults
#             to the function name.
#         :param list[str|unicode] methods: A list of the accepted http methods
#             for this endpoint.  Defaults to ['GET']
#         :param bool no_pks:  If this flag is set to True the ResourceBase
#             subclass's base_url_sans_pks property will be used instead
#             of the base_url.  This is necessary for List endpoints where
#             the pks are not part of the url.
#         :param dict options: Additionaly arguments to pass to the dispatcher
#             that is registering the route with the application.  This is
#             dependent on the individual dispatcher and web framework that
#             you are using.
#         """
#         _logger.info('Initializing apimethod route: %s with options %s', route, options)
#         self.route = route
#         if not methods:
#             methods = ['GET']
#         self.options = options
#         self.options['methods'] = methods
#         self.options['no_pks'] = no_pks
#         self.endpoint = endpoint
# 
#     def __call__(self, func):
#         """
#         The actual decorator that will be called and returns the method
#         that is a ripozo route.
# 
#         In addition to setting some properties on the function itself
#         (i.e. ``__rest_route__`` and ``routes``), It also wraps the actual
#         function calling both the preprocessors and postprocessors.
# 
#         preprocessors get at least the cls, name of the function, request as arguments
# 
#         postprocessors get the cls, function name, request and resource as arguments
# 
#         :param classmethod f:
#         :return: The wrapped classmethod that is an action
#             that can be performed on the resource.  For example,
#             any sort of CRUD action.
#         :rtype: classmethod
#         """
#         setattr(func, '__rest_route__', True)
#         routes = getattr(func, 'routes', [])
#         routes.append((self.route, self.endpoint, self.options))
#         setattr(func, 'routes', routes)
# 
#         @_apiclassmethod
#         @wraps(func)
#         def wrapped(cls, request, *args, **kwargs):
#             """
#             Runs the preo/postprocessors
#             """
#             for proc in cls.preprocessors:
#                 proc(cls, func.__name__, request, *args, **kwargs)
#             resource = func(cls, request, *args, **kwargs)
#             for proc in cls.postprocessors:
#                 proc(cls, func.__name__, request, resource, *args, **kwargs)
#             return resource
#         return wrapped


import logging
import types
import mock
import six
import unittest2
from ripozo.decorators import apimethod
from ripozo.resources.constructor import ResourceMetaClass
from ripozo.resources.relationships import Relationship, ListRelationship
from ripozo.resources.resource_base import ResourceBase, _get_apimethods
from ripozo_tests.helpers.inmemory_manager import InMemoryManager
        """
        Tests trying to use a self-referential relationship
        when constructing a resource
        """
        class Resource(ResourceBase):
            pks = 'id',
            _relationships = [
                Relationship('child', relation='Resource', embedded=True),
                Relationship('parent', relation='Resource')
            ]

        res = Resource(properties=dict(id=1))
        self.assertEqual(len(res.related_resources), 0)

        res = Resource(properties=dict(id=1, child=dict(id=2)))
        self.assertEqual(len(res.related_resources), 1)
        relation = res.related_resources[0][0]
        self.assertIsInstance(relation, Resource)

        res = Resource(properties=dict(id=1, child=dict(id=2, parent=dict(id=1))))
        self.assertEqual(len(res.related_resources), 1)
        relation = res.related_resources[0][0]
        self.assertIsInstance(relation, Resource)

        self.assertEqual(len(relation.related_resources), 1)
        parent = res.related_resources[0][0]
        self.assertIsInstance(parent, Resource)

    def test_get_apimethods_multiwrapped(self):
        class MyResource(ResourceBase):

# Path: ripozo/decorators.py
# class apimethod(object):
#     """
#     Decorator for declaring routes on a ripozo resource.
#     Any method in a ResourceBase subclass that is decorated
#     with this decorator will be exposed as an endpoint in
#     the greater application.  Although an apimethod can be
#     decorated with another apimethod, this is not recommended.
# 
#     Any method decorated with apimethod should return a ResourceBase
#     instance (or a subclass of it).
#     """
# 
#     def __init__(self, route='', endpoint=None, methods=None, no_pks=False, **options):
#         """
#         Initialize the decorator.  These are the options for the endpoint
#         that you are constructing.  It determines what url's will be
#         handled by the decorated method.
# 
#         .. code-block:: python
# 
#             class MyResource(ResourceBase):
#                 @apimethod(route='/myroute', methods=['POST', 'PUT']
#                 def my_method(cls, request):
#                     # ... Do something to handle the request and generate
#                     # the MyResource instance.
# 
#         :param str|unicode route: The route for endpoint.  This will
#             be appended to the base_url for the ResourceBase subclass
#             when constructing the actual route.
#         :param str|unicode endpoint: The name of the endpoint.  Defaults
#             to the function name.
#         :param list[str|unicode] methods: A list of the accepted http methods
#             for this endpoint.  Defaults to ['GET']
#         :param bool no_pks:  If this flag is set to True the ResourceBase
#             subclass's base_url_sans_pks property will be used instead
#             of the base_url.  This is necessary for List endpoints where
#             the pks are not part of the url.
#         :param dict options: Additionaly arguments to pass to the dispatcher
#             that is registering the route with the application.  This is
#             dependent on the individual dispatcher and web framework that
#             you are using.
#         """
#         _logger.info('Initializing apimethod route: %s with options %s', route, options)
#         self.route = route
#         if not methods:
#             methods = ['GET']
#         self.options = options
#         self.options['methods'] = methods
#         self.options['no_pks'] = no_pks
#         self.endpoint = endpoint
# 
#     def __call__(self, func):
#         """
#         The actual decorator that will be called and returns the method
#         that is a ripozo route.
# 
#         In addition to setting some properties on the function itself
#         (i.e. ``__rest_route__`` and ``routes``), It also wraps the actual
#         function calling both the preprocessors and postprocessors.
# 
#         preprocessors get at least the cls, name of the function, request as arguments
# 
#         postprocessors get the cls, function name, request and resource as arguments
# 
#         :param classmethod f:
#         :return: The wrapped classmethod that is an action
#             that can be performed on the resource.  For example,
#             any sort of CRUD action.
#         :rtype: classmethod
#         """
#         setattr(func, '__rest_route__', True)
#         routes = getattr(func, 'routes', [])
#         routes.append((self.route, self.endpoint, self.options))
#         setattr(func, 'routes', routes)
# 
#         @_apiclassmethod
#         @wraps(func)
#         def wrapped(cls, request, *args, **kwargs):
#             """
#             Runs the preo/postprocessors
#             """
#             for proc in cls.preprocessors:
#                 proc(cls, func.__name__, request, *args, **kwargs)
#             resource = func(cls, request, *args, **kwargs)
#             for proc in cls.postprocessors:
#                 proc(cls, func.__name__, request, resource, *args, **kwargs)
#             return resource
#         return wrapped


# Path: ripozo_tests/unit/resources/base.py
import logging
import types
import mock
import six
import unittest2
from ripozo.decorators import apimethod
from ripozo.resources.constructor import ResourceMetaClass
from ripozo.resources.relationships import Relationship, ListRelationship
from ripozo.resources.resource_base import ResourceBase, _get_apimethods
from ripozo_tests.helpers.inmemory_manager import InMemoryManager

        """
        Tests trying to use a self-referential relationship
        when constructing a resource
        """
        class Resource(ResourceBase):
            pks = 'id',
            _relationships = [
                Relationship('child', relation='Resource', embedded=True),
                Relationship('parent', relation='Resource')
            ]

        res = Resource(properties=dict(id=1))
        self.assertEqual(len(res.related_resources), 0)

        res = Resource(properties=dict(id=1, child=dict(id=2)))
        self.assertEqual(len(res.related_resources), 1)
        relation = res.related_resources[0][0]
        self.assertIsInstance(relation, Resource)

        res = Resource(properties=dict(id=1, child=dict(id=2, parent=dict(id=1))))
        self.assertEqual(len(res.related_resources), 1)
        relation = res.related_resources[0][0]
        self.assertIsInstance(relation, Resource)

        self.assertEqual(len(relation.related_resources), 1)
        parent = res.related_resources[0][0]
        self.assertIsInstance(parent, Resource)

    def test_get_apimethods_multiwrapped(self):
        class MyResource(ResourceBase):

            @apimethod(methods=['GET'])