1+ <?php
2+
3+ namespace Tests \Feature \Inventario ;
4+
5+ use Tests \TestCase ;
6+ use Illuminate \Support \Facades \Http ;
7+ use PHPUnit \Framework \Attributes \Test ;
8+
9+ class CategoriaIngredientesControllerTest extends TestCase
10+ {
11+ private function mockApiOk (): void
12+ {
13+ Http::fake ([
14+ '*/categorias/ingredientes ' => Http::response ([
15+ ['idCategoriaIngrediente ' => 1 , 'nombreCategoria ' => 'Harinas ' ],
16+ ['idCategoriaIngrediente ' => 2 , 'nombreCategoria ' => 'Lácteos ' ],
17+ ], 200 )
18+ ]);
19+ }
20+
21+ // =========================================================
22+ // index()
23+ // =========================================================
24+
25+ #[Test]
26+ public function index_retorna_200_con_vista_correcta (): void
27+ {
28+ $ this ->mockApiOk ();
29+
30+ $ response = $ this ->get ('/inventario/categorias-ingredientes ' );
31+
32+ $ response ->assertStatus (200 );
33+ $ response ->assertViewIs ('inventarioviews.categorias.index ' );
34+ }
35+
36+ #[Test]
37+ public function index_pasa_variable_categorias_a_la_vista (): void
38+ {
39+ $ this ->mockApiOk ();
40+
41+ $ response = $ this ->get ('/inventario/categorias-ingredientes ' );
42+
43+ $ response ->assertViewHas ('categorias ' );
44+ }
45+
46+ #[Test]
47+ public function index_carga_con_categorias_vacias_cuando_api_falla (): void
48+ {
49+ Http::fake ([
50+ '*/categorias/ingredientes ' => Http::response ([], 500 )
51+ ]);
52+
53+ $ response = $ this ->get ('/inventario/categorias-ingredientes ' );
54+
55+ // No da 500 — el controller devuelve vista con array vacío
56+ $ response ->assertStatus (200 );
57+ $ response ->assertViewIs ('inventarioviews.categorias.index ' );
58+ $ response ->assertViewHas ('categorias ' , []);
59+ // El error va como variable de vista con ->with()
60+ $ response ->assertViewHas ('error ' );
61+ }
62+
63+ // =========================================================
64+ // store()
65+ // =========================================================
66+
67+ #[Test]
68+ public function store_con_datos_validos_redirige_con_success (): void
69+ {
70+ Http::fake ([
71+ '*/nuevacategoriaingrediente ' => Http::response ('Creada ' , 200 )
72+ ]);
73+
74+ $ response = $ this ->post ('/inventario/categorias-ingredientes/store ' , [
75+ 'nombreCategoria ' => 'Frutas Tropicales '
76+ ]);
77+
78+ $ response ->assertRedirect (route ('categorias-ingredientes.index ' ));
79+ $ response ->assertSessionHas ('success ' , 'Categoría creada con éxito. ' );
80+ }
81+
82+ #[Test]
83+ public function store_falla_si_nombreCategoria_esta_vacio (): void
84+ {
85+ $ response = $ this ->post ('/inventario/categorias-ingredientes/store ' , [
86+ 'nombreCategoria ' => ''
87+ ]);
88+
89+ $ response ->assertSessionHasErrors (['nombreCategoria ' ]);
90+ }
91+
92+ #[Test]
93+ public function store_falla_si_nombreCategoria_supera_255_caracteres (): void
94+ {
95+ $ response = $ this ->post ('/inventario/categorias-ingredientes/store ' , [
96+ 'nombreCategoria ' => str_repeat ('A ' , 256 )
97+ ]);
98+
99+ $ response ->assertSessionHasErrors (['nombreCategoria ' ]);
100+ }
101+
102+ #[Test]
103+ public function store_redirige_con_error_cuando_spring_rechaza (): void
104+ {
105+ Http::fake ([
106+ '*/nuevacategoriaingrediente ' => Http::response ('Error ' , 400 )
107+ ]);
108+
109+ $ response = $ this ->post ('/inventario/categorias-ingredientes/store ' , [
110+ 'nombreCategoria ' => 'Frutas '
111+ ]);
112+
113+ $ response ->assertRedirect ();
114+ $ response ->assertSessionHas ('error ' );
115+ }
116+
117+ // =========================================================
118+ // update()
119+ // =========================================================
120+
121+ #[Test]
122+ public function update_con_datos_validos_redirige_con_success (): void
123+ {
124+ Http::fake ([
125+ '*/categoriaingrediente/1 ' => Http::response ('Actualizada ' , 200 )
126+ ]);
127+
128+ $ response = $ this ->put ('/inventario/categorias-ingredientes/update/1 ' , [
129+ 'nombreCategoria ' => 'Harinas Premium '
130+ ]);
131+
132+ $ response ->assertRedirect (route ('categorias-ingredientes.index ' ));
133+ $ response ->assertSessionHas ('success ' , 'Categoría actualizada con éxito. ' );
134+ }
135+
136+ #[Test]
137+ public function update_falla_validacion_con_nombre_vacio (): void
138+ {
139+ $ response = $ this ->put ('/inventario/categorias-ingredientes/update/1 ' , [
140+ 'nombreCategoria ' => ''
141+ ]);
142+
143+ $ response ->assertSessionHasErrors (['nombreCategoria ' ]);
144+ }
145+
146+ // =========================================================
147+ // destroy()
148+ // =========================================================
149+
150+ #[Test]
151+ public function destroy_elimina_y_redirige_con_success (): void
152+ {
153+ Http::fake ([
154+ '*/eliminarcategoria/1 ' => Http::response ('Eliminada ' , 200 )
155+ ]);
156+
157+ $ response = $ this ->delete ('/inventario/categorias-ingredientes/delete/1 ' );
158+
159+ $ response ->assertRedirect (route ('categorias-ingredientes.index ' ));
160+ $ response ->assertSessionHas ('success ' , 'Categoría eliminada con éxito. ' );
161+ }
162+
163+ #[Test]
164+ public function destroy_redirige_con_error_cuando_spring_falla (): void
165+ {
166+ Http::fake ([
167+ '*/eliminarcategoria/1 ' => Http::response ('Error ' , 500 )
168+ ]);
169+
170+ $ response = $ this ->delete ('/inventario/categorias-ingredientes/delete/1 ' );
171+
172+ $ response ->assertRedirect ();
173+ $ response ->assertSessionHas ('error ' );
174+ }
175+ }
0 commit comments