internal static void SetupGetFeaturesRequestForCacheHit(this Mock <FakeHttpMessageHandler> mock, UnleashApiClientRequestHeaders requestHeaders, string etag) { mock .Setup(mh => mh.Send(It.Is(ApiRequest(HttpMethod.Get, "api/client/features", requestHeaders)))) .Returns(() => CacheHitResponse(etag)); }
internal async Task FetchToggles_WhenServerReturnsExpectedToggles_ReturnsValidResult( UnleashSettings settings, [Frozen] Mock <FakeHttpMessageHandler> httpMessageHandler, [Frozen] UnleashApiClientRequestHeaders requestHeaders, string etag ) { var jsonSerializerSettings = new NewtonsoftJsonSerializerSettings(); var jsonSerializer = new NewtonsoftJsonSerializer(jsonSerializerSettings); var expectedToggles = new ToggleCollection(); httpMessageHandler.SetupGetFeaturesRequestForSuccess(jsonSerializer, expectedToggles, requestHeaders); var httpClient = new HttpClient(httpMessageHandler.Object) { BaseAddress = settings.UnleashApi }; var apiClient = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders); var actualFetchTogglesResult = await apiClient.FetchToggles(etag, CancellationToken.None); var actualToggles = actualFetchTogglesResult.ToggleCollection; Assert.Equal(expectedToggles.Features, actualToggles.Features); Assert.True(actualFetchTogglesResult.HasChanged); Assert.NotEqual(etag, actualFetchTogglesResult.Etag); httpMessageHandler.VerifyAll(); }
internal async Task ExecuteAsync_WhenApiReturns200Ok_CompletesSuccessfully( [Frozen] UnleashSettings settings, [Frozen] Mock <FakeHttpMessageHandler> httpMessageHandler, [Frozen] Mock <IUnleashApiClientFactory> apiClientFactoryMock, [Frozen] UnleashApiClientRequestHeaders requestHeaders, [Frozen] MetricsBucket metricsBucket) { var jsonSerializerSettings = new NewtonsoftJsonSerializerSettings(); var jsonSerializer = new NewtonsoftJsonSerializer(jsonSerializerSettings); var threadSafeMetricsBucket = new ThreadSafeMetricsBucket(metricsBucket); var backgroundTask = new ClientMetricsBackgroundTask(apiClientFactoryMock.Object, settings, threadSafeMetricsBucket); httpMessageHandler.SetupPostSendMetricsRequestForSuccess(requestHeaders); var httpClient = new HttpClient(httpMessageHandler.Object) { BaseAddress = settings.UnleashApi }; var apiClient = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders); apiClientFactoryMock.Setup(cf => cf.CreateClient()).Returns(apiClient); await backgroundTask.ExecuteAsync(CancellationToken.None); httpMessageHandler.VerifyAll(); apiClientFactoryMock.VerifyAll(); }
internal async Task FetchToggles_WhenServerReturns304NotModified_ReturnsCacheHitResult( UnleashSettings settings, [Frozen] Mock <FakeHttpMessageHandler> httpMessageHandler, [Frozen] UnleashApiClientRequestHeaders requestHeaders, string etagMinusQuotes ) { var etag = $"\"{etagMinusQuotes}\""; var jsonSerializerSettings = new NewtonsoftJsonSerializerSettings(); var jsonSerializer = new NewtonsoftJsonSerializer(jsonSerializerSettings); httpMessageHandler.SetupGetFeaturesRequestForCacheHit(requestHeaders, etag); var httpClient = new HttpClient(httpMessageHandler.Object) { BaseAddress = settings.UnleashApi }; var apiClient = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders); var actualFetchTogglesResult = await apiClient.FetchToggles(etag, CancellationToken.None); Assert.Null(actualFetchTogglesResult.ToggleCollection); Assert.False(actualFetchTogglesResult.HasChanged); Assert.Equal(etag, actualFetchTogglesResult.Etag); httpMessageHandler.VerifyAll(); }
internal async Task ExecuteAsync_WhenHttpExceptionOccurs_CompletesSuccessfully( HttpStatusCode statusCode, string responseBody, string responseContentType, [Frozen] UnleashSettings settings, [Frozen] ThreadSafeToggleCollection toggleCollection, [Frozen] Mock <IToggleCollectionCache> toggleCollectionCache, [Frozen] Mock <FakeHttpMessageHandler> httpMessageHandler, [Frozen] Mock <IUnleashApiClientFactory> apiClientFactoryMock, [Frozen] UnleashApiClientRequestHeaders requestHeaders, TaskCompletionSource <object> taskCompletionSource) { var jsonSerializerSettings = new NewtonsoftJsonSerializerSettings(); var jsonSerializer = new NewtonsoftJsonSerializer(jsonSerializerSettings); var backgroundTask = new FetchFeatureTogglesTask(apiClientFactoryMock.Object, toggleCollection, toggleCollectionCache.Object, taskCompletionSource); httpMessageHandler.SetupGetFeaturesRequestForException(requestHeaders, statusCode, responseBody, responseContentType); var httpClient = new HttpClient(httpMessageHandler.Object) { BaseAddress = settings.UnleashApi }; var apiClient = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders); apiClientFactoryMock.Setup(cf => cf.CreateClient()).Returns(apiClient); await backgroundTask.ExecuteAsync(CancellationToken.None); Assert.True(taskCompletionSource.Task.IsCompletedSuccessfully); httpMessageHandler.VerifyAll(); apiClientFactoryMock.VerifyAll(); toggleCollectionCache.VerifyNoOtherCalls(); }
private static IUnleashApiClient CreateApiClient() { var apiUri = new Uri("http://unleash.herokuapp.com/api/"); var jsonSerializer = new DynamicNewtonsoftJsonSerializer(); jsonSerializer.TryLoad(); var httpClientFactory = new DefaultHttpClientFactory(); var requestHeaders = new UnleashApiClientRequestHeaders { AppName = "api-test-client", InstanceTag = "instance1", CustomHttpHeaders = new Dictionary <string, string>() { // "Test" token from 21.10.2021 { "Authorization", "*:default.77c45b703a681983b714fee87e575a823bfb1fd0ab282d9399647243" } }, CustomHttpHeaderProvider = null }; var httpClient = httpClientFactory.Create(apiUri); var client = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders); return(client); }
internal async Task FetchToggles_WhenHttpExceptionOccurs_ReturnsEmptyResult( HttpStatusCode responseStatusCode, string responseBody, string responseContentType, UnleashSettings settings, [Frozen] Mock <FakeHttpMessageHandler> httpMessageHandler, [Frozen] UnleashApiClientRequestHeaders requestHeaders, string etag ) { var jsonSerializerSettings = new NewtonsoftJsonSerializerSettings(); var jsonSerializer = new NewtonsoftJsonSerializer(jsonSerializerSettings); httpMessageHandler.SetupGetFeaturesRequestForException(requestHeaders, responseStatusCode, responseBody, responseContentType); var httpClient = new HttpClient(httpMessageHandler.Object) { BaseAddress = settings.UnleashApi }; var apiClient = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders); var actualFetchTogglesResult = await apiClient.FetchToggles(etag, CancellationToken.None); Assert.Null(actualFetchTogglesResult.ToggleCollection); Assert.Null(actualFetchTogglesResult.Etag); Assert.False(actualFetchTogglesResult.HasChanged); httpMessageHandler.VerifyAll(); }
internal static void SetupPostSendMetricsRequestForException(this Mock <FakeHttpMessageHandler> mock, UnleashApiClientRequestHeaders requestHeaders, HttpStatusCode statusCode, string responseBody = null, string responseContentType = null) { mock .Setup(mh => mh.Send(It.Is(ApiRequest(HttpMethod.Post, "api/client/metrics", requestHeaders)))) .Returns(() => ExceptionResponse(statusCode, responseBody, responseContentType)); }
internal async Task ExecuteAsync_WhenHttpExceptionOccurs_CompletesSuccessfully( HttpStatusCode statusCode, string responseBody, string responseContentType, [Frozen] UnleashSettings settings, [Frozen] Mock <FakeHttpMessageHandler> httpMessageHandler, [Frozen] Mock <IUnleashApiClientFactory> apiClientFactoryMock, [Frozen] UnleashApiClientRequestHeaders requestHeaders, List <string> strategies) { var jsonSerializerSettings = new NewtonsoftJsonSerializerSettings(); var jsonSerializer = new NewtonsoftJsonSerializer(jsonSerializerSettings); var backgroundTask = new ClientRegistrationBackgroundTask(apiClientFactoryMock.Object, settings, strategies); httpMessageHandler.SetupPostRegisterClientRequestForException(requestHeaders, statusCode, responseBody, responseContentType); var httpClient = new HttpClient(httpMessageHandler.Object) { BaseAddress = settings.UnleashApi }; var apiClient = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders); apiClientFactoryMock.Setup(cf => cf.CreateClient()).Returns(apiClient); await backgroundTask.ExecuteAsync(CancellationToken.None); httpMessageHandler.VerifyAll(); apiClientFactoryMock.VerifyAll(); }
internal async Task RegisterMetrics_WhenHttpExceptionOccurs_ReturnsFalse( HttpStatusCode responseStatusCode, string responseBody, string responseContentType, UnleashSettings settings, [Frozen] Mock <FakeHttpMessageHandler> httpMessageHandler, [Frozen] UnleashApiClientRequestHeaders requestHeaders, MetricsBucket metricsBucket ) { var jsonSerializerSettings = new NewtonsoftJsonSerializerSettings(); var jsonSerializer = new NewtonsoftJsonSerializer(jsonSerializerSettings); httpMessageHandler.SetupPostSendMetricsRequestForException(requestHeaders, responseStatusCode, responseBody, responseContentType); var httpClient = new HttpClient(httpMessageHandler.Object) { BaseAddress = settings.UnleashApi }; var apiClient = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders); var threadSafeMetricsBucket = new ThreadSafeMetricsBucket(metricsBucket); var successResult = await apiClient.SendMetrics(threadSafeMetricsBucket, CancellationToken.None); Assert.False(successResult); httpMessageHandler.VerifyAll(); }
internal async Task RegisterMetrics_WhenServerReturns200Ok_ReturnsTrue( UnleashSettings settings, [Frozen] Mock <FakeHttpMessageHandler> httpMessageHandler, [Frozen] UnleashApiClientRequestHeaders requestHeaders, MetricsBucket metricsBucket ) { var jsonSerializerSettings = new NewtonsoftJsonSerializerSettings(); var jsonSerializer = new NewtonsoftJsonSerializer(jsonSerializerSettings); httpMessageHandler.SetupPostSendMetricsRequestForSuccess(requestHeaders); var httpClient = new HttpClient(httpMessageHandler.Object) { BaseAddress = settings.UnleashApi }; var apiClient = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders); var threadSafeMetricsBucket = new ThreadSafeMetricsBucket(metricsBucket); var successResult = await apiClient.SendMetrics(threadSafeMetricsBucket, CancellationToken.None); Assert.True(successResult); httpMessageHandler.VerifyAll(); }
internal static void SetupGetFeaturesRequestForSuccess(this Mock <FakeHttpMessageHandler> mock, IJsonSerializer jsonSerializer, ToggleCollection toggleCollectionResult, UnleashApiClientRequestHeaders requestHeaders) { mock .Setup(mh => mh.Send(It.Is(ApiRequest(HttpMethod.Get, "api/client/features", requestHeaders)))) .Returns(() => SerializedMessageResponse(jsonSerializer, toggleCollectionResult)); }
internal static IUnleashServiceCollection AddUnleash(this IServiceCollection serviceCollection, Action <UnleashSettings> settingsInitializer, IConfiguration configuration, Action <UnleashSettings> settingsOverrider) { if (serviceCollection == null) { throw new ArgumentNullException(nameof(serviceCollection)); } var result = new UnleashServiceCollection(serviceCollection, configuration); var settings = new UnleashSettings(); settingsInitializer?.Invoke(settings); configuration?.Bind(settings); settingsOverrider?.Invoke(settings); SettingsValidator.Validate(settings); var unleashApiClientRequestHeaders = new UnleashApiClientRequestHeaders { AppName = settings.AppName, CustomHttpHeaders = settings.CustomHttpHeaders, InstanceTag = settings.InstanceTag }; serviceCollection.AddSingleton(settings); serviceCollection.AddSingleton <IRandom>(new UnleashRandom()); serviceCollection.AddSingleton(serviceProvider => serviceProvider.GetService <IEnumerable <IStrategy> >()?.ToArray() ?? Array.Empty <IStrategy>()); // Internal services serviceCollection.AddSingleton <NewtonsoftJsonSerializerSettings>(); serviceCollection.AddSingleton <IJsonSerializer, NewtonsoftJsonSerializer>(); serviceCollection.AddSingleton(unleashApiClientRequestHeaders); serviceCollection.AddSingleton <IHttpClientFactory, DefaultHttpClientFactory>(); serviceCollection.AddSingleton <IUnleashApiClientFactory, DefaultUnleashApiClientFactory>(); serviceCollection.AddSingleton <IUnleashApiClient, UnleashApiClient>(); serviceCollection.AddSingleton <IUnleashServices, UnleashServices>(); // Default: SystemTimer scheduled task manager serviceCollection.AddSingleton <IUnleashScheduledTaskManager, SystemTimerScheduledTaskManager>(); // Default: Disk-based JSON toggle collection cache serviceCollection.AddSingleton <IFileSystem, FileSystem>(); serviceCollection.AddSingleton <IToggleCollectionCache, FileSystemToggleCollectionCache>(); serviceCollection.AddScoped <IUnleashContextProvider, DefaultUnleashContextProvider>(); serviceCollection.AddScoped <IUnleash, Unleash>(); return(result); }
internal async Task ExecuteAsync_WhenApiReturns200Ok_CompletesSuccessfully( [Frozen] UnleashSettings settings, [Frozen] ThreadSafeToggleCollection toggleCollection, [Frozen] Mock <IToggleCollectionCache> toggleCollectionCache, [Frozen] Mock <FakeHttpMessageHandler> httpMessageHandler, [Frozen] Mock <IUnleashApiClientFactory> apiClientFactoryMock, [Frozen] UnleashApiClientRequestHeaders requestHeaders, TaskCompletionSource <object> taskCompletionSource) { var jsonSerializerSettings = new NewtonsoftJsonSerializerSettings(); var jsonSerializer = new NewtonsoftJsonSerializer(jsonSerializerSettings); var toggleCollectionInstance = toggleCollection.Instance; toggleCollectionCache .Setup( x => x.Save( It.Is <ToggleCollection>( y => y.Version.Equals(toggleCollectionInstance.Version) && y.Features.All( z => toggleCollectionInstance.Features.Any(zz => zz.Name.Equals(z.Name)) ) ), It.IsAny <string>(), CancellationToken.None ) ) .Returns(Task.CompletedTask); var backgroundTask = new FetchFeatureTogglesTask(apiClientFactoryMock.Object, toggleCollection, toggleCollectionCache.Object, taskCompletionSource); httpMessageHandler.SetupGetFeaturesRequestForSuccess(jsonSerializer, toggleCollectionInstance, requestHeaders); var httpClient = new HttpClient(httpMessageHandler.Object) { BaseAddress = settings.UnleashApi }; var apiClient = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders); apiClientFactoryMock.Setup(cf => cf.CreateClient()).Returns(apiClient); await backgroundTask.ExecuteAsync(CancellationToken.None); Assert.True(taskCompletionSource.Task.IsCompletedSuccessfully); httpMessageHandler.VerifyAll(); apiClientFactoryMock.VerifyAll(); toggleCollectionCache.VerifyAll(); }
protected BaseUnleashApiClientIntegrationTests() { var apiUri = new Uri("http://localhost:4242/"); var jsonSerializer = new NewtonsoftJsonSerializer(new NewtonsoftJsonSerializerSettings()); var httpClientFactory = new DefaultHttpClientFactory(); var requestHeaders = new UnleashApiClientRequestHeaders { AppName = "api-test-client", InstanceTag = "instance1", CustomHttpHeaders = null }; var httpClient = httpClientFactory.Create(apiUri); Client = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders); AdminClient = new UnleashAdminApiClient(httpClient, jsonSerializer); }
private static IUnleashApiClient CreateApiClient() { var apiUri = new Uri("http://unleash.herokuapp.com/api/"); var jsonSerializer = new DynamicNewtonsoftJsonSerializer(); jsonSerializer.TryLoad(); var httpClientFactory = new DefaultHttpClientFactory(); var requestHeaders = new UnleashApiClientRequestHeaders { AppName = "api-test-client", InstanceTag = "instance1", CustomHttpHeaders = null }; var httpClient = httpClientFactory.Create(apiUri); var client = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders); return(client); }
private IUnleashApiClient CreateApiClient() { var jsonSerializer = new DynamicNewtonsoftJsonSerializer(); jsonSerializer.TryLoad(); var requestHeaders = new UnleashApiClientRequestHeaders { AppName = "api-test-client", InstanceTag = "instance1", CustomHttpHeaders = httpHeaders, CustomHttpHeaderProvider = httpHeadersProvider }; var httpClient = new HttpClient(messageHandler) { BaseAddress = new Uri("http://example.com") }; var client = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders); return(client); }
private UnleashApiClient NewTestableClient(string project, MockHttpMessageHandler messageHandler) { var apiUri = new Uri("http://unleash.herokuapp.com/api/"); var jsonSerializer = new DynamicNewtonsoftJsonSerializer(); jsonSerializer.TryLoad(); var requestHeaders = new UnleashApiClientRequestHeaders { AppName = "api-test-client", InstanceTag = "instance1", CustomHttpHeaders = null, CustomHttpHeaderProvider = null }; var httpClient = new HttpClient(messageHandler) { BaseAddress = apiUri, Timeout = TimeSpan.FromSeconds(5) }; return(new UnleashApiClient(httpClient, jsonSerializer, requestHeaders, project)); }
internal static void SetupPostSendMetricsRequestForSuccess(this Mock <FakeHttpMessageHandler> mock, UnleashApiClientRequestHeaders requestHeaders) { mock .Setup(mh => mh.Send(It.Is(ApiRequest(HttpMethod.Post, "api/client/metrics", requestHeaders)))) .Returns(() => EmptyResponse(HttpStatusCode.OK)); }