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))