@@ -53,6 +53,15 @@ def tearDown(self):
53
53
return super ().tearDown ()
54
54
55
55
56
+ class MockOauthlibCoreClass :
57
+ """
58
+ Mock oauthlib, used in test_token_view_status_equals_what_oauthlib_token_response_method_returns.
59
+ """
60
+
61
+ def create_token_response (self , _ ):
62
+ return "url" , {"headers_are_ignored" : True }, '{"Key": "Value"}' , 299
63
+
64
+
56
65
class TestDeviceFlow (DeviceFlowBaseTestCase ):
57
66
"""
58
67
The first 2 tests test the device flow in order
@@ -439,6 +448,43 @@ def test_token_view_returns_404_error_if_device_not_found(self):
439
448
# consumed by devices.
440
449
self .assertEqual (response .__getitem__ ("content-type" ), "application/json" )
441
450
451
+ @mock .patch ("oauth2_provider.views.mixins.OAuthLibMixin.get_oauthlib_core" , MockOauthlibCoreClass )
452
+ def test_token_view_status_equals_what_oauthlib_token_response_method_returns (self ):
453
+ """
454
+ Tests the use case where oauthlib create_token_response returns a status different
455
+ than 200.
456
+ """
457
+ device = DeviceModel (
458
+ client_id = "client_id" ,
459
+ device_code = "device_code" ,
460
+ user_code = "user_code" ,
461
+ scope = "scope" ,
462
+ expires = datetime .now () + timedelta (seconds = 60 ),
463
+ status = "authorized" ,
464
+ )
465
+ device .save ()
466
+
467
+ token_payload = {
468
+ "device_code" : "device_code" ,
469
+ "client_id" : "client_id" ,
470
+ "grant_type" : "urn:ietf:params:oauth:grant-type:device_code" ,
471
+ }
472
+
473
+ response = self .client .post (
474
+ "/o/token/" ,
475
+ data = urlencode (token_payload ),
476
+ content_type = "application/x-www-form-urlencoded" ,
477
+ )
478
+
479
+ self .assertEqual (response ["content-type" ], "application/json" )
480
+ self .assertContains (
481
+ response = response ,
482
+ status_code = 299 ,
483
+ text = '{"Key": "Value"}' ,
484
+ count = 1 ,
485
+ )
486
+ assert not response .has_header ("headers_are_ignored" )
487
+
442
488
@mock .patch (
443
489
"oauthlib.oauth2.rfc8628.endpoints.device_authorization.generate_token" ,
444
490
lambda : "abc" ,
@@ -644,3 +690,9 @@ def test_device_is_expired_method_sets_status_to_expired_if_deadline_passed(self
644
690
645
691
assert is_expired
646
692
assert device .status == device .EXPIRED
693
+
694
+ # calling again is_expired() should return true and not change the state
695
+ is_expired = device .is_expired ()
696
+
697
+ assert is_expired
698
+ assert device .status == device .EXPIRED
0 commit comments