diff --git a/tests/test_admin.py b/tests/test_admin.py new file mode 100644 index 0000000..e9238f9 --- /dev/null +++ b/tests/test_admin.py @@ -0,0 +1,61 @@ +from urllib.parse import urlencode + +from django.contrib.auth.models import User +from django.test import TestCase +from django.urls import reverse + +from user_sessions.backends.db import SessionStore + +from .utils import Client + + +class AdminTest(TestCase): + client_class = Client + + def setUp(self): + User.objects.create_superuser('bouke', '', 'secret') + assert self.client.login(username='bouke', password='secret') + + expired = SessionStore(user_agent='Python/2.5', ip='20.13.1.1') + expired.set_expiry(-365 * 86400) + expired.save() + unexpired = SessionStore(user_agent='Python/2.7', ip='1.1.1.1') + unexpired.save() + + self.admin_url = reverse('admin:user_sessions_session_changelist') + + def test_list(self): + with self.assertWarnsRegex(UserWarning, r"The address 1\.1\.1\.1 is not in the database"): + response = self.client.get(self.admin_url) + self.assertContains(response, 'Select session to change') + self.assertContains(response, '127.0.0.1') + self.assertContains(response, '20.13.1.1') + self.assertContains(response, '1.1.1.1') + + def test_search(self): + with self.assertWarnsRegex(UserWarning, r"The address 127\.0\.0\.1 is not in the database"): + response = self.client.get(self.admin_url, {'q': 'bouke'}) + self.assertContains(response, '127.0.0.1') + self.assertNotContains(response, '20.13.1.1') + self.assertNotContains(response, '1.1.1.1') + + def test_mine(self): + my_sessions = f"{self.admin_url}?{urlencode({'owner': 'my'})}" + with self.assertWarnsRegex(UserWarning, r"The address 127\.0\.0\.1 is not in the database"): + response = self.client.get(my_sessions) + self.assertContains(response, '127.0.0.1') + self.assertNotContains(response, '1.1.1.1') + + def test_expired(self): + expired = f"{self.admin_url}?{urlencode({'active': '0'})}" + with self.assertWarnsRegex(UserWarning, r"The address 20\.13\.1\.1 is not in the database"): + response = self.client.get(expired) + self.assertContains(response, '20.13.1.1') + self.assertNotContains(response, '1.1.1.1') + + def test_unexpired(self): + unexpired = f"{self.admin_url}?{urlencode({'active': '1'})}" + with self.assertWarnsRegex(UserWarning, r"The address 1\.1\.1\.1 is not in the database"): + response = self.client.get(unexpired) + self.assertContains(response, '1.1.1.1') + self.assertNotContains(response, '20.13.1.1') diff --git a/tests/test_client.py b/tests/test_client.py new file mode 100644 index 0000000..4bda6ae --- /dev/null +++ b/tests/test_client.py @@ -0,0 +1,51 @@ +from unittest.mock import patch + +from django.contrib.auth.models import User +from django.conf import settings +from django.test import TestCase +from django.test.utils import override_settings + +from user_sessions.backends.db import SessionStore + +from .utils import Client + + +class ClientTest(TestCase): + def test_invalid_login(self): + client = Client() + self.assertFalse(client.login()) + + def test_restore_session(self): + store = SessionStore(user_agent='Python/2.7', ip='127.0.0.1') + store['foo'] = 'bar' + store.save() + client = Client() + client.cookies[settings.SESSION_COOKIE_NAME] = store.session_key + User.objects.create_user('bouke', '', 'secret') + assert client.login(username='bouke', password='secret') + self.assertEqual(client.session['foo'], 'bar') + + def test_login_logout(self): + client = Client() + User.objects.create_user('bouke', '', 'secret') + assert client.login(username='bouke', password='secret') + assert settings.SESSION_COOKIE_NAME in client.cookies + + client.logout() + assert settings.SESSION_COOKIE_NAME not in client.cookies + + # should not raise + client.logout() + + @patch('django.contrib.auth.signals.user_logged_in.send') + def test_login_signal(self, mock_user_logged_in): + client = Client() + User.objects.create_user('bouke', '', 'secret') + assert client.login(username='bouke', password='secret') + assert mock_user_logged_in.called + request = mock_user_logged_in.call_args[1]['request'] + assert getattr(request, 'user', None) is not None + + @override_settings(INSTALLED_APPS=()) + def test_no_session(self): + self.assertIsNone(Client().session) diff --git a/tests/test_commands.py b/tests/test_commands.py new file mode 100644 index 0000000..2ee13b9 --- /dev/null +++ b/tests/test_commands.py @@ -0,0 +1,42 @@ +from datetime import timedelta + +from django.contrib.auth.models import User +from django.core.management import call_command +from django.test import TestCase, TransactionTestCase +from django.test.utils import modify_settings +from django.utils.timezone import now + +from user_sessions.models import Session + + +class ClearsessionsCommandTest(TestCase): + def test_can_call(self): + Session.objects.create(expire_date=now() - timedelta(days=1), + ip='127.0.0.1') + call_command('clearsessions') + self.assertEqual(Session.objects.count(), 0) + + +class MigratesessionsCommandTest(TransactionTestCase): + @modify_settings(INSTALLED_APPS={'append': 'django.contrib.sessions'}) + def test_migrate_from_login(self): + from django.contrib.sessions.backends.db import ( + SessionStore as DjangoSessionStore, + ) + from django.contrib.sessions.models import Session as DjangoSession + try: + call_command('migrate', 'sessions') + call_command('clearsessions') + user = User.objects.create_user('bouke', '', 'secret') + session = DjangoSessionStore() + session['_auth_user_id'] = user.id + session.save() + self.assertEqual(Session.objects.count(), 0) + self.assertEqual(DjangoSession.objects.count(), 1) + call_command('migratesessions') + new_sessions = list(Session.objects.all()) + self.assertEqual(len(new_sessions), 1) + self.assertEqual(new_sessions[0].user, user) + self.assertEqual(new_sessions[0].ip, '127.0.0.1') + finally: + call_command('migrate', 'sessions', 'zero') diff --git a/tests/test_middleware.py b/tests/test_middleware.py new file mode 100644 index 0000000..b3a98ed --- /dev/null +++ b/tests/test_middleware.py @@ -0,0 +1,45 @@ +from django.contrib.auth.models import User +from django.conf import settings +from django.test import TestCase +from django.urls import reverse + +from user_sessions.models import Session + + +class MiddlewareTest(TestCase): + def test_unmodified_session(self): + self.client.get('/', HTTP_USER_AGENT='Python/2.7') + self.assertNotIn(settings.SESSION_COOKIE_NAME, self.client.cookies) + + def test_modify_session(self): + self.client.get('/modify_session/', HTTP_USER_AGENT='Python/2.7') + self.assertIn(settings.SESSION_COOKIE_NAME, self.client.cookies) + session = Session.objects.get( + pk=self.client.cookies[settings.SESSION_COOKIE_NAME].value + ) + self.assertEqual(session.user_agent, 'Python/2.7') + self.assertEqual(session.ip, '127.0.0.1') + + def test_login(self): + admin_login_url = reverse('admin:login') + user = User.objects.create_superuser('bouke', '', 'secret') + response = self.client.post(admin_login_url, + data={ + 'username': 'bouke', + 'password': 'secret', + 'this_is_the_login_form': '1', + 'next': '/admin/'}, + HTTP_USER_AGENT='Python/2.7') + self.assertRedirects(response, '/admin/') + session = Session.objects.get( + pk=self.client.cookies[settings.SESSION_COOKIE_NAME].value + ) + self.assertEqual( + self.client.cookies[settings.SESSION_COOKIE_NAME]["samesite"], + settings.SESSION_COOKIE_SAMESITE, + ) + self.assertEqual(user, session.user) + + def test_long_ua(self): + self.client.get('/modify_session/', + HTTP_USER_AGENT=''.join('a' for _ in range(400))) diff --git a/tests/test_models.py b/tests/test_models.py new file mode 100644 index 0000000..3de6225 --- /dev/null +++ b/tests/test_models.py @@ -0,0 +1,30 @@ +from django.contrib import auth +from django.contrib.auth.models import User +from django.test import TestCase + +from user_sessions.backends.db import SessionStore +from user_sessions.models import Session + + +class ModelTest(TestCase): + def test_get_decoded(self): + User.objects.create_user('bouke', '', 'secret', id=1) + store = SessionStore(user_agent='Python/2.7', ip='127.0.0.1') + store[auth.SESSION_KEY] = 1 + store['foo'] = 'bar' + store.save() + + session = Session.objects.get(pk=store.session_key) + self.assertEqual(session.get_decoded(), + {'foo': 'bar', auth.SESSION_KEY: 1}) + + def test_very_long_ua(self): + ua = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; ' \ + 'Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; ' \ + '.NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; ' \ + 'InfoPath.3; ms-office; MSOffice 14)' + store = SessionStore(user_agent=ua, ip='127.0.0.1') + store.save() + + session = Session.objects.get(pk=store.session_key) + self.assertEqual(session.user_agent, ua[:200]) diff --git a/tests/test_sessionstore.py b/tests/test_sessionstore.py new file mode 100644 index 0000000..2d0416a --- /dev/null +++ b/tests/test_sessionstore.py @@ -0,0 +1,99 @@ +from datetime import timedelta + +from django.contrib import auth +from django.contrib.auth.models import User +from django.contrib.sessions.backends.base import CreateError +from django.test import TestCase +from django.utils.timezone import now + +from user_sessions.backends.db import SessionStore +from user_sessions.models import Session + + +class SessionStoreTest(TestCase): + def setUp(self): + self.store = SessionStore(user_agent='Python/2.7', ip='127.0.0.1') + User.objects.create_user('bouke', '', 'secret', id=1) + + def test_untouched_init(self): + self.assertFalse(self.store.modified) + self.assertFalse(self.store.accessed) + + def test_auth_session_key(self): + self.assertFalse(auth.SESSION_KEY in self.store) + self.assertFalse(self.store.modified) + self.assertTrue(self.store.accessed) + + self.store.get(auth.SESSION_KEY) + self.assertFalse(self.store.modified) + + self.store[auth.SESSION_KEY] = 1 + self.assertTrue(self.store.modified) + + def test_save(self): + self.store[auth.SESSION_KEY] = 1 + self.store.save() + + session = Session.objects.get(pk=self.store.session_key) + self.assertEqual(session.user_agent, 'Python/2.7') + self.assertEqual(session.ip, '127.0.0.1') + self.assertEqual(session.user_id, 1) + self.assertAlmostEqual(now(), session.last_activity, + delta=timedelta(seconds=5)) + + def test_load_unmodified(self): + self.store[auth.SESSION_KEY] = 1 + self.store.save() + store2 = SessionStore(session_key=self.store.session_key, + user_agent='Python/2.7', ip='127.0.0.1') + store2.load() + self.assertEqual(store2.user_agent, 'Python/2.7') + self.assertEqual(store2.ip, '127.0.0.1') + self.assertEqual(store2.user_id, 1) + self.assertEqual(store2.modified, False) + + def test_load_modified(self): + self.store[auth.SESSION_KEY] = 1 + self.store.save() + store2 = SessionStore(session_key=self.store.session_key, + user_agent='Python/3.3', ip='8.8.8.8') + store2.load() + self.assertEqual(store2.user_agent, 'Python/3.3') + self.assertEqual(store2.ip, '8.8.8.8') + self.assertEqual(store2.user_id, 1) + self.assertEqual(store2.modified, True) + + def test_duplicate_create(self): + s1 = SessionStore(session_key='DUPLICATE', user_agent='Python/2.7', ip='127.0.0.1') + s1.create() + s2 = SessionStore(session_key='DUPLICATE', user_agent='Python/2.7', ip='127.0.0.1') + s2.create() + self.assertNotEqual(s1.session_key, s2.session_key) + + s3 = SessionStore(session_key=s1.session_key, user_agent='Python/2.7', ip='127.0.0.1') + with self.assertRaises(CreateError): + s3.save(must_create=True) + + def test_delete(self): + # not persisted, should just return + self.store.delete() + + # create, then delete + self.store.create() + session_key = self.store.session_key + self.store.delete() + + # non-existing sessions, should not raise + self.store.delete() + self.store.delete(session_key) + + def test_clear(self): + """ + Clearing the session should clear all non-browser information + """ + self.store[auth.SESSION_KEY] = 1 + self.store.clear() + self.store.save() + + session = Session.objects.get(pk=self.store.session_key) + self.assertEqual(session.user_id, None) diff --git a/tests/tests.py b/tests/test_template_filters.py similarity index 56% rename from tests/tests.py rename to tests/test_template_filters.py index 3910a92..7d759a1 100644 --- a/tests/tests.py +++ b/tests/test_template_filters.py @@ -1,25 +1,12 @@ -from datetime import timedelta from unittest import skipUnless -from unittest.mock import patch -from urllib.parse import urlencode - -from django.conf import settings -from django.contrib import auth -from django.contrib.auth.models import User -from django.contrib.sessions.backends.base import CreateError -from django.core.management import call_command -from django.test import TestCase, TransactionTestCase -from django.test.utils import modify_settings, override_settings -from django.urls import reverse -from django.utils.timezone import now - -from user_sessions.backends.db import SessionStore -from user_sessions.models import Session + +from django.test import TestCase +from django.test.utils import override_settings + from user_sessions.templatetags.user_sessions import ( browser, city, country, device, location, platform, ) -from .utils import Client try: from django.contrib.gis.geoip2 import GeoIP2 @@ -35,293 +22,6 @@ geoip_msg = str(error_geoip2) + " and " + str(error_geoip) -class MiddlewareTest(TestCase): - def test_unmodified_session(self): - self.client.get('/', HTTP_USER_AGENT='Python/2.7') - self.assertNotIn(settings.SESSION_COOKIE_NAME, self.client.cookies) - - def test_modify_session(self): - self.client.get('/modify_session/', HTTP_USER_AGENT='Python/2.7') - self.assertIn(settings.SESSION_COOKIE_NAME, self.client.cookies) - session = Session.objects.get( - pk=self.client.cookies[settings.SESSION_COOKIE_NAME].value - ) - self.assertEqual(session.user_agent, 'Python/2.7') - self.assertEqual(session.ip, '127.0.0.1') - - def test_login(self): - admin_login_url = reverse('admin:login') - user = User.objects.create_superuser('bouke', '', 'secret') - response = self.client.post(admin_login_url, - data={ - 'username': 'bouke', - 'password': 'secret', - 'this_is_the_login_form': '1', - 'next': '/admin/'}, - HTTP_USER_AGENT='Python/2.7') - self.assertRedirects(response, '/admin/') - session = Session.objects.get( - pk=self.client.cookies[settings.SESSION_COOKIE_NAME].value - ) - self.assertEqual( - self.client.cookies[settings.SESSION_COOKIE_NAME]["samesite"], - settings.SESSION_COOKIE_SAMESITE, - ) - self.assertEqual(user, session.user) - - def test_long_ua(self): - self.client.get('/modify_session/', - HTTP_USER_AGENT=''.join('a' for _ in range(400))) - - -class ViewsTest(TestCase): - client_class = Client - - def setUp(self): - self.user = User.objects.create_user('bouke', '', 'secret') - assert self.client.login(username='bouke', password='secret') - - def test_list(self): - self.user.session_set.create(session_key='ABC123', ip='127.0.0.1', - expire_date=now() + timedelta(days=1), - user_agent='Firefox') - with self.assertWarnsRegex(UserWarning, r"The address 127\.0\.0\.1 is not in the database"): - response = self.client.get(reverse('user_sessions:session_list')) - self.assertContains(response, 'Active Sessions') - self.assertContains(response, 'Firefox') - self.assertNotContains(response, 'ABC123') - - def test_delete(self): - session_key = self.client.cookies[settings.SESSION_COOKIE_NAME].value - response = self.client.post(reverse('user_sessions:session_delete', - args=[session_key])) - self.assertRedirects(response, '/') - - def test_delete_all_other(self): - self.user.session_set.create(ip='127.0.0.1', expire_date=now() + timedelta(days=1)) - self.assertEqual(self.user.session_set.count(), 2) - response = self.client.post(reverse('user_sessions:session_delete_other')) - with self.assertWarnsRegex(UserWarning, r"The address 127\.0\.0\.1 is not in the database"): - self.assertRedirects(response, reverse('user_sessions:session_list')) - self.assertEqual(self.user.session_set.count(), 1) - - def test_delete_some_other(self): - other = self.user.session_set.create(session_key='OTHER', ip='127.0.0.1', - expire_date=now() + timedelta(days=1)) - self.assertEqual(self.user.session_set.count(), 2) - response = self.client.post(reverse('user_sessions:session_delete', - args=[other.session_key])) - with self.assertWarnsRegex(UserWarning, r"The address 127\.0\.0\.1 is not in the database"): - self.assertRedirects(response, reverse('user_sessions:session_list')) - self.assertEqual(self.user.session_set.count(), 1) - - -class AdminTest(TestCase): - client_class = Client - - def setUp(self): - User.objects.create_superuser('bouke', '', 'secret') - assert self.client.login(username='bouke', password='secret') - - expired = SessionStore(user_agent='Python/2.5', ip='20.13.1.1') - expired.set_expiry(-365 * 86400) - expired.save() - unexpired = SessionStore(user_agent='Python/2.7', ip='1.1.1.1') - unexpired.save() - - self.admin_url = reverse('admin:user_sessions_session_changelist') - - def test_list(self): - with self.assertWarnsRegex(UserWarning, r"The address 1\.1\.1\.1 is not in the database"): - response = self.client.get(self.admin_url) - self.assertContains(response, 'Select session to change') - self.assertContains(response, '127.0.0.1') - self.assertContains(response, '20.13.1.1') - self.assertContains(response, '1.1.1.1') - - def test_search(self): - with self.assertWarnsRegex(UserWarning, r"The address 127\.0\.0\.1 is not in the database"): - response = self.client.get(self.admin_url, {'q': 'bouke'}) - self.assertContains(response, '127.0.0.1') - self.assertNotContains(response, '20.13.1.1') - self.assertNotContains(response, '1.1.1.1') - - def test_mine(self): - my_sessions = f"{self.admin_url}?{urlencode({'owner': 'my'})}" - with self.assertWarnsRegex(UserWarning, r"The address 127\.0\.0\.1 is not in the database"): - response = self.client.get(my_sessions) - self.assertContains(response, '127.0.0.1') - self.assertNotContains(response, '1.1.1.1') - - def test_expired(self): - expired = f"{self.admin_url}?{urlencode({'active': '0'})}" - with self.assertWarnsRegex(UserWarning, r"The address 20\.13\.1\.1 is not in the database"): - response = self.client.get(expired) - self.assertContains(response, '20.13.1.1') - self.assertNotContains(response, '1.1.1.1') - - def test_unexpired(self): - unexpired = f"{self.admin_url}?{urlencode({'active': '1'})}" - with self.assertWarnsRegex(UserWarning, r"The address 1\.1\.1\.1 is not in the database"): - response = self.client.get(unexpired) - self.assertContains(response, '1.1.1.1') - self.assertNotContains(response, '20.13.1.1') - - -class SessionStoreTest(TestCase): - def setUp(self): - self.store = SessionStore(user_agent='Python/2.7', ip='127.0.0.1') - User.objects.create_user('bouke', '', 'secret', id=1) - - def test_untouched_init(self): - self.assertFalse(self.store.modified) - self.assertFalse(self.store.accessed) - - def test_auth_session_key(self): - self.assertFalse(auth.SESSION_KEY in self.store) - self.assertFalse(self.store.modified) - self.assertTrue(self.store.accessed) - - self.store.get(auth.SESSION_KEY) - self.assertFalse(self.store.modified) - - self.store[auth.SESSION_KEY] = 1 - self.assertTrue(self.store.modified) - - def test_save(self): - self.store[auth.SESSION_KEY] = 1 - self.store.save() - - session = Session.objects.get(pk=self.store.session_key) - self.assertEqual(session.user_agent, 'Python/2.7') - self.assertEqual(session.ip, '127.0.0.1') - self.assertEqual(session.user_id, 1) - self.assertAlmostEqual(now(), session.last_activity, - delta=timedelta(seconds=5)) - - def test_load_unmodified(self): - self.store[auth.SESSION_KEY] = 1 - self.store.save() - store2 = SessionStore(session_key=self.store.session_key, - user_agent='Python/2.7', ip='127.0.0.1') - store2.load() - self.assertEqual(store2.user_agent, 'Python/2.7') - self.assertEqual(store2.ip, '127.0.0.1') - self.assertEqual(store2.user_id, 1) - self.assertEqual(store2.modified, False) - - def test_load_modified(self): - self.store[auth.SESSION_KEY] = 1 - self.store.save() - store2 = SessionStore(session_key=self.store.session_key, - user_agent='Python/3.3', ip='8.8.8.8') - store2.load() - self.assertEqual(store2.user_agent, 'Python/3.3') - self.assertEqual(store2.ip, '8.8.8.8') - self.assertEqual(store2.user_id, 1) - self.assertEqual(store2.modified, True) - - def test_duplicate_create(self): - s1 = SessionStore(session_key='DUPLICATE', user_agent='Python/2.7', ip='127.0.0.1') - s1.create() - s2 = SessionStore(session_key='DUPLICATE', user_agent='Python/2.7', ip='127.0.0.1') - s2.create() - self.assertNotEqual(s1.session_key, s2.session_key) - - s3 = SessionStore(session_key=s1.session_key, user_agent='Python/2.7', ip='127.0.0.1') - with self.assertRaises(CreateError): - s3.save(must_create=True) - - def test_delete(self): - # not persisted, should just return - self.store.delete() - - # create, then delete - self.store.create() - session_key = self.store.session_key - self.store.delete() - - # non-existing sessions, should not raise - self.store.delete() - self.store.delete(session_key) - - def test_clear(self): - """ - Clearing the session should clear all non-browser information - """ - self.store[auth.SESSION_KEY] = 1 - self.store.clear() - self.store.save() - - session = Session.objects.get(pk=self.store.session_key) - self.assertEqual(session.user_id, None) - - -class ModelTest(TestCase): - def test_get_decoded(self): - User.objects.create_user('bouke', '', 'secret', id=1) - store = SessionStore(user_agent='Python/2.7', ip='127.0.0.1') - store[auth.SESSION_KEY] = 1 - store['foo'] = 'bar' - store.save() - - session = Session.objects.get(pk=store.session_key) - self.assertEqual(session.get_decoded(), - {'foo': 'bar', auth.SESSION_KEY: 1}) - - def test_very_long_ua(self): - ua = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; ' \ - 'Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; ' \ - '.NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; ' \ - 'InfoPath.3; ms-office; MSOffice 14)' - store = SessionStore(user_agent=ua, ip='127.0.0.1') - store.save() - - session = Session.objects.get(pk=store.session_key) - self.assertEqual(session.user_agent, ua[:200]) - - -class ClientTest(TestCase): - def test_invalid_login(self): - client = Client() - self.assertFalse(client.login()) - - def test_restore_session(self): - store = SessionStore(user_agent='Python/2.7', ip='127.0.0.1') - store['foo'] = 'bar' - store.save() - client = Client() - client.cookies[settings.SESSION_COOKIE_NAME] = store.session_key - User.objects.create_user('bouke', '', 'secret') - assert client.login(username='bouke', password='secret') - self.assertEqual(client.session['foo'], 'bar') - - def test_login_logout(self): - client = Client() - User.objects.create_user('bouke', '', 'secret') - assert client.login(username='bouke', password='secret') - assert settings.SESSION_COOKIE_NAME in client.cookies - - client.logout() - assert settings.SESSION_COOKIE_NAME not in client.cookies - - # should not raise - client.logout() - - @patch('django.contrib.auth.signals.user_logged_in.send') - def test_login_signal(self, mock_user_logged_in): - client = Client() - User.objects.create_user('bouke', '', 'secret') - assert client.login(username='bouke', password='secret') - assert mock_user_logged_in.called - request = mock_user_logged_in.call_args[1]['request'] - assert getattr(request, 'user', None) is not None - - @override_settings(INSTALLED_APPS=()) - def test_no_session(self): - self.assertIsNone(Client().session) - - class LocationTemplateFilterTest(TestCase): @override_settings(GEOIP_PATH=None) def test_no_location(self): @@ -769,36 +469,3 @@ def test_windows81_only(self): def test_windows_only(self): self.assertEqual("Windows", device("Windows not a real browser/10.3")) - - -class ClearsessionsCommandTest(TestCase): - def test_can_call(self): - Session.objects.create(expire_date=now() - timedelta(days=1), - ip='127.0.0.1') - call_command('clearsessions') - self.assertEqual(Session.objects.count(), 0) - - -class MigratesessionsCommandTest(TransactionTestCase): - @modify_settings(INSTALLED_APPS={'append': 'django.contrib.sessions'}) - def test_migrate_from_login(self): - from django.contrib.sessions.backends.db import ( - SessionStore as DjangoSessionStore, - ) - from django.contrib.sessions.models import Session as DjangoSession - try: - call_command('migrate', 'sessions') - call_command('clearsessions') - user = User.objects.create_user('bouke', '', 'secret') - session = DjangoSessionStore() - session['_auth_user_id'] = user.id - session.save() - self.assertEqual(Session.objects.count(), 0) - self.assertEqual(DjangoSession.objects.count(), 1) - call_command('migratesessions') - new_sessions = list(Session.objects.all()) - self.assertEqual(len(new_sessions), 1) - self.assertEqual(new_sessions[0].user, user) - self.assertEqual(new_sessions[0].ip, '127.0.0.1') - finally: - call_command('migrate', 'sessions', 'zero') diff --git a/tests/test_views.py b/tests/test_views.py new file mode 100644 index 0000000..53435f5 --- /dev/null +++ b/tests/test_views.py @@ -0,0 +1,51 @@ +from datetime import timedelta + +from django.conf import settings +from django.contrib.auth.models import User +from django.test import TestCase +from django.urls import reverse +from django.utils.timezone import now + +from .utils import Client + + +class ViewsTest(TestCase): + client_class = Client + + def setUp(self): + self.user = User.objects.create_user('bouke', '', 'secret') + assert self.client.login(username='bouke', password='secret') + + def test_list(self): + self.user.session_set.create(session_key='ABC123', ip='127.0.0.1', + expire_date=now() + timedelta(days=1), + user_agent='Firefox') + with self.assertWarnsRegex(UserWarning, r"The address 127\.0\.0\.1 is not in the database"): + response = self.client.get(reverse('user_sessions:session_list')) + self.assertContains(response, 'Active Sessions') + self.assertContains(response, 'Firefox') + self.assertNotContains(response, 'ABC123') + + def test_delete(self): + session_key = self.client.cookies[settings.SESSION_COOKIE_NAME].value + response = self.client.post(reverse('user_sessions:session_delete', + args=[session_key])) + self.assertRedirects(response, '/') + + def test_delete_all_other(self): + self.user.session_set.create(ip='127.0.0.1', expire_date=now() + timedelta(days=1)) + self.assertEqual(self.user.session_set.count(), 2) + response = self.client.post(reverse('user_sessions:session_delete_other')) + with self.assertWarnsRegex(UserWarning, r"The address 127\.0\.0\.1 is not in the database"): + self.assertRedirects(response, reverse('user_sessions:session_list')) + self.assertEqual(self.user.session_set.count(), 1) + + def test_delete_some_other(self): + other = self.user.session_set.create(session_key='OTHER', ip='127.0.0.1', + expire_date=now() + timedelta(days=1)) + self.assertEqual(self.user.session_set.count(), 2) + response = self.client.post(reverse('user_sessions:session_delete', + args=[other.session_key])) + with self.assertWarnsRegex(UserWarning, r"The address 127\.0\.0\.1 is not in the database"): + self.assertRedirects(response, reverse('user_sessions:session_list')) + self.assertEqual(self.user.session_set.count(), 1)