package org.innovateuk.ifs.registration.controller;

import org.innovateuk.ifs.AbstractApplicationMockMVCTest;
import org.innovateuk.ifs.filter.CookieFlashMessageFilter;
import org.innovateuk.ifs.registration.form.OrganisationTypeForm;
import org.innovateuk.ifs.registration.service.RegistrationCookieService;
import org.innovateuk.ifs.util.EncryptedCookieService;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.test.context.TestPropertySource;
import org.springframework.validation.Validator;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Optional;

import static org.innovateuk.ifs.util.CookieTestUtil.encryptor;
import static org.innovateuk.ifs.util.CookieTestUtil.setupEncryptedCookieService;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@RunWith(MockitoJUnitRunner.Silent.class)
@TestPropertySource(locations = "classpath:application.properties")
public class OrganisationCreationContributorTypeControllerTest extends AbstractApplicationMockMVCTest<OrganisationCreationContributorTypeController> {

    @Mock
    private Validator validator;

    @Mock
    private CookieFlashMessageFilter cookieFlashMessageFilter;

    @Mock
    private RegistrationCookieService registrationCookieService;

    @Mock
    private EncryptedCookieService cookieUtil;

    @Override
    protected OrganisationCreationContributorTypeController supplyControllerUnderTest() {
        return new OrganisationCreationContributorTypeController();
    }

    @Before
    public void setUpData() {

        this.setupCompetition();
        this.setupApplicationWithRoles();
        this.setupApplicationResponses();
        this.setupFinances();
        this.setupInvites();
        this.setupOrganisationTypes();
        setupEncryptedCookieService(cookieUtil);

        when(registrationCookieService.getInviteHashCookieValue(any(HttpServletRequest.class))).thenReturn(Optional.of(INVITE_HASH));
    }

    @Test
    public void chooseOrganisationType() throws Exception {
        mockMvc.perform(
                get("/organisation/create/contributor-organisation-type")
                        .cookie(new Cookie(RegistrationCookieService.INVITE_HASH, encryptor.encrypt(INVITE_HASH)))
        )
                .andExpect(status().is2xxSuccessful())
                .andExpect(view().name("registration/organisation/contributor-organisation-type"))
                .andExpect(model().attributeExists("form", "model"));
    }

    /**
     * Test if the request is redirected forward, to the organisation creation controller.
     */
    @Test
    public void chooseOrganisationTypePostBusiness() throws Exception {
        mockMvc.perform(
                post("/organisation/create/contributor-organisation-type")
                        .cookie(new Cookie(RegistrationCookieService.INVITE_HASH, encryptor.encrypt(INVITE_HASH)))
                        .param("organisationType", "1")

        )
                .andExpect(status().is3xxRedirection())
                .andExpect(view().name("redirect:/organisation/create/find-organisation"))
                .andReturn();

        verify(registrationCookieService, times(1)).saveToOrganisationTypeCookie(any(OrganisationTypeForm.class), any(HttpServletResponse.class));
    }


    /**
     * test if request is redirected back to the form for selecting the subtype of research.
     */
    @Test
    public void chooseOrganisationTypePostResearch() throws Exception {
        mockMvc.perform(
                post("/organisation/create/contributor-organisation-type")
                        .cookie(new Cookie(RegistrationCookieService.INVITE_HASH, encryptor.encrypt(INVITE_HASH)))
                        .param("organisationType", "2")

        )
                .andExpect(status().is3xxRedirection())
                .andExpect(view().name("redirect:/organisation/create/find-organisation"))
                .andReturn();

        verify(registrationCookieService, times(1)).saveToOrganisationTypeCookie(any(OrganisationTypeForm.class), any(HttpServletResponse.class));
    }
}
@@ -42,24 +42,72 @@
 ontroller;%0A%0A
+import com.google.common.collect.ImmutableList;%0A
 import org.i
@@ -207,24 +207,98 @@
 sageFilter;%0A
+import org.innovateuk.ifs.organisation.resource.OrganisationTypeResource;%0A
 import org.i
@@ -394,41 +394,221 @@
 ion.
-service.RegistrationCookieService
+populator.OrganisationCreationSelectTypePopulator;%0Aimport org.innovateuk.ifs.registration.service.RegistrationCookieService;%0Aimport org.innovateuk.ifs.registration.viewmodel.OrganisationCreationSelectTypeViewModel
 ;%0Aim
@@ -1871,17 +1871,16 @@
 idator;%0A
-%0A
     @Moc
@@ -1944,17 +1944,16 @@
 Filter;%0A
-%0A
     @Moc
@@ -2019,17 +2019,16 @@
 ervice;%0A
-%0A
     @Moc
@@ -2075,16 +2075,119 @@
 kieUtil;
+%0A    @Mock%0A    private OrganisationCreationSelectTypePopulator organisationCreationSelectTypePopulator;
 %0A%0A    @O
@@ -2870,32 +2870,526 @@
 ows Exception %7B%0A
+        OrganisationTypeResource organisationTypeResource = new OrganisationTypeResource();%0A        organisationTypeResource.setName(%22org type%22);%0A        organisationTypeResource.setId(1L);%0A%0A        OrganisationCreationSelectTypeViewModel organisationCreationSelectTypeViewModel = new OrganisationCreationSelectTypeViewModel(ImmutableList.of(organisationTypeResource));%0A        when(organisationCreationSelectTypePopulator.populate(any())).thenReturn(organisationCreationSelectTypeViewModel);%0A%0A
         mockMvc.

fix broken test requiring org type populator