def test_get_example_values_get_http_method_with_list_and_dict_vals(self):
        """
        This test verifies if the route we are generating example values for
        is a GET endpoint and the example values are lists or dicts, that we
        json.dumps them when they are returned.  If the HTTP method is any
        other method, they will be returned as normal lists or dicts.
        """
        def mock_logic(e: ExampleArray, f: ExampleObject):
            pass

        mock_logic = add_doctor_attrs(mock_logic)
        route = Rule('/foo/bar/')

        annotation = ResourceAnnotation(mock_logic, 'GET')
        harness = base.BaseHarness('http://foo/bar/')
        example_values = harness._get_example_values(route, annotation)
        expected = {
            'e': json.dumps(['ex', 'array']),
            'f': json.dumps({'str': 'ex str'}),
        }
        assert expected == example_values

        # Change the http method to something other than GET, they should
        # not be json dumped.
        annotation.http_method = 'POST'
        example_values = harness._get_example_values(route, annotation)
        expected = {
            'e': ['ex', 'array'],
            'f': {
                'str': 'ex str'
            },
        }
        assert expected == example_values
    def test_get_json_object_lines_for_request(self):
        """
        This tests that when the request kwarg is True that any
        required params have the description prefixed with
        **Required** and sorted in alphabetical order, followed by
        any optional parameters in alpabetical order.
        """
        def mock_logic(auth: Auth, age: Age, is_deleted: IsDeleted = True):
            pass

        mock_logic = add_doctor_attrs(mock_logic)
        annotation = ResourceAnnotation(mock_logic, 'GET')
        parameters = annotation.logic._doctor_signature.parameters
        properties = {k: p.annotation for k, p in parameters.items()}
        url_params = ['age']
        result = base.get_json_object_lines(annotation,
                                            properties,
                                            field='>json',
                                            url_params=url_params,
                                            request=True)
        assert result == [
            ':param int age: **Required**.  age',
            ':>json str auth: **Required**.  auth token',
            (':>json bool is_deleted: Indicates if the item should be marked '
             'as deleted (Defaults to `True`) '),
        ]
    def test_get_example_values_when_logic_defines_req_obj_type(self):
        """
        This tests that we generate example values appropriately when the
        route defineds a req_obj_type which will pass all request params as
        that object instance to the logic function.

        If a req_obj_type was not defined for the logic, it would expect
        the json body to look like:

        {
            "foo": {
                "foo": "foo",
                "foo_id": 1
            }
        }

        Defining a req_obj_type tells the code that the request body should
        contain those attributes rather than a sub-key within the request.
        """
        def mock_logic(foo: FooInstance):
            pass

        mock_logic = add_doctor_attrs(mock_logic, req_obj_type=FooInstance)
        route = Rule('/foo/bar/')

        annotation = ResourceAnnotation(mock_logic, 'POST')
        harness = base.BaseHarness('http://foo/bar/')
        example_values = harness._get_example_values(route, annotation)
        expected = {
            'foo': 'foo',
            'foo_id': 1,
        }
        assert expected == example_values
def annotation():
    def logic(age: Age,
              name: Name,
              item_id: ItemId = None,
              color: Color = 'green'):
        pass

    logic = add_doctor_attrs(logic)
    annotation = ResourceAnnotation(logic, 'GET')
    return annotation
    def test_get_json_lines_array_response(self):
        """
        Verifies we document properties of an array of objects.
        """
        def mock_logic() -> ExampleObjects:
            pass

        mock_logic = add_doctor_attrs(mock_logic)
        annotation = ResourceAnnotation(mock_logic, 'GET')
        result = base.get_json_lines(annotation, field='<json', route='/foo')
        assert result == [':<jsonarr str str: auth token']
    def test_init_title(self):
        def logic():
            pass

        logic = add_doctor_attrs(logic)
        tests = (
            # (http_method, title, expected)
            ('GET', None, 'Retrieve'),
            ('POST', None, 'Create'),
            ('PUT', None, 'Update'),
            ('DELETE', None, 'Delete'),
            ('PUT', 'Batch', 'Batch'),
        )
        for http_method, title, expected in tests:
            annotation = ResourceAnnotation(logic, http_method, title=title)
            assert annotation.title == expected
    def test_get_json_object_lines_object_response(self):
        """
        This tests that when our response is an object that we return
        all of it's documented properties.
        """
        def mock_logic() -> ExampleObject:
            pass

        mock_logic = add_doctor_attrs(mock_logic)
        annotation = ResourceAnnotation(mock_logic, 'GET')
        result = base.get_json_lines(annotation,
                                     field='>json',
                                     route='/foo',
                                     request=False)
        expected = [':>json str str: auth token']
        assert expected == result
    def test_get_json_lines_response_response(self):
        """
        Verifies when our response is a doctor.response.Response instance
        and it has a type associated with it that we use that type to
        document it.
        """
        def mock_logic() -> Response[ExampleObject]:
            pass

        mock_logic = add_doctor_attrs(mock_logic)
        annotation = ResourceAnnotation(mock_logic, 'GET')
        result = base.get_json_lines(annotation,
                                     field='>json',
                                     route='/foo',
                                     request=False)
        expected = [':>json str str: auth token']
        assert expected == result
    def test_init(self):
        def logic(user_id: int, item_id: ItemId):
            pass

        logic = add_doctor_attrs(logic)
        annotation = ResourceAnnotation(logic, 'POST')
        assert annotation.logic == logic
        assert annotation.http_method == 'POST'
        assert annotation.title == 'Create'

        # Verify that the annotated_parameters attribute only has parameters
        # from the signature that are doctor types.  It shouldn't include
        # `user_id` since int doesn't extend doctor.types.SuperType
        expected = Parameter('item_id',
                             Parameter.POSITIONAL_OR_KEYWORD,
                             default=Parameter.empty,
                             annotation=ItemId)
        assert {'item_id': expected} == annotation.annotated_parameters
    def test_get_json_lines_logic_defines_req_obj_type(self):
        """
        This tests that we properly generate the json params for a request
        when the logic function defines a `req_obj_type`.
        """
        def mock_logic(foo: FooInstance):
            pass

        mock_logic = add_doctor_attrs(mock_logic, req_obj_type=FooInstance)
        annotation = ResourceAnnotation(mock_logic, 'POST')
        result = base.get_json_lines(annotation,
                                     field='<json',
                                     route='/foo',
                                     request=True)
        expected = [
            ':<json int foo_id: **Required**.  foo id', ':<json str foo: foo'
        ]
        assert expected == result
    def test_get_json_object_lines_for_request_with_enum(self):
        def mock_logic(auth: Auth,
                       is_alive: IsAlive,
                       name: Name = None,
                       color: Color = 'blue'):
            pass

        mock_logic = add_doctor_attrs(mock_logic)
        annotation = ResourceAnnotation(mock_logic, 'GET')
        parameters = annotation.logic._doctor_signature.parameters
        properties = {k: p.annotation for k, p in parameters.items()}
        result = base.get_json_object_lines(annotation,
                                            properties,
                                            field='>json',
                                            url_params=[],
                                            request=True)
        assert result == [
            ':>json str auth: **Required**.  auth token',
            ':>json bool is_alive: **Required**.  Is alive?',
            (":>json str color: Color Must be one of: `['blue', 'green']` "
             "(case-insensitive). (Defaults to `blue`) "),
            ':>json str name: name (Defaults to `None`) '
        ]