public async Task LoginWithUnknonUser()
        {
            using (var client = _server.AcceptJson())
            {
                // login with Unknown User
                var loginFormUnkownUser = new UserForm { Username = "******", Password = "******" };

                var loginResponse = await client.PostAsJsonAsync("/api/sessions", loginFormUnkownUser);
                Assert.Equal(HttpStatusCode.NotFound, loginResponse.StatusCode);

                var created = await loginResponse.Content.ReadAsJsonAsync<ApiError>();
                Assert.Equal("No such Player found.", created.Error);
            }
        }
        public async Task LoginWithInvalidPassword()
        {
            using (var client = _server.AcceptJson())
            {
                // login with Invalid Password
                var loginFormInvalidPassword = new UserForm { Username = "******", Password = "******" };

                var loginResponse = await client.PostAsJsonAsync("/api/sessions", loginFormInvalidPassword);
                Assert.Equal(HttpStatusCode.Unauthorized, loginResponse.StatusCode);

                var created = await loginResponse.Content.ReadAsJsonAsync<ApiError>();
                Assert.Equal("Invalid Login Details.", created.Error);
            }
        }
        public async Task LoginWithEmptyForm()
        {
            using (var client = _server.AcceptJson())
            {
                // login with Empty UserForm
                var loginFormEmpty = new UserForm();

                var loginResponse = await client.PostAsJsonAsync("/api/sessions", loginFormEmpty);
                Assert.Equal(HttpStatusCode.BadRequest, loginResponse.StatusCode);

                var created = await loginResponse.Content.ReadAsJsonAsync<ApiError>();
                Assert.Equal("Either Username or Email is required.", created.Error);
            }
        }
        public async Task LoginWithNoPassword()
        {
            using (var client = _server.AcceptJson())
            {
                // login with No Password
                var loginWithNoPassword = new UserForm { Username = "******" };

                var loginResponse = await client.PostAsJsonAsync("/api/sessions", loginWithNoPassword);
                Assert.Equal(HttpStatusCode.BadRequest, loginResponse.StatusCode);

                var created = await loginResponse.Content.ReadAsJsonAsync<ApiError>();
                Assert.Equal("Password is required.", created.Error);
            }
        }
        protected async Task<Session> Login(string username = "******", string password = "******")
        {
            using (var client = new HttpClient { BaseAddress = new Uri(ServerUrl) })
            {
                client.AcceptJson();

                // login 
                var loginForm = new UserForm { Username = username, Password = password };

                var loginResponse = await client.PostAsJsonAsync("/api/sessions", loginForm);
                Assert.True(loginResponse.IsSuccessStatusCode);

                var created = await loginResponse.Content.ReadAsJsonAsync<Session>();

                return created;
            }
        }
        public async Task AddActivityGoal_InvalidId()
        {
            var session = await Login();

            using (var client = new HttpClient { BaseAddress = new Uri(ServerUrl) })
            {
                client.AcceptJson().AddSessionHeader(session.Id);

                var form = new UserForm();

                // Add Activity Goal with invalid Id
                var invalidId = Guid.NewGuid();
                var activityResponse = await client.PutAsJsonAsync($"/api/activities/{invalidId}/goal", form);
                Assert.Equal(HttpStatusCode.NotFound, activityResponse.StatusCode);

                var content = await activityResponse.Content.ReadAsJsonAsync<ApiError>();
                Assert.Equal("No such Activity found.", content.Error);
            }
        }
        public async Task LoginThenObtainSession()
        {
            using (var client = _server.AcceptJson())
            {
                // login
                var loginForm = new UserForm { Username = "******", Password = "******" };

                var loginResponse = await client.PostAsJsonAsync("/api/sessions", loginForm);
                Assert.True(loginResponse.IsSuccessStatusCode);

                var created = await loginResponse.Content.ReadAsJsonAsync<Session>();
                Assert.NotEqual(Guid.Empty, created.Id);
                Assert.Equal(loginForm.Username, created.Player.Username);

                // get session
                var sessionResponse = await client.GetAsync($"/api/sessions/{created.Id}");
                Assert.True(sessionResponse.IsSuccessStatusCode);

                var fetched = await sessionResponse.Content.ReadAsJsonAsync<Session>();
                Assert.Equal(created.Id, fetched.Id);
                Assert.Equal(loginForm.Username, fetched.Player.Username);
            }
        }
        public async Task DeleteValidPlayer()
        {
            var session = await Login();
            var currentSeed = Guid.NewGuid();

            using (var client = new HttpClient { BaseAddress = new Uri(ServerUrl) })
            {
                client.AcceptJson().AddSessionHeader(session.Id);

                var form = new UserForm
                {
                    Username = $"Test.{currentSeed}",
                    Email = $"test.{currentSeed}@playgen.com",
                    Password = "******"
                };

                // Add Player with valid data
                var playerResponse = await client.PostAsJsonAsync($"/api/players", form);
                Assert.Equal(HttpStatusCode.Created, playerResponse.StatusCode);

                var player = await playerResponse.Content.ReadAsJsonAsync<Player>();
                Assert.Equal($"Test.{currentSeed}", player.Username);

                // Delete Player
                playerResponse = await client.DeleteAsync($"/api/players/{player.Id}");
                Assert.Equal(HttpStatusCode.OK, playerResponse.StatusCode);

                player = await playerResponse.Content.ReadAsJsonAsync<Player>();
                Assert.False(player.IsEnabled);
            }
        }
        public async Task UpdatePlayerWithExistingEmail()
        {
            var session = await Login();

            using (var client = new HttpClient { BaseAddress = new Uri(ServerUrl) })
            {
                client.AcceptJson().AddSessionHeader(session.Id);

                var form = new UserForm { Email = "*****@*****.**" };

                // Update Player with existing Email
                var playerResponse = await client.PutAsJsonAsync($"/api/players/{session.Player.Id}", form);
                Assert.Equal(HttpStatusCode.BadRequest, playerResponse.StatusCode);

                var content = await playerResponse.Content.ReadAsJsonAsync<ApiError>();
                Assert.Equal("Player with this Email already exists.", content.Error);
            }
        }
        public async Task UpdatePlayerWithInvaliId()
        {
            var session = await Login();
            var invalidId = Guid.NewGuid();

            using (var client = new HttpClient { BaseAddress = new Uri(ServerUrl) })
            {
                client.AcceptJson().AddSessionHeader(session.Id);

                var form = new UserForm();

                // Update Player with invalid Id
                var playerResponse = await client.PutAsJsonAsync($"/api/players/{invalidId}", form);
                Assert.Equal(HttpStatusCode.NotFound, playerResponse.StatusCode);

                var content = await playerResponse.Content.ReadAsJsonAsync<ApiError>();
                Assert.Equal("No such Player found.", content.Error);
            }
        }
        public async Task UpdatePlayerWithoutId()
        {
            using (var client = new HttpClient { BaseAddress = new Uri(ServerUrl) })
            {
                var form = new UserForm();

                // Update Player without Id
                var playerResponse = await client.PutAsJsonAsync($"/api/players", form);
                Assert.Equal(HttpStatusCode.NotFound, playerResponse.StatusCode);
            }
        }
        public async Task AddPlayer()
        {
            var currentSeed = Guid.NewGuid();

            using (var client = new HttpClient { BaseAddress = new Uri(ServerUrl) })
            {
                var form = new UserForm
                {
                    Username = $"Test.{currentSeed}",
                    Email = $"test.{currentSeed}@playgen.com",
                    Password = "******"
                };

                // Add Player with valid data
                var playerResponse = await client.PostAsJsonAsync($"/api/players", form);
                Assert.Equal(HttpStatusCode.Created, playerResponse.StatusCode);

                var player = await playerResponse.Content.ReadAsJsonAsync<Player>();
                Assert.Equal($"Test.{currentSeed}", player.Username);
            }
        }
        public async Task AddPlayerWithExistingEmail()
        {
            using (var client = new HttpClient { BaseAddress = new Uri(ServerUrl) })
            {
                var form = new UserForm { Email = "*****@*****.**", Password = "******" };

                // Add Player with existing Email
                var playerResponse = await client.PostAsJsonAsync($"/api/players", form);
                Assert.Equal(HttpStatusCode.BadRequest, playerResponse.StatusCode);

                var content = await playerResponse.Content.ReadAsJsonAsync<ApiError>();
                Assert.Equal("Player with this Email already exists.", content.Error);
            }
        }
        public async Task AddPlayerWithoutPassword()
        {
            using (var client = new HttpClient { BaseAddress = new Uri(ServerUrl) })
            {
                var form = new UserForm { Username = "******" };

                // Add Player without Passwrod
                var playerResponse = await client.PostAsJsonAsync($"/api/players", form);
                Assert.Equal(HttpStatusCode.BadRequest, playerResponse.StatusCode);

                var content = await playerResponse.Content.ReadAsJsonAsync<ApiError>();
                Assert.Equal("Password is required.", content.Error);
            }
        }