Added unit tests for user login.

This commit is contained in:
neviyn 2016-01-24 19:01:53 +00:00
parent 80d988e2c6
commit 7dad8ab54d
4 changed files with 88 additions and 11 deletions

View File

@ -4,3 +4,4 @@ SQLALCHEMY_DATABASE_URI = 'sqlite:///wanikani.db'
SECRET_KEY = "putabettersecretkeyhere" SECRET_KEY = "putabettersecretkeyhere"
DEBUG = False DEBUG = False
PORT = 5000 PORT = 5000
SQLALCHEMY_TRACK_MODIFICATIONS = False

View File

@ -4,4 +4,5 @@ flask
flask-login flask-login
flask-sqlalchemy flask-sqlalchemy
flask-wtf flask-wtf
flask-testing
ujson ujson

69
tests.py Normal file
View File

@ -0,0 +1,69 @@
import unittest
from wanikaniburned import app, db, User
from flask.ext.testing import TestCase
class BaseTestCase(TestCase):
def create_app(self):
app.config.update(
TESTING=True,
SQLALCHEMY_DATABASE_URI='sqlite:///:memory:',
SECRET_KEY="testkey",
WTF_CSRF_ENABLED=False,
PRESERVE_CONTEXT_ON_EXCEPTION=False,
HASH_ROUNDS=1
)
return app
def setUp(self):
db.create_all()
def tearDown(self):
db.session.remove()
db.drop_all()
class TestLogin(BaseTestCase):
def login(self):
user = User('test', False)
return self.client.post('/', data={'api_key': user.api_key})
def test_user_login(self):
response = self.login()
self.assertRedirects(response, '/quiz')
def test_user_logout(self):
response = self.login()
self.assertRedirects(response, '/quiz')
response = self.client.get('/logout')
self.assertRedirects(response, '/')
def test_homepage_without_login(self):
response = self.client.get('/')
self.assert200(response)
self.assertTemplateUsed("welcome.html")
def test_quiz_inaccessible_without_login(self):
response = self.client.get('/quiz')
self.assertRedirects(response, '/')
def test_user_items_inaccessible_without_login(self):
response = self.client.get('/user_items')
self.assertRedirects(response, '/')
def test_homepage_with_existing_login(self):
response = self.login() # Login
self.assertRedirects(response, '/quiz')
response = self.client.get('/') # Try to go back to the homepage
self.assertRedirects(response, '/quiz')
def test_user_items_with_existing_login(self):
response = self.login() # Login
self.assertRedirects(response, '/quiz')
response = self.client.get('/user_items')
self.assert200(response)
if __name__ == '__main__':
unittest.main()

View File

@ -12,7 +12,11 @@ from wtforms import StringField
from wtforms.validators import DataRequired from wtforms.validators import DataRequired
app = flask.Flask(__name__) app = flask.Flask(__name__)
app.config.from_pyfile('config.py') app.config.update(
PORT=5000,
JSON_AS_ASCII=False
)
app.config.from_pyfile('config.py', silent=True)
login_manager = LoginManager() login_manager = LoginManager()
login_manager.init_app(app) login_manager.init_app(app)
db = SQLAlchemy(app) db = SQLAlchemy(app)
@ -33,8 +37,10 @@ class User(db.Model):
gravatar = db.Column(db.String) gravatar = db.Column(db.String)
last_updated = db.Column(db.DateTime) last_updated = db.Column(db.DateTime)
def __init__(self, api_key): def __init__(self, api_key, auto_init=True):
self.api_key = api_key self.api_key = api_key
self.last_updated = datetime.min
if auto_init:
self.last_updated = datetime.utcnow() self.last_updated = datetime.utcnow()
self.parse_radicals_and_userdata() self.parse_radicals_and_userdata()
self.parse_kanji() self.parse_kanji()
@ -117,14 +123,14 @@ def get_items_with_level_restriction(level_range, item_state, item_types):
items = [] items = []
radical_count = 0 radical_count = 0
loads = json.loads loads = json.loads
if 'radical' in item_types: if 'radical' in item_types and current_user.radicals:
items.extend({'item_type': 'radical', 'answer': item['meaning'], 'question': item['image'] items.extend({'item_type': 'radical', 'answer': item['meaning'], 'question': item['image']
if item['image'] else item['character']} for item in loads(current_user.radicals) if item['image'] else item['character']} for item in loads(current_user.radicals)
if item['user_specific'] and item['user_specific']['srs'] in item_state if item['user_specific'] and item['user_specific']['srs'] in item_state
and item['level'] in level_range) and item['level'] in level_range)
radical_count = len(items) radical_count = len(items)
kanji_count = 0 kanji_count = 0
if 'kanji' in item_types: if 'kanji' in item_types and current_user.kanji:
for item in filter((lambda x: x['user_specific'] and x['user_specific']['srs'] in item_state for item in filter((lambda x: x['user_specific'] and x['user_specific']['srs'] in item_state
and x['level'] in level_range), loads(current_user.kanji)): and x['level'] in level_range), loads(current_user.kanji)):
items.extend([{'item_type': 'kanji', 'question': item['character'], items.extend([{'item_type': 'kanji', 'question': item['character'],
@ -134,7 +140,7 @@ def get_items_with_level_restriction(level_range, item_state, item_types):
'answer_type': 'eng'}]) 'answer_type': 'eng'}])
kanji_count = int((len(items) - radical_count) / 2) kanji_count = int((len(items) - radical_count) / 2)
vocabulary_count = 0 vocabulary_count = 0
if 'vocab' in item_types: if 'vocab' in item_types and current_user.vocabulary:
for item in filter((lambda x: x['user_specific'] and x['user_specific']['srs'] in item_state for item in filter((lambda x: x['user_specific'] and x['user_specific']['srs'] in item_state
and x['level'] in level_range), loads(current_user.vocabulary)): and x['level'] in level_range), loads(current_user.vocabulary)):
items.extend([{'item_type': 'vocabulary', 'question': item['character'], 'answer': item['kana'], items.extend([{'item_type': 'vocabulary', 'question': item['character'], 'answer': item['kana'],
@ -179,7 +185,7 @@ def show_home():
@app.route('/quiz') @app.route('/quiz')
def show_quiz(): def show_quiz():
if not login_fresh(): if not login_fresh():
if User.query.get(current_user.api_key): if not current_user.is_anonymous and User.query.get(current_user.api_key):
confirm_login() confirm_login()
return flask.render_template("quiz.html") return flask.render_template("quiz.html")
else: else:
@ -224,11 +230,11 @@ def unauthorized():
return flask.redirect(flask.url_for('show_home')) return flask.redirect(flask.url_for('show_home'))
@app.template_filter('datetime_format')
def datetime_format(input_data): def datetime_format(input_data):
return input_data.strftime("%d %B %Y %I:%M%p") return input_data.strftime("%d %B %Y %I:%M%p")
if __name__ == '__main__': if __name__ == '__main__':
db.create_all() db.create_all()
app.jinja_env.filters['datetime_format'] = datetime_format
app.run(threaded=True, port=app.config['PORT']) app.run(threaded=True, port=app.config['PORT'])