Files
fotospiel-app/tests/Feature/Tenant/SettingsApiTest.php
Codex Agent 9cb236f123
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
tests / ui (push) Has been cancelled
Update default branding palette for tenants and guests
2026-01-15 09:32:51 +01:00

192 lines
6.4 KiB
PHP

<?php
namespace Tests\Feature\Tenant;
use App\Models\Tenant;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use PHPUnit\Framework\Attributes\Test;
class SettingsApiTest extends TenantTestCase
{
use RefreshDatabase;
protected Tenant $tenant;
protected User $tenantUser;
protected string $token;
protected function setUp(): void
{
parent::setUp();
$this->mockTenantContext();
}
#[Test]
public function unauthenticated_users_cannot_access_settings()
{
$response = $this->getJson('/api/v1/tenant/settings');
$response->assertStatus(401);
}
#[Test]
public function authenticated_user_can_get_settings()
{
$response = $this->authenticatedRequest('GET', '/api/v1/tenant/settings');
$response->assertStatus(200)
->assertJson(['message' => 'Settings erfolgreich abgerufen.'])
->assertJsonPath('data.settings.branding.primary_color', '#FF5A5F')
->assertJsonPath('data.settings.features.photo_likes_enabled', true);
}
#[Test]
public function user_can_update_settings()
{
$settingsData = [
'settings' => [
'branding' => [
'logo_url' => 'https://example.com/logo.png',
'primary_color' => '#FF6B6B',
'secondary_color' => '#4ECDC4',
],
'features' => [
'photo_likes_enabled' => false,
'event_checklist' => true,
'custom_domain' => true,
],
'custom_domain' => 'custom.example.com',
],
];
$response = $this->authenticatedRequest('POST', '/api/v1/tenant/settings', $settingsData);
$response->assertStatus(200)
->assertJson(['message' => 'Settings erfolgreich aktualisiert.'])
->assertJsonPath('data.settings.branding.primary_color', '#FF6B6B')
->assertJsonPath('data.settings.features.photo_likes_enabled', false)
->assertJsonPath('data.settings.custom_domain', 'custom.example.com');
$this->assertDatabaseHas('tenants', [
'id' => $this->tenant->id,
'settings' => json_encode($settingsData['settings']),
]);
}
#[Test]
public function settings_update_requires_valid_data()
{
$invalidData = [
'settings' => [
'branding' => [
'primary_color' => 'invalid-color',
],
],
];
$response = $this->authenticatedRequest('POST', '/api/v1/tenant/settings', $invalidData);
$response->assertStatus(422)
->assertJsonValidationErrors([
'settings.branding.primary_color',
]);
}
#[Test]
public function user_can_reset_settings_to_defaults()
{
$response = $this->authenticatedRequest('POST', '/api/v1/tenant/settings/reset');
$response->assertStatus(200)
->assertJson(['message' => 'Settings auf Standardwerte zurueckgesetzt.'])
->assertJsonPath('data.settings.branding.primary_color', '#FF5A5F')
->assertJsonPath('data.settings.features.photo_likes_enabled', true);
$this->assertDatabaseHas('tenants', [
'id' => $this->tenant->id,
'settings' => json_encode([
'branding' => [
'logo_url' => null,
'primary_color' => '#FF5A5F',
'secondary_color' => '#FFF8F5',
'font_family' => 'Inter, sans-serif',
],
'features' => [
'photo_likes_enabled' => true,
'event_checklist' => true,
'custom_domain' => false,
'advanced_analytics' => false,
],
'custom_domain' => null,
'contact_email' => $this->tenant->contact_email,
'event_default_type' => 'general',
]),
]);
}
#[Test]
public function user_can_validate_domain_availability()
{
// Valid domain
$response = $this->authenticatedRequest('POST', '/api/v1/tenant/settings/validate-domain', [
'domain' => 'custom.example.com',
]);
$response->assertStatus(200)
->assertJson(['available' => true])
->assertJson(['message' => 'Domain ist verfuegbar.']);
// Invalid domain format
$response = $this->authenticatedRequest('POST', '/api/v1/tenant/settings/validate-domain', [
'domain' => 'invalid@domain',
]);
$response->assertStatus(200)
->assertJson(['available' => false])
->assertJson(['message' => 'Ungueltiges Domain-Format.']);
// Taken domain (create another tenant with same domain)
$otherTenant = Tenant::factory()->create(['custom_domain' => 'taken.example.com']);
$response = $this->authenticatedRequest('POST', '/api/v1/tenant/settings/validate-domain', [
'domain' => 'taken.example.com',
]);
$response->assertStatus(200)
->assertJson(['available' => false])
->assertJson(['message' => 'Domain ist bereits vergeben.']);
}
#[Test]
public function domain_validation_requires_domain_parameter()
{
$response = $this->authenticatedRequest('POST', '/api/v1/tenant/settings/validate-domain');
$response->assertStatus(400)
->assertJsonPath('error.code', 'domain_missing')
->assertJsonPath('error.message', 'Bitte gib eine Domain an.');
}
#[Test]
public function settings_are_tenant_isolated()
{
$otherTenant = Tenant::factory()->create([
'settings' => json_encode(['branding' => ['primary_color' => '#FF0000']]),
]);
$otherUser = User::factory()->create([
'tenant_id' => $otherTenant->id,
'role' => 'admin',
]);
$otherToken = 'mock-jwt-token-'.$otherTenant->id.'-'.time();
// This tenant's user should not see other tenant's settings
$response = $this->authenticatedRequest('GET', '/api/v1/tenant/settings');
$response->assertStatus(200)
->assertJsonPath('data.settings.branding.primary_color', '#FF5A5F') // Default for this tenant
->assertJsonMissing(['#FF0000']); // Other tenant's color
}
}