wanikaniburned/tests.py
2016-05-31 03:53:29 +01:00

247 lines
10 KiB
Python

import gzip
import ujson as json
import unittest
from wanikaniburned import app, db
from wanikaniburned.wanikaniburned import User, datetime_format, parse_range
from flask.ext.testing import TestCase
from datetime import datetime
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_quiz_accessible_with_login(self):
self.login()
response = self.client.get('/quiz')
self.assert200(response)
self.assertTemplateUsed("quiz.html")
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)
def test_login_with_username(self):
user = User('test', False, "alternate")
response = self.client.post('/', data={'api_key': user.username})
self.assertRedirects(response, '/quiz')
def test_login_same_username_new_api_key(self):
user = User('test', False, "alternate")
changed_user = User('newapikey', False, "alternate")
self.assertTrue(User.query.get(changed_user.api_key))
self.assertFalse(User.query.get(user.api_key))
response = self.client.post('/', data={'api_key': user.username})
self.assertRedirects(response, '/quiz')
class TestFormats(unittest.TestCase):
def test_custom_datetime_format(self):
test_time = datetime.min
output = datetime_format(test_time)
self.assertEqual(output, test_time.strftime("%d %B %Y %I:%M%p"))
def test_parse_range_empty(self):
self.assertIsNone(parse_range(""))
def test_parse_range_letters(self):
self.assertIsNone(parse_range("ab-st,z"))
def test_parse_range_single_number(self):
self.assertEqual(parse_range("1"), [1])
def test_parse_range_two_with_dash(self):
self.assertEqual(parse_range("1-4"), [1, 2, 3, 4])
def test_parse_range_two_with_comma(self):
self.assertEqual(parse_range("1,2"), [1, 2])
def test_parse_range_dash_and_comma(self):
self.assertEqual(parse_range("1,4-6"), [1, 4, 5, 6])
class TestUserItems(BaseTestCase):
with gzip.open("testuserdata.json.gz", "rb") as input_file:
user_data = json.loads(input_file.read().decode('utf8'))
user_radicals = user_data['radicals']
user_kanji = user_data['kanji']
user_vocabulary = user_data['vocabulary']
def get_user(self):
user = User('test', False)
user.radicals = json.dumps(self.user_radicals, ensure_ascii=False)
user.kanji = json.dumps(self.user_kanji, ensure_ascii=False)
user.vocabulary = json.dumps(self.user_vocabulary, ensure_ascii=False)
return user
def login(self, user):
return self.client.post('/', data={'api_key': user.api_key})
def count_filter(self, item_list, item_type=None, level_range=list(range(0, 61))):
if item_type is None:
item_type = ['burned']
return sum(1 for item in item_list if item['user_specific'] and item['user_specific']['srs'] in item_type
and item['level'] in level_range)
def flatten_list_to_string(self, input_list):
return ",".join(map(str, input_list))
def test_count_default(self):
user = self.get_user()
self.login(user)
response = self.client.get('/user_items')
response = json.loads(response.data)
self.assertEqual(response['radical_count'], self.count_filter(self.user_radicals))
self.assertEqual(response['kanji_count'], self.count_filter(self.user_kanji))
self.assertEqual(response['vocabulary_count'], self.count_filter(self.user_vocabulary))
def test_filter_single_type(self):
user = self.get_user()
self.login(user)
response = self.client.get('/user_items?item_types=radical')
response = json.loads(response.data)
self.assertEqual(response['radical_count'], self.count_filter(self.user_radicals))
self.assertEqual(response['kanji_count'], 0)
self.assertEqual(response['vocabulary_count'], 0)
def test_filter_double_type(self):
user = self.get_user()
self.login(user)
response = self.client.get('/user_items?item_types=radical,kanji')
response = json.loads(response.data)
self.assertEqual(response['radical_count'], self.count_filter(self.user_radicals))
self.assertEqual(response['kanji_count'], self.count_filter(self.user_kanji))
self.assertEqual(response['vocabulary_count'], 0)
def test_filter_all_type(self):
user = self.get_user()
self.login(user)
response = self.client.get('/user_items?item_types=radical,kanji,vocab')
response = json.loads(response.data)
self.assertEqual(response['radical_count'], self.count_filter(self.user_radicals))
self.assertEqual(response['kanji_count'], self.count_filter(self.user_kanji))
self.assertEqual(response['vocabulary_count'], self.count_filter(self.user_vocabulary))
def test_filter_invalid_type(self):
user = self.get_user()
self.login(user)
response = self.client.get('/user_items?item_types=invalid')
response = json.loads(response.data)
self.assertEqual(response, dict(error='No items within these filter parameters'))
def test_filter_single_level(self):
test_data = [1]
user = self.get_user()
self.login(user)
response = self.client.get('/user_items?level_range=' + (self.flatten_list_to_string(test_data)))
response = json.loads(response.data)
self.assertEqual(response['radical_count'], self.count_filter(self.user_radicals, level_range=test_data))
self.assertEqual(response['kanji_count'], self.count_filter(self.user_kanji, level_range=test_data))
self.assertEqual(response['vocabulary_count'], self.count_filter(self.user_vocabulary, level_range=test_data))
def test_filter_multiple_levels(self):
test_data = [1, 2, 4]
user = self.get_user()
self.login(user)
response = self.client.get('/user_items?level_range=' + (self.flatten_list_to_string(test_data)))
response = json.loads(response.data)
self.assertEqual(response['radical_count'], self.count_filter(self.user_radicals, level_range=test_data))
self.assertEqual(response['kanji_count'], self.count_filter(self.user_kanji, level_range=test_data))
self.assertEqual(response['vocabulary_count'], self.count_filter(self.user_vocabulary, level_range=test_data))
def test_filter_invalid_levels(self):
test_data = [0, 61, 1000]
user = self.get_user()
self.login(user)
response = self.client.get('/user_items?level_range=' + (self.flatten_list_to_string(test_data)))
response = json.loads(response.data)
self.assertEqual(response, dict(error='No items within these filter parameters'))
def test_filter_single_state(self):
test_data = ['enlighten']
user = self.get_user()
self.login(user)
response = self.client.get('/user_items?item_state=' + (self.flatten_list_to_string(test_data)))
response = json.loads(response.data)
self.assertEqual(response['radical_count'], self.count_filter(self.user_radicals, test_data))
self.assertEqual(response['kanji_count'], self.count_filter(self.user_kanji, test_data))
self.assertEqual(response['vocabulary_count'], self.count_filter(self.user_vocabulary, test_data))
def test_filter_multiple_state(self):
test_data = ['guru', 'master', 'apprentice']
user = self.get_user()
self.login(user)
response = self.client.get('/user_items?item_state=' + (self.flatten_list_to_string(test_data)))
response = json.loads(response.data)
self.assertEqual(response['radical_count'], self.count_filter(self.user_radicals, test_data))
self.assertEqual(response['kanji_count'], self.count_filter(self.user_kanji, test_data))
self.assertEqual(response['vocabulary_count'], self.count_filter(self.user_vocabulary, test_data))
def test_filter_invalid_state(self):
test_data = ['invalid', 'alsoinvalid']
user = self.get_user()
self.login(user)
response = self.client.get('/user_items?item_state=' + (self.flatten_list_to_string(test_data)))
response = json.loads(response.data)
self.assertEqual(response, dict(error='No items within these filter parameters'))
if __name__ == '__main__':
unittest.main()