jesse_orange_newable's avatar

Relationship is null in test

In my application a User can make an InvestmentApplication. These models are related to each other like so:


/**
 * Get this user's applications
 *
 * @return void
 */
public function applications()
{
    return $this->hasMany(InvestmentApplication::class, 'user_id', 'id');
}


/**
 * Get the user associated with the investment application.
 */
public function user()
{
    return $this->belongsTo(User::class, 'user_id', 'id');
}

Here is the part in my ApplicationController responsible for making applications:


/**
 * Store a new investment application for investing into the fund
 *
 * @param StoreFundApplication $request
 *
 * @return void
 */
public function store(StoreFundApplication $request)
{
    $this->authorize('create', InvestmentApplication::class);

    $data = $request->validated() + [
        'type' => InvestmentApplication::TYPE_FUND,
        'status' => 'Pending',
    ];

    $application = auth()->user()->applications()->create($data);

    event(new ApplicationSubmitted($application));

    return redirect()->route('user.applications.show', [$application]);
}

This triggers ApplicationSubmitted which looks like this:


<?php

namespace App\Events;

use App\InvestmentApplication;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class ApplicationSubmitted
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    /**
     * The instance of InvestmentApplication
     *
     * @var InvestmentApplication
     */
    public $investmentApplication;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct(InvestmentApplication $investmentApplication)
    {
        $this->investmentApplication = $investmentApplication;
    }
}


This event has attached listeners:


ApplicationSubmitted::class => [
    LogApplicationSubmitted::class,
    SendUserApplicationSubmittedNotification::class,
    SendAdminApplicationSubmittedNotification::class,
    GenerateInvestmentApplicationPDF::class,
],

In SendUserApplicationSubmittedNotification I use $investmentApplication->user->first_name but in my test the user returns null.

My test:


<?php

namespace Tests\Feature;

use App\Events\ApplicationSubmitted;
use App\InvestorDetail;
use App\InvestmentApplication;
use App\Mail\Admin\UserApplicationSubmitted;
use App\Notifications\InvestmentApplicationSubmitted;
use App\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Facades\Mail;
use Tests\TestCase;

class FundApplicationTest extends TestCase
{
    use RefreshDatabase;

    /** @test */
    public function a_user_who_has_not_completed_their_investor_details_cannot_access_the_fund_application_form()
    {
        $user = factory(User::class)->create();

        $this->actingAs($user->fresh())
            ->get(route('user.application.fund.create'))
            ->assertStatus(302);
    }

    /** @test */
    public function a_user_who_has_completed_their_investor_details_can_access_the_fund_application_form()
    {
        $user = factory(User::class)->states('verified', 'certified', 'passive')->create();

        $user->investorDetails->update(factory(InvestorDetail::class)->raw([
            'user_id' => $user->id,
        ]));

        $this->assertTrue($user->investorDetails->is_completed);

        $this->actingAs($user)
            ->get(route('user.application.fund.create'))
            ->assertStatus(200);
    }

    /** @test */
    public function a_user_who_has_completed_their_investor_details_can_submit_a_fund_application()
    {
        $this->expectsEvents(ApplicationSubmitted::class);

        $user = factory(User::class)->states('verified', 'certified', 'passive')->create();

        $user->investorDetails->update(factory(InvestorDetail::class)->raw([
            'user_id' => $user->id,
        ]));

        $this->assertTrue($user->investorDetails->is_completed);

        $application = [
            'type' => InvestmentApplication::TYPE_FUND,
            'deal_id' => null,
            'amount_pledged' => 10000,
            'payment_method' => InvestmentApplication::PAYMENT_BANK_TRANSFER,
        ];

        $this->actingAs($user)
            ->post(route('user.application.fund.store'), $application)
            ->assertStatus(302);

        $this->assertDatabaseHas('investment_applications', [
            'user_id' => $user->id,
            'type' => $application['type'],
            'deal_id' => null,
            'amount_pledged' => $application['amount_pledged'],
            'payment_method' => $application['payment_method'],
        ]);
    }

    /** @test */
    public function submitting_a_fund_application_creates_an_activity_for_this_user()
    {
        Notification::fake();

        $user = factory(User::class)->states('verified', 'certified', 'passive')->create();

        $user->investorDetails->update(factory(InvestorDetail::class)->raw([
            'user_id' => $user->id,
        ]));

        $this->assertTrue($user->investorDetails->is_completed);

        $application = [
            'type' => InvestmentApplication::TYPE_FUND,
            'deal_id' => null,
            'amount_pledged' => 10000,
            'payment_method' => InvestmentApplication::PAYMENT_BANK_TRANSFER,
        ];

        $this->actingAs($user)
            ->post(route('user.application.fund.store'), $application)
            ->assertStatus(302);

        $this->assertDatabaseHas('investment_applications', [
            'user_id' => $user->id,
            'type' => $application['type'],
            'deal_id' => null,
            'amount_pledged' => $application['amount_pledged'],
            'payment_method' => $application['payment_method'],
        ]);

        $this->assertDatabaseHas('user_activities', [
            'user_id' => $user->id,
        ]);
    }

    /** @test */
    public function submitting_a_fund_application_sends_a_notification_to_the_user()
    {
        Notification::fake();

        $user = factory(User::class)->states('verified', 'certified', 'passive')->create();

        $user->investorDetails->update(factory(InvestorDetail::class)->raw([
            'user_id' => $user->id,
        ]));

        $this->assertTrue($user->investorDetails->is_completed);

        $application = [
            'user_id' => $user->id,
            'type' => InvestmentApplication::TYPE_FUND,
            'deal_id' => null,
            'amount_pledged' => 10000,
            'payment_method' => InvestmentApplication::PAYMENT_BANK_TRANSFER,
        ];

        $this->actingAs($user)
            ->post(route('user.application.fund.store'), $application)
            ->assertStatus(302);

        $this->assertDatabaseHas('investment_applications', [
            'user_id' => $user->id,
            'type' => $application['type'],
            'deal_id' => null,
            'amount_pledged' => $application['amount_pledged'],
            'payment_method' => $application['payment_method'],
        ]);

        Notification::assertSentTo($user, InvestmentApplicationSubmitted::class);
    }

    /** @test */
    public function submitting_a_fund_application_sends_a_notification_to_npi()
    {
        Mail::fake();

        $user = factory(User::class)->states('verified', 'certified', 'passive')->create();

        $user->investorDetails->update(factory(InvestorDetail::class)->raw([
            'user_id' => $user->id,
        ]));

        $this->assertTrue($user->investorDetails->is_completed);

        $application = [
            'user_id' => $user->id,
            'type' => InvestmentApplication::TYPE_FUND,
            'deal_id' => null,
            'amount_pledged' => 10000,
            'payment_method' => InvestmentApplication::PAYMENT_BANK_TRANSFER,
        ];

        $this->actingAs($user)
            ->post(route('user.application.fund.store'), $application)
            ->assertStatus(302);

        $this->assertDatabaseHas('investment_applications', [
            'user_id' => $user->id,
            'type' => $application['type'],
            'deal_id' => null,
            'amount_pledged' => $application['amount_pledged'],
            'payment_method' => $application['payment_method'],
        ]);

        Mail::assertSent(UserApplicationSubmitted::class, function ($mail) {
            return $mail->hasTo('[email protected]');
        });
    }
}

If I use $this->withOutExceptionHandling() I can do the following in the notification itself:


<?php

namespace App\Notifications;

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

class InvestmentApplicationSubmitted extends Notification implements ShouldQueue
{
    use Queueable;

    /**
     * The investment application submitted
     *
     * @var InvestmentApplication
     */
    public $investmentApplication;

    /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct($investmentApplication)
    {
        $this->investmentApplication = $investmentApplication;
    }

    /**
     * Get the notification's delivery channels.
     *
     * @param  mixed $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return ['mail'];
    }

    /**
     * Get the mail representation of the notification.
     *
     * @param  mixed                                          $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail($notifiable)
    {
        dd($this->investmentApplication->user);
        dd(User::find($this->investmentApplication->user_id));

        return (new MailMessage)
            ->subject("{$notifiable->first_name}, your investment application was submitted")
            ->markdown('emails.user.investment-application-submitted', [
                'application' => $this->investmentApplication,
            ]);
    }
}

The line - dd($this->investmentApplication->user); returns null but the line underneath returns a valid User object.

I am unsure why the investmentApplication thinks it's related user is null, even though I'm posting the store route that uses the relationship to create the application in the first place.

0 likes
19 replies
bugsysha's avatar

Because you are putting your notification into queue. Once it is queued it serializes the InvestmentApplication model. Then when that job is retrieved from queue and executed it unserializes that InvestmentApplication model but since you have not defined within InvestmentApplication model to always load User it does not have that relationship loaded and that is why you do not have access to it.

On your InvestmentApplication model put something like

protected $with = ['user'];

and it will always load your InvestmentApplication model with User relationship which means that you will have access to it after unserialization.

jesse_orange_newable's avatar

Hello,

This was very interesting in terms of my production environment, I'm just not sure why the test still fails. I have taken your advice though, and eager loaded the relation.

jesse_orange_newable's avatar

    /** @test */
    public function submitting_a_fund_application_sends_a_notification_to_the_user()
    {
        Notification::fake();

        $user = factory(User::class)->states('verified', 'certified', 'passive')->create();

        $user->investorDetails->update(factory(InvestorDetail::class)->raw([
            'user_id' => $user->id,
        ]));

        $this->assertTrue($user->investorDetails->is_completed);

        $application = [
            'user_id' => $user->id,
            'type' => InvestmentApplication::TYPE_FUND,
            'deal_id' => null,
            'amount_pledged' => 10000,
            'payment_method' => InvestmentApplication::PAYMENT_BANK_TRANSFER,
        ];

        $this->actingAs($user)
            ->post(route('user.application.fund.store'), $application)
            ->assertStatus(302);

        $this->assertDatabaseHas('investment_applications', [
            'user_id' => $user->id,
            'type' => $application['type'],
            'deal_id' => null,
            'amount_pledged' => $application['amount_pledged'],
            'payment_method' => $application['payment_method'],
        ]);

        Notification::assertSentTo($user, InvestmentApplicationSubmitted::class);
    }

It always says trying to get property first_name of non object, I'm guessing I've fluffed something, but it does work when tested in a real browser with mail trap.


@component('mail::message')
# Dear {{ $application->user->first_name, 'Investor' }},

Your investment application was submitted successfully, we'll get back to you once this application has been processed.

**Your application details**

@component('mail::table')
| &nbsp;        | &nbsp;        | 
| ------------- |:-------------:| 
| Date of submission      | {{ $application->created_at->format('d M Y') }}                           |
| Amount pledged  | £{{ $application->amount_pledged }}                                               | 
| Type of application  | {{ $application->type }}                                                     | 
| Deal referenced  | {{ $application->deal ? $application->deal->name : 'Not applicable' }} | 
@endcomponent

@component('mail::panel')
This is an automated email from an unattended mailbox
@endcomponent

@component('mail::subcopy')
**Risk warning:** Your capital is at risk. Investing in early stage companies involves risks including loss of capital, illiquidity, lack of dividends and dilution. Newable Ventures Limited does not give tax or investment advice. The availability of tax relief depends on individual investors’ circumstances, and on investee companies’ qualifying status, both of which may be subject to change. If you are in doubt about eligibility for tax reliefs or the tax treatment of your investment, you should seek independent tax advice.

Newable Ventures Limited (FRN 795277) is an Appointed Representative of Larpent Newton & Co Ltd. Larpent Newton & Co Ltd is authorised and regulated by the Financial Conduct Authority, FRN 141275. 
Neither Newable Capital Limited nor Newable Private Investing Limited are Authorised and Regulated by the Financial Conduct Authority.
@endcomponent

@endcomponent

jesse_orange_newable's avatar

1) Tests\Feature\FundApplicationTest::submitting_a_fund_application_sends_a_notification_to_the_user
Facade\Ignition\Exceptions\ViewException: Trying to get property 'full_name' of non-object (View: C:\xampp\htdocs\projects\newable\npi-portal-laravel\resources\views\emails\admin\investment-application-submitted.blade.php)

C:\xampp\htdocs\projects\newable\npi-portal-laravel\resources\views/emails/admin/investment-application-submitted.blade.php:4
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\View\Engines\PhpEngine.php:43
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\View\Engines\CompilerEngine.php:59
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\facade\ignition\src\Views\Engines\CompilerEngine.php:36
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\View\View.php:143
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\View\View.php:126
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\View\View.php:91
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Mail\Markdown.php:64
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Mail\Mailable.php:267
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Mail\Mailable.php:237
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Mail\Mailable.php:153
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Support\Traits\Localizable.php:19
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Mail\Mailable.php:160
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Mail\SendQueuedMailable.php:52
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php:32
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Container\Util.php:36
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php:90
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php:34
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Container\Container.php:590
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Bus\Dispatcher.php:94
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:130
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:105
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Bus\Dispatcher.php:98
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Queue\CallQueuedHandler.php:83
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:130
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:105
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Queue\CallQueuedHandler.php:85
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Queue\CallQueuedHandler.php:59
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Queue\Jobs\Job.php:88
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Queue\SyncQueue.php:45
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Queue\Queue.php:44
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Mail\Mailable.php:180
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Mail\Mailer.php:276
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Mail\Mailer.php:231
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Support\Facades\Facade.php:261
C:\xampp\htdocs\projects\newable\npi-portal-laravel\app\Listeners\SendAdminApplicationSubmittedNotification.php:28
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Events\Dispatcher.php:366
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Events\Dispatcher.php:196
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Foundation\helpers.php:482
C:\xampp\htdocs\projects\newable\npi-portal-laravel\app\Http\Controllers\User\FundController.php:61
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Routing\Controller.php:54
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Routing\ControllerDispatcher.php:45
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Routing\Route.php:219
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Routing\Route.php:176
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Routing\Router.php:681
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:130
C:\xampp\htdocs\projects\newable\npi-portal-laravel\app\Http\Middleware\FundApplicationPending.php:20
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\app\Http\Middleware\ApplicationCompleted.php:24
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\app\Http\Middleware\EligibleInvestor.php:33
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Auth\Middleware\EnsureEmailIsVerified.php:29
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Routing\Middleware\SubstituteBindings.php:41
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Auth\Middleware\Authenticate.php:43
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\VerifyCsrfToken.php:76
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\View\Middleware\ShareErrorsFromSession.php:49
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Session\Middleware\StartSession.php:56
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse.php:37
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Cookie\Middleware\EncryptCookies.php:66
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:105
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Routing\Router.php:683
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Routing\Router.php:658
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Routing\Router.php:624
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Routing\Router.php:613
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php:170
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:130
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\barryvdh\laravel-debugbar\src\Middleware\InjectDebugbar.php:58
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\TransformsRequest.php:21
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\TransformsRequest.php:21
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\ValidatePostSize.php:27
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode.php:63
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\fideloper\proxy\src\TrustProxies.php:57
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:105
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php:145
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php:110
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Foundation\Testing\Concerns\MakesHttpRequests.php:434
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Foundation\Testing\Concerns\MakesHttpRequests.php:252
C:\xampp\htdocs\projects\newable\npi-portal-laravel\tests\Feature\FundApplicationTest.php:139

Caused by
ErrorException: Trying to get property 'full_name' of non-object

C:\xampp\htdocs\projects\newable\npi-portal-laravel\storage\framework\viewse371f9d3c458ba53431582c1994380e1f3c879.php:4
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\View\Engines\PhpEngine.php:43
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\View\Engines\CompilerEngine.php:59
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\facade\ignition\src\Views\Engines\CompilerEngine.php:36
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\View\View.php:143
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\View\View.php:126
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\View\View.php:91
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Mail\Markdown.php:64
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Mail\Mailable.php:267
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Mail\Mailable.php:237
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Mail\Mailable.php:153
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Support\Traits\Localizable.php:19
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Mail\Mailable.php:160
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Mail\SendQueuedMailable.php:52
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php:32
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Container\Util.php:36
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php:90
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php:34
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Container\Container.php:590
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Bus\Dispatcher.php:94
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:130
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:105
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Bus\Dispatcher.php:98
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Queue\CallQueuedHandler.php:83
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:130
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:105
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Queue\CallQueuedHandler.php:85
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Queue\CallQueuedHandler.php:59
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Queue\Jobs\Job.php:88
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Queue\SyncQueue.php:45
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Queue\Queue.php:44
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Mail\Mailable.php:180
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Mail\Mailer.php:276
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Mail\Mailer.php:231
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Support\Facades\Facade.php:261
C:\xampp\htdocs\projects\newable\npi-portal-laravel\app\Listeners\SendAdminApplicationSubmittedNotification.php:28
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Events\Dispatcher.php:366
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Events\Dispatcher.php:196
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Foundation\helpers.php:482
C:\xampp\htdocs\projects\newable\npi-portal-laravel\app\Http\Controllers\User\FundController.php:61
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Routing\Controller.php:54
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Routing\ControllerDispatcher.php:45
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Routing\Route.php:219
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Routing\Route.php:176
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Routing\Router.php:681
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:130
C:\xampp\htdocs\projects\newable\npi-portal-laravel\app\Http\Middleware\FundApplicationPending.php:20
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\app\Http\Middleware\ApplicationCompleted.php:24
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\app\Http\Middleware\EligibleInvestor.php:33
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Auth\Middleware\EnsureEmailIsVerified.php:29
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Routing\Middleware\SubstituteBindings.php:41
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Auth\Middleware\Authenticate.php:43
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\VerifyCsrfToken.php:76
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\View\Middleware\ShareErrorsFromSession.php:49
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Session\Middleware\StartSession.php:56
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse.php:37
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Cookie\Middleware\EncryptCookies.php:66
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:105
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Routing\Router.php:683
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Routing\Router.php:658
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Routing\Router.php:624
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Routing\Router.php:613
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php:170
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:130
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\barryvdh\laravel-debugbar\src\Middleware\InjectDebugbar.php:58
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\TransformsRequest.php:21
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\TransformsRequest.php:21
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\ValidatePostSize.php:27
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode.php:63
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\fideloper\proxy\src\TrustProxies.php:57
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:171
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:105
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php:145
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php:110
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Foundation\Testing\Concerns\MakesHttpRequests.php:434
C:\xampp\htdocs\projects\newable\npi-portal-laravel\vendor\laravel\framework\src\Illuminate\Foundation\Testing\Concerns\MakesHttpRequests.php:252
C:\xampp\htdocs\projects\newable\npi-portal-laravel\tests\Feature\FundApplicationTest.php:139

bugsysha's avatar

@jesse_orange_newable

In error you are getting emails\admin\investment-application-submitted.blade.php and in notification you are using emails.user.investment-application-submitted. Is that a typo or what?

jesse_orange_newable's avatar

It's I think because it that test, it's triggering both listeners so the user object is null in both.


ApplicationSubmitted::class => [
    LogApplicationSubmitted::class,
    SendUserApplicationSubmittedNotification::class,
    SendAdminApplicationSubmittedNotification::class,
    GenerateInvestmentApplicationPDF::class,
],

bugsysha's avatar

@jesse_orange_newable you said that it is complaining about first_name but this error says that the full_name is a problem. Search through your files for full_name and replace it with first_name if that is the correct property on that model.

jesse_orange_newable's avatar

Both attributes exist:


    /**
     * Get the user's full name.
     *
     * @return string
     */
    public function getFullNameAttribute()
    {
        return "{$this->first_name} {$this->last_name}";
    }

bugsysha's avatar

Try to replicate it on new Laravel project.

bugsysha's avatar

At a glance I do not see anything wrong that pops out. There is a bunch of stuff that I would do differently, but it should work.

Problem is that I do not see that view which is complaining about full_name. Is that the only error you are getting?

Post that view here.

jesse_orange_newable's avatar

The view is this one:


@component('mail::message')
# Dear {{ $application->user->first_name, 'Investor' }},

Your investment application was submitted successfully, we'll get back to you once this application has been processed.

**Your application details**

@component('mail::table')
| &nbsp;        | &nbsp;        | 
| ------------- |:-------------:| 
| Date of submission      | {{ $application->created_at->format('d M Y') }}                           |
| Amount pledged  | £{{ $application->amount_pledged }}                                               | 
| Type of application  | {{ $application->type }}                                                     | 
| Deal referenced  | {{ $application->deal ? $application->deal->name : 'Not applicable' }} | 
@endcomponent

@component('mail::panel')
This is an automated email from an unattended mailbox
@endcomponent

@component('mail::subcopy')
@include('emails.partials.risk-warning')
@endcomponent

@endcomponent


and for the admin one, it's this:


@component('mail::message')
# Hi,

{{ $investmentApplication->user->full_name }} has submitted an investment application.

**Application details**

@component('mail::table')
| &nbsp;        | &nbsp;        | 
| ------------- |:-------------:| 
| Date of submission      | {{ $investmentApplication->created_at->format('d M Y') }}                           |
| Amount pledged  | £{{ $investmentApplication->amount_pledged }}                                               | 
| Type of application  | {{ $investmentApplication->type }}                                                     | 
| Deal referenced  | {{ $investmentApplication->deal ? $investmentApplication->deal->name : 'Not applicable' }} | 
@endcomponent

@component('mail::panel')
This is an automated email from an unattended mailbox
@endcomponent

@endcomponent

it's called $application in one because I pass it as application to that view.

Can I ask what you would do differently?

bugsysha's avatar
bugsysha
Best Answer
Level 61

it's called $application in one because I pass it as application to that view.

Yeah, that is not an issue. I have same workflow in my app and everything is working in tests. You've probably missed something.

Steps I have

- Dispatch event and pass to it a model which belongs to a user, inject that model through constructor and make that instance property public
- Register listener for that event in EventServiceProvider
- In handle method for that listener send notification and pass user or users which receive that notification and new instance of that notification to which you pass model from event or user
- In notification inject model or user through constructor and then you can access that instance property from toMail method

Can I ask what you would do differently?

I was thinking about cleaning up tests and code, nothing special

  • is_complete I would use completed_at datetime is far more usable than boolean
  • route('user.application.fund.create') too much nesting of routes
  • 'verified', 'certified' confusing naming
  • since there is already $request no need for auth()->user()
  • $user->investorDetails->update(factory(InvestorDetail::class)->raw([...])); why not use factory here
  • ->assertStatus(302); replace with this ->assertRedirect() or this assertStatus(Response::HTTP_FOUND)

Bottom line is that test works when everything is wired correctly. There is something that is breaking it which I do not see from what you've shown here.

jesse_orange_newable's avatar

Thanks for the feedback, I'm going to go back through and recheck everything.

verified - email verified certified - if you've done the certification

Ah, so you're thinking $request->user() instead?

$user->investorDetails->update(factory(InvestorDetail::class)->raw([...]));

Ah, so rather than updating a user, just make the factory with a user_id included?

Our approaches seem similar, so I'll go and check everything.

jesse_orange_newable's avatar

To be fair, this is the first app I'm properly testing and it's been very useful so far, mainly for refactoring.

Please or to participate in this conversation.