diff --git a/test/fixtures.py b/test/fixtures.py index 37c6f1441..7477713b7 100644 --- a/test/fixtures.py +++ b/test/fixtures.py @@ -8,18 +8,87 @@ from peewee import SqliteDatabase from app import app as application from data import model -from data.database import (close_db_filter, db) +from data.database import close_db_filter, db, configure from data.model.user import LoginWrappedDBUser from endpoints.api import api_bp from endpoints.web import web from initdb import initialize_database, populate_database from path_converters import APIRepositoryPathConverter, RegexConverter, RepositoryPathConverter +from test.testconfig import FakeTransaction + + +@pytest.fixture(scope="session") +def init_db_path(tmpdir_factory): + """ Creates a new database and appropriate configuration. Note that the initial database + is created *once* per session. In the non-full-db-test case, the database_uri fixture + makes a copy of the SQLite database file on disk and passes a new copy to each test. + """ + sqlitedb_file = str(tmpdir_factory.mktemp("data").join("test.db")) + sqlitedb = 'sqlite:///{0}'.format(sqlitedb_file) + conf = {"TESTING": True, + "DEBUG": True, + "DB_URI": sqlitedb} + os.environ['TEST_DATABASE_URI'] = str(sqlitedb) + os.environ['DB_URI'] = str(sqlitedb) + db.initialize(SqliteDatabase(sqlitedb_file)) + application.config.update(conf) + application.config.update({"DB_URI": sqlitedb}) + initialize_database() + populate_database() + close_db_filter(None) + return str(sqlitedb_file) @pytest.fixture() -def app(appconfig): - """ Used by pytest-flask plugin to inject app by test for client See test_security by name injection of client. """ +def database_uri(monkeypatch, init_db_path, sqlitedb_file): + """ Returns the database URI to use for testing. In the SQLite case, a new, distinct copy of + the SQLite database is created by copying the initialized database file (sqlitedb_file) + on a per-test basis. In the non-SQLite case, a reference to the existing database URI is + returned. + """ + # Copy the golden database file to a new path. + shutil.copy2(init_db_path, sqlitedb_file) + + # Monkeypatch the DB_URI. + db_path = 'sqlite:///{0}'.format(sqlitedb_file) + monkeypatch.setenv("DB_URI", db_path) + return db_path + + +@pytest.fixture() +def sqlitedb_file(tmpdir): + """ Returns the path at which the initialized, golden SQLite database file will be placed. """ + test_db_file = tmpdir.mkdir("quaydb").join("test.db") + return str(test_db_file) + +def _create_transaction(db): + return FakeTransaction() + +@pytest.fixture() +def appconfig(database_uri): + """ Returns application configuration for testing that references the proper database URI. """ + conf = { + "TESTING": True, + "DEBUG": True, + "DB_URI": database_uri, + "SECRET_KEY": 'superdupersecret!!!1', + "DB_CONNECTION_ARGS": { + 'threadlocals': True, + 'autorollback': True, + }, + "DB_TRANSACTION_FACTORY": _create_transaction, + } + return conf + +@pytest.fixture() +def initialized_db(appconfig): + """ Configures the database for the database found in the appconfig. """ + configure(appconfig) + +@pytest.fixture() +def app(appconfig, initialized_db): + """ Used by pytest-flask plugin to inject a custom app instance for testing. """ app = Flask(__name__) login_manager = LoginManager(app) @@ -40,51 +109,3 @@ def app(appconfig): app.register_blueprint(web, url_prefix='/') app.config.update(appconfig) return app - - -@pytest.fixture(scope="session") -def init_db_path(tmpdir_factory): - """ Creates a new db and appropriate configuration. Used for parameter by name injection. """ - sqlitedb_file = str(tmpdir_factory.mktemp("data").join("test.db")) - sqlitedb = 'sqlite:///{0}'.format(sqlitedb_file) - conf = {"TESTING": True, - "DEBUG": True, - "DB_URI": sqlitedb} - os.environ['TEST_DATABASE_URI'] = str(sqlitedb) - os.environ['DB_URI'] = str(sqlitedb) - db.initialize(SqliteDatabase(sqlitedb_file)) - application.config.update(conf) - application.config.update({"DB_URI": sqlitedb}) - initialize_database() - populate_database() - close_db_filter(None) - return str(sqlitedb_file) - - -@pytest.fixture() -def database_uri(monkeypatch, init_db_path, sqlitedb_file): - """ Creates the db uri. Used for parameter by name injection. """ - shutil.copy2(init_db_path, sqlitedb_file) - db.initialize(SqliteDatabase(sqlitedb_file)) - db_path = 'sqlite:///{0}'.format(sqlitedb_file) - monkeypatch.setenv("DB_URI", db_path) - return db_path - - -@pytest.fixture() -def sqlitedb_file(tmpdir): - """ Makes file for db. Used for parameter by name injection. """ - test_db_file = tmpdir.mkdir("quaydb").join("test.db") - return str(test_db_file) - - -@pytest.fixture() -def appconfig(database_uri): - """ Makes conf with database_uri. Used for parameter by name injection """ - conf = { - "TESTING": True, - "DEBUG": True, - "DB_URI": database_uri, - "SECRET_KEY": 'superdupersecret!!!1', - } - return conf