Skip to content

Commit 5565720

Browse files
committed
✅[#46] add session profile tests
1 parent 6a61597 commit 5565720

File tree

7 files changed

+216
-17
lines changed

7 files changed

+216
-17
lines changed

open_api_framework/admin.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010
class SessionProfileAdmin(admin.ModelAdmin):
1111
list_display = ["session_key", "user", "exists"]
1212

13-
def __init__(self, model, admin_site):
14-
engine = import_module(settings.SESSION_ENGINE)
15-
self.SessionStore = engine.SessionStore
16-
super().__init__(model, admin_site)
13+
@property
14+
def SessionStore(self):
15+
16+
return import_module(settings.SESSION_ENGINE).SessionStore
1717

1818
def get_queryset(self, request):
1919
qs = super().get_queryset(request)
@@ -29,14 +29,14 @@ def has_change_permission(self, request, obj=None):
2929
def exists(self, obj):
3030
return self.SessionStore().exists(obj.session_key)
3131

32-
def expiration_time(self, obj):
33-
34-
session = self.SessionStore(obj.session_key)
35-
36-
if session.exists(obj.session_key):
37-
return session.get_expiry_date()
38-
return None
39-
4032
def delete_model(self, request, obj):
4133
self.SessionStore(obj.session_key).flush()
4234
super().delete_model(request, obj)
35+
36+
def delete_queryset(self, request, queryset):
37+
38+
session_keys = list(queryset.values_list("session_key", flat=True))
39+
for session_key in session_keys:
40+
self.SessionStore(session_key).flush()
41+
42+
super().delete_queryset(request, queryset)

open_api_framework/conf/base.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,6 @@
243243
"django.middleware.csrf.CsrfViewMiddleware",
244244
"django.contrib.auth.middleware.AuthenticationMiddleware",
245245
"maykin_2fa.middleware.OTPMiddleware",
246-
"mozilla_django_oidc_db.middleware.SessionRefresh",
247246
"django.contrib.messages.middleware.MessageMiddleware",
248247
"django.middleware.clickjacking.XFrameOptionsMiddleware",
249248
"axes.middleware.AxesMiddleware",

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ tests = [
7373
"isort",
7474
"black",
7575
"flake8",
76+
"factory-boy",
7677
]
7778
coverage = [
7879
"pytest-cov",

testapp/settings.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,5 @@
8080
# These are excluded from generate_envvar_docs test by their group
8181
VARIABLE_TO_BE_EXCLUDED = config("VARIABLE_TO_BE_EXCLUDED1", "foo", group="Excluded")
8282
VARIABLE_TO_BE_EXCLUDED = config("VARIABLE_TO_BE_EXCLUDED2", "bar", group="Excluded")
83+
84+
SESSION_ENGINE = "django.contrib.sessions.backends.db"

tests/conftest.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
1-
# import pytest
1+
from importlib import import_module
22

3+
from django.conf import settings as django_settings
34

4-
# @pytest.fixture
5-
# def some_fixture(request):
6-
# return "foo"
5+
import pytest
6+
7+
8+
@pytest.fixture
9+
def cache_session_store(settings):
10+
settings.SESSION_ENGINE = "django.contrib.sessions.backends.cache"
11+
return import_module(django_settings.SESSION_ENGINE).SessionStore
12+
13+
14+
@pytest.fixture
15+
def db_session_store(settings):
16+
settings.SESSION_ENGINE = "django.contrib.sessions.backends.db"
17+
return import_module(django_settings.SESSION_ENGINE).SessionStore

tests/factories.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from importlib import import_module
2+
3+
from django.conf import settings
4+
5+
import factory
6+
import factory.fuzzy
7+
from sessionprofile.models import SessionProfile
8+
9+
10+
class SessionProfileFactory(factory.django.DjangoModelFactory):
11+
12+
session_key = factory.fuzzy.FuzzyText(length=40)
13+
14+
class Meta:
15+
model = SessionProfile
16+
17+
@classmethod
18+
def create(cls, **kwargs):
19+
SessionStore = import_module(settings.SESSION_ENGINE).SessionStore
20+
21+
instance = super().create(**kwargs)
22+
SessionStore(instance.session_key).save(True)
23+
24+
return instance

tests/test_admin.py

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
from django.contrib.sessions.models import Session
2+
from django.urls import reverse
3+
4+
import pytest
5+
from pytest_django.fixtures import admin_user
6+
from sessionprofile.models import SessionProfile
7+
8+
from .factories import SessionProfileFactory
9+
10+
11+
@pytest.fixture
12+
def session_changelist_url():
13+
return reverse("admin:sessionprofile_sessionprofile_changelist")
14+
15+
16+
def test_session_profile_sanity(client, admin_user, session_changelist_url):
17+
18+
client.force_login(admin_user)
19+
response = client.get(session_changelist_url)
20+
assert response.status_code == 200
21+
22+
assert SessionProfile.objects.count() == 1
23+
24+
session = SessionProfile.objects.get()
25+
assert client.session.session_key == session.session_key
26+
27+
28+
admin_user2 = admin_user
29+
30+
31+
def test_only_session_profile_of_user_shown(
32+
client, admin_user, django_user_model, session_changelist_url
33+
):
34+
35+
other_admin = django_user_model.objects.create_superuser("garry")
36+
37+
client.force_login(other_admin)
38+
response = client.get(session_changelist_url)
39+
assert response.status_code == 200
40+
41+
client.force_login(admin_user)
42+
response = client.get(session_changelist_url)
43+
assert response.status_code == 200
44+
45+
# two sessions, one for each user
46+
assert SessionProfile.objects.count() == 2
47+
48+
# Session created after response, needs to be called again
49+
response = client.get(session_changelist_url)
50+
51+
admin_user_session = SessionProfile.objects.get(user=admin_user)
52+
assert admin_user_session.session_key in response.content.decode()
53+
54+
other_user_session = SessionProfile.objects.get(user=other_admin)
55+
assert other_user_session.session_key not in response.content.decode()
56+
57+
58+
def test_delete_with_session_db_backend(
59+
client, admin_user, session_changelist_url, db_session_store
60+
):
61+
client.force_login(admin_user)
62+
63+
session = SessionProfileFactory(user=admin_user)
64+
65+
assert SessionProfile.objects.count() == 1
66+
# sesison created by login
67+
assert Session.objects.count() == 2
68+
assert db_session_store().exists(session.session_key)
69+
70+
url = reverse("admin:sessionprofile_sessionprofile_delete", args=[session.pk])
71+
72+
response = client.post(url, {"post": "yes"})
73+
assert response.status_code == 302
74+
75+
# new session saved upon request
76+
assert SessionProfile.objects.count() == 1
77+
assert SessionProfile.objects.count() != session
78+
assert Session.objects.count() == 1
79+
assert not db_session_store().exists(session.session_key)
80+
81+
82+
def test_delete_with_session_cache_backend(
83+
client, admin_user, session_changelist_url, cache_session_store
84+
):
85+
client.force_login(admin_user)
86+
87+
session = SessionProfileFactory(user=admin_user)
88+
89+
assert SessionProfile.objects.count() == 1
90+
assert Session.objects.count() == 0
91+
assert cache_session_store().exists(session.session_key)
92+
93+
url = reverse("admin:sessionprofile_sessionprofile_delete", args=[session.pk])
94+
95+
response = client.post(url, {"post": "yes"})
96+
assert response.status_code == 302
97+
98+
# new session saved upon request
99+
assert SessionProfile.objects.count() == 1
100+
assert SessionProfile.objects.count() != session
101+
assert Session.objects.count() == 0
102+
assert not cache_session_store().exists(session.session_key)
103+
104+
105+
def test_delete_action_with_session_db_backend(
106+
client, admin_user, session_changelist_url, db_session_store
107+
):
108+
client.force_login(admin_user)
109+
sessions = SessionProfileFactory.create_batch(5, user=admin_user)
110+
111+
# one created from user login
112+
assert Session.objects.count() == 6
113+
assert SessionProfile.objects.count() == 5
114+
115+
session_keys = [session.session_key for session in sessions]
116+
for session_key in session_keys:
117+
assert db_session_store().exists(session_key)
118+
119+
response = client.post(
120+
session_changelist_url,
121+
{"action": "delete_selected", "_selected_action": session_keys, "post": "yes"},
122+
)
123+
assert response.status_code == 302
124+
125+
# one is created as the post request is sent
126+
assert SessionProfile.objects.count() == 1
127+
assert Session.objects.count() == 1
128+
129+
for session_key in session_keys:
130+
assert not db_session_store().exists(session_key)
131+
132+
133+
def test_delete_action_with_session_cache_backend(
134+
client, admin_user, session_changelist_url, cache_session_store
135+
):
136+
137+
client.force_login(admin_user)
138+
sessions = SessionProfileFactory.create_batch(5, user=admin_user)
139+
140+
# no db sessions are created
141+
assert Session.objects.count() == 0
142+
assert SessionProfile.objects.count() == 5
143+
144+
session_keys = [session.session_key for session in sessions]
145+
146+
# sessions are created
147+
for session_key in session_keys:
148+
assert cache_session_store().exists(session_key)
149+
150+
response = client.post(
151+
session_changelist_url,
152+
{"action": "delete_selected", "_selected_action": session_keys, "post": "yes"},
153+
)
154+
assert response.status_code == 302
155+
156+
# one is created as the post request is sent
157+
assert SessionProfile.objects.count() == 1
158+
assert Session.objects.count() == 0
159+
160+
# sessions should be deleted
161+
for session_key in session_keys:
162+
assert not cache_session_store().exists(session_key)

0 commit comments

Comments
 (0)