My Account: Covered profile and auth pages with tests
This commit is contained in:
		
							parent
							
								
									f55e7ca3c9
								
							
						
					
					
						commit
						ce53f641ad
					
				| 
						 | 
					@ -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'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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',
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue