My Account: Covered profile and auth pages with tests

This commit is contained in:
Dan Brown 2023-10-19 16:06:59 +01:00
parent f55e7ca3c9
commit ce53f641ad
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
3 changed files with 167 additions and 1 deletions

View File

@ -161,7 +161,7 @@ class UserAccountController extends Controller
*/ */
public function showAuth(SocialAuthService $socialAuthService) public function showAuth(SocialAuthService $socialAuthService)
{ {
$mfaMethods = user()->mfaValues->groupBy('method'); $mfaMethods = user()->mfaValues()->get()->groupBy('method');
$this->setPageTitle(trans('preferences.auth')); $this->setPageTitle(trans('preferences.auth'));

View File

@ -49,6 +49,7 @@ class RolePermissionsTest extends TestCase
$resp = $this->get('/my-account/profile')->assertOk(); $resp = $this->get('/my-account/profile')->assertOk();
$this->withHtml($resp)->assertElementExists('input[name=email][disabled]'); $this->withHtml($resp)->assertElementExists('input[name=email][disabled]');
$resp->assertSee('Unfortunately you don\'t have permission to change your email address.');
$this->put('/my-account/profile', [ $this->put('/my-account/profile', [
'name' => 'my_new_name', 'name' => 'my_new_name',
'email' => 'new_email@example.com', 'email' => 'new_email@example.com',

View File

@ -2,8 +2,13 @@
namespace Tests\User; namespace Tests\User;
use BookStack\Access\Mfa\MfaValue;
use BookStack\Activity\Tools\UserEntityWatchOptions; use BookStack\Activity\Tools\UserEntityWatchOptions;
use BookStack\Activity\WatchLevels; use BookStack\Activity\WatchLevels;
use BookStack\Api\ApiToken;
use BookStack\Uploads\Image;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Tests\TestCase; use Tests\TestCase;
class UserMyAccountTest extends TestCase class UserMyAccountTest extends TestCase
@ -26,6 +31,166 @@ class UserMyAccountTest extends TestCase
$resp->assertRedirect('/'); $resp->assertRedirect('/');
} }
} }
public function test_profile_updating()
{
$editor = $this->users->editor();
$resp = $this->actingAs($editor)->get('/my-account/profile');
$resp->assertSee('Profile Details');
$html = $this->withHtml($resp);
$html->assertFieldHasValue('name', $editor->name);
$html->assertFieldHasValue('email', $editor->email);
$resp = $this->put('/my-account/profile', [
'name' => 'Barryius',
'email' => 'barryius@example.com',
'language' => 'fr',
]);
$resp->assertRedirect('/my-account/profile');
$this->assertDatabaseHas('users', [
'name' => 'Barryius',
'email' => $editor->email, // No email change due to not having permissions
]);
$this->assertEquals(setting()->getUser($editor, 'language'), 'fr');
}
public function test_profile_user_avatar_update_and_reset()
{
$user = $this->users->viewer();
$avatarFile = $this->files->uploadedImage('avatar-icon.png');
$this->assertEquals(0, $user->image_id);
$upload = $this->actingAs($user)->call('PUT', "/my-account/profile", [
'name' => 'Barry Scott',
], [], ['profile_image' => $avatarFile], []);
$upload->assertRedirect('/my-account/profile');
$user->refresh();
$this->assertNotEquals(0, $user->image_id);
/** @var Image $image */
$image = Image::query()->findOrFail($user->image_id);
$this->assertFileExists(public_path($image->path));
$reset = $this->put("/my-account/profile", [
'name' => 'Barry Scott',
'profile_image_reset' => 'true',
]);
$upload->assertRedirect('/my-account/profile');
$user->refresh();
$this->assertFileDoesNotExist(public_path($image->path));
$this->assertEquals(0, $user->image_id);
}
public function test_profile_admin_options_link_shows_if_permissions_allow()
{
$editor = $this->users->editor();
$resp = $this->actingAs($editor)->get('/my-account/profile');
$resp->assertDontSee('Administrator Options');
$this->withHtml($resp)->assertLinkNotExists(url("/settings/users/{$editor->id}"));
$this->permissions->grantUserRolePermissions($editor, ['users-manage']);
$resp = $this->actingAs($editor)->get('/my-account/profile');
$resp->assertSee('Administrator Options');
$this->withHtml($resp)->assertLinkExists(url("/settings/users/{$editor->id}"));
}
public function test_profile_self_delete()
{
$editor = $this->users->editor();
$resp = $this->actingAs($editor)->get('/my-account/profile');
$this->withHtml($resp)->assertLinkExists(url('/my-account/delete'), 'Delete Account');
$resp = $this->get('/my-account/delete');
$resp->assertSee('Delete My Account');
$this->withHtml($resp)->assertElementContains('form[action$="/my-account"] button', 'Confirm');
$resp = $this->delete('/my-account');
$resp->assertRedirect('/');
$this->assertDatabaseMissing('users', ['id' => $editor->id]);
}
public function test_profile_self_delete_shows_ownership_migration_if_can_manage_users()
{
$editor = $this->users->editor();
$resp = $this->actingAs($editor)->get('/my-account/delete');
$resp->assertDontSee('Migrate Ownership');
$this->permissions->grantUserRolePermissions($editor, ['users-manage']);
$resp = $this->actingAs($editor)->get('/my-account/delete');
$resp->assertSee('Migrate Ownership');
}
public function test_auth_password_change()
{
$editor = $this->users->editor();
$resp = $this->actingAs($editor)->get('/my-account/auth');
$resp->assertSee('Change Password');
$this->withHtml($resp)->assertElementExists('form[action$="/my-account/auth/password"]');
$password = Str::random();
$resp = $this->put('/my-account/auth/password', [
'password' => $password,
'password-confirm' => $password,
]);
$resp->assertRedirect('/my-account/auth');
$editor->refresh();
$this->assertTrue(Hash::check($password, $editor->password));
}
public function test_auth_password_change_hides_if_not_using_email_auth()
{
$editor = $this->users->editor();
$resp = $this->actingAs($editor)->get('/my-account/auth');
$resp->assertSee('Change Password');
config()->set('auth.method', 'oidc');
$resp = $this->actingAs($editor)->get('/my-account/auth');
$resp->assertDontSee('Change Password');
}
public function test_auth_page_has_mfa_links()
{
$editor = $this->users->editor();
$resp = $this->actingAs($editor)->get('/my-account/auth');
$resp->assertSee('0 methods configured');
$this->withHtml($resp)->assertLinkExists(url('/mfa/setup'));
MfaValue::upsertWithValue($editor, 'totp', 'testval');
$resp = $this->get('/my-account/auth');
$resp->assertSee('1 method configured');
}
public function test_auth_page_api_tokens()
{
$editor = $this->users->editor();
$resp = $this->actingAs($editor)->get('/my-account/auth');
$resp->assertSee('API Tokens');
$this->withHtml($resp)->assertLinkExists(url("/api-tokens/{$editor->id}/create?context=my-account"));
ApiToken::factory()->create(['user_id' => $editor->id, 'name' => 'My great token']);
$editor->unsetRelations();
$resp = $this->get('/my-account/auth');
$resp->assertSee('My great token');
}
public function test_interface_shortcuts_updating() public function test_interface_shortcuts_updating()
{ {
$this->asEditor(); $this->asEditor();