Skip to content
Snippets Groups Projects
Commit 096cfacb authored by Carl Schönfelder's avatar Carl Schönfelder
Browse files

#18: Improved model and tests

parent b161b1be
No related branches found
No related tags found
1 merge request!23Resolve "Add db-tests"
......@@ -2,8 +2,8 @@ from flask import Flask
from flask_bcrypt import Bcrypt
from flask_jwt_extended.jwt_manager import JWTManager
from flask_sqlalchemy import SQLAlchemy
from app.database import Base
from app.database import Base
bcrypt = Bcrypt()
jwt = JWTManager()
......@@ -29,6 +29,16 @@ def create_app(config_name="configmodule.DevelopmentConfig"):
return app
def add_user(email, plaintext_password, role, city):
from app.database.models import City, Role, User
item_role = Role.query.filter_by(name=role).first()
item_city = City.query.filter_by(name=city).first()
user = User(email, bcrypt.generate_password_hash(plaintext_password), item_role.id, item_city.id)
db.session.add(user)
db.commit()
def identity(payload):
user_id = payload["identity"]
return models.User.query.filter_by(id=user_id)
......
......@@ -2,6 +2,7 @@ import datetime
from app import db
from app.api import api_blueprint
from app.database.controller import add_user
from app.database.models import Blacklist, User
from app.utils.validator import edit_user_schema, login_schema, register_schema, validateObject
from flask import request
......@@ -90,11 +91,12 @@ def create():
if existing_user != None:
return {"message": "User already exists"}, 400
user = User(json_dict["email"], json_dict["password"])
db.session.add(user)
add_user(json_dict["email"], json_dict["password"], json_dict["role"], json_dict["city"])
db.session.commit()
return user.get_dict(), 200
item_user = User.query.filter_by(email=json_dict["email"]).first()
return item_user.get_dict(), 200
@api_blueprint.route("/users/", methods=["PUT"])
......
from app import db
from app.database.models import City, Role, User
def add_user(email, plaintext_password, role, city):
item_role = Role.query.filter_by(name=role).first()
item_city = City.query.filter_by(name=city).first()
user = User(email, plaintext_password, item_role.id, item_city.id)
db.session.add(user)
from enum import unique
from app import bcrypt, db
from sqlalchemy.ext.declarative import declared_attr
from sqlalchemy.ext.hybrid import hybrid_method, hybrid_property
......@@ -7,7 +9,8 @@ STRING_SIZE = 254
class Blacklist(db.Model):
id = db.Column(db.Integer, primary_key=True)
jti = db.Column(db.String, unique=True, nullable=False)
jti = db.Column(db.String, unique=True)
expire_date = db.Column(db.Integer, nullable=True)
def __init__(self, jti):
self.jti = jti
......@@ -23,6 +26,7 @@ class Role(db.Model):
self.name = name
# TODO Region?
class City(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(STRING_SIZE), unique=True)
......@@ -36,27 +40,26 @@ class City(db.Model):
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(254), unique=True, nullable=False)
name = db.Column(db.String(50), nullable=True)
email = db.Column(db.String(STRING_SIZE), unique=True)
name = db.Column(db.String(STRING_SIZE), nullable=True)
_password = db.Column(db.LargeBinary(60), nullable=False)
authenticated = db.Column(db.Boolean, default=False)
# Change to false for Two factor authen
authenticated = db.Column(db.Boolean, default=False)
twoAuthConfirmed = db.Column(db.Boolean, default=True)
twoAuthCode = db.Column(db.String(100), nullable=True)
twoAuthCode = db.Column(db.String(STRING_SIZE), nullable=True)
role_id = db.Column(db.Integer, db.ForeignKey("role.id"), nullable=True) # Change to false
city_id = db.Column(db.Integer, db.ForeignKey("city.id"), nullable=True) # Change to false
role_id = db.Column(db.Integer, db.ForeignKey("role.id"), nullable=False)
city_id = db.Column(db.Integer, db.ForeignKey("city.id"), nullable=False)
media = db.relationship("Media", backref="upload_by")
def __init__(self, email, plaintext_password, name=None, role_id=None, city_id=None):
def __init__(self, email, plaintext_password, role_id, city_id):
self._password = bcrypt.generate_password_hash(plaintext_password)
self.email = email
self.role_id = role_id
self.city_id = city_id
self.name = name
self.authenticated = False
def get_dict(self):
......@@ -78,26 +81,26 @@ class User(db.Model):
class Media(db.Model):
id = db.Column(db.Integer, primary_key=True)
filename = db.Column(db.String(STRING_SIZE), unique=True)
type = db.Column(db.Integer, nullable=False)
type_id = db.Column(db.Integer, db.ForeignKey("media_type.id"), nullable=False)
upload_by_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False)
styles = db.relationship("Style", backref="bg_image")
def __init__(self, filename, type, upload_by_id):
def __init__(self, filename, type_id, upload_by_id):
self.filename = filename
self.type = type
self.type_id = type_id
self.upload_by_id = upload_by_id
class Style(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(STRING_SIZE), unique=True)
css = db.Column(db.Text, nullable=True)
css = db.Column(db.Text, nullable=False)
bg_image_id = db.Column(db.Integer, db.ForeignKey("media.id"), nullable=True)
competition = db.relationship("Competition", backref="style")
def __init__(self, name, css=None, bg_image_id=None):
def __init__(self, name, css, bg_image_id=None):
self.name = name
self.css = css
self.bg_image_id = bg_image_id
......@@ -119,8 +122,9 @@ class Competition(db.Model):
class Team(db.Model):
__table_args__ = (db.UniqueConstraint("competition_id", "name"),)
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(STRING_SIZE), unique=True)
name = db.Column(db.String(STRING_SIZE), nullable=False)
competition_id = db.Column(db.Integer, db.ForeignKey("competition.id"), nullable=False)
answered_questions = db.relationship("AnsweredQuestion", backref="team")
......@@ -131,39 +135,41 @@ class Team(db.Model):
class Slide(db.Model):
__table_args__ = (db.UniqueConstraint("order", "competition_id"),)
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(STRING_SIZE), unique=True)
title = db.Column(db.String(STRING_SIZE), nullable=True)
order = db.Column(db.Integer, nullable=False)
tweak_settings = db.Column(db.Text, nullable=True)
title = db.Column(db.String(STRING_SIZE), nullable=False, default="")
body = db.Column(db.Text, nullable=False, default="")
timer = db.Column(db.Integer, nullable=False, default=0)
tweak_settings = db.Column(db.Text, nullable=False, default="")
competition_id = db.Column(db.Integer, db.ForeignKey("competition.id"), nullable=False)
questions = db.relationship("Question", backref="slide")
def __init__(self, name, order, competition_id, tweak_settings=None):
self.name = name
def __init__(self, order, competition_id):
self.order = order
self.competition_id = competition_id
self.tweak_settings = tweak_settings
class Question(db.Model):
__table_args__ = (db.UniqueConstraint("slide_id", "name"), db.UniqueConstraint("slide_id", "order"))
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(STRING_SIZE), unique=True)
timer = db.Column(db.Integer, nullable=False)
type = db.Column(db.Integer, nullable=False)
name = db.Column(db.String(STRING_SIZE), nullable=False)
order = db.Column(db.Integer, nullable=False)
type_id = db.Column(db.Integer, db.ForeignKey("question_type.id"), nullable=False)
slide_id = db.Column(db.Integer, db.ForeignKey("slide.id"), nullable=False)
answered_questions = db.relationship("AnsweredQuestion", backref="question")
alternatives = db.relationship("QuestionAlternative", backref="question")
def __init__(self, name, timer, type, slide_id):
def __init__(self, name, order, type_id, slide_id):
self.name = name
self.timer = timer
self.type = type
self.order = order
self.type_id = type_id
self.slide_id = slide_id
class QuestionAlternative(db.Model):
__table_args__ = (db.UniqueConstraint("question_id", "order"),)
id = db.Column(db.Integer, primary_key=True)
text = db.Column(db.String(STRING_SIZE), nullable=False)
value = db.Column(db.Boolean, nullable=False)
......@@ -177,10 +183,12 @@ class QuestionAlternative(db.Model):
self.question_id = question_id
# TODO QuestionAnswer
class AnsweredQuestion(db.Model):
__table_args__ = (db.UniqueConstraint("question_id", "team_id"),)
id = db.Column(db.Integer, primary_key=True)
data = db.Column(db.Text, nullable=False)
score = db.Column(db.Integer, nullable=False)
score = db.Column(db.Integer, nullable=False, default=0) # 0: False, 1: True
question_id = db.Column(db.Integer, db.ForeignKey("question.id"), nullable=False)
team_id = db.Column(db.Integer, db.ForeignKey("team.id"), nullable=False)
......@@ -191,6 +199,24 @@ class AnsweredQuestion(db.Model):
self.team_id = team_id
class MediaType(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(STRING_SIZE), unique=True)
media = db.relationship("Media", backref="type")
def __init__(self, name):
self.name = name
class QuestionType(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(STRING_SIZE), unique=True)
questions = db.relationship("Question", backref="type")
def __init__(self, name):
self.name = name
"""
QuestionHandler = db.Table(
"question_handler",
......
from app import add_user, db
from app.database.controller import add_user
from app.database.models import City, MediaType, QuestionType, Role, User
media_types = ["Image", "Video"]
question_types = ["Boolean", "Multiple", "Text"]
roles = ["Admin", "Editor"]
cities = ["Linköping"]
def add_default_values():
# Add media types
for type in media_types:
db.session.add(MediaType(type))
# Add question types
for type in question_types:
db.session.add(QuestionType(type))
# Add roles
for role in roles:
db.session.add(Role(role))
# Add cities
for city in cities:
db.session.add(City(city))
# Commit changes to db
db.session.commit()
# Add user with role and city
add_user("test@test.se", "password", "Admin", "Linköping")
db.session.commit()
from app import db
def get_one(type, **kwargs):
return type.query.filter_by(**kwargs).first()
# Try insert invalid row. If it fails then the test is passed
def assert_insert_fail(type, *args):
try:
db.session.add(type(*args))
db.session.commit()
assert False
except:
db.session.rollback()
def assert_exists(type, length, **kwargs):
items = type.query.filter_by(**kwargs).all()
assert len(items) == length
return items[0]
def assert_object_values(object, dict):
for k, v in dict.items():
assert getattr(object, k) == v
from requests import *
import json
HOST = "http://localhost:5000/"
def _post(url: str, jdict: dict):
post(HOST + url, json.dumps(jdict))
def asdasd(i: int):
return i
print("Populate default database data")
_post("user/", {"email": "admin@test.com", "password": "password", "name": "Admin Adminsson"})
......@@ -17,6 +17,8 @@ login_schema = {
register_schema = {
"email": {"type": "string", "required": True, "regex": _email_regex},
"password": {"type": "string", "required": True, "minlength": 6, "maxlength": 128},
"role": {"type": "string", "required": True},
"city": {"type": "string", "required": True},
}
edit_user_schema = {
......
import json
from app.database.populate import add_default_values
from tests import app, client
def test_app(client):
add_default_values()
register_data = {"email": "test1@test.se", "password": "abc123", "role": "Admin", "city": "Linköping"}
# Create user
rv = client.post(
"/api/users/",
data=json.dumps({"email": "test@test.se", "password": "abc123"}),
data=json.dumps(register_data),
)
rv_dict = json.loads(rv.data.decode())
assert rv.status_code == 200
assert rv_dict["id"] == 1
assert rv_dict["id"] == 2
assert "password" not in rv_dict
assert rv_dict["email"] == "test@test.se"
assert rv_dict["email"] == "test1@test.se"
# Try loggin with wrong PASSWORD
rv = client.post("/api/users/login", data=json.dumps({"email": "test@test.se", "password": "abc1234"}))
rv = client.post("/api/users/login", data=json.dumps({"email": "test1@test.se", "password": "abc1234"}))
assert rv.status_code == 401
# Try loggin with wrong Email
rv = client.post("/api/users/login", data=json.dumps({"email": "test1@test.se", "password": "abc1234"}))
rv = client.post("/api/users/login", data=json.dumps({"email": "testx@test.se", "password": "abc1234"}))
assert rv.status_code == 401
# Try loggin with right PASSWORD
rv = client.post("/api/users/login", data=json.dumps({"email": "test@test.se", "password": "abc123"}))
rv = client.post("/api/users/login", data=json.dumps({"email": "test1@test.se", "password": "abc123"}))
rv_dict = json.loads(rv.data.decode())
assert rv.status_code == 200
headers = {"Authorization": "Bearer " + rv_dict["access_token"]}
......@@ -35,7 +39,7 @@ def test_app(client):
rv = client.get("/api/users/", headers=headers)
rv_dict = json.loads(rv.data.decode())
assert rv.status_code == 200
assert rv_dict["email"] == "test@test.se"
assert rv_dict["email"] == "test1@test.se"
rv = client.put("/api/users/", data=json.dumps({"name": "carl carlsson"}), headers=headers)
rv_dict = json.loads(rv.data.decode())
......
import json
import pytest
from app.database.models import AnsweredQuestion, City, Competition, Media, Question, Role, Slide, Style, Team, User
from app.database.controller import add_user
from app.database.models import (
AnsweredQuestion,
City,
Competition,
Media,
MediaType,
Question,
QuestionType,
Role,
Slide,
Style,
Team,
User,
)
from app.database.populate import add_default_values
from app.utils.db_test_helpers import *
from tests import app, client, db
roles = ["Admin", "Editor"]
cities = ["Sveg", "Linköping"]
@pytest.mark.skip()
def create_user():
# Add roles
for role in roles:
db.session.add(Role(role))
# Add cities
for city in cities:
db.session.add(City(city))
# Commit roles and cities to db
db.session.commit()
# Get one role and one city
item_role = Role.query.filter_by(name="Admin").first()
item_city = City.query.filter_by(name="Sveg").first()
# Add user with role and city
db.session.add(
User(
"test@test.se",
"password",
"carl carlsson",
item_role.id,
item_city.id,
)
)
# Return the user
db.session.commit()
item_user = User.query.filter_by(email="test@test.se").first()
return item_user
# server/env/Scripts/pytest.exe --cov app server/tests/
def test_user(client):
item_user = create_user()
add_default_values()
item_user = User.query.filter_by(email="test@test.se").first()
# Assert user
assert item_user != None
assert item_user.city.name == "Sveg"
assert item_user.city.name == "Linköping"
assert item_user.role.name == "Admin"
item_role = Role.query.filter_by(name="Admin").first()
item_city = City.query.filter_by(name="Sveg").first()
item_city = City.query.filter_by(name="Linköping").first()
# Assert user with role and city
assert len(item_role.users) == 1 and item_role.users[0].id == item_user.id
......@@ -60,10 +40,14 @@ def test_user(client):
def test_media_style(client):
item_user = create_user()
add_default_values()
item_user = User.query.filter_by(email="test@test.se").first()
# Get image type
image_type = MediaType.query.filter_by(name="Image").first()
# Add image
db.session.add(Media("bild.png", 1, item_user.id))
db.session.add(Media("bild.png", image_type.id, item_user.id))
db.session.commit()
# Assert image
......@@ -87,10 +71,14 @@ def test_media_style(client):
def test_question(client):
item_user = create_user()
add_default_values()
item_user = User.query.filter_by(email="test@test.se").first()
# Get image type
image_type = MediaType.query.filter_by(name="Image").first()
# Add image
db.session.add(Media("bild.png", 1, item_user.id))
db.session.add(Media("bild.png", image_type.id, item_user.id))
db.session.commit()
item_media = Media.query.filter_by(filename="bild.png").first()
......@@ -100,29 +88,65 @@ def test_question(client):
item_style = Style.query.filter_by(name="template").first()
# Add competition
item_city = City.query.filter_by(name="Sveg").first()
item_city = City.query.filter_by(name="Linköping").first()
db.session.add(Competition("teknik8", item_style.id, item_city.id))
db.session.add(Competition("teknik9", item_style.id, item_city.id))
db.session.commit()
item_competition = Competition.query.filter_by(name="teknik8").first()
item_competition_2 = Competition.query.filter_by(name="teknik9").first()
assert item_competition != None
assert item_competition.id == 1
assert item_competition.style.name == "template"
assert item_competition.city.name == "Sveg"
assert item_competition.city.name == "Linköping"
# Add teams
db.session.add(Team("Lag1", item_competition.id))
db.session.add(Team("Lag2", item_competition.id))
db.session.commit()
# Slide
db.session.add(Slide("Slide1", 1, item_competition.id))
db.session.add(Slide("Slide2", 2, item_competition.id))
db.session.add(Slide("Slide3", 3, item_competition.id))
assert_insert_fail(Team, "Lag1", item_competition.id)
db.session.add(Team("Lag1", item_competition_2.id))
db.session.commit()
item_slides = Slide.query.all()
"""
# TrueFalse
db.session.add(Question("Fråga1", "Är 1+1=2", 60, item_slides[1].id))
assert Team.query.filter((Team.competition_id == item_competition.id) & (Team.name == "Lag1")).count() == 1
assert Team.query.filter((Team.competition_id == item_competition.id) & (Team.name == "Lag2")).count() == 1
assert Team.query.filter((Team.competition_id == item_competition_2.id) & (Team.name == "Lag1")).count() == 1
assert Team.query.filter(Team.name == "Lag1").count() == 2
assert Team.query.filter(Team.competition_id == item_competition.id).count() == 2
assert Team.query.count() == 3
# Add slides
db.session.add(Slide(1, item_competition.id))
db.session.add(Slide(2, item_competition.id))
db.session.add(Slide(3, item_competition.id))
db.session.commit()
# item_question1 = Question.query.filter_by(name="Fråga1").first()
# Try add slide with same order
assert_insert_fail(Slide, 1, item_competition.id)
assert_exists(Slide, 1, order=1)
item_slide1 = Slide.query.filter_by(order=1).first()
item_slide2 = Slide.query.filter_by(order=2).first()
item_slide3 = Slide.query.filter_by(order=3).first()
assert item_slide1 != None
assert item_slide2 != None
assert item_slide3 != None
# Multiple choice
db.session.add(Question("Fråga2", "Vilket land är störst", 60, item_slides[2].id))
# Add questions
question_type_bool = QuestionType.query.filter_by(name="Boolean").first()
question_type_multiple = QuestionType.query.filter_by(name="Multiple").first()
db.session.add(Question("Fråga1", 0, question_type_bool.id, item_slide2.id))
db.session.add(Question("Fråga2", 1, question_type_multiple.id, item_slide3.id))
db.session.commit()
"""
assert question_type_bool != None
assert question_type_multiple != None
item_q1 = Question.query.filter_by(name="Fråga1").first()
item_q2 = Question.query.filter_by(name="Fråga2").first()
assert item_q1.type.name == "Boolean"
assert item_q2.type.name == "Multiple"
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment