Laravel Testing User::store() with phpunit - laravel-4

I'm learning both Laravel and UnitTesting at the moment, so this may be a stupid question.
I'm getting stuck on how to best test the controller function below:
UserController:
public function store()
{
$input = Input::all();
$user = new User($input);
if( ! $user->save()){
return Redirect::back()->withInput()->withErrors($user->getErrors());
}
return Redirect::to('/user');
}
here's the test as I have it so far:
/**
* #dataProvider providerTestUserStoreAddsUsersCorrectly
*/
public function testUserStoreAddsUsersCorrectly($first_name, $last_name, $email, $password)
{
$response = $this->call('POST', 'user', array('first_name'=>$first_name, 'last_name'=>$last_name, 'email'=>$email, 'password'=>$password));
}
public function providerTestUserStoreAddsUsersCorrectly(){
return array(
array("FirstName", "LastName", "Email#add.com", "pass1234")
);
}
This is actually working and adding the user to the db correctly, but I'm not sure how to test the output / what assertions to use as the response should be to add the user to the db and to redirect to the /user page.
How do I finish this test?

If you need to check success status then you can simply send status code from your controller
and check status in test
public function store()
{
$input = Input::all();
$user = new User($input);
if( !$user->save() ){
return array("status"=>'failed');
}
return array("status"=>'success');
}
public function testUserStoreAddsUsersCorrectly($first_name, $last_name, $email, $password)
{
$requested_arr = [
'first_name' => $first_name,
'last_name' => $last_name,
'email' => $email,
'password' => $password
];
$response = $this->call('POST', 'user', $requested_arr);
$data = json_decode($response ->getContent(), true);
if ($data['status']) {
$this->assertTrue(true);
} else {
$this->assertTrue(false);
}
}

Related

FatalThrowableError in Call to a member function get_one() on null

i have some laravel code like this
public function update_password(Request $request)
{
$data = array(
'password_current' => $request->input('password_current'),
'password_new' => $request->input('password_new'),
'password_new_confirmation' => $request->input('password_new_confirmation'),
);
$rules = [
'password_current' => 'required',
'password_new' => 'required|confirmed',
'password_new_confirmation' => 'required',
];
$validator = Validator::make($data, $rules);
if ($validator->fails()) {
return redirect()->action('Editor\ProfileController#edit_password')->withInput()->withErrors(['New password confirmation failed!']);
} else {
$user = $this->UserRepository->get_one(Auth::user()->id);
if(Hash::check($request->input('password_current'), $user->password))
{
$this->UserRepository->change_password(Auth::user()->id, $request->input('password_new'));
return redirect()->action('Editor\ProfileController#show');
} else {
return redirect()->action('Editor\ProfileController#edit_password')->withInput()->withErrors(['Current password mismatch!']);
}
}
}
but when i run the program, the program notification is FatalThrowableError, Call to a member function get_one() on null. i change with other script in google but no one is work.
$user = $this->UserRepository->get_one(Auth::user()->id);
anyone ever had this problem?
I try to change script like
use Auth;
$user_id = Auth::user()->id;
and still not work.

delete_cookie('name') not working codeigniter 4

I am trying to delete the cookie i create when user logs in but somehow delete_cookie() function is not deleting the cookie i made. I checked the documentation and everything but i cannot get it to work
Here is my code
public function __construct()
{
helper('cookie');
}
public function login() {
$data = [];
$session = session();
$model = new AdminModel();
$username = $this->request->getPost('username');
$password = $this->request->getPost('password');
$remember = $this->request->getPost('agree');
$rules = [
'username' => 'required',
'password' => 'required',
];
if(!$this->validate($rules)) {
$data['validation'] = $this->validator;
} else {
$admin = $model->where('username', $username)->where('password', $password)->first();
if($admin) {
$session->set('uid', $admin['id']);
if($remember) {
set_cookie([
'name' => 'id',
'value' => $admin['id'],
'expire' => '3600',
'httponly' => false
]);
}
} else {
$session->setFlashdata('msg', 'Incorrect Username or Password');
return redirect()->to('admin/login');
}
}
return view('admin/login', $data);
}
public function logout() {
$session = session();
$session->destroy();
delete_cookie('id');
return redirect()->to('admin/login')->withCookies();
}
Edit:
I fixed it. I had to redirect with withCookies();
use this Library
use Config\Services;
Services::response()->deleteCookie('id');
refer this link
https://codeigniter.com/user_guide/libraries/cookies.html

Laravel : Reset password get 6 digits without validation

I have simple function to reset my password. In my function there is minimum requirement for password value is 1 digit but when i try to update the password it is not updated, when i put 6 digits in password it is working fine.
I found that in vendor\laravel\framework\src\Illuminate\Auth\Passwords a passwordBroker.phpfile has one function
protected function validatePasswordWithDefaults(array $credentials)
{
list($password, $confirm) = [
$credentials['password'],
$credentials['password_confirmation'],
];
return $password === $confirm && mb_strlen($password) >= 6; // here it is
}
and it contains validation that ($password) >= 6 how can i remove it, when i changes in this file it is working. on my .gitignore vendor folder not updated in live. what is the solution ? how can override this validation ?
for reference here is my resetpassword function
public function resetPassword(ResetPasswordRequest $request, JWTAuth $JWTAuth)
{
$validator = Validator::make($request->all(), User::resetPasswordRules());
if ($validator->fails()) {
return response()->json([
'message' => "422 Unprocessable Entity",
'errors' => $validator->messages(),
'status_code' => 422,
]);
}
$response = $this->broker()->reset(
$this->credentials($request), function ($user, $password) {
$this->reset($user, $password);
}
);
if($response !== Password::PASSWORD_RESET) {
return response()->json([
'message' => "Internal Server Error",
'status_code' => 500,
]);
}
$user = User::where('email', '=', $request->get('email'))->first();
$user->UserDeviceData()->firstOrCreate([
'device_id' => $request->device_id
]);
return (new UserTransformer)->transform($user,[
'request_type' => 'reset_password',
'token' => $JWTAuth->fromUser($user)
]);
}
This is how you can fix this:
public function resetPassword(ResetPasswordRequest $request, JWTAuth $JWTAuth)
{
... // Validator check and json response
$broker = $this->broker();
// Replace default validation of the PasswordBroker
$broker->validator(function (array $credentials) {
return true; // Password match is already validated in PasswordBroker so just return true here
});
$response = $broker->reset(
$this->credentials($request), function ($user, $password) {
$this->reset($user, $password);
});
...
}
First you gen an instance of the broker and then you add a callable function which it will use for the validation instead of validatePasswordWithDefaults. In there you just need to return true because the PasswordBroker already has a check $password === $confirm.

Problems creating users in laravel

I am creating the traditional register of users with Laravel and I have a problem to send specific value.
public function postUserRegister(){
$input = Input::all();
$rules = array(
'name' => 'required',
);
$v = Validator::make($input, $rules);
if($v->passes() ) {
$user = User::create(Input::all());
} else {
Session::flash('msg', 'The information is wrong');
return Redirect::back();
}
}
This code works correctly , but I need to send always the same value into table users and this column doesn't appear in the form. How can I send the value of the table if the value doesn't appear?
You can just supply the value manually. There are several ways to do this, here is one:
$user = new User(Input::all());
$user->yourcolumn = $yourdata;
$user->save();
You can use input merge to add extra fields.
Input::merge(array('val_key' => $val_name));
$input = Input::all();
Firstly, I think it would be ideal to clean a bit the method, something like that:
public function postUserRegister(Request $request)
{
$validator = Validator::make($request->all(), [
'name' => 'required'
]);
if ($v->fails()) {
Session::flash('msg', 'The information is wrong');
}
User::create($request->all());
return Redirect::back();
}
And now you can simply assign a data to a specific column by using:
$request->merge(['column_name' => 'data']);
The data can be null, or variable etc. And now the whole code would look something like:
public function postUserRegister(Request $request)
{
$request->merge(['column_name' => 'data']);
$validator = Validator::make($request->all(), [
'name' => 'required'
]);
if ($validator->fails()) {
Session::flash('msg', 'The information is wrong');
}
User::create($request->all());
return Redirect::back();
}
You can add whatever data you want directly into the create method:
public function postUserRegister()
{
$input = request()->all();
if (validator($input, ['name' => 'required'])->fails()) {
return back()->with('msg', 'The information is wrong');
}
$user = User::create($input + ['custom' => 'data']);
//
}
P.S. Merging that data into the request itself is a bad idea.
You can do this in the User model by adding the boot() method.
class User extends Model
{
public static function boot()
{
parent::boot();
static::creating(function ($user) {
$user->newColumn = 'some-value';
});
}
...
}
Reference: https://laravel.com/docs/5.2/eloquent#events

Laravel 4 Authentication does not work and gives NO ERROR

I have been searching for solutions and changing my code back and forth but nothing worked for me and I honestly have given up hope to fix it by myself.
It stays on the same page and does not Redirect::to('test2'), but stays in the same page and when I remove the else { return Redirect::to('login'), it gives me a blank page.
Any help would be extremely appreciated.
This is my user model file:
protected $fillable=['email', 'password'];
protected $table = 'users';
protected $hidden = array('password', 'remember_token');
protected $primaryKey = 'id';
public static $rules = array(
'email' => 'required|email',
'password' => 'required',
);
public function getAuthIdentifier()
{
return $this->getKey();
}
public function getAuthPassword()
{
return $this->password;
}
public function getReminderEmail()
{
return $this->email;
}
This is my routing functions:
Route::get('/login', function(){
return View::make('login');
});
Route::post('/login', function(){
$validator = Validator::make(Input::all(), User::$rules);
if ($validator->fails()) {
return Redirect::to('login')
->withErrors($validator)
->withInput(Input::except('password'));
} else {
$userData = array(
'email' => Input::get('email'),
'password' => Input::get('password')
);
if (Auth::attempt($userData)) {
return Redirect::to('test2');
echo 'SUCCESS!';
} else {
return Redirect::to('login');
}
}
I have been struggling around with the hash at beginning.
1. If the length of your password column isn't 60 then it wouldn't allow you to login.
2. Before logging via Auth::attempt() instead try to fetch the data of the user using his username
and then compare the password using Hash::check()
try something this
Route::post('/login', function(){
$validator = Validator::make(Input::all(), User::$rules);
if ($validator->fails()) {
return Redirect::to('login')
->withErrors($validator)
->withInput(Input::except('password'));
} else {
$email=Input::get('email');
$user=User::where('email','=',$email)->first();
$bool=Hash::check('your password for the email',$user->password);
if(bool)
{
if (Auth::attempt(Input::only('email','password')))
{
return Redirect::to('test2');
echo 'SUCCESS!';
}else{
return Redirect::to('login');
}
}else{
return echo 'password didn't matche';
}
}

Resources