-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
243 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
from flask import Flask, request | ||
from werkzeug.exceptions import HTTPException | ||
from flask_sqlalchemy import SQLAlchemy | ||
|
||
|
||
app = Flask(__name__) | ||
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:' | ||
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False | ||
|
||
db = SQLAlchemy(app) | ||
|
||
|
||
pets = [ | ||
{ | ||
'name': 'Kitty', | ||
'category': 'cat' | ||
}, | ||
{ | ||
'name': 'Coco', | ||
'category': 'dog' | ||
}, | ||
{ | ||
'name': 'Flash', | ||
'category': 'cat' | ||
} | ||
] | ||
|
||
|
||
class PetModel(db.Model): | ||
id = db.Column(db.Integer, primary_key=True) | ||
name = db.Column(db.String(10)) | ||
category = db.Column(db.String(10)) | ||
|
||
|
||
@app.before_first_request | ||
def init_database(): | ||
"""Create the table and add some fake data.""" | ||
db.create_all() | ||
for pet_data in pets: | ||
pet = PetModel(**pet_data) | ||
db.session.add(pet) | ||
db.session.commit() | ||
|
||
|
||
@app.errorhandler(HTTPException) | ||
def handle_http_errors(error): | ||
return {'message': error.name}, error.code | ||
|
||
|
||
def pet_schema(pet): | ||
return { | ||
'id': pet.id, | ||
'name': pet.name, | ||
'category': pet.category | ||
} | ||
|
||
|
||
@app.get('/') | ||
def say_hello(): | ||
return {'message': 'Hello!'} | ||
|
||
|
||
@app.get('/pets/<int:pet_id>') | ||
def get_pet(pet_id): | ||
pet = PetModel.query.get(pet_id) | ||
if pet is None: | ||
return {'message': 'Pet not found.'}, 404 | ||
return pet_schema(pet) | ||
|
||
|
||
@app.get('/pets') | ||
def get_pets(): | ||
pets = PetModel.query.all() | ||
return {'pets': [pet_schema(pet) for pet in pets]} | ||
|
||
|
||
@app.post('/pets') | ||
def create_pet(): | ||
data = request.json | ||
if 'name' not in data or 'category' not in data: | ||
return {'message': 'The name and category field is required.'}, 400 | ||
if len(data['name']) > 10: | ||
return {'message': 'The length of the name must be between 0 and 10.'}, 400 | ||
if data['category'] not in ['cat', 'dog']: | ||
return {'message': 'The category must be one of: dog, cat.'}, 400 | ||
|
||
pet = PetModel(name=data['name'], category=data['category']) | ||
db.session.add(pet) | ||
db.session.commit() | ||
return pet_schema(pet), 201 | ||
|
||
|
||
@app.patch('/pets/<int:pet_id>') | ||
def update_pet(pet_id): | ||
pet = PetModel.query.get(pet_id) | ||
if pet is None: | ||
return {'message': 'Pet not found.'}, 404 | ||
|
||
data = request.json | ||
if 'name' in data: | ||
if len(data['name']) > 10: | ||
return {'message': 'The length of the name must be between 0 and 10.'}, 400 | ||
else: | ||
pet.name = data['name'] | ||
if 'category' in data: | ||
if data['category'] not in ['cat', 'dog']: | ||
return {'message': 'The category must be one of: dog, cat.'}, 400 | ||
else: | ||
pet.category = data['category'] | ||
db.session.commit() | ||
return pet_schema(pet) | ||
|
||
|
||
@app.delete('/pets/<int:pet_id>') | ||
def delete_pet(pet_id): | ||
pet = PetModel.query.get(pet_id) | ||
if pet is None: | ||
return {'message': 'Pet not found.'}, 404 | ||
db.session.delete(pet) | ||
db.session.commit() | ||
return '', 204 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
from importlib import reload | ||
import sys | ||
|
||
import pytest | ||
|
||
|
||
examples = [ | ||
'flask', | ||
] | ||
|
||
|
||
@pytest.fixture | ||
def client(request): | ||
app_path = f'examples/{request.param}' | ||
sys.path.insert(0, app_path) | ||
import app | ||
app = reload(app) | ||
_app = app.app | ||
_app.testing = True | ||
sys.path.remove(app_path) | ||
return _app.test_client() | ||
|
||
|
||
@pytest.mark.parametrize('client', examples, indirect=True) | ||
def test_say_hello(client): | ||
rv = client.get('/') | ||
assert rv.status_code == 200 | ||
assert rv.json | ||
assert rv.json['message'] == 'Hello!' | ||
|
||
|
||
@pytest.mark.parametrize('client', examples, indirect=True) | ||
def test_get_pet(client): | ||
rv = client.get('/pets/1') | ||
assert rv.status_code == 200 | ||
assert rv.json | ||
assert rv.json['name'] == 'Kitty' | ||
assert rv.json['category'] == 'cat' | ||
|
||
rv = client.get('/pets/13') | ||
assert rv.status_code == 404 | ||
assert rv.json | ||
|
||
|
||
@pytest.mark.parametrize('client', examples, indirect=True) | ||
def test_get_pets(client): | ||
rv = client.get('/pets') | ||
assert rv.status_code == 200 | ||
assert rv.json | ||
assert len(rv.json['pets']) == 3 | ||
assert rv.json['pets'][0]['name'] == 'Kitty' | ||
assert rv.json['pets'][0]['category'] == 'cat' | ||
|
||
|
||
@pytest.mark.parametrize('client', examples, indirect=True) | ||
def test_create_pet(client): | ||
rv = client.post('/pets', json={ | ||
'name': 'Grey', | ||
'category': 'cat' | ||
}) | ||
assert rv.status_code == 201 | ||
assert rv.json | ||
assert rv.json['name'] == 'Grey' | ||
assert rv.json['category'] == 'cat' | ||
|
||
|
||
@pytest.mark.parametrize('client', examples, indirect=True) | ||
@pytest.mark.parametrize('data', [ | ||
{'name': 'Grey', 'category': 'human'}, | ||
{'name': 'Fyodor Mikhailovich Dostoevsky', 'category': 'cat'}, | ||
{'category': 'cat'}, | ||
{'name': 'Grey'} | ||
]) | ||
def test_create_pet_with_bad_data(client, data): | ||
rv = client.post('/pets', json=data) | ||
assert rv.status_code == 400 | ||
assert rv.json | ||
|
||
|
||
@pytest.mark.parametrize('client', examples, indirect=True) | ||
def test_update_pet(client): | ||
new_data = { | ||
'name': 'Ghost', | ||
'category': 'dog' | ||
} | ||
|
||
rv = client.patch('/pets/1', json=new_data) | ||
assert rv.status_code == 200 | ||
assert rv.json | ||
|
||
rv = client.get('/pets/1') | ||
assert rv.status_code == 200 | ||
assert rv.json == new_data | ||
|
||
rv = client.patch('/pets/13', json=new_data) | ||
assert rv.status_code == 404 | ||
assert rv.json | ||
|
||
|
||
@pytest.mark.parametrize('client', examples, indirect=True) | ||
@pytest.mark.parametrize('data', [ | ||
{'name': 'Fyodor Mikhailovich Dostoevsky'}, | ||
{'category': 'human'} | ||
]) | ||
def test_update_pet_with_bad_data(client, data): | ||
rv = client.patch('/pets/1', json=data) | ||
assert rv.status_code == 400 | ||
assert rv.json | ||
|
||
|
||
@pytest.mark.parametrize('client', examples, indirect=True) | ||
def test_delete_pet(client): | ||
rv = client.delete('/pets/1') | ||
assert rv.status_code == 204 | ||
|
||
rv = client.get('/pets/1') | ||
assert rv.status_code == 404 | ||
assert rv.json | ||
|
||
rv = client.delete('/pets/13') | ||
assert rv.status_code == 404 | ||
assert rv.json |