public async Task ShouldRefreshAllRefreshableTokens() { using (var authDelegatingHandler = new AuthDelegatingHandler() { InnerHandler = _handler }) using (var httpClient = new HttpClient(authDelegatingHandler)) using (var memoryCache = new MemoryCache(new MemoryCacheOptions())) { var fakeClock = FakeClock.FromUtc(2019, 10, 10); var now = fakeClock.GetCurrentInstant(); var testTokenSetRepository = new TestTokenSetRepository(); //// Add test tokens // Valid tokens (shouldn't be refreshed) await testTokenSetRepository.AddOrUpdateTokenSet(new TokenSet("token0", "bearer0", 3600, new Uri("https://test-endpoint/api/"), "testOrgKey", "testRefreshToken", now, "0", "0")); await testTokenSetRepository.AddOrUpdateTokenSet(new TokenSet("token1", "bearer1", 3600, new Uri("https://test-endpoint/api/"), "testOrgKey", "testRefreshToken", now, "1", "1")); // Nearing expiry (should be refreshed) await testTokenSetRepository.AddOrUpdateTokenSet(new TokenSet("token2", "bearer2", 3600, new Uri("https://test-endpoint/api/"), "testOrgKey", "testRefreshToken", now.Minus(Duration.FromDays(18)), "2", "2")); // Expired (shouldn't be refreshed, as it will fail anyway) await testTokenSetRepository.AddOrUpdateTokenSet(new TokenSet("token3", "bearer3", 3600, new Uri("https://test-endpoint/api/"), "testOrgKey", "testRefreshToken", now.Minus(Duration.FromDays(30)), "3", "3")); var actionstepServiceConfigurationOptions = new ActionstepServiceConfigurationOptions("clientId", "clientSecret"); var actionstepService = new ActionstepService(new NullLogger <ActionstepService>(), httpClient, actionstepServiceConfigurationOptions, testTokenSetRepository, fakeClock, memoryCache); var config = new ConfigurationBuilder(); config.AddInMemoryCollection(new Dictionary <string, string>() { { "WCACoreSettings:PEXASettings:Environment", "Test" } }); var wcaCoreSettingsOptions = Options.Create(config.Build().Get <WCACoreSettings>()); var refreshTokens = new RefreshAllTokens(testTokenSetRepository, actionstepService, fakeClock); await refreshTokens.Run(null, new NullLogger <RefreshAllTokens>()); Assert.Equal("token0", testTokenSetRepository.TokenSets.Single(t => t.Id == "0").AccessToken); Assert.Equal("token1", testTokenSetRepository.TokenSets.Single(t => t.Id == "1").AccessToken); Assert.Equal("updatedAccessToken", testTokenSetRepository.TokenSets.Single(t => t.Id == "2").AccessToken); Assert.Equal("token3", testTokenSetRepository.TokenSets.Single(t => t.Id == "3").AccessToken); } }
public async void ShouldListActionstepParticipants() { using (var authDelegatingHandler = new AuthDelegatingHandler() { InnerHandler = _handler }) using (var httpClient = new HttpClient(authDelegatingHandler)) using (var memoryCache = new MemoryCache(new MemoryCacheOptions())) { var fakeClock = new FakeClock(Instant.FromUtc(2019, 05, 07, 2, 3)); var testTokenRepository = new TestTokenSetRepository(); var testTokenSet = GetTestTokenSet(); await testTokenRepository.AddOrUpdateTokenSet(testTokenSet); var options = new ActionstepServiceConfigurationOptions("clientId", "clientSecret"); var actionstepService = new ActionstepService(new NullLogger <ActionstepService>(), httpClient, options, testTokenRepository, fakeClock, memoryCache); var request = new ListParticipantsRequest { TokenSetQuery = new TokenSetQuery(testTokenSet.UserId, testTokenSet.OrgKey) }; var response = await actionstepService.Handle <ListParticipantsResponse>(request); var admin = response.Participants.SingleOrDefault(p => p.Id == 1); Assert.NotNull(admin); var expectedBirthTimestamp = new LocalDate(2000, 1, 1); var expectedDeathTimestamp = new LocalDate(2001, 1, 1); Assert.Equal(expectedBirthTimestamp, admin.BirthTimestamp); Assert.Equal(expectedDeathTimestamp, admin.DeathTimestamp); } }
public async void ShouldGetDataCollectionValues() { using (var authDelegatingHandler = new AuthDelegatingHandler() { InnerHandler = _handler }) using (var httpClient = new HttpClient(authDelegatingHandler)) using (var memoryCache = new MemoryCache(new MemoryCacheOptions())) { var fakeClock = new FakeClock(Instant.FromUtc(2019, 05, 07, 2, 3)); var testTokenRepository = new TestTokenSetRepository(); var testTokenSet = GetTestTokenSet(); await testTokenRepository.AddOrUpdateTokenSet(testTokenSet); var options = new ActionstepServiceConfigurationOptions("clientId", "clientSecret"); var actionstepService = new ActionstepService(new NullLogger <ActionstepService>(), httpClient, options, testTokenRepository, fakeClock, memoryCache); var dataCollectionRecordValuesRequest = new ListDataCollectionRecordValuesRequest(); dataCollectionRecordValuesRequest.ActionstepId = 7; dataCollectionRecordValuesRequest.TokenSetQuery = new TokenSetQuery(testTokenSet.UserId, testTokenSet.OrgKey); dataCollectionRecordValuesRequest.DataCollectionRecordNames.AddRange(new[] { "property", "convdet", "keydates" }); dataCollectionRecordValuesRequest.DataCollectionFieldNames.AddRange(new[] { "titleref", "lotno", "planno", "plantype", "smtdateonly", "smttime", "purprice" }); var response = await actionstepService.Handle <ListDataCollectionRecordValuesResponse>(dataCollectionRecordValuesRequest); Assert.Equal(6, response.DataCollectionRecordValues.Count); Assert.Equal("test-title-ref", response["property", "titleref"]); } }
public async Task ShouldGetActionWithMultipleMatterIds() { using (var authDelegatingHandler = new AuthDelegatingHandler() { InnerHandler = _handler }) using (var httpClient = new HttpClient(authDelegatingHandler)) using (var memoryCache = new MemoryCache(new MemoryCacheOptions())) { var fakeClock = new FakeClock(Instant.FromUtc(2019, 05, 07, 2, 3)); var testTokenRepository = new TestTokenSetRepository(); var testTokenSet = GetTestTokenSet(); await testTokenRepository.AddOrUpdateTokenSet(testTokenSet); var options = new ActionstepServiceConfigurationOptions("clientId", "clientSecret"); var actionstepService = new ActionstepService(new NullLogger <ActionstepService>(), httpClient, options, testTokenRepository, fakeClock, memoryCache); var listActionsRequest = new ListActionsRequest(); listActionsRequest.ActionstepIds.AddRange(new[] { 1, 7 }); listActionsRequest.TokenSetQuery = new TokenSetQuery(testTokenSet.UserId, testTokenSet.OrgKey); var response = await actionstepService.Handle <ListActionsResponse>(listActionsRequest); Assert.Equal(2, response.Actions.Count); Assert.True(response.Actions.Exists(a => a.Id == 1)); Assert.True(response.Actions.Exists(a => a.Id == 7)); } }
public async Task ShouldRetryRefreshingInvalidToken() { using (var authDelegatingHandler = new AuthDelegatingHandler() { InnerHandler = _handler }) using (var httpClient = new HttpClient(authDelegatingHandler)) using (var memoryCache = new MemoryCache(new MemoryCacheOptions())) { var tokenHandler = new TestTokenSetRepository(); var fakeClock = new FakeClock(Instant.FromUtc(2019, 05, 07, 2, 3)); var testTokenRepository = new TestTokenSetRepository(); var testTokenSet = GetTestTokenSet(isInvalid: true); await testTokenRepository.AddOrUpdateTokenSet(testTokenSet); var options = new ActionstepServiceConfigurationOptions("clientId", "clientSecret"); var actionstepService = new ActionstepService(new NullLogger <ActionstepService>(), httpClient, options, testTokenRepository, fakeClock, memoryCache); var response = await actionstepService.Handle <GetActionResponse>(new GetActionRequest { ActionId = 1, TokenSetQuery = new TokenSetQuery(testTokenSet.UserId, testTokenSet.OrgKey) }); // Should be called 3 times. First from this test method to arrange this test token, second from the handler to set the lock, and third time to unlock/update with refreshed data. Assert.Equal(3, testTokenRepository.AddOrUpdateTokenSetCount); } }
public async void ShouldGetActionWithMatterId() { using (var authDelegatingHandler = new AuthDelegatingHandler() { InnerHandler = _handler }) using (var httpClient = new HttpClient(authDelegatingHandler)) using (var memoryCache = new MemoryCache(new MemoryCacheOptions())) { var fakeClock = new FakeClock(Instant.FromUtc(2019, 05, 07, 2, 3)); var options = new ActionstepServiceConfigurationOptions("clientId", "clientSecret"); var tokenSetRepository = new TestTokenSetRepository(); var testTokenSet = GetTestTokenSet(); await tokenSetRepository.AddOrUpdateTokenSet(testTokenSet); var actionstepService = new ActionstepService(new NullLogger <ActionstepService>(), httpClient, options, tokenSetRepository, fakeClock, memoryCache); var response = await actionstepService.Handle <GetActionResponse>(new GetActionRequest { ActionId = 1, TokenSetQuery = new TokenSetQuery(testTokenSet.UserId, testTokenSet.OrgKey) }); Assert.Equal(1, response.Action.Id); Assert.Null(response.Action.IsBillableOverride); Assert.False(response.Action.IsDeleted); Assert.True(response.Action.IsFavorite); } }
public async Task CanDisconnectFromActionstepOrg() { var fakeClock = FakeClock.FromUtc(2019, 10, 10); var now = fakeClock.GetCurrentInstant(); var testTokenSetRepository = new TestTokenSetRepository(); // Add test token var testUser = new WCAUser() { Id = "0" }; const string orgKey = "testOrgKey"; await testTokenSetRepository.AddOrUpdateTokenSet(new TokenSet("token0", "bearer0", 3600, new Uri("https://test-endpoint/api/"), orgKey, "testRefreshToken", now, testUser.Id)); // Make sure the test item was added so we can be sure it was removed and not missing to begin with Assert.Single(testTokenSetRepository.TokenSets); IRequestHandler <DisconnectFromActionstepOrg.DisconnectFromActionstepOrgCommand> handlerUnderTest = new DisconnectFromActionstepOrg.Handler(new DisconnectFromActionstepOrg.ValidatorCollection(), testTokenSetRepository); await handlerUnderTest.Handle(new DisconnectFromActionstepOrg.DisconnectFromActionstepOrgCommand() { AuthenticatedUser = testUser, ActionstepOrgKey = orgKey }, new CancellationToken()); Assert.Empty(testTokenSetRepository.TokenSets); }
public async Task SecondTokenRefreshWaitsForFirst() { using (var authDelegatingHandler = new AuthDelegatingHandler() { InnerHandler = _handler }) using (var httpClient = new HttpClient(authDelegatingHandler)) using (var memoryCache = new MemoryCache(new MemoryCacheOptions())) { var tokenHandler = new TestTokenSetRepository(); var fakeClock = new FakeClock(Instant.FromUtc(2019, 05, 07, 2, 3)); var testTokenRepository = new TestTokenSetRepository(); var options = new ActionstepServiceConfigurationOptions("clientId", "clientSecret"); var actionstepService = new ActionstepService(new NullLogger <ActionstepService>(), httpClient, options, testTokenRepository, fakeClock, memoryCache); var now = fakeClock.GetCurrentInstant(); /// We're using the TokenType purely as a mechanism to talk to <see cref="TestTokenSetRepository"/>. /// This allows us to delay one refresh while queueing another to ensure the locking/retry works correctly /// with concurrent refresh requests. var tokenTypeTest1 = "bearer-test1"; var tokenTypeTest2 = "bearer-test2"; // First, store a locked expired token var tokenId = "locking test token"; var tokenSet1 = new TokenSet( "testAccessToken1", tokenTypeTest1, 3600, new Uri("https://api.uri/api/auto-increment/"), "testOrgKey", "testRefreshToken1", now.Minus(Duration.FromMinutes(120)), "testUser", tokenId); tokenSet1.LockForRefresh(now.Plus(Duration.FromMinutes(60))); var storedTokenSet1 = await testTokenRepository.AddOrUpdateTokenSet(tokenSet1); // Now we set up a second expired token with the same id. var tokenSet2 = new TokenSet( "testAccessToken2", tokenTypeTest2, 3600, new Uri("https://api.uri/api/auto-increment/"), "testOrgKey", "testRefreshToken2", now.Minus(Duration.FromMinutes(120)), "testUser", tokenId); // Try to refresh using the second token (which has the same tokenId). It should be blocked by the locked token1 from above. var tokenSet2RefreshTask = actionstepService.RefreshAccessTokenIfExpired(tokenSet2, forceRefresh: false); /// Delay to give the <see cref="RefreshAccessTokenIfExpired"/> a chance to await Task.Delay(50); // Now store a valid token of test type 1, this will unlock the token tokenSet1 = new TokenSet( "testAccessToken1", tokenTypeTest1, 3600, new Uri("https://api.uri/api/auto-increment/"), "testOrgKey", "testRefreshToken1", now, "testUser", tokenId); await testTokenRepository.AddOrUpdateTokenSet(tokenSet1); tokenSet2RefreshTask.Wait(); // The token from the refresh should be the one we put in the repository. Assert.Equal(tokenTypeTest1, tokenSet2RefreshTask.Result.TokenType); } }
public async Task ShouldCreatePEXAWorkspaceRequestFromActionstep() { var testUser = await _containerFixture.GetTestUser(); await _containerFixture.ExecuteScopeAsync(async serviceProvider => { using (var authDelegatingHandler = new AuthDelegatingHandler() { InnerHandler = _handler }) using (var httpClient = new HttpClient(authDelegatingHandler)) { var fakeClock = new FakeClock(new Instant()); var testTokenSetRepository = new TestTokenSetRepository(); await testTokenSetRepository.AddOrUpdateTokenSet(new TokenSet("accessToken", "bearer", 3600, new Uri("https://uri/api"), "testOrg", "refreshToken", fakeClock.GetCurrentInstant(), testUser.Id)); var options = new ActionstepServiceConfigurationOptions("clientId", "clientSecret"); var actionstepService = new ActionstepService(new NullLogger <ActionstepService>(), httpClient, options, testTokenSetRepository, fakeClock, new MemoryCache(new MemoryCacheOptions())); var mapper = serviceProvider.GetService <IMapper>(); var actionstepToWcaMapper = serviceProvider.GetService <IActionstepToWCAMapper>(); PrepareTestData(serviceProvider); var handler = new PEXAWorkspaceCreationRequestFromActionstepQueryHandler(actionstepService, mapper, actionstepToWcaMapper); var token = new CancellationToken(); var query = new PEXAWorkspaceCreationRequestFromActionstepQuery { AuthenticatedUser = testUser, MatterId = 1, ActionstepOrg = "testOrg" }; var pexaWorkspaceCreationResponse = await handler.Handle(query, token); Assert.Equal("1", pexaWorkspaceCreationResponse.CreatePexaWorkspaceCommand.PexaWorkspaceCreationRequest.SubscriberReference); Assert.Equal("Yes", pexaWorkspaceCreationResponse.CreatePexaWorkspaceCommand.PexaWorkspaceCreationRequest.FinancialSettlement); var config = new ConfigurationBuilder(); config.AddInMemoryCollection(new Dictionary <string, string>() { { "WCACoreSettings:PEXASettings:Environment", "Test" } }); var pexaService = new PEXAService(httpClient, config.Build()); var request = new WorkspaceCreationRequestCommand(pexaWorkspaceCreationResponse.CreatePexaWorkspaceCommand.PexaWorkspaceCreationRequest, "dummyToken"); var response = await pexaService.Handle <WorkspaceCreationResponse>(request, CancellationToken.None); Assert.Equal("PEXA190167645", response.WorkspaceId); Assert.Equal("In Preparation", response.WorkspaceStatus); var xmldiff = new XmlDiff(XmlDiffOptions.IgnoreChildOrder | XmlDiffOptions.IgnoreNamespaces | XmlDiffOptions.IgnorePrefixes); var expectedXml = EmbeddedResource.Read("ResponseData.create-workspace-result.xml"); var actualXml = _handler.RequestContent; var expectedReader = XElement.Parse(expectedXml).CreateReader(); var actualReader = XElement.Parse(actualXml).CreateReader(); using (var diffStringWriter = new StringWriter()) using (var diffWriter = XmlWriter.Create(diffStringWriter)) { var areXmlIdentical = xmldiff.Compare(expectedReader, actualReader, diffWriter); diffWriter.Flush(); foreach (var diffLine in diffStringWriter.ToString().Split(diffStringWriter.NewLine)) { _output.WriteLine(diffLine); } Assert.True(areXmlIdentical); } } }); }