1+ package com .example .Proyecto .service .Inventario .Categortiaingredientes ;
2+
3+ import com .example .Proyecto .controller .CategoriaIngredientesController ;
4+ import com .example .Proyecto .service .CategoriaIngredientesService .CategoriaIngredientes ;
5+ import com .example .Proyecto .service .CategoriaIngredientesService .CategoriaIngredientesService ;
6+ import com .fasterxml .jackson .databind .ObjectMapper ;
7+ import org .junit .jupiter .api .BeforeEach ;
8+ import org .junit .jupiter .api .DisplayName ;
9+ import org .junit .jupiter .api .Test ;
10+ import org .springframework .beans .factory .annotation .Autowired ;
11+ import org .springframework .boot .test .autoconfigure .web .servlet .WebMvcTest ;
12+ import org .springframework .http .MediaType ;
13+ import org .springframework .security .test .context .support .WithMockUser ;
14+ import org .springframework .test .context .bean .override .mockito .MockitoBean ;
15+ import org .springframework .test .web .servlet .MockMvc ;
16+
17+ import java .util .Collections ;
18+ import java .util .List ;
19+
20+ import static org .hamcrest .Matchers .*;
21+ import static org .mockito .ArgumentMatchers .any ;
22+ import static org .mockito .ArgumentMatchers .anyInt ;
23+ import static org .mockito .Mockito .*;
24+ import static org .springframework .security .test .web .servlet .request .SecurityMockMvcRequestPostProcessors .csrf ;
25+ import static org .springframework .test .web .servlet .request .MockMvcRequestBuilders .*;
26+ import static org .springframework .test .web .servlet .result .MockMvcResultMatchers .*;
27+
28+ @ WebMvcTest (CategoriaIngredientesController .class )
29+ @ DisplayName ("CategoriaIngredientesController - Pruebas de Integración Web" )
30+ class CategoriaIngredientesControllerTest {
31+
32+ @ Autowired
33+ private MockMvc mockMvc ;
34+
35+ @ MockitoBean
36+ private CategoriaIngredientesService categoriaIngredientesService ;
37+
38+ @ Autowired
39+ private ObjectMapper objectMapper ;
40+
41+ private CategoriaIngredientes categoriaHarinas ;
42+ private CategoriaIngredientes categoriaLacteos ;
43+
44+ @ BeforeEach
45+ void setUp () {
46+ categoriaHarinas = new CategoriaIngredientes ();
47+ categoriaHarinas .setIdCategoriaIngrediente (1 );
48+ categoriaHarinas .setNombreCategoria ("Harinas" );
49+
50+ categoriaLacteos = new CategoriaIngredientes ();
51+ categoriaLacteos .setIdCategoriaIngrediente (2 );
52+ categoriaLacteos .setNombreCategoria ("Lácteos" );
53+ }
54+
55+ // ─────────────────────────────────────────────
56+ // GET /categorias/ingredientes
57+ // ─────────────────────────────────────────────
58+
59+ @ Test
60+ @ DisplayName ("GET /categorias/ingredientes - retorna 200 con lista de categorías" )
61+ @ WithMockUser
62+ void obtenerTodas_retorna200_conListaDeCategorias () throws Exception {
63+ when (categoriaIngredientesService .obtenerTodasLasCategoriasIngredientes ())
64+ .thenReturn (List .of (categoriaHarinas , categoriaLacteos ));
65+
66+ mockMvc .perform (get ("/categorias/ingredientes" )
67+ .contentType (MediaType .APPLICATION_JSON ))
68+ .andExpect (status ().isOk ())
69+ .andExpect (content ().contentType (MediaType .APPLICATION_JSON ))
70+ .andExpect (jsonPath ("$" , hasSize (2 )))
71+ .andExpect (jsonPath ("$[0].idCategoriaIngrediente" , is (1 )))
72+ .andExpect (jsonPath ("$[0].nombreCategoria" , is ("Harinas" )))
73+ .andExpect (jsonPath ("$[1].idCategoriaIngrediente" , is (2 )))
74+ .andExpect (jsonPath ("$[1].nombreCategoria" , is ("Lácteos" )));
75+
76+ verify (categoriaIngredientesService , times (1 )).obtenerTodasLasCategoriasIngredientes ();
77+ }
78+
79+ @ Test
80+ @ DisplayName ("GET /categorias/ingredientes - retorna 200 con lista vacía" )
81+ @ WithMockUser
82+ void obtenerTodas_retorna200_conListaVacia () throws Exception {
83+ when (categoriaIngredientesService .obtenerTodasLasCategoriasIngredientes ())
84+ .thenReturn (Collections .emptyList ());
85+
86+ mockMvc .perform (get ("/categorias/ingredientes" )
87+ .contentType (MediaType .APPLICATION_JSON ))
88+ .andExpect (status ().isOk ())
89+ .andExpect (jsonPath ("$" , hasSize (0 )));
90+
91+ verify (categoriaIngredientesService , times (1 )).obtenerTodasLasCategoriasIngredientes ();
92+ }
93+
94+ @ Test
95+ @ DisplayName ("GET /categorias/ingredientes - retorna 401 sin autenticación" )
96+ void obtenerTodas_retorna401_sinAutenticacion () throws Exception {
97+ mockMvc .perform (get ("/categorias/ingredientes" ))
98+ .andExpect (status ().isUnauthorized ());
99+
100+ verifyNoInteractions (categoriaIngredientesService );
101+ }
102+
103+ // ─────────────────────────────────────────────
104+ // POST /nuevacategoriaingrediente
105+ // ─────────────────────────────────────────────
106+
107+ @ Test
108+ @ DisplayName ("POST /nuevacategoriaingrediente - retorna 200 con mensaje de éxito" )
109+ @ WithMockUser
110+ void crearCategoria_retorna200_conMensajeExito () throws Exception {
111+ doNothing ().when (categoriaIngredientesService ).crearCategoriaIngrediente (any (CategoriaIngredientes .class ));
112+
113+ mockMvc .perform (post ("/nuevacategoriaingrediente" )
114+ .with (csrf ())
115+ .contentType (MediaType .APPLICATION_JSON )
116+ .content (objectMapper .writeValueAsString (categoriaHarinas )))
117+ .andExpect (status ().isOk ())
118+ .andExpect (content ().string (containsString ("Harinas" )))
119+ .andExpect (content ().string (containsString ("creada con éxito" )));
120+
121+ verify (categoriaIngredientesService , times (1 )).crearCategoriaIngrediente (any (CategoriaIngredientes .class ));
122+ }
123+
124+ @ Test
125+ @ DisplayName ("POST /nuevacategoriaingrediente - retorna 401 sin autenticación" )
126+ void crearCategoria_retorna401_sinAutenticacion () throws Exception {
127+ mockMvc .perform (post ("/nuevacategoriaingrediente" )
128+ .with (csrf ())
129+ .contentType (MediaType .APPLICATION_JSON )
130+ .content (objectMapper .writeValueAsString (categoriaHarinas )))
131+ .andExpect (status ().isUnauthorized ());
132+
133+ verifyNoInteractions (categoriaIngredientesService );
134+ }
135+
136+ // ─────────────────────────────────────────────
137+ // PUT /categoriaingrediente/{id}
138+ // ─────────────────────────────────────────────
139+
140+ @ Test
141+ @ DisplayName ("PUT /categoriaingrediente/{id} - retorna 200 cuando la categoría existe" )
142+ @ WithMockUser
143+ void editarCategoria_retorna200_cuandoCategoriaExiste () throws Exception {
144+ when (categoriaIngredientesService .editarCategoriaIngrediente (any (CategoriaIngredientes .class )))
145+ .thenReturn (1 );
146+
147+ mockMvc .perform (put ("/categoriaingrediente/1" )
148+ .with (csrf ())
149+ .contentType (MediaType .APPLICATION_JSON )
150+ .content (objectMapper .writeValueAsString (categoriaHarinas )))
151+ .andExpect (status ().isOk ())
152+ .andExpect (content ().string (containsString ("actualizada correctamente" )));
153+
154+ verify (categoriaIngredientesService , times (1 )).editarCategoriaIngrediente (any (CategoriaIngredientes .class ));
155+ }
156+
157+ @ Test
158+ @ DisplayName ("PUT /categoriaingrediente/{id} - retorna 404 cuando el ID no existe" )
159+ @ WithMockUser
160+ void editarCategoria_retorna404_cuandoIdNoExiste () throws Exception {
161+ when (categoriaIngredientesService .editarCategoriaIngrediente (any (CategoriaIngredientes .class )))
162+ .thenReturn (0 );
163+
164+ mockMvc .perform (put ("/categoriaingrediente/99" )
165+ .with (csrf ())
166+ .contentType (MediaType .APPLICATION_JSON )
167+ .content (objectMapper .writeValueAsString (categoriaHarinas )))
168+ .andExpect (status ().isNotFound ());
169+
170+ verify (categoriaIngredientesService , times (1 )).editarCategoriaIngrediente (any (CategoriaIngredientes .class ));
171+ }
172+
173+ @ Test
174+ @ DisplayName ("PUT /categoriaingrediente/{id} - retorna 401 sin autenticación" )
175+ void editarCategoria_retorna401_sinAutenticacion () throws Exception {
176+ mockMvc .perform (put ("/categoriaingrediente/1" )
177+ .with (csrf ())
178+ .contentType (MediaType .APPLICATION_JSON )
179+ .content (objectMapper .writeValueAsString (categoriaHarinas )))
180+ .andExpect (status ().isUnauthorized ());
181+
182+ verifyNoInteractions (categoriaIngredientesService );
183+ }
184+
185+ // ─────────────────────────────────────────────
186+ // DELETE /eliminarcategoria/{id}
187+ // ─────────────────────────────────────────────
188+
189+ @ Test
190+ @ DisplayName ("DELETE /eliminarcategoria/{id} - retorna 200 cuando la categoría existe" )
191+ @ WithMockUser
192+ void eliminarCategoria_retorna200_cuandoCategoriaExiste () throws Exception {
193+ when (categoriaIngredientesService .eliminarCategoriaIngrediente (anyInt ()))
194+ .thenReturn (1 );
195+
196+ mockMvc .perform (delete ("/eliminarcategoria/1" )
197+ .with (csrf ()))
198+ .andExpect (status ().isOk ())
199+ .andExpect (content ().string (containsString ("eliminada correctamente" )));
200+
201+ verify (categoriaIngredientesService , times (1 )).eliminarCategoriaIngrediente (1 );
202+ }
203+
204+ @ Test
205+ @ DisplayName ("DELETE /eliminarcategoria/{id} - retorna 404 cuando el ID no existe" )
206+ @ WithMockUser
207+ void eliminarCategoria_retorna404_cuandoIdNoExiste () throws Exception {
208+ when (categoriaIngredientesService .eliminarCategoriaIngrediente (anyInt ()))
209+ .thenReturn (0 );
210+
211+ mockMvc .perform (delete ("/eliminarcategoria/99" )
212+ .with (csrf ()))
213+ .andExpect (status ().isNotFound ());
214+
215+ verify (categoriaIngredientesService , times (1 )).eliminarCategoriaIngrediente (99 );
216+ }
217+
218+ @ Test
219+ @ DisplayName ("DELETE /eliminarcategoria/{id} - retorna 401 sin autenticación" )
220+ void eliminarCategoria_retorna401_sinAutenticacion () throws Exception {
221+ mockMvc .perform (delete ("/eliminarcategoria/1" )
222+ .with (csrf ()))
223+ .andExpect (status ().isUnauthorized ());
224+
225+ verifyNoInteractions (categoriaIngredientesService );
226+ }
227+ }
0 commit comments