forked from ScoDoc/ScoDoc
reorganized unit tests and fixed bug in cache handling
This commit is contained in:
parent
3876b02626
commit
d30c071c5d
@ -117,7 +117,7 @@ Pour créer un utilisateur "super admin", c'est à dire admin dans tous les dép
|
||||
|
||||
## Tests
|
||||
|
||||
python -m unittest tests.test_users
|
||||
pytest tests/unit/test_users.py
|
||||
|
||||
# TODO
|
||||
|
||||
|
@ -24,36 +24,20 @@ from config import Config
|
||||
from app.scodoc import notesdb as ndb
|
||||
from app.scodoc import sco_cache
|
||||
|
||||
app = Flask(__name__)
|
||||
app.config.from_object(Config)
|
||||
|
||||
db = SQLAlchemy(app)
|
||||
migrate = Migrate(app, db)
|
||||
db = SQLAlchemy()
|
||||
migrate = Migrate()
|
||||
login = LoginManager()
|
||||
login.login_view = "auth.login"
|
||||
login.login_message = "Please log in to access this page."
|
||||
mail = Mail()
|
||||
bootstrap = Bootstrap(app)
|
||||
bootstrap = Bootstrap()
|
||||
moment = Moment()
|
||||
|
||||
cache = Cache(config={"CACHE_TYPE": "MemcachedCache"}) # XXX TODO: configuration file
|
||||
|
||||
|
||||
@app.before_request
|
||||
def open_dept_db_connection():
|
||||
# current_app.logger.info("open_dept_db_connection")
|
||||
if hasattr(g, "scodoc_dept") and not hasattr(g, "db_conn") and g.scodoc_dept:
|
||||
g.db_conn = ndb.open_dept_connection()
|
||||
|
||||
|
||||
@app.teardown_request
|
||||
def close_dept_db_connection():
|
||||
# current_app.logger.info("close_dept_db_connection")
|
||||
if hasattr(g, "db_conn"):
|
||||
ndb.close_dept_connection()
|
||||
|
||||
|
||||
def create_app(config_class=Config):
|
||||
print("create_app")
|
||||
app = Flask(__name__, static_url_path="/ScoDoc/static", static_folder="static")
|
||||
app.logger.setLevel(logging.DEBUG)
|
||||
app.config.from_object(config_class)
|
||||
|
@ -156,7 +156,7 @@ def scodoc7func(context):
|
||||
elif not hasattr(g, "scodoc_dept"):
|
||||
g.scodoc_dept = None
|
||||
# --- Open DB connection
|
||||
app.open_dept_db_connection()
|
||||
app.views.open_dept_db_connection()
|
||||
# --- Emulate Zope's REQUEST
|
||||
REQUEST = ZRequest()
|
||||
g.zrequest = REQUEST
|
||||
@ -227,10 +227,10 @@ class ScoDoc7Context(object):
|
||||
|
||||
def __init__(self, name=""):
|
||||
self.name = name
|
||||
logging.getLogger(__name__).info("created %s" % self)
|
||||
# logging.getLogger(__name__).info("created %s" % self)
|
||||
|
||||
def populate(self, globals_dict):
|
||||
logging.getLogger(__name__).info("populating context %s" % self)
|
||||
# logging.getLogger(__name__).info("populating context %s" % self)
|
||||
for k in globals_dict:
|
||||
if (not k.startswith("_")) and (
|
||||
isinstance(globals_dict[k], types.FunctionType)
|
||||
|
@ -75,7 +75,7 @@ class ScoDocCache:
|
||||
|
||||
@classmethod
|
||||
def _get_key(cls, oid):
|
||||
return g.scodoc_dept + "_" + cls.prefix + oid
|
||||
return g.scodoc_dept + "_" + cls.prefix + "_" + oid
|
||||
|
||||
@classmethod
|
||||
def get(cls, oid):
|
||||
@ -84,16 +84,10 @@ class ScoDocCache:
|
||||
|
||||
@classmethod
|
||||
def set(cls, oid, value):
|
||||
"""Store evaluation"""
|
||||
return CACHE.set(cls._get_key(oid), value, timeout=cls.timeout)
|
||||
|
||||
@classmethod
|
||||
def get_cached(cls, oid):
|
||||
"""get cached object. Clients should use .get()
|
||||
This function is usefull for tests, because get() may be
|
||||
overloaded by subclasses.
|
||||
"""
|
||||
return ScoDocCache.get(oid)
|
||||
"""Store value"""
|
||||
key = cls._get_key(oid)
|
||||
log(f"CACHE key={key}, timeout={cls.timeout}")
|
||||
return CACHE.set(key, value, timeout=cls.timeout)
|
||||
|
||||
@classmethod
|
||||
def delete(cls, oid):
|
||||
@ -103,7 +97,10 @@ class ScoDocCache:
|
||||
@classmethod
|
||||
def delete_many(cls, oids):
|
||||
"""Remove multiple keys at once"""
|
||||
CACHE.delete_many([cls._get_key(oid) for oid in oids])
|
||||
# delete_many seems bugged:
|
||||
# CACHE.delete_many([cls._get_key(oid) for oid in oids])
|
||||
for oid in oids:
|
||||
cls.delete(oid)
|
||||
|
||||
|
||||
class EvaluationCache(ScoDocCache):
|
||||
@ -190,13 +187,13 @@ class NotesTableCache(ScoDocCache):
|
||||
prefix = "NT"
|
||||
|
||||
@classmethod
|
||||
def get(cls, formsemestre_id):
|
||||
def get(cls, formsemestre_id, compute=True):
|
||||
"""Returns NotesTable for this formsemestre
|
||||
If not in cache, build it and cache it.
|
||||
If not in cache and compute is True, build it and cache it.
|
||||
"""
|
||||
key = cls._get_key(formsemestre_id)
|
||||
nt = CACHE.get(key)
|
||||
if nt:
|
||||
if nt or not compute:
|
||||
return nt
|
||||
from app.scodoc import notes_table
|
||||
|
||||
|
@ -8,7 +8,7 @@ import psycopg2
|
||||
import psycopg2.extras
|
||||
|
||||
from flask import current_app
|
||||
from app import app, db
|
||||
from app import db
|
||||
from app.auth.models import User, Role
|
||||
|
||||
|
||||
|
@ -2,6 +2,8 @@
|
||||
"""ScoDoc Flask views
|
||||
"""
|
||||
from flask import Blueprint
|
||||
from flask import g
|
||||
from app.scodoc import notesdb as ndb
|
||||
|
||||
scodoc_bp = Blueprint("scodoc", __name__)
|
||||
scolar_bp = Blueprint("scolar", __name__)
|
||||
@ -10,6 +12,19 @@ users_bp = Blueprint("users", __name__)
|
||||
absences_bp = Blueprint("absences", __name__)
|
||||
essais_bp = Blueprint("essais", __name__)
|
||||
|
||||
from app.views import scodoc, notes, scolar, absences, users, essais
|
||||
|
||||
scolar.context.Notes = notes.context # XXX transitoire #sco8
|
||||
@scodoc_bp.before_app_request
|
||||
def open_dept_db_connection():
|
||||
# current_app.logger.info("open_dept_db_connection")
|
||||
if hasattr(g, "scodoc_dept") and not hasattr(g, "db_conn") and g.scodoc_dept:
|
||||
g.db_conn = ndb.open_dept_connection()
|
||||
|
||||
|
||||
@scodoc_bp.teardown_app_request
|
||||
def close_dept_db_connection(arg):
|
||||
# current_app.logger.info("close_dept_db_connection")
|
||||
if hasattr(g, "db_conn"):
|
||||
ndb.close_dept_connection()
|
||||
|
||||
|
||||
from app.views import scodoc, notes, scolar, absences, users, essais
|
||||
|
12
config.py
12
config.py
@ -7,7 +7,7 @@ BASEDIR = os.path.abspath(os.path.dirname(__file__))
|
||||
load_dotenv(os.path.join(BASEDIR, ".env"))
|
||||
|
||||
|
||||
class ConfigClass(object):
|
||||
class Config:
|
||||
"""General configuration. Mostly loaded from environment via .env"""
|
||||
|
||||
SECRET_KEY = os.environ.get("SECRET_KEY") or "un-grand-secret-introuvable"
|
||||
@ -30,6 +30,9 @@ class ConfigClass(object):
|
||||
BOOTSTRAP_SERVE_LOCAL = os.environ.get("BOOTSTRAP_SERVE_LOCAL")
|
||||
# for ScoDoc 7 compat (à changer)
|
||||
INSTANCE_HOME = os.environ.get("INSTANCE_HOME", "/opt/scodoc")
|
||||
SCODOC_VAR_DIR = os.path.join(
|
||||
os.environ.get("INSTANCE_HOME", "/opt/scodoc"), "var", "scodoc"
|
||||
)
|
||||
|
||||
# For legacy ScoDoc7 installs: postgresql user
|
||||
SCODOC7_SQL_USER = os.environ.get("SCODOC7_SQL_USER", "www-data")
|
||||
@ -37,10 +40,3 @@ class ConfigClass(object):
|
||||
# STATIC_URL_PATH = "/ScoDoc/static"
|
||||
# static_folder = "stat"
|
||||
# SERVER_NAME = os.environ.get("SERVER_NAME")
|
||||
|
||||
def __init__(self):
|
||||
"""Used to build some config variable at startup time"""
|
||||
self.SCODOC_VAR_DIR = os.path.join(self.INSTANCE_HOME, "var", "scodoc")
|
||||
|
||||
|
||||
Config = ConfigClass()
|
||||
|
@ -1,2 +1,2 @@
|
||||
#
|
||||
import tests.test_users
|
||||
import tests.unit.test_users
|
||||
|
@ -1,20 +1,29 @@
|
||||
import pytest
|
||||
|
||||
from app import app, db
|
||||
from flask import g
|
||||
|
||||
import app as myapp
|
||||
from app import db, create_app
|
||||
from app.auth.models import User, Role, Permission
|
||||
from app.scodoc import sco_bulletins_standard
|
||||
from app.scodoc import notesdb as ndb
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@pytest.fixture()
|
||||
def test_client():
|
||||
# Setup
|
||||
app.config["TESTING"] = True
|
||||
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite://"
|
||||
myapp.Config.TESTING = True
|
||||
myapp.Config.SQLALCHEMY_DATABASE_URI = "sqlite://"
|
||||
apptest = create_app()
|
||||
# Run tests:
|
||||
with app.test_client() as client:
|
||||
with app.app_context():
|
||||
with apptest.test_client() as client:
|
||||
with apptest.app_context():
|
||||
db.create_all()
|
||||
Role.insert_roles()
|
||||
g.scodoc_dept = "RT"
|
||||
g.db_conn = ndb.open_dept_connection()
|
||||
yield client
|
||||
# Teardown:
|
||||
db.session.remove()
|
||||
db.drop_all()
|
||||
ndb.close_dept_connection()
|
||||
# Teardown:
|
||||
db.session.remove()
|
||||
db.drop_all()
|
||||
|
@ -4,14 +4,14 @@
|
||||
|
||||
Ré-écriture de test_users avec pytest.
|
||||
|
||||
Usage:
|
||||
Usage: pytest tests/unit/test_users.py
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from tests.conftest import test_client
|
||||
from flask import current_app
|
||||
|
||||
from app import app, db
|
||||
from app import db
|
||||
from app.auth.models import User, Role, Permission
|
||||
from app.scodoc.sco_roles_default import SCO_ROLES_DEFAULTS
|
||||
|
||||
@ -19,10 +19,6 @@ from app.scodoc.sco_roles_default import SCO_ROLES_DEFAULTS
|
||||
DEPT = "XX"
|
||||
|
||||
|
||||
def test_test(test_client):
|
||||
assert 1 == 1
|
||||
|
||||
|
||||
def test_password_hashing(test_client):
|
||||
u = User(user_name="susan")
|
||||
db.session.add(u)
|
||||
|
Loading…
Reference in New Issue
Block a user