Skip to content

Commit 18d1769

Browse files
committed
feat: add async tests
1 parent bf589cf commit 18d1769

1 file changed

Lines changed: 131 additions & 1 deletion

File tree

test/oauth2_test.py

Lines changed: 131 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,13 @@
1212

1313
from datetime import datetime, timedelta
1414
from unittest import IsolatedAsyncioTestCase
15-
from unittest.mock import patch
15+
16+
import unittest
17+
import pytest
18+
from unittest.mock import patch, MagicMock
19+
from openfga_sdk.credentials import CredentialConfiguration
20+
from openfga_sdk.oauth2 import OAuth2Client
21+
1622

1723
import urllib3
1824

@@ -494,3 +500,127 @@ async def test_get_authentication_add_scheme_and_path(self, mock_request):
494500
},
495501
)
496502
await rest_client.close()
503+
504+
class TestOAuth2ClientScopeHandling(unittest.TestCase):
505+
"""Test OAuth2Client scope serialization in synchronous context"""
506+
507+
def setUp(self):
508+
self.config = CredentialConfiguration(
509+
client_id="test_client_id",
510+
client_secret="test_client_secret",
511+
api_issuer="https://example.com",
512+
api_audience="test_audience"
513+
)
514+
self.oauth_client = OAuth2Client(self.config)
515+
516+
@patch('requests.post')
517+
def test_list_scopes_serialization(self, mock_post):
518+
"""Test that list scopes are serialized as space-delimited string"""
519+
# Setup mock response
520+
mock_response = MagicMock()
521+
mock_response.json.return_value = {"access_token": "test_token", "expires_in": 3600}
522+
mock_response.status_code = 200
523+
mock_post.return_value = mock_response
524+
525+
# Set list scopes
526+
self.config.scopes = ["read", "write", "admin"]
527+
528+
# Make token request
529+
self.oauth_client.request_token()
530+
531+
# Verify scope parameter was correctly formatted
532+
args, kwargs = mock_post.call_args
533+
self.assertIn('data', kwargs)
534+
self.assertIn('scope', kwargs['data'])
535+
self.assertEqual(kwargs['data']['scope'], "read write admin")
536+
537+
@patch('requests.post')
538+
def test_string_scope_serialization(self, mock_post):
539+
"""Test that string scope is used unchanged"""
540+
# Setup mock response
541+
mock_response = MagicMock()
542+
mock_response.json.return_value = {"access_token": "test_token", "expires_in": 3600}
543+
mock_response.status_code = 200
544+
mock_post.return_value = mock_response
545+
546+
# Set string scope
547+
self.config.scopes = "read write admin"
548+
549+
# Make token request
550+
self.oauth_client.request_token()
551+
552+
# Verify scope parameter was passed unchanged
553+
args, kwargs = mock_post.call_args
554+
self.assertIn('data', kwargs)
555+
self.assertIn('scope', kwargs['data'])
556+
self.assertEqual(kwargs['data']['scope'], "read write admin")
557+
558+
559+
class TestOAuth2ClientScopeHandlingAsync:
560+
"""Test OAuth2Client scope serialization in asynchronous context"""
561+
562+
@pytest.fixture
563+
def oauth_client(self):
564+
config = CredentialConfiguration(
565+
client_id="test_client_id",
566+
client_secret="test_client_secret",
567+
api_issuer="https://example.com",
568+
api_audience="test_audience"
569+
)
570+
return OAuth2Client(config)
571+
572+
@pytest.mark.asyncio
573+
async def test_list_scopes_serialization_async(self, oauth_client, monkeypatch):
574+
"""Test that list scopes are serialized as space-delimited string in async context"""
575+
# Mock the async HTTP response
576+
mock_response = MagicMock()
577+
mock_response.json = MagicMock(return_value={"access_token": "test_token", "expires_in": 3600})
578+
mock_response.status_code = 200
579+
580+
# Set up mock for the async HTTP client
581+
mock_client_session = MagicMock()
582+
mock_client_session.post = MagicMock(return_value=mock_response)
583+
mock_client_session.__aenter__ = MagicMock(return_value=mock_client_session)
584+
mock_client_session.__aexit__ = MagicMock(return_value=None)
585+
586+
monkeypatch.setattr('aiohttp.ClientSession', MagicMock(return_value=mock_client_session))
587+
588+
# Set list scopes
589+
oauth_client.configuration.scopes = ["read", "write", "admin"]
590+
591+
# Make async token request
592+
await oauth_client.request_token_async()
593+
594+
# Verify scope parameter was correctly formatted
595+
args, kwargs = mock_client_session.post.call_args
596+
self.assertIn('data', kwargs)
597+
self.assertIn('scope', kwargs['data'])
598+
self.assertEqual(kwargs['data']['scope'], "read write admin")
599+
600+
@pytest.mark.asyncio
601+
async def test_string_scope_serialization_async(self, oauth_client, monkeypatch):
602+
"""Test that string scope is used unchanged in async context"""
603+
# Mock the async HTTP response
604+
mock_response = MagicMock()
605+
mock_response.json = MagicMock(return_value={"access_token": "test_token", "expires_in": 3600})
606+
mock_response.status_code = 200
607+
608+
# Set up mock for the async HTTP client
609+
mock_client_session = MagicMock()
610+
mock_client_session.post = MagicMock(return_value=mock_response)
611+
mock_client_session.__aenter__ = MagicMock(return_value=mock_client_session)
612+
mock_client_session.__aexit__ = MagicMock(return_value=None)
613+
614+
monkeypatch.setattr('aiohttp.ClientSession', MagicMock(return_value=mock_client_session))
615+
616+
# Set string scope
617+
oauth_client.configuration.scopes = "read write admin"
618+
619+
# Make async token request
620+
await oauth_client.request_token_async()
621+
622+
# Verify scope parameter was passed unchanged
623+
args, kwargs = mock_client_session.post.call_args
624+
self.assertIn('data', kwargs)
625+
self.assertIn('scope', kwargs['data'])
626+
self.assertEqual(kwargs['data']['scope'], "read write admin")

0 commit comments

Comments
 (0)