Dynamic buttons href tests with phpunit - php

I'm initiating my tests using phpunit so, I have doubts about how to test things dynamically. I created a table dynamically as the image bellow
Here are my view:
<div class="panel-body">
#if(Session::has('success'))
<div class="alert alert-success">{{Session::get('success')}}</div>
#endif
<table class="table">
<th>Unity Name</th>
<th>Phone Number</th>
<th>Actions</th>
<tbody>
#foreach($companies as $company)
<tr>
<td>{{$company->name}}</td>
<td>{{$company->owner_number}}</td>
<td>
{{Form::open(['method' => 'DELETE', 'url'=>'/admin/company/'.$company->id, 'style' => 'display:inline'])}}
<button type="submit" class="btn btn-default fa fa-trash-o"></button>
{{Form::close()}}
</td>
</tr>
#endforeach
</tbody>
</table>
</div>
</div>
So, how can I test the href tag if I haven't previously the tag id?

I did some tests like these one in Symfony projects.
In dev environment, I insert some data in a dev database. After this step, I launch functionnal tests. In these tests, I analyze tag's content. Here is an example from your data :
$client = static::createClient();
$crawler = $client->request('GET', '/yourUrl');
$node = $crawler->filter('#show-company-1');
self::assertNotEmpty($node, "Node #show-company-1 does not exists");
self::assertEmpty( $node->html(), "#show-company-1 content is not empty");
self::assertContains('/admin/company/1', $node->attr('href'), "a#show-company-1.href has not a good value");
Before request, you can add some logic to determine the id of your company.

Related

I am getting a "Trying to get property of non-object" error from my controller

I am getting a "Trying to get property of non-object" error whenever I try to process a deposit in my controller
Here is my controller
users::where('id',$user->id)
->update([
'confirmed_plan' => $deposit->plan,
'activated_at' => \Carbon\Carbon::now(),
'last_growth' => \Carbon\Carbon::now(),
]);
//get plan
$p=plans::where('id',$deposit->plan)->first();
//get settings
$settings=settings::where('id', '=', '1')->first();
$earnings=$settings->referral_commission*$p->price/100;
//increment the user's referee total clients activated by 1
agents::where('agent',$user->ref_by)->increment('total_activated', 1);
agents::where('agent',$user->ref_by)->increment('earnings', $earnings);
}
//update deposits
deposits::where('id',$id)
->update([
'status' => 'Processed',
]);
return redirect()->back()
->with('message', 'Action Sucessful!');
}
And The Error seems to be at this line of code
$earnings=$settings->referral_commission*$p->price/100;
And Here is my process deposit view blade
#include('header')
<!-- //header-ends -->
<!-- main content start-->
<div id="page-wrapper">
<div class="main-page signup-page">
<h3 class="title1">Manage clients deposits</h3>
#if(Session::has('message'))
<div class="row">
<div class="col-lg-12">
<div class="alert alert-info alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<i class="fa fa-info-circle"></i> {{ Session::get('message') }}
</div>
</div>
</div>
#endif
<div class="bs-example widget-shadow table-responsive" data-example-id="hoverable-table">
<table class="table table-hover">
<thead>
<tr>
<th>ID</th>
<th>Client name</th>
<th>Client email</th>
<th>Amount</th>
<th>Payment mode</th>
<th>Plan</th>
<th>Status</th>
<th>Date created</th>
<th>Option</th>
</tr>
</thead>
<tbody>
#foreach($deposits as $deposit)
<tr>
<th scope="row">{{$deposit->id}}</th>
<td>{{$deposit->duser->name}}</td>
<td>{{$deposit->duser->email}}</td>
<td>${{$deposit->amount}}</td>
<td>{{$deposit->payment_mode}}</td>
#if(isset($deposit->dplan->name))
<td>{{$deposit->dplan->name}}</td>
#else
<td>For withdrawal</td>
#endif
<td>{{$deposit->status}}</td>
<td>{{$deposit->created_at}}</td>
<td> <a class="btn btn-default" href="{{ url('dashboard/pdeposit') }}/{{$deposit->id}}">Process</a></td>
</tr>
#endforeach
</tbody>
</table>
</div>
</div>
</div>
#include('modals')
#include('footer')
I keep getting "Trying to get property of non-object" error without any explanation as to where to look at. I need help please.
Are you sure you have a $settings object with id of 1?
$settings=settings::where('id', '=', '1')->first(); // <-- why 1, why not just first()?
If you are hard coding a single id for a single setting into the DB that will always be the same, and always id of 1... consider just adding that to code instead.
Also check on $deposit->plan -- is this correct, or maybe should this be $deposit->plan_id or similar? Perhaps the $p is null because there is no value for $deposit->plan.
You can set some error checking here by checking for null ahead of the calculation:
if(isset($settings) && isset($p)){
$earnings=$settings->referral_commission*$p->price/100;
}
else
{
$earnings = 0; // or whatever you want to replace it with should there be no setting
}

Can't delete from SQLite table in Laravel

I'm Doing a "take home assignment" for job interview. While I have some experience in web development, its not my forte. I am trying to delete a row in a SQLite table using a HTML DELETE button. I am using Laravel-php framework.
I've tried different solutions on google and stack Overflow, but none seem to solve the problem. I modeled my approach after this Laracasts video
Link to my code
The blade seems to be passing the correct info ($id from $contact->id) & the controller seems to be receiving. But the given contact associated with the id isn't being deleted.
FROM BLADE:
<div class="col-md-6">
<table class="table table-striped table-hover">
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Address</th>
</tr>
#foreach($contacts as $contact)
<tr>
<td> {{$contact->f_name}} </td>
<td> {{$contact->l_name}} </td>
<td> {{$contact->address}} </td>
<td>
<form method="POST" action="/delete/{{ $contact->id }}">
#method('DELETE')
#csrf
<div class="field">
<div class="control">
<button type="submit" class="button">Delete Contact</button>
</div>
</div>
</form>
</td>
</tr>
#endforeach
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</table>
</div>
FROM CONTROLLER:
public function delete($id) {
Contact::find($id)->delete();
return view('index');
}
FROM ROUTE:
Route::delete('/delete', [
'uses'=>'ContactController#delete',
'as'=>'contacts.delete'
]);
you're not getting the id on your delete method, you need to include it on the url like
Route::delete('/delete/{id}', [
'uses'=>'ContactController#delete',
'as'=>'contacts.delete'
]);
in this case, you don't need to change the delete method.
you can also retrieve the id from the request object without changing the delete route, int this case you need to include the id as a hidden input on your view and your delete method will look like this
public function delete(Request $request) {
Contact::find($request->id)->delete();
return view('index');
}

Laravel 5.8 Routed page not found 404 error

I am new to Laravel. I am learning Laravel from tutorial and I drive into one problem which I can't solve.
I think I have problem somewhere into Routing, but I can't find it
Funny thing is that if the href is {{route('tag.create'}}, then it goes to creating page, but when I need to use ID it's not working...
I had same functionality for posts and categories, but everything worked fine for those two. So I really need your help to see what I can't see. I have these files:
index.blade.php:
#extends('layouts.app')
#section('content')
<div class="card">
<div class="card-body">
<table class="table table-hover">
<thead>
<th>
Tag name
</th>
<th>
Delete
</th>
</thead>
<tbody>
#if($tags->count()>0)
#foreach($tags as $tag)
<tr>
<td>
{{$tag->tag}}
</td>
<td>
<i class="fa fa-trash" aria-hidden="true"></i>
</td>
</tr>
#endforeach
#else
<tr>
<th colspan="5" class="text-center">
No tags yet
</th>
</tr>
#endif
</tbody>
</table>
</div>
</div>
#stop
web.php - this is the place where I define routes for tags for TagsController.php:
//Tags
Route::get('/tags',[
'uses'=>'TagsController#index',
'as'=> 'tags'
]);
Route::post('/tag/update/{$id}',[
'uses'=>'TagsController#update',
'as'=> 'tag.update'
]);
Route::get('/tag/create',[
'uses'=>'TagsController#create',
'as'=> 'tag.create'
]);
Route::post('/tag/store',[
'uses'=>'TagsController#store',
'as'=> 'tag.store'
]);
Route::get('/tag/delete/{$id}',[
'uses'=>'TagsController#destroy',
'as'=> 'tag.delete'
]);
TagsController.php - at first I tried to destroy the element, then I tried to return create view(because when I go through /tag/create rout everything works), but neither worked here
public function destroy($id)
{
return view ('admin.tags.create');
/*
Tag::destroy($id);
Session::flash('success', 'Tag deleted succesfully');
return redirect()->back();*/
}
I believe that you should set the route to Route::get('/tag/delete/{id}',[ 'uses'=>'TagsController#destroy', 'as'=> 'tag.delete' ]); because in your case you are telling the route to expect a variable called $id
Please change the parameters in the route setup in web.php from $id to id. I should solve your issue.
Eg: Route::get('/tag/delete/{id}',[
'uses'=>'TagsController#destroy',
'as'=> 'tag.delete'
]);
Thanks !!.

Laravel parent-child data displaying in Bootstrap table in blade

I have a simple Laravel project to show parent records in a table, with collapsible row(s) to show child records. I have a nice Bootstrap table, can join the parent and child tables in my controller and populate the table, but can't group the children under the one parent. I'm not sure if I built the passed dataset incorrectly in my controller, or if I'm missing some "Laravel way" to do this. It's an easy proposition, loop through the parents until one has a child, then loop through it's children, then resume looping parents, etc., but it's driving me insane. I can't find any direct example or reference to solve my issue, but this is a common requirement.
I need to know how to reference the child records to loop through them to populate the collapsed section. My attempts either result in a parent row for each individual child (the code shown) or a bunch of duplicated child items. If I could pass two datasets from my controller, one of parents and a separate of children, then I could in code build this, but I don't know how to do that in Laravel or if there's an easier way.
I did start with Laravel DataTables but to get detail child rows requires implementing handlebar templates in Laravel and I couldn't find a usable reference to do that, so decided to revert to from-scratch-code my own using a Bootstrap table. Than I got stuck.
Here's my controller (DataassetsController.php). The "investment-accounts" table contains parents (as do the other joined tables), and the "investment-line-items" table contains child records for the "investment-accounts".
class DataassetsController extends Controller
{
public function getUnion()
{
$money = DB::table('monetary_assets')
->select(['monetary_asset_name as name', 'monetary_asset_type as type', 'monetary_asset_value as value', DB::raw("NULL as item"), DB::raw("NULL as institution_id"), DB::raw("NULL as item_id")]);
$personal = DB::table('personal_property_assets')
->select(['personal_name as name', 'personal_type as type', 'personal_current_value as value', DB::raw("NULL as item"), DB::raw("NULL as institution_id"), DB::raw("NULL as item_id")]);
$investments = DB::table('investment_accounts')
->join('investment_line_items', 'investment_institution_name_id', '=', 'investment_accounts.id')
->select(['investment_institution_name as name', 'Investment_account_type as type', DB::raw("NULL as value"), 'investment_name as item', 'investment_institution_name_id as institution_id', 'investment_accounts.id as item_id' ]);
$union = DB::table('real_property_assets')
->select(['real_name as name', 'real_type as type', 'real_current_value as value', DB::raw("NULL as item"), DB::raw("NULL as institution_id"), DB::raw("NULL as item_id")])
->union($money)
->union($personal)
->union($investments)
->get();
return view('assets.allassets', ['user_assets' => $union]);
}
Here's my route:
Route::get('/dataassets', 'DataassetsController#getUnion');
Here's my blade (allassets.blade.php) code:
#extends('layouts.master')
<!-- Collapsible accordion rows in bootstrap -->
<div class="col-lg-6">
<div class="panel panel-default">
<div class="panel-heading"><h3>All Assets</h3></div>
<div class="panel-body">
<table class="table table-condensed" style="border-collapse:collapse;">
<thead>
<tr><th> </th>
<th>Asset Name</th>
<th>Type</th>
<th>Value</th>
</tr>
</thead>
<tbody>
#foreach ($user_assets as $user_asset) <!-- don't forget to add a variable to the loop to index ID's of subrow -->
<tr data-toggle="collapse" data-target="#demo{{$loop->index}}" class="accordion-toggle">
#isset($user_asset->item)
<td><button class="btn btn-default btn-xs"><span class="glyphicon glyphicon-eye-open"></span></button></td>
#else
<td></td>
#endisset
<td>{{$user_asset->name}}</td>
<td>{{$user_asset->type}}</td>
<td style="text-align:right">${{ number_format($user_asset->value,2)}}</td>
<?php $var = ($user_asset->name); ?>
</tr>
#isset($user_asset->item)
<tr>
<td colspan="12" class="hiddenRow"><div class="accordian-body collapse" id="demo{{$loop->index}}">
<table class="table table-striped">
<thead>
<th>Item</th>
<th>Value</th>
<th>Institution</th>
<th>Item</th>
<th>Edit</th>
</thead>
<tbody>
<tr>
<td>{{$user_asset->item}}</td>
<td> placeholder</td>
<td> {{$user_asset->institution_id}}</td>
<td> {{$user_asset->item_id}}</td>
<td><a href="#" class="btn btn-default btn-sm">
<i class="glyphicon glyphicon-cog"></i></a></td></tr>
</tbody>
</table>
</div> </td>
</tr>
#endisset
#endforeach
</tbody>
</table>
</div>
</div>
</div>
<!-- end Bootstrap table -->
Here's a picture of what I get, with one of the children rows popped out:
Bootstrap table showing only one child at a time with multiple copies of parent
Here's a pic of the database tables in question:
The parent and child tables (other tables referenced above do not have children, only this one)
I'm using Laravel 5.5 & PHP7 on XAMPP
Any help or suggestions are very welcome.

Laravel "No query results for model [App\Schedule]" error when not calling model

I have a perplexing issue that I cannot seem to figure out. I am trying to load a webpage from a button, but it keeps poping up the error No query results for model [App\Schedule]. I have no idea why it's doing that, as there is nowhere I am trying to access that model when trying to load the webpage. Below is what I have so far (it's a work in progress)
Here is the link:
<a class="btn btn-primary" role="button" href="/schedule/availability">Set Availability</a>
Here is the Route:
Route::get('/schedule/availability', 'ScheduleController#getAvailabilityCalendar');
Here is the method inside of the ScheduleController:
public function getAvailabilityCalendar(){
$dt = Carbon::now('America/Los_Angeles');
$return['DayOfWeek'] = $dt->dayOfWeek;
$return['DisplayDays'] = (($dt->daysInMonth + $return['DayOfWeek'] + 1) <= 35) ? 34:41;
return view('contractors.availability', compact('return'));
}
And here is the view that is returned:
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>Sunday </th>
<th>Monday </th>
<th>Tuesday </th>
<th>Wednesday </th>
<th>Thursday </th>
<th>Friday </th>
<th>Saturday </th>
</tr>
</thead>
<tbody>
<tr>
#for ($i = 0, $j=-$return['DayOfWeek']; $i <= $return['DisplayDays']; $i++, $j++)
#if($i < $return['DayOfWeek'])
<td></td>
#else
#if($i %7 == 0)
</tr><tr>
#endif
#if($j < 30)
<td>{{\Carbon\Carbon::now('America/Los_Angeles')->addDays($i-$return['DayOfWeek']+1)->format('F jS')}}
<hr>
<div class="form-group">
<label data-toggle="popover" data-trigger="hover" data-content="Add Times available in the following format: 10:00am-4:00pm. You may also add multiple blocks of time separated by comma. Example: 10:00am-12:00pm, 2:00pm-4:00pm">Available Time</label>
<input type="text" class="form-control availability" />
</div>
<div class="checkbox">
<label>
<input type="checkbox" class="all-day-check" />All Day</label>
</div>
</td>
#else
<td></td>
#endif
#endif
#endfor
</tr>
</tbody>
</table>
</div>
<script>
$(document).on('change', '.all-day-check', function(){
if (this.checked) {
$(this).closest("input.availability").prop("disabled", true);
}else{
$(this).closest("input.availability").prop("disabled", false);
}
});
</script>
I can't find anywhere that would need a reference to the App\Schedule model, which is a model in my project. I am at a total loss as to what it could be or why it's trying to run something I never asked it to run.
Edit: There is also no other instance of /schedule/availability in the routes file as well, I triple checked.
Update: Here is the Constructor for ScheduleController:
public function __construct()
{
$this->middleware('auth'); //Check is user is logged in
}
Here is the stacktrace I received (For some reason, it didn't show up in my error log so I only have the screenshot)
As it turns out in the discussion in comments above. The culprit is narrowed down to a conflicting route.
Route:something('/schedule', ...)
was found before
Route::get('/schedule/availability', 'ScheduleController#getAvailabilityCalendar');
and the Route:something fires before the desired route. It should be noted that route defined first will be the first one to serve. This is the reason why Route:resource should be put after your custom Route:get or another routes to avoid confusion.
Next item in the list when changing routes but it does not updated, alwasy fire a php artisan route:clear. It will clear the route caches - can check in the docs.

Categories