package ca.ulaval.ticketmaster.web;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.when;

import javax.servlet.http.HttpSession;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.validation.support.BindingAwareModelMap;
//import org.springframework.mock.web.MockHttpSession;
import org.springframework.mock.web.MockHttpSession;


import ca.ulaval.ticketmaster.dao.util.DataManager;
import ca.ulaval.ticketmaster.model.User;
import ca.ulaval.ticketmaster.model.User.AccessLevel;
import ca.ulaval.ticketmaster.web.viewmodels.UserViewModel;

@RunWith(MockitoJUnitRunner.class)
public class HomeControllerTest {

    @Mock
    public DataManager datamanager;

    @InjectMocks
    public HomeController controller;

    private BindingAwareModelMap model;

    @Before
    public void setUp() {
	model = new BindingAwareModelMap();
    }

    @Test
    public void createAddANewViewModelToTheModelAndCheckReturn() {

	String ret = controller.MainFrame(model);

	assertEquals(ret, "Home");
    }

    @Test
    public void testHome() {
	String ret = controller.home(model);

	assertEquals(ret, "Home");
    }

    @Test
    public void testCreateUserGET() {
	String ret = controller.CreateUser(model);

	assertNotNull(model.get("user"));
	assertEquals(ret, "CreateUser");

    }

    @Test
    public void testCreateUserPOST() {
    	
    	HttpSession httpSession = new MockHttpSession();
    	
	UserViewModel viewModel = new UserViewModel();
	viewModel.setUsername("bob");

	String ret = controller.CreateUser(viewModel, null, model, httpSession);


	assertEquals(model.get("username"), viewModel.getUsername());
	assertEquals(ret, "Home");

    }

    @Test
    public void testLoginGET() {

	String ret = controller.Login(model);

	assertEquals(ret, "Home");

    }

    @Test
    public void testSuccessfulLogin() {
    	
    	HttpSession httpSession = new MockHttpSession();
	
	String adminUsername = "CarloBoutet";
	
	User admin = new User(adminUsername);
	admin.setPassword("123");
	admin.setAccessLevel(AccessLevel.Admin);
	
	when(datamanager.findUser(adminUsername)).thenReturn(admin);
	
	//FOQQWEQEFQOF
	//when(httpSession.setAttribute("sesusername", admin.getAccessLevel().toString()).thenReturn("bob"));

	String ret = controller.Login(adminUsername, admin.getPassword(), model, httpSession);

	assertEquals(ret, "Home");

	assertNotNull(httpSession.getAttribute("sesusername"));
	assertNotNull(httpSession.getAttribute("sesacceslevel"));

	//assertNotNull(model.get("sesacceslevel"));
	//assertNotNull(model.get("sesusername"));

    }

    @Test
    public void testFailLoginWithExistingUser() {
    	
    	HttpSession httpSession = new MockHttpSession();
	
	User admin = new User("CarloBoutet");
	admin.setPassword("123");
	
	when(datamanager.findUser(admin.getUsername())).thenReturn(admin);

	String ret = controller.Login(admin.getUsername(), "NOTTHEPASSWORD", model, httpSession);

	assertEquals(ret, "Home");

	assertNull(httpSession.getAttribute("sesacceslevel"));
	assertNull(httpSession.getAttribute("sesusername"));

	//On ne verifie pas le contenu car ce serait restrictif si on change un message d'erreur
	//@TODO demander au prof
	assertNotNull(model.get("errorMsg"));
	assertNotNull(model.get("currentPage"));

    }

    @Test
    public void testFailLoginWithUnexistingUser() {
    	
    	HttpSession httpSession = new MockHttpSession();

	String ret = controller.Login("HEY!!", "FFFFFFUUUUUUUUU", model, httpSession);

	assertEquals(ret, "Home");

	assertNull(httpSession.getAttribute("sesacceslevel"));
	assertNull(httpSession.getAttribute("sesusername"));

	//On ne verifie pas le contenu car ce serait restrictif si on change un message d'erreur
	//@TODO demander au prof
	assertNotNull(model.get("errorMsg"));
	assertNotNull(model.get("currentPage"));

    }

    @Test
    public void testDisconnect() {
    	
    	HttpSession httpSession = new MockHttpSession();
    	
	String ret = controller.Disconnect(model, /* ehm... null*/httpSession);
	
	assertNull(httpSession.getAttribute("sesacceslevel"));
	assertNull(httpSession.getAttribute("sesusername"));

	assertEquals(ret, "Home");

    }
    
    @Test
    public void testBasket() {
    	
    	HttpSession httpSession = new MockHttpSession();
    	
    	String ret = controller.Basket(model, httpSession);
    	
    	assertEquals(model.get("currentPage"), "Basket.jsp");

    	assertEquals(ret, "Basket");
    }

}

@@ -203,16 +203,56 @@
 to.when;
+%0Aimport static org.mockito.Mockito.mock;
 %0A%0Aimport
@@ -466,24 +466,77 @@
 UnitRunner;%0A
+import org.springframework.validation.BindingResult;%0A
 import org.s
@@ -701,16 +701,20 @@
 sion;%0A%0A%0A
+%0A%0A%0A%0A
 import c
@@ -853,16 +853,132 @@
 sLevel;%0A
+import ca.ulaval.ticketmaster.web.DomaineAffaire.DAUser;%0Aimport ca.ulaval.ticketmaster.web.converter.UserConverter;%0A
 import c
@@ -1145,16 +1145,62 @@
 manager;
+%0A    %0A    @InjectMocks%0A%09public DAUser domaine;
 %0A%0A    @I
@@ -1857,24 +1857,116 @@
 serPOST() %7B%0A
+    %09//Je test directement dans le domaine, puisque le controlleur ne fait qu'un appel .. ?%0A
     %09%0A    %09H
@@ -2102,35 +2102,197 @@
 %22);%0A
-%0A%09String ret = controller.C
+%09%0A    BindingResult result = mock(BindingResult.class);%0A    %0A    User user = UserConverter.convert(viewModel);%0A%09%0A%09when(datamanager.saveUser(user)).thenReturn(true);%0A%0A%09String ret = domaine.c
 reat
@@ -2297,16 +2297,22 @@
 ateUser(
+user, 
 viewMode
@@ -2317,21 +2317,23 @@
 del,
- null,
  model,
+ result,
  htt
@@ -2346,16 +2346,18 @@
 on);%0A%0A%0A%09
+//
 assertEq
@@ -2368,24 +2368,27 @@
 (model.get(%22
+ses
 username%22), 
@@ -2409,24 +2409,100 @@
 sername());%0A
+%09assertEquals(httpSession.getAttribute(%22sesusername%22), user.getUsername());%0A
 %09assertEqual

Test HomeController (incomplet; mais wtf le 2e "niveau" amener)