package com.drumonii.loltrollbuild.controller.admin;

import com.drumonii.loltrollbuild.config.WebSecurityConfig.UserRole;
import com.drumonii.loltrollbuild.security.login.LoginResponse.LoginStatus;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.MediaType;
import org.springframework.security.test.context.support.WithAnonymousUser;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

import static com.drumonii.loltrollbuild.config.Profiles.TESTING;
import static com.drumonii.loltrollbuild.config.WebSecurityConfig.WebDevTestingSecurityConfig.IN_MEM_PASSWORD;
import static com.drumonii.loltrollbuild.config.WebSecurityConfig.WebDevTestingSecurityConfig.IN_MEM_USERNAME;
import static org.hamcrest.core.Is.is;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.formLogin;
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated;
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.unauthenticated;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@RunWith(SpringRunner.class)
@WebMvcTest(AdminLoginController.class)
@ActiveProfiles({ TESTING })
public class AdminLoginControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Value("${api.base-path}")
    private String apiPath;

    @WithAnonymousUser
    @Test
    public void adminLogin() throws Exception {
        mockMvc.perform(get("/admin/login"))
                .andExpect(forwardedUrl("/index.html"));
    }

    @Test
    public void adminLoginWithValidCredentials() throws Exception {
        mockMvc.perform(formLogin(apiPath + "/admin/login")
                .user(IN_MEM_USERNAME)
                .password(IN_MEM_PASSWORD))
                .andExpect(authenticated()
                        .withAuthenticationName("admin")
                        .withRoles(UserRole.ADMIN))
                .andExpect(status().isOk())
                .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
                .andExpect(jsonPath("$.status", is(LoginStatus.SUCCESS.name())))
                .andExpect(jsonPath("$.message").exists())
                .andExpect(jsonPath("$.userDetails").exists())
                .andExpect(jsonPath("$.userDetails.username").exists())
                .andExpect(jsonPath("$.userDetails.authorities").isArray())
                .andExpect(jsonPath("$.userDetails.authorities[0].authority", is("ROLE_" + UserRole.ADMIN)))
                .andExpect(jsonPath("$.userDetails.password").doesNotExist())
                .andExpect(jsonPath("$.userDetails.enabled").doesNotExist())
                .andExpect(jsonPath("$.userDetails.accountNonExpired").doesNotExist())
                .andExpect(jsonPath("$.userDetails.accountNonLocked").doesNotExist())
                .andExpect(jsonPath("$.userDetails.credentialsNonExpired").doesNotExist());
    }

    @Test
    public void adminLoginWithInvalidCredentials() throws Exception {
        mockMvc.perform(formLogin(apiPath + "/admin/login")
                .user("bad_username")
                .password("bad_password"))
                .andExpect(unauthenticated())
                .andExpect(status().isOk())
                .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
                .andExpect(jsonPath("$.status", is(LoginStatus.FAILED.name())))
                .andExpect(jsonPath("$.message").exists());
    }

}
@@ -47,16 +47,80 @@
 admin;%0A%0A
+import com.drumonii.loltrollbuild.annotation.WithMockAdminUser;%0A
 import c
@@ -256,16 +256,95 @@
 Status;%0A
+import com.drumonii.loltrollbuild.security.logout.LogoutResponse.LogoutStatus;%0A
 import o
@@ -1315,16 +1315,127 @@
 mLogin;%0A
+import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;%0A
 import s
@@ -1743,16 +1743,104 @@
 rs.get;%0A
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;%0A
 import s
@@ -4277,9 +4277,1283 @@
 %0A    %7D%0A%0A
-%7D
+    @WithMockAdminUser%0A    @Test%0A    public void adminLogout() throws Exception %7B%0A        mockMvc.perform(post(%22%7BbaseUrl%7D/admin/logout%22, apiPath).with(csrf())%0A                .accept(MediaType.APPLICATION_JSON))%0A                .andExpect(unauthenticated())%0A                .andExpect(status().isOk())%0A                .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))%0A                .andExpect(jsonPath(%22$.status%22, is(LogoutStatus.SUCCESS.name())))%0A                .andExpect(jsonPath(%22$.message%22).exists())%0A                .andExpect(jsonPath(%22$.userDetails%22).exists())%0A                .andExpect(jsonPath(%22$.userDetails.username%22).exists())%0A                .andExpect(jsonPath(%22$.userDetails.authorities%22).isArray())%0A                .andExpect(jsonPath(%22$.userDetails.authorities%5B0%5D.authority%22, is(%22ROLE_%22 + UserRole.ADMIN)))%0A                .andExpect(jsonPath(%22$.userDetails.password%22).doesNotExist())%0A                .andExpect(jsonPath(%22$.userDetails.enabled%22).doesNotExist())%0A                .andExpect(jsonPath(%22$.userDetails.accountNonExpired%22).doesNotExist())%0A                .andExpect(jsonPath(%22$.userDetails.accountNonLocked%22).doesNotExist())%0A                .andExpect(jsonPath(%22$.userDetails.credentialsNonExpired%22).doesNotExist());%0A    %7D%0A%0A%7D%0A

Add test for admin logout