TRF Certest first commit

This commit is contained in:
2025-02-26 08:57:46 +01:00
commit 3ce064a108
2524 changed files with 475404 additions and 0 deletions
@@ -0,0 +1,91 @@
<?php
namespace Tests\Feature\Web;
use Facades\Tests\Setup\UserFactory;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
use Vanguard\User;
class ImpersonateUsersTest extends TestCase
{
use RefreshDatabase;
protected function setUp(): void
{
parent::setUp();
$this->artisan('db:seed --class=RolesSeeder');
$this->artisan('db:seed --class=PermissionsSeeder');
}
/** @test */
public function unverified_users_cannot_impersonate_other_users()
{
$user = UserFactory::withPermissions('users.manage')->unverified()->create();
User::factory()->create();
$this->actingAs($user)->get('/users')->assertRedirect('/email/verify');
}
/** @test */
public function a_user_with_appropriate_permission_can_impersonate_other_users_from_a_user_list_page()
{
$user = UserFactory::withPermissions('users.manage')->create();
User::factory()->create();
$this->actingAs($user)->get('/users')->assertSee('Impersonate');
}
/** @test */
public function a_user_dont_see_impersonate_button_next_to_his_name_in_the_user_list()
{
$user = UserFactory::withPermissions('users.manage')->create();
$this->actingAs($user)->get('/user')->assertDontSee('Impersonate');
}
/** @test */
public function clicking_on_impersonate_button_will_impersonate_the_user()
{
$userA = UserFactory::withPermissions('users.manage')->create();
$userB = UserFactory::user()->create();
$this->actingAs($userA)
->get(route('impersonate', $userB))
->assertRedirect('/');
$this->assertTrue(auth()->user()->is($userB));
}
/** @test */
public function while_impersonating_user_can_stop_impersonating_by_clicking_on_the_header_button()
{
$userA = UserFactory::withPermissions('users.manage')->create();
$userB = UserFactory::user()->create();
$this->actingAs($userA)->get(route('impersonate', $userB));
$this->assertTrue(auth()->user()->is($userB));
$this->get('/')->assertSee('Stop Impersonating');
$this->get(route('impersonate.leave'));
$this->assertTrue(auth()->user()->is($userA));
}
/** @test */
public function while_impersonating_user_cannot_impersonate_other_user_even_if_he_has_a_permission()
{
$userA = UserFactory::withPermissions('users.manage')->create();
$userB = UserFactory::withPermissions('users.manage')->create();
$this->actingAs($userA)->get(route('impersonate', $userB));
$this->get('/user')
->assertDontSee('Impersonate');
}
}
+270
View File
@@ -0,0 +1,270 @@
<?php
namespace Tests\Feature\Web;
use Carbon\Carbon;
use Event;
use Facades\Tests\Setup\UserFactory;
use Illuminate\Cache\RateLimiter;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Testing\TestResponse;
use PragmaRX\Google2FA\Google2FA;
use Setting;
use Tests\TestCase;
use Tests\UpdatesSettings;
use Vanguard\Events\User\LoggedIn;
use Vanguard\User;
class LoginTest extends TestCase
{
use RefreshDatabase, UpdatesSettings;
/** @test */
public function successful_login()
{
$user = UserFactory::withCredentials('foo', 'bar')->create();
$this->loginUser('foo', 'bar')
->assertRedirect('/');
$this->assertTrue(auth()->check());
$this->assertTrue($user->is(auth()->user()));
}
/** @test */
public function last_login_timestamp_is_updated_after_successful_login()
{
$testDate = Carbon::now();
Carbon::setTestNow($testDate);
$user = UserFactory::withCredentials('foo', 'bar')->create();
$this->assertNull($user->last_login);
$this->loginUser('foo', 'bar');
$this->assertEquals($testDate->timestamp, $user->fresh()->last_login->timestamp);
}
/** @test */
public function login_with_wrong_credentials_will_fail()
{
$this->loginUser('foo', 'bar')
->assertRedirect('/login');
$this->assertFalse(auth()->check());
}
/** @test */
public function country_id_remains_the_same_after_login()
{
$user = User::factory()->create([
'username' => 'foo',
'password' => 'bar',
'country_id' => 688,
]);
$this->loginUser('foo', 'bar')
->assertRedirect('/');
$this->assertEquals(688, $user->fresh()->country_id);
}
/** @test */
public function throttling()
{
$this->setSettings([
'throttle_enabled' => true,
'throttle_attempts' => 3,
'throttle_lockout_time' => 2, // 2 minutes
]);
for ($i = 0; $i < 3; $i++) {
$this->loginUser('foo', 'bar');
}
$this->loginUser('foo', 'bar')
->assertRedirect('login')
->assertSessionHasErrors('username');
$this->assertTrue(app(RateLimiter::class)->tooManyAttempts('foo|127.0.0.1', 3));
}
/** @test */
public function login_with_remember()
{
$user = UserFactory::withCredentials('foo', 'bar')->create();
Setting::set('remember_me', false);
$this->get('login')
->assertDontSeeText('name="remember"', false);
Setting::set('remember_me', true);
$this->get('login')
->assertSee('name="remember"', false);
$this->loginUser('foo', 'bar', true)
->assertRedirect('/');
$this->assertNotNull($user->fresh()->remember_token);
$this->assertNotNull($user->fresh()->last_login);
}
/** @test */
public function login_max_number_of_sessions_reached()
{
$user = UserFactory::withCredentials('foo', 'bar')->create();
Setting::set('max_active_sessions', 1);
\DB::table('sessions')->insert([
'id' => \Str::random(),
'user_id' => $user->id,
'ip_address' => fake()->ipv4,
'user_agent' => fake()->userAgent,
'payload' => 'test',
'last_activity' => Carbon::now()->timestamp,
]);
$this->loginUser('foo', 'bar')
->assertRedirect('/login');
$this->assertSessionHasError(trans('auth.max_sessions_reached'));
$this->assertFalse(\Auth::check());
}
/** @test */
public function banned_user_cannot_log_in()
{
UserFactory::withCredentials('foo', 'bar')->banned()->create();
$this->loginUser('foo', 'bar')
->assertRedirect('/login');
$this->assertSessionHasError('Your account is banned by administrator.');
}
/** @test */
public function login_with_2fa_enabled()
{
$google2fa = new Google2FA();
$secret = encrypt($google2fa->generateSecretKey());
$this->withoutExceptionHandling();
$this->setSettings(['2fa.enabled' => true]);
Event::fake([LoggedIn::class]);
$user = UserFactory::withCredentials('foo', 'bar')->create();
$user->two_factor_secret = $secret;
$user->two_factor_confirmed_at = Carbon::now();
$user->save();
$validCode = $google2fa->getCurrentOtp(decrypt($user->two_factor_secret));
$this->loginUser('foo', 'bar')
->assertRedirect('auth/two-factor-authentication')
->assertSessionHas('auth.2fa.id', $user->id);
$this->post('auth/two-factor-authentication', ['code' => $validCode])
->assertRedirect('/');
$this->assertTrue(auth()->check());
Event::assertDispatched(LoggedIn::class);
}
/** @test */
public function login_with_2fa_enabled_redirect_to_custom_page()
{
$google2fa = new Google2FA();
$secret = encrypt($google2fa->generateSecretKey());
$this->withoutExceptionHandling();
$this->setSettings(['2fa.enabled' => true]);
Event::fake([LoggedIn::class]);
$user = UserFactory::withCredentials('foo', 'bar')->create();
$user->two_factor_secret = $secret;
$user->two_factor_confirmed_at = Carbon::now();
$user->save();
$validCode = $google2fa->getCurrentOtp(decrypt($user->two_factor_secret));
$this->loginUser('foo', 'bar', redirectTo: 'https://google.com')
->assertRedirect('auth/two-factor-authentication')
->assertSessionHas('auth.2fa.id', $user->id);
$this->post('auth/two-factor-authentication', ['code' => $validCode])
->assertRedirect('https://google.com');
$this->assertTrue(auth()->check());
Event::assertDispatched(LoggedIn::class);
}
/** @test */
public function login_with_wrong_2fa_token()
{
$google2fa = new Google2FA();
$secret = encrypt($google2fa->generateSecretKey());
$this->setSettings(['2fa.enabled' => true]);
$user = UserFactory::withCredentials('foo', 'bar')->create();
$user->two_factor_secret = $secret;
$user->two_factor_confirmed_at = Carbon::now();
$user->save();
$this->loginUser('foo', 'bar')
->assertRedirect('auth/two-factor-authentication')
->assertSessionHas('auth.2fa.id', $user->id);
$this->post('auth/two-factor-authentication', ['code' => '123123'])->assertRedirect('login');
$this->assertSessionHasError('Invalid 2FA token.');
}
/** @test */
public function login_with_wrong_2fa_token_when_custom_redirect_page_is_provided()
{
$google2fa = new Google2FA();
$secret = encrypt($google2fa->generateSecretKey());
$this->setSettings(['2fa.enabled' => true]);
$user = UserFactory::withCredentials('foo', 'bar')->create();
$user->two_factor_secret = $secret;
$user->two_factor_confirmed_at = Carbon::now();
$user->save();
$this->loginUser('foo', 'bar', redirectTo: 'https://google.com')
->assertRedirect('auth/two-factor-authentication')
->assertSessionHas('auth.2fa.id', $user->id);
$this->post('auth/two-factor-authentication', ['code' => '123'])
->assertRedirect('login?to=https://google.com');
$this->assertSessionHasError('Invalid 2FA token.');
}
private function loginUser($username, $password, $remember = false, $redirectTo = null): TestResponse
{
$url = 'login';
if ($redirectTo) {
$url .= '?to='.urlencode($redirectTo);
}
return $this->post($url, [
'username' => $username,
'password' => $password,
'remember' => $remember,
]);
}
}
+370
View File
@@ -0,0 +1,370 @@
<?php
namespace Tests\Feature\Web;
use Event;
use Facades\Tests\Setup\RoleFactory;
use Facades\Tests\Setup\UserFactory;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
use Vanguard\Events\Permission\Created;
use Vanguard\Events\Permission\Deleted;
use Vanguard\Events\Permission\Updated;
use Vanguard\Events\Role\PermissionsUpdated;
use Vanguard\Permission;
use Vanguard\Role;
class PermissionsTest extends TestCase
{
use RefreshDatabase;
protected function setUp(): void
{
parent::setUp();
$this->artisan('db:seed');
$this->be(UserFactory::admin()->create());
}
/** @test */
public function permissions_list()
{
$permission = Permission::factory()->create();
$this->get('permissions')
->assertSee($permission->display_name);
}
/** @test */
public function only_users_with_appropriate_permissions_can_access_the_permissions_list_page()
{
$roleA = RoleFactory::create();
$roleB = RoleFactory::withPermissions('permissions.manage')->create();
$userA = UserFactory::role($roleA)->create();
$userB = UserFactory::role($roleB)->create();
$this->actingAs($userA)->get('/permissions')->assertStatus(403);
$this->actingAs($userB)->get('/permissions')->assertOk();
}
/** @test */
public function permission_list_with_roles()
{
$permission = Permission::factory()->create();
$role = Role::first();
$role->permissions()->attach($permission->id);
$this->get('permissions')
->assertSee($permission->display_name)
->assertSee("roles[$role->id][]");
}
/** @test */
public function save_role_permissions()
{
$this->withoutExceptionHandling();
Event::fake([
PermissionsUpdated::class,
]);
$permission = Permission::factory()->create();
$role = Role::factory()->create();
$this->post('permissions/save', [
'roles' => [
$role->id => [$permission->id],
],
]);
$this->assertSessionHasSuccess('Permissions saved successfully.');
$this->assertDatabaseHas('permission_role', [
'role_id' => $role->id,
'permission_id' => $permission->id,
]);
Event::assertDispatched(PermissionsUpdated::class);
}
/** @test */
public function only_users_with_appropriate_permissions_can_save_role_permissions()
{
$roleA = RoleFactory::create();
$roleB = RoleFactory::withPermissions('permissions.manage')->create();
$userA = UserFactory::role($roleA)->create();
$userB = UserFactory::role($roleB)->create();
$permission = Permission::factory()->create();
$role = Role::factory()->create();
$data = [$role->id => [$permission->id]];
$this->actingAs($userA)
->post('permissions/save', ['roles' => $data])
->assertStatus(403);
$this->assertDatabaseMissing('permission_role', [
'role_id' => $role->id,
'permission_id' => $permission->id,
]);
$this->actingAs($userB)
->post('permissions/save', ['roles' => $data]);
$this->assertDatabaseHas('permission_role', [
'role_id' => $role->id,
'permission_id' => $permission->id,
]);
}
/** @test */
public function save_role_permissions_if_no_permission_is_selected_for_specific_role()
{
Event::fake([
PermissionsUpdated::class,
]);
$role1 = Role::factory()->create();
$permission1 = Permission::factory()->create();
$role1->permissions()->attach($permission1->id);
$role2 = Role::factory()->create();
$permission2 = Permission::factory()->create();
$role2->permissions()->attach($permission2->id);
$this->post('/permissions/save', [
'roles' => [
$role1->id => [$permission1->id],
],
]);
$this->assertSessionHasSuccess('Permissions saved successfully.');
$this->assertDatabaseHas('permission_role', [
'role_id' => $role1->id,
'permission_id' => $permission1->id,
]);
$this->assertDatabaseMissing('permission_role', [
'role_id' => $role2->id,
'permission_id' => $permission2->id,
]);
Event::assertDispatched(PermissionsUpdated::class);
}
/** @test */
public function create_permission()
{
$this->app->instance('middleware.disable', false);
Event::fake([
Created::class,
]);
$data = $this->validParams();
$this->post('permissions', $data)
->assertRedirect('/permissions');
$this->assertSessionHasSuccess('Permission created successfully.');
$this->assertDatabaseHas('permissions', $data);
Event::assertDispatched(Created::class);
}
/** @test */
public function only_users_with_appropriate_permission_can_create_new_permissions()
{
$roleA = RoleFactory::create();
$roleB = RoleFactory::withPermissions('permissions.manage')->create();
$userA = UserFactory::role($roleA)->create();
$userB = UserFactory::role($roleB)->create();
$data = $this->validParams();
$this->actingAs($userA)
->post('permissions', $data)
->assertStatus(403);
$this->assertDatabaseMissing('permissions', $data);
$this->actingAs($userB)
->post('permissions', $data)
->assertRedirect('/permissions');
$this->assertDatabaseHas('permissions', $data);
}
/** @test */
public function permission_name_must_have_valid_format()
{
$this->app->instance('middleware.disable', false);
$data = $this->validParams();
$response = $this->post('permissions', $this->validParams(['name' => 'invalid name']));
$response->assertSessionHasErrors('name');
$this->assertDatabaseMissing('permissions', $data);
$response = $this->post('permissions', $this->validParams(['name' => 'invalid*name']));
$response->assertSessionHasErrors('name');
$this->assertDatabaseMissing('permissions', $data);
}
/** @test */
public function update_permission()
{
$this->withoutExceptionHandling();
Event::fake([
Updated::class,
]);
$permission = Permission::factory()->create();
$this->get("permissions/{$permission->id}/edit")
->assertOk()
->assertSee($permission->id)
->assertSee($permission->name)
->assertSee($permission->display_name);
$data = $this->validParams();
$this->put("permissions/{$permission->id}", $data);
$this->assertSessionHasSuccess('Permission updated successfully.');
$this->assertDatabaseHas('permissions', $data + ['id' => $permission->id]);
Event::assertDispatched(Updated::class);
}
/** @test */
public function only_users_with_appropriate_permission_can_update_existing_permissions()
{
$roleA = RoleFactory::create();
$roleB = RoleFactory::withPermissions('permissions.manage')->create();
$userA = UserFactory::role($roleA)->create();
$userB = UserFactory::role($roleB)->create();
$permission = Permission::factory()->create();
$data = $this->validParams();
$this->actingAs($userA)
->put("permissions/{$permission->id}", $data)
->assertStatus(403);
$this->assertEquals($permission->toArray(), $permission->fresh()->toArray());
$this->actingAs($userB)
->put("permissions/{$permission->id}", $data)
->assertRedirect('/permissions');
$permission->refresh();
$this->assertEquals($permission->name, $data['name']);
$this->assertEquals($permission->display_name, $data['display_name']);
$this->assertEquals($permission->description, $data['description']);
}
/** @test */
public function removable_attribute_cannot_be_changed_on_update()
{
$permission = Permission::factory()->create(['removable' => false]);
$data = $this->validParams(['removable' => true]);
$this->put("permissions/{$permission->id}", $data);
$permission->refresh();
$this->assertEquals($permission->name, $data['name']);
$this->assertEquals($permission->display_name, $data['display_name']);
$this->assertEquals($permission->description, $data['description']);
$this->assertFalse($permission->removable);
}
/** @test */
public function permission_name_must_have_valid_format_while_updating_the_permission()
{
$permission = Permission::factory()->create(['name' => 'foo']);
$response = $this->put('permissions/'.$permission->id, $this->validParams(['name' => 'invalid name']));
$response->assertSessionHasErrors('name');
$this->assertEquals('foo', $permission->fresh()->name);
$response = $this->put('permissions/'.$permission->id, $this->validParams(['name' => 'invalid*name']));
$response->assertSessionHasErrors('name');
$this->assertEquals('foo', $permission->fresh()->name);
}
/** @test */
public function delete_permission()
{
Event::fake([
Deleted::class,
]);
$permission = Permission::factory()->create();
$this->delete(route('permissions.destroy', $permission->id))
->assertRedirect('/permissions');
$this->assertSessionHasSuccess('Permission deleted successfully.');
$this->assertDatabaseMissing('permissions', ['id' => $permission->id]);
Event::assertDispatched(Deleted::class);
}
/** @test */
public function only_users_with_appropriate_permission_can_delete_permissions()
{
$roleA = RoleFactory::create();
$roleB = RoleFactory::withPermissions('permissions.manage')->create();
$userA = UserFactory::role($roleA)->create();
$userB = UserFactory::role($roleB)->create();
$permission = Permission::factory()->create();
$this->actingAs($userA)
->delete("permissions/{$permission->id}")
->assertStatus(403);
$this->assertNotNull($permission->fresh());
$this->actingAs($userB)
->delete("permissions/{$permission->id}")
->assertRedirect('/permissions');
$this->assertNull($permission->fresh());
}
/** @test */
public function non_removable_permissions_cannot_be_removed()
{
$permission = Permission::factory()->create(['removable' => false]);
$this->delete(route('permissions.destroy', $permission->id))
->assertStatus(404);
$this->assertNotNull($permission->fresh());
}
private function validParams(array $override = []): array
{
return array_merge([
'name' => 'foo_permission',
'display_name' => 'Foo Permission',
'description' => 'the description',
], $override);
}
}
+172
View File
@@ -0,0 +1,172 @@
<?php
namespace Tests\Feature\Web;
use Facades\Tests\Setup\UserFactory;
use Illuminate\Auth\Notifications\VerifyEmail;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Notification;
use Mail;
use Tests\TestCase;
use Tests\UpdatesSettings;
use Vanguard\Support\Enum\UserStatus;
use Vanguard\User;
class RegistrationTest extends TestCase
{
use RefreshDatabase, UpdatesSettings;
protected function setUp(): void
{
parent::setUp();
$this->artisan('db:seed');
}
/** @test */
public function when_registration_is_disabled_a_visitor_cannot_see_the_registration_form()
{
$this->setSettings(['reg_enabled' => false]);
$this->get('register')->assertStatus(404);
$this->get('login')->assertDontSee('You don\'t have an account?');
}
/** @test */
public function registration_with_email_confirmation()
{
$this->setSettings([
'reg_enabled' => true,
'reg_email_confirmation' => true,
'registration.captcha.enabled' => false,
'tos' => true,
]);
Notification::fake();
$data = $this->getRegistrationFormStubData();
$this->post('/register', $data)->assertRedirect('/');
$expected = Arr::except($data, ['password', 'password_confirmation', 'tos']);
$expected += ['status' => UserStatus::UNCONFIRMED];
$this->assertDatabaseHas('users', $expected);
$user = User::where('email', $data['email'])->first();
Notification::assertSentTo($user, VerifyEmail::class);
}
/** @test */
public function registration_without_email_confirmation()
{
$this->setSettings([
'reg_enabled' => true,
'reg_email_confirmation' => false,
'notifications_signup_email' => false,
'registration.captcha.enabled' => false,
'tos' => true,
]);
Notification::fake();
$data = $this->getRegistrationFormStubData();
$this->post('/register', $data)->assertRedirect('/');
$expected = Arr::except($data, ['password', 'password_confirmation', 'tos']);
$expected += ['status' => UserStatus::ACTIVE];
$this->assertDatabaseHas('users', $expected);
Notification::assertNotSentTo(
User::where('email', $data['email'])->first(),
VerifyEmail::class
);
}
/** @test */
public function email_notification_is_being_sent_when_new_user_registers()
{
$this->setSettings([
'app_name' => 'foo',
'reg_enabled' => true,
'reg_email_confirmation' => false,
'notifications_signup_email' => true,
'registration.captcha.enabled' => false,
'tos' => true,
]);
Mail::fake();
$admin = UserFactory::admin()->email('john.doe@test.com')->create();
$user1 = UserFactory::user()->email('jane.doe@test.com')->create();
$user2 = UserFactory::user()->email('josh.doe@test.com')->create();
$this->post('/register', $this->getRegistrationFormStubData());
Mail::assertQueued(\Vanguard\Mail\UserRegistered::class, 2);
}
/** @test */
public function redirect_to_custom_page_after_login()
{
UserFactory::withCredentials('foo', 'bar')->create();
$this->post('/login', [
'username' => 'foo',
'password' => 'bar',
'to' => 'http://www.google.com',
])->assertRedirect('http://www.google.com');
}
/** @test */
public function custom_redirect_page_is_available_after_failed_login_attempt()
{
$to = 'http://www.google.com';
$this->post('/login', [
'username' => 'foo',
'password' => 'bar',
'to' => 'http://www.google.com',
])->assertRedirect('login?to='.$to);
}
/** @test */
public function access_to_auth_pages_is_not_allowed_for_authenticated_users()
{
$this->setSettings([
'reg_enabled' => true,
'2fa.enabled' => true,
'forgot_password' => true,
]);
$user = UserFactory::withCredentials('foo', 'bar')->create();
$this->be($user);
$forbiddenGetRoutes = [
'login', 'register', 'password/reset', 'password/reset/123',
'auth/facebook/login', 'auth/facebook/callback',
];
foreach ($forbiddenGetRoutes as $route) {
$this->get($route)->assertRedirect('/');
}
$this->get('auth/two-factor-authentication')->assertRedirect('/login');
}
private function getRegistrationFormStubData()
{
return [
'email' => 'test@test.com',
'username' => 'johndoe',
'password' => '123123123',
'password_confirmation' => '123123123',
'tos' => 1,
];
}
}
+233
View File
@@ -0,0 +1,233 @@
<?php
namespace Tests\Feature\Web;
use Facades\Tests\Setup\RoleFactory;
use Facades\Tests\Setup\UserFactory;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
use Vanguard\Role;
class RolesTest extends TestCase
{
use RefreshDatabase;
protected function setUp(): void
{
parent::setUp();
$this->artisan('db:seed');
}
/** @test */
public function guests_cannot_view_role_list()
{
$this->get('/roles')->assertRedirect('/login');
}
/** @test */
public function users_without_appropriate_permission_cannot_view_role_list()
{
$roleA = RoleFactory::create();
$roleB = RoleFactory::withPermissions('roles.manage')->create();
$userA = UserFactory::role($roleA)->create();
$userB = UserFactory::role($roleB)->create();
$this->actingAs($userA)->get('/roles')->assertStatus(403);
$this->actingAs($userB)->get('/roles')->assertOk();
}
/** @test */
public function roles_list_is_displayed_properly()
{
$roleA = RoleFactory::create();
$roleB = RoleFactory::create();
$roles = $this->actingAsAdmin()->get('/roles')->viewData('roles');
$this->assertCount(4, $roles); // 2 default roles are created when db is seeded
$this->assertTrue($roles->contains($roleA));
$this->assertTrue($roles->contains($roleB));
}
/** @test */
public function create_role()
{
$data = Role::factory()->raw();
$this->actingAsAdmin()
->post('/roles', $data)
->assertRedirect('/roles');
$this->assertSessionHasSuccess('Role created successfully.');
$this->assertDatabaseHas('roles', $data);
}
/** @test */
public function users_without_appropriate_permission_cannot_create_new_roles()
{
$roleA = RoleFactory::create();
$roleB = RoleFactory::withPermissions('roles.manage')->create();
$userA = UserFactory::role($roleA)->create();
$userB = UserFactory::role($roleB)->create();
$data = Role::factory()->raw();
$this->actingAs($userA)
->post('/roles', $data)
->assertStatus(403);
$this->assertDatabaseMissing('roles', $data);
$this->actingAs($userB)
->post('/roles', $data)
->assertRedirect('roles');
$this->assertDatabaseHas('roles', $data);
}
/** @test */
public function update_role()
{
$role = Role::factory()->create(['name' => 'foo']);
$this->actingAsAdmin()
->get("roles/{$role->id}/edit")
->assertOk()
->assertSee($role->name)
->assertSee($role->display_name)
->assertSee($role->description);
$data = Role::factory()->raw();
$this->put("/roles/{$role->id}", $data);
$this->assertSessionHasSuccess('Role updated successfully.');
$this->assertDatabaseHas('roles', $data + ['id' => $role->id]);
}
/** @test */
public function users_without_appropriate_permission_cannot_update_role()
{
$roleA = RoleFactory::create();
$roleB = RoleFactory::withPermissions('roles.manage')->create();
$userA = UserFactory::role($roleA)->create();
$userB = UserFactory::role($roleB)->create();
$role = Role::factory()->create(['name' => 'foo']);
$data = Role::factory()->raw();
$this->actingAs($userA)
->put("/roles/{$role->id}", $data)
->assertStatus(403);
$this->assertEquals($role->toArray(), $role->fresh()->toArray());
$this->actingAs($userB)
->put("/roles/{$role->id}", $data)
->assertRedirect('roles');
$role->refresh();
$this->assertEquals($role->name, $data['name']);
$this->assertEquals($role->display_name, $data['display_name']);
$this->assertEquals($role->description, $data['description']);
}
/** @test */
public function removable_attribute_cannot_be_changed_on_update()
{
$role = RoleFactory::unremovable()->create();
$data = Role::factory()->raw(['removable' => true]);
$this->actingAsAdmin()->put("/roles/{$role->id}", $data);
$role->refresh();
$this->assertEquals($role->name, $data['name']);
$this->assertEquals($role->display_name, $data['display_name']);
$this->assertEquals($role->description, $data['description']);
$this->assertFalse($role->removable);
}
/** @test */
public function delete_role()
{
$role = RoleFactory::removable()->create();
$this->actingAsAdmin()->delete(route('roles.destroy', $role));
$this->assertNull($role->fresh());
}
/** @test */
public function users_without_appropriate_permission_cannot_delete_role()
{
$roleA = RoleFactory::create();
$roleB = RoleFactory::withPermissions('roles.manage')->create();
$userA = UserFactory::role($roleA)->create();
$userB = UserFactory::role($roleB)->create();
$role = Role::factory()->create(['name' => 'foo']);
$this->actingAs($userA)
->delete(route('roles.destroy', $role->id))
->assertStatus(403);
$this->assertNotNull($role->fresh());
$this->actingAs($userB)
->delete(route('roles.destroy', $role->id))
->assertRedirect('roles');
$this->assertNull($role->fresh());
}
/** @test */
public function users_receive_default_role_after_their_role_is_deleted()
{
$user = UserFactory::create();
$role = Role::factory()->create(['removable' => true]);
$userRole = Role::where('name', 'User')->first();
$user->setRole($role);
$this->assertTrue($user->fresh()->hasRole($role->name));
$this->actingAsAdmin()->delete(route('roles.destroy', $role));
$this->assertDatabaseHas('users', [
'role_id' => $userRole->id,
'id' => $user->id,
]);
$user = $user->fresh();
$this->assertFalse($user->hasRole($role->name));
$this->assertTrue($user->hasRole($userRole->name));
}
/** @test */
public function only_removable_roles_can_be_deleted()
{
$removableRole = Role::factory()->create(['removable' => true]);
$nonRemovableRole = Role::factory()->create(['removable' => false]);
$this->beAdmin();
$this->delete(route('roles.destroy', $removableRole->id));
$this->assertNull($removableRole->fresh());
$this->delete(route('roles.destroy', $nonRemovableRole->id))
->assertStatus(404);
$this->assertNotNull($nonRemovableRole->fresh());
}
}
@@ -0,0 +1,105 @@
<?php
namespace Tests\Feature\Web\Settings;
use Facades\Tests\Setup\RoleFactory;
use Facades\Tests\Setup\UserFactory;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Setting;
use Tests\TestCase;
class AuthSettingsTest extends TestCase
{
use RefreshDatabase;
protected function setUp(): void
{
parent::setUp();
$this->artisan('db:seed');
}
/** @test */
public function update_auth_settings()
{
Setting::set('app_name', 'bar');
$data = $this->getAuthSettingsData();
$this->actingAsAdmin()
->from('/settings/auth')
->post('/settings/auth', $data)
->assertRedirect('/settings/auth');
$this->assertAuthSettingsUpdated($data);
}
/** @test */
public function only_users_with_appropriate_permission_can_update_auth_settings()
{
Setting::set('app_name', 'bar');
$roleA = RoleFactory::create();
$roleB = RoleFactory::withPermissions('settings.auth')->create();
$userA = UserFactory::role($roleA)->create();
$userB = UserFactory::role($roleB)->create();
$data = $this->getAuthSettingsData();
$this->actingAs($userA)
->from('/settings/auth')
->post('/settings/auth', $data)
->assertStatus(403);
$this->assertAuthSettingsNotUpdated($data);
$this->actingAs($userB)
->from('/settings/auth')
->post('/settings/auth', $data)
->assertRedirect('/settings/auth');
$this->assertAuthSettingsUpdated($data);
}
private function assertAuthSettingsUpdated(array $data)
{
$this->assertEquals($data['remember_me'], Setting::get('remember_me'));
$this->assertEquals($data['forgot_password'], Setting::get('forgot_password'));
$this->assertEquals($data['login_reset_token_lifetime'], Setting::get('login_reset_token_lifetime'));
$this->assertEquals($data['throttle_enabled'], Setting::get('throttle_enabled'));
$this->assertEquals($data['throttle_attempts'], Setting::get('throttle_attempts'));
$this->assertEquals($data['throttle_lockout_time'], Setting::get('throttle_lockout_time'));
$this->assertEquals($data['reg_enabled'], Setting::get('reg_enabled'));
$this->assertEquals($data['tos'], Setting::get('tos'));
$this->assertEquals($data['reg_email_confirmation'], Setting::get('reg_email_confirmation'));
}
private function assertAuthSettingsNotUpdated(array $data)
{
$this->assertNotEquals($data['remember_me'], Setting::get('remember_me'));
$this->assertNotEquals($data['forgot_password'], Setting::get('forgot_password'));
$this->assertNotEquals($data['login_reset_token_lifetime'], Setting::get('login_reset_token_lifetime'));
$this->assertNotEquals($data['throttle_enabled'], Setting::get('throttle_enabled'));
$this->assertNotEquals($data['throttle_attempts'], Setting::get('throttle_attempts'));
$this->assertNotEquals($data['throttle_lockout_time'], Setting::get('throttle_lockout_time'));
$this->assertNotEquals($data['reg_enabled'], Setting::get('reg_enabled'));
$this->assertNotEquals($data['tos'], Setting::get('tos'));
$this->assertNotEquals($data['reg_email_confirmation'], Setting::get('reg_email_confirmation'));
}
private function getAuthSettingsData()
{
return [
'remember_me' => 1,
'forgot_password' => 1,
'login_reset_token_lifetime' => 123,
'throttle_enabled' => 1,
'throttle_attempts' => 10,
'throttle_lockout_time' => 2,
'reg_enabled' => 1,
'tos' => 1,
'reg_email_confirmation' => 1,
];
}
}
@@ -0,0 +1,49 @@
<?php
namespace Tests\Feature\Web\Settings;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Setting;
use Tests\TestCase;
class CaptchaSettingsTest extends TestCase
{
use RefreshDatabase;
protected function setUp(): void
{
parent::setUp();
$this->artisan('db:seed');
}
/** @test */
public function enable_captcha()
{
Setting::set('registration.captcha.enabled', false);
$this->assertFalse(Setting::get('registration.captcha.enabled'));
$this->actingAsAdmin()
->from('/settings/auth')
->post('/settings/auth/registration/captcha/enable')
->assertRedirect('/settings/auth');
$this->assertTrue(Setting::get('registration.captcha.enabled'));
}
/** @test */
public function disable_two_factor()
{
Setting::set('registration.captcha.enabled', true);
$this->assertTrue(Setting::get('registration.captcha.enabled'));
$this->actingAsAdmin()
->from('/settings/auth')
->post('/settings/auth/registration/captcha/disable')
->assertRedirect('/settings/auth');
$this->assertFalse(Setting::get('registration.captcha.enabled'));
}
}
@@ -0,0 +1,62 @@
<?php
namespace Tests\Feature\Web\Settings;
use Facades\Tests\Setup\RoleFactory;
use Facades\Tests\Setup\UserFactory;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Setting;
use Tests\TestCase;
class GeneralSettingsTest extends TestCase
{
use RefreshDatabase;
protected function setUp(): void
{
parent::setUp();
$this->artisan('db:seed');
}
/** @test */
public function update_general_settings()
{
Setting::set('app_name', 'bar');
$this->assertEquals('bar', Setting::get('app_name'));
$this->actingAsAdmin()
->from('/settings/general')
->post('/settings/general', ['app_name' => 'foo'])
->assertRedirect('/settings/general');
$this->assertEquals('foo', Setting::get('app_name'));
}
/** @test */
public function only_users_with_appropriate_permission_can_update_general_settings()
{
Setting::set('app_name', 'bar');
$roleA = RoleFactory::create();
$roleB = RoleFactory::withPermissions('settings.general')->create();
$userA = UserFactory::role($roleA)->create();
$userB = UserFactory::role($roleB)->create();
$this->actingAs($userA)
->from('/settings/general')
->post('/settings/general', ['app_name' => 'foo'])
->assertStatus(403);
$this->assertEquals('bar', Setting::get('app_name'));
$this->actingAs($userB)
->from('/settings/general')
->post('/settings/general', ['app_name' => 'foo'])
->assertRedirect('/settings/general');
$this->assertEquals('foo', Setting::get('app_name'));
}
}
@@ -0,0 +1,49 @@
<?php
namespace Tests\Feature\Web\Settings;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Setting;
use Tests\TestCase;
class TwoFactorSettingsTest extends TestCase
{
use RefreshDatabase;
protected function setUp(): void
{
parent::setUp();
$this->artisan('db:seed');
}
/** @test */
public function enable_two_factor()
{
Setting::set('2fa.enabled', false);
$this->assertFalse(Setting::get('2fa.enabled'));
$this->actingAsAdmin()
->from('/settings/auth')
->post('/settings/auth/2fa/enable')
->assertRedirect('/settings/auth');
$this->assertTrue(Setting::get('2fa.enabled'));
}
/** @test */
public function disable_two_factor()
{
Setting::set('2fa.enabled', true);
$this->assertTrue(Setting::get('2fa.enabled'));
$this->actingAsAdmin()
->from('/settings/auth')
->post('/settings/auth/2fa/disable')
->assertRedirect('/settings/auth');
$this->assertFalse(Setting::get('2fa.enabled'));
}
}
+137
View File
@@ -0,0 +1,137 @@
<?php
namespace Tests\Feature\Web;
use Facades\Tests\Setup\RoleFactory;
use Facades\Tests\Setup\UserFactory;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Setting;
use Tests\TestCase;
class SettingsTest extends TestCase
{
use RefreshDatabase;
protected function setUp(): void
{
parent::setUp();
$this->artisan('db:seed');
}
/** @test */
public function update_general_settings()
{
Setting::set('app_name', 'bar');
$this->assertEquals('bar', Setting::get('app_name'));
$this->actingAsAdmin()
->from('/settings/general')
->post('/settings/general', ['app_name' => 'foo'])
->assertRedirect('/settings/general');
$this->assertEquals('foo', Setting::get('app_name'));
}
/** @test */
public function only_users_with_appropriate_permission_can_update_general_settings()
{
Setting::set('app_name', 'bar');
$roleA = RoleFactory::create();
$roleB = RoleFactory::withPermissions('settings.general')->create();
$userA = UserFactory::role($roleA)->create();
$userB = UserFactory::role($roleB)->create();
$this->actingAs($userA)
->from('/settings/general')
->post('/settings/general', ['app_name' => 'foo'])
->assertStatus(403);
$this->assertEquals('bar', Setting::get('app_name'));
$this->actingAs($userB)
->from('/settings/general')
->post('/settings/general', ['app_name' => 'foo'])
->assertRedirect('/settings/general');
$this->assertEquals('foo', Setting::get('app_name'));
}
/** @test */
public function update_auth_settings()
{
Setting::set('app_name', 'bar');
$data = $this->getAuthSettingsData();
$this->actingAsAdmin()
->from('/settings/auth')
->post('/settings/auth', $data)
->assertRedirect('/settings/auth');
$this->assertAuthSettingsUpdated($data);
}
/** @test */
public function only_users_with_appropriate_permission_can_update_auth_settings()
{
Setting::set('app_name', 'bar');
$roleA = RoleFactory::create();
$roleB = RoleFactory::withPermissions('settings.auth')->create();
$userA = UserFactory::role($roleA)->create();
$userB = UserFactory::role($roleB)->create();
$data = $this->getAuthSettingsData();
$this->actingAs($userA)
->from('/settings/auth')
->post('/settings/auth', $data)
->assertStatus(403);
$this->assertAuthSettingsNotUpdated($data);
$this->actingAs($userB)
->from('/settings/auth')
->post('/settings/auth', $data)
->assertRedirect('/settings/auth');
$this->assertAuthSettingsUpdated($data);
}
private function assertAuthSettingsUpdated(array $data)
{
$this->assertEquals($data['remember_me'], Setting::get('remember_me'));
$this->assertEquals($data['forgot_password'], Setting::get('forgot_password'));
$this->assertEquals($data['login_reset_token_lifetime'], Setting::get('login_reset_token_lifetime'));
$this->assertEquals($data['throttle_enabled'], Setting::get('throttle_enabled'));
$this->assertEquals($data['throttle_attempts'], Setting::get('throttle_attempts'));
$this->assertEquals($data['throttle_lockout_time'], Setting::get('throttle_lockout_time'));
}
private function assertAuthSettingsNotUpdated(array $data)
{
$this->assertNotEquals($data['remember_me'], Setting::get('remember_me'));
$this->assertNotEquals($data['forgot_password'], Setting::get('forgot_password'));
$this->assertNotEquals($data['login_reset_token_lifetime'], Setting::get('login_reset_token_lifetime'));
$this->assertNotEquals($data['throttle_enabled'], Setting::get('throttle_enabled'));
$this->assertNotEquals($data['throttle_attempts'], Setting::get('throttle_attempts'));
$this->assertNotEquals($data['throttle_lockout_time'], Setting::get('throttle_lockout_time'));
}
private function getAuthSettingsData()
{
return [
'remember_me' => 1,
'forgot_password' => 1,
'login_reset_token_lifetime' => 123,
'throttle_enabled' => 1,
'throttle_attempts' => 10,
'throttle_lockout_time' => 2,
];
}
}
@@ -0,0 +1,228 @@
<?php
namespace Tests\Feature\Web;
use Auth;
use DB;
use Facades\Tests\Setup\UserFactory;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Laravel\Socialite\Contracts\Provider as SocialiteProvider;
use Laravel\Socialite\Contracts\User as SocialUserContract;
use Mockery as m;
use Socialite;
use Tests\TestCase;
use Tests\UpdatesSettings;
use Vanguard\Support\Enum\UserStatus;
use Vanguard\User;
class SocialAuthenticationTest extends TestCase
{
use RefreshDatabase, UpdatesSettings;
protected function setUp(): void
{
parent::setUp();
$this->artisan('db:seed');
}
/** @test */
public function social_login_for_new_user()
{
$this->setSettings(['reg_enabled' => true]);
$socialUser = new StubSocialUser;
$driver = m::mock(SocialiteProvider::class);
$driver->shouldReceive('user')->andReturn($socialUser);
Socialite::shouldReceive('driver')->with('foo')->andReturn($driver);
$this->get('auth/foo/callback');
$this->assertDatabaseHas('users', [
'username' => null,
'email' => $socialUser->getEmail(),
'first_name' => 'John',
'last_name' => 'Doe',
'status' => UserStatus::ACTIVE,
'email_verified_at' => now(),
]);
$user = User::where('email', $socialUser->getEmail())->first();
$this->assertDatabaseHas('social_logins', [
'user_id' => $user->id,
'provider' => 'foo',
'provider_id' => $socialUser->getId(),
'avatar' => $socialUser->getAvatar(),
]);
$this->assertEquals($user->id, Auth::id());
}
/** @test */
public function social_login_for_new_user_if_registration_is_disabled()
{
$this->setSettings(['reg_enabled' => false]);
$socialUser = new StubSocialUser;
$driver = m::mock(SocialiteProvider::class);
$driver->shouldReceive('user')->andReturn($socialUser);
Socialite::shouldReceive('driver')->with('foo')->andReturn($driver);
$this->get('auth/foo/callback')
->assertRedirect('/login');
$this->assertSessionHasError('Only users who already created an account can log in.');
}
/** @test */
public function social_login_for_banned_user()
{
$user = UserFactory::banned()->create();
$socialUser = new StubSocialUser;
$driver = m::mock(SocialiteProvider::class);
$driver->shouldReceive('user')->andReturn($socialUser);
Socialite::shouldReceive('driver')->with('foo')->andReturn($driver);
DB::table('social_logins')->insert([
'user_id' => $user->id,
'provider' => 'foo',
'provider_id' => $socialUser->getId(),
'avatar' => $socialUser->getAvatar(),
'created_at' => \Carbon\Carbon::now(),
]);
$this->get('auth/foo/callback')
->assertRedirect('/login');
$this->assertSessionHasError('Your account is banned by administrator.');
}
/** @test */
public function social_login_for_existing_user()
{
$user = User::factory()->create();
$socialUser = new StubSocialUser;
$driver = m::mock(SocialiteProvider::class);
$driver->shouldReceive('user')->andReturn($socialUser);
Socialite::shouldReceive('driver')->with('foo')->andReturn($driver);
DB::table('social_logins')->insert([
'user_id' => $user->id,
'provider' => 'foo',
'provider_id' => $socialUser->getId(),
'avatar' => $socialUser->getAvatar(),
'created_at' => \Carbon\Carbon::now(),
]);
$this->get('auth/foo/callback')
->assertRedirect('/');
$this->assertEquals($user->id, Auth::id());
}
/** @test */
public function missing_email_login()
{
$this->setSettings(['reg_enabled' => true]);
$socialUser = new StubSocialUserWithoutEmail;
$driver = m::mock(SocialiteProvider::class);
$driver->shouldReceive('user')->andReturn($socialUser);
Socialite::shouldReceive('driver')->with('foo')->andReturn($driver);
$this->get('auth/foo/callback')
->assertRedirect('login');
$this->assertSessionHasError('You have to provide your email address.');
}
/** @test */
public function social_login_for_user_with_one_word_name()
{
$this->setSettings(['reg_enabled' => true]);
$socialUser = new StubSocialUserWithOneWordName;
$driver = m::mock(SocialiteProvider::class);
$driver->shouldReceive('user')->andReturn($socialUser);
Socialite::shouldReceive('driver')->with('foo')->andReturn($driver);
$this->get('auth/foo/callback')
->assertRedirect('/');
$this->assertDatabaseHas('users', [
'username' => null,
'email' => $socialUser->getEmail(),
'first_name' => 'John',
'last_name' => '',
'status' => UserStatus::ACTIVE,
]);
$user = User::where('email', $socialUser->getEmail())->first();
$this->assertDatabaseHas('social_logins', [
'user_id' => $user->id,
'provider' => 'foo',
'provider_id' => $socialUser->getId(),
'avatar' => $socialUser->getAvatar(),
]);
$this->assertEquals($user->id, Auth::id());
}
}
class StubSocialUser implements SocialUserContract
{
public function getId()
{
return '123';
}
public function getNickname()
{
return 'johndoe';
}
public function getName()
{
return 'John Doe';
}
public function getEmail()
{
return 'john@doe.com';
}
public function getAvatar()
{
return 'http://www.gravatar.com/avatar';
}
}
class StubSocialUserWithoutEmail extends StubSocialUser
{
public $email = null;
public function getEmail()
{
return $this->email;
}
}
class StubSocialUserWithOneWordName extends StubSocialUser
{
public function getName()
{
return 'John';
}
}
+261
View File
@@ -0,0 +1,261 @@
<?php
namespace Tests\Feature\Web;
use Carbon\Carbon;
use Event;
use Facades\Tests\Setup\UserFactory;
use Illuminate\Foundation\Testing\RefreshDatabase;
use PragmaRX\Google2FA\Google2FA;
use Tests\TestCase;
use Tests\UpdatesSettings;
use Vanguard\Events\User\TwoFactorEnabled;
use Vanguard\User;
class TwoFactorAuthTest extends TestCase
{
use RefreshDatabase, UpdatesSettings;
protected function setUp(): void
{
parent::setUp();
$this->artisan('db:seed');
}
/** @test */
public function the_2fa_form_is_visible_on_profile_page_if_2fa_is_enabled()
{
config(['services.authy.key' => 'test']);
$this->setSettings(['2fa.enabled' => false]);
$this->actingAsAdmin()
->get('profile')
->assertDontSee('Two-Factor Authentication');
$this->setSettings(['2fa.enabled' => true]);
$this->actingAsAdmin()
->get('profile')
->assertSee('Two-Factor Authentication');
}
/** @test */
public function the_2fa_form_is_visible_on_edit_user_page_if_2fa_is_enabled()
{
config(['services.authy.key' => 'test']);
$this->setSettings(['2fa.enabled' => false]);
$user = UserFactory::create();
$this->actingAsAdmin()
->get("/users/{$user->id}/edit")
->assertDontSee('Two-Factor Authentication');
$this->setSettings(['2fa.enabled' => true]);
$this->actingAsAdmin()
->get("/users/{$user->id}/edit")
->assertSee('Two-Factor Authentication');
}
/** @test */
public function enable_2fa_from_profile_page()
{
$this->setSettings(['2fa.enabled' => true]);
$user = UserFactory::user()->create();
$this->actingAs($user)
->post('/two-factor/enable')
->assertRedirect('/')
->assertSessionHas('tab', '2fa');
$this->assertTrue(
\DB::table('users')
->where('id', $user->id)
->whereNotNull('two_factor_secret')
->exists()
);
}
/** @test */
public function enable_2fa_from_edit_user_page()
{
$this->setSettings(['2fa.enabled' => true]);
$user = UserFactory::user()->create();
$formData = ['user' => $user->id];
$this->actingAsAdmin()
->post("users/{$user->id}/two-factor/enable", $formData)
->assertRedirect("/")
->assertSessionHas('tab', '2fa');
$this->assertTrue(
\DB::table('users')
->where('id', $user->id)
->whereNotNull('two_factor_secret')
->exists()
);
}
/** @test */
public function users_without_appropriate_permissions_cannot_enable_2fa_for_other_users()
{
$this->setSettings(['2fa.enabled' => true]);
$this->be(UserFactory::user()->create());
$user = UserFactory::user()->create();
$this->post('two-factor/enable', [
'user' => $user->id,
])->assertStatus(403);
$this->assertTrue(
\DB::table('users')
->where('id', $user->id)
->whereNull('two_factor_secret')
->exists()
);
}
/** @test */
public function code_field_is_required_during_2fa_verification()
{
$this->setSettings(['2fa.enabled' => true]);
$user = UserFactory::user()->create();
$user->two_factor_secret = '123123';
$user->save();
$this->actingAs($user)
->post('two-factor/verify')
->assertSessionHasErrors('code');
}
/** @test */
public function the_2fa_verification_with_wrong_token_will_fail()
{
$google2fa = new Google2FA();
$secret = encrypt($google2fa->generateSecretKey());
$this->withoutExceptionHandling();
$this->setSettings(['2fa.enabled' => true]);
$user = UserFactory::user()->create();
$user->two_factor_secret = $secret;
$user->save();
$this->actingAs($user)
->post('two-factor/verify', ['code' => '123123']);
$this->assertSessionHasError('Invalid 2FA token.');
}
/** @test */
public function successful_2fa_code_verification()
{
$google2fa = new Google2FA();
$secret = encrypt($google2fa->generateSecretKey());
$this->setSettings(['2fa.enabled' => true]);
Event::fake([
TwoFactorEnabled::class,
]);
$user = UserFactory::user()->create();
$user->two_factor_secret = $secret;
$user->save();
$validCode = $google2fa->getCurrentOtp(decrypt($user->two_factor_secret));
$this->actingAs($user)
->post('two-factor/verify', ['code' => $validCode])
->assertRedirect('/profile');
$this->assertDatabaseHas('users', [
'id' => $user->id,
'two_factor_secret' => $secret,
]);
Event::assertDispatched(TwoFactorEnabled::class);
}
/** @test */
public function user_can_disable_2fa()
{
$google2fa = new Google2FA();
$secret = encrypt($google2fa->generateSecretKey());
$this->setSettings(['2fa.enabled' => true]);
$user = UserFactory::user()->create();
$user->two_factor_secret = $secret;
$user->two_factor_confirmed_at = Carbon::now();
$user->save();
$this->be($user);
Event::fake([
\Vanguard\Events\User\TwoFactorDisabled::class,
]);
$this->from('/profile')
->post('two-factor/disable')
->assertRedirect('/profile');
$this->assertSessionHasSuccess('Two-Factor Authentication disabled successfully.');
Event::assertDispatched(\Vanguard\Events\User\TwoFactorDisabled::class);
}
/** @test */
public function user_can_disable_2fa_for_another_user()
{
$google2fa = new Google2FA();
$secret = encrypt($google2fa->generateSecretKey());
$this->setSettings(['2fa.enabled' => true]);
Event::fake([
\Vanguard\Events\User\TwoFactorDisabled::class,
]);
$this->beAdmin();
$user = UserFactory::user()->create();
$user->two_factor_secret = $secret;
$user->two_factor_confirmed_at = Carbon::now();
$user->save();
$this->from("/users/{$user->id}/edit")
->post("/users/{$user->id}/two-factor/disable", ['user' => $user->id])
->assertRedirect("/users/{$user->id}/edit");
$this->assertDatabaseHas('users', [
'id' => $user->id,
'two_factor_secret' => null,
]);
$this->assertSessionHasSuccess('Two-Factor Authentication disabled successfully.');
Event::assertDispatched(\Vanguard\Events\User\TwoFactorDisabled::class);
}
/** @test */
public function user_without_appropriate_permissions_cannot_disable_2fa_for_another_user()
{
$this->setSettings(['2fa.enabled' => true]);
$this->be(UserFactory::user()->create());
$user = User::factory()->create();
$this->post('two-factor/disable', ['user' => $user->id])->assertForbidden();
}
}
+259
View File
@@ -0,0 +1,259 @@
<?php
namespace Tests\Feature\Web;
use Carbon\Carbon;
use Event;
use Facades\Tests\Setup\UserFactory;
use Hash;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\UploadedFile;
use Storage;
use Tests\TestCase;
use Vanguard\Events\User\ChangedAvatar;
use Vanguard\Events\User\UpdatedProfileDetails;
use Vanguard\Role;
use Vanguard\Support\Enum\UserStatus;
class UpdateProfileTest extends TestCase
{
use RefreshDatabase;
protected function setUp(): void
{
parent::setUp();
$this->be(UserFactory::create());
}
/** @test */
public function user_can_access_his_profile_page()
{
$this->get('/profile')->assertOk();
}
/** @test
*/
public function user_can_update_his_profile_details()
{
Event::fake([
UpdatedProfileDetails::class,
]);
$data = $this->getStubDetailsData();
$this->from('/profile')
->put('profile/details', $data)
->assertRedirect('/profile');
$this->assertSessionHasSuccess('Profile updated successfully.');
$this->assertDatabaseHas('users', $data + ['id' => auth()->id()]);
Event::assertDispatched(UpdatedProfileDetails::class);
}
/** @test */
public function user_cannot_change_his_status_while_updating_the_profile()
{
$data = $this->getStubDetailsData();
$this->from('/profile')
->put('profile/details', $data + ['status' => UserStatus::BANNED->value])
->assertRedirect('/profile');
$this->assertSessionHasSuccess('Profile updated successfully.');
$this->assertDatabaseHas('users', $data + [
'id' => auth()->id(),
'status' => UserStatus::ACTIVE,
]);
}
/** @test */
public function user_cannot_change_his_role_while_updating_the_profile()
{
$data = $this->getStubDetailsData();
$role = Role::factory()->create();
$this->from('/profile')
->put('profile/details', $data + ['role_id' => $role])
->assertRedirect('/profile');
$this->assertSessionHasSuccess('Profile updated successfully.');
$this->assertNotEquals($role->id, auth()->user()->role_id);
}
/** @test */
public function update_avatar()
{
Event::fake([
ChangedAvatar::class,
]);
Storage::fake('public');
$data = [
'avatar' => UploadedFile::fake()->image('photo1.jpg', 300, 300),
'points' => [
'x1' => 0,
'y1' => 0,
'x2' => 200,
'y2' => 200,
],
];
$this->from('profile')
->post('/profile/avatar', $data)
->assertRedirect('profile');
$this->assertSessionHasSuccess('Avatar changed successfully.');
$user = auth()->user()->fresh();
$this->assertNotNull($user->avatar);
Storage::disk('public')->assertExists("upload/users/{$user->avatar}");
[$width, $height] = getimagesizefromstring(
Storage::disk('public')->get("upload/users/{$user->avatar}")
);
$this->assertEquals(160, $width);
$this->assertEquals(160, $height);
Event::assertDispatched(ChangedAvatar::class);
}
/** @test */
public function update_avatar_with_invalid_image_file()
{
Storage::fake('public');
$data = [
'avatar' => UploadedFile::fake()->create('foo.txt', 123),
'points' => [
'x1' => 0,
'y1' => 0,
'x2' => 200,
'y2' => 200,
],
];
$this->from('profile')
->post('/profile/avatar', $data)
->assertRedirect('profile')
->assertSessionHasErrors('avatar');
$user = auth()->user()->fresh();
Storage::disk('public')->assertMissing("upload/users/{$user->avatar}");
$this->assertNull($user->avatar);
}
/** @test */
public function update_avatar_external()
{
Event::fake([
ChangedAvatar::class,
]);
$data = ['url' => '//www.gravatar.com/avatar'];
$this->post(route('profile.update.avatar-external', auth()->id()), $data)
->assertRedirect();
$this->assertSessionHasSuccess('Avatar changed successfully.');
$this->assertEquals($data['url'], auth()->user()->fresh()->avatar);
Event::assertDispatched(ChangedAvatar::class);
}
/** @test */
public function update_user_login_details()
{
$data = [
'email' => 'john@doe.com',
'username' => 'milos',
'password' => 'milos123123',
'password_confirmation' => 'milos123123',
];
$this->from('/profile')
->put('profile/login-details', $data)
->assertRedirect('/profile');
$this->assertSessionHasSuccess('Login details updated successfully.');
$user = auth()->user()->fresh();
$this->assertEquals($data['email'], $user->email);
$this->assertEquals($data['username'], $user->username);
$this->assertTrue(Hash::check($data['password'], $user->password));
}
/** @test */
public function password_is_not_changed_if_omited_on_update()
{
auth()->user()->update([
'email' => 'john@example.com',
'password' => '123123',
]);
$data = [
'email' => 'test@test.com',
'password' => '',
'password_confirmation' => '',
];
$this->from('/profile')
->put('profile/login-details', $data)
->assertRedirect('/profile');
$user = auth()->user()->fresh();
$this->assertEquals($data['email'], $user->email);
$this->assertTrue(Hash::check('123123', $user->password));
}
/** @test */
public function user_session_invalidation()
{
$this->withoutExceptionHandling();
config(['session.driver' => 'database']);
$user = UserFactory::withCredentials('foo', 'bar')->create();
$this->be($user);
$agent = $this->app['agent'];
$device = $agent->device() ?: 'Unknown';
$platform = $agent->platform() ?: 'Unknown';
// Log-in manually to actually create session record in DB
$this->post('/login', ['username' => 'foo', 'password' => 'bar']);
$this->get('/profile/sessions')
->assertSee('127.0.0.1')
->assertSee($device)
->assertSee($platform)
->assertSee($agent->browser());
$sessionId = \DB::table('sessions')->where('user_id', $user->id)->first()->id;
$this->delete("profile/sessions/{$sessionId}/invalidate");
$this->assertDatabaseMissing('sessions', ['user_id' => $user->id]);
}
private function getStubDetailsData(): array
{
return [
'first_name' => 'foo',
'last_name' => 'bar',
'birthday' => Carbon::now()->subYears(25)->format('Y-m-d'),
'phone' => '12345667',
'address' => 'the address',
'country_id' => 688, //Serbia,
];
}
}
+710
View File
@@ -0,0 +1,710 @@
<?php
namespace Tests\Feature\Web;
use Carbon\Carbon;
use Event;
use Facades\Tests\Setup\RoleFactory;
use Facades\Tests\Setup\UserFactory;
use Hash;
use Illuminate\Contracts\Pagination\Paginator;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Storage;
use Tests\TestCase;
use Tests\UpdatesSettings;
use Vanguard\Events\User\UpdatedByAdmin;
use Vanguard\Role;
use Vanguard\Support\Enum\UserStatus;
use Vanguard\User;
class UsersTest extends TestCase
{
use RefreshDatabase, UpdatesSettings;
protected function setUp(): void
{
parent::setUp();
$this->artisan('db:seed', ['--class' => 'RolesSeeder']);
$this->artisan('db:seed', ['--class' => 'PermissionsSeeder']);
$this->artisan('db:seed', ['--class' => 'CountriesSeeder']);
}
/** @test */
public function guests_cannot_view_the_user_list_page()
{
$this->get('/users')->assertRedirect('/login');
}
/** @test */
public function users_without_appropriate_permission_cannot_view_user_list_page()
{
$roleA = RoleFactory::create();
$roleB = RoleFactory::withPermissions('users.manage')->create();
$userA = UserFactory::role($roleA)->create();
$userB = UserFactory::role($roleB)->create();
$this->actingAs($userA)->get('/users')->assertForbidden();
$this->actingAs($userB)->get('/users')->assertOk();
}
/** @test */
public function user_collection_is_being_properly_passed_to_the_view()
{
$admin = UserFactory::admin()->create();
$active = UserFactory::user()->create();
$banned = UserFactory::user()->banned()->create();
$unconfirmed = UserFactory::user()->unconfirmed()->create();
$users = $this->actingAs($admin)->get('users')->viewData('users');
$this->assertCount(4, $users);
$this->assertTrue($users->contains($admin));
$this->assertTrue($users->contains($active));
$this->assertTrue($users->contains($banned));
$this->assertTrue($users->contains($unconfirmed));
}
/** @test */
public function user_list_is_paginated()
{
$this->beAdmin();
$users = $this->get('users')->viewData('users');
$this->assertInstanceOf(Paginator::class, $users);
$this->assertCount(1, $users->items());
}
/** @test */
public function users_can_be_filtered_out_by_search_term()
{
$user1 = User::factory()->create(['first_name' => 'Milos', 'last_name' => 'Stojanovic']);
$user2 = User::factory()->create(['first_name' => 'John', 'last_name' => 'Doe']);
$user3 = User::factory()->create(['first_name' => 'Jane', 'last_name' => 'Doe']);
$users = $this->actingAsAdmin()->get('users?search=doe')->viewData('users');
$this->assertCount(2, $users);
$this->assertTrue($users->contains($user3));
$this->assertTrue($users->contains($user2));
}
/** @test */
public function users_can_be_filtered_out_by_status()
{
User::factory()->times(2)->create();
User::factory()->times(3)->create(['status' => UserStatus::UNCONFIRMED]);
$users = $this->actingAsAdmin()
->get('users?status='.UserStatus::BANNED->value)
->viewData('users');
$this->assertCount(0, $users);
}
/** @test */
public function admin_can_successfully_create_new_users()
{
$data = $this->validParams();
$this->actingAsAdmin()
->post('/users', $data)
->assertRedirect('/users');
$this->assertSessionHasSuccess('User created successfully.');
$user = User::where('email', $data['email'])->first();
$this->assertDatabaseHas('users', Arr::except($data, ['password', 'password_confirmation']));
$this->assertTrue(Hash::check('123123123', $user->password));
}
/** @test */
public function users_without_appropriate_permissions_cannot_create_new_users()
{
$roleA = RoleFactory::create();
$roleB = RoleFactory::withPermissions('users.manage')->create();
$userA = UserFactory::role($roleA)->create();
$userB = UserFactory::role($roleB)->create();
$data = $this->validParams();
$this->actingAs($userA)->post('/users', $data)->assertForbidden();
$this->assertNUll(User::where('email', $data['email'])->first());
$this->actingAs($userB)->post('/users', $data)->assertRedirect('/users');
$this->assertNotNull(User::where('email', $data['email'])->first());
}
/** @test */
public function email_field_is_required_while_creating_a_user()
{
$data = Arr::except($this->validParams(), ['email']);
$this->actingAsAdmin()
->from('/users')
->post('/users', $data)
->assertRedirect('/users')
->assertSessionHasErrors('email');
}
/** @test */
public function email_field_must_be_a_valid_email_while_creating_a_user()
{
$data = $this->validParams(['email' => 'foo']);
$this->actingAsAdmin()
->from('/users')
->post('/users', $data)
->assertRedirect('/users')
->assertSessionHasErrors('email');
}
/** @test */
public function email_must_be_unique_while_creating_a_user()
{
$this->beAdmin();
UserFactory::user()->email('john@example.com')->create();
$data = $this->validParams(['email' => 'john@example.com']);
$this->from('/users')
->post('/users', $data)
->assertRedirect('/users')
->assertSessionHasErrors('email');
}
/** @test */
public function username_is_not_required()
{
$this->beAdmin();
$data = $this->validParams();
unset($data['username']);
$this->from('/users')
->post('/users', $data)
->assertRedirect('/users');
$this->assertNotNull(User::where('email', $data['email'])->first());
}
/** @test */
public function username_must_be_unique_while_creating_a_user()
{
$this->beAdmin();
User::factory()->create(['username' => 'johndoe']);
$data = $this->validParams(['username' => 'johndoe']);
$this->from('/users')
->post('/users', $data)
->assertRedirect('/users')
->assertSessionHasErrors('username');
}
/** @test */
public function password_is_required_while_creating_a_user()
{
$this->beAdmin();
$data = $this->validParams();
unset($data['password']);
$this->from('/users')
->post('/users', $data)
->assertRedirect('/users')
->assertSessionHasErrors('password');
}
/** @test */
public function password_must_be_at_least_6_characters_long_while_creating_a_user()
{
$this->beAdmin();
$data = $this->validParams(['password' => '12345']);
$this->from('/users')
->post('/users', $data)
->assertRedirect('/users')
->assertSessionHasErrors('password');
}
/** @test */
public function password_must_be_confirmed_while_creating_a_user()
{
$this->beAdmin();
$data = $this->validParams();
unset($data['password_confirmation']);
$this->from('/users')
->post('/users', $data)
->assertRedirect('/users')
->assertSessionHasErrors('password');
}
/** @test */
public function birthday_must_be_a_valid_date_while_creating_a_user()
{
$this->beAdmin();
$data = $this->validParams(['birthday' => 'foo']);
$this->from('/users')
->post('/users', $data)
->assertRedirect('/users')
->assertSessionHasErrors('birthday');
}
/** @test */
public function role_field_is_required_while_creating_a_user()
{
$this->beAdmin();
$data = $this->validParams();
unset($data['role_id']);
$this->from('/users')
->post('/users', $data)
->assertRedirect('/users')
->assertSessionHasErrors('role_id');
}
/** @test */
public function selected_role_must_exist_inside_the_system_while_creating_a_user()
{
$this->beAdmin();
$data = $this->validParams(['role_id' => 123]);
$this->from('/users')
->post('/users', $data)
->assertRedirect('/users')
->assertSessionHasErrors('role_id');
}
/** @test */
public function country_id_field_is_not_required_while_creating_a_user()
{
$data = $this->validParams(['country_id' => 0]);
$this->actingAsAdmin()
->post('/users', $data)
->assertRedirect('/users');
$this->assertSessionHasSuccess('User created successfully.');
$user = User::where('email', $data['email'])->first();
$expected = Arr::except($data, ['password', 'password_confirmation']);
$expected['country_id'] = null;
$this->assertDatabaseHas('users', $expected);
$this->assertTrue(Hash::check('123123123', $user->password));
}
/** @test */
public function country_id_must_exist_inside_the_system_while_creating_a_user()
{
$this->beAdmin();
$data = $this->validParams(['country_id' => 12345]);
$this->from('/users')
->post('/users', $data)
->assertRedirect('/users')
->assertSessionHasErrors('country_id');
}
/** @test */
public function admin_can_view_users_profile()
{
$user = UserFactory::user()->create();
$this->actingAsAdmin()->get("users/{$user->id}")->assertOk();
}
/** @test */
public function users_without_appropriate_permissions_cannot_view_profile_for_another_user()
{
$roleA = RoleFactory::create();
$roleB = RoleFactory::withPermissions('users.manage')->create();
$userA = UserFactory::role($roleA)->create();
$userB = UserFactory::role($roleB)->create();
$this->actingAs($userA)->get("users/{$userB->id}")->assertForbidden();
$this->actingAs($userB)->get("users/{$userA->id}")->assertOk();
}
/** @test */
public function update_user_details()
{
\Event::fake([
UpdatedByAdmin::class,
]);
$this->beAdmin();
$user = UserFactory::user()->create();
$data = $this->validParams();
$this->from("users/{$user->id}/edit")
->put("/users/{$user->id}/update/details", $data)
->assertRedirect("users/{$user->id}/edit");
$expected = Arr::except($data, ['password', 'password_confirmation']);
$this->assertDatabaseHas('users', $expected + ['id' => $user->id]);
$this->assertSessionHasSuccess('User updated successfully.');
Event::assertDispatched(UpdatedByAdmin::class);
}
/** @test */
public function users_without_appropriate_permissions_cannot_update_other_users()
{
$roleA = RoleFactory::create();
$roleB = RoleFactory::withPermissions('users.manage')->create();
$userA = UserFactory::role($roleA)->create();
$userB = UserFactory::role($roleB)->create();
$data = $this->validParams();
$this->actingAs($userA)
->from("users/{$userB->id}/edit")
->put("/users/{$userB->id}/update/details", $data)
->assertForbidden();
$this->assertNotEquals($data['email'], $userB->fresh()->email);
$this->actingAs($userB)
->from("users/{$userA->id}/edit")
->put("/users/{$userA->id}/update/details", $data)
->assertRedirect("users/{$userA->id}/edit");
$this->assertEquals($data['email'], $userA->fresh()->email);
}
/** @test */
public function banning_a_user_will_invalidate_all_his_sessions()
{
config(['session.driver' => 'database']);
$this->beAdmin();
$user = UserFactory::user()->create(['remember_token' => Str::random(60)]);
\DB::table('sessions')->insert([
'id' => Str::random(40),
'user_id' => $user->id,
'ip_address' => '127.0.0.1',
'user_agent' => 'Foo',
'payload' => Str::random(),
'last_activity' => Carbon::now()->subMinute()->timestamp,
]);
$data = $this->validParams(['status' => UserStatus::BANNED->value]);
$this->put("/users/{$user->id}/update/details", $data);
$this->assertDatabaseMissing('sessions', ['user_id' => $user->id]);
$this->assertNull($user->fresh()->remember_token);
}
/** @test */
public function admin_can_update_users_login_details()
{
$this->beAdmin();
$user = UserFactory::user()->create();
$data = [
'email' => 'john@doe.com',
'username' => 'milos',
'password' => '123123123',
'password_confirmation' => '123123123',
];
$this->put("users/{$user->id}/update/login-details", $data)
->assertRedirect("users/{$user->id}/edit");
$this->assertSessionHasSuccess('Login details updated successfully.');
$user = $user->fresh();
$this->assertEquals($data['email'], $user->email);
$this->assertEquals($data['username'], $user->username);
$this->assertTrue(Hash::check($data['password'], $user->password));
}
/** @test */
public function users_without_appropriate_permissions_cannot_update_other_users_login_details()
{
$roleA = RoleFactory::create();
$roleB = RoleFactory::withPermissions('users.manage')->create();
$userA = UserFactory::role($roleA)->create();
$userB = UserFactory::role($roleB)->create();
$data = [
'email' => 'john@doe.com',
'username' => 'milos',
'password' => '123123123',
'password_confirmation' => '123123123',
];
$this->actingAs($userA)
->from("users/{$userB->id}/edit")
->put("users/{$userB->id}/update/login-details", $data)
->assertForbidden();
$this->assertNotEquals($data['email'], $userB->fresh()->email);
$this->actingAs($userB)
->from("users/{$userA->id}/edit")
->put("users/{$userA->id}/update/login-details", $data)
->assertRedirect("users/{$userA->id}/edit");
$this->assertEquals($data['email'], $userA->fresh()->email);
}
/** @test */
public function two_factor_form_visibility()
{
config(['services.authy.key' => 'test']);
$this->setSettings(['2fa.enabled' => false]);
$user = UserFactory::user()->create();
$this->actingAsAdmin()
->get("users/{$user->id}/edit")
->assertDontSee('Two-Factor Authentication');
$this->setSettings(['2fa.enabled' => true]);
$this->actingAsAdmin()
->get("users/{$user->id}/edit")
->assertSee('Two-Factor Authentication');
}
/** @test */
public function admin_can_update_avatar_on_behalf_of_a_user()
{
Storage::fake('public');
$data = [
'avatar' => UploadedFile::fake()->image('photo1.jpg', 300, 300),
'points' => [
'x1' => 0,
'y1' => 0,
'x2' => 200,
'y2' => 200,
],
];
$user = UserFactory::user()->create();
$this->actingAsAdmin()
->from("users/{$user->id}/edit")
->post("users/{$user->id}/update/avatar", $data)
->assertRedirect("users/{$user->id}/edit");
$this->assertSessionHasSuccess('Avatar changed successfully.');
$user->refresh();
$this->assertNotNull($user->avatar);
Storage::disk('public')->assertExists("upload/users/{$user->avatar}");
[$width, $height] = getimagesizefromstring(
Storage::disk('public')->get("upload/users/{$user->avatar}")
);
$this->assertEquals(160, $width);
$this->assertEquals(160, $height);
}
/** @test */
public function admin_can_update_avatar_on_behalf_of_a_user_only_if_valid_file_is_selected()
{
Storage::fake('public');
$data = [
'avatar' => UploadedFile::fake()->create('foo.txt', 123),
'points' => [
'x1' => 0,
'y1' => 0,
'x2' => 200,
'y2' => 200,
],
];
$user = UserFactory::user()->create();
$this->actingAsAdmin()
->from("users/{$user->id}/edit")
->post("users/{$user->id}/update/avatar", $data)
->assertRedirect("users/{$user->id}/edit");
$this->assertNull($user->fresh()->avatar);
}
/** @test */
public function users_without_appropriate_permissions_cannot_update_avatar_for_other_users()
{
Storage::fake('public');
$roleA = RoleFactory::create();
$roleB = RoleFactory::withPermissions('users.manage')->create();
$userA = UserFactory::role($roleA)->create();
$userB = UserFactory::role($roleB)->create();
$data = [
'avatar' => UploadedFile::fake()->image('photo1.jpg', 300, 300),
'points' => [
'x1' => 0,
'y1' => 0,
'x2' => 200,
'y2' => 200,
],
];
$this->actingAs($userA)
->from("users/{$userB->id}/edit")
->post("users/{$userB->id}/update/avatar", $data)
->assertForbidden();
$this->assertNull($userB->fresh()->avatar);
$this->actingAs($userB)
->from("users/{$userA->id}/edit")
->post("users/{$userA->id}/update/avatar", $data)
->assertRedirect("users/{$userA->id}/edit");
$this->assertNotNull($userA->fresh()->avatar);
}
/** @test */
public function session_page_is_not_available_for_non_database_driver()
{
config(['session.driver' => 'array']);
$user = UserFactory::admin()->create();
$this->actingAs($user)
->get('users')
->assertDontSee('User Sessions');
// this page should not be accessible if
// database session driver is not being used
$this->get("users/{$user->id}/sessions")->assertNotFound();
}
/** @test */
public function invalidate_session()
{
config(['session.driver' => 'database']);
Carbon::setTestNow(Carbon::now());
$user = UserFactory::admin()->withCredentials('foo', 'bar')->create();
$agent = $this->app['agent'];
$device = $agent->device() ?: 'Unknown';
$platform = $agent->platform() ?: 'Unknown';
// Log-in manually to actually create session record in DB
$this->post('/login', ['username' => 'foo', 'password' => 'bar']);
$this->get("users/{$user->id}/sessions")
->assertSee('127.0.0.1')
->assertSee($device)
->assertSee($platform)
->assertSee($agent->browser());
$sessionId = \DB::table('sessions')->where('user_id', $user->id)->first()->id;
$this->delete("users/{$user->id}/sessions/{$sessionId}/invalidate");
$this->assertDatabaseMissing('sessions', ['user_id' => $user->id]);
}
/** @test */
public function admins_can_delete_other_users()
{
$user = UserFactory::user()->create();
$this->actingAsAdmin()
->delete(route('users.destroy', $user))
->assertRedirect('users');
$this->assertSessionHasSuccess('User deleted successfully.');
$this->assertNull($user->fresh());
}
/** @test */
public function users_without_appropriate_permissions_cannot_delete_other_users()
{
$roleA = RoleFactory::create();
$roleB = RoleFactory::withPermissions('users.manage')->create();
$userA = UserFactory::role($roleA)->create();
$userB = UserFactory::role($roleB)->create();
$this->actingAs($userA)
->delete(route('users.destroy', $userB))
->assertForbidden();
$this->assertNotNull($userB->fresh());
$this->actingAs($userB)
->delete(route('users.destroy', $userA))
->assertRedirect('/users');
$this->assertNull($userA->fresh());
}
/** @test */
public function user_cannot_delete_himself()
{
$this->beAdmin();
$this->delete(route('users.destroy', auth()->id()))
->assertRedirect('/users');
$this->assertNotNull(auth()->user()->fresh());
$this->assertSessionHasError('You cannot delete yourself.');
}
protected function validParams(array $overrides = []): array
{
return array_merge([
'role_id' => Role::whereName('User')->first()->id,
'status' => UserStatus::ACTIVE->value,
'first_name' => 'foo',
'last_name' => 'bar',
'birthday' => Carbon::now()->subYears(25)->format('Y-m-d'),
'phone' => '12345667',
'address' => 'the address',
'country_id' => 688, //Serbia,
'email' => 'john@doe.com',
'username' => 'johndoe',
'password' => '123123123',
'password_confirmation' => '123123123',
], $overrides);
}
}