<commit_before>namespace IdentityBase.Public.IntegrationTests
{
    using System.Net.Http;
    using System.Threading.Tasks;
    using FluentAssertions;
    using Microsoft.AspNetCore.TestHost;
    using Moq;
    using Newtonsoft.Json;
    using ServiceBase.Extensions;
    using ServiceBase.Mvc;
    using ServiceBase.Notification.Email;
    using ServiceBase.Tests;
    using Xunit;

    [Collection("ApiChangeEmailTests")]
    public class ApiChangeEmailTests
    {
        const string aliceId =    "0<PASSWORD>";
        const string notFoundId = "00000000-4c73-ffe4-b0f2-c00403e4adee";

        private TestServer CreateServer(
            Mock<IEmailService> emailServiceMock = null)
        {
            return TestServerBuilderExtensions
                .CreateServer(emailServiceMock, (builder) =>
                {
                    builder
                        .Alter("App:EnableAccountChangeEmailEndpoint", "true");
                }, TestServerBuilderExtensions.CreateServer().CreateHandler());
        }

        [Fact(DisplayName = "API: Change email / Confirm / Login")]
        public async Task ChangeEmail_Confirm_Login()
        {
            string confirmUrl = null;
            string cancelUrl = null;

            // Mock the email service to intercept the outgoing email messages
            var emailServiceMock = EmailServiceHelper.GetEmailServiceMock(
                IdentityBaseConstants.EmailTemplates.UserAccountEmailChanged,
                "nerd<EMAIL>", (templateName, emailTo, viewData, isHtml) =>
                {
                    // 2. Get confirm url and call it
                    confirmUrl = viewData
                        .ToDictionary()["ConfirmUrl"].ToString();

                    cancelUrl = viewData
                        .ToDictionary()["CancelUrl"].ToString();

                });

            TestServer server = this.CreateServer(emailServiceMock);
            HttpClient client = await server.CreateAuthenticatedClient();

            string uri = $"/useraccounts/{aliceId}/change_email";
            HttpResponseMessage response = await client.PostJsonAsync(uri, new
            {
                Email = "<EMAIL>d<EMAIL>",
                ClientId = "mvc.hybrid",
                Force = false
            });

            response.EnsureSuccessStatusCode();
            // response.AssertSchema(Schemas.InvitationsPostResponse);

            Assert.NotNull(confirmUrl);
            Assert.NotNull(cancelUrl);

            // Post password

            // Try authenticate
        }


        [Fact(DisplayName = "API: Change email / User does not exists")]
        public async Task ChangeEmail_UserDoesNotExists()
        {
            TestServer server = this.CreateServer();
            HttpClient client = await server.CreateAuthenticatedClient();

            string uri = $"/useraccounts/{notFoundId}/change_email";
            HttpResponseMessage response = await client.PostJsonAsync(uri,
                new
                {
                    Email = "<EMAIL>",
                    ClientId = "mvc.hybrid"
                });

            response.StatusCode
                .Should().Be(System.Net.HttpStatusCode.NotFound);
        }

        [Fact(DisplayName = "API: Change email / Email already taken")]
        public async Task ChangeEmail_EmailAlreadyTaken()
        {
            TestServer server = this.CreateServer();
            HttpClient client = await server.CreateAuthenticatedClient();

            string uri = $"/useraccounts/{aliceId}/change_email";
            HttpResponseMessage response = await client.PostJsonAsync(uri,
                new
                {
                    Email = "<EMAIL>",
                    ClientId = "mvc.hybrid",
                });

            response.StatusCode
                .Should().Be(System.Net.HttpStatusCode.BadRequest);

            string json = await response.Content.ReadAsStringAsync();
            json.Should().Be("{\"type\":\"SerializableError\",\"error\":{\"email\":[\"The Email field is invalid, Email already taken.\"]}}");
        }

        [Fact(DisplayName = "API: Change email / ClientId missing")]
        public async Task ChangeEmail_ClientIdMissing()
        {
            TestServer server = this.CreateServer();
            HttpClient client = await server.CreateAuthenticatedClient();

            string uri = $"/useraccounts/{aliceId}/change_email";
            HttpResponseMessage response = await client.PostJsonAsync(uri,
                new
                {
                    Email = "<EMAIL>",
                });

            response.StatusCode
                .Should().Be(System.Net.HttpStatusCode.BadRequest);

            string json = await response.Content.ReadAsStringAsync();
            json.Should().Be("{\"type\":\"SerializableError\",\"error\":{\"clientId\":[\"The ClientId field is required.\"]}}");
        }


        [Fact(DisplayName = "API: Change email / Invalid ClientId")]
        public async Task ChangeEmail_InvalidClientId()
        {
            TestServer server = this.CreateServer();
            HttpClient client = await server.CreateAuthenticatedClient();

            string uri = $"/useraccounts/{aliceId}/change_email";
            HttpResponseMessage response = await client.PostJsonAsync(uri,
                new
                {
                    Email = "<EMAIL>",
                    ClientId = "invalid_one"
                });

            response.StatusCode
                .Should().Be(System.Net.HttpStatusCode.BadRequest);
            
            string json = await response.Content.ReadAsStringAsync();
            json.Should().Be("{\"type\":\"SerializableError\",\"error\":{\"clientId\":[\"The ClientId field is invalid.\"]}}"); <commit_msg>Added test<commit_after>namespace IdentityBase.Public.IntegrationTests
{
    using System.Net.Http;
    using System.Threading.Tasks;
    using FluentAssertions;
    using Microsoft.AspNetCore.TestHost;
    using Moq;
    using Newtonsoft.Json;
    using ServiceBase.Extensions;
    using ServiceBase.Mvc;
    using ServiceBase.Notification.Email;
    using ServiceBase.Tests;
    using Xunit;

    [Collection("ApiChangeEmailTests")]
    public class ApiChangeEmailTests
    {
        const string aliceId = "0c2954d2-4c73-44e3-b0f2-c00403e4adef";
        const string notFoundId = "00000000-4c73-ffe4-b0f2-c00403e4adee";

        private TestServer CreateServer(
            Mock<IEmailService> emailServiceMock = null)
        {
            return TestServerBuilderExtensions
                .CreateServer(emailServiceMock, (builder) =>
                {
                    builder
                        .Alter("App:EnableAccountChangeEmailEndpoint", "true");
                }, TestServerBuilderExtensions.CreateServer().CreateHandler());
        }

        [Fact(DisplayName = "API: Change email / Confirm / Login")]
        public async Task ChangeEmail_Confirm_Login()
        {
            string confirmUrl = null;
            string cancelUrl = null;

            // Mock the email service to intercept the outgoing email messages
            var emailServiceMock = EmailServiceHelper.GetEmailServiceMock(
                IdentityBaseConstants.EmailTemplates.UserAccountEmailChanged,
                "nerd@localhost", (templateName, emailTo, viewData, isHtml) =>
                {
                    // 2. Get confirm url and call it
                    confirmUrl = viewData
                        .ToDictionary()["ConfirmUrl"].ToString();

                    cancelUrl = viewData
                        .ToDictionary()["CancelUrl"].ToString();

                });

            TestServer server = this.CreateServer(emailServiceMock);
            HttpClient client = await server.CreateAuthenticatedClient();

            string uri = $"/useraccounts/{aliceId}/change_email";
            HttpResponseMessage response = await client.PostJsonAsync(uri, new
            {
                Email = "<EMAIL>",
                ClientId = "mvc.hybrid",
                Force = false
            });

            response.EnsureSuccessStatusCode();
            // response.AssertSchema(Schemas.InvitationsPostResponse);

            Assert.NotNull(confirmUrl);
            Assert.NotNull(cancelUrl);

            // Post password

            // Try authenticate
        }

        [Fact(DisplayName = "API: Change email / Force update")]
        public async Task ChangeEmail_FoceUpdate()
        {
            string confirmUrl = null;
            string cancelUrl = null;

            // Mock the email service to intercept the outgoing email messages
            var emailServiceMock = EmailServiceHelper.GetEmailServiceMock(
                IdentityBaseConstants.EmailTemplates.UserAccountEmailChanged,
                "ner<EMAIL>", (templateName, emailTo, viewData, isHtml) =>
                {
                    // 2. Get confirm url and call it
                    confirmUrl = viewData
                        .ToDictionary()["ConfirmUrl"].ToString();

                    cancelUrl = viewData
                        .ToDictionary()["CancelUrl"].ToString();

                });

            TestServer server = this.CreateServer(emailServiceMock);
            HttpClient client = await server.CreateAuthenticatedClient();

            string uri = $"/useraccounts/{aliceId}/change_email";
            HttpResponseMessage response = await client.PostJsonAsync(uri, new
            {
                Email = "<EMAIL>",
                ClientId = "mvc.hybrid",
                Force = true
            });

            response.EnsureSuccessStatusCode();
            var json = response.Content.ReadAsStringAsync().Result;
        }

        [Fact(DisplayName = "API: Change email / User does not exists")]
        public async Task ChangeEmail_UserDoesNotExists()
        {
            TestServer server = this.CreateServer();
            HttpClient client = await server.CreateAuthenticatedClient();

            string uri = $"/useraccounts/{notFoundId}/change_email";
            HttpResponseMessage response = await client.PostJsonAsync(uri,
                new
                {
                    Email = "<EMAIL>",
                    ClientId = "mvc.hybrid"
                });

            response.StatusCode
                .Should().Be(System.Net.HttpStatusCode.NotFound);
        }

        [Fact(DisplayName = "API: Change email / Email already taken")]
        public async Task ChangeEmail_EmailAlreadyTaken()
        {
            TestServer server = this.CreateServer();
            HttpClient client = await server.CreateAuthenticatedClient();

            string uri = $"/useraccounts/{aliceId}/change_email";
            HttpResponseMessage response = await client.PostJsonAsync(uri,
                new
                {
                    Email = "<EMAIL>",
                    ClientId = "mvc.hybrid",
                });

            response.StatusCode
                .Should().Be(System.Net.HttpStatusCode.BadRequest);

            string json = await response.Content.ReadAsStringAsync();
            json.Should().Be("{\"type\":\"SerializableError\",\"error\":{\"email\":[\"The Email field is invalid, Email already taken.\"]}}");
        }

        [Fact(DisplayName = "API: Change email / ClientId missing")]
        public async Task ChangeEmail_ClientIdMissing()
        {
            TestServer server = this.CreateServer();
            HttpClient client = await server.CreateAuthenticatedClient();

            string uri = $"/useraccounts/{aliceId}/change_email";
            HttpResponseMessage response = await client.PostJsonAsync(uri,
                new
                {
                    Email = "nerd@localhost",
                });

            response.StatusCode
                .Should().Be(System.Net.HttpStatusCode.BadRequest);

            string json = await response.Content.ReadAsStringAsync();
            json.Should().Be("{\"type\":\"SerializableError\",\"error\":{\"clientId\":[\"The ClientId field is required.\"]}}");
        }

        [Fact(DisplayName = "API: Change email / Invalid ClientId")]
        public async Task ChangeEmail_InvalidClientId()
        {
            TestServer server = this.CreateServer();
            HttpClient client = await server.CreateAuthenticatedClient();

            string uri = $"/useraccounts/{aliceId}/change_email";
            HttpResponseMessage response = await client.PostJsonAsync(uri,
                new
                {
                    Email = "nerd@localhost",
                    ClientId = "invalid_one"
                });

            response.StatusCode
                .Should().Be(System.Net.HttpStatusCode.BadRequest);

            string json = await response.Content.ReadAsStringAsync();
            json.Should().Be("{\"type\":\"SerializableError\",\"error\":{\"clientId\":[\"The ClientId field is invalid.\"]}}");
{'fraction_non_alphanumeric': 0.10176820322755, 'fraction_numerical': 0.004941703343371168, 'mean_word_length': 1.8095444685466378, 'pattern_counts': {'":': 18, '<': 18, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3229454', 'n_tokens_mistral': 3184, 'n_tokens_neox': 2998, 'n_words': 638}