async def test_fractional_backoff_applied_when_token_expiring(self): token_validity_seconds = 5 * 60 expiring_token = generate_token_with_custom_expiry( token_validity_seconds) refresher = MagicMock(side_effect=[ create_access_token(expiring_token), create_access_token(expiring_token) ]) credential = CommunicationTokenCredential(expiring_token, token_refresher=refresher, proactive_refresh=True) next_milestone = token_validity_seconds / 2 assert credential._timer.interval == next_milestone async with credential: with patch(user_credential_async.__name__ + '.' + get_current_utc_as_int.__name__, return_value=(get_current_utc_as_int() + next_milestone)): await credential.get_token() assert refresher.call_count == 1 next_milestone = next_milestone / 2 assert credential._timer.interval == next_milestone
async def test_proactive_refresher_keeps_scheduling_again(self): refresh_minutes = 10 token_validity_minutes = 60 expired_token = generate_token_with_custom_expiry(-5 * 60) skip_to_timestamp = get_current_utc_as_int() + ( token_validity_minutes - refresh_minutes) * 60 + 1 first_refreshed_token = create_access_token( generate_token_with_custom_expiry(token_validity_minutes * 60)) last_refreshed_token = create_access_token( generate_token_with_custom_expiry(2 * token_validity_minutes * 60)) refresher = MagicMock(side_effect=[ self.get_completed_future(first_refreshed_token), self.get_completed_future(last_refreshed_token) ]) credential = CommunicationTokenCredential(expired_token, token_refresher=refresher, proactive_refresh=True) async with credential: access_token = await credential.get_token() with patch(user_credential_async.__name__ + '.' + get_current_utc_as_int.__name__, return_value=skip_to_timestamp): access_token = await credential.get_token() assert refresher.call_count == 2 assert access_token.token == last_refreshed_token.token # check that next refresh is always scheduled assert credential._timer is not None
async def test_proactive_refresher_should_be_called_after_specified_time( self): refresh_minutes = 10 token_validity_minutes = 60 start_timestamp = get_current_utc_as_int() skip_to_timestamp = start_timestamp + \ (token_validity_minutes - refresh_minutes + 5) * 60 initial_token = generate_token_with_custom_expiry( token_validity_minutes * 60) refreshed_token = generate_token_with_custom_expiry( 2 * token_validity_minutes * 60) refresher = MagicMock(return_value=self.get_completed_future( create_access_token(refreshed_token))) with patch(user_credential_async.__name__ + '.' + get_current_utc_as_int.__name__, return_value=skip_to_timestamp): credential = CommunicationTokenCredential( initial_token, token_refresher=refresher, proactive_refresh=True) async with credential: access_token = await credential.get_token() assert refresher.call_count == 1 assert access_token.token == refreshed_token # check that next refresh is always scheduled assert credential._timer is not None
def test_communicationtokencredential_raises_if_refresher_returns_expired_token(self): refresher = MagicMock( return_value=create_access_token(self.expired_token)) credential = CommunicationTokenCredential(self.expired_token, token_refresher=refresher) with self.assertRaises(ValueError): credential.get_token() self.assertEqual(refresher.call_count, 1)
def test_communicationtokencredential_token_expired_refresh_called(self): refresher = MagicMock( return_value=create_access_token(self.sample_token)) credential = CommunicationTokenCredential(self.expired_token, token_refresher=refresher) access_token = credential.get_token() refresher.assert_called_once() self.assertEqual(access_token.token, self.sample_token)
def test_uses_initial_token_as_expected(self): refresher = MagicMock( return_value=create_access_token(self.expired_token)) credential = CommunicationTokenCredential( self.sample_token, token_refresher=refresher, proactive_refresh=True) access_token = credential.get_token() self.assertEqual(refresher.call_count, 0) self.assertEqual(access_token.token, self.sample_token)
def test_exit_cancels_timer(self): refreshed_token = create_access_token( generate_token_with_custom_expiry(30 * 60)) refresher = MagicMock(return_value=refreshed_token) credential = CommunicationTokenCredential( self.expired_token,token_refresher=refresher, proactive_refresh=True) credential.get_token() credential.close() assert credential._timer is None
async def test_raises_if_refresher_returns_expired_token(self): expired_token = generate_token_with_custom_expiry(-(10 * 60)) refresher = MagicMock(return_value=self.get_completed_future( create_access_token(expired_token))) credential = CommunicationTokenCredential(expired_token, token_refresher=refresher) with self.assertRaises(ValueError): await credential.get_token() assert refresher.call_count == 1
async def test_exit_cancels_timer(self): refreshed_token = create_access_token( generate_token_with_custom_expiry(30 * 60)) refresher = MagicMock(return_value=refreshed_token) expired_token = generate_token_with_custom_expiry(-10 * 60) credential = CommunicationTokenCredential(expired_token, token_refresher=refresher, proactive_refresh=True) async with credential: assert credential._timer is not None assert refresher.call_count == 0 assert credential._timer is not None
def test_refresher_should_not_be_called_when_token_still_valid(self): generated_token = generate_token_with_custom_expiry(15 * 60) new_token = generate_token_with_custom_expiry(10 * 60) refresher = MagicMock(return_value=create_access_token(new_token)) credential = CommunicationTokenCredential( generated_token, token_refresher=refresher, proactive_refresh=False) for _ in range(10): access_token = credential.get_token() refresher.assert_not_called() assert generated_token == access_token.token
def test_exit_enter_scenario_throws_exception(self): refreshed_token = create_access_token( generate_token_with_custom_expiry(30 * 60)) refresher = MagicMock(return_value=refreshed_token) credential = CommunicationTokenCredential( self.expired_token,token_refresher=refresher, proactive_refresh=True) credential.get_token() credential.close() assert credential._timer is None with pytest.raises(RuntimeError) as err: credential.get_token() assert str(err.value) == "An instance of CommunicationTokenCredential cannot be reused once it has been closed."
async def test_refresher_should_not_be_called_before_expiring_time(self): initial_token = generate_token_with_custom_expiry(15 * 60) refreshed_token = generate_token_with_custom_expiry(10 * 60) refresher = MagicMock( return_value=create_access_token(refreshed_token)) credential = CommunicationTokenCredential(initial_token, token_refresher=refresher, proactive_refresh=True) access_token = await credential.get_token() refresher.assert_not_called() assert initial_token == access_token.token
async def test_refresher_should_be_called_immediately_with_expired_token( self): refreshed_token = generate_token_with_custom_expiry(10 * 60) refresher = MagicMock(return_value=self.get_completed_future( create_access_token(refreshed_token))) expired_token = generate_token_with_custom_expiry(-(5 * 60)) credential = CommunicationTokenCredential(expired_token, token_refresher=refresher) access_token = await credential.get_token() refresher.assert_called_once() assert refreshed_token == access_token.token
def test_communicationtokencredential_token_expired_refresh_called_asnecessary(self): refresher = MagicMock(return_value=create_access_token(self.expired_token))