package org.synyx.urlaubsverwaltung.person.api;

import org.junit.Before;
import org.junit.Test;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.synyx.urlaubsverwaltung.person.Person;
import org.synyx.urlaubsverwaltung.person.PersonService;
import org.synyx.urlaubsverwaltung.api.ApiExceptionHandlerControllerAdvice;
import org.synyx.urlaubsverwaltung.testdatacreator.TestDataCreator;

import java.util.Arrays;
import java.util.Optional;

import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;


public class PersonApiControllerTest {

    private MockMvc mockMvc;

    private PersonService personServiceMock;

    @Before
    public void setUp() {

        personServiceMock = mock(PersonService.class);

        mockMvc = MockMvcBuilders.standaloneSetup(new PersonApiController(personServiceMock))
            .setControllerAdvice(new ApiExceptionHandlerControllerAdvice())
                .build();
    }


    @Test
    public void ensureReturnsAllActivePersons() throws Exception {

        Person person1 = TestDataCreator.createPerson("foo");
        Person person2 = TestDataCreator.createPerson("bar");

        when(personServiceMock.getActivePersons()).thenReturn(Arrays.asList(person1, person2));

        mockMvc.perform(get("/api/persons"))
            .andExpect(status().isOk())
            .andExpect(content().contentType("application/json;charset=UTF-8"))
            .andExpect(jsonPath("$.response").exists())
            .andExpect(jsonPath("$.response.persons").exists())
            .andExpect(jsonPath("$.response.persons", hasSize(2)));

        verify(personServiceMock).getActivePersons();
    }


    @Test
    public void ensureReturnsListWithOneElementIfLoginNameSpecified() throws Exception {

        Person person = TestDataCreator.createPerson("muster");
        when(personServiceMock.getPersonByLogin(anyString())).thenReturn(Optional.of(person));

        mockMvc.perform(get("/api/persons").param("ldap", "muster"))
            .andExpect(status().isOk())
            .andExpect(content().contentType("application/json;charset=UTF-8"))
            .andExpect(jsonPath("$.response").exists())
            .andExpect(jsonPath("$.response.persons").exists())
            .andExpect(jsonPath("$.response.persons", hasSize(1)))
            .andExpect(jsonPath("$.response.persons[0].ldapName", is("muster")));

        verify(personServiceMock).getPersonByLogin("muster");
    }


    @Test
    public void ensureReturnsEmptyListForUnknownLoginName() throws Exception {

        when(personServiceMock.getPersonByLogin(anyString())).thenReturn(Optional.empty());

        mockMvc.perform(get("/api/persons").param("ldap", "muster"))
            .andExpect(status().isOk())
            .andExpect(content().contentType("application/json;charset=UTF-8"))
            .andExpect(jsonPath("$.response").exists())
            .andExpect(jsonPath("$.response.persons").exists())
            .andExpect(jsonPath("$.response.persons", hasSize(0)));

        verify(personServiceMock).getPersonByLogin("muster");
    }
}

@@ -2046,35 +2046,29 @@
 nPath(%22$
-.response%22).exists(
+%22, hasSize(2)
 ))%0A     
@@ -2101,34 +2101,33 @@
 (%22$.
-response.persons%22).exists(
+%5B0%5D.firstName%22, is(%22Foo%22)
 ))%0A 
@@ -2164,93 +2164,100 @@
 (%22$.
-response.persons%22, hasSize(2)));%0A%0A        verify(personServiceMock).getActivePersons(
+%5B1%5D.lastName%22, is(%22Bar%22)))%0A            .andExpect(jsonPath(%22$.%5B0%5D.email%22, is(%22foo@test.de%22))
 );%0A 
@@ -2254,33 +2254,32 @@
 .de%22)));%0A    %7D%0A%0A
-%0A
     @Test%0A    pu
@@ -2304,47 +2304,22 @@
 turn
-sListWithOneElementIfLoginNameSpecified
+SpecificPerson
 () t
@@ -2358,16 +2358,17 @@
 n person
+1
  = TestD
@@ -2396,569 +2396,39 @@
 on(%22
-muster%22);%0A        when(personServiceMock.getPersonByLogin(anyString())).thenReturn(Optional.of(person));%0A%0A        mockMvc.perform(get(%22/api/persons%22).param(%22ldap%22, %22muster%22))%0A            .andExpect(status().isOk())%0A            .andExpect(content().contentType(%22application/json;charset=UTF-8%22))%0A            .andExpect(jsonPath(%22$.response%22).exists())%0A            .andExpect(jsonPath(%22$.response.persons%22).exists())%0A            .andExpect(jsonPath(%22$.response.persons%22, hasSize(1)))%0A            .andExpect(jsonPath(%22$.response.persons%5B0%5D.ldapName%22, is(%22muster%22))
+foo%22);%0A        person1.setId(42
 );%0A%0A
@@ -2427,38 +2427,36 @@
 d(42);%0A%0A        
-verify
+when
 (personServiceMo
@@ -2449,33 +2449,32 @@
 ersonServiceMock
-)
 .getPersonByLogi
@@ -2473,180 +2473,24 @@
 onBy
-Login(%22muster%22);%0A    %7D%0A%0A%0A    @Test%0A    public void ensureReturnsEmptyListForUnknownLoginName() throws Exception %7B%0A%0A        when(personServiceMock.getPersonByLogin(anyString
+ID(person1.getId
 ()))
@@ -2514,14 +2514,18 @@
 nal.
-empty(
+of(person1
 ));%0A
@@ -2570,32 +2570,11 @@
 sons
-%22).param(%22ldap%22, %22muster
+/42
 %22))%0A
@@ -2732,26 +2732,29 @@
 (%22$.
-response%22).exists(
+firstName%22, is(%22Foo%22)
 ))%0A 
@@ -2791,34 +2791,28 @@
 (%22$.
-response.persons%22).exists(
+lastName%22, is(%22Foo%22)
 ))%0A 
@@ -2849,101 +2849,34 @@
 (%22$.
-response.persons%22, hasSize(0)));%0A%0A        verify(personServiceMock).getPersonByLogin(%22muster%22
+email%22, is(%22foo@test.de%22))
 );%0A 
@@ -2880,10 +2880,12 @@
 ;%0A    %7D%0A
+%0A%0A
 %7D%0A

test coverage for new persons api