public async Task ShouldReturnIntervalServerErrorIfUnhandledException()
        {
            var config = new FunctionConfiguration
            {
                Recipient             = "*****@*****.**",
                FallbackSubject       = "You got mail!",
                UseRedirectResponse   = true,
                AllowUserRedirectUrls = true
            };

            var requestReader = CreateRequestReader(
                "name", "Captain Test",
                "email", "*****@*****.**",
                "message", "Test message!");

            var smtpClientMock = new Mock <ISmtpClient>();

            smtpClientMock
            .Setup(sc => sc.SendAsync(It.IsAny <MailMessage>()))
            .ThrowsAsync(new InvalidOperationException("BOOM"));

            var function = new SendEmailFunction(
                config,
                requestReader,
                () => smtpClientMock.Object);

            var result = await function.Run(Mock.Of <HttpRequest>(), Mock.Of <ILogger>());

            Assert.IsType <InternalServerErrorResult>(result);
        }
        public async Task ShouldReturnBadRequestIfSuppliedUrlRequiredAndNotSupplied()
        {
            var config = new FunctionConfiguration
            {
                Recipient             = "*****@*****.**",
                FallbackSubject       = "You got mail!",
                UseRedirectResponse   = true,
                AllowUserRedirectUrls = true
            };

            var requestReader = CreateRequestReader(
                "name", "Captain Test",
                "email", "*****@*****.**",
                "message", "Test message!");

            var function = new SendEmailFunction(
                config,
                requestReader,
                Mock.Of <ISmtpClient>);

            var result = await function.Run(Mock.Of <HttpRequest>(), Mock.Of <ILogger>());

            var badRequestResult = Assert.IsType <BadRequestErrorMessageResult>(result);

            Assert.Equal("Missing redirect URL.", badRequestResult.Message);
        }
        public async Task ShouldReturnBadRequestIfErrorReadingFormData()
        {
            var config = new FunctionConfiguration();

            var requestReader = CreateRequestReader(onReadForm => onReadForm
                                                    .ThrowsAsync(new InvalidOperationException()));

            var function = new SendEmailFunction(
                config,
                requestReader,
                Mock.Of <ISmtpClient>);

            var result = await function.Run(Mock.Of <HttpRequest>(), Mock.Of <ILogger>());

            var badRequestResult = Assert.IsType <BadRequestErrorMessageResult>(result);

            Assert.Equal("Invalid form data", badRequestResult.Message);
        }
        public async Task ShouldReturnBadRequestIfEmailNotSupplied()
        {
            var config = new FunctionConfiguration();

            var requestReader = CreateRequestReader(
                "name", "Captain Test",
                "message", "Test message!");

            var function = new SendEmailFunction(
                config,
                requestReader,
                Mock.Of <ISmtpClient>);

            var result = await function.Run(Mock.Of <HttpRequest>(), Mock.Of <ILogger>());

            var badRequestResult = Assert.IsType <BadRequestErrorMessageResult>(result);

            Assert.Equal("Missing email details.", badRequestResult.Message);
        }
        public async Task ShouldReturnBadRequestIfNameEmpty()
        {
            var config = new FunctionConfiguration();

            var requestReader = CreateRequestReader(
                "name", string.Empty,
                "email", "*****@*****.**",
                "message", "Test message!");

            var function = new SendEmailFunction(
                config,
                requestReader,
                Mock.Of <ISmtpClient>);

            var result = await function.Run(Mock.Of <HttpRequest>(), Mock.Of <ILogger>());

            var badRequestResult = Assert.IsType <BadRequestErrorMessageResult>(result);

            Assert.Equal("Blank email details.", badRequestResult.Message);
        }
        public async Task ShouldReturnRedirectToFallbackUrl()
        {
            var config = new FunctionConfiguration
            {
                Recipient             = "*****@*****.**",
                FallbackSubject       = "You got mail!",
                UseRedirectResponse   = true,
                AllowUserRedirectUrls = true,
                SuccessRedirectUrl    = "email-sent.com"
            };

            var requestReader = CreateRequestReader(
                "name", "Captain Test",
                "email", "*****@*****.**",
                "message", "Test message!");

            var sentMail = default(MailMessage);

            var smtpClientMock = new Mock <ISmtpClient>();

            smtpClientMock
            .Setup(sc => sc.SendAsync(It.IsAny <MailMessage>()))
            .Callback((MailMessage mail) => sentMail = mail)
            .Returns(Task.CompletedTask);

            var function = new SendEmailFunction(
                config,
                requestReader,
                () => smtpClientMock.Object);

            var result = await function.Run(Mock.Of <HttpRequest>(), Mock.Of <ILogger>());

            var redirectResult = Assert.IsType <RedirectResult>(result);

            Assert.Equal("email-sent.com", redirectResult.Url);
            Assert.False(redirectResult.Permanent);

            Assert.NotNull(sentMail);
        }
        public async Task ShouldReturnOk()
        {
            var config = new FunctionConfiguration
            {
                Recipient       = "*****@*****.**",
                FallbackSubject = "You got mail!"
            };

            var requestReader = CreateRequestReader(
                "name", "Captain Test",
                "email", "*****@*****.**",
                "message", "Test message!");

            var sentMail = default(MailMessage);

            var smtpClientMock = new Mock <ISmtpClient>();

            smtpClientMock
            .Setup(sc => sc.SendAsync(It.IsAny <MailMessage>()))
            .Callback((MailMessage mail) => sentMail = mail)
            .Returns(Task.CompletedTask);

            var function = new SendEmailFunction(
                config,
                requestReader,
                () => smtpClientMock.Object);

            var result = await function.Run(Mock.Of <HttpRequest>(), Mock.Of <ILogger>());

            Assert.IsType <OkResult>(result);

            Assert.NotNull(sentMail);
            Assert.Equal("\"Captain Test\" <*****@*****.**>", sentMail.From.ToString());
            Assert.Equal("*****@*****.**", sentMail.To.ToString());
            Assert.Equal("You got mail!", sentMail.Subject);
            Assert.Equal("Test message!", sentMail.Body);
        }