package my.ostrea.blog;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.security.test.context.support.WithUserDetails;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.*;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = BlogApplication.class)
@WebAppConfiguration
public class BlogApplicationTests {
    private MockMvc mockMvc;

    @Autowired
    private WebApplicationContext webApplicationContext;

    @Before
    public void setUp() {
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
                .apply(springSecurity())
                .build();
    }

    @Test
    public void accessingStartPageAsAnonymousShouldReturnViewNamedIndexAndModelWithZeroAttributes()
            throws Exception {
        mockMvc.perform(get("/"))
                .andExpect(status().isOk())
                .andExpect(view().name("index"))
                .andExpect(model().attributeDoesNotExist("articles"));
    }

	@Test
    @WithUserDetails("test")
	public void accessingStartPageAsLoggedUserShouldReturnViewNamedIndexAndModelWithOneAttribute() throws Exception {
        mockMvc.perform(
                get("/"))
                .andExpect(status().isOk())
                .andExpect(view().name("index"))
                .andExpect(model().attributeExists("articles"));
    }

    @Test
    public void accessingUsernamePageAsAnonymousShouldRedirectToLoginPage()
            throws Exception {
        mockMvc.perform(get("/test"))
                .andExpect(status().is3xxRedirection())
                .andExpect(redirectedUrlPattern("**/login"));
    }

    @Test
    @WithMockUser("userForTests")
    public void accessingUsernamePageAsLoggedUserIfUsernameIsNotLoggedUsernameShouldShowIndexViewWithModelWithOneAttr()
            throws Exception {
        mockMvc.perform(get("/admin"))
                .andExpect(status().isOk())
                .andExpect(view().name("index"))
                .andExpect(model().attributeExists("articles"));
    }

    @Test
    @WithMockUser("userForTests")
    public void accessingNotExistingUsernamePageAsLoggedUserShouldShowIndexViewWithModelWithZeroAttr()
            throws Exception {
        mockMvc.perform(get("/not_existing_user"))
                .andExpect(status().isOk())
                .andExpect(view().name("index"))
                .andExpect(model().attributeDoesNotExist("articles"));
    }

    @Test
    @WithUserDetails("test")
    public void accessingYourOwnUsernamePageAsLoggedUserShouldRedirectToIndex()
            throws Exception {
        mockMvc.perform(get("/test"))
                .andExpect(status().is3xxRedirection())
                .andExpect(redirectedUrl("/"));
    }

    // TODO form login tests, delete article tests
}

@@ -29,80 +29,319 @@
 ort 
-org.junit.Before;%0Aimport org.junit.Test;%0Aimport org.junit.runner.RunWith
+my.ostrea.blog.controllers.BaseController;%0Aimport my.ostrea.blog.models.ArticleRepository;%0Aimport my.ostrea.blog.models.UserRepository;%0Aimport org.junit.Before;%0Aimport org.junit.Test;%0Aimport org.junit.runner.RunWith;%0Aimport org.mockito.InjectMocks;%0Aimport org.mockito.Mock;%0Aimport org.mockito.MockitoAnnotations
 ;%0Aim
@@ -935,16 +935,44 @@
 ntext;%0A%0A
+import java.util.Iterator;%0A%0A
 import s
@@ -1228,16 +1228,87 @@
 urers.*;
+%0Aimport static org.mockito.Mockito.*;%0Aimport static org.junit.Assert.*;
 %0A%0A@RunWi
@@ -1604,16 +1604,60 @@
 tUp() %7B%0A
+        MockitoAnnotations.initMocks(this);%0A
         
@@ -1681,16 +1681,33 @@
 Builders
+%0A                
 .webAppC
@@ -3957,10 +3957,506 @@
 e tests%0A
+    @Test%0A    @WithMockUser(%22userForTests%22)%0A    public void deletingNotExistingArticleShouldReturnNotFound() throws Exception %7B%0A        mockMvc.perform(get(%22/delete_article?article_id=-1%22))%0A                .andExpect(status().isNotFound());%0A    %7D%0A%0A    @Test%0A    @WithMockUser(%22userForTests%22)%0A    public void deletingOtherPersonArticleShouldReturnForbidden() throws Exception %7B%0A        mockMvc.perform(get(%22/delete_article?article_id=2%22))%0A                .andExpect(status().isForbidden());%0A    %7D%0A
 %7D%0A

Add test for delete