<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: MacDonald Chika</title>
    <description>The latest articles on Forem by MacDonald Chika (@macelux).</description>
    <link>https://forem.com/macelux</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F785555%2Fcc3fdcf5-801d-4113-9733-8306c48359fd.jpeg</url>
      <title>Forem: MacDonald Chika</title>
      <link>https://forem.com/macelux</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/macelux"/>
    <language>en</language>
    <item>
      <title>How To Install TLS/SSL on Docker Nginx Container With Let’s Encrypt</title>
      <dc:creator>MacDonald Chika</dc:creator>
      <pubDate>Mon, 12 Jun 2023 04:08:05 +0000</pubDate>
      <link>https://forem.com/macelux/how-to-install-tlsssl-on-docker-nginx-container-with-lets-encrypt-34c5</link>
      <guid>https://forem.com/macelux/how-to-install-tlsssl-on-docker-nginx-container-with-lets-encrypt-34c5</guid>
      <description>&lt;p&gt;Are you running an Nginx Docker container and want to ensure secure and encrypted connections for your website? Look no further! In this comprehensive tutorial, I will guide you through the process of obtaining a free SSL certificate from Let’s Encrypt using Certbot. By following these step-by-step instructions, you will fortify your Nginx container with robust SSL encryption, bolstering the security of your web application.&lt;/p&gt;

&lt;p&gt;In this tutorial, you will discover how to secure your Nginx Docker container by leveraging Let’s Encrypt and Certbot. We will use Certbot to obtain a free SSL certificate for Nginx.&lt;/p&gt;

&lt;p&gt;You will need the following to follow this tutorial:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Ubuntu server&lt;/li&gt;
&lt;li&gt;A registered domain name. You can take a look at Namecheap to purchase a domain name. We will use &lt;a href="http://www.example.com"&gt;www.example.com&lt;/a&gt; for the purpose of this tutorial.&lt;/li&gt;
&lt;li&gt;Set up two DNS records for your server: an A record, for example.com, that points to your server’s public IP address, and an A record for &lt;a href="http://www.example.com"&gt;www.example.com&lt;/a&gt;, also pointing to the same IP address.&lt;/li&gt;
&lt;li&gt;Docker installed on your server(version 20.10.22) or a later version.&lt;/li&gt;
&lt;li&gt;Docker-compose installed on your server (version 1.29.0) or a later version.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is Let’s Encrypt?
&lt;/h2&gt;

&lt;p&gt;Let’s Encrypt is a global Certificate Authority (CA). We let people and organizations worldwide obtain, renew, and manage SSL/TLS certificates. According to Let’s Encrypt, websites can use their certificates to enable secure HTTPS connections. &lt;a href="https://letsencrypt.org/docs/faq/#:~:text=Let%E2%80%99s%20Encrypt%20is%20a%20global%20Certificate%20Authority%20(CA).%20We%20let%20people%20and%20organizations%20around%20the%20world%20obtain%2C%20renew%2C%20and%20manage%20SSL/TLS%20certificates.%20Our%20certificates%20can%20be%20used%20by%20websites%20to%20enable%20secure%20HTTPS%20connections."&gt;LetsEncrypt&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that you know a little about Let’s Encrypt, let's look at the steps involved:&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Install Certbot
&lt;/h2&gt;

&lt;p&gt;To use Let’s Encrypt to obtain an SSL certificate, the first step is to install Certbot on your server.&lt;/p&gt;

&lt;p&gt;Install Certbot with apt and follow the prompts by selecting ok or entering Yes where required.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update
sudo apt install cerbot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Certbot software is now ready to use. The next step is to obtain the SSL certificate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Obtain TSL/SSL Certificate
&lt;/h2&gt;

&lt;p&gt;The next step is to obtain the TLS/SSL certificate from the Let’s Encrypt authority using the Certbot software. You must type the following to get the TSL/SSL certificate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo certbot certonly --webroot --webroot-path /your/project/root/public/directory/path  -d example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s quickly explain what the Certbot options do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;certonly:&lt;/strong&gt; This option tells Certbot only to obtain the certificate, and you will do the manual installation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;— webroot:&lt;/strong&gt; The webroot plugin requires that you specify a directory on your server where Certbot can place a temporary file to prove that you have control over the domain you request a certificate for.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;-— webroot-path:&lt;/strong&gt; This specifies the directory where Certbot should place the temporary file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;-d:&lt;/strong&gt; This option specifies the domain or subdomain you want to obtain a certificate.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;If this is your first time running `certbot`, you will be prompted to enter your email address and agree to the service terms.

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices)
 (Enter 'c' to cancel): test@mail.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.3-September-21-2022.pdf. You must
agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If this command you just run is successful, &lt;code&gt;certbot&lt;/code&gt; will ask how you would like to redirect traffic to HTTPS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel):
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hit the &lt;code&gt;Enter&lt;/code&gt; Key when you are done making your choice. If successful, you should get a message that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/example.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/example.com/privkey.pem
   Your cert will expire on 2023-07-18. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot again
   with the "certonly" option. To non-interactively renew *all* of
   your certificates, run "certbot renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Copy The TSL/SSL Certificates
&lt;/h2&gt;

&lt;p&gt;Your certificates have been downloaded in this directory&lt;br&gt;
&lt;code&gt;/etc/letsencrypt/live/example.com/&lt;/code&gt;. You will need to copy out the certificates to a new directory &lt;code&gt;/etc/letsencrypt&lt;/code&gt; with any symbolic links encountered in the source directory using the &lt;code&gt;-L&lt;/code&gt; option so that the contents of the linked files are copied rather than just the link itself.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo mkdir -p /etc/letsencrypt/ssl #create an SSL directory to save the fullchain and privkey files 

sudo cp -r -L /etc/letsencrypt/live/example.com/fullchain.pem /etc/letsencrypt/ssl/
sudo cp -r -L /etc/letsencrypt/live/example.com/privkey.pem /etc/letsencrypt/ssl/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You might want to give the necessary permissions so that the certificates in the new directory are read only by a specific user and group as thus:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo chown &amp;lt;nginx_user&amp;gt;:&amp;lt;nginx_group&amp;gt; /etc/letsencrypt/ssl/fullchain.pem
sudo chown &amp;lt;nginx_user&amp;gt;:&amp;lt;nginx_group&amp;gt; /etc/letsencrypt/ssl/privkey.pem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Update Docker-compose File
&lt;/h2&gt;

&lt;p&gt;You should create another file and name it docker-compose-production.yml, assuming you already have a docker-compose.yml file you use locally. This is to differentiate the production docker-compose file, which would have the certificates referenced by paths.&lt;/p&gt;

&lt;p&gt;So here is what your &lt;code&gt;docker-compose-production.yml&lt;/code&gt; should look like after updating it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nginx:
        container_name: example_nginx_prod
        image: nginx:latest
        ports:
            - "${SSL_PORT}:443"
            - "${HTTP_PORT}:80"
        volumes:
            - ./:/your/project/root/directory/path
            - /etc/letsencrypt/ssl/fullchain.pem:/etc/nginx/ssl/fullchain.pem
            - /etc/letsencrypt/ssl/privkey.pem:/etc/nginx/ssl/privkey.pem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5: Update Your Nginx conf
&lt;/h2&gt;

&lt;p&gt;The next step is to update your nginx conf file in your docker container to include the certificates like thus:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server {
    listen [::]:443 ssl;
    listen 443 ssl; 

    root /your/project/root/public/directory/path;
    index index.html index.php index.htm index.nginx-debian.html;
    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;

    server_name example.com;

    ssl_certificate /etc/nginx/ssl/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/privkey.pem;

    error_page 404 /index.php;

    location / { 
        try_files $uri $uri/ /index.php?$query_string;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 6: Rebuild The Docker Container
&lt;/h2&gt;

&lt;p&gt;At this point, you are done with the hard part. You need to rebuild the docker container for your changes to take effect. For example, using docker-compose, you could do it this way:&lt;/p&gt;

&lt;p&gt;At this point, you are done with the hard part. You need to rebuild the docker container for your changes to take effect. For example, using docker-compose, you could do it this way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker-compose -f docker-compose-production.yml build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: You can use the &lt;code&gt;no-cache&lt;/code&gt; option if need be.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker-compose -f docker-compose-production.yml build --no-cache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, bring your docker container back up using this command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker-compose -f docker-compose-production.yml up -d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion:
&lt;/h2&gt;

&lt;p&gt;Following this tutorial, you have successfully secured your Nginx Docker container with Let’s Encrypt SSL certificates. Your web application now benefits from the highest level of encryption and trust, providing a secure environment for users to interact with your content.&lt;/p&gt;

&lt;p&gt;Remember to renew your SSL certificates to maintain continuous security regularly.&lt;/p&gt;

&lt;p&gt;Happy Learning :)!&lt;/p&gt;

</description>
      <category>docker</category>
      <category>ubuntu</category>
      <category>devops</category>
      <category>security</category>
    </item>
    <item>
      <title>How To Test Mail and Database Notifications in Laravel 8</title>
      <dc:creator>MacDonald Chika</dc:creator>
      <pubDate>Wed, 11 May 2022 17:49:23 +0000</pubDate>
      <link>https://forem.com/macelux/how-to-test-mail-and-database-notifications-in-laravel-8-178o</link>
      <guid>https://forem.com/macelux/how-to-test-mail-and-database-notifications-in-laravel-8-178o</guid>
      <description>&lt;p&gt;I was working on a project in Laravel and needed to test the mail content of a mail notification and also the database notification but I could not figure it out. After some research, I figured that you can actually unit test or assert mail notification content as well as database notification without sending an actual notification. I will show you how to do that in this article.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;If you are reading this, I will assume that you already know how to write unit tests in Laravel using PHPUnit. If you don't , you can click &lt;a href="https://dev.to/macelux/test-driven-development-tdd-in-laravel-8-21kn"&gt;here&lt;/a&gt; to get you started.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Firstly, we will create a notification using this Laravel command&lt;br&gt;
&lt;code&gt;php artisan make:notification TestNotification&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Your file should look like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;

class TestNotification extends Notification
{
    use Queueable;

    private $user;

    public function __construct($user)
    {
        $this-&amp;gt;$user = $user;
    }

    public function via($notifiable)
    {
        return ['mail','database'];
    }

    public function toMail($notifiable)
    {
        return (new MailMessage)
                    -&amp;gt;line('The introduction to the notification.')
                    -&amp;gt;action('Notification Action', url('/'))
                    -&amp;gt;line('Thank you for using our application!');
    }

    public function toArray($notifiable)
    {
        return [
            'some' =&amp;gt; 'data'
        ];
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then in your test, you should fake the notification by calling the notification facade and then a static function &lt;strong&gt;fake()&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We are going to test the database notification. In your test file, create a function &lt;strong&gt;testDatabaseNotification()&lt;/strong&gt;. Afterward, we will arrange our test case, act and assert.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public function testDatabaseNotification()
    {   
        // Arrange
        Notification::fake(); 
        $this-&amp;gt;user = User::factory()-&amp;gt;create();
        $email_subject = "Test Notification";

        // Act 
        $this-&amp;gt;user-&amp;gt;notify(new TestNotification($email_subject));

        // Assert
        Notification::assertSentTo($this-&amp;gt;user, TestNotification::class, function ($notification, $channels) use($email_subject){
            $this-&amp;gt;assertContains('database', $channels);

            $databaseNotification = (object)$notification-&amp;gt;toArray($this-&amp;gt;user);
            $this-&amp;gt;assertEquals( $email_subject, $databaseNotification-&amp;gt;title);

            return true;
        });
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we are going to test our mail notification&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public function testMailNotification()
    {   
        // Arrange
        Notification::fake();
        $this-&amp;gt;user = User::factory()-&amp;gt;create();
        $email_subject = "Test notification";

        // Act
        $this-&amp;gt;user-&amp;gt;notify(new TestNotification($email_subject));

        // Assert
        Notification::assertSentTo($this-&amp;gt;user, TestNotification::class, function ($notification, $channels) use($email_subject){
            $this-&amp;gt;assertContains('mail', $channels);

            $mailNotification = (object)$notification-&amp;gt;toMail($this-&amp;gt;user);
            $this-&amp;gt;assertEquals($email_subject, $mailNotification-&amp;gt;subject,);

            $this-&amp;gt;assertEquals('The introduction to the notification.', $mailNotification-&amp;gt;introLines[0]);
            $this-&amp;gt;assertEquals('Thank you for using our application!', $mailNotification-&amp;gt;outroLines[0]);
            $this-&amp;gt;assertEquals('Notification Action', $mailNotification-&amp;gt;actionText);
            $this-&amp;gt;assertEquals($mailNotification-&amp;gt;actionUrl, url('/'));

            return true;
        });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You see here that we are retrieving the content of the mail notification.&lt;/p&gt;

&lt;p&gt;Here is the full code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

namespace Tests\Unit;

use App\Notifications\TestNotification;
use Illuminate\Support\Facades\Notification;
use App\Model\User;
use Tests\TestCase;

class MailNotificationTest extends TestCase
{
    /**
     * @var \Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model|mixed
     */
    private $user;

    /**
     * A basic test example.
     *
     * @return void
     */
    public function testDatabaseNotification()
    {
        Notification::fake();
        $this-&amp;gt;user = User::factory()-&amp;gt;create();
        $email_subject = "Test Notification";

        $this-&amp;gt;user-&amp;gt;notify(new TestNotification($email_subject));

        Notification::assertSentTo($this-&amp;gt;user, TestNotification::class, function ($notification, $channels) use($email_subject){
            $this-&amp;gt;assertContains('database', $channels);

            $databaseNotification = (object)$notification-&amp;gt;toArray($this-&amp;gt;user);
            $this-&amp;gt;assertEquals( $email_subject, $databaseNotification-&amp;gt;title);

            return true;
        });
    }

    public function testMailNotification()
    {
        Notification::fake();
        $this-&amp;gt;user = User::factory()-&amp;gt;create();
        $email_subject = "Test notification";

        $this-&amp;gt;user-&amp;gt;notify(new TestNotification($email_subject));

        Notification::assertSentTo($this-&amp;gt;user, TestNotification::class, function ($notification, $channels) use($email_subject){
            $this-&amp;gt;assertContains('mail', $channels);

            $mailNotification = (object)$notification-&amp;gt;toMail($this-&amp;gt;user);
            $this-&amp;gt;assertEquals($email_subject, $mailNotification-&amp;gt;subject,);

            $this-&amp;gt;assertEquals('The introduction to the notification.', $mailNotification-&amp;gt;introLines[0]);
            $this-&amp;gt;assertEquals('Thank you for using our application!', $mailNotification-&amp;gt;outroLines[0]);
            $this-&amp;gt;assertEquals('Notification Action', $mailNotification-&amp;gt;actionText);
            $this-&amp;gt;assertEquals($mailNotification-&amp;gt;actionUrl, url('/'));

            return true;
        });
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have successfully asserted mail and database content in Laravel notification.&lt;br&gt;
Please share in the comment below what you think about this.&lt;/p&gt;

&lt;p&gt;Happy Coding :)&lt;/p&gt;

</description>
      <category>tdd</category>
      <category>php</category>
      <category>laravel</category>
      <category>notifications</category>
    </item>
    <item>
      <title>How To Make Laravel Pusher Work In Production</title>
      <dc:creator>MacDonald Chika</dc:creator>
      <pubDate>Sat, 12 Feb 2022 12:28:12 +0000</pubDate>
      <link>https://forem.com/macelux/how-to-make-laravel-pusher-work-in-production-2mlj</link>
      <guid>https://forem.com/macelux/how-to-make-laravel-pusher-work-in-production-2mlj</guid>
      <description>&lt;p&gt;If you have ever deployed your laravel code to production environment and then you realized that for some reasons Pusher does not work in your production environment , then you are not alone. I will show you how to make Pusher work in your production environment from the server side. &lt;/p&gt;

&lt;p&gt;To make Pusher work in production, we need to ensure that Pusher has been set up correctly in our application. Let's set up Pusher on our existing Laravel application. If you have already installed Pusher, then skip to the next step. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you don't know how to create a fresh Laravel application click &lt;a href="https://laravel.com/docs/8.x/installation"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Install Pusher&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer require pusher/pusher-php-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once installation is complete, we'll make sure that Laravel broadcasting is registered in &lt;strong&gt;config/app.php&lt;/strong&gt;. Go to config/app.php and uncomment the line below in the &lt;strong&gt;providers&lt;/strong&gt; array.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;// App\Providers\BroadcastServiceProvider&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you need to know more about creating and defining events then take a look at &lt;a href="https://laravel.com/docs/8.x/events#defining-events"&gt;this&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Configure Pusher&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We will configure our pusher app credentials in config/broadcasting.php. We will create and get our Pusher credentials from here. And now. we'll supply our credentials in the .env file as thus:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PUSHER_APP_ID=xxxxxx
PUSHER_APP_KEY=xxxxxxxxxxxxxxxxxxxx
PUSHER_APP_SECRET=xxxxxxxxxxxxxxxxxxxx
PUSHER_APP_CLUSTER=xx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Replace the xs with the actual pusher credentials&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, we need to modify the pusher array in &lt;strong&gt;config/broadcasting.php&lt;/strong&gt; so that it looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'pusher' =&amp;gt; [
    'driver' =&amp;gt; 'pusher',
    'key' =&amp;gt; env('PUSHER_APP_KEY'),
    'secret' =&amp;gt; env('PUSHER_APP_SECRET'),
    'app_id' =&amp;gt; env('PUSHER_APP_ID'),
    'options' =&amp;gt; [
        'cluster' =&amp;gt; env('PUSHER_APP_CLUSTER'),
        'useTLS' =&amp;gt; true,
        'encrypted' =&amp;gt; true,
    ],
],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3: Update .env and Run Artisan Command&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We will now change the value of our broadcast driver in the .env from &lt;strong&gt;log&lt;/strong&gt; to &lt;strong&gt;pusher&lt;/strong&gt;. This tells Laravel what broadcast driver to use when implementing &lt;strong&gt;ShouldBroadcast&lt;/strong&gt;  interface in our event class.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;BROADCAST_DRIVER=pusher&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And finally, run this command in your production environment&lt;/p&gt;

&lt;p&gt;&lt;code&gt;php artisan config:clear&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You might want to run the following command;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;php artisan tinker&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;and then check that your broadcasting configuration is correct - particularly the default connection which should be &lt;code&gt;pusher&lt;/code&gt; - with the following line of code.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;config('broadcasting');&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you have followed the steps above, then your events should work fine now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
You have learned how to make Pusher work in a production environment.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Please note:&lt;/strong&gt; there could be a number of reasons why your Pusher events do not work in your production environment. This is just one of them.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>laravel</category>
      <category>laravelevents</category>
      <category>pushercontest</category>
      <category>php</category>
    </item>
    <item>
      <title>Test-Driven Development (TDD) in Laravel 8</title>
      <dc:creator>MacDonald Chika</dc:creator>
      <pubDate>Tue, 25 Jan 2022 18:17:50 +0000</pubDate>
      <link>https://forem.com/macelux/test-driven-development-tdd-in-laravel-8-21kn</link>
      <guid>https://forem.com/macelux/test-driven-development-tdd-in-laravel-8-21kn</guid>
      <description>&lt;p&gt;Before we delve into Test-Driven Development, let's first define the term TDD.&lt;/p&gt;

&lt;p&gt;**&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Test-Driven Development(TDD)?
&lt;/h2&gt;

&lt;p&gt;**&lt;br&gt;
According to Wikipedia, "&lt;em&gt;Test-Driven Development is a software development process relying on software requirements being converted to test cases before the software is fully developed, and tracking all software development by repeatedly testing the software against all test cases&lt;/em&gt;".&lt;/p&gt;

&lt;p&gt;It is a software development approach that emphasizes writing bug-free codes by developing test cases to specify and validate what the code will do. &lt;/p&gt;

&lt;p&gt;Here is what Test-Driven Development (TDD) cycle looks like;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Write a test&lt;/li&gt;
&lt;li&gt;Run the test -- which will fail&lt;/li&gt;
&lt;li&gt;Write some code&lt;/li&gt;
&lt;li&gt;Run the test again&lt;/li&gt;
&lt;li&gt;Make changes to code to make the test pass(refactor)&lt;/li&gt;
&lt;li&gt;Repeat&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  How To Write Tests in Laravel
&lt;/h2&gt;

&lt;p&gt;For the purpose of this article, we will create a simple CRUD API to create, read  , update and delete blog posts. Let's begin by creating a fresh Laravel project by using &lt;strong&gt;Composer&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Create and initialize the project&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;composer create-project laravel/laravel blog&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd blog&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can run the command below to be sure that everything works fine&lt;br&gt;
&lt;code&gt;php artisan serve&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Set up your test suite&lt;/strong&gt;&lt;br&gt;
Update your &lt;code&gt;phpunit.xml&lt;/code&gt; file in your root directory. Uncomment these lines of codes. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;server name="DB_CONNECTION" value="sqlite"/&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;code&gt;&amp;lt;server name="DB_DATABASE" value=":memory:"/&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The updated file should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
&amp;lt;phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
         bootstrap="vendor/autoload.php"
         colors="true"&amp;gt;
    &amp;lt;testsuites&amp;gt;
        &amp;lt;testsuite name="Unit"&amp;gt;
            &amp;lt;directory suffix="Test.php"&amp;gt;./tests/Unit&amp;lt;/directory&amp;gt;
        &amp;lt;/testsuite&amp;gt;
        &amp;lt;testsuite name="Feature"&amp;gt;
            &amp;lt;directory suffix="Test.php"&amp;gt;./tests/Feature&amp;lt;/directory&amp;gt;
        &amp;lt;/testsuite&amp;gt;
    &amp;lt;/testsuites&amp;gt;
    &amp;lt;coverage processUncoveredFiles="true"&amp;gt;
        &amp;lt;include&amp;gt;
            &amp;lt;directory suffix=".php"&amp;gt;./app&amp;lt;/directory&amp;gt;
        &amp;lt;/include&amp;gt;
    &amp;lt;/coverage&amp;gt;
    &amp;lt;php&amp;gt;
        &amp;lt;server name="APP_ENV" value="testing"/&amp;gt;
        &amp;lt;server name="BCRYPT_ROUNDS" value="4"/&amp;gt;
        &amp;lt;server name="CACHE_DRIVER" value="array"/&amp;gt;
        &amp;lt;server name="DB_CONNECTION" value="sqlite"/&amp;gt;
        &amp;lt;server name="DB_DATABASE" value=":memory:"/&amp;gt;
        &amp;lt;server name="MAIL_MAILER" value="array"/&amp;gt;
        &amp;lt;server name="QUEUE_CONNECTION" value="sync"/&amp;gt;
        &amp;lt;server name="SESSION_DRIVER" value="array"/&amp;gt;
        &amp;lt;server name="TELESCOPE_ENABLED" value="false"/&amp;gt;
    &amp;lt;/php&amp;gt;
&amp;lt;/phpunit&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We uncommented or added those lines of code to ensure that PHPUnit uses &lt;strong&gt;:memory:&lt;/strong&gt; database so that tests run faster. Now that our test suite is set up, let’s set up our base test file &lt;strong&gt;TestCase.php&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

namespace Tests;

use Faker\Factory as Faker;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
use Illuminate\Support\Facades\Artisan;

abstract class TestCase extends BaseTestCase
{
    use CreatesApplication, RefreshDatabase;

    protected $faker;

    /**
     * Sets up the tests
     */
    public function setUp(): void
    {
        parent::setUp();

        $this-&amp;gt;faker = Faker::create();

        Artisan::call('migrate'); // runs the migration
    }


    /**
     * Rolls back migrations
     */
    public function tearDown(): void
    {
        Artisan::call('migrate:rollback');

        parent::tearDown();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You would notice that we use the &lt;strong&gt;RefreshDatabase&lt;/strong&gt; trait because it is often useful to reset our database after each test so that data from a previous test does not interfere with subsequent tests. You may also notice that we added two methods &lt;strong&gt;setUp()&lt;/strong&gt; and &lt;strong&gt;tearDown()&lt;/strong&gt;. The former is run by the test runner prior to each test and the latter after each test. They help keep your test code clean and flexible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Create and write your test&lt;/strong&gt;&lt;br&gt;
To create a test file in laravel 8, simple run this artisan command&lt;/p&gt;

&lt;p&gt;&lt;code&gt;php artisan make:test PostTest&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The command above creates a PostTest.php file in &lt;strong&gt;tests/Feature&lt;/strong&gt; directory.&lt;/p&gt;

&lt;p&gt;The next thing we need to do is write our actual test.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You will need to either prefix your methods name with test i.e testCanCreateAPost or use the /** &lt;a class="mentioned-user" href="https://dev.to/test"&gt;@test&lt;/a&gt; &lt;em&gt;/ annotation. That way **PhpUnit&lt;/em&gt;* knows that it needs to run your test.&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

namespace Tests\Feature;

use Tests\TestCase;

class PostTest extends TestCase
{
    /** @test*/
    public function canCreateAPost()
    {
        $data = [
            'title' =&amp;gt; $this-&amp;gt;faker-&amp;gt;sentence,
            'description' =&amp;gt; $this-&amp;gt;faker-&amp;gt;paragraph
        ];

        $response = $this-&amp;gt;json('POST', '/api/v1/posts', $data);

        $response-&amp;gt;assertStatus(201)
             -&amp;gt;assertJson(compact('data'));

        $this-&amp;gt;assertDatabaseHas('posts', [
          'title' =&amp;gt; $data['title'],
          'description' =&amp;gt; $data['description']
        ]);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4: Run your test&lt;/strong&gt;&lt;br&gt;
Now we need to run our test with phpunit as thus:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;./vendor/bin/phpunit&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;or laravel artisan command which is pretty cool as it provides verbose test reports in order to ease development and debugging:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;php artisan test&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F95scp6coqhqjfuo6uzcu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F95scp6coqhqjfuo6uzcu.png" alt="TDD in Laravel 8"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Oops! Our test &lt;strong&gt;FAILED&lt;/strong&gt;! is this good? Yes, it is in fact fine for our test to fail as it follows the second rule of TDD that it should Fail after creating the test.&lt;/p&gt;

&lt;p&gt;So why did our test fail?&lt;/p&gt;

&lt;p&gt;The error says the expected response code is 201 — as we have asserted in our test — but received** 404 (Not found)&lt;strong&gt;. This means that the endpoint [POST]‘&lt;/strong&gt;/api/v1/posts**’ does not exist and we need to create one. This brings us to the next step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Make Test Pass&lt;/strong&gt;&lt;br&gt;
What we will be doing in this step is to make our test pass. First to get rid of the 404 error, let create an endpoint.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CREATE THE ENDPOINT IN YOUR ROUTE FILE&lt;/strong&gt;&lt;br&gt;
let’s go to our route file located at ‘routes/api.php’ and create that endpoint. All routes created in this file are automatically prefixed with &lt;strong&gt;‘/api’&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;php artisan make:controller --resource&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can either run this command to create a RESTful controller in the /app/Http/Controllers/Api directory or you can create it manually.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now let’s debug our controller and validate our request&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the store method, where the POST request goes, return a response as thus:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class PostController extends Controller
{

    public function index()
    {
        //
    }

    public function create()
    {
        //
    }

    public function store(Request $request)
    {
        return response()
            -&amp;gt;json([
                'message' =&amp;gt; 'Post created'
            ]);
    }


    public function show($id)
    {
        //
    }


    public function edit($id)
    {
        //
    }


    public function update(Request $request, $id)
    {
       //
    }

    public function destroy($id)
    {
        //
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will create a request file containing some validation rules to validate the data going into our database.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;php artisan make:request CreatePostRequest&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Remember to change &lt;strong&gt;false&lt;/strong&gt; to &lt;strong&gt;true&lt;/strong&gt; in the &lt;strong&gt;authorize()&lt;/strong&gt; method&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class CreatePostRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'title' =&amp;gt; ['required'],
            'description' =&amp;gt; ['required']
        ];
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are going to import and pass our CreatePostRequest to the store method of our controller. The store() method in our controller should now look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public function store(CreatePostRequest $request)
{
    return response()
        -&amp;gt;json([
            'message' =&amp;gt; 'Post created'
        ]);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Remember to import the CreatePostRequest class.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;CREATE YOUR MODEL AND MIGRATION&lt;/strong&gt;php artisan make:model Post -m&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;php artisan make:model Post -m&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;This artisan command creates our model and migration. The -m flag creates a migration file under &lt;strong&gt;database/migrations&lt;/strong&gt; directory. We will add &lt;strong&gt;title&lt;/strong&gt; and &lt;strong&gt;description&lt;/strong&gt; columns in our migration as thus:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreatePostsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table-&amp;gt;id();
            $table-&amp;gt;string('title');
            $table-&amp;gt;string('description');
            $table-&amp;gt;timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('posts');
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And in our Model, we have to define the hidden and fillable fields.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;


class Post extends Model
{
    use HasFactory;

    protected $fillable = [
        'title',
        'description'
    ];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once that is done, we will edit our store method as thus:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public function store(CreatePostRequest $request)
{
    $data = $request-&amp;gt;validated();  // only validated request

    $post = Post::create($data);   // creates and return post

    return response()
      -&amp;gt;json([ 
        'message' =&amp;gt; 'Post created'
      ]);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: remember to import the &lt;strong&gt;Post&lt;/strong&gt; class in your controller&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;RE-RUN TESTS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;php artisan test&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3s10mb2423bwnkjjkcy9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3s10mb2423bwnkjjkcy9.png" alt="Failed asserting 201 is identical to 200 - Test-Driven development in Laravel 8"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our test &lt;strong&gt;Failed&lt;/strong&gt; again but this time it says that it can’t assert that &lt;strong&gt;201&lt;/strong&gt; is identical to &lt;strong&gt;200&lt;/strong&gt;. This means that our endpoint returns a 200 response code instead of a &lt;strong&gt;201&lt;/strong&gt;. So let’s add a &lt;strong&gt;201&lt;/strong&gt; response code — which means that the resource was successfully created.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public function store(CreatePostRequest $request)
{
    $data = $request-&amp;gt;validated();  // only validated request

    $post = Post::create($data);   // creates and return post

    return response()
        -&amp;gt;json([ 
            'message' =&amp;gt; 'Post created'
        ], 201);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;let's re-run our test again.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: if you get a &lt;strong&gt;500&lt;/strong&gt; response code, you can take a look at the log file at &lt;strong&gt;/storage/logs/laravel.log&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw3ikl9r0ztdjsux0o5iv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw3ikl9r0ztdjsux0o5iv.png" alt="Unable to find Json - Test-Driven development in laravel 8"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we get another error. It can’t assert that a certain JSON exists, which was defined in our test here&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$data = [
    'title' =&amp;gt; $this-&amp;gt;faker-&amp;gt;sentence,
    'description' =&amp;gt; $this-&amp;gt;faker-&amp;gt;paragraph
];
$response = $this-&amp;gt;json('POST', '/api/v1/posts', $data);
$response-&amp;gt;assertStatus(201)
      -&amp;gt;dump() // use this to know what data is being returned 
     -&amp;gt;assertJson(compact('data')); // this line here
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To solve this, we need to return the created resource to assert that it matches the data that is being sent to the endpoint. So, within our &lt;strong&gt;store()&lt;/strong&gt; method will add a ‘data’ object that returns the newly created resource to our payload.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public function store(CreatePostRequest $request)
{
    $data = $request-&amp;gt;validated();  // only validated request

    $post = Post::create($data);   // creates and return post

    return response()
        -&amp;gt;json([
            'data' =&amp;gt;  $post,
            'message' =&amp;gt; 'Post created'
        ], 201);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once that is done, we will re-run our test.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbgwv461uyw2003oipegj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbgwv461uyw2003oipegj.png" alt="Test passed - Test-driven development in laravel 8"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;WELL DONE! You have made the test pass.&lt;/p&gt;

</description>
      <category>php</category>
      <category>testing</category>
      <category>programming</category>
      <category>laravel</category>
    </item>
  </channel>
</rss>
