From 55bb589f6114fa33729198e508f939d00c52b406 Mon Sep 17 00:00:00 2001 From: Disco DeDisco Date: Tue, 3 Feb 2026 14:54:37 -0500 Subject: [PATCH] added functional_tests to installed apps in core.settings (but only when debug is true); created management dir to contain new django cmds & listed in .dockerignore; created management.create_session cmd; recreated container.db.sqlite3; tweaked test_server setup in functional_tests.base; added test_server failsafe to magic link login testing in .test_login --- .dockerignore | 1 + container.db.sqlite3 | Bin 135168 -> 106496 bytes infra/deploy-playbook.yaml | 3 ++- src/core/settings.py | 7 ++++-- src/functional_tests/base.py | 5 ++-- src/functional_tests/management/__init__.py | 0 .../management/commands/__init__.py | 0 .../management/commands/create_session.py | 23 ++++++++++++++++++ src/functional_tests/test_login.py | 3 +++ 9 files changed, 37 insertions(+), 5 deletions(-) create mode 100644 src/functional_tests/management/__init__.py create mode 100644 src/functional_tests/management/commands/__init__.py create mode 100644 src/functional_tests/management/commands/create_session.py diff --git a/.dockerignore b/.dockerignore index ea2e09c..2e27272 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1 +1,2 @@ src/db.sqlite3 +src/functional_tests/management diff --git a/container.db.sqlite3 b/container.db.sqlite3 index 0c342b74c4dcef7cc3872fa9464e795072df6953..226a71f51f3bc7014cd62e158ae9cf467b9d12ac 100644 GIT binary patch delta 3773 zcmai1YiuLc6`tc6Kk}Hlc{$F;aXgNbc1qCh3sT@kI?RZEemgjy<~+EQBh0ThrxeNZ6~>W{Xd-WksZ zuSL67d^6{K=Y03O=RW58+#{}Y&pGb*wuT6T=*Hh`pOFU+gt2pYd);ohT1w!ol7715SPhUMC39=Ba#Csz3fEboIzViK^;r2RJLNq2; zuJ#D^3A`u>T&2@juU3jh1(~ZPd}3XO6pf0aT=|JFRu9OM#EF$pd?WQhL<~nF6}gwI z2gF!Jebz-g$v}g- zY7@pK6#{*X-a@~^O1_CU(F(e-Tb@Td4CQfy zslkxoLX^i-HOfggYtQysG1!Xt^ZUHH4ubUK37t6rP9`# zTC8~{+bMUzkXm{Fw%*%W`f&p3=o_erQs@KpD*7dQ0?i^3c@f2Y%)H6G!2FbXf_aF! zmnkqQ<_L2eGeW;X|Cat4{W!xi4E-Pa16*8sr-gz5I5#!*Om(xfZ4?ZEGp%OSl64&T ztFF{4E~4e?MHKkKsif1@ET3t+Od6voJ*^Z3!DX=+9&goSkrk9mJe>vyI1CEIbej}*lftNShnZlvC=5?~)nid;r5!cfW^&jK z4kMz~94%#XSo6}-K|u&8i^g)Is?%b!oQz3N8C;f!?xbJ{NRzH+Hk-RB;DJmZs@Ay% zX{sU?Zw=7sreF|AgS*CCNzOmo;X=y<`Ut&=o;I8$QAnNIo>`X%}?`W&66$7q(eHNW5deDkBt z=bKlXCz|`49Zi2}dcNtArgOXHXwyzFYbPKOs@VkNN{%&Vj5Vv&=g0WK&~CZ&M@$+98);- zwF}@Lz^`en{qwE0C(c+QY`d9f*Pk@<+AQNGYy?|PlD*w^O^1=y*MhNuAxdw&2tFsm zMu?~M;foM(GM2Gu7&JD5gOvXDi17Sd=YMPHd@AKhS7kH zL5b8yEoVLCxXJc7T6*t1EHCaub z3KxatvswVS1Z8d$gFD+*+KQ8k;y>nm#@&&2Jx> zo0=M1T9}yM%q)(5H8ZubF}5~w$M&&P)5qgnaVwg*gBx9)p3$P4+Zw+!wY8AnnEA@$ z;nTV4@yNo`_Uy6o?fKEE_1xlUarDkbapT0wL4Gqg8{rQowlZp3Ngd7~J99X@kT^56 zw6roS9gdGK4IK?1O-|+~#0^4h(Lm(43*?4TqMM+6}z@Wwk0&>IB)!=KCU zlfOe;keqF}Q2}TiZA14F_;9&zw|qC+k!_?jo7V7#&nme?>RBbbmQjbXC5NMYN{K0Q zQcQ~~w&b)FPA*IMzLSciWAd#)j?XG-C7UWJ+RCbu)iR}g?$AnB(K1FpCx=CaR|I@( zi;2lp5`WU_vMg~bFGXchGL!(K-X_r7_}=>`bf6a#690$L7_tpr!9zw@aK=;USU))n zHHs&XSO)oQ*&pm#9wYbex9jyK#u37~fg^ezs69WDCE(T4v$RW$sQ=pr-%^)s(9 z4*KS%zcqf^IN$J~>y+~$$3GlPj(+=-)U%X8p0`Qxne9W{FMxob6WRl1o-B6^=r3g9 z7TBjda&Q8IdLjq=pguoJ{k-A z1xXCCbMwd9xrLdT18g7usnOS9oSKFGVIic$B)G{?xK9tIpvTf>9AVdF8P8qiwt&+U z2tYYsqsl<4T^moGU!=(ZZX}6an43JZ5XZ{2wEoyhIM5U-4|Y2}i4c^(roXH}kA5}} zEVSvr*TAh`%EM8z?AoXQT7ek2evpJYvV5vbUpk4WpjFQ)xbC+k!KKHifY<+U64t?^ z#}y1Z4RGET?l6WbP%Y)wcKv)3GdJnJDV+6e5>Ali{xz^k@1Mqs8&`qR;}g)UmsRM{&rHCb zWOy L@rq*({ssR9$s+$s delta 4652 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 diff --git a/infra/deploy-playbook.yaml b/infra/deploy-playbook.yaml index 3181d81..366a56a 100644 --- a/infra/deploy-playbook.yaml +++ b/infra/deploy-playbook.yaml @@ -78,8 +78,9 @@ env: DJANGO_DEBUG_FALSE: "1" DJANGO_SECRET_KEY: "{{ secret_key.content | b64decode }}" - DJANGO_ALLOWED_HOST: "staging.earthmanrpg.me,www.earthmanrpg.me,dashboard.earthmanrpg.me,earthmanrpg.me,104.131.184.0,localhost" + DJANGO_ALLOWED_HOST: "localhost,staging.earthmanrpg.me,www.earthmanrpg.me,dashboard.earthmanrpg.me,earthmanrpg.me,104.131.184.0" DJANGO_DB_PATH: "/home/nonroot/db.sqlite3" + EMAIL_HOST_PASSWORD: "{{ lookup('env', 'EMAIL_HOST_PASSWORD') }}" ports: 80:8888 # container port 80 (standard http port) maps to server port 8888 (arbitrary internal port) diff --git a/src/core/settings.py b/src/core/settings.py index 7206c26..4f77465 100644 --- a/src/core/settings.py +++ b/src/core/settings.py @@ -51,6 +51,9 @@ INSTALLED_APPS = [ # Depend apps ] +if 'DJANGO_DEBUG_FALSE' not in os.environ: + INSTALLED_APPS += ['functional_tests'] + MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', @@ -149,7 +152,7 @@ LOGGING = { # Email Settings EMAIL_HOST = "smtp.mailgun.org" -EMAIL_HOST_USER = os.environ["EMAIL_HOST_USER"] -EMAIL_HOST_PASSWORD = os.environ["EMAIL_HOST_PASSWORD"] +EMAIL_HOST_USER = os.environ.get("EMAIL_HOST_USER") # switch back to .environ[] when collectstatic moved outside docker build process +EMAIL_HOST_PASSWORD = os.environ.get("EMAIL_HOST_PASSWORD") # switch back to .environ[] EMAIL_PORT = 587 EMAIL_USER_TLS = True diff --git a/src/functional_tests/base.py b/src/functional_tests/base.py index 0c2a505..6c29c5d 100644 --- a/src/functional_tests/base.py +++ b/src/functional_tests/base.py @@ -27,8 +27,9 @@ class FunctionalTest(StaticLiveServerTestCase): # Helper methods def setUp(self): self.browser = webdriver.Firefox() - if test_server := os.environ.get('TEST_SERVER'): - self.live_server_url = 'http://' + test_server + self.test_server = os.environ.get("TEST_SERVER") + if self.test_server: + self.live_server_url = 'http://' + self.test_server def tearDown(self): self.browser.quit() diff --git a/src/functional_tests/management/__init__.py b/src/functional_tests/management/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/functional_tests/management/commands/__init__.py b/src/functional_tests/management/commands/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/functional_tests/management/commands/create_session.py b/src/functional_tests/management/commands/create_session.py new file mode 100644 index 0000000..b96bf65 --- /dev/null +++ b/src/functional_tests/management/commands/create_session.py @@ -0,0 +1,23 @@ +from django.conf import settings +from django.contrib.auth import BACKEND_SESSION_KEY, SESSION_KEY, get_user_model +from django.contrib.sessions.backends.db import SessionStore +from django.core.management.base import BaseCommand + +User = get_user_model() + + +class Command(BaseCommand): + def add_arguments(self, parser): + parser.add_argument("email") + + def handle(self, *args, **options): + session_key = create_pre_authenticated_session(options["email"]) + self.stdout.write(session_key) + +def create_pre_authenticated_session(email): + user = User.objects.create(email=email) + session = SessionStore() + session[SESSION_KEY] = user.pk + session[BACKEND_SESSION_KEY] = settings.AUTHENTICATION_BACKENDS[0] + session.save() + return session.session_key diff --git a/src/functional_tests/test_login.py b/src/functional_tests/test_login.py index 4a96ed4..477b0ac 100644 --- a/src/functional_tests/test_login.py +++ b/src/functional_tests/test_login.py @@ -21,6 +21,9 @@ class LoginTest(FunctionalTest): ) ) + if self.test_server: + return + email = mail.outbox.pop() self.assertIn(TEST_EMAIL, email.to) self.assertEqual(email.subject, SUBJECT)