mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-08-07 23:03:00 +03:00
My Account: Updated and started adding to tests
- Updated existing tests now affected by my-account changes. - Updated some existing tests to more accuractly check the scenario. - Updated some code styling in SocialController. - Fixed redirects for social account flows to fit my-account. - Added test for social account attaching. - Added test for api token redirect handling.
This commit is contained in:
@@ -51,7 +51,7 @@ class WebhookCallTest extends TestCase
|
||||
{
|
||||
// This test must not fake the queue/bus since this covers an issue
|
||||
// around handling and serialization of items now deleted from the database.
|
||||
$this->newWebhook(['active' => true, 'endpoint' => 'https://wh.example.com'], ['all']);
|
||||
$webhook = $this->newWebhook(['active' => true, 'endpoint' => 'https://wh.example.com'], ['all']);
|
||||
$this->mockHttpClient([new Response(500)]);
|
||||
|
||||
$user = $this->users->newUser();
|
||||
@@ -61,8 +61,10 @@ class WebhookCallTest extends TestCase
|
||||
/** @var ApiToken $apiToken */
|
||||
$editor = $this->users->editor();
|
||||
$apiToken = ApiToken::factory()->create(['user_id' => $editor]);
|
||||
$resp = $this->delete($editor->getEditUrl('/api-tokens/' . $apiToken->id));
|
||||
$resp->assertRedirect($editor->getEditUrl('#api_tokens'));
|
||||
$this->delete($apiToken->getUrl())->assertRedirect();
|
||||
|
||||
$webhook->refresh();
|
||||
$this->assertEquals('Response status from endpoint was 500', $webhook->last_error);
|
||||
}
|
||||
|
||||
public function test_failed_webhook_call_logs_error()
|
||||
|
@@ -18,7 +18,7 @@ class SocialAuthTest extends TestCase
|
||||
$user = User::factory()->make();
|
||||
|
||||
$this->setSettings(['registration-enabled' => 'true']);
|
||||
config(['GOOGLE_APP_ID' => 'abc123', 'GOOGLE_APP_SECRET' => '123abc', 'APP_URL' => 'http://localhost']);
|
||||
config(['GOOGLE_APP_ID' => 'abc123', 'GOOGLE_APP_SECRET' => '123abc']);
|
||||
|
||||
$mockSocialite = $this->mock(Factory::class);
|
||||
$mockSocialDriver = Mockery::mock(Provider::class);
|
||||
@@ -45,7 +45,6 @@ class SocialAuthTest extends TestCase
|
||||
config([
|
||||
'GOOGLE_APP_ID' => 'abc123', 'GOOGLE_APP_SECRET' => '123abc',
|
||||
'GITHUB_APP_ID' => 'abc123', 'GITHUB_APP_SECRET' => '123abc',
|
||||
'APP_URL' => 'http://localhost',
|
||||
]);
|
||||
|
||||
$mockSocialite = $this->mock(Factory::class);
|
||||
@@ -86,12 +85,41 @@ class SocialAuthTest extends TestCase
|
||||
$this->assertActivityExists(ActivityType::AUTH_LOGIN, null, 'github; (' . $this->users->admin()->id . ') ' . $this->users->admin()->name);
|
||||
}
|
||||
|
||||
public function test_social_account_attach()
|
||||
{
|
||||
config([
|
||||
'GOOGLE_APP_ID' => 'abc123', 'GOOGLE_APP_SECRET' => '123abc',
|
||||
]);
|
||||
$editor = $this->users->editor();
|
||||
|
||||
$mockSocialite = $this->mock(Factory::class);
|
||||
$mockSocialDriver = Mockery::mock(Provider::class);
|
||||
$mockSocialUser = Mockery::mock(\Laravel\Socialite\Contracts\User::class);
|
||||
|
||||
$mockSocialUser->shouldReceive('getId')->twice()->andReturn('logintest123');
|
||||
$mockSocialUser->shouldReceive('getAvatar')->andReturn(null);
|
||||
|
||||
$mockSocialite->shouldReceive('driver')->twice()->with('google')->andReturn($mockSocialDriver);
|
||||
$mockSocialDriver->shouldReceive('redirect')->once()->andReturn(redirect('/login/service/google/callback'));
|
||||
$mockSocialDriver->shouldReceive('user')->once()->andReturn($mockSocialUser);
|
||||
|
||||
// Test login routes
|
||||
$resp = $this->actingAs($editor)->followingRedirects()->get('/login/service/google');
|
||||
$resp->assertSee('Access & Security');
|
||||
|
||||
// Test social callback with matching social account
|
||||
$this->assertDatabaseHas('social_accounts', [
|
||||
'user_id' => $editor->id,
|
||||
'driver' => 'google',
|
||||
'driver_id' => 'logintest123',
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_social_account_detach()
|
||||
{
|
||||
$editor = $this->users->editor();
|
||||
config([
|
||||
'GITHUB_APP_ID' => 'abc123', 'GITHUB_APP_SECRET' => '123abc',
|
||||
'APP_URL' => 'http://localhost',
|
||||
]);
|
||||
|
||||
$socialAccount = SocialAccount::query()->forceCreate([
|
||||
@@ -100,11 +128,11 @@ class SocialAuthTest extends TestCase
|
||||
'driver_id' => 'logintest123',
|
||||
]);
|
||||
|
||||
$resp = $this->actingAs($editor)->get($editor->getEditUrl());
|
||||
$resp = $this->actingAs($editor)->get('/my-account/auth');
|
||||
$this->withHtml($resp)->assertElementContains('form[action$="/login/service/github/detach"]', 'Disconnect Account');
|
||||
|
||||
$resp = $this->post('/login/service/github/detach');
|
||||
$resp->assertRedirect($editor->getEditUrl());
|
||||
$resp->assertRedirect('/my-account/auth#social-accounts');
|
||||
$resp = $this->followRedirects($resp);
|
||||
$resp->assertSee('Github account was successfully disconnected from your profile.');
|
||||
|
||||
@@ -115,7 +143,6 @@ class SocialAuthTest extends TestCase
|
||||
{
|
||||
config([
|
||||
'services.google.client_id' => 'abc123', 'services.google.client_secret' => '123abc',
|
||||
'APP_URL' => 'http://localhost',
|
||||
]);
|
||||
|
||||
$user = User::factory()->make();
|
||||
@@ -153,7 +180,7 @@ class SocialAuthTest extends TestCase
|
||||
{
|
||||
config([
|
||||
'services.google.client_id' => 'abc123', 'services.google.client_secret' => '123abc',
|
||||
'APP_URL' => 'http://localhost', 'services.google.auto_register' => true, 'services.google.auto_confirm' => true,
|
||||
'services.google.auto_register' => true, 'services.google.auto_confirm' => true,
|
||||
]);
|
||||
|
||||
$user = User::factory()->make();
|
||||
@@ -191,7 +218,7 @@ class SocialAuthTest extends TestCase
|
||||
$user = User::factory()->make(['email' => 'nonameuser@example.com']);
|
||||
|
||||
$this->setSettings(['registration-enabled' => 'true']);
|
||||
config(['GITHUB_APP_ID' => 'abc123', 'GITHUB_APP_SECRET' => '123abc', 'APP_URL' => 'http://localhost']);
|
||||
config(['GITHUB_APP_ID' => 'abc123', 'GITHUB_APP_SECRET' => '123abc']);
|
||||
|
||||
$mockSocialite = $this->mock(Factory::class);
|
||||
$mockSocialDriver = Mockery::mock(Provider::class);
|
||||
|
@@ -44,14 +44,12 @@ class RolePermissionsTest extends TestCase
|
||||
|
||||
public function test_user_cannot_change_email_unless_they_have_manage_users_permission()
|
||||
{
|
||||
$userProfileUrl = '/settings/users/' . $this->user->id;
|
||||
$originalEmail = $this->user->email;
|
||||
$this->actingAs($this->user);
|
||||
|
||||
$resp = $this->get($userProfileUrl)
|
||||
->assertOk();
|
||||
$resp = $this->get('/my-account/profile')->assertOk();
|
||||
$this->withHtml($resp)->assertElementExists('input[name=email][disabled]');
|
||||
$this->put($userProfileUrl, [
|
||||
$this->put('/my-account/profile', [
|
||||
'name' => 'my_new_name',
|
||||
'email' => 'new_email@example.com',
|
||||
]);
|
||||
@@ -63,11 +61,12 @@ class RolePermissionsTest extends TestCase
|
||||
|
||||
$this->permissions->grantUserRolePermissions($this->user, ['users-manage']);
|
||||
|
||||
$resp = $this->get($userProfileUrl)
|
||||
->assertOk();
|
||||
$this->withHtml($resp)->assertElementNotExists('input[name=email][disabled]')
|
||||
$resp = $this->get('/my-account/profile')->assertOk();
|
||||
$this->withHtml($resp)
|
||||
->assertElementNotExists('input[name=email][disabled]')
|
||||
->assertElementExists('input[name=email]');
|
||||
$this->put($userProfileUrl, [
|
||||
|
||||
$this->put('/my-account/profile', [
|
||||
'name' => 'my_new_name_2',
|
||||
'email' => 'new_email@example.com',
|
||||
]);
|
||||
|
@@ -607,7 +607,7 @@ class ImageTest extends TestCase
|
||||
$this->actingAs($editor);
|
||||
|
||||
$file = $this->getTestProfileImage();
|
||||
$this->call('PUT', '/settings/users/' . $editor->id, [], [], ['profile_image' => $file], []);
|
||||
$this->call('PUT', '/my-account/profile', [], [], ['profile_image' => $file], []);
|
||||
|
||||
$profileImages = Image::where('type', '=', 'user')->where('created_by', '=', $editor->id)->get();
|
||||
$this->assertTrue($profileImages->count() === 1, 'Found profile images does not match upload count');
|
||||
@@ -615,7 +615,7 @@ class ImageTest extends TestCase
|
||||
$imagePath = public_path($profileImages->first()->path);
|
||||
$this->assertTrue(file_exists($imagePath));
|
||||
|
||||
$userDelete = $this->asAdmin()->delete("/settings/users/{$editor->id}");
|
||||
$userDelete = $this->asAdmin()->delete($editor->getEditUrl());
|
||||
$userDelete->assertStatus(302);
|
||||
|
||||
$this->assertDatabaseMissing('images', [
|
||||
|
@@ -5,25 +5,26 @@ namespace Tests\User;
|
||||
use BookStack\Activity\ActivityType;
|
||||
use BookStack\Api\ApiToken;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Tests\TestCase;
|
||||
|
||||
class UserApiTokenTest extends TestCase
|
||||
{
|
||||
protected $testTokenData = [
|
||||
protected array $testTokenData = [
|
||||
'name' => 'My test API token',
|
||||
'expires_at' => '2050-04-01',
|
||||
];
|
||||
|
||||
public function test_tokens_section_not_visible_without_access_api_permission()
|
||||
public function test_tokens_section_not_visible_in_my_account_without_access_api_permission()
|
||||
{
|
||||
$user = $this->users->viewer();
|
||||
|
||||
$resp = $this->actingAs($user)->get($user->getEditUrl());
|
||||
$resp = $this->actingAs($user)->get('/my-account/auth');
|
||||
$resp->assertDontSeeText('API Tokens');
|
||||
|
||||
$this->permissions->grantUserRolePermissions($user, ['access-api']);
|
||||
|
||||
$resp = $this->actingAs($user)->get($user->getEditUrl());
|
||||
$resp = $this->actingAs($user)->get('/my-account/auth');
|
||||
$resp->assertSeeText('API Tokens');
|
||||
$resp->assertSeeText('Create Token');
|
||||
}
|
||||
@@ -43,14 +44,14 @@ class UserApiTokenTest extends TestCase
|
||||
{
|
||||
$editor = $this->users->editor();
|
||||
|
||||
$resp = $this->asAdmin()->get($editor->getEditUrl('/create-api-token'));
|
||||
$resp = $this->asAdmin()->get("/api-tokens/{$editor->id}/create");
|
||||
$resp->assertStatus(200);
|
||||
$resp->assertSee('Create API Token');
|
||||
$resp->assertSee('Token Secret');
|
||||
|
||||
$resp = $this->post($editor->getEditUrl('/create-api-token'), $this->testTokenData);
|
||||
$resp = $this->post("/api-tokens/{$editor->id}/create", $this->testTokenData);
|
||||
$token = ApiToken::query()->latest()->first();
|
||||
$resp->assertRedirect($editor->getEditUrl('/api-tokens/' . $token->id));
|
||||
$resp->assertRedirect("/api-tokens/{$editor->id}/{$token->id}");
|
||||
$this->assertDatabaseHas('api_tokens', [
|
||||
'user_id' => $editor->id,
|
||||
'name' => $this->testTokenData['name'],
|
||||
@@ -63,7 +64,7 @@ class UserApiTokenTest extends TestCase
|
||||
$this->assertDatabaseMissing('api_tokens', [
|
||||
'secret' => $secret,
|
||||
]);
|
||||
$this->assertTrue(\Hash::check($secret, $token->secret));
|
||||
$this->assertTrue(Hash::check($secret, $token->secret));
|
||||
|
||||
$this->assertTrue(strlen($token->token_id) === 32);
|
||||
$this->assertTrue(strlen($secret) === 32);
|
||||
@@ -75,7 +76,10 @@ class UserApiTokenTest extends TestCase
|
||||
public function test_create_with_no_expiry_sets_expiry_hundred_years_away()
|
||||
{
|
||||
$editor = $this->users->editor();
|
||||
$this->asAdmin()->post($editor->getEditUrl('/create-api-token'), ['name' => 'No expiry token', 'expires_at' => '']);
|
||||
|
||||
$resp = $this->asAdmin()->post("/api-tokens/{$editor->id}/create", ['name' => 'No expiry token', 'expires_at' => '']);
|
||||
$resp->assertRedirect();
|
||||
|
||||
$token = ApiToken::query()->latest()->first();
|
||||
|
||||
$over = Carbon::now()->addYears(101);
|
||||
@@ -89,7 +93,9 @@ class UserApiTokenTest extends TestCase
|
||||
public function test_created_token_displays_on_profile_page()
|
||||
{
|
||||
$editor = $this->users->editor();
|
||||
$this->asAdmin()->post($editor->getEditUrl('/create-api-token'), $this->testTokenData);
|
||||
$resp = $this->asAdmin()->post("/api-tokens/{$editor->id}/create", $this->testTokenData);
|
||||
$resp->assertRedirect();
|
||||
|
||||
$token = ApiToken::query()->latest()->first();
|
||||
|
||||
$resp = $this->get($editor->getEditUrl());
|
||||
@@ -102,28 +108,29 @@ class UserApiTokenTest extends TestCase
|
||||
public function test_secret_shown_once_after_creation()
|
||||
{
|
||||
$editor = $this->users->editor();
|
||||
$resp = $this->asAdmin()->followingRedirects()->post($editor->getEditUrl('/create-api-token'), $this->testTokenData);
|
||||
$resp = $this->asAdmin()->followingRedirects()->post("/api-tokens/{$editor->id}/create", $this->testTokenData);
|
||||
$resp->assertSeeText('Token Secret');
|
||||
|
||||
$token = ApiToken::query()->latest()->first();
|
||||
$this->assertNull(session('api-token-secret:' . $token->id));
|
||||
|
||||
$resp = $this->get($editor->getEditUrl('/api-tokens/' . $token->id));
|
||||
$resp = $this->get("/api-tokens/{$editor->id}/{$token->id}");
|
||||
$resp->assertOk();
|
||||
$resp->assertDontSeeText('Client Secret');
|
||||
}
|
||||
|
||||
public function test_token_update()
|
||||
{
|
||||
$editor = $this->users->editor();
|
||||
$this->asAdmin()->post($editor->getEditUrl('/create-api-token'), $this->testTokenData);
|
||||
$this->asAdmin()->post("/api-tokens/{$editor->id}/create", $this->testTokenData);
|
||||
$token = ApiToken::query()->latest()->first();
|
||||
$updateData = [
|
||||
'name' => 'My updated token',
|
||||
'expires_at' => '2011-01-01',
|
||||
];
|
||||
|
||||
$resp = $this->put($editor->getEditUrl('/api-tokens/' . $token->id), $updateData);
|
||||
$resp->assertRedirect($editor->getEditUrl('/api-tokens/' . $token->id));
|
||||
$resp = $this->put("/api-tokens/{$editor->id}/{$token->id}", $updateData);
|
||||
$resp->assertRedirect("/api-tokens/{$editor->id}/{$token->id}");
|
||||
|
||||
$this->assertDatabaseHas('api_tokens', array_merge($updateData, ['id' => $token->id]));
|
||||
$this->assertSessionHas('success');
|
||||
@@ -133,13 +140,13 @@ class UserApiTokenTest extends TestCase
|
||||
public function test_token_update_with_blank_expiry_sets_to_hundred_years_away()
|
||||
{
|
||||
$editor = $this->users->editor();
|
||||
$this->asAdmin()->post($editor->getEditUrl('/create-api-token'), $this->testTokenData);
|
||||
$this->asAdmin()->post("/api-tokens/{$editor->id}/create", $this->testTokenData);
|
||||
$token = ApiToken::query()->latest()->first();
|
||||
|
||||
$resp = $this->put($editor->getEditUrl('/api-tokens/' . $token->id), [
|
||||
$this->put("/api-tokens/{$editor->id}/{$token->id}", [
|
||||
'name' => 'My updated token',
|
||||
'expires_at' => '',
|
||||
]);
|
||||
])->assertRedirect();
|
||||
$token->refresh();
|
||||
|
||||
$over = Carbon::now()->addYears(101);
|
||||
@@ -153,15 +160,15 @@ class UserApiTokenTest extends TestCase
|
||||
public function test_token_delete()
|
||||
{
|
||||
$editor = $this->users->editor();
|
||||
$this->asAdmin()->post($editor->getEditUrl('/create-api-token'), $this->testTokenData);
|
||||
$this->asAdmin()->post("/api-tokens/{$editor->id}/create", $this->testTokenData);
|
||||
$token = ApiToken::query()->latest()->first();
|
||||
|
||||
$tokenUrl = $editor->getEditUrl('/api-tokens/' . $token->id);
|
||||
$tokenUrl = "/api-tokens/{$editor->id}/{$token->id}";
|
||||
|
||||
$resp = $this->get($tokenUrl . '/delete');
|
||||
$resp->assertSeeText('Delete Token');
|
||||
$resp->assertSeeText($token->name);
|
||||
$this->withHtml($resp)->assertElementExists('form[action="' . $tokenUrl . '"]');
|
||||
$this->withHtml($resp)->assertElementExists('form[action$="' . $tokenUrl . '"]');
|
||||
|
||||
$resp = $this->delete($tokenUrl);
|
||||
$resp->assertRedirect($editor->getEditUrl('#api_tokens'));
|
||||
@@ -175,15 +182,46 @@ class UserApiTokenTest extends TestCase
|
||||
$editor = $this->users->editor();
|
||||
$this->permissions->grantUserRolePermissions($editor, ['users-manage']);
|
||||
|
||||
$this->asAdmin()->post($viewer->getEditUrl('/create-api-token'), $this->testTokenData);
|
||||
$this->asAdmin()->post("/api-tokens/{$viewer->id}/create", $this->testTokenData);
|
||||
$token = ApiToken::query()->latest()->first();
|
||||
|
||||
$resp = $this->actingAs($editor)->get($viewer->getEditUrl('/api-tokens/' . $token->id));
|
||||
$resp = $this->actingAs($editor)->get("/api-tokens/{$viewer->id}/{$token->id}");
|
||||
$resp->assertStatus(200);
|
||||
$resp->assertSeeText('Delete Token');
|
||||
|
||||
$resp = $this->actingAs($editor)->delete($viewer->getEditUrl('/api-tokens/' . $token->id));
|
||||
$resp = $this->actingAs($editor)->delete("/api-tokens/{$viewer->id}/{$token->id}");
|
||||
$resp->assertRedirect($viewer->getEditUrl('#api_tokens'));
|
||||
$this->assertDatabaseMissing('api_tokens', ['id' => $token->id]);
|
||||
}
|
||||
|
||||
public function test_return_routes_change_depending_on_entry_context()
|
||||
{
|
||||
$user = $this->users->admin();
|
||||
$returnByContext = [
|
||||
'settings' => url("/settings/users/{$user->id}/#api_tokens"),
|
||||
'my-account' => url('/my-account/auth#api_tokens'),
|
||||
];
|
||||
|
||||
foreach ($returnByContext as $context => $returnUrl) {
|
||||
$resp = $this->actingAs($user)->get("/api-tokens/{$user->id}/create?context={$context}");
|
||||
$this->withHtml($resp)->assertLinkExists($returnUrl, 'Cancel');
|
||||
|
||||
$this->post("/api-tokens/{$user->id}/create", $this->testTokenData);
|
||||
$token = $user->apiTokens()->latest()->first();
|
||||
|
||||
$resp = $this->get($token->getUrl());
|
||||
$this->withHtml($resp)->assertLinkExists($returnUrl, 'Back');
|
||||
|
||||
$resp = $this->delete($token->getUrl());
|
||||
$resp->assertRedirect($returnUrl);
|
||||
}
|
||||
}
|
||||
|
||||
public function test_context_assumed_for_editing_tokens_of_another_user()
|
||||
{
|
||||
$user = $this->users->viewer();
|
||||
|
||||
$resp = $this->asAdmin()->get("/api-tokens/{$user->id}/create?context=my-account");
|
||||
$this->withHtml($resp)->assertLinkExists($user->getEditUrl('#api_tokens'), 'Cancel');
|
||||
}
|
||||
}
|
||||
|
174
tests/User/UserMyAccountTest.php
Normal file
174
tests/User/UserMyAccountTest.php
Normal file
@@ -0,0 +1,174 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\User;
|
||||
|
||||
use BookStack\Activity\Tools\UserEntityWatchOptions;
|
||||
use BookStack\Activity\WatchLevels;
|
||||
use Tests\TestCase;
|
||||
|
||||
class UserMyAccountTest extends TestCase
|
||||
{
|
||||
public function test_index_view()
|
||||
{
|
||||
$resp = $this->asEditor()->get('/my-account');
|
||||
$resp->assertRedirect('/my-account/profile');
|
||||
}
|
||||
|
||||
public function test_views_not_accessible_to_guest_user()
|
||||
{
|
||||
$categories = ['profile', 'auth', 'shortcuts', 'notifications', ''];
|
||||
$this->setSettings(['app-public' => 'true']);
|
||||
|
||||
$this->permissions->grantUserRolePermissions($this->users->guest(), ['receive-notifications']);
|
||||
|
||||
foreach ($categories as $category) {
|
||||
$resp = $this->get('/my-account/' . $category);
|
||||
$resp->assertRedirect('/');
|
||||
}
|
||||
}
|
||||
public function test_interface_shortcuts_updating()
|
||||
{
|
||||
$this->asEditor();
|
||||
|
||||
// View preferences with defaults
|
||||
$resp = $this->get('/my-account/shortcuts');
|
||||
$resp->assertSee('UI Shortcut Preferences');
|
||||
|
||||
$html = $this->withHtml($resp);
|
||||
$html->assertFieldHasValue('enabled', 'false');
|
||||
$html->assertFieldHasValue('shortcut[home_view]', '1');
|
||||
|
||||
// Update preferences
|
||||
$resp = $this->put('/my-account/shortcuts', [
|
||||
'enabled' => 'true',
|
||||
'shortcut' => ['home_view' => 'Ctrl + 1'],
|
||||
]);
|
||||
|
||||
$resp->assertRedirect('/my-account/shortcuts');
|
||||
$resp->assertSessionHas('success', 'Shortcut preferences have been updated!');
|
||||
|
||||
// View updates to preferences page
|
||||
$resp = $this->get('/my-account/shortcuts');
|
||||
$html = $this->withHtml($resp);
|
||||
$html->assertFieldHasValue('enabled', 'true');
|
||||
$html->assertFieldHasValue('shortcut[home_view]', 'Ctrl + 1');
|
||||
}
|
||||
|
||||
public function test_body_has_shortcuts_component_when_active()
|
||||
{
|
||||
$editor = $this->users->editor();
|
||||
$this->actingAs($editor);
|
||||
|
||||
$this->withHtml($this->get('/'))->assertElementNotExists('body[component="shortcuts"]');
|
||||
|
||||
setting()->putUser($editor, 'ui-shortcuts-enabled', 'true');
|
||||
$this->withHtml($this->get('/'))->assertElementExists('body[component="shortcuts"]');
|
||||
}
|
||||
|
||||
public function test_notification_routes_requires_notification_permission()
|
||||
{
|
||||
$viewer = $this->users->viewer();
|
||||
$resp = $this->actingAs($viewer)->get('/my-account/notifications');
|
||||
$this->assertPermissionError($resp);
|
||||
|
||||
$resp = $this->actingAs($viewer)->get('/my-account/profile');
|
||||
$resp->assertDontSeeText('Notification Preferences');
|
||||
|
||||
$resp = $this->put('/my-account/notifications');
|
||||
$this->assertPermissionError($resp);
|
||||
|
||||
$this->permissions->grantUserRolePermissions($viewer, ['receive-notifications']);
|
||||
$resp = $this->get('/my-account/notifications');
|
||||
$resp->assertOk();
|
||||
$resp->assertSee('Notification Preferences');
|
||||
}
|
||||
|
||||
public function test_notification_preferences_updating()
|
||||
{
|
||||
$editor = $this->users->editor();
|
||||
|
||||
// View preferences with defaults
|
||||
$resp = $this->actingAs($editor)->get('/my-account/notifications');
|
||||
$resp->assertSee('Notification Preferences');
|
||||
|
||||
$html = $this->withHtml($resp);
|
||||
$html->assertFieldHasValue('preferences[comment-replies]', 'false');
|
||||
|
||||
// Update preferences
|
||||
$resp = $this->put('/my-account/notifications', [
|
||||
'preferences' => ['comment-replies' => 'true'],
|
||||
]);
|
||||
|
||||
$resp->assertRedirect('/my-account/notifications');
|
||||
$resp->assertSessionHas('success', 'Notification preferences have been updated!');
|
||||
|
||||
// View updates to preferences page
|
||||
$resp = $this->get('/my-account/notifications');
|
||||
$html = $this->withHtml($resp);
|
||||
$html->assertFieldHasValue('preferences[comment-replies]', 'true');
|
||||
}
|
||||
|
||||
public function test_notification_preferences_show_watches()
|
||||
{
|
||||
$editor = $this->users->editor();
|
||||
$book = $this->entities->book();
|
||||
|
||||
$options = new UserEntityWatchOptions($editor, $book);
|
||||
$options->updateLevelByValue(WatchLevels::COMMENTS);
|
||||
|
||||
$resp = $this->actingAs($editor)->get('/my-account/notifications');
|
||||
$resp->assertSee($book->name);
|
||||
$resp->assertSee('All Page Updates & Comments');
|
||||
|
||||
$options->updateLevelByValue(WatchLevels::DEFAULT);
|
||||
|
||||
$resp = $this->actingAs($editor)->get('/my-account/notifications');
|
||||
$resp->assertDontSee($book->name);
|
||||
$resp->assertDontSee('All Page Updates & Comments');
|
||||
}
|
||||
|
||||
public function test_notification_preferences_dont_error_on_deleted_items()
|
||||
{
|
||||
$editor = $this->users->editor();
|
||||
$book = $this->entities->book();
|
||||
|
||||
$options = new UserEntityWatchOptions($editor, $book);
|
||||
$options->updateLevelByValue(WatchLevels::COMMENTS);
|
||||
|
||||
$this->actingAs($editor)->delete($book->getUrl());
|
||||
$book->refresh();
|
||||
$this->assertNotNull($book->deleted_at);
|
||||
|
||||
$resp = $this->actingAs($editor)->get('/my-account/notifications');
|
||||
$resp->assertOk();
|
||||
$resp->assertDontSee($book->name);
|
||||
}
|
||||
|
||||
public function test_notification_preferences_not_accessible_to_guest()
|
||||
{
|
||||
$this->setSettings(['app-public' => 'true']);
|
||||
$guest = $this->users->guest();
|
||||
$this->permissions->grantUserRolePermissions($guest, ['receive-notifications']);
|
||||
|
||||
$resp = $this->get('/my-account/notifications');
|
||||
$this->assertPermissionError($resp);
|
||||
|
||||
$resp = $this->put('/my-account/notifications', [
|
||||
'preferences' => ['comment-replies' => 'true'],
|
||||
]);
|
||||
$this->assertPermissionError($resp);
|
||||
}
|
||||
|
||||
public function test_notification_comment_options_only_exist_if_comments_active()
|
||||
{
|
||||
$resp = $this->asEditor()->get('/my-account/notifications');
|
||||
$resp->assertSee('Notify upon comments');
|
||||
$resp->assertSee('Notify upon replies');
|
||||
|
||||
setting()->put('app-disable-comments', true);
|
||||
|
||||
$resp = $this->get('/my-account/notifications');
|
||||
$resp->assertDontSee('Notify upon comments');
|
||||
$resp->assertDontSee('Notify upon replies');
|
||||
}
|
||||
}
|
@@ -8,167 +8,6 @@ use Tests\TestCase;
|
||||
|
||||
class UserPreferencesTest extends TestCase
|
||||
{
|
||||
public function test_index_view()
|
||||
{
|
||||
$resp = $this->asEditor()->get('/preferences');
|
||||
$resp->assertOk();
|
||||
$resp->assertSee('Interface Keyboard Shortcuts');
|
||||
$resp->assertSee('Edit Profile');
|
||||
}
|
||||
|
||||
public function test_index_view_accessible_but_without_profile_and_notifications_for_guest_user()
|
||||
{
|
||||
$this->setSettings(['app-public' => 'true']);
|
||||
$this->permissions->grantUserRolePermissions($this->users->guest(), ['receive-notifications']);
|
||||
$resp = $this->get('/preferences');
|
||||
$resp->assertOk();
|
||||
$resp->assertSee('Interface Keyboard Shortcuts');
|
||||
$resp->assertDontSee('Edit Profile');
|
||||
$resp->assertDontSee('Notification');
|
||||
}
|
||||
public function test_interface_shortcuts_updating()
|
||||
{
|
||||
$this->asEditor();
|
||||
|
||||
// View preferences with defaults
|
||||
$resp = $this->get('/preferences/shortcuts');
|
||||
$resp->assertSee('Interface Keyboard Shortcuts');
|
||||
|
||||
$html = $this->withHtml($resp);
|
||||
$html->assertFieldHasValue('enabled', 'false');
|
||||
$html->assertFieldHasValue('shortcut[home_view]', '1');
|
||||
|
||||
// Update preferences
|
||||
$resp = $this->put('/preferences/shortcuts', [
|
||||
'enabled' => 'true',
|
||||
'shortcut' => ['home_view' => 'Ctrl + 1'],
|
||||
]);
|
||||
|
||||
$resp->assertRedirect('/preferences/shortcuts');
|
||||
$resp->assertSessionHas('success', 'Shortcut preferences have been updated!');
|
||||
|
||||
// View updates to preferences page
|
||||
$resp = $this->get('/preferences/shortcuts');
|
||||
$html = $this->withHtml($resp);
|
||||
$html->assertFieldHasValue('enabled', 'true');
|
||||
$html->assertFieldHasValue('shortcut[home_view]', 'Ctrl + 1');
|
||||
}
|
||||
|
||||
public function test_body_has_shortcuts_component_when_active()
|
||||
{
|
||||
$editor = $this->users->editor();
|
||||
$this->actingAs($editor);
|
||||
|
||||
$this->withHtml($this->get('/'))->assertElementNotExists('body[component="shortcuts"]');
|
||||
|
||||
setting()->putUser($editor, 'ui-shortcuts-enabled', 'true');
|
||||
$this->withHtml($this->get('/'))->assertElementExists('body[component="shortcuts"]');
|
||||
}
|
||||
|
||||
public function test_notification_routes_requires_notification_permission()
|
||||
{
|
||||
$viewer = $this->users->viewer();
|
||||
$resp = $this->actingAs($viewer)->get('/preferences/notifications');
|
||||
$this->assertPermissionError($resp);
|
||||
|
||||
$resp = $this->put('/preferences/notifications');
|
||||
$this->assertPermissionError($resp);
|
||||
|
||||
$this->permissions->grantUserRolePermissions($viewer, ['receive-notifications']);
|
||||
$resp = $this->get('/preferences/notifications');
|
||||
$resp->assertOk();
|
||||
$resp->assertSee('Notification Preferences');
|
||||
}
|
||||
|
||||
public function test_notification_preferences_updating()
|
||||
{
|
||||
$editor = $this->users->editor();
|
||||
|
||||
// View preferences with defaults
|
||||
$resp = $this->actingAs($editor)->get('/preferences/notifications');
|
||||
$resp->assertSee('Notification Preferences');
|
||||
|
||||
$html = $this->withHtml($resp);
|
||||
$html->assertFieldHasValue('preferences[comment-replies]', 'false');
|
||||
|
||||
// Update preferences
|
||||
$resp = $this->put('/preferences/notifications', [
|
||||
'preferences' => ['comment-replies' => 'true'],
|
||||
]);
|
||||
|
||||
$resp->assertRedirect('/preferences/notifications');
|
||||
$resp->assertSessionHas('success', 'Notification preferences have been updated!');
|
||||
|
||||
// View updates to preferences page
|
||||
$resp = $this->get('/preferences/notifications');
|
||||
$html = $this->withHtml($resp);
|
||||
$html->assertFieldHasValue('preferences[comment-replies]', 'true');
|
||||
}
|
||||
|
||||
public function test_notification_preferences_show_watches()
|
||||
{
|
||||
$editor = $this->users->editor();
|
||||
$book = $this->entities->book();
|
||||
|
||||
$options = new UserEntityWatchOptions($editor, $book);
|
||||
$options->updateLevelByValue(WatchLevels::COMMENTS);
|
||||
|
||||
$resp = $this->actingAs($editor)->get('/preferences/notifications');
|
||||
$resp->assertSee($book->name);
|
||||
$resp->assertSee('All Page Updates & Comments');
|
||||
|
||||
$options->updateLevelByValue(WatchLevels::DEFAULT);
|
||||
|
||||
$resp = $this->actingAs($editor)->get('/preferences/notifications');
|
||||
$resp->assertDontSee($book->name);
|
||||
$resp->assertDontSee('All Page Updates & Comments');
|
||||
}
|
||||
|
||||
public function test_notification_preferences_dont_error_on_deleted_items()
|
||||
{
|
||||
$editor = $this->users->editor();
|
||||
$book = $this->entities->book();
|
||||
|
||||
$options = new UserEntityWatchOptions($editor, $book);
|
||||
$options->updateLevelByValue(WatchLevels::COMMENTS);
|
||||
|
||||
$this->actingAs($editor)->delete($book->getUrl());
|
||||
$book->refresh();
|
||||
$this->assertNotNull($book->deleted_at);
|
||||
|
||||
$resp = $this->actingAs($editor)->get('/preferences/notifications');
|
||||
$resp->assertOk();
|
||||
$resp->assertDontSee($book->name);
|
||||
}
|
||||
|
||||
public function test_notification_preferences_not_accessible_to_guest()
|
||||
{
|
||||
$this->setSettings(['app-public' => 'true']);
|
||||
$guest = $this->users->guest();
|
||||
$this->permissions->grantUserRolePermissions($guest, ['receive-notifications']);
|
||||
|
||||
$resp = $this->get('/preferences/notifications');
|
||||
$this->assertPermissionError($resp);
|
||||
|
||||
$resp = $this->put('/preferences/notifications', [
|
||||
'preferences' => ['comment-replies' => 'true'],
|
||||
]);
|
||||
$this->assertPermissionError($resp);
|
||||
}
|
||||
|
||||
public function test_notification_comment_options_only_exist_if_comments_active()
|
||||
{
|
||||
$resp = $this->asEditor()->get('/preferences/notifications');
|
||||
$resp->assertSee('Notify upon comments');
|
||||
$resp->assertSee('Notify upon replies');
|
||||
|
||||
setting()->put('app-disable-comments', true);
|
||||
|
||||
$resp = $this->get('/preferences/notifications');
|
||||
$resp->assertDontSee('Notify upon comments');
|
||||
$resp->assertDontSee('Notify upon replies');
|
||||
}
|
||||
|
||||
public function test_update_sort_preference()
|
||||
{
|
||||
$editor = $this->users->editor();
|
||||
|
Reference in New Issue
Block a user