simple-module-test 0.0.38__tar.gz → 0.0.39__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {simple_module_test-0.0.38 → simple_module_test-0.0.39}/PKG-INFO +8 -8
- {simple_module_test-0.0.38 → simple_module_test-0.0.39}/pyproject.toml +8 -8
- {simple_module_test-0.0.38 → simple_module_test-0.0.39}/simple_module_test/fixtures.py +3 -0
- {simple_module_test-0.0.38 → simple_module_test-0.0.39}/simple_module_test/mail.py +2 -11
- {simple_module_test-0.0.38 → simple_module_test-0.0.39}/simple_module_test/plugin.py +2 -1
- simple_module_test-0.0.39/simple_module_test/process_state.py +24 -0
- simple_module_test-0.0.39/tests/test_testing_process_state.py +94 -0
- {simple_module_test-0.0.38 → simple_module_test-0.0.39}/.gitignore +0 -0
- {simple_module_test-0.0.38 → simple_module_test-0.0.39}/LICENSE +0 -0
- {simple_module_test-0.0.38 → simple_module_test-0.0.39}/README.md +0 -0
- {simple_module_test-0.0.38 → simple_module_test-0.0.39}/simple_module_test/__init__.py +0 -0
- {simple_module_test-0.0.38 → simple_module_test-0.0.39}/simple_module_test/_schema.py +0 -0
- {simple_module_test-0.0.38 → simple_module_test-0.0.39}/simple_module_test/app_factory.py +0 -0
- {simple_module_test-0.0.38 → simple_module_test-0.0.39}/simple_module_test/database.py +0 -0
- {simple_module_test-0.0.38 → simple_module_test-0.0.39}/simple_module_test/fake_events.py +0 -0
- {simple_module_test-0.0.38 → simple_module_test-0.0.39}/simple_module_test/redis_server.py +0 -0
- {simple_module_test-0.0.38 → simple_module_test-0.0.39}/simple_module_test/routes.py +0 -0
- {simple_module_test-0.0.38 → simple_module_test-0.0.39}/simple_module_test/session_cookie.py +0 -0
- {simple_module_test-0.0.38 → simple_module_test-0.0.39}/simple_module_test/setup_wizard.py +0 -0
- {simple_module_test-0.0.38 → simple_module_test-0.0.39}/simple_module_test/tenant_client.py +0 -0
- {simple_module_test-0.0.38 → simple_module_test-0.0.39}/simple_module_test/waiting.py +0 -0
- {simple_module_test-0.0.38 → simple_module_test-0.0.39}/tests/test_app_factory.py +0 -0
- {simple_module_test-0.0.38 → simple_module_test-0.0.39}/tests/test_fake_events.py +0 -0
- {simple_module_test-0.0.38 → simple_module_test-0.0.39}/tests/test_plugin_fixtures.py +0 -0
- {simple_module_test-0.0.38 → simple_module_test-0.0.39}/tests/test_schema_reuse_pg.py +0 -0
- {simple_module_test-0.0.38 → simple_module_test-0.0.39}/tests/test_waiting_helpers.py +0 -0
- {simple_module_test-0.0.38 → simple_module_test-0.0.39}/tests/test_worker_database.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: simple_module_test
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.39
|
|
4
4
|
Summary: Shared pytest fixtures (app, client, db_session, authenticated_client) for writing simple_module module tests
|
|
5
5
|
Project-URL: Homepage, https://github.com/antosubash/simple_module_python
|
|
6
6
|
Project-URL: Repository, https://github.com/antosubash/simple_module_python
|
|
@@ -22,13 +22,13 @@ Classifier: Topic :: Software Development :: Testing
|
|
|
22
22
|
Classifier: Typing :: Typed
|
|
23
23
|
Requires-Python: >=3.12
|
|
24
24
|
Requires-Dist: fastapi<0.157,>=0.140
|
|
25
|
-
Requires-Dist: httpx
|
|
26
|
-
Requires-Dist: pytest-asyncio
|
|
27
|
-
Requires-Dist: pytest
|
|
28
|
-
Requires-Dist: simple-module-core==0.0.
|
|
29
|
-
Requires-Dist: simple-module-db==0.0.
|
|
30
|
-
Requires-Dist: simple-module-hosting==0.0.
|
|
31
|
-
Requires-Dist: sqlalchemy
|
|
25
|
+
Requires-Dist: httpx<0.29,>=0.27
|
|
26
|
+
Requires-Dist: pytest-asyncio<2,>=0.24
|
|
27
|
+
Requires-Dist: pytest<10,>=8.0
|
|
28
|
+
Requires-Dist: simple-module-core==0.0.39
|
|
29
|
+
Requires-Dist: simple-module-db==0.0.39
|
|
30
|
+
Requires-Dist: simple-module-hosting==0.0.39
|
|
31
|
+
Requires-Dist: sqlalchemy<3,>=2.0
|
|
32
32
|
Description-Content-Type: text/markdown
|
|
33
33
|
|
|
34
34
|
# simple_module_test
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "simple_module_test"
|
|
3
|
-
version = "0.0.
|
|
3
|
+
version = "0.0.39"
|
|
4
4
|
description = "Shared pytest fixtures (app, client, db_session, authenticated_client) for writing simple_module module tests"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "MIT"
|
|
@@ -22,13 +22,13 @@ classifiers = [
|
|
|
22
22
|
]
|
|
23
23
|
dependencies = [
|
|
24
24
|
"fastapi>=0.140,<0.157",
|
|
25
|
-
"httpx>=0.27",
|
|
26
|
-
"pytest>=8.0",
|
|
27
|
-
"pytest-asyncio>=0.24",
|
|
28
|
-
"simple_module_core==0.0.
|
|
29
|
-
"simple_module_db==0.0.
|
|
30
|
-
"simple_module_hosting==0.0.
|
|
31
|
-
"sqlalchemy>=2.0",
|
|
25
|
+
"httpx>=0.27,<0.29",
|
|
26
|
+
"pytest>=8.0,<10",
|
|
27
|
+
"pytest-asyncio>=0.24,<2",
|
|
28
|
+
"simple_module_core==0.0.39",
|
|
29
|
+
"simple_module_db==0.0.39",
|
|
30
|
+
"simple_module_hosting==0.0.39",
|
|
31
|
+
"sqlalchemy>=2.0,<3",
|
|
32
32
|
]
|
|
33
33
|
|
|
34
34
|
[project.entry-points.pytest11]
|
|
@@ -161,6 +161,9 @@ async def _seed_setup_admin(application) -> None:
|
|
|
161
161
|
async def _build_app(settings: Settings, *, seed_admin: bool):
|
|
162
162
|
from simple_module_hosting.app_builder import create_app
|
|
163
163
|
|
|
164
|
+
# Process-wide state is reset per test by the autouse fixture in
|
|
165
|
+
# ``process_state``, not here: a second app built inside one test must not
|
|
166
|
+
# reset the live first app's mail sender or lease backend.
|
|
164
167
|
application = create_app(settings)
|
|
165
168
|
|
|
166
169
|
await _create_all_tables(application.state.sm.db.engine)
|
|
@@ -10,8 +10,7 @@ from __future__ import annotations
|
|
|
10
10
|
from collections.abc import Iterator
|
|
11
11
|
|
|
12
12
|
import pytest
|
|
13
|
-
from simple_module_core import
|
|
14
|
-
from simple_module_core.mail import MailMessage
|
|
13
|
+
from simple_module_core.mail import MailMessage, install_mail_sender
|
|
15
14
|
|
|
16
15
|
|
|
17
16
|
class CapturedMail:
|
|
@@ -28,14 +27,6 @@ class CapturedMail:
|
|
|
28
27
|
return [m for m in self.messages if m.to == address]
|
|
29
28
|
|
|
30
29
|
|
|
31
|
-
@pytest.fixture(autouse=True)
|
|
32
|
-
def _reset_process_mail_sender() -> Iterator[None]:
|
|
33
|
-
sender, resolver = core_mail._sender, core_mail._resolver
|
|
34
|
-
yield
|
|
35
|
-
core_mail.install_mail_sender(sender)
|
|
36
|
-
core_mail.install_mail_resolver(resolver)
|
|
37
|
-
|
|
38
|
-
|
|
39
30
|
@pytest.fixture
|
|
40
31
|
def captured_mail() -> Iterator[CapturedMail]:
|
|
41
32
|
"""Install a recording sender that claims to deliver; yields it.
|
|
@@ -45,5 +36,5 @@ def captured_mail() -> Iterator[CapturedMail]:
|
|
|
45
36
|
reinstalls the real one; reinstall with ``install_mail_sender(captured)``.
|
|
46
37
|
"""
|
|
47
38
|
captured = CapturedMail()
|
|
48
|
-
|
|
39
|
+
install_mail_sender(captured)
|
|
49
40
|
yield captured
|
|
@@ -33,7 +33,8 @@ from simple_module_test.fixtures import ( # noqa: F401
|
|
|
33
33
|
settings,
|
|
34
34
|
setup_pending_app,
|
|
35
35
|
)
|
|
36
|
-
from simple_module_test.mail import
|
|
36
|
+
from simple_module_test.mail import captured_mail # noqa: F401
|
|
37
|
+
from simple_module_test.process_state import _reset_process_state # noqa: F401
|
|
37
38
|
from simple_module_test.redis_server import redis_server # noqa: F401
|
|
38
39
|
from simple_module_test.tenant_client import tenant_client # noqa: F401
|
|
39
40
|
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""Reset process services between tests and apps built by the test plugin."""
|
|
2
|
+
|
|
3
|
+
from collections.abc import Iterator
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
from simple_module_core.leases import reset_lease_backend
|
|
7
|
+
from simple_module_core.mail import reset_mail_sender
|
|
8
|
+
from simple_module_hosting.sentry import reset_sentry
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def reset_process_state() -> None:
|
|
12
|
+
"""Restore unconfigured services without retaining another app's resources."""
|
|
13
|
+
reset_mail_sender()
|
|
14
|
+
reset_lease_backend()
|
|
15
|
+
reset_sentry()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@pytest.fixture(autouse=True)
|
|
19
|
+
def _reset_process_state() -> Iterator[None]:
|
|
20
|
+
reset_process_state()
|
|
21
|
+
try:
|
|
22
|
+
yield
|
|
23
|
+
finally:
|
|
24
|
+
reset_process_state()
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"""Process services are isolated between plugin-built apps and tests."""
|
|
2
|
+
|
|
3
|
+
from unittest.mock import Mock
|
|
4
|
+
|
|
5
|
+
from simple_module_core.leases import (
|
|
6
|
+
InProcessLeaseBackend,
|
|
7
|
+
configure_leases,
|
|
8
|
+
get_leases,
|
|
9
|
+
reset_lease_backend,
|
|
10
|
+
)
|
|
11
|
+
from simple_module_core.mail import (
|
|
12
|
+
ConsoleMailSender,
|
|
13
|
+
current_mail_sender,
|
|
14
|
+
install_mail_resolver,
|
|
15
|
+
install_mail_sender,
|
|
16
|
+
mail_transport_installed,
|
|
17
|
+
reset_mail_sender,
|
|
18
|
+
resolve_mail_sender,
|
|
19
|
+
)
|
|
20
|
+
from simple_module_hosting import sentry
|
|
21
|
+
from simple_module_test.mail import CapturedMail
|
|
22
|
+
from simple_module_test.process_state import reset_process_state
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
async def test_reset_mail_clears_sender_and_worker_resolver() -> None:
|
|
26
|
+
sender = CapturedMail()
|
|
27
|
+
|
|
28
|
+
async def resolver(db):
|
|
29
|
+
return sender
|
|
30
|
+
|
|
31
|
+
install_mail_sender(sender)
|
|
32
|
+
install_mail_resolver(resolver)
|
|
33
|
+
reset_mail_sender()
|
|
34
|
+
assert not mail_transport_installed()
|
|
35
|
+
assert isinstance(current_mail_sender(), ConsoleMailSender)
|
|
36
|
+
assert isinstance(await resolve_mail_sender(object()), ConsoleMailSender)
|
|
37
|
+
assert current_mail_sender().include_body is False
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
async def test_reset_leases_discards_configuration_and_held_names() -> None:
|
|
41
|
+
original = InProcessLeaseBackend()
|
|
42
|
+
configure_leases(original)
|
|
43
|
+
assert await original.acquire("held", "previous-app", 60) == 1
|
|
44
|
+
reset_lease_backend()
|
|
45
|
+
replacement = get_leases()
|
|
46
|
+
assert replacement is not original
|
|
47
|
+
assert isinstance(replacement, InProcessLeaseBackend)
|
|
48
|
+
assert await replacement.acquire("held", "next-app", 60) == 1
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def test_reset_sentry_closes_and_unbinds_client(monkeypatch) -> None:
|
|
52
|
+
import pytest
|
|
53
|
+
|
|
54
|
+
sdk = pytest.importorskip("sentry_sdk")
|
|
55
|
+
scope = Mock()
|
|
56
|
+
monkeypatch.setattr(sdk, "get_global_scope", lambda: scope)
|
|
57
|
+
monkeypatch.setattr(sentry, "_enabled", True)
|
|
58
|
+
sentry._request_scope.set({"type": "http"})
|
|
59
|
+
sentry.reset_sentry()
|
|
60
|
+
scope.client.close.assert_called_once_with()
|
|
61
|
+
scope.set_client.assert_called_once_with(None)
|
|
62
|
+
assert not sentry.is_enabled()
|
|
63
|
+
assert sentry._request_scope.get() is None
|
|
64
|
+
sentry.reset_sentry()
|
|
65
|
+
scope.client.close.assert_called_once_with()
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
async def test_plugin_second_app_keeps_first_apps_services(settings, monkeypatch) -> None:
|
|
69
|
+
"""Resets are per test (autouse fixture), so a second app in one test must not
|
|
70
|
+
wipe the first app's installed mail sender."""
|
|
71
|
+
from fastapi import FastAPI
|
|
72
|
+
from simple_module_hosting import app_builder
|
|
73
|
+
from simple_module_test import fixtures
|
|
74
|
+
|
|
75
|
+
def create_app(settings):
|
|
76
|
+
app = FastAPI()
|
|
77
|
+
app.state.sm = Mock()
|
|
78
|
+
return app
|
|
79
|
+
|
|
80
|
+
async def create_tables(engine):
|
|
81
|
+
pass
|
|
82
|
+
|
|
83
|
+
monkeypatch.setattr(app_builder, "create_app", create_app)
|
|
84
|
+
monkeypatch.setattr(fixtures, "_create_all_tables", create_tables)
|
|
85
|
+
install_mail_sender(CapturedMail())
|
|
86
|
+
async for _app in fixtures._build_app(settings, seed_admin=False):
|
|
87
|
+
assert mail_transport_installed()
|
|
88
|
+
reset_process_state()
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def test_autouse_reset_clears_state_left_by_a_previous_test() -> None:
|
|
92
|
+
# The autouse ``_reset_process_state`` fixture ran before this test.
|
|
93
|
+
assert not mail_transport_installed()
|
|
94
|
+
assert not sentry.is_enabled()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{simple_module_test-0.0.38 → simple_module_test-0.0.39}/simple_module_test/session_cookie.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|