Skip to content

Commit

Permalink
changed the tests, integrated idle and old working code back in
Browse files Browse the repository at this point in the history
removed offline users from list of online users, which wasn't there before and might have caused the cache overflow. Online, offline and idle tests have been rewritten
  • Loading branch information
Maria Mafalda Fernando committed May 9, 2019
1 parent 8aaa8f4 commit d15ccd0
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 34 deletions.
58 changes: 34 additions & 24 deletions portal/middleware/online_status/status.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
from django.core.cache import cache
from django.conf import settings

TIME_OFFLINE = getattr(settings, "USERS_ONLINE__TIME_OFFLINE", 10)
TIME_IDLE = getattr(settings, "USERS_ONLINE__TIME_IDLE", 60)
TIME_OFFLINE = getattr(settings, "USERS_ONLINE__TIME_OFFLINE", 2 * 60)

CACHE_PREFIX_USER = (
getattr(settings, "USERS_ONLINE__CACHE_PREFIX_USER", "online_user") + "_%d"
Expand All @@ -28,6 +29,9 @@ def __init__(self, request):
self.ip = request.META["REMOTE_ADDR"]
self.session = request.session.session_key

def set_idle(self):
self.status = 0

def set_active(self, request):
self.status = 1
self.seen = datetime.now()
Expand Down Expand Up @@ -61,34 +65,40 @@ def refresh_user(request):

def refresh_users_list(request, **kwargs):
"""Updates online users list and their statuses"""

updated = kwargs.pop("updated", None)
online_users = cache.get(CACHE_USERS)
if not online_users:
online_users = []
online_users = []

updated_found = set_offline_users(request, online_users, updated)
for online_status in cache.get(CACHE_USERS, []):
seconds = (datetime.now() - online_status.seen).seconds

if not updated_found and updated.is_authenticated():
online_users.append(updated)
cache.set(CACHE_USERS, online_users, TIME_OFFLINE)
# 'updated' will be added into `online_users` later
if not online_status.user == updated.user:
is_offline = set_user_idle_or_offline(online_status, seconds)
if not is_offline:
online_users.append(online_status)

update_online_users(updated, online_users)

def set_offline_users(request, online_users, updated):
updated_found = False
for obj in online_users:
seconds = (datetime.now() - obj.seen).seconds
if seconds > TIME_OFFLINE:
online_users.remove(obj)
cache.delete(CACHE_PREFIX_USER % obj.user.pk)
if updated_user_is_authenticated(obj, updated):
obj.set_active(request)
obj.seen = datetime.now()
updated_found = True

return updated_found
cache.set(CACHE_USERS, online_users, TIME_OFFLINE)


def updated_user_is_authenticated(obj, updated):
if obj.user == updated.user and updated.is_authenticated():
def set_user_idle_or_offline(online_status, seconds):
# delete expired
if seconds > TIME_OFFLINE:
cache.delete(CACHE_PREFIX_USER % online_status.user.pk)
return True
return False
elif seconds > TIME_IDLE:
# default value will be used if the second cache is expired
user_status = cache.get(
CACHE_PREFIX_USER % online_status.user.pk, online_status
)
online_status.set_idle()
user_status.set_idle()
cache.set(CACHE_PREFIX_USER % online_status.user.pk, user_status, TIME_OFFLINE)
return False


def update_online_users(updated, online_users):
if updated.user.is_authenticated:
online_users.append(updated)
37 changes: 27 additions & 10 deletions portal/tests/test_online_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,19 @@
from django.core.cache import cache
from django.core.urlresolvers import reverse
from django.test import TestCase
from django.test.utils import override_settings

from portal.middleware.online_status import status

status.TIME_OFFLINE = 3
status.TIME_IDLE = 1
status.ONLY_LOGGED_USERS = True

# override settings so we don't have to wait so long during tests
@override_settings(USERS_ONLINE__TIME_OFFLINE=6, USERS_ONLINE__ONLY_LOGGED_USERS=True)
class TestOnlineStatus(TestCase):
def setUp(self):
self.user1 = User.objects.get_or_create(username="test1")[0]
self.user2 = User.objects.get_or_create(username="test2")[0]

def login_as(self, user):
password = user.password
if not password:
Expand All @@ -58,20 +63,17 @@ def login_as(self, user):
user.save()
self.client.login(username=user.username, password=password)

def setUp(self):
self.user1 = User.objects.get_or_create(username="test1")[0]
self.user2 = User.objects.get_or_create(username="test2")[0]

def list_len(self, length):
users = cache.get(status.CACHE_USERS)
self.assertEqual(len(users), length)

def setup_conditions(self):
def base_setup(self):
cache.clear()
self.client.get(reverse("dashboard"))
useronline = cache.get(status.CACHE_PREFIX_USER % self.user1.pk)
self.assertEqual(useronline, None)

# Log user1 in, assert if online
self.login_as(self.user1)
self.client.get(reverse("dashboard"))
useronline = cache.get(status.CACHE_PREFIX_USER % self.user1.pk)
Expand All @@ -83,21 +85,36 @@ def setup_conditions(self):
self.client.logout()

def test_user_online(self):
self.setup_conditions()
self.base_setup()

# Log user2 in, assert if online
self.login_as(self.user2)

self.client.get(reverse("dashboard"))
useronline = cache.get(status.CACHE_PREFIX_USER % self.user2.pk)
self.assertEqual(useronline.user, self.user2)
self.assertEqual(useronline.status, 1)

self.list_len(2)

def test_user_idle(self):
self.base_setup()

# Check idle
sleep(status.TIME_IDLE + 1)
self.client.get(reverse("dashboard"))
useronline = cache.get(status.CACHE_PREFIX_USER % self.user1.pk)
self.assertEqual(useronline.user, self.user1)
self.assertEqual(useronline.status, 0)

self.list_len(1)

def test_user_offline(self):
self.setup_conditions()
self.base_setup()

# Check offline
sleep(status.TIME_OFFLINE + 1)
self.client.get(reverse("dashboard"))
useronline = cache.get(status.CACHE_PREFIX_USER % self.user1.pk)
self.assertEqual(useronline, None)

self.list_len(0)

0 comments on commit d15ccd0

Please sign in to comment.