diff --git a/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/controller/PreferenceControllerTest.java b/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/controller/PreferenceControllerTest.java new file mode 100644 index 0000000..de56c65 --- /dev/null +++ b/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/controller/PreferenceControllerTest.java @@ -0,0 +1,72 @@ +package fr.vincent.ramiere.mangerautourdesimplonback.controller; + +import fr.vincent.ramiere.mangerautourdesimplonback.models.Preference; +import fr.vincent.ramiere.mangerautourdesimplonback.service.PreferenceService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import java.util.Collections; +import java.util.Optional; +import static org.mockito.Mockito.times; +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.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +class PreferenceControllerTest { + + private PreferenceService preferenceService; + private MockMvc mockMvc; + + @BeforeEach + void setup() { + preferenceService = Mockito.mock(PreferenceService.class); + PreferenceController controller = new PreferenceController(preferenceService); + mockMvc = MockMvcBuilders.standaloneSetup(controller).build(); + } + + @Test + void getPreferencesByPersonneId_shouldReturnOkAndCallService() throws Exception { + when(preferenceService.getPreferencesByPersonneId(42)).thenReturn(Collections.emptyList()); + + mockMvc.perform(get("/api/v1/preferences/user/42")) + .andExpect(status().isOk()); + + verify(preferenceService, times(1)).getPreferencesByPersonneId(42); + } + + @Test + void saveOrUpdatePreference_shouldReturnNotFound_whenServiceReturnsEmpty() throws Exception { + when(preferenceService.saveOrUpdatePreference(1, 2, 5, true)) + .thenReturn(Optional.empty()); + + String json = "{\"personneId\":1,\"restaurantId\":2,\"note\":5,\"favori\":true}"; + + mockMvc.perform(put("/api/v1/preferences") + .contentType(MediaType.APPLICATION_JSON) + .content(json)) + .andExpect(status().isNotFound()); + + verify(preferenceService, times(1)).saveOrUpdatePreference(1, 2, 5, true); + } + + @Test + void saveOrUpdatePreference_shouldReturnOk_whenServiceReturnsPreference() throws Exception { + Preference prefMock = Mockito.mock(Preference.class); + when(preferenceService.saveOrUpdatePreference(7, 8, 3, false)) + .thenReturn(Optional.of(prefMock)); + + String json = "{\"personneId\":7,\"restaurantId\":8,\"note\":3,\"favori\":false}"; + + mockMvc.perform(put("/api/v1/preferences") + .contentType(MediaType.APPLICATION_JSON) + .content(json)) + .andExpect(status().isOk()); + + verify(preferenceService, times(1)).saveOrUpdatePreference(7, 8, 3, false); + } +} diff --git a/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/models/PreferencePKTest.java b/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/models/PreferencePKTest.java new file mode 100644 index 0000000..0c83749 --- /dev/null +++ b/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/models/PreferencePKTest.java @@ -0,0 +1,48 @@ +package fr.vincent.ramiere.mangerautourdesimplonback.models; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; + +class PreferencePKTest { + + @Test + void noArgsConstructor_settersAndGetters_handleNulls() { + PreferencePK pk = new PreferencePK(); + // initially null + assertNull(pk.getPersonne()); + assertNull(pk.getRestau()); + + // set to null explicitly and verify + pk.setPersonne(null); + pk.setRestau(null); + assertNull(pk.getPersonne()); + assertNull(pk.getRestau()); + } + + @Test + void equals_and_hashCode_withBothFieldsNull_areEqual() { + PreferencePK a = new PreferencePK(); + PreferencePK b = new PreferencePK(); + + // Both have null personne and restau -> should be equal and have same hashCode + assertEquals(a, b); + assertEquals(b, a); + assertEquals(a.hashCode(), b.hashCode()); + + // reflexive + assertEquals(a, a); + } + + @Test + void equals_withSameReference_isTrue_and_hashCodeStable() { + PreferencePK original = new PreferencePK(); + PreferencePK sameRef = original; + + assertEquals(original, sameRef); + assertEquals(original.hashCode(), sameRef.hashCode()); + + int firstHash = original.hashCode(); + int secondHash = original.hashCode(); + assertEquals(firstHash, secondHash, "hashCode should be stable across invocations"); + } +} diff --git a/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/models/PreferenceTest.java b/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/models/PreferenceTest.java new file mode 100644 index 0000000..dc8d2e1 --- /dev/null +++ b/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/models/PreferenceTest.java @@ -0,0 +1,65 @@ + +package fr.vincent.ramiere.mangerautourdesimplonback.models; + +import org.junit.jupiter.api.Test; +import java.io.*; +import static org.junit.jupiter.api.Assertions.*; + +class PreferenceTest { + + @Test + void defaultConstructor_and_setters_getters() { + Preference p = new Preference(); + assertNull(p.getPreferencePK()); + assertNull(p.getNote()); + assertNull(p.getFavori()); + + p.setNote(5); + p.setFavori(Boolean.TRUE); + + assertEquals(5, p.getNote()); + assertTrue(p.getFavori()); + } + + @Test + void allArgsConstructor_setsFieldsInOrder() { + // AllArgsConstructor order is (PreferencePK preferencePK, Integer note, Boolean + // favori) + Preference p = new Preference(null, 3, Boolean.FALSE); + + assertNull(p.getPreferencePK()); + assertEquals(3, p.getNote()); + assertFalse(p.getFavori()); + } + + @Test + void singleArgConstructor_setsOnlyPreferencePK() { + Preference p = new Preference((PreferencePK) null); + + assertNull(p.getPreferencePK()); + // other fields remain null when not provided + assertNull(p.getNote()); + assertNull(p.getFavori()); + } + + @Test + void implementsSerializable_and_canBeSerialized() throws Exception { + Preference original = new Preference(null, 4, Boolean.TRUE); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + try (ObjectOutputStream oos = new ObjectOutputStream(bos)) { + oos.writeObject(original); + } + + byte[] bytes = bos.toByteArray(); + try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes))) { + Object obj = ois.readObject(); + assertTrue(obj instanceof Preference); + Preference deserialized = (Preference) obj; + + assertEquals(original.getPreferencePK(), deserialized.getPreferencePK()); + assertEquals(original.getNote(), deserialized.getNote()); + assertEquals(original.getFavori(), deserialized.getFavori()); + } + } +} diff --git a/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/services/PreferenceServiceTest.java b/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/services/PreferenceServiceTest.java new file mode 100644 index 0000000..dc05244 --- /dev/null +++ b/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/services/PreferenceServiceTest.java @@ -0,0 +1,116 @@ +package fr.vincent.ramiere.mangerautourdesimplonback.services; + +import fr.vincent.ramiere.mangerautourdesimplonback.models.Personne; +import fr.vincent.ramiere.mangerautourdesimplonback.models.Preference; +import fr.vincent.ramiere.mangerautourdesimplonback.models.PreferencePK; +import fr.vincent.ramiere.mangerautourdesimplonback.models.Restaurant; +import fr.vincent.ramiere.mangerautourdesimplonback.repository.PersonneRepository; +import fr.vincent.ramiere.mangerautourdesimplonback.repository.PreferenceRepository; +import fr.vincent.ramiere.mangerautourdesimplonback.repository.RestaurantRepository; +import fr.vincent.ramiere.mangerautourdesimplonback.service.PreferenceService; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import java.util.List; +import java.util.Optional; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +/** + * Unit tests for PreferenceService. + */ +@ExtendWith(MockitoExtension.class) +class PreferenceServiceTest { + + @Mock + private PreferenceRepository preferenceRepository; + + @Mock + private PersonneRepository personneRepository; + + @Mock + private RestaurantRepository restaurantRepository; + + @InjectMocks + private PreferenceService preferenceService; + + @Test + void getPreferencesByPersonneId_returnsListFromRepository() { + Personne p = mock(Personne.class); + Restaurant r = mock(Restaurant.class); + Preference pref = new Preference(new PreferencePK(p, r)); + List expected = List.of(pref); + + when(preferenceRepository.findByPreferencePK_Personne_Id(1)).thenReturn(expected); + + List result = preferenceService.getPreferencesByPersonneId(1); + + assertSame(expected, result); + verify(preferenceRepository, times(1)).findByPreferencePK_Personne_Id(1); + } + + @Test + void saveOrUpdatePreference_whenPersonMissing_returnsEmpty() { + when(personneRepository.findById(1)).thenReturn(Optional.empty()); + // restaurant repo may or may not be called; service checks person first + Optional result = preferenceService.saveOrUpdatePreference(1, 2, 5, true); + + assertTrue(result.isEmpty()); + verify(personneRepository, times(1)).findById(1); + verifyNoInteractions(preferenceRepository); + } + + @Test + void saveOrUpdatePreference_createsNewPreference_andSavesIt() { + Personne personne = new Personne(); + Restaurant restaurant = new Restaurant(); + + when(personneRepository.findById(10)).thenReturn(Optional.of(personne)); + when(restaurantRepository.findById(20)).thenReturn(Optional.of(restaurant)); + when(preferenceRepository.findById(any(PreferencePK.class))).thenReturn(Optional.empty()); + when(preferenceRepository.save(any(Preference.class))).thenAnswer(invocation -> invocation.getArgument(0)); + + Optional result = preferenceService.saveOrUpdatePreference(10, 20, 4, Boolean.TRUE); + + assertTrue(result.isPresent()); + Preference saved = result.get(); + // assume typical getter names getNote/getFavori exist on Preference + assertEquals(4, saved.getNote()); + assertEquals(Boolean.TRUE, saved.getFavori()); + + ArgumentCaptor captor = ArgumentCaptor.forClass(Preference.class); + verify(preferenceRepository, times(1)).save(captor.capture()); + Preference captured = captor.getValue(); + assertEquals(4, captured.getNote()); + assertEquals(Boolean.TRUE, captured.getFavori()); + } + + @Test + void saveOrUpdatePreference_updatesExistingPreference_andSavesIt() { + Personne personne = new Personne(); + Restaurant restaurant = new Restaurant(); + PreferencePK pk = new PreferencePK(personne, restaurant); + Preference existing = new Preference(pk); + existing.setNote(1); + existing.setFavori(false); + + when(personneRepository.findById(7)).thenReturn(Optional.of(personne)); + when(restaurantRepository.findById(8)).thenReturn(Optional.of(restaurant)); + when(preferenceRepository.findById(any(PreferencePK.class))).thenReturn(Optional.of(existing)); + when(preferenceRepository.save(any(Preference.class))).thenAnswer(invocation -> invocation.getArgument(0)); + + Optional result = preferenceService.saveOrUpdatePreference(7, 8, 10, Boolean.TRUE); + + assertTrue(result.isPresent()); + Preference updated = result.get(); + assertSame(existing, updated); + assertEquals(10, updated.getNote()); + assertEquals(Boolean.TRUE, updated.getFavori()); + + verify(preferenceRepository, times(1)).save(existing); + } +}