Add initial tests for the admin site

Tests that the admin site requires a user with the admin role
This commit is contained in:
Matthew Welch 2021-03-28 17:33:59 -07:00
parent 85909e7087
commit a69c85c588
8 changed files with 88 additions and 6 deletions

1
.gitignore vendored
View File

@ -2,3 +2,4 @@
.idea/ .idea/
__pycache__/ __pycache__/
venv/ venv/
test.db

View File

@ -68,9 +68,6 @@ def query_questions():
"multiple_choice": getattr(question, "multiple_choice", None) is not None, "multiple_choice": getattr(question, "multiple_choice", None) is not None,
"hidden_answer": getattr(question, "hidden_answer", None) is not None, "hidden_answer": getattr(question, "hidden_answer", None) is not None,
}) })
# question1 = get_question(database.AllQuestions, 0)
# question2 = get_question(database.AllQuestions, 1)
# question3 = get_question(database.AllQuestions, 2)
return jsonify(response_dict) return jsonify(response_dict)

View File

@ -29,3 +29,11 @@ class Development(Config):
DEBUG = True DEBUG = True
TESTING = True TESTING = True
DB_URL = f"postgresql+psycopg2://{Config.DB_USER}:{Config.DB_PASSWORD}@{Config.DB_HOST}:{Config.DB_PORT}/{Config.DB_NAME}" DB_URL = f"postgresql+psycopg2://{Config.DB_USER}:{Config.DB_PASSWORD}@{Config.DB_HOST}:{Config.DB_PORT}/{Config.DB_NAME}"
class Testing(Config):
FLASK_ENV = "testing"
DEBUG = True
TESTING = True
WTF_CSRF_ENABLED = False
DB_URL = "sqlite:///test.db"

View File

@ -3,8 +3,7 @@ from flask_security import UserMixin, RoleMixin
import sqlalchemy import sqlalchemy
from typing import Union, Optional, Literal, Type, List, Tuple from typing import Union, Optional, Literal, Type, List, Tuple
import random import random
from sqlalchemy import Column, JSON, String, Integer, create_engine, ForeignKey, func, ARRAY, Boolean, UnicodeText, \ from sqlalchemy import Column, JSON, String, Integer, create_engine, ForeignKey, func, Boolean, UnicodeText, DateTime
DateTime
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.associationproxy import association_proxy from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.orm import sessionmaker, relationship, scoped_session from sqlalchemy.orm import sessionmaker, relationship, scoped_session
@ -31,6 +30,11 @@ def init_db():
Base.metadata.create_all(engine) Base.metadata.create_all(engine)
def destroy_db():
engine = create_engine(current_app.config["DB_URL"])
Base.metadata.drop_all(engine)
Base = declarative_base() Base = declarative_base()
@ -134,7 +138,7 @@ class MultipleChoice(Base):
question_id = Column(Integer, ForeignKey("all_questions.question_id"), primary_key=True) question_id = Column(Integer, ForeignKey("all_questions.question_id"), primary_key=True)
multiple_choice_difficulty = Column(Integer) multiple_choice_difficulty = Column(Integer)
multiple_choice_hint = Column(JSON) multiple_choice_hint = Column(JSON)
wrong_answers = Column(ARRAY(String)) wrong_answers = Column(JSON)
all_question_relationship = relationship("AllQuestions", lazy="joined", back_populates="multiple_choice") all_question_relationship = relationship("AllQuestions", lazy="joined", back_populates="multiple_choice")
question_text = association_proxy("all_question_relationship", "question_text") question_text = association_proxy("all_question_relationship", "question_text")

View File

@ -10,3 +10,4 @@ scramp==1.2.0
SQLAlchemy==1.3.23 SQLAlchemy==1.3.23
Werkzeug==1.0.1 Werkzeug==1.0.1
Flask-Security-Too~=4.0.0 Flask-Security-Too~=4.0.0
pytest~=6.2.2

0
tests/__init__.py Normal file
View File

60
tests/conftest.py Normal file
View File

@ -0,0 +1,60 @@
import os
from flask_security import hash_password, SQLAlchemySessionUserDatastore
from QuizTheWord.database import User, Role, AllQuestions, MultipleChoice, HiddenAnswer, get_session, init_db, destroy_db
import pytest
@pytest.fixture(scope="module")
def client():
os.environ["CONFIGURATION_SETUP"] = "QuizTheWord.config.Testing"
from QuizTheWord import app
with app.app.test_client() as client:
with app.app.app_context():
yield client
@pytest.fixture(scope="module")
def session():
return get_session()
@pytest.fixture(scope="module")
def init_database(client, session):
init_db()
user_datastore = SQLAlchemySessionUserDatastore(session, User, Role)
admin_role = user_datastore.create_role(name="admin")
basic_user = user_datastore.create_user(email="basic@test.com", password=hash_password("password"))
admin_user = user_datastore.create_user(email="admin@test.com", password=hash_password("admin"))
main_question = AllQuestions(question_id=0, question="question", answer="answer", addresses="")
multiple_choice = MultipleChoice(question_id=0, difficulty=1, hint="", wrong_answers=["", ""], base_question=main_question)
hidden_answer = HiddenAnswer(question_id=0, difficulty=1, hint="", base_question=main_question)
session.add(admin_role)
session.add(basic_user)
session.add(admin_user)
session.add(main_question)
session.add(multiple_choice)
session.add(hidden_answer)
user_datastore.add_role_to_user(admin_user, admin_role)
session.commit()
yield
destroy_db()
@pytest.fixture
def login_basic_user(client, init_database):
client.post("/login", data=dict(email="basic@test.com", password="password", remember=False), follow_redirects=True)
yield
client.get('/logout', follow_redirects=True)
@pytest.fixture
def login_admin_user(client, init_database):
client.post("/login", data=dict(email="admin@test.com", password="admin", remember=False), follow_redirects=True)
yield
client.get('/logout', follow_redirects=True)

11
tests/test_admin.py Normal file
View File

@ -0,0 +1,11 @@
from flask.testing import FlaskClient
def test_admin_home_with_basic_user(client: FlaskClient, login_basic_user):
response = client.get("/admin/")
assert response.status_code == 403
def test_admin_home_with_admin_user(client: FlaskClient, login_admin_user):
response = client.get("/admin/")
assert response.status_code == 200