package com.singlestone.contacts.controller; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.ArrayList; import java.util.List; import com.fasterxml.jackson.databind.ObjectMapper; import com.singlestone.contacts.model.Address; import com.singlestone.contacts.model.Contact; import com.singlestone.contacts.model.Name; import com.singlestone.contacts.model.Phone.Type; import com.singlestone.contacts.model.dto.CallListDTO; import com.singlestone.contacts.model.dto.ContactDTO; import com.singlestone.contacts.model.dto.PhoneDTO; import com.singlestone.contacts.service.ContactService; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @ExtendWith(MockitoExtension.class) public class ContactControllerTest { @Mock private ContactService contactService; @InjectMocks private ContactController contactController; @Autowired private MockMvc mockMvc; private ContactDTO createTestContactDTO() { ContactDTO testContactDTO = new ContactDTO(); Name name = new Name(); name.setFirst("first"); name.setMiddle("middle"); name.setLast("last"); testContactDTO.setName(name); Address address = new Address(); address.setStreet("street"); address.setCity("city"); address.setState("state"); address.setZip("zip"); List phones = new ArrayList<>(); phones.add(new PhoneDTO("111-111-1111", Type.HOME)); testContactDTO.setPhone(phones); testContactDTO.setEmail("e@mail.com"); return testContactDTO; } private static String asJsonString(final Object obj) { try{ return new ObjectMapper().writeValueAsString(obj); }catch (Exception e){ throw new RuntimeException(e); } } @BeforeEach public void setup() { mockMvc = MockMvcBuilders.standaloneSetup(contactController).build(); } @Test void testCreateContact() throws Exception { ContactDTO contactToCreate = createTestContactDTO(); when(contactService.createContact(any())).thenReturn(contactToCreate); mockMvc.perform(post("/api/v1/contacts"). contentType(MediaType.APPLICATION_JSON). content(asJsonString(contactToCreate))). andExpect(status().isCreated()); verify(contactService, times(1)).createContact(any()); } @Test void testGetAllContacts() throws Exception { ContactDTO contactToCreate = createTestContactDTO(); List contacts = new ArrayList<>(); contacts.add(contactToCreate); when(contactService.getAllContacts()).thenReturn(contacts); mockMvc.perform(get("/api/v1/contacts"). accept(MediaType.APPLICATION_JSON). content("")). andExpect(status().isOk()); verify(contactService, times(1)).getAllContacts(); } @Test void testGetAllContactsNoContactsAvailable() throws Exception { List contacts = new ArrayList<>(); when(contactService.getAllContacts()).thenReturn(contacts); mockMvc.perform(get("/api/v1/contacts"). accept(MediaType.APPLICATION_JSON). content("")). andExpect(status().isNoContent()); verify(contactService, times(1)).getAllContacts(); } @Test void testGetContact() throws Exception { ContactDTO contactToGet = createTestContactDTO(); when(contactService.getContact(anyLong())).thenReturn(contactToGet); mockMvc.perform(get("/api/v1/contacts/1"). accept(MediaType.APPLICATION_JSON). content("")). andExpect(status().isOk()); verify(contactService, times(1)).getContact(anyLong()); } @Test void testGetContactDoesNotExist() throws Exception { when(contactService.getContact(anyLong())).thenReturn(null); mockMvc.perform(get("/api/v1/contacts/1"). accept(MediaType.APPLICATION_JSON). content("")). andExpect(status().isNotFound()); verify(contactService, times(1)).getContact(anyLong()); } @Test void testUpdateContact() throws Exception { ContactDTO contactToUpdate = createTestContactDTO(); when(contactService.updateContact(anyLong(), any())).thenReturn(contactToUpdate); mockMvc.perform(put("/api/v1/contacts/1"). contentType(MediaType.APPLICATION_JSON). content(asJsonString(contactToUpdate))). andExpect(status().isOk()); verify(contactService, times(1)).updateContact(anyLong(), any()); } @Test void testUpdateContactDoesNotExist() throws Exception { ContactDTO contact = createTestContactDTO(); when(contactService.updateContact(anyLong(), any())).thenReturn(null); mockMvc.perform(put("/api/v1/contacts/1"). contentType(MediaType.APPLICATION_JSON). content(asJsonString(contact))). andExpect(status().isNotFound()); verify(contactService, times(1)).updateContact(anyLong(), any()); } @Test void testDeleteContact() throws Exception { ContactDTO contactToDelete = createTestContactDTO(); when(contactService.deleteContact(anyLong())).thenReturn(contactToDelete); mockMvc.perform(delete("/api/v1/contacts/1"). accept(MediaType.APPLICATION_JSON). content("")). andExpect(status().isNoContent()); verify(contactService, times(1)).deleteContact(anyLong()); } @Test void testDeleteContactDoesNotExist() throws Exception { when(contactService.deleteContact(anyLong())).thenReturn(null); mockMvc.perform(delete("/api/v1/contacts/1"). accept(MediaType.APPLICATION_JSON). content("")). andExpect(status().isNotFound()); verify(contactService, times(1)).deleteContact(anyLong()); } @Test void testGetCallList() throws Exception { Contact contact = new Contact(createTestContactDTO()); contact.getPhone().get(0).setContact(contact); CallListDTO contactToreturn = new CallListDTO(contact.getPhone().get(0)); List contacts = new ArrayList<>(); contacts.add(contactToreturn); when(contactService.getCallList()).thenReturn(contacts); mockMvc.perform(get("/api/v1/contacts/call-list"). accept(MediaType.APPLICATION_JSON). content("")). andExpect(status().isOk()); verify(contactService, times(1)).getCallList(); } @Test void testGetCallListIsEmpty() throws Exception { List contacts = new ArrayList<>(); when(contactService.getCallList()).thenReturn(contacts); mockMvc.perform(get("/api/v1/contacts/call-list"). accept(MediaType.APPLICATION_JSON). content("")). andExpect(status().isNoContent()); verify(contactService, times(1)).getCallList(); } }