I am looking forward to learn Livewire and its test as well. Now I have created component for registering users and it is working fine, but when I try to do a test I get this error:
Failed asserting that an array has the key 'redirect'.
Here are the parts of the code:
RegisterTest
class RegisterTest extends TestCase
{
use RefreshDatabase;
/** #test */
public function can_register()
{
Livewire::test('auth.register')
->set('name', 'user')
->set('email', 'user#outlook.com')
->set('password', 'secret')
->set('password_confirmation', 'secret')
->call('register')
->assertRedirect('/');
}
}
Component
public $name = '';
public $email = '';
public $password = '';
public $password_confirmation = '';
public function register()
{
$data = $this->validate([
'name' => 'required|string',
'email' => 'required|email',
'password' => 'required|confirmed|min:8|string'
]);
User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
return redirect('/');
}
This is pretty easy.
Add the following file:
->assertHasNoErrors(['name', 'email', 'password']);
before
->assertRedirect('/');
line and you will see it will fail. This is because your validation tells password should be minimum 8 characters and in your test it is 6 (you used secret as password)
Related
I was recently updating from laravel's sanctum to passport; and there is this one test that bothers me a lot.
In sanctum there is this method under the PersonalAccessToken model that finds the token and returns the token if it exists.
I don't seem to find anything like that in the docs or online.
I'm validating the test by asserting that $user->tokens is not empty... yet I wish to validate that the token I'm returning from my login controller is indeed a token; not just the creation;
Thnx in advance...
Login Test
public function user_can_login()
{
//$this->withoutExceptionHandling();
$user = User::factory()->create();
$url = route('api.v1.auth.login', [
'email' => $user->email,
'password' => 'password'
]);
$res = $this->jsonApi()
->post($url)
->assertStatus(200);
$token = $res->json(['access_token']);
$this->assertNotEmpty($user->tokens);
}
Login method in authcontroller
public function login(Request $request)
{
$request->validate([
'email' => 'required|email',
'password' => 'required',
]);
$credentials = $request->only(['email', 'password']);
if (Auth::attempt($credentials)) {
$user = Auth::user();
$access_token = $user->createToken('laravel-api.local')->accessToken;
return response()->json(['access_token' => $access_token], 200);
} else {
return response()->json(['error' => 'Unauthorized'], 401);
}
}
pues:dont know why im writing the code, but just for ref of what i'm doing
https://laracasts.com/discuss/channels/testing/how-do-i-create-a-route-while-testing
solution is quite simple... you'll find it here... I had an issue when I tried that before hand and it seems to be with the use of the Route::name('name') method and the route('name') function threw a server error. but if you call the path directly it should work...
any who... authController and login method stay the same but the test changes to...
public function setUp(): void
{
parent::setUp();
Route::middleware('auth:api')
->get('/test-route', function (Request $request) {
return $request->user();
});
$clientRepository = new ClientRepository();
$client = $clientRepository->createPersonalAccessClient(
null,
'Personal Access Client Test',
'/'
);
DB::table('oauth_personal_access_clients')->insert([
'client_id' => $client->id,
'created_at' => date('Y-m-d'),
'updated_at' => date('Y-m-d'),
]);
}
/** #test */
public function user_can_login_with_correct_credentials()
{
//$this->withoutExceptionHandling();
$user = User::factory()->create();
$url = route('api.v1.auth.login', [
'email' => $user->email,
'password' => 'password',
'device_name' => $user->name . ' test Device'
]);
$res = $this->jsonApi()
->post($url)
->assertStatus(200);
$token = $res->json(['access_token']);
$this->jsonApi()
->withHeader('Authorization', 'Bearer ' . $token)
->get('/test-route')
->assertStatus(200);
}
I'm trying to test if the current password is same as in DB.
my simplified controller:
class ChangePasswordController extends Controller
{
public function update(Request $request, User $user)
{
$this->validate($request, [
'current_password' => ['required', new CurrentPassword()],
'password' => 'required|string|min:6|confirmed'
]);
$user->update([
'password' => bcrypt($request->password)
]);
}
}
in my custom CurrentPassword rule i'm checking the hash like this:
class CurrentPassword implements Rule
{
public function passes($attribute, $value)
{
$check = Hash::check($value, auth()->user()->password);
dump($check);
return $check;
}
public function message()
{
return 'Current password is incorrect.';
}
}
and my test for the custom rule is:
/** #test */
public function an_authenticated_user_may_change_own_password()
{
$this->withoutExceptionHandling();
$user = factory(User::class)->create([
'password' => '1234'
]);
$this->actingAs($user)->patch("/profile/{$user->id}/password", [
'current_password' => '1234',
'password' => 'mynewpassword',
'password_confirmation' => 'mynewpassword'
]);
$this->assertTrue(Hash::check('mynewpassword', $user->fresh()->password));
}
unfortunately i'm getting an error:
1)
Tests\Feature\UpdatePasswordTest::an_authenticated_user_may_change_own_password
Illuminate\Validation\ValidationException: The given data was invalid.
i don't understand why this is happining. My dump($check); returns false when i run this test. My $value is '1234' and the auth()->user()->password returns also '1234'. Maybe somebody have an idee what I'm doing wrong.
this test is getting green:
/** #test */
public function current_password_must_be_valid()
{
$user = factory(User::class)->create([
'password' => '1234'
]);
$this->actingAs($user)->patch("/profile/{$user->id}/password", [
'current_password' => '12345',
'password' => 'mynewpassword',
'password_confirmation' => 'mynewpassword'
])->assertSessionHasErrors('current_password');
}
You should hash your password in your factory as well, otherwise Eloquent will store it in cleartext (that's why auth()->user()->password returns '1234')
public function current_password_must_be_valid()
{
$user = factory(User::class)->create([
'password' => Hash::make('1234'); // remember to import the Hash facade
]);
...
}
i have my default registration for auth controller. i want to register also the emp_id created from users table to employee table. once registered.
my RegisterController
use App\User;
use App\Employee
public function count_users(){
$count = User::count();
return date('y').'-'.sprintf('%04d',$count);
}
protected function create(array $data)
{
return User::create([
'emp_id' => $this->count_users(),
'username' => $data['username'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
return Employee::create([
'emp_id' => $this->count_users()
]);
}
Please check following line in your code:
return User::create([ .....
Above line creates the user and returns the created user. Any code below "return" is not being called.
Please try following code:
use App\User;
use App\Employee
public function count_users(){
$count = User::count();
return date('y').'-'.sprintf('%04d',$count);
}
protected function create(array $data)
{
$emp_id = $this->count_users();
$user = User::create([
'emp_id' => $emp_id,
'username' => $data['username'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
Employee::create([
'emp_id' => $emp_id
]);
return $user;
}
i want to change the default password field name of Laravel Auth, this because im using ORACLE, How can i change ? i tried this but i cant login
User.php
protected $table = 'SEG_USUARIOS1';
public function getAuthPassword()
{
return $this->contrasenha;
}
RegisterController.php
protected function validator(array $data)
{
return Validator::make($data, [
'email' => 'required|string|email|max:255|unique:SEG_USUARIOS1',
'contrasenha' => 'required|string|min:6|confirmed',
]);
}
protected function create(array $data)
{
$user = User::create([
'nombre' => $data['name'],
'email' => $data['email'],
'contrasenha' => bcrypt($data['password']),
'verifytoken' => Str::random(40),
]);
$thisUser = User::findOrFail($user->usuario_id);
$this->sendEmail($thisUser);
return $user;
}
Im Using laravel 5.4
My code was ok, the only problem was that I'am using another primary key,
so you have to use it in User.php
protected $primaryKey = 'your_id';
I try to create custom login page but I got an error
Undefined index: password
my controller code
$this->validate($Request, [
'Email' => 'required',
'password' => 'required',
]);
$email = $Request['Email'];
$password = md5($Request['password']);
$login = new login();
$login = login::where('Email', $email);
if(empty($password))
{
return('404');
}
if(Auth::attempt(['Email' => $Request->input('Email'), 'Password' =>$password]))
{
return ('ok');
}
return ('no');
any one help my to create custom login
this is my new code
but again i gor undefined::passsword
public function logincheck(Request $request)
{
$this->validate($request, [
'Email' => 'required',
'password' => 'required',
]);
$email = $request->Email;
$password = md5($request->get('password'));
if(Auth::attempt(['Email' => $request->get('Email'), 'Password' =>md5($request->get('password'))]))
{
return ('ok');
}
return ('no');
}
Your error comes from
$Request['password']
You are treating Request as an array. It's an object. You do
public funciton login(Request $request)
{
$password = $request->password;
//or use the global helper
$password = request('password');
//Attempt login
if(Auth::attempt(['Email' => $request->get('Email'), 'Password' =>$password]))
{
return ('ok');
}
}
Also if you follow Laravel tutorial properly, you don't need md5 to hash password. Auth::attemp() will hash it for you