//Since this test performs a large number of operations it should not be rerun on other clouds.
        private async Task RunOnBehalfOfTestWithTokenCacheAsync(LabResponse labResponse)
        {
            LabUser user = labResponse.User;
            string  oboHost;
            string  secret;
            string  authority;
            string  publicClientID;
            string  confidentialClientID;

            string[] oboScope;

            oboHost              = PublicCloudHost;
            secret               = _keyVault.GetSecret(TestConstants.MsalOBOKeyVaultUri).Value;
            authority            = TestConstants.AuthorityOrganizationsTenant;
            publicClientID       = PublicCloudPublicClientIDOBO;
            confidentialClientID = PublicCloudConfidentialClientIDOBO;
            oboScope             = s_publicCloudOBOServiceScope;

            //TODO: acquire scenario specific client ids from the lab response

            SecureString securePassword = new NetworkCredential("", user.GetOrFetchPassword()).SecurePassword;
            var          factory        = new HttpSnifferClientFactory();

            var msalPublicClient = PublicClientApplicationBuilder.Create(publicClientID)
                                   .WithAuthority(authority)
                                   .WithRedirectUri(TestConstants.RedirectUri)
                                   .WithTestLogging()
                                   .WithHttpClientFactory(factory)
                                   .Build();

            var builder = msalPublicClient.AcquireTokenByUsernamePassword(oboScope, user.Upn, securePassword);

            builder.WithAuthority(authority);

            var authResult = await builder.ExecuteAsync().ConfigureAwait(false);

            var confidentialApp = ConfidentialClientApplicationBuilder
                                  .Create(confidentialClientID)
                                  .WithAuthority(new Uri(oboHost + authResult.TenantId), true)
                                  .WithClientSecret(secret)
                                  .WithTestLogging()
                                  .BuildConcrete();

            var userCacheRecorder = confidentialApp.UserTokenCache.RecordAccess();

            UserAssertion userAssertion = new UserAssertion(authResult.AccessToken);

            string atHash = userAssertion.AssertionHash;

            authResult = await confidentialApp.AcquireTokenOnBehalfOf(s_scopes, userAssertion)
                         .ExecuteAsync(CancellationToken.None)
                         .ConfigureAwait(false);

            MsalAssert.AssertAuthResult(authResult, user);
            Assert.AreEqual(atHash, userCacheRecorder.LastAfterAccessNotificationArgs.SuggestedCacheKey);

            //Run OBO again. Should get token from cache
            authResult = await confidentialApp.AcquireTokenOnBehalfOf(s_scopes, userAssertion)
                         .ExecuteAsync(CancellationToken.None)
                         .ConfigureAwait(false);


            Assert.IsNotNull(authResult);
            Assert.IsNotNull(authResult.AccessToken);
            Assert.IsNotNull(authResult.IdToken);
            Assert.IsTrue(!userCacheRecorder.LastAfterAccessNotificationArgs.IsApplicationCache);
            Assert.IsTrue(userCacheRecorder.LastAfterAccessNotificationArgs.HasTokens);
            Assert.AreEqual(atHash, userCacheRecorder.LastAfterAccessNotificationArgs.SuggestedCacheKey);
            Assert.AreEqual(TokenSource.Cache, authResult.AuthenticationResultMetadata.TokenSource);

            //Expire access tokens
            TokenCacheHelper.ExpireAccessTokens(confidentialApp.UserTokenCacheInternal);

            //Run OBO again. Should do token refresh since the AT is expired
            authResult = await confidentialApp.AcquireTokenOnBehalfOf(s_scopes, userAssertion)
                         .ExecuteAsync(CancellationToken.None)
                         .ConfigureAwait(false);

            Assert.IsNotNull(authResult);
            Assert.IsNotNull(authResult.AccessToken);
            Assert.IsNotNull(authResult.IdToken);
            Assert.IsTrue(!userCacheRecorder.LastAfterAccessNotificationArgs.IsApplicationCache);
            Assert.IsTrue(userCacheRecorder.LastAfterAccessNotificationArgs.HasTokens);
            Assert.AreEqual(atHash, userCacheRecorder.LastAfterAccessNotificationArgs.SuggestedCacheKey);
            Assert.AreEqual(TokenSource.IdentityProvider, authResult.AuthenticationResultMetadata.TokenSource);
            AssertLastHttpContent("refresh_token");

            //creating second app with no refresh tokens
            var atItems          = confidentialApp.UserTokenCacheInternal.Accessor.GetAllAccessTokens();
            var confidentialApp2 = ConfidentialClientApplicationBuilder
                                   .Create(confidentialClientID)
                                   .WithAuthority(new Uri(oboHost + authResult.TenantId), true)
                                   .WithClientSecret(secret)
                                   .WithTestLogging()
                                   .WithHttpClientFactory(factory)
                                   .BuildConcrete();

            TokenCacheHelper.ExpireAndSaveAccessToken(confidentialApp2.UserTokenCacheInternal, atItems.FirstOrDefault());

            //Should perform OBO flow since the access token is expired and the refresh token does not exist
            authResult = await confidentialApp2.AcquireTokenOnBehalfOf(s_scopes, userAssertion)
                         .ExecuteAsync(CancellationToken.None)
                         .ConfigureAwait(false);

            Assert.IsNotNull(authResult);
            Assert.IsNotNull(authResult.AccessToken);
            Assert.IsNotNull(authResult.IdToken);
            Assert.IsTrue(!userCacheRecorder.LastAfterAccessNotificationArgs.IsApplicationCache);
            Assert.IsTrue(userCacheRecorder.LastAfterAccessNotificationArgs.HasTokens);
            Assert.AreEqual(atHash, userCacheRecorder.LastAfterAccessNotificationArgs.SuggestedCacheKey);
            Assert.AreEqual(TokenSource.IdentityProvider, authResult.AuthenticationResultMetadata.TokenSource);
            AssertLastHttpContent("on_behalf_of");

            TokenCacheHelper.ExpireAccessTokens(confidentialApp2.UserTokenCacheInternal);
            TokenCacheHelper.UpdateUserAssertions(confidentialApp2);

            //Should perform OBO flow since the access token and the refresh token contains the wrong user assertion hash
            authResult = await confidentialApp2.AcquireTokenOnBehalfOf(s_scopes, userAssertion)
                         .ExecuteAsync(CancellationToken.None)
                         .ConfigureAwait(false);

            Assert.IsNotNull(authResult);
            Assert.IsNotNull(authResult.AccessToken);
            Assert.IsNotNull(authResult.IdToken);
            Assert.IsTrue(!userCacheRecorder.LastAfterAccessNotificationArgs.IsApplicationCache);
            Assert.IsTrue(userCacheRecorder.LastAfterAccessNotificationArgs.HasTokens);
            Assert.AreEqual(atHash, userCacheRecorder.LastAfterAccessNotificationArgs.SuggestedCacheKey);
            Assert.AreEqual(TokenSource.IdentityProvider, authResult.AuthenticationResultMetadata.TokenSource);
            AssertLastHttpContent("on_behalf_of");
        }