@@ -1648,3 +1648,51 @@ def test_schema_cache_startup_load_with_in_db_config(defaultenv, metapostgrest):
1648
1648
response = metapostgrest .session .post ("/rpc/reset_db_schemas_config" )
1649
1649
assert response .text == ""
1650
1650
assert response .status_code == 204
1651
+
1652
+
1653
+ def test_jwt_cache_purges_expired_entries (defaultenv ):
1654
+ "test expired cache entries are purged on cache miss"
1655
+
1656
+ # The verification of actual cache size reduction is done locally
1657
+ # This test is written for code coverage of purgeExpired function
1658
+
1659
+ relativeSeconds = lambda sec : int (
1660
+ (datetime .now (timezone .utc ) + timedelta (seconds = sec )).timestamp ()
1661
+ )
1662
+
1663
+ headers = lambda sec : jwtauthheader (
1664
+ {"role" : "postgrest_test_author" , "exp" : relativeSeconds (sec )},
1665
+ SECRET ,
1666
+ )
1667
+
1668
+ env = {
1669
+ ** defaultenv ,
1670
+ "PGRST_JWT_CACHE_MAX_LIFETIME" : "86400" ,
1671
+ "PGRST_JWT_SECRET" : SECRET ,
1672
+ "PGRST_DB_CONFIG" : "false" ,
1673
+ }
1674
+
1675
+ with run (env = env ) as postgrest :
1676
+
1677
+ # Generate two unique JWT tokens
1678
+ # The 1 second sleep is needed for it generate a unique token
1679
+ hdrs1 = headers (5 )
1680
+ postgrest .session .get ("/authors_only" , headers = hdrs1 )
1681
+
1682
+ time .sleep (1 )
1683
+
1684
+ hdrs2 = headers (5 )
1685
+ postgrest .session .get ("/authors_only" , headers = hdrs2 )
1686
+
1687
+ # Wait 5 seconds for the tokens to expire
1688
+ time .sleep (5 )
1689
+
1690
+ hdrs3 = headers (5 )
1691
+
1692
+ # Make another request which should cause a cache miss and so
1693
+ # the purgeExpired function will be triggered.
1694
+ #
1695
+ # This should remove the 2 expired tokens but adds another to cache
1696
+ response = postgrest .session .get ("/authors_only" , headers = hdrs3 )
1697
+
1698
+ assert response .status_code == 200
0 commit comments