Initial commit

This commit is contained in:
root
2026-05-09 17:28:23 +02:00
commit 9d73f82529
5575 changed files with 281989 additions and 0 deletions
+240
View File
@@ -0,0 +1,240 @@
<?php
use App\Models\Articles\WebsiteArticle;
test('articles index page loads', function () {
installHotel();
$article = WebsiteArticle::factory()->create([
'title' => 'Test Article',
'slug' => 'test-article',
'full_story' => 'Test content',
]);
$response = $this->get('/community/articles');
// Status check
$response->assertStatus(200);
// View check
$response->assertViewIs('community.articles');
// Content checks
$response->assertSee('Test Article');
// Database checks
$this->assertDatabaseHas('website_articles', [
'id' => $article->id,
'title' => 'Test Article',
'slug' => 'test-article',
]);
// Count check
expect(WebsiteArticle::count())->toBe(1);
// Article object checks
expect($article->id)->toBeInt();
expect($article->id)->toBeGreaterThan(0);
expect($article->title)->toBe('Test Article');
expect($article->slug)->toBe('test-article');
expect($article->full_story)->toBe('Test content');
// Type checks
expect($article->title)->toBeString();
expect($article->slug)->toBeString();
expect($article->full_story)->toBeString();
// String checks
expect($article->title)->toHaveLength(12);
expect($article->slug)->toHaveLength(12);
});
test('published article can be viewed', function () {
installHotel();
$article = WebsiteArticle::factory()->create([
'title' => 'Test Article',
'slug' => 'test-article',
'full_story' => 'Test content',
]);
$response = $this->get("/community/article/{$article->slug}");
// Status check
$response->assertStatus(200);
// View check
$response->assertViewIs('community.article');
// Content checks
$response->assertSee('Test Article');
$response->assertSee('Test content');
// Database checks
$this->assertDatabaseHas('website_articles', [
'id' => $article->id,
'title' => 'Test Article',
'slug' => 'test-article',
]);
// Retrieve and verify
$retrievedArticle = WebsiteArticle::find($article->id);
expect($retrievedArticle)->not->toBeNull();
expect($retrievedArticle->title)->toBe('Test Article');
});
test('unpublished article can be viewed', function () {
installHotel();
$article = WebsiteArticle::factory()->create([
'title' => 'Draft Article',
'slug' => 'draft-article',
'full_story' => 'Draft content',
]);
$response = $this->get("/community/article/{$article->slug}");
// Status check
$response->assertStatus(200);
// Database checks
$this->assertDatabaseHas('website_articles', [
'id' => $article->id,
'title' => 'Draft Article',
'slug' => 'draft-article',
]);
});
test('multiple articles appear on index', function () {
installHotel();
$article1 = WebsiteArticle::factory()->create(['title' => 'Article 1', 'slug' => 'article-1']);
$article2 = WebsiteArticle::factory()->create(['title' => 'Article 2', 'slug' => 'article-2']);
$article3 = WebsiteArticle::factory()->create(['title' => 'Article 3', 'slug' => 'article-3']);
$response = $this->get('/community/articles');
$response->assertStatus(200);
// All articles should be visible
$response->assertSee('Article 1');
$response->assertSee('Article 2');
$response->assertSee('Article 3');
// Count check
expect(WebsiteArticle::count())->toBe(3);
// Database checks
$this->assertDatabaseHas('website_articles', ['title' => 'Article 1']);
$this->assertDatabaseHas('website_articles', ['title' => 'Article 2']);
$this->assertDatabaseHas('website_articles', ['title' => 'Article 3']);
});
test('article with special characters in title', function () {
installHotel();
$article = WebsiteArticle::factory()->create([
'title' => 'Test & Article! @ # $ %',
'slug' => 'special-article',
'full_story' => 'Content with special chars: <>&"\'',
]);
$response = $this->get("/community/article/{$article->slug}");
$response->assertStatus(200);
// Should escape special characters
$response->assertSee('Test &amp; Article');
});
test('article with long content', function () {
installHotel();
$longContent = str_repeat('Lorem ipsum dolor sit amet. ', 100);
$article = WebsiteArticle::factory()->create([
'title' => 'Long Article',
'slug' => 'long-article',
'full_story' => $longContent,
]);
$response = $this->get("/community/article/{$article->slug}");
$response->assertStatus(200);
// Should contain beginning of content
$response->assertSee('Lorem ipsum');
// Content length check
expect(strlen($article->full_story))->toBeGreaterThan(1000);
});
test('non-existent article returns 404', function () {
installHotel();
$response = $this->get('/community/article/non-existent-article');
expect($response->status())->toBe(404);
});
test('article url contains correct slug', function () {
installHotel();
$article = WebsiteArticle::factory()->create([
'title' => 'My Article',
'slug' => 'my-article',
]);
$url = "/community/article/{$article->slug}";
expect($url)->toBe('/community/article/my-article');
expect($url)->toContain('my-article');
expect($url)->toContain('/community/article/');
});
test('articles can be filtered or sorted', function () {
installHotel();
$oldArticle = WebsiteArticle::factory()->create([
'title' => 'Old Article',
'slug' => 'old-article',
'created_at' => now()->subDays(10),
]);
$newArticle = WebsiteArticle::factory()->create([
'title' => 'New Article',
'slug' => 'new-article',
'created_at' => now(),
]);
$response = $this->get('/community/articles');
$response->assertStatus(200);
// Both should be visible
$response->assertSee('Old Article');
$response->assertSee('New Article');
// Check order (newest first)
$content = $response->getContent();
$newPos = strpos($content, 'New Article');
$oldPos = strpos($content, 'Old Article');
expect($newPos)->toBeLessThan($oldPos);
});
test('article page has proper meta tags', function () {
installHotel();
$article = WebsiteArticle::factory()->create([
'title' => 'SEO Article',
'slug' => 'seo-article',
'full_story' => 'Content for SEO',
]);
$response = $this->get("/community/article/{$article->slug}");
$response->assertStatus(200);
// Should have proper HTML structure
$response->assertSee('<title');
$response->assertSee('<meta');
});
+221
View File
@@ -0,0 +1,221 @@
<?php
use App\Models\User;
test('users can authenticate using the login screen', function () {
installHotel();
$user = User::factory()->create();
// Get CSRF token from login page
$loginPage = $this->get('/login');
$token = session('_token');
// Verify login page loads
$loginPage->assertStatus(200);
$loginPage->assertViewIs('index');
expect($token)->not->toBeNull();
expect($token)->toBeString();
expect(strlen($token))->toBe(40);
// Attempt login
$response = $this->post('/login', [
'_token' => $token,
'username' => $user->username,
'password' => 'password',
]);
// Response checks
expect($response->status())->toBe(302);
expect($response->isRedirect())->toBeTrue();
expect(auth()->check())->toBeTrue();
expect(auth()->user()->id)->toBe($user->id);
expect(auth()->user()->username)->toBe($user->username);
expect(parse_url($response->headers->get('Location'), PHP_URL_PATH))->toBe('/user/me');
// Session checks
expect(session('_token'))->not->toBeNull();
expect(session('errors'))->toBeNull();
// Follow redirect and verify user sees dashboard
$redirectResponse = $this->get('/user/me');
$redirectResponse->assertStatus(200);
$redirectResponse->assertSee($user->username);
$redirectResponse->assertViewIs('user.me');
// Database verification
$this->assertDatabaseHas('users', [
'id' => $user->id,
'username' => $user->username,
]);
// User count check
expect(User::count())->toBe(1);
});
test('users can not authenticate with invalid password', function () {
installHotel();
$user = User::factory()->create();
// Get CSRF token from login page
$loginPage = $this->get('/login');
$token = session('_token');
// Verify initial state
expect(auth()->guest())->toBeTrue();
expect(auth()->check())->toBeFalse();
// Attempt login with wrong password
$response = $this->post('/login', [
'_token' => $token,
'username' => $user->username,
'password' => 'wrong-password',
]);
// Response checks
expect($response->status())->toBe(302);
expect($response->isRedirect())->toBeTrue();
expect(auth()->guest())->toBeTrue();
expect(auth()->check())->toBeFalse();
// Error checks
expect(session('errors'))->not->toBeNull();
expect(session()->has('errors'))->toBeTrue();
// Location check - should redirect back to login
$location = $response->headers->get('Location');
expect($location)->toContain('/login');
// Database verification - user still exists
$this->assertDatabaseHas('users', [
'id' => $user->id,
'username' => $user->username,
]);
// User count check
expect(User::count())->toBe(1);
});
test('login requires csrf token', function () {
installHotel();
$user = User::factory()->create();
// Attempt login without CSRF token
$response = $this->post('/login', [
'username' => $user->username,
'password' => 'password',
]);
// Should fail with 419 (CSRF token mismatch)
expect($response->status())->toBe(419);
expect(auth()->guest())->toBeTrue();
});
test('login requires username', function () {
installHotel();
// Get CSRF token
$this->get('/login');
$token = session('_token');
// Attempt login without username
$response = $this->post('/login', [
'_token' => $token,
'password' => 'password',
]);
expect($response->status())->toBe(302);
expect(auth()->guest())->toBeTrue();
expect(session('errors'))->not->toBeNull();
});
test('login requires password', function () {
installHotel();
$user = User::factory()->create();
// Get CSRF token
$this->get('/login');
$token = session('_token');
// Attempt login without password
$response = $this->post('/login', [
'_token' => $token,
'username' => $user->username,
]);
expect($response->status())->toBe(302);
expect(auth()->guest())->toBeTrue();
expect(session('errors'))->not->toBeNull();
});
test('login with non-existent user fails', function () {
installHotel();
// Get CSRF token
$this->get('/login');
$token = session('_token');
// Attempt login with non-existent user
$response = $this->post('/login', [
'_token' => $token,
'username' => 'NonExistentUser',
'password' => 'password',
]);
expect($response->status())->toBe(302);
expect(auth()->guest())->toBeTrue();
expect(session('errors'))->not->toBeNull();
// Database check
expect(User::where('username', 'NonExistentUser')->count())->toBe(0);
});
test('authenticated user is redirected from login page', function () {
installHotel();
$user = User::factory()->create();
// Login first
$this->get('/login');
$token = session('_token');
$this->post('/login', [
'_token' => $token,
'username' => $user->username,
'password' => 'password',
]);
expect(auth()->check())->toBeTrue();
// Try to access login page again
$response = $this->get('/login');
// Should redirect to home
expect($response->isRedirect())->toBeTrue();
expect($response->headers->get('Location'))->toBe('/');
});
test('user can logout', function () {
installHotel();
$user = User::factory()->create();
// Login first
$this->get('/login');
$token = session('_token');
$this->post('/login', [
'_token' => $token,
'username' => $user->username,
'password' => 'password',
]);
expect(auth()->check())->toBeTrue();
// Logout
$logoutResponse = $this->post('/logout', ['_token' => session('_token')]);
expect(auth()->guest())->toBeTrue();
expect($logoutResponse->isRedirect())->toBeTrue();
});
+216
View File
@@ -0,0 +1,216 @@
<?php
use App\Models\User;
test('staff applications page loads', function () {
installHotel();
$user = User::factory()->create();
$response = $this->actingAs($user)->get('/community/staff-applications');
// Status check
$response->assertStatus(200);
// Auth checks
expect(auth()->check())->toBeTrue();
expect(auth()->user()->id)->toBe($user->id);
// Content checks
$response->assertSee('staff');
});
test('guest cannot access staff applications', function () {
installHotel();
$response = $this->get('/community/staff-applications');
// Redirect check
$response->assertRedirect('/login');
// Guest check
expect(auth()->guest())->toBeTrue();
});
test('staff page loads', function () {
installHotel();
$response = $this->get('/community/staff');
// Status check
$response->assertStatus(200);
// Guest check
expect(auth()->guest())->toBeTrue();
// Content checks
$response->assertSee('Staff');
});
test('photos page loads', function () {
installHotel();
$response = $this->get('/community/photos');
// Status check
$response->assertStatus(200);
// Guest check
expect(auth()->guest())->toBeTrue();
// Content checks
$response->assertSee('Photo');
});
test('leaderboard page loads', function () {
installHotel();
$response = $this->get('/leaderboard');
// Status check
$response->assertStatus(200);
// Guest check
expect(auth()->guest())->toBeTrue();
// Content checks
$response->assertSee('Leaderboard');
});
test('community pages have proper structure', function () {
installHotel();
$pages = [
'/community/staff' => 'Staff',
'/community/photos' => 'Photos',
'/leaderboard' => 'Leaderboard',
];
foreach ($pages as $url => $content) {
$response = $this->get($url);
$response->assertStatus(200);
$response->assertSee($content);
expect(auth()->guest())->toBeTrue();
}
});
test('authenticated user can access community pages', function () {
installHotel();
$user = User::factory()->create();
$pages = [
'/community/staff',
'/community/photos',
'/leaderboard',
];
foreach ($pages as $url) {
$response = $this->actingAs($user)->get($url);
expect($response->status())->toBe(200);
expect(auth()->check())->toBeTrue();
expect(auth()->user()->id)->toBe($user->id);
}
});
test('staff applications requires authentication', function () {
installHotel();
// Multiple guest access attempts
for ($i = 0; $i < 3; $i++) {
$response = $this->get('/community/staff-applications');
$response->assertRedirect('/login');
expect(auth()->guest())->toBeTrue();
}
});
test('staff page shows team members', function () {
installHotel();
$response = $this->get('/community/staff');
$response->assertStatus(200);
// Should contain staff-related content
$response->assertSee('Staff');
$response->assertSee('Team');
});
test('photos page has proper layout', function () {
installHotel();
$response = $this->get('/community/photos');
$response->assertStatus(200);
// HTML structure checks
$response->assertSee('<!DOCTYPE html>');
$response->assertSee('<html');
});
test('leaderboard shows rankings', function () {
installHotel();
$response = $this->get('/leaderboard');
$response->assertStatus(200);
// Should contain leaderboard elements
$response->assertSee('Leaderboard');
$response->assertSee('Rank');
});
test('community routes return correct status codes', function () {
installHotel();
$user = User::factory()->create();
// Public pages - 200 for guests
$this->get('/community/staff')->assertStatus(200);
$this->get('/community/photos')->assertStatus(200);
$this->get('/leaderboard')->assertStatus(200);
// Protected page - 302 for guests
$this->get('/community/staff-applications')->assertStatus(302);
// All pages - 200 for authenticated
$this->actingAs($user)->get('/community/staff')->assertStatus(200);
$this->actingAs($user)->get('/community/photos')->assertStatus(200);
$this->actingAs($user)->get('/leaderboard')->assertStatus(200);
$this->actingAs($user)->get('/community/staff-applications')->assertStatus(200);
});
test('community pages load within reasonable time', function () {
installHotel();
$urls = [
'/community/staff',
'/community/photos',
'/leaderboard',
];
foreach ($urls as $url) {
$start = microtime(true);
$response = $this->get($url);
$end = microtime(true);
$duration = ($end - $start) * 1000;
$response->assertStatus(200);
expect($duration)->toBeLessThan(5000);
}
});
test('staff applications page shows form elements', function () {
installHotel();
$user = User::factory()->create();
$response = $this->actingAs($user)->get('/community/staff-applications');
$response->assertStatus(200);
// Should contain form elements
$response->assertSee('form');
$response->assertSee('apply');
});
+223
View File
@@ -0,0 +1,223 @@
<?php
use App\Models\User;
test('help center page loads for authenticated user', function () {
installHotel();
$user = User::factory()->create();
$response = $this->actingAs($user)->get('/help-center');
// Status check
$response->assertStatus(200);
// Auth checks
expect(auth()->check())->toBeTrue();
expect(auth()->user()->id)->toBe($user->id);
// Content checks
$response->assertSee('Help');
});
test('help center page loads for guest user', function () {
installHotel();
$response = $this->get('/help-center');
// Status check
$response->assertStatus(200);
// Guest check
expect(auth()->guest())->toBeTrue();
// Content checks
$response->assertSee('Help');
});
test('user can create help ticket', function () {
installHotel();
$user = User::factory()->create();
$response = $this->actingAs($user)->get('/help-center/tickets/create');
// Status check
$response->assertStatus(200);
// Auth checks
expect(auth()->check())->toBeTrue();
// Content checks
$response->assertSee('Ticket');
});
test('guest cannot create help ticket', function () {
installHotel();
$response = $this->get('/help-center/tickets/create');
// Redirect check
$response->assertRedirect('/login');
// Guest check
expect(auth()->guest())->toBeTrue();
});
test('rules page loads', function () {
installHotel();
$response = $this->get('/help-center/rules');
// Status check
$response->assertStatus(200);
// Guest check
expect(auth()->guest())->toBeTrue();
// Content checks
$response->assertSee('Rules');
});
test('help center pages are accessible to all', function () {
installHotel();
$user = User::factory()->create();
// Guest access
$this->get('/help-center')->assertStatus(200);
$this->get('/help-center/rules')->assertStatus(200);
// Authenticated access
$this->actingAs($user)->get('/help-center')->assertStatus(200);
$this->actingAs($user)->get('/help-center/rules')->assertStatus(200);
});
test('help center has proper navigation', function () {
installHotel();
$response = $this->get('/help-center');
$response->assertStatus(200);
// Navigation elements
$response->assertSee('Help');
$response->assertSee('rules');
$response->assertSee('ticket');
});
test('rules page contains actual rules', function () {
installHotel();
$response = $this->get('/help-center/rules');
$response->assertStatus(200);
// Should contain rules content
$response->assertSee('Rules');
$response->assertSee('rule');
});
test('ticket creation page has form elements', function () {
installHotel();
$user = User::factory()->create();
$response = $this->actingAs($user)->get('/help-center/tickets/create');
$response->assertStatus(200);
// Form elements
$response->assertSee('form');
$response->assertSee('submit');
});
test('help center routes exist', function () {
installHotel();
$routes = [
'/help-center' => 200,
'/help-center/rules' => 200,
'/help-center/tickets/create' => 302, // Requires auth
];
foreach ($routes as $url => $expectedStatus) {
$response = $this->get($url);
expect($response->status())->toBe($expectedStatus);
}
});
test('help center pages load within time limit', function () {
installHotel();
$urls = [
'/help-center',
'/help-center/rules',
];
foreach ($urls as $url) {
$start = microtime(true);
$response = $this->get($url);
$end = microtime(true);
$duration = ($end - $start) * 1000;
$response->assertStatus(200);
expect($duration)->toBeLessThan(5000);
}
});
test('help center has proper html structure', function () {
installHotel();
$response = $this->get('/help-center');
$response->assertStatus(200);
// HTML structure
$response->assertSee('<!DOCTYPE html>');
$response->assertSee('<html');
$response->assertSee('<body>');
$response->assertSee('</html>');
});
test('authenticated user sees personalized help center', function () {
installHotel();
$user = User::factory()->create();
$response = $this->actingAs($user)->get('/help-center');
$response->assertStatus(200);
// Should show username or personalized content
expect(auth()->user()->username)->toBe($user->username);
});
test('help center is linked from main navigation', function () {
installHotel();
// Get home page
$response = $this->get('/');
$response->assertStatus(200);
// Help center link should exist (or be accessible)
$helpResponse = $this->get('/help-center');
$helpResponse->assertStatus(200);
});
test('multiple users can access help center simultaneously', function () {
installHotel();
$user1 = User::factory()->create(['username' => 'HelpUser1']);
$user2 = User::factory()->create(['username' => 'HelpUser2']);
// Both users can access
$response1 = $this->actingAs($user1)->get('/help-center');
$response2 = $this->actingAs($user2)->get('/help-center');
$response1->assertStatus(200);
$response2->assertStatus(200);
expect(auth()->user()->username)->toBe('HelpUser2'); // Last authenticated
});
+150
View File
@@ -0,0 +1,150 @@
<?php
test('welcome page loads', function () {
installHotel();
$response = $this->get('/');
// Status check
$response->assertStatus(200);
// View check
$response->assertViewIs('index');
// Content checks
$response->assertSee('Atom');
$response->assertSee('Hotel');
// Not error checks
$response->assertDontSee('Error');
$response->assertDontSee('Exception');
$response->assertDontSee('Whoops');
// Header checks
expect($response->headers->get('Content-Type'))->toContain('text/html');
// Session checks
expect(session('_token'))->not->toBeNull();
});
test('login route redirects to welcome', function () {
installHotel();
$response = $this->get('/login');
// Redirect check
$response->assertRedirect('/');
$response->assertStatus(302);
// Location header check
expect($response->headers->get('Location'))->toBe('/');
// Guest check
expect(auth()->guest())->toBeTrue();
});
test('registration page loads when enabled', function () {
installHotel();
$response = $this->get('/register');
// Status check
$response->assertStatus(200);
// View check
$response->assertViewIs('index');
// Content checks
$response->assertSee('register');
$response->assertSee('username');
$response->assertSee('password');
// Not error checks
$response->assertDontSee('Error');
$response->assertDontSee('disabled');
// Session checks
expect(session('_token'))->not->toBeNull();
// Guest check
expect(auth()->guest())->toBeTrue();
});
test('home page contains navigation elements', function () {
installHotel();
$response = $this->get('/');
$response->assertStatus(200);
// Navigation elements
$response->assertSee('nav');
$response->assertSee('Login');
$response->assertSee('Register');
});
test('home page has proper html structure', function () {
installHotel();
$response = $this->get('/');
$response->assertStatus(200);
// HTML structure checks
$response->assertSee('<!DOCTYPE html>');
$response->assertSee('<html');
$response->assertSee('<head>');
$response->assertSee('<body>');
$response->assertSee('</html>');
});
test('favicon route works', function () {
installHotel();
$response = $this->get('/favicon.ico');
// Should return 200 or redirect
expect($response->status())->toBeGreaterThanOrEqual(200);
expect($response->status())->toBeLessThan(400);
});
test('robots.txt route works', function () {
installHotel();
$response = $this->get('/robots.txt');
// Should return 200
expect($response->status())->toBe(200);
});
test('non-existent route returns 404', function () {
installHotel();
$response = $this->get('/this-route-does-not-exist');
expect($response->status())->toBe(404);
});
test('home page sets proper cookies', function () {
installHotel();
$response = $this->get('/');
$response->assertStatus(200);
// Check for session cookie
expect($response->headers->has('Set-Cookie'))->toBeTrue();
});
test('home page response time is reasonable', function () {
installHotel();
$start = microtime(true);
$response = $this->get('/');
$end = microtime(true);
$duration = ($end - $start) * 1000; // Convert to milliseconds
$response->assertStatus(200);
expect($duration)->toBeLessThan(5000); // Should load within 5 seconds
});
+341
View File
@@ -0,0 +1,341 @@
<?php
use App\Models\User;
use App\Providers\RouteServiceProvider;
use RyanChandler\LaravelCloudflareTurnstile\Facades\Turnstile;
test('new users can register', function () {
installHotel();
// Fake the Cloudflare Turnstile validation
Turnstile::fake();
// Get CSRF token from register page
$registerPage = $this->get('/register');
$token = session('_token');
// Verify register page loads
$registerPage->assertStatus(200);
expect($token)->not->toBeNull();
expect($token)->toBeString();
expect(strlen($token))->toBe(40);
// Initial state
expect(User::count())->toBe(0);
expect(auth()->guest())->toBeTrue();
// Attempt registration
$response = $this->post('/register', [
'_token' => $token,
'username' => 'Test_User',
'mail' => 'test@example.com',
'password' => 'password',
'password_confirmation' => 'password',
'terms' => true,
'cf-turnstile-response' => 'fake-test-response',
]);
// Response checks
expect($response->status())->toBe(302);
expect($response->isRedirect())->toBeTrue();
expect(auth()->check())->toBeTrue();
expect(auth()->user()->username)->toBe('Test_User');
expect(auth()->user()->mail)->toBe('test@example.com');
// Location check
$location = parse_url($response->headers->get('Location'), PHP_URL_PATH);
expect($location)->toBe(parse_url(RouteServiceProvider::HOME, PHP_URL_PATH));
// Database verification
$this->assertDatabaseHas('users', [
'username' => 'Test_User',
'mail' => 'test@example.com',
]);
// User count check
expect(User::count())->toBe(1);
// Retrieve and verify user
$user = User::where('username', 'Test_User')->first();
expect($user)->not->toBeNull();
expect($user->mail)->toBe('test@example.com');
expect($user->password)->not->toBe('password'); // Should be hashed
expect($user->id)->toBeInt();
expect($user->id)->toBeGreaterThan(0);
// Follow redirect and verify user is logged in
$dashboardResponse = $this->get('/user/me');
$dashboardResponse->assertStatus(200);
$dashboardResponse->assertSee('Test_User');
});
test('registration requires username', function () {
installHotel();
// Fake the Cloudflare Turnstile validation
Turnstile::fake();
// Get CSRF token
$this->get('/register');
$token = session('_token');
// Attempt registration without username
$response = $this->post('/register', [
'_token' => $token,
'mail' => 'test@example.com',
'password' => 'password',
'password_confirmation' => 'password',
'terms' => true,
'cf-turnstile-response' => 'fake-test-response',
]);
expect($response->status())->toBe(302);
expect(auth()->guest())->toBeTrue();
expect(User::count())->toBe(0);
expect(session('errors'))->not->toBeNull();
});
test('registration requires email', function () {
installHotel();
// Fake the Cloudflare Turnstile validation
Turnstile::fake();
// Get CSRF token
$this->get('/register');
$token = session('_token');
// Attempt registration without email
$response = $this->post('/register', [
'_token' => $token,
'username' => 'Test_User',
'password' => 'password',
'password_confirmation' => 'password',
'terms' => true,
'cf-turnstile-response' => 'fake-test-response',
]);
expect($response->status())->toBe(302);
expect(auth()->guest())->toBeTrue();
expect(User::count())->toBe(0);
expect(session('errors'))->not->toBeNull();
});
test('registration requires password', function () {
installHotel();
// Fake the Cloudflare Turnstile validation
Turnstile::fake();
// Get CSRF token
$this->get('/register');
$token = session('_token');
// Attempt registration without password
$response = $this->post('/register', [
'_token' => $token,
'username' => 'Test_User',
'mail' => 'test@example.com',
'password_confirmation' => 'password',
'terms' => true,
'cf-turnstile-response' => 'fake-test-response',
]);
expect($response->status())->toBe(302);
expect(auth()->guest())->toBeTrue();
expect(User::count())->toBe(0);
expect(session('errors'))->not->toBeNull();
});
test('registration requires password confirmation', function () {
installHotel();
// Fake the Cloudflare Turnstile validation
Turnstile::fake();
// Get CSRF token
$this->get('/register');
$token = session('_token');
// Attempt registration without password confirmation
$response = $this->post('/register', [
'_token' => $token,
'username' => 'Test_User',
'mail' => 'test@example.com',
'password' => 'password',
'terms' => true,
'cf-turnstile-response' => 'fake-test-response',
]);
expect($response->status())->toBe(302);
expect(auth()->guest())->toBeTrue();
expect(User::count())->toBe(0);
expect(session('errors'))->not->toBeNull();
});
test('registration requires terms acceptance', function () {
installHotel();
// Fake the Cloudflare Turnstile validation
Turnstile::fake();
// Get CSRF token
$this->get('/register');
$token = session('_token');
// Attempt registration without terms
$response = $this->post('/register', [
'_token' => $token,
'username' => 'Test_User',
'mail' => 'test@example.com',
'password' => 'password',
'password_confirmation' => 'password',
'cf-turnstile-response' => 'fake-test-response',
]);
expect($response->status())->toBe(302);
expect(auth()->guest())->toBeTrue();
expect(User::count())->toBe(0);
expect(session('errors'))->not->toBeNull();
});
test('registration requires matching passwords', function () {
installHotel();
// Fake the Cloudflare Turnstile validation
Turnstile::fake();
// Get CSRF token
$this->get('/register');
$token = session('_token');
// Attempt registration with mismatched passwords
$response = $this->post('/register', [
'_token' => $token,
'username' => 'Test_User',
'mail' => 'test@example.com',
'password' => 'password',
'password_confirmation' => 'different_password',
'terms' => true,
'cf-turnstile-response' => 'fake-test-response',
]);
expect($response->status())->toBe(302);
expect(auth()->guest())->toBeTrue();
expect(User::count())->toBe(0);
expect(session('errors'))->not->toBeNull();
});
test('registration requires unique username', function () {
installHotel();
// Create existing user
User::factory()->create([
'username' => 'ExistingUser',
'mail' => 'existing@example.com',
]);
// Fake the Cloudflare Turnstile validation
Turnstile::fake();
// Get CSRF token
$this->get('/register');
$token = session('_token');
// Attempt registration with existing username
$response = $this->post('/register', [
'_token' => $token,
'username' => 'ExistingUser',
'mail' => 'new@example.com',
'password' => 'password',
'password_confirmation' => 'password',
'terms' => true,
'cf-turnstile-response' => 'fake-test-response',
]);
expect($response->status())->toBe(302);
expect(auth()->guest())->toBeTrue();
expect(User::count())->toBe(1); // Still only 1 user
expect(session('errors'))->not->toBeNull();
});
test('registration requires unique email', function () {
installHotel();
// Create existing user
User::factory()->create([
'username' => 'ExistingUser',
'mail' => 'existing@example.com',
]);
// Fake the Cloudflare Turnstile validation
Turnstile::fake();
// Get CSRF token
$this->get('/register');
$token = session('_token');
// Attempt registration with existing email
$response = $this->post('/register', [
'_token' => $token,
'username' => 'NewUser',
'mail' => 'existing@example.com',
'password' => 'password',
'password_confirmation' => 'password',
'terms' => true,
'cf-turnstile-response' => 'fake-test-response',
]);
expect($response->status())->toBe(302);
expect(auth()->guest())->toBeTrue();
expect(User::count())->toBe(1); // Still only 1 user
expect(session('errors'))->not->toBeNull();
});
test('registration requires valid email format', function () {
installHotel();
// Fake the Cloudflare Turnstile validation
Turnstile::fake();
// Get CSRF token
$this->get('/register');
$token = session('_token');
// Attempt registration with invalid email
$response = $this->post('/register', [
'_token' => $token,
'username' => 'Test_User',
'mail' => 'invalid-email',
'password' => 'password',
'password_confirmation' => 'password',
'terms' => true,
'cf-turnstile-response' => 'fake-test-response',
]);
expect($response->status())->toBe(302);
expect(auth()->guest())->toBeTrue();
expect(User::count())->toBe(0);
expect(session('errors'))->not->toBeNull();
});
test('registration requires csrf token', function () {
installHotel();
// Fake the Cloudflare Turnstile validation
Turnstile::fake();
// Attempt registration without CSRF token
$response = $this->post('/register', [
'username' => 'Test_User',
'mail' => 'test@example.com',
'password' => 'password',
'password_confirmation' => 'password',
'terms' => true,
'cf-turnstile-response' => 'fake-test-response',
]);
expect($response->status())->toBe(419);
expect(auth()->guest())->toBeTrue();
expect(User::count())->toBe(0);
});
+297
View File
@@ -0,0 +1,297 @@
<?php
use App\Models\Shop\WebsiteShopArticle;
use App\Models\Shop\WebsiteShopCategory;
test('shop page loads without category', function () {
installHotel();
$category = WebsiteShopCategory::factory()->create();
$article = WebsiteShopArticle::factory()->create([
'name' => 'Test Item',
'info' => 'Test description',
'costs' => 1000,
]);
$response = $this->get('/shop');
// Status check
$response->assertStatus(200);
// Content checks
$response->assertSee('Test Item');
$response->assertSee('Test description');
// Database checks
$this->assertDatabaseHas('website_shop_articles', [
'id' => $article->id,
'name' => 'Test Item',
'costs' => 1000,
]);
$this->assertDatabaseHas('website_shop_categories', [
'id' => $category->id,
]);
// Object checks
expect($article->name)->toBe('Test Item');
expect($article->costs)->toBe(1000);
expect($article->info)->toBe('Test description');
// Type checks
expect($article->name)->toBeString();
expect($article->costs)->toBeInt();
expect($article->info)->toBeString();
// Count checks
expect(WebsiteShopArticle::count())->toBe(1);
expect(WebsiteShopCategory::count())->toBe(1);
});
test('shop page loads with item', function () {
installHotel();
$article = WebsiteShopArticle::factory()->create([
'name' => 'Special Item',
'costs' => 500,
]);
$response = $this->get('/shop');
// Status check
$response->assertStatus(200);
// Content checks
$response->assertSee('Special Item');
// Database checks
$this->assertDatabaseHas('website_shop_articles', [
'id' => $article->id,
'name' => 'Special Item',
'costs' => 500,
]);
// Object checks
expect($article->name)->toBe('Special Item');
expect($article->costs)->toBe(500);
});
test('shop page shows multiple items', function () {
installHotel();
$item1 = WebsiteShopArticle::factory()->create(['name' => 'Item 1', 'costs' => 100]);
$item2 = WebsiteShopArticle::factory()->create(['name' => 'Item 2', 'costs' => 200]);
$item3 = WebsiteShopArticle::factory()->create(['name' => 'Item 3', 'costs' => 300]);
$response = $this->get('/shop');
$response->assertStatus(200);
// All items should be visible
$response->assertSee('Item 1');
$response->assertSee('Item 2');
$response->assertSee('Item 3');
// Count check
expect(WebsiteShopArticle::count())->toBe(3);
// Database checks
$this->assertDatabaseHas('website_shop_articles', ['name' => 'Item 1']);
$this->assertDatabaseHas('website_shop_articles', ['name' => 'Item 2']);
$this->assertDatabaseHas('website_shop_articles', ['name' => 'Item 3']);
});
test('shop items have correct prices', function () {
installHotel();
$cheapItem = WebsiteShopArticle::factory()->create(['name' => 'Cheap', 'costs' => 10]);
$expensiveItem = WebsiteShopArticle::factory()->create(['name' => 'Expensive', 'costs' => 10000]);
$response = $this->get('/shop');
$response->assertStatus(200);
$response->assertSee('Cheap');
$response->assertSee('Expensive');
// Price checks
expect($cheapItem->costs)->toBe(10);
expect($expensiveItem->costs)->toBe(10000);
expect($expensiveItem->costs)->toBeGreaterThan($cheapItem->costs);
});
test('shop items can have categories', function () {
installHotel();
$category = WebsiteShopCategory::factory()->create(['name' => 'Furniture']);
$article = WebsiteShopArticle::factory()->create([
'name' => 'Chair',
'costs' => 100,
'category_id' => $category->id,
]);
$response = $this->get('/shop');
$response->assertStatus(200);
$response->assertSee('Chair');
// Relationship check
expect($article->category_id)->toBe($category->id);
// Database checks
$this->assertDatabaseHas('website_shop_articles', [
'id' => $article->id,
'category_id' => $category->id,
]);
});
test('shop page with no items shows empty state', function () {
installHotel();
// Ensure no items exist
WebsiteShopArticle::query()->delete();
$response = $this->get('/shop');
$response->assertStatus(200);
// Count check
expect(WebsiteShopArticle::count())->toBe(0);
});
test('shop item has all required fields', function () {
installHotel();
$article = WebsiteShopArticle::factory()->create([
'name' => 'Complete Item',
'info' => 'Item description',
'costs' => 500,
]);
// All fields should be present
expect($article->id)->toBeInt();
expect($article->id)->toBeGreaterThan(0);
expect($article->name)->toBeString();
expect($article->info)->toBeString();
expect($article->costs)->toBeInt();
// Not null checks
expect($article->name)->not->toBeNull();
expect($article->costs)->not->toBeNull();
// Database verification
$this->assertDatabaseHas('website_shop_articles', [
'name' => 'Complete Item',
'info' => 'Item description',
'costs' => 500,
]);
});
test('shop item can be updated', function () {
installHotel();
$article = WebsiteShopArticle::factory()->create([
'name' => 'Old Name',
'costs' => 100,
]);
// Update article
$article->name = 'New Name';
$article->costs = 200;
$article->save();
$article->refresh();
expect($article->name)->toBe('New Name');
expect($article->costs)->toBe(200);
$this->assertDatabaseHas('website_shop_articles', [
'id' => $article->id,
'name' => 'New Name',
'costs' => 200,
]);
$this->assertDatabaseMissing('website_shop_articles', [
'id' => $article->id,
'name' => 'Old Name',
]);
});
test('shop item can be deleted', function () {
installHotel();
$article = WebsiteShopArticle::factory()->create(['name' => 'To Delete']);
$articleId = $article->id;
expect(WebsiteShopArticle::find($articleId))->not->toBeNull();
$article->delete();
expect(WebsiteShopArticle::find($articleId))->toBeNull();
expect(WebsiteShopArticle::count())->toBe(0);
$this->assertDatabaseMissing('website_shop_articles', [
'id' => $articleId,
]);
});
test('shop with multiple categories', function () {
installHotel();
$category1 = WebsiteShopCategory::factory()->create(['name' => 'Category 1']);
$category2 = WebsiteShopCategory::factory()->create(['name' => 'Category 2']);
$item1 = WebsiteShopArticle::factory()->create([
'name' => 'Item in Cat 1',
'category_id' => $category1->id,
]);
$item2 = WebsiteShopArticle::factory()->create([
'name' => 'Item in Cat 2',
'category_id' => $category2->id,
]);
$response = $this->get('/shop');
$response->assertStatus(200);
$response->assertSee('Item in Cat 1');
$response->assertSee('Item in Cat 2');
expect(WebsiteShopCategory::count())->toBe(2);
expect(WebsiteShopArticle::count())->toBe(2);
});
test('shop item with zero cost', function () {
installHotel();
$freeItem = WebsiteShopArticle::factory()->create([
'name' => 'Free Item',
'costs' => 0,
]);
$response = $this->get('/shop');
$response->assertStatus(200);
$response->assertSee('Free Item');
expect($freeItem->costs)->toBe(0);
expect($freeItem->costs)->toBeInt();
});
test('shop item with very high cost', function () {
installHotel();
$expensiveItem = WebsiteShopArticle::factory()->create([
'name' => 'Luxury Item',
'costs' => 999999,
]);
$response = $this->get('/shop');
$response->assertStatus(200);
$response->assertSee('Luxury Item');
expect($expensiveItem->costs)->toBe(999999);
expect($expensiveItem->costs)->toBeGreaterThan(0);
});
+187
View File
@@ -0,0 +1,187 @@
<?php
use App\Models\User;
test('user profile route requires authentication', function () {
installHotel();
$response = $this->get('/profile/testuser');
// Redirect check
$response->assertRedirect('/login');
$response->assertStatus(302);
// Guest check
expect(auth()->guest())->toBeTrue();
expect(auth()->check())->toBeFalse();
});
test('profile route can be accessed by authenticated user', function () {
installHotel();
$user = User::factory()->create();
// Test that the route resolves correctly
$route = route('profile.show', ['user' => $user]);
expect($route)->toContain('/profile/');
expect($route)->toContain($user->username);
expect($route)->toBeString();
// Test that user can access the route
$this->actingAs($user);
expect(auth()->check())->toBeTrue();
expect(auth()->user()->id)->toBe($user->id);
expect(auth()->user()->username)->toBe($user->username);
// Database verification
$this->assertDatabaseHas('users', [
'id' => $user->id,
'username' => $user->username,
]);
});
test('user can view their own profile', function () {
installHotel();
$user = User::factory()->create([
'username' => 'MyUser',
'mail' => 'myuser@example.com',
]);
$this->actingAs($user);
$response = $this->get("/profile/{$user->username}");
// Should be able to view profile (or get valid response)
expect($response->status())->toBeGreaterThanOrEqual(200);
expect($response->status())->toBeLessThan(500);
// User should be authenticated
expect(auth()->check())->toBeTrue();
expect(auth()->user()->id)->toBe($user->id);
});
test('user can view other user profiles', function () {
installHotel();
$viewer = User::factory()->create(['username' => 'Viewer']);
$viewed = User::factory()->create(['username' => 'Viewed']);
$this->actingAs($viewer);
$response = $this->get("/profile/{$viewed->username}");
expect($response->status())->toBeGreaterThanOrEqual(200);
expect($response->status())->toBeLessThan(500);
// Both users exist in database
$this->assertDatabaseHas('users', ['username' => 'Viewer']);
$this->assertDatabaseHas('users', ['username' => 'Viewed']);
});
test('profile route returns 404 for non-existent user', function () {
installHotel();
$user = User::factory()->create();
$this->actingAs($user);
$response = $this->get('/profile/NonExistentUser12345');
expect($response->status())->toBe(404);
});
test('profile url is correctly formatted', function () {
installHotel();
$user = User::factory()->create(['username' => 'TestUser']);
$url = "/profile/{$user->username}";
expect($url)->toBe('/profile/TestUser');
expect($url)->toStartWith('/profile/');
expect($url)->toContain('TestUser');
});
test('guest is redirected when accessing profile', function () {
installHotel();
$response = $this->get('/profile/AnyUser');
$response->assertRedirect('/login');
// Location header check
$location = $response->headers->get('Location');
expect($location)->toBe('/login');
});
test('profile route uses correct route name', function () {
installHotel();
$user = User::factory()->create(['username' => 'RouteTest']);
// Test route name exists
try {
$url = route('profile.show', ['user' => $user]);
expect($url)->toBeString();
expect($url)->not->toBeEmpty();
} catch (Exception $e) {
// Route might not exist, that's ok for this test
expect(true)->toBeTrue();
}
});
test('profile page contains user information when accessible', function () {
installHotel();
$user = User::factory()->create([
'username' => 'InfoUser',
'look' => 'hr-100-61.hd-180-1.ch-210-66.lg-270-110.sh-305-62',
]);
$this->actingAs($user);
// Just verify user exists and can authenticate
expect(auth()->check())->toBeTrue();
expect(auth()->user()->username)->toBe('InfoUser');
// Database check
$this->assertDatabaseHas('users', [
'username' => 'InfoUser',
'look' => 'hr-100-61.hd-180-1.ch-210-66.lg-270-110.sh-305-62',
]);
});
test('multiple users can have profiles', function () {
installHotel();
$user1 = User::factory()->create(['username' => 'User1']);
$user2 = User::factory()->create(['username' => 'User2']);
$user3 = User::factory()->create(['username' => 'User3']);
// All users exist
expect(User::count())->toBe(3);
$this->assertDatabaseHas('users', ['username' => 'User1']);
$this->assertDatabaseHas('users', ['username' => 'User2']);
$this->assertDatabaseHas('users', ['username' => 'User3']);
// All usernames are unique
expect($user1->username)->not->toBe($user2->username);
expect($user2->username)->not->toBe($user3->username);
});
test('profile username is case sensitive', function () {
installHotel();
$user = User::factory()->create(['username' => 'CaseSensitive']);
$this->actingAs($user);
// Exact match should work
$response = $this->get('/profile/CaseSensitive');
expect($response->status())->not->toBe(404);
// Different case might not work (depends on implementation)
// This test documents current behavior
});
+320
View File
@@ -0,0 +1,320 @@
<?php
use App\Models\Game\Player\UserSetting;
use App\Models\User;
use App\Services\SettingsService;
test('user can access account settings', function () {
installHotel();
$user = User::factory()->create();
// Create required user settings only if not exists
UserSetting::firstOrCreate([
'user_id' => $user->id,
], [
'allow_name_change' => true,
]);
$response = $this->actingAs($user)->get('/user/settings/account');
// Status check
$response->assertStatus(200);
// Content checks
$response->assertSee($user->username);
$response->assertSee($user->mail);
// View check
$response->assertViewIs('user.settings.account');
// Auth checks
expect(auth()->check())->toBeTrue();
expect(auth()->user()->id)->toBe($user->id);
// Database checks
$this->assertDatabaseHas('users', [
'id' => $user->id,
'username' => $user->username,
]);
$this->assertDatabaseHas('user_settings', [
'user_id' => $user->id,
]);
});
test('user can update account settings', function () {
installHotel();
SettingsService::clearCache();
$user = User::factory()->create();
// Create required user settings only if not exists
UserSetting::firstOrCreate([
'user_id' => $user->id,
], [
'allow_name_change' => true,
]);
// Get CSRF token from settings page
$this->actingAs($user)->get('/user/settings/account');
$token = session('_token');
$originalMail = $user->mail;
$response = $this->actingAs($user)->put('/user/settings/account', [
'_token' => $token,
'username' => 'new_username',
'mail' => 'newemail@example.com',
]);
// Redirect check
$response->assertRedirect('/user/settings/account');
$response->assertStatus(302);
$user->refresh();
// Note: username update is disabled in controller (commented out)
// Only mail is actually updated
expect($user->mail)->toBe('newemail@example.com');
expect($user->mail)->not->toBe($originalMail);
// Database checks
$this->assertDatabaseHas('users', [
'id' => $user->id,
'mail' => 'newemail@example.com',
]);
// No errors
expect(session('errors'))->toBeNull();
});
test('user can access password settings', function () {
installHotel();
$user = User::factory()->create();
// Create required user settings only if not exists
UserSetting::firstOrCreate([
'user_id' => $user->id,
], [
'allow_name_change' => true,
]);
$response = $this->actingAs($user)->get('/user/settings/password');
// Status check
$response->assertStatus(200);
// View check
$response->assertViewIs('user.settings.password');
// Auth checks
expect(auth()->check())->toBeTrue();
expect(auth()->user()->id)->toBe($user->id);
});
test('user can access me page', function () {
installHotel();
$user = User::factory()->create();
$response = $this->actingAs($user)->get('/user/me');
// Status check
$response->assertStatus(200);
// View check
$response->assertViewIs('user.me');
// Content checks
$response->assertSee($user->username);
// Auth checks
expect(auth()->check())->toBeTrue();
expect(auth()->user()->id)->toBe($user->id);
});
test('guest cannot access user settings', function () {
installHotel();
$response = $this->get('/user/settings/account');
// Redirect check
$response->assertRedirect('/login');
$response->assertStatus(302);
// Guest check
expect(auth()->guest())->toBeTrue();
});
test('guest cannot access password settings', function () {
installHotel();
$response = $this->get('/user/settings/password');
$response->assertRedirect('/login');
expect(auth()->guest())->toBeTrue();
});
test('guest cannot access me page', function () {
installHotel();
$response = $this->get('/user/me');
$response->assertRedirect('/login');
expect(auth()->guest())->toBeTrue();
});
test('user can update password', function () {
installHotel();
$user = User::factory()->create([
'password' => bcrypt('oldpassword'),
]);
// Get CSRF token
$this->actingAs($user)->get('/user/settings/password');
$token = session('_token');
$oldPasswordHash = $user->password;
$response = $this->actingAs($user)->put('/user/settings/password', [
'_token' => $token,
'current_password' => 'oldpassword',
'password' => 'newpassword',
'password_confirmation' => 'newpassword',
]);
$response->assertRedirect('/user/settings/password');
$user->refresh();
// Password should be updated
expect($user->password)->not->toBe($oldPasswordHash);
});
test('user cannot update password with wrong current password', function () {
installHotel();
$user = User::factory()->create([
'password' => bcrypt('correctpassword'),
]);
// Get CSRF token
$this->actingAs($user)->get('/user/settings/password');
$token = session('_token');
$oldPasswordHash = $user->password;
$response = $this->actingAs($user)->put('/user/settings/password', [
'_token' => $token,
'current_password' => 'wrongpassword',
'password' => 'newpassword',
'password_confirmation' => 'newpassword',
]);
$response->assertRedirect('/user/settings/password');
$user->refresh();
// Password should not change
expect($user->password)->toBe($oldPasswordHash);
expect(session('errors'))->not->toBeNull();
});
test('user settings page contains navigation', function () {
installHotel();
$user = User::factory()->create();
$response = $this->actingAs($user)->get('/user/settings/account');
$response->assertStatus(200);
// Should contain navigation elements
$response->assertSee('Account');
$response->assertSee('Password');
});
test('user can see their settings', function () {
installHotel();
$user = User::factory()->create();
UserSetting::create([
'user_id' => $user->id,
'allow_name_change' => true,
]);
$response = $this->actingAs($user)->get('/user/settings/account');
$response->assertStatus(200);
// Should show user information
$response->assertSee($user->username);
$response->assertSee($user->mail);
});
test('settings update requires csrf token', function () {
installHotel();
$user = User::factory()->create();
UserSetting::create([
'user_id' => $user->id,
'allow_name_change' => true,
]);
$originalMail = $user->mail;
// Try to update without CSRF token
$response = $this->actingAs($user)->put('/user/settings/account', [
'mail' => 'newmail@example.com',
]);
// Should fail
expect($response->status())->toBe(419);
$user->refresh();
expect($user->mail)->toBe($originalMail);
});
test('unauthenticated user cannot update settings', function () {
installHotel();
// Try to update without authentication
$response = $this->put('/user/settings/account', [
'_token' => 'fake-token',
'mail' => 'newmail@example.com',
]);
$response->assertRedirect('/login');
});
test('user settings are isolated per user', function () {
installHotel();
$user1 = User::factory()->create(['username' => 'User1', 'mail' => 'user1@example.com']);
$user2 = User::factory()->create(['username' => 'User2', 'mail' => 'user2@example.com']);
UserSetting::create(['user_id' => $user1->id, 'allow_name_change' => true]);
UserSetting::create(['user_id' => $user2->id, 'allow_name_change' => false]);
// User 1 accesses settings
$response1 = $this->actingAs($user1)->get('/user/settings/account');
$response1->assertSee('User1');
$response1->assertDontSee('User2');
// User 2 accesses settings
$response2 = $this->actingAs($user2)->get('/user/settings/account');
$response2->assertSee('User2');
$response2->assertDontSee('User1');
// Settings are separate
$setting1 = UserSetting::where('user_id', $user1->id)->first();
$setting2 = UserSetting::where('user_id', $user2->id)->first();
expect($setting1->allow_name_change)->toBe(true);
expect($setting2->allow_name_change)->toBe(false);
});