fix: prompt for continuum support in app installer
unless installer declares static preference, then do not prompt. also, do not prompt if continuum packages are missing.
This commit is contained in:
parent
d018d4e764
commit
dd56fbcc2d
3 changed files with 255 additions and 95 deletions
|
|
@ -64,25 +64,119 @@ class TestInstallHandler(ConfigTestCase):
|
|||
|
||||
def test_do_install_steps(self):
|
||||
handler = self.make_handler()
|
||||
handler.templates = TemplateLookup(
|
||||
directories=[
|
||||
self.app.resource_path("wuttjamaican:templates/install"),
|
||||
]
|
||||
)
|
||||
dbinfo = {
|
||||
"dburl": f"sqlite:///{self.tempdir}/poser.sqlite",
|
||||
}
|
||||
db_url = f"sqlite:///{self.tempdir}/poser.sqlite"
|
||||
|
||||
with patch.object(handler, "get_dbinfo", return_value=dbinfo):
|
||||
with patch.object(handler, "prompt_user_for_context") as prompt_user:
|
||||
prompt_user.return_value = {"db_url": db_url, "wants_continuum": False}
|
||||
with patch.object(handler, "make_appdir") as make_appdir:
|
||||
with patch.object(handler, "install_db_schema") as install_db_schema:
|
||||
with patch.object(handler, "install_db_schema") as install_schema:
|
||||
|
||||
# nb. just for sanity/coverage
|
||||
install_db_schema.return_value = True
|
||||
self.assertFalse(handler.schema_installed)
|
||||
install_schema.return_value = True
|
||||
handler.do_install_steps()
|
||||
self.assertTrue(make_appdir.called)
|
||||
prompt_user.assert_called_once()
|
||||
make_appdir.assert_called_once()
|
||||
install_schema.assert_called_once_with(db_url)
|
||||
self.assertTrue(handler.schema_installed)
|
||||
install_db_schema.assert_called_once_with(dbinfo["dburl"])
|
||||
|
||||
def test_prompt_user_for_context(self):
|
||||
db_url = f"sqlite:///{self.tempdir}/poser.sqlite"
|
||||
with patch.object(mod.InstallHandler, "get_db_url", return_value=db_url):
|
||||
|
||||
# should prompt for continuum by default
|
||||
handler = self.make_handler()
|
||||
with patch.object(handler, "prompt_bool") as prompt_bool:
|
||||
prompt_bool.return_value = True
|
||||
context = handler.prompt_user_for_context()
|
||||
prompt_bool.assert_called_once_with(
|
||||
"use continuum for data versioning?", default=False
|
||||
)
|
||||
self.assertEqual(context, {"db_url": db_url, "wants_continuum": True})
|
||||
|
||||
# should not prompt if continuum flag already true
|
||||
handler = self.make_handler()
|
||||
with patch.object(handler, "wants_continuum", new=True):
|
||||
with patch.object(handler, "prompt_bool") as prompt_bool:
|
||||
context = handler.prompt_user_for_context()
|
||||
prompt_bool.assert_not_called()
|
||||
self.assertEqual(
|
||||
context, {"db_url": db_url, "wants_continuum": True}
|
||||
)
|
||||
|
||||
# should not prompt if continuum flag already false
|
||||
handler = self.make_handler()
|
||||
with patch.object(handler, "wants_continuum", new=False):
|
||||
with patch.object(handler, "prompt_bool") as prompt_bool:
|
||||
context = handler.prompt_user_for_context()
|
||||
prompt_bool.assert_not_called()
|
||||
self.assertEqual(
|
||||
context, {"db_url": db_url, "wants_continuum": False}
|
||||
)
|
||||
|
||||
# should not prompt if continuum pkg missing...
|
||||
handler = self.make_handler()
|
||||
with patch("builtins.__import__", side_effect=ImportError):
|
||||
with patch.object(handler, "prompt_bool") as prompt_bool:
|
||||
context = handler.prompt_user_for_context()
|
||||
prompt_bool.assert_not_called()
|
||||
self.assertEqual(
|
||||
context, {"db_url": db_url, "wants_continuum": False}
|
||||
)
|
||||
|
||||
def test_get_db_url(self):
|
||||
try:
|
||||
import sqlalchemy
|
||||
from wuttjamaican.db.util import SA2
|
||||
except ImportError:
|
||||
pytest.skip("test is not relevant without sqlalchemy")
|
||||
|
||||
handler = self.make_handler()
|
||||
|
||||
# url from dbinfo is returned, if present
|
||||
dbinfo = {"db_url": "sqlite:///"}
|
||||
with patch.object(handler, "get_dbinfo", return_value=dbinfo):
|
||||
db_url = handler.get_db_url()
|
||||
self.assertEqual(db_url, "sqlite:///")
|
||||
|
||||
# or url will be assembled from dbinfo parts
|
||||
dbinfo = {
|
||||
"dbtype": "postgresql",
|
||||
"dbhost": "localhost",
|
||||
"dbport": 5432,
|
||||
"dbname": "poser",
|
||||
"dbuser": "poser",
|
||||
"dbpass": "seekrit",
|
||||
}
|
||||
with patch.object(handler, "get_dbinfo", return_value=dbinfo):
|
||||
with patch.object(handler, "test_db_connection", return_value=None):
|
||||
db_url = handler.get_db_url()
|
||||
seekrit = "***" if SA2 else "seekrit"
|
||||
self.assertEqual(
|
||||
str(db_url),
|
||||
f"postgresql+psycopg2://poser:{seekrit}@localhost:5432/poser",
|
||||
)
|
||||
|
||||
# now we test the "test db connection" feature
|
||||
dbinfo = {"db_url": "sqlite:///"}
|
||||
with patch.object(handler, "get_dbinfo", return_value=dbinfo):
|
||||
with patch.object(handler, "test_db_connection") as test_db_connection:
|
||||
with patch.object(handler, "rprint") as rprint:
|
||||
with patch.object(mod, "sys") as sys:
|
||||
|
||||
# pretend user gave bad dbinfo; should exit
|
||||
test_db_connection.return_value = "bad dbinfo"
|
||||
sys.exit.side_effect = RuntimeError
|
||||
self.assertRaises(RuntimeError, handler.get_db_url)
|
||||
sys.exit.assert_called_once_with(1)
|
||||
|
||||
# pretend user gave good dbinfo
|
||||
sys.exit.reset_mock()
|
||||
test_db_connection.return_value = None
|
||||
db_url = handler.get_db_url()
|
||||
self.assertFalse(sys.exit.called)
|
||||
rprint.assert_called_with("[bold green]good[/bold green]")
|
||||
self.assertEqual(str(db_url), "sqlite:///")
|
||||
|
||||
def test_get_dbinfo(self):
|
||||
try:
|
||||
|
|
@ -101,28 +195,20 @@ class TestInstallHandler(ConfigTestCase):
|
|||
return "seekrit"
|
||||
return default
|
||||
|
||||
with patch.object(mod, "sys") as sys:
|
||||
with patch.object(handler, "prompt_generic", side_effect=prompt_generic):
|
||||
with patch.object(handler, "test_db_connection") as test_db_connection:
|
||||
with patch.object(handler, "rprint") as rprint:
|
||||
# bad dbinfo
|
||||
test_db_connection.return_value = "bad dbinfo"
|
||||
sys.exit.side_effect = RuntimeError
|
||||
self.assertRaises(RuntimeError, handler.get_dbinfo)
|
||||
sys.exit.assert_called_once_with(1)
|
||||
with patch.object(handler, "prompt_generic", side_effect=prompt_generic):
|
||||
|
||||
seekrit = "***" if SA2 else "seekrit"
|
||||
|
||||
# good dbinfo
|
||||
sys.exit.reset_mock()
|
||||
test_db_connection.return_value = None
|
||||
dbinfo = handler.get_dbinfo()
|
||||
self.assertFalse(sys.exit.called)
|
||||
rprint.assert_called_with("[bold green]good[/bold green]")
|
||||
self.assertEqual(
|
||||
str(dbinfo["dburl"]),
|
||||
f"postgresql+psycopg2://poser:{seekrit}@localhost:5432/poser",
|
||||
)
|
||||
dbinfo = handler.get_dbinfo()
|
||||
self.assertEqual(
|
||||
dbinfo,
|
||||
{
|
||||
"dbtype": "postgresql",
|
||||
"dbhost": "localhost",
|
||||
"dbport": "5432",
|
||||
"dbname": "poser",
|
||||
"dbuser": "poser",
|
||||
"dbpass": "seekrit",
|
||||
},
|
||||
)
|
||||
|
||||
def test_make_db_url(self):
|
||||
try:
|
||||
|
|
@ -136,14 +222,28 @@ class TestInstallHandler(ConfigTestCase):
|
|||
seekrit = "***" if SA2 else "seekrit"
|
||||
|
||||
url = handler.make_db_url(
|
||||
"postgresql", "localhost", "5432", "poser", "poser", "seekrit"
|
||||
dict(
|
||||
dbtype="postgresql",
|
||||
dbhost="localhost",
|
||||
dbport="5432",
|
||||
dbname="poser",
|
||||
dbuser="poser",
|
||||
dbpass="seekrit",
|
||||
)
|
||||
)
|
||||
self.assertEqual(
|
||||
str(url), f"postgresql+psycopg2://poser:{seekrit}@localhost:5432/poser"
|
||||
)
|
||||
|
||||
url = handler.make_db_url(
|
||||
"mysql", "localhost", "3306", "poser", "poser", "seekrit"
|
||||
dict(
|
||||
dbtype="mysql",
|
||||
dbhost="localhost",
|
||||
dbport="3306",
|
||||
dbname="poser",
|
||||
dbuser="poser",
|
||||
dbpass="seekrit",
|
||||
)
|
||||
)
|
||||
self.assertEqual(
|
||||
str(url), f"mysql+mysqlconnector://poser:{seekrit}@localhost:3306/poser"
|
||||
|
|
@ -172,8 +272,8 @@ class TestInstallHandler(ConfigTestCase):
|
|||
handler = self.make_handler()
|
||||
|
||||
# can handle dburl as string
|
||||
dbinfo = {"dburl": "sqlite:///poser.sqlite"}
|
||||
context = handler.make_template_context(dbinfo)
|
||||
db_url = "sqlite:///poser.sqlite"
|
||||
context = handler.make_template_context(db_url=db_url)
|
||||
self.assertEqual(context["envdir"], sys.prefix)
|
||||
self.assertEqual(context["pkg_name"], "poser")
|
||||
self.assertEqual(context["app_title"], "poser")
|
||||
|
|
@ -188,8 +288,8 @@ class TestInstallHandler(ConfigTestCase):
|
|||
pytest.skip("remainder of test is not relevant without sqlalchemy")
|
||||
|
||||
# but also can handle dburl as object
|
||||
dbinfo = {"dburl": sa.create_engine("sqlite:///poser.sqlite").url}
|
||||
context = handler.make_template_context(dbinfo)
|
||||
db_url = sa.create_engine("sqlite:///poser.sqlite").url
|
||||
context = handler.make_template_context(db_url=db_url)
|
||||
self.assertEqual(context["envdir"], sys.prefix)
|
||||
self.assertEqual(context["pkg_name"], "poser")
|
||||
self.assertEqual(context["app_title"], "poser")
|
||||
|
|
@ -205,8 +305,8 @@ class TestInstallHandler(ConfigTestCase):
|
|||
self.app.resource_path("wuttjamaican:templates/install"),
|
||||
]
|
||||
)
|
||||
dbinfo = {"dburl": "sqlite:///poser.sqlite"}
|
||||
context = handler.make_template_context(dbinfo)
|
||||
db_url = "sqlite:///poser.sqlite"
|
||||
context = handler.make_template_context(db_url=db_url)
|
||||
handler.make_appdir(context, appdir=self.tempdir)
|
||||
wutta_conf = os.path.join(self.tempdir, "wutta.conf")
|
||||
with open(wutta_conf, "rt") as f:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue