public async Task EnvironmentNotSupportedResultIs501NotSupported()
        {
            var validAuthentication = MockAuthentication.Get();
            var actionResponse      = new RegisterAction.Response
            {
                Type           = RegisterAction.ResponseType.EnvironmentNotSupported,
                ServerIdentity = new CaberIdentity {
                    Uuid = validAuthentication.ServerUuid.Value
                },
                Environment = new CaberSharedEnvironment()
            };
            var action = Mock.Of <RegisterAction>(a => a.Execute(It.IsAny <RegisterAction.Request>(), It.IsAny <ClaimsPrincipal>()) == actionResponse);

            using (var server = CreateServer(validAuthentication, action))
            {
                await server.StartAsync();

                var request = CreateMinimalValidRequest(validAuthentication);

                var response = await server.MakeClientRequest(validAuthentication,
                                                              $"/register/{validAuthentication.ClientUuid}",
                                                              HttpMethod.Post,
                                                              new StringContent(JsonConvert.SerializeObject(request)));

                Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotImplemented));
            }
        }
        public async Task RequestWithCertificatesAndHeaders_Yields200OK()
        {
            var validAuthentication = MockAuthentication.Get();

            using (var server = CreateServer(validAuthentication))
            {
                await server.StartAsync();

                var response = await server.MakeClientRequest(validAuthentication, "/Test/Default");

                Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
            }
        }
        public async Task NotKnownClientUuidAndCertificate_Yields200OK()
        {
            var authentication = MockAuthentication.Get();

            authentication.ValidatePeerIdentityResult = PeerIdentityValidationResult.NotOnRecord;

            using (var server = CreateServer(authentication))
            {
                await server.StartAsync();

                var response = await server.MakeClientRequest(authentication, "/Test/Default");

                Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
            }
        }
        public async Task MismatchedClientUuidAndCertificate_Yields401Unauthorized()
        {
            var authentication = MockAuthentication.Get();

            authentication.ValidatePeerIdentityResult = PeerIdentityValidationResult.Mismatch;

            using (var server = CreateServer(authentication))
            {
                await server.StartAsync();

                var response = await server.MakeClientRequest(authentication, "/Test/Default");

                Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.Unauthorized));
                var message = JsonConvert.DeserializeObject <CaberAuthenticationFailureMessage>(await response.Content.ReadAsStringAsync());
                Assert.That(message.Reason, Is.EqualTo(CaberMutualAuthenticationFailureReason.ClientCertificateDoesNotMatchAnyKnownForTheClaimedUUID.ToString()));
            }
        }
        public async Task IncorrectXCaberRecipientHeader_Yields401Unauthorized()
        {
            var validAuthentication = MockAuthentication.Get();

            using (var server = CreateServer(validAuthentication))
            {
                await server.StartAsync();

                var invalid = validAuthentication.Copy();
                invalid.ServerUuid = Guid.NewGuid();

                var response = await server.MakeClientRequest(invalid, "/Test/Default");

                Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.Unauthorized));
                var message = JsonConvert.DeserializeObject <CaberAuthenticationFailureMessage>(await response.Content.ReadAsStringAsync());
                Assert.That(message.Reason, Is.EqualTo(CaberMutualAuthenticationFailureReason.ServerUUIDDoesNotReferToThisInstance.ToString()));
            }
        }
        public async Task MissingClientCertificate_Yields401Unauthorized()
        {
            var validAuthentication = MockAuthentication.Get();

            using (var server = CreateServer(validAuthentication))
            {
                await server.StartAsync();

                var invalid = validAuthentication.Copy();
                invalid.ClientCertificate = null;

                var response = await server.MakeClientRequest(invalid, "/Test/Default");

                Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.Unauthorized));
                var message = JsonConvert.DeserializeObject <CaberAuthenticationFailureMessage>(await response.Content.ReadAsStringAsync());
                Assert.That(message.Reason, Is.EqualTo(CaberMutualAuthenticationFailureReason.NoClientCertificateProvided.ToString()));
            }
        }
        public async Task InvalidServerCertificate_YieldsClientError()
        {
            var authentication = MockAuthentication.Get();

            authentication.ServerCertificateIsValid = false;

            var router = Mock.Of <ICaberRequestRouter>();

            using (var server = CreateServer(authentication, router))
            {
                await server.StartAsync();

                var exception = Assert.CatchAsync <HttpRequestException>(() => server.MakeClientRequest(authentication, "/Test/Default"));
                Assert.That(exception.InnerException?.InnerException, Is.InstanceOf <AuthenticationException>());
                Assert.That(exception.InnerException?.InnerException?.Message, Does.Contain("remote certificate is invalid"));
                Mock.Get(router).Verify(r => r.Route(It.IsAny <CaberRequestContext>()), Times.Never);
            }
        }
        public async Task UriClientUuidMismatchIs400BadRequest()
        {
            var validAuthentication = MockAuthentication.Get();
            var action = Mock.Of <RegisterAction>();

            using (var server = CreateServer(validAuthentication, action))
            {
                await server.StartAsync();

                var request = CreateMinimalValidRequest(validAuthentication);

                var response = await server.MakeClientRequest(validAuthentication,
                                                              $"/register/{Guid.NewGuid()}",
                                                              HttpMethod.Post,
                                                              new StringContent(JsonConvert.SerializeObject(request)));

                Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
            }
        }
        public async Task MinimalValidRequestInvokesAction()
        {
            var validAuthentication = MockAuthentication.Get();
            var action = Mock.Of <RegisterAction>();

            using (var server = CreateServer(validAuthentication, action))
            {
                await server.StartAsync();

                var request = CreateMinimalValidRequest(validAuthentication);

                await server.MakeClientRequest(validAuthentication,
                                               $"/register/{validAuthentication.ClientUuid}",
                                               HttpMethod.Post,
                                               new StringContent(JsonConvert.SerializeObject(request)));

                Mock.Get(action).Verify(a => a.Execute(It.IsAny <RegisterAction.Request>(), It.IsAny <ClaimsPrincipal>()));
            }
        }
        public async Task InvalidClientCertificate_YieldsErrorBeforeRouting()
        {
            var authentication = MockAuthentication.Get();

            authentication.ClientCertificateIsValid = false;

            var router = Mock.Of <ICaberRequestRouter>();

            using (var server = CreateServer(authentication, router))
            {
                await server.StartAsync();

                var exception = Assert.CatchAsync <HttpRequestException>(() => server.MakeClientRequest(authentication, "/Test/Default"));
                Assert.That(exception, Has.InnerException);
                Assert.That(exception, Has.InnerException.InnerException);
                Assert.That(exception, Has.InnerException.InnerException.Message.Contains("decryption"));
                Mock.Get(router).Verify(r => r.Route(It.IsAny <CaberRequestContext>()), Times.Never);
            }
        }