Тестирование фляги facebook, логин python
После того, как я добавил "if 'username' not in login_session" в мои маршруты, мои тесты не прошли. Я использую логин через фейсбук. Как правильно настроить свои тесты для прохождения логина через фейсбук и все остальные маршруты?
Файл просмотров с вспомогательными функциями и входом в Facebook, также несколько моих маршрутов.
views.py
# Login Helper Functions
def createUser(login_session):
newUser = User(name=login_session['username'], email=login_session[
'email'], picture=login_session['picture'])
newUser.save()
user = db.session.query(User).filter_by(email=login_session['email']).one()
return user.id
def getUserInfo(user_id):
user = db.session.query(User).filter_by(id=user_id).one()
return user
def getUserID(email):
try:
user = db.session.query(User).filter_by(email=email).one()
return user.id
except:
return None
# Create anti-forgery state token to protect the security of your user
@home_blueprint.route('/login')
def showLogin():
state = ''.join(random.choice(string.ascii_uppercase + string.digits)
for x in xrange(32))
login_session['state'] = state
# return "The current session state is %s" % login_session['state']
return render_template('login.html', STATE=state)
@home_blueprint.route('/fbconnect', methods=['POST'])
def fbconnect():
if request.args.get('state') != login_session['state']:
response = make_response(json.dumps('Invalid state parameter.'), 401)
response.headers['Content-Type'] = 'application/json'
return response
access_token = request.data
print "access token received %s " % access_token
app_id = os.environ['FACEBOOK_APP_ID']
app_secret = os.environ['FACEBOOK_APP_SECRET']
url = 'https://graph.facebook.com/oauth/access_token?grant_type=fb_exchange_token&client_id=%s&client_secret=%s&fb_exchange_token=%s' % (
app_id, app_secret, access_token)
h = httplib2.Http()
result = h.request(url, 'GET')[1]
# Use token to get user info from API
userinfo_url = "https://graph.facebook.com/v2.8/me"
'''
Due to the formatting for the result from the server token exchange we have to
split the token first on commas and select the first index which gives us the key : value
for the server access token then we split it on colons to pull out the actual token value
and replace the remaining quotes with nothing so that it can be used directly in the graph
api calls
'''
token = result.split(',')[0].split(':')[1].replace('"', '')
url = 'https://graph.facebook.com/v2.9/me?access_token=%s&fields=name,id,email' % token
h = httplib2.Http()
result = h.request(url, 'GET')[1]
# print "url sent for API access:%s"% url
# print "API JSON result: %s" % result
data = json.loads(result)
login_session['provider'] = 'facebook'
login_session['username'] = data["name"]
login_session['email'] = data["email"]
login_session['facebook_id'] = data["id"]
# The token must be stored in the login_session in order to properly logout
login_session['access_token'] = token
# Get user picture
url = 'https://graph.facebook.com/v2.9/me/picture?access_token=%s&redirect=0&height=200&width=200' % token
h = httplib2.Http()
result = h.request(url, 'GET')[1]
data = json.loads(result)
login_session['picture'] = data["data"]["url"]
# see if user exists
user_id = getUserID(login_session['email'])
if not user_id:
user_id = createUser(login_session)
login_session['user_id'] = user_id
output = ''
output += '<h1>Welcome, '
output += login_session['username']
output += '!</h1>'
output += '<img src="'
output += login_session['picture']
output += ' " style = "width: 300px; height: 300px;border-radius: 150px;-webkit-border-radius: 150px;-moz-border-radius: 150px;"> '
flash("Now logged in as %s" % login_session['username'])
return output
@home_blueprint.route('/fbdisconnect')
def fbdisconnect():
facebook_id = login_session['facebook_id']
# The access token must me included to successfully logout
access_token = login_session['access_token']
url = 'https://graph.facebook.com/%s/permissions?access_token=%s' % (facebook_id, access_token)
h = httplib2.Http()
result = h.request(url, 'DELETE')[1]
return "you have been logged out"
# Show all restaurants
@home_blueprint.route('/')
@home_blueprint.route('/restaurant/')
def showRestaurants():
# restaurants = Restaurant.query.all()
restaurants = db.session.query(Restaurant).order_by(Restaurant.name.asc())
if 'username' not in login_session: # render diff templates based on if user is logged in or not
return render_template('publicrestaurants.html', restaurants=restaurants)
else:
return render_template('restaurants.html', restaurants=restaurants)
# Create a new restaurant
@home_blueprint.route('/restaurant/new/', methods=['GET', 'POST'])
def newRestaurant():
if 'username' not in login_session: # verify if user is logged in
return redirect('/login')
if request.method == 'POST':
newRestaurant = Restaurant(
name=request.form['name'], user_id=login_session['user_id']) # add user id to know who created the restaurant
newRestaurant.save()
flash('New Restaurant %s Successfully Created' % newRestaurant.name)
return redirect(url_for('home.showRestaurants'))
else:
return render_template('newRestaurant.html')
# Edit a restaurant
@home_blueprint.route('/restaurant/<int:restaurant_id>/edit/', methods=['GET', 'POST'])
def editRestaurant(restaurant_id):
if 'username' not in login_session:
return redirect('/login')
editedRestaurant = db.session.query(Restaurant).filter_by(id=restaurant_id).one()
if editedRestaurant.user_id != login_session['user_id']:
return "<script> function myFunction() {alert('You are not authorized to edit this restaurant. Please create your own restaurant in order to delete.');}</script><body onload='myFunction()''>"
if request.method == 'POST':
if request.form['name']:
editedRestaurant.name = request.form['name']
editedRestaurant.save()
flash('Restaurant Successfully Edited %s' % editedRestaurant.name)
return redirect(url_for('home.showRestaurants'))
else:
return render_template('editRestaurant.html', restaurant=editedRestaurant)
# Delete a restaurant
@home_blueprint.route('/restaurant/<int:restaurant_id>/delete/', methods=['GET', 'POST'])
def deleteRestaurant(restaurant_id):
if 'username' not in login_session:
return redirect('/login')
restaurantToDelete = db.session.query(
Restaurant).filter_by(id=restaurant_id).one()
# alert messages tro let user know hes not authorized since he didnt create it, used in create, edit, delete functions
if restaurantToDelete.user_id != login_session['user_id']:
return "<script> function myFunction() {alert('You are not authorized to delete this restaurant. Please create your own restaurant in order to delete.');}</script><body onload='myFunction()''>"
if request.method == 'POST':
restaurantToDelete.delete()
flash('%s Successfully Deleted' % restaurantToDelete.name)
return redirect(url_for('home.showRestaurants', restaurant_id=restaurant_id))
else:
return render_template('deleteRestaurant.html', restaurant=restaurantToDelete)
Файл моих моделей models.py
from project import db
from sqlalchemy.orm import relationship
from sqlalchemy import ForeignKey
class ResourceMixin(object):
def save(self):
"""
Save a model instance.
:return: Model instance
"""
db.session.add(self)
db.session.commit()
return self
def delete(self):
"""
Delete a model instance.
:return: db.session.commit()'s result
"""
db.session.delete(self)
return db.session.commit()
class User(ResourceMixin, db.Model):
__tablename__ = 'user'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(250), nullable=False)
email = db.Column(db.String(250), nullable=False)
picture = db.Column(db.String(250))
restaurant = db.relationship('Restaurant', backref='restaurant')
menuItems = db.relationship('MenuItem', backref='user')
def __init__(self, name, email, picture):
self.name = name
self.email = email
self.picture = picture
class Restaurant(ResourceMixin, db.Model):
__tablename__ = 'restaurant'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(250), nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
menuItem = db.relationship('MenuItem', backref='menu_item')
def __init__(self, name, user_id):
self.name = name
self.user_id = user_id
@property
def serialize(self):
"""Return object data in easily serializeable format"""
return {
'name': self.name,
'id': self.id,
}
class MenuItem(ResourceMixin, db.Model):
__tablename__ = 'menu_item'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), nullable=False)
description = db.Column(db.String(250))
price = db.Column(db.String(8))
course = db.Column(db.String(250))
restaurant_id = db.Column(db.Integer, db.ForeignKey('restaurant.id'))
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
def __init__(self, name, description, price, course, restaurant_id, user_id):
self.name = name
self.description = description
self.price = price
self.course = course
self.restaurant_id = restaurant_id
self.user_id = user_id
@property
def serialize(self):
"""Return object data in easily serializeable format"""
return {
'name': self.name,
'description': self.description,
'id': self.id,
'price': self.price,
'course': self.course,
}
Тесты, которые я хочу пройти, я знаю, что для каждого теста мне нужно, чтобы имя пользователя находилось в сеансе входа в систему, но я не знаю, как его настроить. Пожалуйста помоги!!!!!!tests.py
import unittest
from flask.ext.testing import TestCase
from project import app, db
from project.models import Restaurant, User, MenuItem
class BaseTestCase(TestCase):
"""A base test case."""
def create_app(self):
app.config.from_object('config.TestConfig')
return app
def setUp(self):
db.create_all()
db.session.add(User("admin", "ad@min.com", "admin"))
db.session.add(Restaurant("New Pizza", "1"))
db.session.add(MenuItem(name="New Pizza", description="Cheese Pizza",
price="12.99", course="Entree",
restaurant_id="1", user_id="1"))
db.session.commit()
def tearDown(self):
db.session.remove()
db.drop_all()
class FlaskTestCase(BaseTestCase):
def test_restaurant(self):
response = self.client.get('/restaurant/', content_type='html/text')
self.assertEqual(response.status_code, 200)
def test_restaurant_new(self):
response = self.client.post(
'/restaurant/new/',
data=dict(name="Pizza Place"),
follow_redirects=True)
self.assertIn(b'Successfully Created', response.data)
def test_restaurant_edit(self):
response = self.client.post(
'/restaurant/1/edit/',
data=dict(name="New Pizza 201"),
follow_redirects=True)
self.assertIn(b'Successfully Edited', response.data)
def test_restaurant_delete(self):
response = self.client.post(
'/restaurant/1/delete/', follow_redirects=True)
self.assertIn(b'Successfully Deleted', response.data)
def test_showMenu(self):
response = self.client.get('/restaurant/1/menu/',
content_type='html/text')
self.assertTrue(b'Add Menu Item' in response.data)
def test_newMenuItem(self):
response = self.client.post(
'/restaurant/1/menu/new/',
data=dict(name="New Pizza 23", description="Peperoni Pizza",
price="14.99", course="Entree", restaurant_id="1",
user_id="1"), follow_redirects=True)
self.assertIn(b'Successfully Created', response.data)
def test_editMenuItem(self):
response = self.client.post(
'/restaurant/1/menu/1/edit/',
data=dict(name="New Pizza", description="Cheese Pizza",
price="12.99", course="Entree", restaurant_id="1",
user_id="1"), follow_redirects=True)
self.assertIn(b'Menu Item Successfully Edited', response.data)
def test_deleteMenuItem(self):
response = self.client.post(
'/restaurant/1/menu/1/delete/',
follow_redirects=True
)
self.assertIn(b'Successfully Deleted', response.data)
if __name__ == '__main__':
unittest.main()