From a013bb51feacd4823feb8956a5b1a93935acd436 Mon Sep 17 00:00:00 2001 From: David Beniamine <david.beniamine@tetras-libre.fr> Date: Wed, 15 Feb 2023 23:44:40 +0100 Subject: [PATCH] Working test with fixtures --- Mirador_backend/app.py | 8 ++++-- Mirador_backend/models.py | 15 +++++++--- .../tests/test_mirador_resource.py | 12 ++++++-- Mirador_backend/tests/tester.py | 14 ++++++++-- Mirador_backend/utils/app.py | 9 ++++++ Mirador_backend/utils/config.py | 12 +++----- Mirador_backend/utils/database.py | 28 +++++++++---------- cli | 2 +- 8 files changed, 65 insertions(+), 35 deletions(-) create mode 100644 Mirador_backend/utils/app.py diff --git a/Mirador_backend/app.py b/Mirador_backend/app.py index 5c652c5..9ac4c93 100644 --- a/Mirador_backend/app.py +++ b/Mirador_backend/app.py @@ -6,20 +6,22 @@ from flask_apispec.extension import FlaskApiSpec from Mirador_backend.routes import v1 from Mirador_backend.utils.config import ConfigFactory from Mirador_backend.utils.database import db +from Mirador_backend.utils.app import setApp app = Flask(__name__) +setApp(app) api = Api(app) docs = FlaskApiSpec(app) -app.config.from_object(ConfigFactory.getConfig()) -app.db = db +app.config.from_object(ConfigFactory()) +app.db = db(app.config['DB'], app.config['DEBUG']) v1.register_routes(api, docs) @app.teardown_appcontext def shutdown_session(exception=None): - db.close() + app.db.close() if __name__ == '__main__': diff --git a/Mirador_backend/models.py b/Mirador_backend/models.py index 5847f07..c35529c 100644 --- a/Mirador_backend/models.py +++ b/Mirador_backend/models.py @@ -5,7 +5,7 @@ from sqlalchemy import Integer, JSON from sqlalchemy import select from sqlalchemy.exc import NoResultFound import json -from Mirador_backend.utils.database import db +from Mirador_backend.utils.app import getApp class NotFound(NoResultFound): @@ -16,7 +16,10 @@ class BaseModel(DeclarativeBase): """A generic model class """ - session = db.db_session + session = getApp().db.session + """Access the db session""" + + engine = getApp().db.engine """Access the db session""" fillable = [] @@ -30,9 +33,13 @@ class BaseModel(DeclarativeBase): } """Actual data fields""" - def create_tables(): + def create_all(): """Creates all tables for all models""" - BaseModel.metadata.create_all(db.engine) + BaseModel.metadata.create_all(getApp().db.engine) + + def drop_all(): + """drop all tables for all models""" + BaseModel.metadata.drop_all(getApp().db.engine) @classmethod def query(cls, stmt): diff --git a/Mirador_backend/tests/test_mirador_resource.py b/Mirador_backend/tests/test_mirador_resource.py index 37da0e2..a0a0558 100644 --- a/Mirador_backend/tests/test_mirador_resource.py +++ b/Mirador_backend/tests/test_mirador_resource.py @@ -4,15 +4,21 @@ from Mirador_backend.tests.tester import TestCase class MiradorResourceTest(TestCase): + def getData(self): + return self.getFixtureRecordsByModel(self.fixtures[0], 'Mirador_backend.models.MiradorResource') + def testGetOne(self): + id = 1 payload = json.dumps({}) - response = self.client.get(self.base + '/1', headers={"Content-Type": "application/json"}, data=payload) + response = self.client.get(f'{self.base}/{id}', headers={"Content-Type": "application/json"}, data=payload) self.assertEqual(200, response.status_code) - self.assertEqual(None, response.json) + + expected = next(x for x in self.getData() if x['id'] == id) + self.assertEqual(expected, response.json) def testGetAll(self): payload = json.dumps({}) response = self.client.get(self.base, headers={"Content-Type": "application/json"}, data=payload) self.assertEqual(200, response.status_code) - self.assertEqual([], response.json) + self.assertEqual({str(x['id']): x for x in self.getData()}, response.json) diff --git a/Mirador_backend/tests/tester.py b/Mirador_backend/tests/tester.py index b1aae8b..57a9bff 100644 --- a/Mirador_backend/tests/tester.py +++ b/Mirador_backend/tests/tester.py @@ -1,18 +1,28 @@ import unittest +import json +from os.path import dirname, abspath +from flask_fixtures import FixturesMixin from Mirador_backend.app import app -from flask_fixtures import FixturesMixin +from Mirador_backend.models import BaseModel class TestCase(unittest.TestCase, FixturesMixin): fixtures = ['test.json'] app = app - db = app.db + db = BaseModel def setUp(self): self.base = 'v1/mirador_resource' self.client = app.test_client() + def getFixture(self, name): + with open(f'{dirname(abspath(__file__))}/fixtures/{name}') as f: + return json.load(f) + + def getFixtureRecordsByModel(self, name, model): + return next(x['records'] for x in self.getFixture(name) if x['model'] == model) + def tearDown(self): # TODO pass diff --git a/Mirador_backend/utils/app.py b/Mirador_backend/utils/app.py new file mode 100644 index 0000000..71f6b56 --- /dev/null +++ b/Mirador_backend/utils/app.py @@ -0,0 +1,9 @@ +def getApp(): + return getApp.app + + +getApp.app = None + + +def setApp(app): + getApp.app = app diff --git a/Mirador_backend/utils/config.py b/Mirador_backend/utils/config.py index a7f9976..002af56 100644 --- a/Mirador_backend/utils/config.py +++ b/Mirador_backend/utils/config.py @@ -14,7 +14,7 @@ class Config(object): APISPEC_SWAGGER_UI_URL = '/swagger-ui/' # URI to access UI of API Doc ENV = getenv('ENV', 'dev') TESTING = False - DEBUG = False + DEBUG = getenv('ENV', 'dev') != 'prod' DB = { 'TYPE': getenv('DB_TYPE', 'mariadb+mariadbconnector'), 'USER': getenv('MYSQL_USER', 'user'), @@ -26,14 +26,10 @@ class Config(object): class TestingConfig(Config): TESTING = True + DEBUG = True DB = None FIXTURES_DIRS = ['tests/fixtures'] -class ConfigFactory(): - config = None - - def getConfig(): - if ConfigFactory.config is None: - ConfigFactory.config = TestingConfig() if getenv('ENV', 'dev') == 'test' else Config() - return ConfigFactory.config +def ConfigFactory(): + return TestingConfig if getenv('ENV', 'dev') == 'test' else Config diff --git a/Mirador_backend/utils/database.py b/Mirador_backend/utils/database.py index 20bbc19..8d35a0d 100644 --- a/Mirador_backend/utils/database.py +++ b/Mirador_backend/utils/database.py @@ -1,20 +1,20 @@ from sqlalchemy import create_engine from sqlalchemy.orm import scoped_session, sessionmaker -from Mirador_backend.utils.config import ConfigFactory - - -def getDBUri(): - params = ConfigFactory.getConfig().DB - if params is None: - return 'sqlite://' - return f'{params["TYPE"]}://{params["USER"]}:{params["PASSWORD"]}@{params["HOST"]}/{params["BASE"]}' class db(): - engine = create_engine(getDBUri(), echo=ConfigFactory.getConfig().DEBUG) - db_session = scoped_session(sessionmaker(autocommit=False, - autoflush=False, - bind=engine)) + def __getDBUri(self): + params = self.config + if params is None: + return 'sqlite://' + return f'{params["TYPE"]}://{params["USER"]}:{params["PASSWORD"]}@{params["HOST"]}/{params["BASE"]}' + + def __init__(self, config, debug): + self.config = config + self.engine = create_engine(self.__getDBUri(), echo=debug) + self.session = scoped_session(sessionmaker(autocommit=False, + autoflush=False, + bind=self.engine)) - def close(): - db.db_session.remove() + def close(self): + self.session.remove() diff --git a/cli b/cli index 60329d4..d40535c 100755 --- a/cli +++ b/cli @@ -69,7 +69,7 @@ case $action in set +x ;; "mysql_init") - $cmd python -c 'from Mirador_backend.models import BaseModel; BaseModel.create_tables()' + $cmd python -c 'from Mirador_backend.models import BaseModel; BaseModel.create_all()' ;; "shell") $cmd ipython -- GitLab