def test_response_errors(self):
        client = Client("http://example.com", fetch_schema=False)

        User = client.resource_factory(
            "user",
            {
                "type": "object",
                "properties": {"$uri": {"type": "string", "readOnly": True}, "name": {"type": "string"}},
                "links": [
                    {"rel": "self", "method": "GET", "href": "/user/{id}"},
                    {"rel": "makeAdmin", "method": "POST", "href": "/user/{id}/make-admin"},
                ],
            },
        )

        responses.add(
            responses.GET, "http://example.com/user/1", status=404, json={"status": 404, "message": "Not Found"}
        )

        responses.add(
            responses.POST,
            "http://example.com/user/2/make-admin",
            status=400,
            json={"status": 400, "message": "Forbidden"},
        )

        with self.assertRaises(HTTPError) as ctx:
            User.fetch(1)

        self.assertEqual(404, ctx.exception.response.status_code)

        with self.assertRaises(HTTPError) as ctx:
            User.make_admin(id=2)

        self.assertEqual(400, ctx.exception.response.status_code)
    def test_resource_update_property(self):
        client = Client('http://example.com/api', fetch_schema=False)

        User = client.resource_factory('user', {
            "type": "object",
            "description": "The description for 'user'.",
            "properties": {
                "$uri": {
                    "type": "string",
                    "readOnly": True
                },
                "name": {
                    "type": "string"
                }
            },
            "links": []
        })

        user = User()
        user.name = 'foo'
        self.assertEqual('foo', user.name)
        self.assertEqual('foo', user['name'])
        self.assertEqual({
            "$uri": None,
            "name": "foo"
        }, user._properties)

        with self.assertRaises(AttributeError):
            user.id = 123
Exemple #3
0
    def test_singleton(self):
        client = Client('http://example.com/api', fetch_schema=False)

        User = client.resource_factory(
            'user', {
                "type":
                "object",
                "description":
                "The description for 'user'.",
                "properties": {
                    "$uri": {
                        "type": "string",
                        "readOnly": True
                    },
                    "name": {
                        "type": "string"
                    }
                },
                "links": [{
                    "rel": "self",
                    "href": "/api/user/{id}",
                    "method": "GET"
                }]
            })

        user_a = User('/api/user/123')
        user_b = User('/api/user/123')

        self.assertIs(user_a, user_b)

        user_c = User(123)
        self.assertIs(user_a, user_c)
    def test_fetch_resource_uri_id(self):
        client = Client('http://example.com', fetch_schema=False)

        User = client.resource_factory('user', {
            "type": "object",
            "properties": {
                "$uri": {
                    "type": "string",
                    "readOnly": True
                },
                "name": {
                    "type": "string"
                }
            },
            "links": [
                {
                    "rel": "self",
                    "method": "GET",
                    "href": "/user/{id}",
                    "schema": {
                        "$ref": "#"
                    }
                }
            ]
        })

        # should not result in a fetch:
        self.assertEqual('/user/123', uri_for(User('/user/123')))
        self.assertEqual(123, User('/user/123').id)
Exemple #5
0
    def test_resource_update_property(self):
        client = Client('http://example.com/api', fetch_schema=False)

        User = client.resource_factory(
            'user', {
                "type": "object",
                "description": "The description for 'user'.",
                "properties": {
                    "$uri": {
                        "type": "string",
                        "readOnly": True
                    },
                    "name": {
                        "type": "string"
                    }
                },
                "links": []
            })

        user = User()
        user.name = 'foo'
        self.assertEqual('foo', user.name)
        self.assertEqual('foo', user['name'])
        self.assertEqual({"$uri": None, "name": "foo"}, user._properties)

        with self.assertRaises(AttributeError):
            user.id = 123
    def test_decode_reference(self):
        client = Client('http://example.com', fetch_schema=False)

        User = client.resource_factory('user', {
            "type": "object",
            "properties": {
                "$uri": {
                    "type": "string",
                    "readOnly": True
                },
                "name": {
                    "type": "string"
                }
            },
            "links": [
                {
                    "rel": "self",
                    "method": "GET",
                    "href": "/user/{id}"
                },
                {
                    "rel": "instances",
                    "method": "GET",
                    "href": "/user"
                }
            ]
        })

        result = json.loads(json.dumps({
            "owner": {"$ref": "/user/123"}
        }), cls=PotionJSONDecoder, client=client)

        self.assertEqual({
            "owner": User(123)
        }, result)
Exemple #7
0
    def test_decode_reference(self):
        client = Client('http://example.com', fetch_schema=False)

        User = client.resource_factory(
            'user', {
                "type":
                "object",
                "properties": {
                    "$uri": {
                        "type": "string",
                        "readOnly": True
                    },
                    "name": {
                        "type": "string"
                    }
                },
                "links": [{
                    "rel": "self",
                    "method": "GET",
                    "href": "/user/{id}"
                }, {
                    "rel": "instances",
                    "method": "GET",
                    "href": "/user"
                }]
            })

        result = json.loads(json.dumps({"owner": {
            "$ref": "/user/123"
        }}),
                            cls=PotionJSONDecoder,
                            client=client)

        self.assertEqual({"owner": User(123)}, result)
    def test_singleton(self):
        client = Client('http://example.com/api', fetch_schema=False)

        User = client.resource_factory('user', {
            "type": "object",
            "description": "The description for 'user'.",
            "properties": {
                "$uri": {
                    "type": "string",
                    "readOnly": True
                },
                "name": {
                    "type": "string"
                }
            },
            "links": [
                {
                    "rel": "self",
                    "href": "/api/user/{id}",
                    "method": "GET"
                }
            ]
        })

        user_a = User('/api/user/123')
        user_b = User('/api/user/123')

        self.assertIs(user_a, user_b)

        user_c = User(123)
        self.assertIs(user_a, user_c)
Exemple #9
0
    def test_fetch_resource_uri_id(self):
        client = Client('http://example.com', fetch_schema=False)

        User = client.resource_factory(
            'user', {
                "type":
                "object",
                "properties": {
                    "$uri": {
                        "type": "string",
                        "readOnly": True
                    },
                    "name": {
                        "type": "string"
                    }
                },
                "links": [{
                    "rel": "self",
                    "method": "GET",
                    "href": "/user/{id}",
                    "schema": {
                        "$ref": "#"
                    }
                }]
            })

        # should not result in a fetch:
        self.assertEqual('/user/123', uri_for(User('/user/123')))
        self.assertEqual(123, User('/user/123').id)
    def test_pagination(self):
        client = Client("http://example.com", fetch_schema=False)

        User = client.resource_factory(
            "user",
            {
                "type": "object",
                "properties": {"$uri": {"type": "string", "readOnly": True}, "name": {"type": "string"}},
                "links": [
                    {"rel": "self", "href": "/user/{id}", "method": "GET"},
                    {
                        "rel": "instances",
                        "method": "GET",
                        "href": "/user",
                        "schema": {
                            "type": "object",
                            "properties": {
                                "page": {"default": 1, "minimum": 1, "type": "integer"},
                                "per_page": {"default": 20, "maximum": 100, "minimum": 1, "type": "integer"},
                            },
                        },
                        "target_schema": {"$ref": "#"},
                    },
                ],
            },
        )

        def request_callback(request):
            users = [{"$uri": "/user/{}".format(i), "name": "user-{}".format(i)} for i in range(1, 36)]

            params = parse_qs(urlparse(request.url).query)
            offset = (int(params["page"][0]) - 1) * int(params["per_page"][0])
            return 200, {"X-Total-Count": "35"}, json.dumps(users[offset : offset + int(params["per_page"][0])])

        responses.add_callback(
            responses.GET, "http://example.com/user", callback=request_callback, content_type="application/json"
        )

        result = User.instances()

        # TODO test: result = User.instances(where={"foo": {"$gt": 123}})
        # TODO magic: result = User.instances.where(foo__gt=123).sort(foo=DESC)

        self.assertIsInstance(result, PaginatedList)
        self.assertEqual(35, len(result))
        self.assertEqual(1, len(result._pages))
        self.assertEqual(
            [{"$uri": "/user/{}".format(i), "name": "user-{}".format(i)} for i in range(1, 36)], list(result)
        )
        self.assertEqual(2, len(result._pages))
        self.assertEqual(20, len(result._pages[1]))
        self.assertEqual(15, len(result._pages[2]))
Exemple #11
0
    def test_first(self):
        client = Client('http://example.com', fetch_schema=False)

        User = client.resource_factory(
            'user', {
                "type":
                "object",
                "properties": {
                    "$uri": {
                        "type": "string",
                        "readOnly": True
                    },
                    "name": {
                        "type": "string"
                    }
                },
                "links": [{
                    "rel": "instances",
                    "method": "GET",
                    "href": "/user",
                    "schema": {
                        "type": "object",
                        "properties": {
                            "page": {
                                "type": "number"
                            },
                            "per_page": {
                                "type": "number"
                            },
                        }
                    }
                }]
            })

        def request_callback(request):
            if 'missing' in request.url:
                return 200, {}, '[]'
            return 200, {}, json.dumps([{"$uri": "/user/1", "name": "foo"}])

        responses.add_callback(responses.GET,
                               'http://example.com/user',
                               callback=request_callback,
                               content_type='application/json')

        self.assertTrue(User.instances.returns_pagination())

        foo = User.first(where={"name": "foo"})
        self.assertEqual("foo", foo.name)

        with self.assertRaises(ItemNotFound):
            missing = User.first(where={"name": "missing"})
    def test_encode_reference(self):
        client = Client("http://example.com", fetch_schema=False)

        User = client.resource_factory(
            "user",
            {
                "type": "object",
                "properties": {"$uri": {"type": "string", "readOnly": True}, "name": {"type": "string"}},
                "links": [{"rel": "instances", "method": "GET", "href": "/user"}],
            },
        )

        result = json.loads(json.dumps({"owner": User(uri="/user/123", name="foo")}, cls=PotionJSONEncoder))

        self.assertEqual({"owner": {"$ref": "/user/123"}}, result)
    def test_response_errors(self):
        client = Client('http://example.com', fetch_schema=False)

        User = client.resource_factory('user', {
            "type": "object",
            "properties": {
                "$uri": {
                    "type": "string",
                    "readOnly": True
                },
                "name": {
                    "type": "string"
                }
            },
            "links": [
                {
                    "rel": "self",
                    "method": "GET",
                    "href": "/user/{id}"
                },
                {
                    "rel": "makeAdmin",
                    "method": "POST",
                    "href": "/user/{id}/make-admin"
                }
            ]
        })

        responses.add(responses.GET, 'http://example.com/user/1', status=404, json={
            "status": 404,
            "message": "Not Found"
        })

        responses.add(responses.POST, 'http://example.com/user/2/make-admin', status=400, json={
            "status": 400,
            "message": "Forbidden"
        })


        with self.assertRaises(HTTPError) as ctx:
            User.fetch(1)

        self.assertEqual(404, ctx.exception.response.status_code)

        with self.assertRaises(HTTPError) as ctx:
            User.make_admin(id=2)

        self.assertEqual(400, ctx.exception.response.status_code)
    def test_first(self):
        client = Client('http://example.com', fetch_schema=False)

        User = client.resource_factory('user', {
            "type": "object",
            "properties": {
                "$uri": {
                    "type": "string",
                    "readOnly": True
                },
                "name": {
                    "type": "string"
                }
            },
            "links": [
                {
                    "rel": "instances",
                    "method": "GET",
                    "href": "/user",
                    "schema": {
                        "type": "object",
                        "properties": {
                            "page": {"type": "number"},
                            "per_page": {"type": "number"},
                        }
                    }
                }
            ]
        })

        def request_callback(request):
            if 'missing' in request.url:
                return 200, {}, '[]'
            return 200, {}, json.dumps([{"$uri": "/user/1", "name": "foo"}])

        responses.add_callback(responses.GET, 'http://example.com/user',
                               callback=request_callback,
                               content_type='application/json')

        self.assertTrue(User.instances.returns_pagination())

        foo = User.first(where={"name": "foo"})
        self.assertEqual("foo", foo.name)

        with self.assertRaises(ItemNotFound):
            missing = User.first(where={"name": "missing"})
    def test_subclass_resource(self):
        client = Client("http://example.com", fetch_schema=False)

        class CustomResource(Resource):
            def is_car(self):
                return self.wheels == 4

        Vehicle = client.resource_factory(
            "vehicle",
            {
                "type": "object",
                "properties": {
                    "$uri": {"type": "string", "readOnly": True},
                    "name": {"type": "string"},
                    "wheels": {"type": "number"},
                },
                "links": [
                    {
                        "rel": "instances",
                        "method": "GET",
                        "href": "/vehicle",
                        "schema": {
                            "type": "object",
                            "properties": {"page": {"type": "number"}, "per_page": {"type": "number"}},
                        },
                    },
                    {"rel": "self", "method": "GET", "href": "/vehicle/{id}", "schema": {"$ref": "#"}},
                ],
            },
            resource_cls=CustomResource,
        )

        self.assertEqual(True, Vehicle(name="Quad", wheels=4).is_car())
        self.assertEqual(False, Vehicle(name="Bike", wheels=2).is_car())

        responses.add(
            responses.GET, "http://example.com/vehicle/2", json={"$uri": "/vehicle/2", "name": "Bus", "wheels": 6}
        )

        responses.add(
            responses.GET, "http://example.com/vehicle", json=[{"$uri": "/vehicle/2", "name": "Bus", "wheels": 6}]
        )

        self.assertEqual(6, Vehicle(2).wheels)
        self.assertEqual(False, Vehicle(2).is_car())
        self.assertEqual([Vehicle(2)], list(Vehicle.instances()))
    def test_decode_instance(self):
        client = Client("http://example.com", fetch_schema=False)

        User = client.resource_factory(
            "user",
            {
                "type": "object",
                "properties": {"$uri": {"type": "string", "readOnly": True}, "name": {"type": "string"}},
                "links": [{"rel": "instances", "method": "GET", "href": "/user"}],
            },
        )

        result = json.loads(json.dumps({"$uri": "/user/123", "name": "foo"}), cls=PotionJSONDecoder, client=client)

        self.assertEqual(client.instance("/user/123"), result)
        self.assertEqual("foo", result.name)
        self.assertEqual(123, result.id)
    def test_encode_decode_date(self):
        client = Client('http://example.com', fetch_schema=False)

        Event = client.resource_factory('event', {
            "type": "object",
            "properties": {
                "$uri": {
                    "type": "string",
                    "readOnly": True
                },
                "start_date": {
                    "type": "object",
                    "additionalProperties": False,
                    "properties": {
                        "$date": {
                            "type": "integer"
                        }
                    }
                }
            },
            "links": [
                {
                    "rel": "instances",
                    "method": "GET",
                    "href": "/event"
                },
                {
                    "rel": "create",
                    "method": "POST",
                    "href": "/event",
                    "schema": {
                        "type": "object",
                        "additionalProperties": False,
                        "properties": {
                            "start_date": {
                                "type": "object",
                                "additionalProperties": False,
                                "properties": {
                                    "$date": {
                                        "type": "integer"
                                    }
                                }
                            }
                        }
                    }
                }
            ]
        })

        responses.add(responses.GET, 'http://example.com/event', json=[
            {
                "$uri": "/event/1",
                "start_date": {
                    "$date": 1451060269000
                }
            }
        ])

        events = Event.instances()
        self.assertEqual(1, len(events))
        self.assertEqual({
            "$uri": "/event/1",
            "start_date": datetime(2015, 12, 25, 16, 17, 49, tzinfo=timezone.utc)
        }, events[0]._properties)


        def request_callback(request):
            request_data = json.loads(request.body)
            self.assertEqual({
                "start_date": {
                    "$date": 1451060269000
                }
            }, request_data)
            return 201, {}, json.dumps({
                "$uri": "/event/2",
                "start_date": request_data['start_date']
            })

        responses.add_callback(responses.POST, 'http://example.com/event',
                               callback=request_callback,
                               content_type='application/json')

        self.assertEqual(False, Event._create.schema.can_include_property('$uri'))
        self.assertEqual(True, Event._create.schema.can_include_property('start_date'))

        event = Event()
        event.start_date = datetime(2015, 12, 25, 16, 17, 49, tzinfo=timezone.utc)
        event.save()

        self.assertEqual(2, event.id)
        self.assertEqual({
            "$uri": "/event/2",
            "start_date": datetime(2015, 12, 25, 16, 17, 49, tzinfo=timezone.utc)
        }, event._properties)
Exemple #18
0
    def test_encode_decode_date(self):
        client = Client('http://example.com', fetch_schema=False)

        Event = client.resource_factory(
            'event', {
                "type":
                "object",
                "properties": {
                    "$uri": {
                        "type": "string",
                        "readOnly": True
                    },
                    "start_date": {
                        "type": "object",
                        "additionalProperties": False,
                        "properties": {
                            "$date": {
                                "type": "integer"
                            }
                        }
                    }
                },
                "links": [{
                    "rel": "instances",
                    "method": "GET",
                    "href": "/event"
                }, {
                    "rel": "create",
                    "method": "POST",
                    "href": "/event",
                    "schema": {
                        "type": "object",
                        "additionalProperties": False,
                        "properties": {
                            "start_date": {
                                "type": "object",
                                "additionalProperties": False,
                                "properties": {
                                    "$date": {
                                        "type": "integer"
                                    }
                                }
                            }
                        }
                    }
                }]
            })

        responses.add(responses.GET,
                      'http://example.com/event',
                      json=[{
                          "$uri": "/event/1",
                          "start_date": {
                              "$date": 1451060269000
                          }
                      }])

        events = Event.instances()
        self.assertEqual(1, len(events))
        self.assertEqual(
            {
                "$uri":
                "/event/1",
                "start_date":
                datetime(2015, 12, 25, 16, 17, 49, tzinfo=timezone.utc)
            }, events[0]._properties)

        def request_callback(request):
            request_data = json.loads(request.body)
            self.assertEqual({"start_date": {
                "$date": 1451060269000
            }}, request_data)
            return 201, {}, json.dumps({
                "$uri": "/event/2",
                "start_date": request_data['start_date']
            })

        responses.add_callback(responses.POST,
                               'http://example.com/event',
                               callback=request_callback,
                               content_type='application/json')

        self.assertEqual(False,
                         Event._create.schema.can_include_property('$uri'))
        self.assertEqual(
            True, Event._create.schema.can_include_property('start_date'))

        event = Event()
        event.start_date = datetime(2015,
                                    12,
                                    25,
                                    16,
                                    17,
                                    49,
                                    tzinfo=timezone.utc)
        event.save()

        self.assertEqual(2, event.id)
        self.assertEqual(
            {
                "$uri":
                "/event/2",
                "start_date":
                datetime(2015, 12, 25, 16, 17, 49, tzinfo=timezone.utc)
            }, event._properties)
    def test_pagination(self):
        client = Client('http://example.com', fetch_schema=False)

        User = client.resource_factory('user', {
            "type": "object",
            "properties": {
                "$uri": {
                    "type": "string",
                    "readOnly": True
                },
                "name": {
                    "type": "string"
                }
            },
            "links": [
                {
                    "rel": "self",
                    "href": "/user/{id}",
                    "method": "GET"
                },
                {
                    "rel": "instances",
                    "method": "GET",
                    "href": "/user",
                    "schema": {
                        "type": "object",
                        "properties": {
                            "page": {
                                "default": 1,
                                "minimum": 1,
                                "type": "integer"
                            },
                            "per_page": {
                                "default": 20,
                                "maximum": 100,
                                "minimum": 1,
                                "type": "integer"
                            }
                        }
                    },
                    "target_schema": {
                        "$ref": "#"
                    }
                }
            ]
        })

        def request_callback(request):
            users = [
                {
                    "$uri": "/user/{}".format(i),
                    "name": "user-{}".format(i)
                } for i in range(1, 36)
                ]

            params = parse_qs(urlparse(request.url).query)
            offset = (int(params['page'][0]) - 1) * int(params['per_page'][0])
            return 200, {'X-Total-Count': '35'}, json.dumps(users[offset:offset + int(params['per_page'][0])])

        responses.add_callback(responses.GET, 'http://example.com/user',
                               callback=request_callback,
                               content_type='application/json')

        result = User.instances()

        # TODO test: result = User.instances(where={"foo": {"$gt": 123}})
        # TODO magic: result = User.instances.where(foo__gt=123).sort(foo=DESC)

        self.assertIsInstance(result, PaginatedList)
        self.assertEqual(35, len(result))
        self.assertEqual(1, len(result._pages))
        self.assertEqual([
                             {
                                 "$uri": "/user/{}".format(i),
                                 "name": "user-{}".format(i)
                             } for i in range(1, 36)
                             ], list(result))
        self.assertEqual(2, len(result._pages))
        self.assertEqual(20, len(result._pages[1]))
        self.assertEqual(15, len(result._pages[2]))
    def test_subclass_resource(self):
        client = Client('http://example.com', fetch_schema=False)

        class CustomResource(Resource):

            def is_car(self):
                return self.wheels == 4

        Vehicle = client.resource_factory('vehicle', {
            "type": "object",
            "properties": {
                "$uri": {
                    "type": "string",
                    "readOnly": True
                },
                "name": {
                    "type": "string"
                },
                "wheels": {
                    "type": "number"
                }
            },
            "links": [
                {
                    "rel": "instances",
                    "method": "GET",
                    "href": "/vehicle",
                    "schema": {
                        "type": "object",
                        "properties": {
                            "page": {"type": "number"},
                            "per_page": {"type": "number"},
                        }
                    }
                },
                {
                    "rel": "self",
                    "method": "GET",
                    "href": "/vehicle/{id}",
                    "schema": {
                        "$ref": "#"
                    }
                }
            ]
        }, resource_cls=CustomResource)

        self.assertEqual(True, Vehicle(name="Quad", wheels=4).is_car())
        self.assertEqual(False, Vehicle(name="Bike", wheels=2).is_car())

        responses.add(responses.GET, 'http://example.com/vehicle/2', json={
            "$uri": "/vehicle/2",
            "name": "Bus",
            "wheels": 6
        })

        responses.add(responses.GET, 'http://example.com/vehicle', json=[{
            "$uri": "/vehicle/2",
            "name": "Bus",
            "wheels": 6
        }])

        self.assertEqual(6, Vehicle(2).wheels)
        self.assertEqual(False, Vehicle(2).is_car())
        self.assertEqual([Vehicle(2)], list(Vehicle.instances()))