public async Task SaveClientTenantOldPrefixAcceptsFalsePositives()
        {
#if NETCOREAPP
            var saveConfigHandler =
                new SaveClientTenant(async ctx =>
            {
                _foundClientTenant = FulcrumApplication.Context.ClientTenant;
                await Task.CompletedTask;
            }, SaveClientTenant.LegacyVersionPrefix);
#else
            var mockHandler       = new Mock <HttpMessageHandler>();
            var saveConfigHandler = new SaveClientTenant(SaveClientTenant.LegacyVersionPrefix)
            {
                InnerHandler = new GetContextTestHandler
                {
                    InnerHandler = mockHandler.Object
                }
            };
            var invoker = new HttpMessageInvoker(saveConfigHandler);
#endif


            _foundClientTenant = null;
            var url = "https://ver-fulcrum-fundamentals.azurewebsites.net/api/v1/false/positive/ServiceMetas/ServiceHealth";
#if NETCOREAPP
            var context = new DefaultHttpContext();
            SetRequest(context, url);
            await saveConfigHandler.InvokeAsync(context);
#else
            var request = new HttpRequestMessage(HttpMethod.Get, url);
            await invoker.SendAsync(request, CancellationToken.None);
#endif
            Assert.IsNotNull(_foundClientTenant);
        }
        public async Task SaveConfigurationFail()
        {
#if NETCOREAPP
            var saveConfigHandler =
                new SaveClientTenant(async context => await Task.CompletedTask, SaveClientTenant.LegacyVersionPrefix);
#else
            var saveConfigHandler = new SaveClientTenant(SaveClientTenant.LegacyVersionPrefix)
            {
                InnerHandler = new Mock <HttpMessageHandler>().Object
            };
            var invoker = new HttpMessageInvoker(saveConfigHandler);
#endif
            FulcrumApplication.Context.ClientTenant = null;
            foreach (var url in new[]
            {
                "http://gooogle.com/",
                "https://anywhere.org/api/v1/eels/"
            })
            {
#if NETCOREAPP
                var context = new DefaultHttpContext();
                SetRequest(context, url);
                await saveConfigHandler.InvokeAsync(context);
#else
                var request = new HttpRequestMessage(HttpMethod.Get, url);
                await invoker.SendAsync(request, CancellationToken.None);
#endif
                Assert.IsNull(FulcrumApplication.Context.ClientTenant);
            }
        }
        public async Task SavedConfigurationHandlesNoCorrelationId()
        {
            // Setup a mocked logger as the FullLogger so that we have full control
            var mockLogger = new Mock <ISyncLogger>();

            FulcrumApplication.Setup.SynchronousFastLogger = mockLogger.Object;
            mockLogger.Setup(x => x.LogSync(It.IsAny <LogRecord>())).Verifiable();

            // The expected correlation id propagated as a request header
            const string corrId = "Qorrr";

            var leverConfig = new Mock <ILeverServiceConfiguration>();

#if NETCOREAPP
            var innerHandler =
                new SaveClientTenantConfiguration(async c =>
            {
                _foundCorrelationId = FulcrumApplication.Context.CorrelationId;
                await Task.CompletedTask;
            }, leverConfig.Object);
            var outerHandler = new SaveClientTenant(innerHandler.InvokeAsync, SaveClientTenant.LegacyVersionPrefix);
#else
            // Simulate a pipe of DelegatingHandlers
            var outerHandler = new SaveClientTenant(SaveClientTenant.LegacyVersionPrefix)
            {
                InnerHandler = new SaveClientTenantConfiguration(new Mock <ILeverServiceConfiguration>().Object)
                {
                    InnerHandler = new GetContextTestHandler
                    {
                        InnerHandler = new Mock <HttpMessageHandler>().Object
                    }
                }
            };
#endif
            var url = "https://v-mock.org/v2/smoke-testing-company/ver/";

            // Simulate an incoming request
#if NETCOREAPP
            var context = new DefaultHttpContext();
            SetRequest(context, url);
            context.Request.Headers.Add("X-Correlation-ID", corrId);
            await outerHandler.InvokeAsync(context);
#else
            var invoker = new HttpMessageInvoker(outerHandler);
            var request = new HttpRequestMessage(HttpMethod.Get, url);
            request.Headers.Add("X-Correlation-ID", corrId);
            await invoker.SendAsync(request, CancellationToken.None);
#endif

            // Check that LogAsync has NOT been invoked
            mockLogger.VerifyNoOtherCalls();

            Assert.AreEqual(corrId, _foundCorrelationId,
                            "When SaveConfiguration is run before SaveCorrelationId, we still expect X-Correlation-ID header to be handled");
        }
        public async Task SaveClientTenantOldPrefixSuccess()
        {
#if NETCOREAPP
            var saveConfigHandler =
                new SaveClientTenant(async context =>
            {
                _foundClientTenant = FulcrumApplication.Context.ClientTenant;
                await Task.CompletedTask;
            }, SaveClientTenant.LegacyVersionPrefix);
#else
            var mockHandler       = new Mock <HttpMessageHandler>();
            var saveConfigHandler = new SaveClientTenant(SaveClientTenant.LegacyVersionPrefix)
            {
                InnerHandler = new GetContextTestHandler
                {
                    InnerHandler = mockHandler.Object
                }
            };
            var invoker = new HttpMessageInvoker(saveConfigHandler);
#endif

            foreach (var entry in new Dictionary <Tenant, string>
            {
                { new Tenant("smoke-testing-company", "ver"), "https://v-mock.org/v2/smoke-testing-company/ver/" },
                {
                    new Tenant("smoke-testing-company", "local"),
                    "https://v-mock.org/api/v-pa1/smoke-testing-company/local/"
                },
                {
                    new Tenant("fulcrum", "prd"),
                    "https://prd-fulcrum-fundamentals.azurewebsites.net/api/v1/fulcrum/prd/ServiceMetas/ServiceHealth"
                },
                {
                    new Tenant("fulcrum", "ver"),
                    "https://ver-fulcrum-fundamentals.azurewebsites.net/api/v1/fulcrum/ver/ServiceMetas/ServiceHealth"
                }
            })
            {
                _foundClientTenant = null;
                var expectedTenant = entry.Key;
#if NETCOREAPP
                var context = new DefaultHttpContext();
                SetRequest(context, entry.Value);
                await saveConfigHandler.InvokeAsync(context);
#else
                var request = new HttpRequestMessage(HttpMethod.Get, entry.Value);
                await invoker.SendAsync(request, CancellationToken.None);
#endif
                Assert.AreEqual(expectedTenant, _foundClientTenant,
                                $"Could not find tenant '{expectedTenant}' from url '{entry.Value}'. Found {_foundClientTenant}");
            }
        }
        public async Task SaveCorrelationIdMustNotBeBeforeSaveClientTenantConfiguration()
        {
            const string url = "https://v-mock.org/v2/smoke-testing-company/ver";

#if NETCOREAPP
            var innerHandler  = new SaveClientTenantConfiguration(async ctx => await Task.CompletedTask, new Mock <ILeverServiceConfiguration>().Object);
            var middleHandler =
                new SaveClientTenant(innerHandler.InvokeAsync, SaveClientTenant.LegacyVersionPrefix);
            var outerHandler =
                new SaveCorrelationId(middleHandler.InvokeAsync);
            var context = new DefaultHttpContext();
            SetRequest(context, url);
#else
            var outerHandler = new SaveCorrelationId
            {
                InnerHandler = new SaveClientTenant(SaveClientTenant.LegacyVersionPrefix)
                {
                    InnerHandler = new SaveClientTenantConfiguration(new Mock <ILeverServiceConfiguration>().Object)
                    {
                        InnerHandler = new GetContextTestHandler()
                        {
                            InnerHandler = new Mock <HttpMessageHandler>().Object
                        }
                    }
                }
            };
            var invoker = new HttpMessageInvoker(outerHandler);
            var request = new HttpRequestMessage(HttpMethod.Get, url);
#endif

            try
            {
#if NETCOREAPP
                await outerHandler.InvokeAsync(context);
#else
                await invoker.SendAsync(request, CancellationToken.None);
#endif
                Assert.Fail("Expected an exception");
            }
            catch (FulcrumContractException e)
            {
                Assert.IsTrue(e.Message.Contains("must not precede"));
            }
            catch (Exception e)
            {
                Assert.Fail(
                    $"Expected an exception of type {nameof(FulcrumContractException)}, but caught exception {e.GetType().FullName}");
            }
        }
        public async Task SavedConfigurationWhenLoggingWithNoCorrelationId()
        {
            // Simulate a pipe of DelegatingHandlers where SaveConfiguration happens first
#if NETCOREAPP
            var innerHandler = new SaveCorrelationId(async context =>
            {
                _foundClientTenant  = FulcrumApplication.Context.ClientTenant;
                _foundCorrelationId = FulcrumApplication.Context.CorrelationId;
                await Task.CompletedTask;
            });
            var middleHandler = new SaveClientTenantConfiguration(innerHandler.InvokeAsync, new Mock <ILeverServiceConfiguration>().Object);
            var outerHandler  =
                new SaveClientTenant(middleHandler.InvokeAsync, SaveClientTenant.LegacyVersionPrefix);
#else
            var outerHandler = new SaveClientTenant(SaveClientTenant.LegacyVersionPrefix)
            {
                InnerHandler = new SaveClientTenantConfiguration(new Mock <ILeverServiceConfiguration>().Object)
                {
                    InnerHandler = new SaveCorrelationId
                    {
                        InnerHandler = new GetContextTestHandler()
                        {
                            InnerHandler = new Mock <HttpMessageHandler>().Object
                        }
                    }
                }
            };
#endif

            // Define Organization/Environment for the uri path
            const string org = "my-org";
            const string env = "prd";

            // Invoke a request and get back the tenant that was logged on
            var loggedTenant = await SavedConfigurationPlayingWithSaveCorrelationId(
#if NETCOREAPP
                outerHandler.InvokeAsync,
#else
                outerHandler,
#endif
                org, env);

            Assert.IsNotNull(_foundCorrelationId, "CorrelationId should have been created");
            Assert.AreEqual(_foundClientTenant, loggedTenant,
                            $"Expected the tenant on the value provider ('{_foundClientTenant}') to equal the logged tenant ('{loggedTenant}')");
        }