1+ from datetime import timedelta
2+
13import pytest
24from django .contrib .auth import get_user_model
35from django .core .exceptions import ImproperlyConfigured , ValidationError
@@ -294,31 +296,66 @@ def test_str(self):
294296class TestClearExpired (BaseTestModels ):
295297 def setUp (self ):
296298 super ().setUp ()
297- # Insert two tokens on database.
299+ # Insert many tokens, both expired and not, and grants.
300+ self .num_tokens = 100
301+ now = timezone .now ()
302+ earlier = now - timedelta (seconds = 100 )
303+ later = now + timedelta (seconds = 100 )
298304 app = Application .objects .create (
299305 name = "test_app" ,
300306 redirect_uris = "http://localhost http://example.com http://example.org" ,
301307 user = self .user ,
302308 client_type = Application .CLIENT_CONFIDENTIAL ,
303309 authorization_grant_type = Application .GRANT_AUTHORIZATION_CODE ,
304310 )
305- AccessToken .objects .create (
306- token = "555" ,
307- expires = timezone .now (),
308- scope = 2 ,
309- application = app ,
310- user = self .user ,
311- created = timezone .now (),
312- updated = timezone .now (),
311+ # make 200 access tokens, half current and half expired.
312+ expired_access_tokens = AccessToken .objects .bulk_create (
313+ AccessToken (token = "expired AccessToken {}" .format (i ), expires = earlier )
314+ for i in range (self .num_tokens )
313315 )
314- AccessToken .objects .create (
315- token = "666" ,
316- expires = timezone .now (),
317- scope = 2 ,
318- application = app ,
319- user = self .user ,
320- created = timezone .now (),
321- updated = timezone .now (),
316+ current_access_tokens = AccessToken .objects .bulk_create (
317+ AccessToken (token = f"current AccessToken { i } " , expires = later ) for i in range (self .num_tokens )
318+ )
319+ # Give the first half of the access tokens a refresh token,
320+ # alternating between current and expired ones.
321+ RefreshToken .objects .bulk_create (
322+ RefreshToken (
323+ token = f"expired AT's refresh token { i } " ,
324+ application = app ,
325+ access_token = expired_access_tokens [i ].pk ,
326+ user = self .user ,
327+ )
328+ for i in range (0 , len (expired_access_tokens ) // 2 , 2 )
329+ )
330+ RefreshToken .objects .bulk_create (
331+ RefreshToken (
332+ token = f"current AT's refresh token { i } " ,
333+ application = app ,
334+ access_token = current_access_tokens [i ].pk ,
335+ user = self .user ,
336+ )
337+ for i in range (1 , len (current_access_tokens ) // 2 , 2 )
338+ )
339+ # Make some grants, half of which are expired.
340+ Grant .objects .bulk_create (
341+ Grant (
342+ user = self .user ,
343+ code = f"old grant code { i } " ,
344+ application = app ,
345+ expires = earlier ,
346+ redirect_uri = "https://localhost/redirect" ,
347+ )
348+ for i in range (self .num_tokens )
349+ )
350+ Grant .objects .bulk_create (
351+ Grant (
352+ user = self .user ,
353+ code = f"new grant code { i } " ,
354+ application = app ,
355+ expires = later ,
356+ redirect_uri = "https://localhost/redirect" ,
357+ )
358+ for i in range (self .num_tokens )
322359 )
323360
324361 def test_clear_expired_tokens (self ):
@@ -333,15 +370,21 @@ def test_clear_expired_tokens_incorect_timetype(self):
333370 assert result == "ImproperlyConfigured"
334371
335372 def test_clear_expired_tokens_with_tokens (self ):
336- self .client .login (username = "test_user" , password = "123456" )
337- self .oauth2_settings .REFRESH_TOKEN_EXPIRE_SECONDS = 0
338- ttokens = AccessToken .objects .count ()
339- expiredt = AccessToken .objects .filter (expires__lte = timezone .now ()).count ()
340- assert ttokens == 2
341- assert expiredt == 2
373+ self .oauth2_settings .CLEAR_EXPIRED_TOKENS_BATCH_SIZE = 10
374+ self .oauth2_settings .CLEAR_EXPIRED_TOKENS_BATCH_INTERVAL = 0.0
375+ at_count = AccessToken .objects .count ()
376+ assert at_count == 2 * self .num_tokens , f"{ 2 * self .num_tokens } access tokens should exist."
377+ rt_count = RefreshToken .objects .count ()
378+ assert rt_count == self .num_tokens // 2 , f"{ self .num_tokens // 2 } refresh tokens should exist."
379+ gt_count = Grant .objects .count ()
380+ assert gt_count == self .num_tokens * 2 , f"{ self .num_tokens * 2 } grants should exist."
342381 clear_expired ()
343- expiredt = AccessToken .objects .filter (expires__lte = timezone .now ()).count ()
344- assert expiredt == 0
382+ at_count = AccessToken .objects .count ()
383+ assert at_count == self .num_tokens , "Half the access tokens should not have been deleted."
384+ rt_count = RefreshToken .objects .count ()
385+ assert rt_count == self .num_tokens // 2 , "Half of the refresh tokens should have been deleted."
386+ gt_count = Grant .objects .count ()
387+ assert gt_count == self .num_tokens , "Half the grants should have been deleted."
345388
346389
347390@pytest .mark .django_db
0 commit comments