Seguiremos investigando nuestro código en este tutorial de laravel y abordaremos muchas cosas. Agregar enlaces a los perfiles de usuario está sobre la mesa, así como limpiar nuestros archivos de vista haciendo uso de parciales. A partir de ahí, pasaremos a agregar soporte para mostrar propietarios de subprocesos respaldados por pruebas. Agregaremos una nueva clase de prueba de ParticipateInForumTest para comenzar a probar y construir el concepto de usuarios autenticados que agregan respuestas a los hilos. Por último, echaremos un vistazo rápido a la adición de un middleware simple para proteger un punto final de los usuarios no autenticados.


Vinculación a un perfil de usuario

Recuerde que en el último episodio, configuramos la vista show.blade.php para ver un hilo específico. En esa página, vemos todas las respuestas con el nombre de la persona que envió la respuesta. Podría ser bueno vincular al perfil del usuario que envió una respuesta, así que sigamos adelante y agreguemos eso a nuestro marcado ahora. Solo enlazaremos a un # por ahora, ya que todavía no tenemos perfiles en la aplicación.

vinculación a perfiles de usuario


Limpiar archivos de vista con parciales

En el directorio resources / views / threads, podemos crear un nuevo archivo de reply.blade.php. En este archivo, podemos extraer parte del marcado en nuestro show.blade.php para hacer las cosas un poco más agradables. Aquí está el código en el nuevo archivo parcial, así como el archivo show.blade.php actualizado que ahora hace uso de una inclusión para traer el parcial.


Adición de soporte para mostrar propietarios de subprocesos

Cuando vemos una página de hilo, vemos el nombre de los usuarios que publican respuestas, pero no el nombre del usuario que publicó el hilo. Agreguemos soporte para esto aquí. Por tanto, comenzaremos construyendo pruebas unitarias para Threads. Primero podemos crear la nueva clase ThreadTest, luego agregar las pruebas individuales (métodos de esa clase) una vez que estén en su lugar.

vagrant @ homestead: ~ / Code / forumio $ php artisan make: test ThreadTest --unit
Prueba creada con éxito.

En el fragmento de arriba, agregamos una prueba para confirmar que un hilo tiene respuestas. Deberíamos haber agregado esto ya, pero no se preocupe. Ejecutarlo muy rápido con la opción –filter de phpunit muestra que está funcionando.

vagrant @ homestead: ~ / Code / forumio $ phpunit --filter ThreadTest
PHPUnit 6.5.2 por Sebastian Bergmann y colaboradores.

. 1/1 (100%)

Tiempo: 1,24 segundos, memoria: 8,00 MB

OK (1 prueba, 1 afirmación)

Otra prueba que queremos agregar es el hecho de que un hilo tiene un creador. Sigamos adelante y agreguemos una prueba para eso. El pseudo pensamiento para esta prueba es: Dado que tengo un hilo, cuando busco al propietario de ese hilo, podemos afirmar que es una instancia de Usuario.

Ejecutemos esa prueba de forma aislada usando el indicador –filter ahora.

vagabundo @ homestead: ~ / Code / forumio $ phpunit --filter test_a_thread_has_a_creator
PHPUnit 6.5.2 por Sebastian Bergmann y colaboradores.

F 1/1 (100%)

Tiempo: 1,15 segundos, memoria: 8,00 MB

Hubo 1 falla:

1) Pruebas \ Unidad \ ThreadTest :: test_a_thread_has_a_creator
No se pudo afirmar que null es una instancia de la clase "App \ User".

/home/vagrant/Code/forumio/tests/Unit/ThreadTest.php:24

¡FALLOS!
Pruebas: 1, afirmaciones: 1, fallos: 1.

Como era de esperar, esta prueba falla ya que aún no tenemos las tuberías para admitir esta función. Construyamos el código y hagamos que esta prueba pase.

Ejecute nuestra prueba nuevamente y estamos listos para comenzar.

vagabundo @ homestead: ~ / Code / forumio $ phpunit --filter test_a_thread_has_a_creator
PHPUnit 6.5.2 por Sebastian Bergmann y colaboradores.

. 1/1 (100%)

Tiempo: 852 ms, memoria: 8,00 MB

OK (1 prueba, 1 afirmación)

¡Muy genial! Ahora, lo que esto significa es que deberíamos poder actualizar nuestro archivo de vista para hacer referencia al propietario de un hilo, y no nos va a explotar cuando vayamos a verlo en el navegador. Pongamos a prueba esa teoría.

Al verlo en el navegador, podemos ver que funciona muy bien, ya que el Dr. Austyn Dicki PhD hizo una publicación en un hilo.
hilo tiene un propietario ahora trabajando


Cree una nueva prueba para los usuarios que participan en el foro

Hasta ahora, todas nuestras pruebas se han centrado en navegar y leer hilos en el foro. Necesitamos algunas pruebas para ayudar a los usuarios que participan en el foro. Una vez más, podemos utilizar a Artisan para construir el andamio para nosotros. Esta será una prueba de funciones.

vagrant @ homestead: ~ / Code / forumio $ php artisan make: test ParticipateInForumTest
Prueba creada con éxito.

¿Qué queremos lograr con esta prueba? Aquí está el pseudocódigo para ayudarnos.

  • Dado que hay un usuario autenticado
  • Dado un hilo existente
  • Cuando el usuario agrega una respuesta a un hilo
  • La respuesta del usuario debe verse en la página.

Traducir el pseudocódigo anterior en una prueba real puede verse así:

Ok, ejecutemos la prueba y, por supuesto, debería fallar.

vagabundo @ homestead: ~ / Código / forumio $ phpunit
PHPUnit 6.5.2 por Sebastian Bergmann y colaboradores.

F ....... 8/8 (100%)

Tiempo: 1,97 segundos, memoria: 10,00 MB

Hubo 1 falla:

1) Tests \ Feature \ ParticipateInForumTest :: test_an_authenticated_user_can_participate_in_forum_threads
No se pudo afirmar que (el html) contiene "In autem at consequatur minima et. Quia qui fugiat ducimus. Eveniet mollitia quam doloremque ipsum.".

/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestResponse.php:236
/home/vagrant/Code/forumio/tests/Feature/ParticipateInForumTest.php:23

¡FALLOS!
Pruebas: 8, Afirmaciones: 11, Fallos: 1.

Esto es interesante. La prueba falla, pero no falla hasta la última línea de la prueba. En realidad, debería fallar incluso antes que esto. Si miramos la línea 21, la prueba está realizando una solicitud de publicación a un punto final que ni siquiera existe. ¿Debería fallar la prueba allí? A continuación se explica cómo solucionar ese pequeño problema técnico. Visite el archivo Handler.php en nuestro proyecto y agregue el código resaltado como se ve aquí. (En Laravel 5.5 ahora puede alternar el manejo de excepciones ).

Cuando luego ejecutamos la prueba, de hecho detectamos ese error cuando intentamos enviar una solicitud de publicación a un punto final inexistente.

vagabundo @ homestead: ~ / Código / forumio $ phpunit
PHPUnit 6.5.2 por Sebastian Bergmann y colaboradores.

E ....... 8/8 (100%)

Tiempo: 1,69 segundos, memoria: 10,00 MB

Hubo 1 error:

1) Tests \ Feature \ ParticipateInForumTest :: test_an_authenticated_user_can_participate_in_forum_threads
Symfony \ Component \ HttpKernel \ Exception \ NotFoundHttpException:

/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php:179
/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Routing/Router.php:612
/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Routing/Router.php:601
/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Routing/Router.php:590
/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:176
/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:30
/home/vagrant/Code/forumio/vendor/fideloper/proxy/src/TrustProxies.php:56
/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:149
/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:53
/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php:30
/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:149
/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:53
/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php:30
/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:149
/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:53
/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php:27
/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:149
/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:53
/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php:46
/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:149
/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:53
/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:102
/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:151
/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:116
/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php:345
/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php:195
/home/vagrant/Code/forumio/tests/Feature/ParticipateInForumTest.php:21

¡ERRORES!
Pruebas: 8, afirmaciones: 10, errores: 1.

Desarrolle la nueva característica

Okay. Ahora que tenemos nuestra prueba en su lugar y las trampas resueltas, podemos desarrollar la función. Lo primero que necesitamos para que un usuario publique una respuesta en un hilo es un punto final (o ruta) al que enviar la respuesta. Usamos una solicitud POST en este tipo de escenario, así que construyamos nuestro archivo de rutas como tal.

Una nota rápida sobre el nombre del controlador y el método que elegimos para esta nueva ruta. Podríamos agregar fácilmente un nuevo método al ThreadsController como addReply () o algún método similar. En realidad, tiene más sentido ceñirse a los métodos tranquilos de indexar, crear, almacenar, mostrar, editar, actualizar o destruir. La idea detrás de esto es que si sigues agregando métodos de cualquier manera a un solo controlador, ese controlador se saldrá de control y causarás dolor al tratar de mantenerlo. Entonces, con ese pensamiento en mente, comencemos a construir el RepliesController que habíamos creado en un tutorial anterior.

Así que hay un poco de magia aquí que deberíamos discutir rápidamente. En primer lugar, estamos haciendo uso del enlace del modelo de ruta, que básicamente obtiene el modelo de la base de datos simplemente escribiendo insinuando el método store (). Cosas bastante bonitas. Ahora, además de esto, estamos haciendo uso de un método addReply () que aún no existe en ese modelo. Comenzaremos agregando una prueba a nuestra clase ThreadTest.

Ejecutemos rápidamente la prueba y veamos si obtenemos el error esperado.

vagrant @ homestead: ~ / Code / forumio $ phpunit --filter ThreadTest
PHPUnit 6.5.2 por Sebastian Bergmann y colaboradores.

..E 3/3 (100%)

Tiempo: 894 ms, memoria: 8,00 MB

Hubo 1 error:

1) Pruebas \ Unidad \ ThreadTest :: test_a_thread_can_add_a_reply
BadMethodCallException: llamada al método no definido Illuminate \ Database \ Query \ Builder :: addReply ()

/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:2459
/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:1273
/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:1455
/home/vagrant/Code/forumio/tests/Unit/ThreadTest.php:34

¡ERRORES!
Pruebas: 3, afirmaciones: 2, errores: 1.

Eso parece correcto, la prueba falla porque estamos haciendo una llamada a un método que aún no existe. Sigamos adelante y creemoslo ahora.

¡Vale genial! Parece que todo está en su lugar, así que ejecutemos la prueba nuevamente y veamos cómo funciona.

vagrant @ homestead: ~ / Code / forumio $ phpunit --filter ThreadTest
PHPUnit 6.5.2 por Sebastian Bergmann y colaboradores.

..E 3/3 (100%)

Tiempo: 880 ms, memoria: 8,00 MB

Hubo 1 error:

1) Pruebas \ Unidad \ ThreadTest :: test_a_thread_can_add_a_reply
Illuminate \ Database \ Eloquent \ MassAssignmentException: cuerpo

/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:232
/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:152
/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:275
/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/HasOneOrMany.php:276
/home/vagrant/Code/forumio/app/Thread.php:26
/home/vagrant/Code/forumio/tests/Unit/ThreadTest.php:34

¡ERRORES!
Pruebas: 3, afirmaciones: 2, errores: 1.

Oh chico. Parece que estamos recibiendo una excepción de asignación masiva. Si no está familiarizado, lo que esto significa es que Laravel está protegiendo su aplicación para que no se inserten datos falsos en la base de datos cuando no se supone que suceda. La asignación masiva es toda una lección en sí misma, pero por ahora solo podemos decirle a Laravel que acepte cualquier cosa. Hacemos esto estableciendo la siguiente propiedad: protected $ guarded = []; en el modelo de Thread y Reply. Una vez que actualizamos ambos modelos para permitir que se inserte cualquier dato, podemos ejecutar la prueba nuevamente y pasa.

vagrant @ homestead: ~ / Code / forumio $ phpunit --filter ThreadTest
PHPUnit 6.5.2 por Sebastian Bergmann y colaboradores.

... 3/3 (100%)

Tiempo: 866 ms, memoria: 8,00 MB

OK (3 pruebas, 3 afirmaciones)

Con nuestro modelo funcionando, podemos volver al controlador y agregar una función de redireccionamiento rápido hacia atrás.


Evitar que los usuarios no autenticados publiquen

Solo queremos que los usuarios que hayan iniciado sesión en nuestra aplicación puedan publicar respuestas a los hilos. En nuestra clase ParticipateInForumTest tenemos una prueba para usuarios autenticados, pero no para usuarios no autenticados. Creemos una nueva prueba para cubrir eso ahora.

En la función de prueba test_unauthenticated_users_can_not_add_replies, puede leerlo al revés. Básicamente, si se realiza una solicitud de publicación en el punto final dado, debería fallar con una excepción de autenticación. Ejecutemos la prueba y veamos qué sucede.

vagabundo @ homestead: ~ / Código / forumio $ phpunit
PHPUnit 6.5.2 por Sebastian Bergmann y colaboradores.

F ......... 10/10 (100%)

Tiempo: 1,5 segundos, memoria: 10,00 MB

Hubo 1 falla:

1) Tests \ Feature \ ParticipateInForumTest :: test_unauthenticated_users_can_not_add_replies
No se pudo afirmar que la excepción de tipo "Illuminate \ Database \ Eloquent \ ModelNotFoundException" coincide con la excepción esperada "Illuminate \ Auth \ AuthenticationException". El mensaje era: "No hay resultados de consulta para el modelo [App \ Thread]".

Entonces nuestra nueva prueba no está pasando. ¿Por qué es esto? Bueno, en realidad no hemos implementado ningún tipo de protección en el controlador para evitar que los usuarios no autenticados accedan a varios puntos finales. Para hacer esto, podemos agregar un middlewareAbra el archivo RepliesController y agregue lo siguiente.

Con esta protección de middleware implementada, todas las pruebas ahora pasan nuevamente. ¡Agradable!

vagabundo @ homestead: ~ / Código / forumio $ phpunit
PHPUnit 6.5.2 por Sebastian Bergmann y colaboradores.

.......... 10/10 (100%)

Tiempo: 1,47 segundos, memoria: 10,00 MB

OK (10 pruebas, 13 afirmaciones)

Uso de la autenticación de prueba para permitir que los usuarios registrados publiquen un resumen de respuestas

Este fue un buen tutorial que introdujo el concepto de probar si un usuario de nuestra aplicación tiene un usuario que ha iniciado sesión, y si ese usuario puede o no publicar respuestas a los hilos en nuestra aplicación de foro. Además, hicimos una buena limpieza general de algunos archivos de vista.