class SQLAlchemySequenceTestCase(BaseTestCase): def setUp(self): super(SQLAlchemySequenceTestCase, self).setUp() self.app.config['SQLALCHEMY_ENGINE'] = 'sqlite://' self.api = Api(self.app) self.sa = SQLAlchemy(self.app, session_options={"autoflush": False}) def test_sequence_primary_key(self): sa = self.sa user_id_seq = sa.Sequence('user_id_seq') class User(sa.Model): id = sa.Column(sa.Integer, user_id_seq, primary_key=True) username = sa.Column(sa.String, unique=True) sa.create_all() class UserResource(ModelResource): class Schema: username = fields.String() class Meta: model = User include_id = True self.api.add_resource(UserResource) response = self.client.post('/user', data={"username": "******"}) self.assert200(response) self.assertJSONEqual({"$id": 1, "username": "******"}, response.json)
def setUp(self): super(ErrorMessagesTestCase, self).setUp() self.api = Api(self.app, prefix='/prefix') class ErrorResource(Resource): @Route.GET def forbidden(self): raise Forbidden() @Route.GET def python_exception(self): raise ValueError() @Route.GET def duplicate_key(self): raise DuplicateKey() @Route.GET def custom_message(self): raise PotionException('something went wrong') class Meta: name = 'error' self.api.add_resource(ErrorResource)
def test_api_register_resource(self): class BookResource(ModelResource): class Meta: name = "book" model = "book" manager = MemoryManager api = Api(self.app) api.add_resource(BookResource) response = self.client.get("/schema") self.assertEqual( { "$schema": "http://json-schema.org/draft-04/hyper-schema#", "properties": { "book": { "$ref": "/book/schema#" } }, }, response.json, ) response = self.client.get("/book/schema") self.assert200(response)
class SQLAlchemyInspectionTestCase(BaseTestCase): def setUp(self): super(SQLAlchemyInspectionTestCase, self).setUp() self.app.config["SQLALCHEMY_ENGINE"] = "sqlite://" self.api = Api(self.app) self.sa = sa = SQLAlchemy(self.app, session_options={"autoflush": False}) def test_inspection_auto_id_attribute_type(self): sa = self.sa class User(sa.Model): username = sa.Column(sa.String, primary_key=True) first_name = sa.Column(sa.String) last_name = sa.Column(sa.String) sa.create_all() class UserResource(ModelResource): class Schema: username = fields.String() class Meta: model = User include_id = True self.api.add_resource(UserResource) self.assertEqual(User.username, UserResource.manager.id_column) self.assertEqual("username", UserResource.manager.id_field.attribute) self.assertIsInstance(UserResource.manager.id_field, fields.String) response = self.client.post("/user", data={"username": "******", "first_name": "Foo"}) self.assert200(response) self.assertJSONEqual({"$id": "foo", "first_name": "Foo", "last_name": None, "username": "******"}, response.json)
def setUp(self): super(PrincipalTestCase, self).setUp() self.mock_user = None @identity_loaded.connect_via(self.app) def on_identity_loaded(sender, identity): identity.provides.add(UserNeed(identity.id)) for role in self.mock_user.get('roles', []): identity.provides.add(RoleNeed(role)) for need in self.mock_user.get('needs', []): identity.provides.add(need) def authenticate(fn): @wraps(fn) def wrapper(*args, **kwargs): auth = request.authorization if not auth: raise Unauthorized() if auth.password == 'password': identity_changed.send(current_app._get_current_object(), identity=Identity( self.mock_user['id'])) else: raise Unauthorized() return fn(*args, **kwargs) return wrapper self.api = Api(self.app, decorators=[authenticate])
def test_api_blueprint(self): api_bp = Blueprint("potion_blueprint", __name__.split(".")[0]) api = Api(api_bp) api.add_resource(self.SampleResource) # Register Blueprint self.app.register_blueprint(api_bp) self.client.get("/samples")
def setUp(self): super(FieldsTestCase, self).setUp() app = self.app app.config['MONGODB_DB'] = 'potion-test-db' app.config['TESTING'] = True self.api = Api(self.app, default_manager=MongoEngineManager) self.me = MongoEngine(app)
def test_api_blueprint(self): api_bp = Blueprint("potion_blueprint", __name__.split(".")[0]) api = Api(api_bp) api.add_resource(self.SampleResource) # Register Blueprint self.app.register_blueprint(api_bp) response = self.client.get("/samples")
class ErrorMessagesTestCase(BaseTestCase): def setUp(self): super(ErrorMessagesTestCase, self).setUp() self.api = Api(self.app, prefix='/prefix') class ErrorResource(Resource): @Route.GET def forbidden(self): raise Forbidden() @Route.GET def python_exception(self): raise ValueError() @Route.GET def duplicate_key(self): raise DuplicateKey() class Meta: name = 'error' self.api.add_resource(ErrorResource) def test_werkzeug_exception(self): response = self.client.get('/prefix/error/forbidden') self.assert403(response) self.assertEqual({ "message": "You don't have the permission to access the requested resource. " "It is either read-protected or not readable by the server.", "status": 403 }, response.json) def test_potion_exception(self): response = self.client.get('/prefix/error/duplicate-key') self.assertStatus(response, 409) self.assertEqual({ "message": "Conflict", "status": 409 }, response.json) def test_not_found_exception(self): response = self.client.get('/prefix/error/missing') self.assert404(response) self.assertEqual({ "message": "The requested URL was not found on the server. If you entered " "the URL manually please check your spelling and try again.", "status": 404 }, response.json) def test_exception_outside_api(self): response = self.client.get('/missing') self.assert404(response) @unittest.SkipTest def test_python_exception(self): response = self.client.get('/prefix/error/python-exception') self.assert500(response) self.assertEqual({}, response.json)
def setUp(self): super(SQLAlchemySignalTestCase, self).setUp() self.app.config['SQLALCHEMY_ENGINE'] = 'sqlite://' self.api = Api(self.app) self.sa = sa = SQLAlchemy(self.app) class User(sa.Model): id = sa.Column(sa.Integer, primary_key=True) parent_id = sa.Column(sa.Integer, sa.ForeignKey(id)) name = sa.Column(sa.String(60), nullable=False) gender = sa.Column(sa.String(1)) parent = sa.relationship('User', remote_side=[id], backref=backref('children')) def __eq__(self, other): return self.name == other.name def __repr__(self): return 'User({})'.format(self.name) class Group(sa.Model): id = sa.Column(sa.Integer, primary_key=True) name = sa.Column(sa.String(60), nullable=False) class GroupMembership(sa.Model): id = sa.Column(sa.Integer, primary_key=True) user_id = sa.Column(sa.Integer, sa.ForeignKey(User.id), nullable=False) group_id = sa.Column(sa.Integer, sa.ForeignKey(Group.id), nullable=False) user = sa.relationship(User) group = sa.relationship(Group) sa.create_all() class UserResource(ModelResource): class Meta: model = User children = Relation('self') class GroupResource(ModelResource): class Meta: model = Group members = Relation(UserResource) self.User = User self.Group = Group self.UserResource = UserResource self.GroupResource = GroupResource self.api.add_resource(UserResource) self.api.add_resource(GroupResource)
def setUp(self): super(FilterTestCase, self).setUp() app = self.app app.config['SQLALCHEMY_ENGINE'] = 'sqlite://' app.config['TESTING'] = True self.api = Api(self.app) self.sa = sa = SQLAlchemy(app) class User(sa.Model): id = sa.Column(sa.Integer, primary_key=True) first_name = sa.Column(sa.String(60), nullable=False) last_name = sa.Column(sa.String(60), nullable=False) gender = sa.Column(sa.String(1)) age = sa.Column(sa.Integer) is_staff = sa.Column(sa.Boolean, default=None) class Thing(sa.Model): id = sa.Column(sa.Integer, primary_key=True) name = sa.Column(sa.String(60), nullable=False) belongs_to_id = sa.Column(sa.Integer, sa.ForeignKey(User.id)) belongs_to = sa.relationship(User) sa.create_all() class UserResource(ModelResource): class Schema: gender = fields.String(enum=['f', 'm'], nullable=True) class Meta: model = User include_id = True class ThingResource(ModelResource): class Schema: belongs_to = fields.ToOne('user') class Meta: model = Thing class AllowUserResource(ModelResource): class Meta: model = User name = 'allow-user' allowed_filters = {'first_name': ['$eq'], 'is_staff': '*'} self.api.add_resource(UserResource) self.api.add_resource(ThingResource) self.api.add_resource(AllowUserResource)
def test_api_blueprint_w_prefix(self): api_bp = Blueprint("potion_blueprint", __name__.split(".")[0]) api = Api(api_bp, prefix="/api/v1") api.add_resource(self.SampleResource) # Register Blueprint self.app.register_blueprint(api_bp) response = self.client.get("/api/v1/samples") self.assert200(response) response = self.client.get("/api/v1/samples/schema") self.assertEqual('^\\/api\\/v1\\/samples\\/[^/]+$', response.json['properties']['$uri']['pattern'])
def setUp(self): super(SQLAlchemyRelationTestCase, self).setUp() self.app.config['SQLALCHEMY_ENGINE'] = 'sqlite://' self.api = Api(self.app) self.sa = sa = SQLAlchemy(self.app, session_options={"autoflush": False}) group_members = sa.Table( 'group_members', sa.Column('group_id', sa.Integer(), sa.ForeignKey('group.id')), sa.Column('user_id', sa.Integer(), sa.ForeignKey('user.id')), ) class User(sa.Model): id = sa.Column(sa.Integer, primary_key=True) parent_id = sa.Column(sa.Integer, sa.ForeignKey(id)) name = sa.Column(sa.String(60), nullable=False) parent = sa.relationship('User', remote_side=[id], backref=backref('children', lazy='dynamic')) class Group(sa.Model): id = sa.Column(sa.Integer, primary_key=True) name = sa.Column(sa.String(60), nullable=False) members = sa.relationship( 'User', secondary=group_members, backref=backref('memberships', lazy='dynamic'), ) sa.create_all() class UserResource(ModelResource): class Meta: model = User include_id = True include_type = True children = Relation('self') class GroupResource(ModelResource): class Meta: model = Group include_id = True include_type = True members = Relation('user') self.api.add_resource(UserResource) self.api.add_resource(GroupResource)
def init_app(app): """ Configuring the Flask app's extensions """ # initialize Flask extensions app.db = init_db(app) # setup Flask-Potion routes v1_api = Api(app) v1_api.add_resource(BetaResource) v1_api.add_resource(AlphaResource) return app
def test_route_decorator(self): def unauthorize(fn): @wraps(fn) def wrapper(*args, **kwargs): raise Unauthorized() return wrapper def denormalize(fn): @wraps(fn) def wrapper(*args, **kwargs): return 'not ' + fn(*args, **kwargs) return wrapper class FooResource(Resource): @Route.GET def no_decorator(self): return 'normal' @Route.GET def simple_decorator(self): return 'normal' @Route.GET def unauthorize_decorator(self): return 'normal' class Meta: name = 'foo' title = 'Foo bar' route_decorators = { 'readSimpleDecorator': denormalize, 'readUnauthorizeDecorator': unauthorize } self.assertEqual('normal', FooResource().no_decorator()) self.assertEqual('normal', FooResource().simple_decorator()) self.assertEqual('normal', FooResource().unauthorize_decorator()) api = Api(self.app) api.add_resource(FooResource) response = self.client.get("/foo/no-decorator") self.assertEqual('normal', response.json) response = self.client.get("/foo/simple-decorator") self.assertEqual('not normal', response.json) response = self.client.get("/foo/unauthorize-decorator") self.assert401(response)
def test_route_decorator(self): def unauthorize(fn): @wraps(fn) def wrapper(*args, **kwargs): raise Unauthorized() return wrapper def denormalize(fn): @wraps(fn) def wrapper(*args, **kwargs): return 'not ' + fn(*args, **kwargs) return wrapper class FooResource(Resource): @Route.GET def no_decorator(self): return 'normal' @Route.GET def simple_decorator(self): return 'normal' @Route.GET def unauthorize_decorator(self): return 'normal' class Meta: name = 'foo' title = 'Foo bar' route_decorators = { 'readSimpleDecorator': denormalize, 'readUnauthorizeDecorator': unauthorize, } self.assertEqual('normal', FooResource().no_decorator()) self.assertEqual('normal', FooResource().simple_decorator()) self.assertEqual('normal', FooResource().unauthorize_decorator()) api = Api(self.app) api.add_resource(FooResource) response = self.client.get("/foo/no-decorator") self.assertEqual('normal', response.json) response = self.client.get("/foo/simple-decorator") self.assertEqual('not normal', response.json) response = self.client.get("/foo/unauthorize-decorator") self.assert401(response)
def setUp(self): super(MongoEngineTestCase, self).setUp() self.app.config['MONGODB_DB'] = 'potion-test-db' self.api = Api(self.app, default_manager=MongoEngineManager) self.me = me = MongoEngine(self.app) class Type(me.Document): meta = {"collection": "type"} name = StringField(max_length=60, null=False, unique=True) @property def machines(self): return Machine.objects(type=self) @machines.setter def machines(self, machines): for m in machines: m.type = self class Machine(me.Document): meta = {"collection": "machine"} name = StringField(max_length=60, null=False) wattage = FloatField(null=True) type = ReferenceField(Type) class MachineResource(ModelResource): class Meta: model = Machine include_id = True include_type = True class Schema: type = fields.ToOne('type') class TypeResource(ModelResource): class Meta: model = Type include_id = True include_type = True class Schema: machines = fields.ToMany('machine') self.MachineResource = MachineResource self.TypeResource = TypeResource self.api.add_resource(MachineResource) self.api.add_resource(TypeResource)
def setUp(self): super(PeeweeSignalTestCase, self).setUp() app = self.app app.config['DATABASE'] = 'sqlite://' self.db = db = PeeweeTestDB(self.app) self.api = Api(self.app, default_manager=PeeweeManager) class User(db.Model): name = CharField(max_length=60) gender = CharField(max_length=1, null=True) parent = ForeignKeyField('self', null=True, related_name='children') def __eq__(self, other): return self.name == other.name def __repr__(self): return 'User({})'.format(self.name) class Group(db.Model): name = CharField(max_length=60) class GroupMembership(db.Model): user = ForeignKeyField(User) group = ForeignKeyField(Group) db.database.connect() db.database.create_tables([User, Group, GroupMembership]) class UserResource(ModelResource): class Meta: model = User children = Relation('self') class GroupResource(ModelResource): class Meta: model = Group members = Relation(UserResource) self.User = User self.Group = Group self.UserResource = UserResource self.GroupResource = GroupResource self.api.add_resource(UserResource) self.api.add_resource(GroupResource)
def setUp(self): super(SQLAlchemyTestCase, self).setUp() self.app.config['SQLALCHEMY_ENGINE'] = 'sqlite://' self.api = Api(self.app, default_manager=SQLAlchemyManager) self.sa = sa = SQLAlchemy(self.app, session_options={"autoflush": False}) class Type(sa.Model): id = sa.Column(sa.Integer, primary_key=True) name = sa.Column(sa.String(60), nullable=False, unique=True) version = sa.Column(sa.Integer(), nullable=True) class Machine(sa.Model): id = sa.Column(sa.Integer, primary_key=True) name = sa.Column(sa.String(60), nullable=False) wattage = sa.Column(sa.Float) type_id = sa.Column(sa.Integer, sa.ForeignKey(Type.id)) type = sa.relationship(Type, backref=backref('machines', lazy='dynamic', uselist=True)) sa.create_all() class MachineResource(ModelResource): class Meta: model = Machine include_id = True include_type = True class Schema: type = fields.ToOne('type') class TypeResource(ModelResource): class Meta: model = Type include_id = True include_type = True class Schema: machines = fields.ToMany('machine') self.MachineResource = MachineResource self.TypeResource = TypeResource self.api.add_resource(MachineResource) self.api.add_resource(TypeResource)
def test_api_prefix(self): api = Api(self.app, prefix='/api/v1') class BookResource(ModelResource): class Meta: name = "book" model = "book" manager = MemoryManager @Route.GET def genres(self): return ['fiction', 'non-fiction'] @ItemRoute.GET def rating(self): return 4.5 api.add_resource(BookResource) response = self.client.get("/schema") self.assert404(response) response = self.client.get("/api/v1/schema") self.assertEqual( { "$schema": "http://json-schema.org/draft-04/hyper-schema#", "properties": { "book": { "$ref": "/api/v1/book/schema#" } }, }, response.json, ) response = self.client.get("/api/v1/book/schema") self.assert200(response) self.assertEqual( { "/api/v1/book", "/api/v1/book/schema", "/api/v1/book/genres", "/api/v1/book/{id}", "/api/v1/book/{id}/rating", }, {link_['href'] for link_ in response.json['links']}, )
def test_api_blueprint_w_prefix(self): api_bp = Blueprint("potion_blueprint", __name__.split(".")[0]) api = Api(api_bp, prefix="/api/v1") api.add_resource(self.SampleResource) # Register Blueprint self.app.register_blueprint(api_bp) response = self.client.get("/api/v1/samples") self.assert200(response) response = self.client.get("/api/v1/samples/schema") self.assertEqual( '^\\/api\\/v1\\/samples\\/[^/]+$', response.json['properties']['$uri']['pattern'], )
def test_route_success_code(self): class FooResource(Resource): @Route.GET(success_code=201) def foo(self): return 'foo' class Meta: name = 'foo' api = Api(self.app) api.add_resource(FooResource) response = self.client.get("/foo/foo") self.assertEqual(201, response.status_code) self.assertEqual('foo', response.json)
def test_resource_route_rule_resolution(self): class FooResource(Resource): @Route.GET(lambda r: '/<{}:id>'.format(r.meta.id_converter), rel="self") def read(self, id): return {"id": id} read.response_schema = fields.Object({"id": fields.Integer()}) class Meta: name = 'foo' id_converter = 'int' Api(prefix="/v1").add_resource(FooResource) self.assertEqual('/v1/foo/<int:id>', FooResource.read.rule_factory(FooResource)) self.assertEqual('<int:id>', FooResource.read.rule_factory(FooResource, True)) data, code, headers = FooResource().described_by() self.assertJSONEqual( { "rel": "self", "href": "/v1/foo/{id}", "method": "GET", "targetSchema": { "type": "object", "properties": { "id": { "type": "integer" } }, "additionalProperties": False } }, data["links"][1])
def setUp(self): super(PrincipalTestCase, self).setUp() self.mock_user = None @identity_loaded.connect_via(self.app) def on_identity_loaded(sender, identity): identity.provides.add(UserNeed(identity.id)) for role in self.mock_user.get('roles', []): identity.provides.add(RoleNeed(role)) for need in self.mock_user.get('needs', []): identity.provides.add(need) def authenticate(fn): @wraps(fn) def wrapper(*args, **kwargs): auth = request.authorization if not auth: raise Unauthorized() if auth.password == 'password': identity_changed.send(current_app._get_current_object(), identity=Identity(self.mock_user['id'])) else: raise Unauthorized() return fn(*args, **kwargs) return wrapper self.api = Api(self.app, decorators=[authenticate])
def create_app(config_name): from flask_potion import Api app = Flask(__name__, instance_relative_config=True) app.config.from_object(config_by_name[config_name]) app.logger.info('Connecting database') db.init_app(app) app.logger.info('Setting authenticator') def authenticate(email, password): user = User.query.filter_by(email=email).first() if user and safe_str_cmp(user.password.encode('utf-8'), password.encode('utf-8')): return user def identity(payload): user_id = payload['identity'] return User.query.get(user_id) jwt = JWT(app, authenticate, identity) app.logger.info('creating Flask-Potion Apis') from application import apis api = Api(app, prefix='/api/v1', title='Backend API') apis.create_api(api) app.logger.info('Finished initialization') return app
class SQLAlchemyInspectionTestCase(BaseTestCase): def setUp(self): super(SQLAlchemyInspectionTestCase, self).setUp() self.app.config['SQLALCHEMY_ENGINE'] = 'sqlite://' self.api = Api(self.app) self.sa = SQLAlchemy(self.app, session_options={"autoflush": False}) def test_inspection_auto_id_attribute_type(self): sa = self.sa class User(sa.Model): username = sa.Column(sa.String, primary_key=True) first_name = sa.Column(sa.String) last_name = sa.Column(sa.String) sa.create_all() class UserResource(ModelResource): class Schema: username = fields.String() class Meta: model = User include_id = True self.api.add_resource(UserResource) self.assertEqual(User.username, UserResource.manager.id_column) self.assertEqual('username', UserResource.manager.id_field.attribute) self.assertIsInstance(UserResource.manager.id_field, fields.String) response = self.client.post('/user', data={ "username": "******", "first_name": "Foo" }) self.assert200(response) self.assertJSONEqual( { "$id": "foo", "first_name": "Foo", "last_name": None, "username": "******" }, response.json, )
def setUp(self): super(PeeweeRelationTestCase, self).setUp() self.app.config['DATABASE'] = 'sqlite://' self.db = db = PeeweeTestDB(self.app) self.api = Api(self.app) class User(db.Model): parent = pw.ForeignKeyField('self', related_name='children', null=True) name = pw.CharField(max_length=60, null=False) class Group(db.Model): name = pw.CharField(max_length=60, null=False) members = ManyToManyField(User, related_name='memberships') db.database.connect() db.database.create_tables([ User, Group, Group.members.get_through_model()]) self.User = User self.Group = Group class UserResource(ModelResource): class Meta: model = User include_id = True include_type = True manager = PeeweeManager children = Relation('self') class GroupResource(ModelResource): class Meta: model = Group include_id = True include_type = True manager = PeeweeManager members = Relation('user') self.api.add_resource(UserResource) self.api.add_resource(GroupResource)
def setUp(self): super(FilterTestCase, self).setUp() app = self.app app.config['SQLALCHEMY_ENGINE'] = 'sqlite://' app.config['TESTING'] = True self.api = Api(self.app) self.sa = sa = SQLAlchemy(app) class User(sa.Model): id = sa.Column(sa.Integer, primary_key=True) first_name = sa.Column(sa.String(60), nullable=False) last_name = sa.Column(sa.String(60), nullable=False) gender = sa.Column(sa.String(1)) age = sa.Column(sa.Integer) is_staff = sa.Column(sa.Boolean, default=None) class Thing(sa.Model): id = sa.Column(sa.Integer, primary_key=True) name = sa.Column(sa.String(60), nullable=False) belongs_to_id = sa.Column(sa.Integer, sa.ForeignKey(User.id)) belongs_to = sa.relationship(User) sa.create_all() class UserResource(ModelResource): class Schema: gender = fields.String(enum=['f', 'm'], nullable=True) class Meta: model = User include_id = True class ThingResource(ModelResource): class Schema: belongs_to = fields.ToOne('user') class Meta: model = Thing class AllowUserResource(ModelResource): class Meta: model = User name = 'allow-user' allowed_filters = { 'first_name': ['$eq'], 'is_staff': '*' } self.api.add_resource(UserResource) self.api.add_resource(ThingResource) self.api.add_resource(AllowUserResource)
class ResourceTestCase(BaseTestCase): def setUp(self): super(ResourceTestCase, self).setUp() self.api = Api(self.app) def test_resource(self): class FooResource(Resource): class Schema: name = fields.String() class Meta: name = 'foo' self.api.add_resource(FooResource) #self.assertEqual(['create', 'update', 'schema'], list(FooResource.routes.())) data, code, headers = FooResource().described_by() self.assertEqual({"name": {"type": "string"}}, data["properties"])
def setUp(self): super(MongoEngineSignalTestCase, self).setUp() self.app.config['MONGODB_DB'] = 'potion-test-db' self.api = Api(self.app, default_manager=MongoEngineManager) self.me = me = MongoEngine(self.app) class User(me.Document): name = StringField(max_length=60, null=False) gender = StringField(max_length=1, null=True) children = ListField(ReferenceField("User")) def __eq__(self, other): return self.name == other.name def __repr__(self): return 'User({})'.format(self.name) class Group(me.Document): name = StringField(max_length=60, null=False) class GroupMembership(me.Document): user = ReferenceField(User) group = ReferenceField(Group) class UserResource(ModelResource): class Meta: model = User children = Relation('self') class GroupResource(ModelResource): class Meta: model = Group members = Relation(UserResource) self.User = User self.Group = Group self.UserResource = UserResource self.GroupResource = GroupResource self.api.add_resource(UserResource) self.api.add_resource(GroupResource)
class ResourceTestCase(BaseTestCase): def setUp(self): super(ResourceTestCase, self).setUp() self.api = Api(self.app) def test_resource(self): class FooResource(Resource): class Schema: name = fields.String() class Meta: name = "foo" self.api.add_resource(FooResource) # self.assertEqual(['create', 'update', 'schema'], list(FooResource.routes.())) data, code, headers = FooResource().described_by() self.assertEqual({"name": {"type": "string"}}, data["properties"])
def setUp(self): super(PeeweeTestCase, self).setUp() self.app.config['DATABASE'] = 'sqlite://' self.db = db = PeeweeTestDB(self.app) self.api = Api(self.app) class Type(db.Model): name = pw.CharField(max_length=60, null=False, unique=True) class Machine(db.Model): name = pw.CharField(max_length=60, null=False) wattage = pw.FloatField(null=True) type = pw.ForeignKeyField(Type, related_name='machines') self.db.database.connect() self.db.database.create_tables([Type, Machine]) class MachineResource(ModelResource): class Meta: model = Machine include_id = True include_type = True manager = PeeweeManager class Schema: type = fields.ToOne('type') class TypeResource(ModelResource): class Meta: model = Type include_id = True include_type = True manager = PeeweeManager class Schema: machines = fields.ToMany(MachineResource) self.MachineResource = MachineResource self.TypeResource = TypeResource self.api.add_resource(MachineResource) self.api.add_resource(TypeResource)
def test_api_schema(self): api = Api(self.app, title="Welcome to Foo API!", description="...") response = self.client.get("/schema") self.assertEqual( { "$schema": "http://json-schema.org/draft-04/hyper-schema#", "title": "Welcome to Foo API!", "description": "...", "properties": {} }, response.json)
def test_schema_decoration(self): def is_teapot(fn): @wraps(fn) def wrapper(*args, **kwargs): return '', 418, {} return wrapper api = Api(self.app, decorators=[is_teapot]) class FooResource(Resource): class Meta: name = 'foo' api.add_resource(FooResource) response = self.client.get("/schema") self.assertEqual(response.status_code, 418) response = self.client.get("/foo/schema") self.assertEqual(response.status_code, 418)
def setUp(self): super(FilterTestCase, self).setUp() app = self.app app.config['MONGODB_DB'] = 'potion-test-db' app.config['TESTING'] = True self.api = Api(self.app, default_manager=MongoEngineManager) self.me = me = MongoEngine(app) class User(me.Document): meta = { "collection": "user" } first_name = StringField(max_length=60, null=False) last_name = StringField(max_length=60, null=False) gender = StringField(max_length=1) age = IntField() is_staff = BooleanField(default=None) class UserResource(ModelResource): class Schema: gender = fields.String(enum=['f', 'm'], nullable=True) class Meta: model = User class AllowUserResource(ModelResource): class Meta: model = User name = 'allow-user' filters = { 'first_name': ['eq'], 'is_staff': True } self.api.add_resource(UserResource) self.api.add_resource(AllowUserResource)
def test_api_register_resource(self): class BookResource(ModelResource): class Meta: name = "book" model = "book" manager = MemoryManager api = Api(self.app) api.add_resource(BookResource) response = self.client.get("/schema") self.assertEqual({ "$schema": "http://json-schema.org/draft-04/hyper-schema#", "properties": { "book": {"$ref": "/book/schema#"} } }, response.json) response = self.client.get("/book/schema") self.assert200(response)
def test_api_prefix(self): api = Api(self.app, prefix='/api/v1') class BookResource(ModelResource): class Meta: name = "book" model = "book" manager = MemoryManager @Route.GET def genres(self): return ['fiction', 'non-fiction'] @ItemRoute.GET def rating(self): return 4.5 api.add_resource(BookResource) response = self.client.get("/schema") self.assert404(response) response = self.client.get("/api/v1/schema") self.assertEqual({ "$schema": "http://json-schema.org/draft-04/hyper-schema#", "properties": { "book": {"$ref": "/api/v1/book/schema#"} } }, response.json) response = self.client.get("/api/v1/book/schema") self.assert200(response) self.assertEqual({ "/api/v1/book", "/api/v1/book/schema", "/api/v1/book/genres", "/api/v1/book/{id}", "/api/v1/book/{id}/rating" }, {l['href'] for l in response.json['links']})
def setUp(self): super(MongoEngineTestCase, self).setUp() self.app.config['MONGODB_DB'] = 'potion-test-db' self.api = Api(self.app, default_manager=MongoEngineManager) self.me = me = MongoEngine(self.app) class Type(me.Document): meta = {"collection": "type"} name = StringField(max_length=60, null=False, unique=True) @property def machines(self): return Machine.objects(type=self) @machines.setter def machines(self, machines): for m in machines: m.type = self class Machine(me.Document): meta = {"collection": "machine"} name = StringField(max_length=60, null=False) wattage = FloatField(null=True) type = ReferenceField(Type) class MachineResource(ModelResource): class Meta: manager = MongoEngineManager model = Machine include_id = True include_type = True class Schema: type = fields.ToOne('type') class TypeResource(ModelResource): class Meta: manager = MongoEngineManager model = Type include_id = True include_type = True class Schema: machines = fields.ToMany('machine') self.MachineResource = MachineResource self.TypeResource = TypeResource self.api.add_resource(MachineResource) self.api.add_resource(TypeResource)
def test_schema_decoration_disable(self): def is_teapot(fn): @wraps(fn) def wrapper(*args, **kwargs): return '', 418, {} return wrapper self.app.config['POTION_DECORATE_SCHEMA_ENDPOINTS'] = False api = Api(self.app, decorators=[is_teapot]) class FooResource(Resource): class Meta: name = 'foo' api.add_resource(FooResource) response = self.client.get("/schema") self.assert200(response) response = self.client.get("/foo/schema") self.assert200(response)
def initialize_app(flask_app): configure_app(flask_app) api = Api(app) blueprint = Blueprint('api', __name__, url_prefix='/api') api.init_app(blueprint) flask_app.register_blueprint(blueprint) api.add_resource(CampaignResource) api.add_resource(Resource) # Swagger(app) db.init_app(flask_app)
def setUp(self): super(PeeeeFilterTestCase, self).setUp() app = self.app app.config['DATABASE'] = 'sqlite://' self.db = db = PeeweeTestDB(self.app) self.api = Api(self.app, default_manager=PeeweeManager) app.debug = True class User(db.Model): id = IntegerField(primary_key=True) first_name = CharField(max_length=60, null=False) last_name = CharField(max_length=60, null=False) gender = CharField(max_length=1, null=True) age = IntegerField() is_staff = BooleanField(default=None) db.database.connect() db.database.create_tables([User]) class UserResource(ModelResource): class Schema: gender = fields.String(enum=['f', 'm'], nullable=True) class Meta: model = User class AllowUserResource(ModelResource): class Meta: model = User name = 'allow-user' allowed_filters = {'first_name': ['$eq'], 'is_staff': '*'} self.api.add_resource(UserResource) self.api.add_resource(AllowUserResource)
def setUp(self): super(SQLAlchemySortTestCase, self).setUp() self.app.config['SQLALCHEMY_ENGINE'] = 'sqlite://' self.api = Api(self.app) self.sa = sa = SQLAlchemy(self.app, session_options={"autoflush": False}) class Type(sa.Model): id = sa.Column(sa.Integer, primary_key=True) name = sa.Column(sa.String(60), nullable=False) class Machine(sa.Model): id = sa.Column(sa.Integer, primary_key=True) name = sa.Column(sa.String(60), nullable=False) type_id = sa.Column(sa.Integer, sa.ForeignKey(Type.id)) type = sa.relationship(Type, foreign_keys=[type_id]) sa.create_all() class MachineResource(ModelResource): class Meta: model = Machine class Schema: type = fields.ToOne('type') class TypeResource(ModelResource): class Meta: model = Type sort_attribute = ('name', True) self.MachineResource = MachineResource self.TypeResource = TypeResource self.api.add_resource(MachineResource) self.api.add_resource(TypeResource)
class SQLAlchemySequenceTestCase(BaseTestCase): def setUp(self): super(SQLAlchemySequenceTestCase, self).setUp() self.app.config['SQLALCHEMY_ENGINE'] = 'sqlite://' self.api = Api(self.app) self.sa = sa = SQLAlchemy(self.app, session_options={"autoflush": False}) def test_sequence_primary_key(self): sa = self.sa user_id_seq = sa.Sequence('user_id_seq') class User(sa.Model): id = sa.Column(sa.Integer, user_id_seq, primary_key=True) username = sa.Column(sa.String, unique=True) sa.create_all() class UserResource(ModelResource): class Schema: username = fields.String() class Meta: model = User include_id = True self.api.add_resource(UserResource) response = self.client.post('/user', data={"username": "******"}) self.assert200(response) self.assertJSONEqual({ "$id": 1, "username": "******" }, response.json)
def setUp(self): super(QueryOptionsSQLAlchemyTestCase, self).setUp() self.app.config['SQLALCHEMY_ENGINE'] = 'sqlite://' self.api = Api(self.app, default_manager=SQLAlchemyManager) self.sa = sa = SQLAlchemy(self.app, session_options={"autoflush": False}) class Type(sa.Model): id = sa.Column(sa.Integer, primary_key=True) name = sa.Column(sa.String(60), nullable=False, unique=True) version = sa.Column(sa.Integer(), nullable=True) machines = sa.relationship('Machine', back_populates='type') class Machine(sa.Model): id = sa.Column(sa.Integer, primary_key=True) name = sa.Column(sa.String(60), nullable=False) wattage = sa.Column(sa.Float) type_id = sa.Column(sa.Integer, sa.ForeignKey(Type.id)) type = sa.relationship(Type, back_populates='machines') sa.create_all() class MachineResource(ModelResource): class Meta: model = Machine include_type = True class Schema: type = fields.ToOne('type') class TypeResource(ModelResource): class Meta: model = Type include_type = True query_options = [joinedload(Type.machines)] class Schema: machines = fields.ToMany('machine') self.MachineResource = MachineResource self.TypeResource = TypeResource self.api.add_resource(MachineResource) self.api.add_resource(TypeResource)
def setUp(self): super(SQLAlchemyRelationTestCase, self).setUp() self.app.config["SQLALCHEMY_ENGINE"] = "sqlite://" self.api = Api(self.app) self.sa = sa = SQLAlchemy(self.app, session_options={"autoflush": False}) group_members = sa.Table( "group_members", sa.Column("group_id", sa.Integer(), sa.ForeignKey("group.id")), sa.Column("user_id", sa.Integer(), sa.ForeignKey("user.id")), ) class User(sa.Model): id = sa.Column(sa.Integer, primary_key=True) parent_id = sa.Column(sa.Integer, sa.ForeignKey(id)) name = sa.Column(sa.String(60), nullable=False) parent = sa.relationship("User", remote_side=[id], backref=backref("children", lazy="dynamic")) class Group(sa.Model): id = sa.Column(sa.Integer, primary_key=True) name = sa.Column(sa.String(60), nullable=False) members = sa.relationship("User", secondary=group_members, backref=backref("memberships", lazy="dynamic")) sa.create_all() class UserResource(ModelResource): class Meta: model = User include_id = True include_type = True children = Relation("self") class GroupResource(ModelResource): class Meta: model = Group include_id = True include_type = True members = Relation("user") self.api.add_resource(UserResource) self.api.add_resource(GroupResource)
def setUp(self): super(SQLAlchemyTestCase, self).setUp() self.app.config["SQLALCHEMY_ENGINE"] = "sqlite://" self.api = Api(self.app, default_manager=SQLAlchemyManager) self.sa = sa = SQLAlchemy(self.app, session_options={"autoflush": False}) class Type(sa.Model): id = sa.Column(sa.Integer, primary_key=True) name = sa.Column(sa.String(60), nullable=False, unique=True) class Machine(sa.Model): id = sa.Column(sa.Integer, primary_key=True) name = sa.Column(sa.String(60), nullable=False) wattage = sa.Column(sa.Float) type_id = sa.Column(sa.Integer, sa.ForeignKey(Type.id)) type = sa.relationship(Type, backref=backref("machines", lazy="dynamic", uselist=True)) sa.create_all() class MachineResource(ModelResource): class Meta: model = Machine include_id = True include_type = True class Schema: type = fields.ToOne("type") class TypeResource(ModelResource): class Meta: model = Type include_id = True include_type = True class Schema: machines = fields.ToMany("machine") self.MachineResource = MachineResource self.TypeResource = TypeResource self.api.add_resource(MachineResource) self.api.add_resource(TypeResource)
def setUp(self): super(PeeeeFilterTestCase, self).setUp() app = self.app app.config['DATABASE'] = 'sqlite://' self.db = db = PeeweeTestDB(self.app) self.api = Api(self.app, default_manager=PeeweeManager) app.debug = True class User(db.Model): id = IntegerField(primary_key=True) first_name = CharField(max_length=60, null=False) last_name = CharField(max_length=60, null=False) gender = CharField(max_length=1, null=True) age = IntegerField() is_staff = BooleanField(default=None) db.database.connect() db.database.create_tables([User]) class UserResource(ModelResource): class Schema: gender = fields.String(enum=['f', 'm'], nullable=True) class Meta: model = User class AllowUserResource(ModelResource): class Meta: model = User name = 'allow-user' allowed_filters = { 'first_name': ['$eq'], 'is_staff': '*' } self.api.add_resource(UserResource) self.api.add_resource(AllowUserResource)
def setUp(self): super(FilterTestCase, self).setUp() app = self.app app.config['MONGODB_DB'] = 'potion-test-db' app.config['TESTING'] = True self.api = Api(self.app, default_manager=MongoEngineManager) self.me = me = MongoEngine(app) class User(me.Document): meta = { "collection": "user" } first_name = StringField(max_length=60, null=False) last_name = StringField(max_length=60, null=False) gender = StringField(max_length=1) age = IntField() is_staff = BooleanField(default=None) class UserResource(ModelResource): class Schema: gender = fields.String(enum=['f', 'm'], nullable=True) class Meta: model = User class AllowUserResource(ModelResource): class Meta: model = User name = 'allow-user' allowed_filters = { 'first_name': ['$eq'], 'is_staff': '*' } self.api.add_resource(UserResource) self.api.add_resource(AllowUserResource)
def setUp(self): super(SQLAlchemySortTestCase, self).setUp() self.app.config['SQLALCHEMY_ENGINE'] = 'sqlite://' self.api = Api(self.app) self.sa = sa = SQLAlchemy( self.app, session_options={"autoflush": False}) class Type(sa.Model): id = sa.Column(sa.Integer, primary_key=True) name = sa.Column(sa.String(60), nullable=False) class Machine(sa.Model): id = sa.Column(sa.Integer, primary_key=True) name = sa.Column(sa.String(60), nullable=False) type_id = sa.Column(sa.Integer, sa.ForeignKey(Type.id)) type = sa.relationship(Type, foreign_keys=[type_id]) sa.create_all() class MachineResource(ModelResource): class Meta: model = Machine class Schema: type = fields.ToOne('type') class TypeResource(ModelResource): class Meta: model = Type sort_attribute = ('name', True) self.MachineResource = MachineResource self.TypeResource = TypeResource self.api.add_resource(MachineResource) self.api.add_resource(TypeResource)
def setUp(self): super(MongoEngineRelationTestCase, self).setUp() self.app.config['MONGODB_DB'] = 'potion-test-db' self.api = Api(self.app, default_manager=MongoEngineManager) self.me = me = MongoEngine(self.app) class User(me.Document): name = StringField(max_length=60) children = ListField(ReferenceField('User')) @property def memberships(self): return Group.objects(members__in=self) class Group(me.Document): name = StringField(max_length=60) members = ListField(ReferenceField('User')) class UserResource(ModelResource): class Meta: model = User include_id = True include_type = True children = Relation('self') class GroupResource(ModelResource): class Meta: model = Group include_id = True include_type = True members = Relation('user') self.api.add_resource(UserResource) self.api.add_resource(GroupResource)
class PeeweeRelationTestCase(BaseTestCase): def setUp(self): super(PeeweeRelationTestCase, self).setUp() self.app.config['DATABASE'] = 'sqlite://' self.db = db = PeeweeTestDB(self.app) self.api = Api(self.app) class User(db.Model): parent = pw.ForeignKeyField('self', related_name='children', null=True) name = pw.CharField(max_length=60, null=False) class Group(db.Model): name = pw.CharField(max_length=60, null=False) members = ManyToManyField(User, related_name='memberships') db.database.connect() db.database.create_tables([ User, Group, Group.members.get_through_model()]) self.User = User self.Group = Group class UserResource(ModelResource): class Meta: model = User include_id = True include_type = True manager = PeeweeManager children = Relation('self') class GroupResource(ModelResource): class Meta: model = Group include_id = True include_type = True manager = PeeweeManager members = Relation('user') self.api.add_resource(UserResource) self.api.add_resource(GroupResource) def tearDown(self): self.db.database.drop_tables([ self.Group.members.get_through_model(), self.Group, self.User]) if not self.db.database.is_closed(): self.db.database.close() def test_relationship_secondary(self): response = self.client.post('/group', data={'name': 'Foo'}) self.assert200(response) self.assertJSONEqual({ '$id': 1, '$type': 'group', 'name': 'Foo'}, response.json) response = self.client.post('/user', data={'name': 'Bar'}) self.assert200(response) self.assertJSONEqual({ '$id': 1, '$type': 'user', 'name': 'Bar'}, response.json) response = self.client.get('/group/1/members') self.assert200(response) self.assertJSONEqual([], response.json) response = self.client.post( '/group/1/members', data={'$ref': '/user/1'}) self.assert200(response) self.assertJSONEqual({'$ref': '/user/1'}, response.json) response = self.client.get('/group/1/members') self.assert200(response) self.assertJSONEqual([{'$ref': '/user/1'}], response.json) def test_relationship_secondary_delete_missing(self): response = self.client.post('/group', data={"name": "Foo"}) response = self.client.post('/user', data={"name": "Bar"}) response = self.client.delete('/group/1/members/1') self.assertStatus(response, 204) def test_relationship_post(self): response = self.client.post('/user', data={'name': 'Foo'}) self.assert200(response) self.assertJSONEqual({ '$id': 1, '$type': 'user', 'name': 'Foo'}, response.json) response = self.client.post('/user', data={'name': 'Bar'}) self.assert200(response) self.assertJSONEqual({ '$id': 2, '$type': 'user', 'name': 'Bar'}, response.json) response = self.client.post( '/user/1/children', data={'$ref': '/user/2'}) self.assert200(response) self.assertJSONEqual({'$ref': '/user/2'}, response.json) def test_relationship_get(self): self.test_relationship_post() response = self.client.get('/user/1/children') self.assert200(response) self.assertJSONEqual([{'$ref': '/user/2'}], response.json) def test_relationship_delete(self): self.test_relationship_post() response = self.client.delete('/user/1/children/2') self.assertStatus(response, 204) response = self.client.get('/user/1/children') self.assert200(response) self.assertJSONEqual([], response.json) def test_relationship_pagination(self): response = self.client.post('/user', data={'name': 'Foo'}) self.assert200(response) for i in range(2, 50): response = self.client.post('/user', data={'name': str(i)}) self.assert200(response) response = self.client.post( '/user/1/children', data={'$ref': '/user/{}'.format(response.json['$id'])}) self.assert200(response) response = self.client.get('/user/1/children') self.assert200(response) self.assertJSONEqual( [{'$ref': '/user/{}'.format(i)} for i in range(2, 22)], response.json) response = self.client.get('/user/1/children?page=3') self.assert200(response) self.assertJSONEqual( [{'$ref': '/user/{}'.format(i)} for i in range(42, 50)], response.json)