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/
__pycache__/
venv/
test.db

View File

@ -68,9 +68,6 @@ def query_questions():
"multiple_choice": getattr(question, "multiple_choice", 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)

View File

@ -29,3 +29,11 @@ class Development(Config):
DEBUG = True
TESTING = True
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
from typing import Union, Optional, Literal, Type, List, Tuple
import random
from sqlalchemy import Column, JSON, String, Integer, create_engine, ForeignKey, func, ARRAY, Boolean, UnicodeText, \
DateTime
from sqlalchemy import Column, JSON, String, Integer, create_engine, ForeignKey, func, Boolean, UnicodeText, DateTime
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.orm import sessionmaker, relationship, scoped_session
@ -31,6 +30,11 @@ def init_db():
Base.metadata.create_all(engine)
def destroy_db():
engine = create_engine(current_app.config["DB_URL"])
Base.metadata.drop_all(engine)
Base = declarative_base()
@ -134,7 +138,7 @@ class MultipleChoice(Base):
question_id = Column(Integer, ForeignKey("all_questions.question_id"), primary_key=True)
multiple_choice_difficulty = Column(Integer)
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")
question_text = association_proxy("all_question_relationship", "question_text")

View File

@ -10,3 +10,4 @@ scramp==1.2.0
SQLAlchemy==1.3.23
Werkzeug==1.0.1
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