Scout para Laravel – Documentación de Laravel 6

Introducción

Laravel Scout proporciona una sencilla solución, basada en un controlador (driver) para agregar búsquedas de texto completo a tus modelos Eloquent. Usando observadores de modelo, Scout mantendrá automáticamente tus índices de búsqueda sincronizados con tus registros de Eloquent.

Actualmente, Scout viene con el controlador (driver) Algolia; sin embargo, la escritura de controladores personalizados es simple y eres libre de extender Scout con tus propias implementaciones de búsqueda.

Instalación

Primero, instala Scout por medio del manejador de paquetes Composer:

composer require laravel/scout

Después de instalar Scout, debes publicar la configuración de Scout usando el comando Artisan vendor:publish. Este comando publicará el archivo de configuración scout.php en tu directorio config:

php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"

Finalmente, agrega el trait Laravel\Scout\Searchable al modelo en el que te gustaría hacer búsquedas. Este trait registrará un observador de modelo para mantener el modelo sincronizado con tu controlador de búsqueda:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;

class Post extends Model
{
    use Searchable;
}

Ver post

Laravel Passport – Documentación de Laravel 6

Introducción

Laravel ya facilita la autenticación por medio de formularios de inicio de sesión tradicionales, pero ¿Qué pasa con las APIs? Las APIs típicamente usan tokens para autenticar a los usuarios y no mantienen el estado de sesión entre solicitudes. Laravel hace de la autenticación de API algo muy simple usando Passport de Laravel, el cual proporciona una implementación de servidor OAuth2 completa para tu aplicación Laravel en sólo minutos. Passport está construido sobre el servidor League OAuth2 que es mantenido por Andy Millington y Simon Hamp.

Esta documentación asume que estás familiarizado con OAuth2. Si no sabes nada sobre OAuth2, considera familiarizarte con la terminología general y las características de Outh2 antes de continuar.

Actualizando Passport

Al actualizar a una nueva versión mayor de Passport, es importante que revises detalladamente la guía de actualización.

Instalación

Para empezar, instala Passport por medio del gestor de paquetes Composer:

composer require laravel/passport

El proveedor de servicio de Passport registra su propio directorio de migración de base de datos con el framework, así que deberías migrar tu base de datos después de instalar el paquete. Las migraciones de Passport crearán las tablas que tu aplicación necesita para almacenar clientes y tokens de acceso:

php artisan migrate

A continuación, debes ejecutar el comando passport:install. Este comando creará las claves de encriptación necesarias para generar tokens de acceso seguro. Además, el comando creará clientes de «acceso personal» y «permiso de contraseña» los cuales serán usados para generar tokens de acceso:

php artisan passport:install

Después de ejecutar este comando, agrega el trait Laravel\Passport\HasApiTokens a tu modelo App\User. Este trait proporcionará algunos métodos helper para tu modelo los cuales permitirán que inspecciones el token y alcances del usuario autenticado:

<?php

namespace App;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Passport\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, Notifiable;
}

Luego, deberías llamar al método Passport::routes dentro del método boot de tu AuthServiceProvider. Este método registrará las rutas necesarias para suministrar tokens y revocar tokens de acceso, clientes y tokens de acceso personal:

<?php

namespace App\Providers;

use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
use Laravel\Passport\Passport;

class AuthServiceProvider extends ServiceProvider
{
    /**
    * The policy mappings for the application.
    *
    * @var array
    */
    protected $policies = [
        'App\Model' => 'App\Policies\ModelPolicy',
    ];

    /**
    * Register any authentication / authorization services.
    *
    * @return void
    */
    public function boot()
    {
        $this->registerPolicies();

        Passport::routes();
    }
}

Finalmente, en tu archivo de configuración config/auth.php, debes establecer la opción driver del guard de autenticación de api a passport. Esto indicará a tu aplicación que utilice el TokenGuard de Passport al momento de autenticar las solicitudes de API entrantes:

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver' => 'passport',
        'provider' => 'users',
    ],
],

Ver post

Laravel Horizon – Documentación de Laravel 6

Introducción

Horizon proporciona un bonito panel de control y sistema de configuración controlado por código para Laravel, potenciado por colas de Redis. Horizon te permite monitorear fácilmente métricas claves de tu sistema de colas tales como tasa de rendimiento, tiempo de ejecución y fallas de tareas.

Toda la configuración de tu worker es almacenada en un solo archivo de configuración sencillo, permitiendo que tu configuración quede en el código fuente donde tu equipo completo pueda colaborar.

Instalación

Debes asegurarte de que tu conexión de cola está establecido a redis en tu archivo de configuración queue.

Puedes usar Composer para instalar Horizon en tu proyecto de Laravel:

composer require laravel/horizon ~3.0

Después de instalar Horizon, publica sus assets usando el comando Artisan horizon:install:

php artisan horizon:install

Ver post

Laravel Envoy – Documentación de Laravel 6

Introducción

Laravel Envoy proporciona una sintaxis limpia y mínima para definir las tareas comunes que ejecutas en tus servidores remotos. Utilizando el estilo de sintaxis de Blade, puedes configurar fácilmente tareas para deploy, comandos de Artisan y más. Envoy solamente es compatible con sistemas operativos Mac y Linux.

Instalación

Primero, instala Envoy utilizando el comando de Composer global require:

composer global require laravel/envoy

Dado que las librerías globales de Composer ocasionalmente pueden causar conflictos en la versión del paquete, puedes considerar utilizar cgr, el cual es un reemplazo directo para el comando composer global require. Las instrucciones de instalación de la librería cgr pueden ser encontradas en GitHub.

Asegúrate de colocar el directorio ~/.composer/vendor/bin en tu PATH para que el ejecutable envoy pueda ser localizado cuando se ejecute el comando envoy en tu terminal.

Actualizar envoy

También puedes usar Composer para mantener tu instalación de Envoy actualizada. Ejecutar el comando composer global update actualizará todos tus paquetes de Composer instalados globalmente:

composer global update

Escribir tareas

Todas tus tareas de Envoy deberán definirse en un archivo Envoy.blade.php en la raíz de tu proyecto. Aquí un ejemplo para comenzar:

@servers(['web' => ['[email protected]']])

@task('foo', ['on' => 'web'])
    ls -la
@endtask

Como puedes ver, un arreglo @servers es definido al inicio del archivo, permitiéndote hacer referencia a estos servidores en la opción on en la declaración de tus tareas. Dentro de tus declaraciones @task, deberás colocar el código Bash que se deberá ejecutar en tu servidor una vez que la tarea sea ejecutada.

Puedes forzar que un script se ejecute localmente especificando la dirección IP del servidor como 127.0.0.1:

@servers(['localhost' => '127.0.0.1'])

Ver post

Laravel Cashier – Documentación de Laravel 6

Introducción

Laravel Cashier proporciona una expresiva interfaz fluida para los servicios de pagos en línea por suscripción de Stripe. Maneja casi todo el código de facturación de suscripción que estás teniendo pavor de escribir. Además de la gestión de suscripción, Cashier puede manejar cupones, cambio de suscripciones, «cantidades» de suscripción, cancelación de períodos de gracia e incluso generar PDFs de facturas.

Actualizando Cashier

Al actualizar a una versión nueva de Cashier, es importante que revises cuidadosamente la guía de actualización.

Para prevenir errores por cambios de actualización, Cashier usa una versión API de Stripe fija. Cashier 10.1 utiliza la versión 2019-08-14 de la API para Stripe. La versión API para Stripe será actualizada con los cambios menores en los lanzamientos de software (releases) con el propósito de asegurar la incorporación de las mejoras y nuevas funcionalidades de Stripe.

Instalación

Primero, instala el paquete de Cashier para Stripe Con Composer:

composer require laravel/cashier

Para asegurar que Cashier maneje todos los eventos de Stripe apropiadamente, recuerda configurar el manejo de webhook de Cashier.

Migraciones de bases de datos

El proveedor de servicio de Cashier registra su propio directorio de migración de base de datos, así que recuerda migrar tu base de datos después de instalar el paquete. Las migraciones de Cashier añadirán varias columnas a tu tabla users al igual que crearán una nueva tabla subscriptions para manejar todas las suscripciones de tus clientes:

php artisan migrate

Si necesitas sobrescribir las migraciones que vienen con el paquete de Cashier, puedes publicarlas usando el comando Artisan vendor:publish:

php artisan vendor:publish --tag="cashier-migrations"

Si prefieres prevenir que las migraciones de Cashier se ejecuten completamente, puedes usar el método ignoreMigrations proporcionado por Cashier. Típicamente, este método debería ser ejecutado en el método register de tu AppServiceProvider:

use Laravel\Cashier\Cashier;

Cashier::ignoreMigrations();

Stripe recomienda que cualquier columna usada para almacenar los identificadores de Stripe debería ser sensible a mayúsculas. Como consecuencia, deberías asegurarte que el ordenamiento de columna para la columna stripe_id sea puesto a, por ejemplo, utf8_bin en MySQL. Puedes buscar más información en la documentación de Stripe.

Configuración

Ver post

Mocking – Documentación de Laravel 6

Introducción

Al momento de probar aplicaciones de Laravel, puedes querer «simular» (mock) ciertos aspectos de tu aplicación de modo que realmente no sean ejecutados durante una prueba dada. Por ejemplo, al momento de probar un controlador que despacha un evento, puedes querer simular los listeners de eventos de modo que realmente no se ejecuten durante la prueba. Esto te permite probar solamente la respuesta HTTP del controlador sin preocuparte por la ejecución de los listeners de eventos, ya que los listeners de eventos pueden ser evaluados en sus propios casos de prueba.

Laravel provee funciones helpers para simular eventos, tareas y clases facades predeterminadas. Estos helpers proporcionan principalmente una capa conveniente sobre la clase Mockery de modo que no tengas que hacer manualmente llamadas complicadas a métodos Mockery. Puedes también usar Mockery o PHPUnit para crear tus propios mocks o spies.

Mocking de objetos

Cuando hagas mocking de un objeto que vas a inyectar en tu aplicación a través del contenedor de servicio de Laravel, debes enlazar tu instancia a la que le has hecho mocking al contenedor como un enlace de instance. Esto le indicará al contenedor que use tu instancia «mockeada» del objeto en lugar de construir el propio objeto:

use App\Service;
use Mockery;

$this->instance(Service::class, Mockery::mock(Service::class, function ($mock) {
    $mock->shouldReceive('process')->once();
}));

Para hacer esto más conveniente, puedes usar el método mock, que es proporcionado por la clase TestCase base de Laravel:

use App\Service;

$this->mock(Service::class, function ($mock) {
    $mock->shouldReceive('process')->once();
});

Puedes usar el método partialMock cuando sólo necesitas simular algunos métodos de un objeto. Los métodos que no son simulados serán ejecutados de forma normal al ser llamados:

use App\Service;

$this->partialMock(Service::class, function ($mock) {
    $mock->shouldReceive('process')->once();
});

De forma similar, si quieres espiar un objeto, la clase de prueba base de Laravel ofrece un método spy como un wrapper conveniente del método Mockery::spy:

use App\Service;

$this->spy(Service::class, function ($mock) {
    $mock->shouldHaveReceived('process');
});

Fake de trabajos (jobs)

Como una alternativa a mocking, puedes usar el método fake de la clase facade Bus para evitar que determinadas tareas sean despachadas. Al momento de usar fakes, las aserciones serán hechas después de que el código bajo prueba sea ejecutado.

<?php

namespace Tests\Feature;

use App\Jobs\ShipOrder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Support\Facades\Bus;
use Tests\TestCase;

class ExampleTest extends TestCase
{
    public function testOrderShipping()
    {
        Bus::fake();

        // Perform order shipping...

        Bus::assertDispatched(ShipOrder::class, function ($job) use ($order) {
            return $job->order->id === $order->id;
        });

        // Assert a job was not dispatched...
        Bus::assertNotDispatched(AnotherJob::class);
    }
}

Fake de eventos

Como una alternativa a mocking, puedes usar el método fake de la clase facade Event para prevenir la ejecución de todos los listeners de eventos. Después puedes comprobar que los eventos fueron despachados e incluso inspeccionar los datos que recibieron. Al momento de usar fakes, las aserciones son hechas después de que el código bajo prueba sea ejecutado:

<?php

namespace Tests\Feature;

use App\Events\OrderFailedToShip;
use App\Events\OrderShipped;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Support\Facades\Event;
use Tests\TestCase;

class ExampleTest extends TestCase
{
    /**
    * Test order shipping.
    */
    public function testOrderShipping()
    {
        Event::fake();

        // Perform order shipping...

        Event::assertDispatched(OrderShipped::class, function ($e) use ($order) {
            return $e->order->id === $order->id;
        });

        // Assert an event was dispatched twice...
        Event::assertDispatched(OrderShipped::class, 2);

        // Assert an event was not dispatched...
        Event::assertNotDispatched(OrderFailedToShip::class);
    }
}

Después de llamar a Event::fake(), no se ejecutarán listeners de eventos. Entonces, si tus pruebas usan model factories que dependen de eventos, como crear una UUID durante el evento de modelo creating, debes llamar Event::fake() después de usar tus factories.

Haciendo fake a un subconjunto de eventos

Si sólo deseas hacer fake a listeners de eventos para un grupo específico de eventos, puedes pasarlos a los métodos fake o fakeFor:

/**
* Test order process.
*/
public function testOrderProcess()
{
    Event::fake([
        OrderCreated::class,
    ]);

    $order = factory(Order::class)->create();

    Event::assertDispatched(OrderCreated::class);

    // Other events are dispatched as normal...
    $order->update([...]);
}

Ver post

Pruebas de Base de Datos – Documentación de Laravel 6

Introducción

Laravel proporciona una variedad de herramientas útiles para hacer que sea más fácil probar tus aplicaciones que manejan base de datos. Primero, puedes usar el método (helper) assertDatabaseHas para comprobar que los datos existentes en la base de datos coinciden con un conjunto dado de criterios. Por ejemplo, si quisieras verificar que hay un registro en la tabla users con el valor email de [email protected], puedes hacer lo siguiente:

public function testDatabase()
{
    // Make call to application...

    $this->assertDatabaseHas('users', [
        'email' => '[email protected]',
    ]);
}

También podrías usar el método assertDatabaseMissing para comprobar que esos datos no existen en la base de datos.

El método assertDatabaseHas y otros métodos como éste son muy convenientes. Eres libre de usar cualquiera de los métodos de aserción integrados de PHPUnit para complementar tus pruebas funcionales (Feature tests).

Generando factories

Para crear un factory, usa el comando Artisan make:factory:

php artisan make:factory PostFactory

El nuevo factory será colocado en tu directorio database/factories.

La opción --model puede ser usada para indicar el nombre del modelo creado por el factory. Esta opción pre-completará el archivo de factory generado con el modelo dado:

php artisan make:factory PostFactory --model=Post

Reiniciando la base de datos después de cada prueba

Con frecuencia es útil reinicializar tu base de datos después de cada prueba de modo que los datos de una prueba previa no interfieran con las pruebas subsecuentes. El trait RefreshDatabase toma como enfoque más óptimo migrar tu base de datos de pruebas, dependiendo de si estás usando una base de datos en memoria o una base de datos tradicional. Usa el trait en tu clase de prueba y todo será manejado automáticamente sin que tengas que preocuparte por esto:

<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Tests\TestCase;

class ExampleTest extends TestCase
{
    use RefreshDatabase;

    /**
    * A basic functional test example.
    *
    * @return void
    */
    public function testBasicExample()
    {
        $response = $this->get('/');

        // ...
    }
}

Escribiendo factories

Al momento de probar, puedes necesitar insertar unos cuantos registros dentro de tu base de datos antes de ejecutar tu prueba. En lugar de especificar manualmente el valor de cada columna cuando crees estos datos de prueba, Laravel permite que definas un conjunto de atributos predeterminados para cada uno de tus modelos de Eloquent usando factories de modelos. Para empezar, demos un vistazo al archivo database/factories/UserFactory.php en tu aplicación. De forma predeterminada, este archivo contiene una definición de factory:

use Faker\Generator as Faker;
use Illuminate\Support\Str;

$factory->define(App\User::class, function (Faker $faker) {
    return [
        'name' => $faker->name,
        'email' => $faker->unique()->safeEmail,
        'email_verified_at' => now(),
        'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
        'remember_token' => Str::random(10),
    ];
});

Dentro del Closure, la cual sirve como la definición del factory, puedes devolver los valores de prueba predeterminados de todos los atributos del modelo. El Closure recibirá una instancia de la librería PHP Faker, la cual permitirá que generes convenientemente varios tipos de datos aleatorios para las pruebas.

También puedes crear archivos de factories adicionales para cada modelo para una mejor organización. Por ejemplo, podrías crear archivos UserFactory.php y CommentFactory.php dentro de tu directorio database/factories. Todos los archivos dentro del directorio factories serán cargados automáticamente por Laravel.

Puedes establecer la configuración regional de Faker agregando una opción faker_locale a tu archivo de configuración config/app.php.

Ver post

Laravel Dusk – Documentación de Laravel 6

Introducción

Laravel Dusk proporciona una API de automatización y prueba para navegador expresiva y fácil de usar. De forma predeterminada, Dusk no requiere que instales JDK o Selenium en tu computador. En su lugar, Dusk usa una instalación de ChromeDriver independiente. Sin embargo, siéntete libre de utilizar cualquier otro driver compatible con Selenium que desees.

Instalación

Para empezar, debes agregar la dependencia de Composer laravel/dusk a tu proyecto:

composer require --dev laravel/dusk

Si estás registrando manualmente el proveedor de servicio de Dusk, nunca deberías registrarlo en tu entorno de producción, ya que hacerlo así podría conducir a que usuarios arbitrarios sean capaces de autenticarse en tu aplicación.

Después de la instalación del paquete Dusk, ejecuta el comando Artisan dusk:install:

php artisan dusk:install

Un directorio Browser será creado dentro de tu directorio tests y contendrá una prueba de ejemplo. Seguido, establece la variable de entorno APP_URL en tu archivo .env. Este valor debería coincidir con la URL que uses para acceder a tu aplicación en un navegador.

Para ejecutar tus pruebas, usa el comando de Artisan dusk. El comando dusk acepta cualquier argumento que también sea aceptado por el comando phpunit:

php artisan dusk

Si tuviste fallos en las pruebas la última vez que se ejecutó el comando dusk, puedes ahorrar tiempo volviendo a ejecutar las pruebas fallidas usando el comando dusk:fails:

php artisan dusk:fails

Ver post

Pruebas de consola – Documentación de Laravel 6

Introducción

Además de simplificar las pruebas de HTTP, Laravel proporciona una API simple para probar las aplicaciones de consola que solicitan información al usuario.

Esperando entrada / salida

Laravel te permite «simular» (mock) fácilmente la entrada de datos por parte del usuario mediante la consola utilizando el método expectsQuestion. Además, puedes especificar el código de salida y el texto que esperas que genere el comando de consola utilizando los métodos assertExitCode y expectsOutput. Por ejemplo, considera el siguiente comando de consola:

Artisan::command('question', function () {
    $name = $this->ask('What is your name?');

    $language = $this->choice('Which language do you program in?', [
        'PHP',
        'Ruby',
        'Python',
    ]);

    $this->line('Your name is '.$name.' and you program in '.$language.'.');
});

Puedes probar este comando con la siguiente prueba que utiliza los métodos expectsQuestion, expectsOutput y assertExitCode:

/**
* Test a console command.
*
* @return void
*/
public function testConsoleCommand()
{
    $this->artisan('question')
         ->expectsQuestion('What is your name?', 'Taylor Otwell')
         ->expectsQuestion('Which language do you program in?', 'PHP')
         ->expectsOutput('Your name is Taylor Otwell and you program in PHP.')
         ->assertExitCode(0);
}

Pruebas HTTP – Documentación de Laravel 6

Introducción

Laravel proporciona una API muy fluida para hacer solicitudes HTTP a tu aplicación y examinar la salida. Por ejemplo, demos un vistazo a la prueba funcional definida a continuación:

<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Tests\TestCase;

class ExampleTest extends TestCase
{
    /**
    * A basic test example.
    *
    * @return void
    */
    public function testBasicTest()
    {
        $response = $this->get('/');

        $response->assertStatus(200);
    }
}

El método get simula una solicitud GET dentro de la aplicación, mientras que el método assertStatus comprueba que la respuesta devuelta debería tener el código de estado HTTP dado. Además de esta sencilla aserción, Laravel también contiene una variedad de aserciones para inspeccionar de la respuesta los encabezados, contenidos, estructura JSON y más.

Ver post

Suscríbete a nuestro boletín

Te enviaremos publicaciones con consejos útiles y múltiples recursos para que sigas aprendiendo.

Suscríbete a nuestro boletín

Recibe consejos útiles, promos y múltiples recursos directamente en tu correo.

Tu nombre y correo serán enviados directamente a MailChimp. No compartiremos tus datos con otras empresas.