I want to test a repository pattern in Laravel 5.6 using PHPUnit and Mockery.
This is my code:
// PackageControllerTest.php
namespace Tests\Feature;
use Tests\TestCase;
use App\Contracts\PackageInterface;
use App\Http\Controllers\PackageController;
use Illuminate\Database\Eloquent\Collection;
class PackageControllerTest extends TestCase
{
protected $mock;
protected $target;
public function setUp()
{
parent::setUp();
parent::initDatabase();
$this->mock = $this->initMock(PackageInterface::class);
$this->target = $this->app->make(PackageController::class);
}
public function testIndex()
{
$expected = new Collection([
['name' => 'Name 1', 'html_url' => 'HTML URL 1'],
['name' => 'Name 2', 'html_url' => 'HTML URL 2'],
['name' => 'Name 3', 'html_url' => 'HTML URL 3'],
]);
$this->mock
->shouldReceive('getAllPackages')
->once()
->andReturn($expected);
$actual = $this->target->index()->packages;
$this->assertEquals($expected, $actual);
}
public function testUpdate()
{
//
}
public function tearDown()
{
parent::resetDatabase();
$this->mock = null;
$this->target = null;
}
}
// PackageControllerTest.php
...
public function index()
{
$packages = $this->package->getAllPackages();
return view('package.index', compact('packages'));
}
public function update($package_id)
{
$package = $this->package->updatePackage($package_id);
return redirect()->back();
}
// PackageRepository.php
...
public function getAllPackages()
{
$packages = $this->package->all();
return $packages;
}
public function updatePackage($package_id)
{
$package = $this->package->find($package_id);
$package->description = $this->request->description;
$package->save();
return $package;
}
The part of "testIndex()" works.
But next, I want to test the part of "testUpdate()".
How can I do?
Please help, thanks.
like this
$this->mock
->shouldReceive('updatePackage')
->with(1)
->once()
->andReturn($expected);
$actual = $this->target->update(1);
$this->assertRedirect('edit page url');
or
use DatabaseTransactions in top of class
$id = DB::table('your_table')->insertGetId(['description' => 'old'])
request()->set('description', 'test');
$actual = $this->target->update(id);
$this->assertDatabaseHas('your_table', [
'id' => $id,
'description' => 'test'
]);
Related
I want test the return output on repository method. But when i call the method the database suddenly refreshed. But when i try to not call the repository method and i debug the table it has record. Here is my code, am i miss something ?
use App\Repositories\UserRepository;
class ExampleTest extends TestCase
{
protected $repository;
protected function setUp(): void
{
parent::setUp();
$this->repository = app(UserRepository::class);
}
public function it_should_return_empty_when_no_filter_found()
{
$this->seedingDb();
$response = $this->repository->filter(); // When i call this the record on table return empty
dd($response); // Result empty
}
private function seedingDb()
{
for ($i = 0; $i < 5; $i++) {
User::create([
'name' => $this->faker->word,
'role' => $this->faker->word,
'property_name' => $this->faker->word,
'email' => $this->faker->email,
'phone_number' => $this->faker->phoneNumber,
'password' => $this->faker->word,
'status' => 'active',
]);
}
}
}
User Repository:
use App\Repositories\UserRepository;
class UserRepository
{
public function filter()
{
return User::whereStatus('active')->get()->toArray();
}
}
The User::create() method is probably returning errors.
Try creating a model factory as described here: https://laravel.com/docs/8.x/database-testing#defining-model-factories
That way, instead of $this->seedingDb() you can do:
$users = User::factory()->count(5)->make();
I am using Laravel-5.8 for a web application. Also, I am using maatwebsite-3.1 to import excel file.
Model: HrEmployee
protected $table = 'hr_employees';
protected $fillable = [
'employee_code',
'user_id',
'address',
'company_id',
'email',
'line_manager_id',
'employee_designation_id',
'employee_job_title_id',
'employee_status_id',
'employee_type_id',
'employement_type_id',
'employment_date',
'first_name',
'last_name',
'is_hod'
];
public function user()
{
return $this->belongsTo('App\User');
}
public function parent()
{
return $this->belongsTo('HrEmployee', 'line_manager_id');
}
public function children()
{
return $this->hasMany('HrEmployee', 'ine_manager_id');
}
public function company()
{
return $this->belongsTo('App\Models\Organization\OrgCompany','company_id');
}
public function designation()
{
return $this->belongsTo('App\Models\Hr\HrDesignation','employee_designation_id');
}
public function jobtitle()
{
return $this->belongsTo('App\Models\Hr\HrJobTitle','employee_job_title_id');
}
public function employeestatus()
{
return $this->belongsTo('App\Models\Hr\HrEmployeeStatus','employee_status_id');
}
public function employeetype()
{
return $this->belongsTo('App\Models\Hr\HrEmployeeType','employee_type_id');
}
public function employementtype()
{
return $this->belongsTo('App\Models\Hr\HrEmployementType','employement_type_id');
}
public function department()
{
return $this->belongsTo('App\Models\Organization\OrgDepartment','department_id');
}
I have already configured the Maatwebsite Excel Package
app/Imports/EmployeesImport.php
namespace App\Imports;
use App\User;
use App\HrEmployee;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
class EmployeesImport implements ToModel, WithHeadingRow
{
public function model(array $row)
{
return new HrEmployee([
'employee_code' => $row['employee_code'],
'email' => $row['email'],
'first_name' => $row['first_name'],
'last_name' => $row['last_name'],
'line_manager_id' => $row['line_manager_id'],
'employee_designation_id' => $row['employee_designation_id'],
'employee_job_title_id' => $row['employee_job_title_id'],
]);
}
}
Controller
class HrEmployeesController extends Controller
{
public function importExportView()
{
return view('import');
}
public function import()
{
Excel::import(new EmployeesImport,request()->file('file'));
return back();
}
}
How do I re-write my code to accommodate the foreign keys (line_manager_id,employee_designation_id,employee_job_title_id), so that it will map the keys to the name.
For example, if designation_name is entered to the excel sheet it should map it to employee_designation_id.
Thank you
Just find the foreign key ID in the EmployeesImport
$row['employee_designation_id'] = HrDesignation::where("name", "like", "%".$row['designation']."%");
$row['line_manager_id'] = HrEmployee::where("first_name", "like", "%".$row['line_manager']."%");
$row['employee_job_title_id'] = HrJobTitle::where("name", "like", "%".$row['job_title']."%");
or the full code
namespace App\Imports;
use App\User;
use App\HrEmployee;
use App\Hr\HrDesignation;
use App\Hr\HrJobTitle;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
class EmployeesImport implements ToModel, WithHeadingRow
{
public function model(array $row)
{
$row['employee_designation_id'] = HrDesignation::where("name", "like", "%".$row['designation']."%");
$row['line_manager_id'] = HrEmployee::where("first_name", "like", "%".$row['line_manager']."%");
$row['employee_job_title_id'] = HrJobTitle::where("name", "like", "%".$row['job_title']."%");
return new HrEmployee([
'employee_code' => $row['employee_code'],
'email' => $row['email'],
'first_name' => $row['first_name'],
'last_name' => $row['last_name'],
'line_manager_id' => $row['line_manager_id'],
'employee_designation_id' => $row['employee_designation_id'],
'employee_job_title_id' => $row['employee_job_title_id'],
]);
}
}
namespace App\Imports;
use App\User;
use App\HrEmployee;
use App\Hr\HrDesignation;
use App\Hr\HrJobTitle;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
class EmployeesImport implements ToModel, WithHeadingRow
{
public function model(array $row)
{
$employee_designation = HrDesignation::where("name", "like", "%".$row['designation']."%")->first();
$line_manager = HrEmployee::where("first_name", "like", "%".$row['line_manager']."%")->first();
$employee_job_title = HrJobTitle::where("name", "like", "%".$row['job_title']."%")->first();
$row['employee_designation_id'] = $employee_designation->id;
$row['line_manager_id'] = $line_manager->id;
$row['employee_job_title_id'] = $employee_job_title->id;
return new HrEmployee([
'employee_code' => $row['employee_code'],
'email' => $row['email'],
'first_name' => $row['first_name'],
'last_name' => $row['last_name'],
'line_manager_id' => $row['line_manager_id'],
'employee_designation_id' => $row['employee_designation_id'],
'employee_job_title_id' => $row['employee_job_title_id'],
]);
}
}
i am trying to return back to departments after add a new department but this what happens :
Route [admin.departments.index] not defined
this is my store function in the DepartmentController
class DepartmentController extends BaseController
{
public function store(Request $request)
{
$this->validate($request, [
'department_name' => 'required|max:191',
]);
$params = $request->except('_token');
$department = $this->departmentRepository->createDepartment($params);
if (!$department) {
return $this->responseRedirectBack('Error occurred while creating department.', 'error', true, true);
}
return $this->responseRedirect('admin.deparments.index', 'Department added successfully' ,'success',false, false);
}
}
this is the responseRedirect function in the base controller
class BaseController extends Controller
{
protected function responseRedirect($route, $message, $type = 'info',
$error = false, $withOldInputWhenError = false)
{
$this->setFlashMessage($message, $type);
$this->showFlashMessages();
if ($error && $withOldInputWhenError) {
return redirect()->back()->withInput();
}
return redirect()->route($route);
}
}
these are the routes
Route::group(['prefix' => 'departments'], function() {
Route::get('/', 'Admin\DepartmentController#index')->name('admin.departments.index');
Route::get('/create', 'Admin\DepartmentController#create')->name('admin.departments.create');
Route::post('/store', 'Admin\DepartmentController#store')->name('admin.departments.store');
Route::get('/{id}/edit', 'Admin\DepartmentController#edit')->name('admin.departments.edit');
Route::post('/update', 'Admin\DepartmentController#update')->name('admin.departments.update');
Route::get('/{id}/delete', 'Admin\DepartmentController#delete')->name('admin.departments.delete');
});
InvalidArgumentException
Route [admin.deparments.index] not defined.
The store function in your DepartmentController returns a typo: admin.deparments.index should be admin.departments.index.
Error Message: http://puu.sh/d4l0F/5b0ac07e68.png
I've even saved the $transportation object before trying to create associations. I've verified that both $transporation, $from and $to are all their respective objects and they are.
I'm sure I'm missing something stupid here but I'm out of ideas.
My code:
class RideBuilder implements RideBuilderInterface
{
public function create(Advance $advance)
{
$ride = new Ride;
if($ride->validate(Input::all())) {
$ride->save();
$to = Location::find(Input::get('dropoffLocation'));
$from = Location::find(Input::get('pickupLocation'));
$transportation = new Transportation;
$transportation->save();
$transportation->transportable()->associate($ride);
$transportation->to()->associate($to);
$transportation->from()->associate($from);
$event = new Event;
$event->start = Input::get('ridePickUpTime');
$event->save();
$event->eventable->save($transportation);
$event->subjectable->save($advance);
}
return $ride;
}
}
Location Model:
class Location extends Elegant
{
protected $table = 'locations';
public $rules = array(
'label' => 'required|min:2',
'street' => 'required',
'city' => 'required',
'state' => 'required',
'type' => 'required',
);
public function advance()
{
return $this->belongsTo('Booksmart\Booking\Advance\Model\Advance');
}
public function locationable()
{
return $this->morphTo();
}
}
Transportation Model:
class Transportation extends Elegant
{
protected $table = 'transportations';
public function event()
{
$this->morphOne('Booksmart\Component\Event\Model\Event');
}
public function start_location()
{
$this->belongsTo('Booksmart\Component\Location\Model\Location', 'start_location');
}
public function end_location()
{
$this->belongsTo('Booksmart\Component\Location\Model\Location', 'end_location');
}
}
I had a similar issue. I made the stupid mistake of not adding the "return" in the relationship method!
Make sure you return the relationship... Obviously this will not work:
public function medicineType()
{
$this->belongsTo('MedicineType', 'id');
}
This is the correct way:
public function medicineType()
{
return $this->belongsTo('MedicineType', 'id');
}
Easy to miss, hard to debug...
Here is my model class
class Sessions_model extends CI_Model
{
private $permission = array()
public function __construct()
{
parent::__construct();
}
public function is_login()
{
if($this->session->userdata('logged_in')) return TRUE;
else return false;
}
public function login($username,$password)
{
$this->db->where('username',$username);
$this->db->where('password',$password);
$query = $this->db->get('users');
if($query->num_rows()==1){
$user = $query->row();
$this->set_authnication($user->id);
return TRUE;
}
}
public function logout()
{
$this->session->sess_destroy();
}
public function set_authnication($user_id)
{
$this->load->helper('date');
$query = $this->db->where('id',$user_id)->get('users');
$user = $query->row();
$auth_data = array(
'user_id' => $user_id,
'logged_in' => 1,
'name' => $user->name,
'username'=> $user->username,
'email' => $user->email,
'role' => $this->initRole($user_id),
'lastVisitDate'=> now()
);
$this->session->set_userdata($auth_data);
}
public function initRole($id)
{
$role_perm = array();
$role = $this->db->where('id',$id)->get('roles')->row();
return $role_perm= array(
$role->description => $this->getPerm($role->id)
);
}
public function getPerm($id)
{
$perms = $this->db->where('role_id',$id)->get('permissions')->result();
foreach ($perms as $perm) {
$this->permissions[$perm->permission] = true;
}
return $this->permissions;
}
public function hasPermTo()
{
// $this->getPerm('1');
// return (isset($permissions[$perm]))? 'true' : 'false';
// print_r($this->session->userdata('role'));
print_r($this->permissions);
}
}
when i loggin username and password is set and call set_authnication($user_id).When this login method completed i've got Role with permissions.i set my private attribute with associate permission ..all things seem ok so far
My prob when user who is authnicated come i try to validate that this user has permission to the that class ,so i call function
$this->sessions_model->hasPermTo();
but this time my private attribute is empty array() .. it have nth ...
i dont' what the problem is ?
Your private variable is permission but you're settings permissions (note the S at the end).