Development 4.6.0 #12
@@ -0,0 +1,181 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Domains\Admin\Actions\UpdateAvailablePaymentMethod\UpdateAvailablePaymentMethodAction;
|
||||
use App\Domains\Admin\Actions\UpdateAvailablePaymentMethod\UpdateAvailablePaymentMethodRequest;
|
||||
use App\Domains\Event\Actions\UpdateEvent\UpdateEventCommand;
|
||||
use App\Domains\Event\Actions\UpdateEvent\UpdateEventRequest;
|
||||
use App\Models\AvailablePaymentMethod;
|
||||
use App\Models\Event;
|
||||
use App\Models\PaymentMethod;
|
||||
use App\Models\Tenant;
|
||||
use App\ValueObjects\Amount;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Tests\TestCase;
|
||||
|
||||
class PaymentMethodConfigurationTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
private Tenant $tenant;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->tenant = Tenant::create([
|
||||
'slug' => 'tv',
|
||||
'name' => 'Test',
|
||||
'email' => 't@example.com',
|
||||
'email_finance' => 'finance@example.com',
|
||||
'url' => 'test.local',
|
||||
'account_name' => 'Test e.V.',
|
||||
'account_iban' => 'DE00',
|
||||
'account_bic' => 'XY',
|
||||
'city' => 'Stadt',
|
||||
'postcode' => '00000',
|
||||
'is_active_local_group' => true,
|
||||
'has_active_instance' => true,
|
||||
]);
|
||||
|
||||
app()->instance('tenant', $this->tenant);
|
||||
|
||||
PaymentMethod::create(['slug' => PaymentMethod::PAYMENT_ACCOUNT_TRANSACTION]);
|
||||
PaymentMethod::create(['slug' => PaymentMethod::PAYMENT_NOT_DEFINED]);
|
||||
|
||||
DB::table('participation_fee_types')->insert([
|
||||
'slug' => 'FIXED',
|
||||
'name' => 'Fixed',
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
}
|
||||
|
||||
private function availableMethod(string $slug, bool $active = false, array $config = []): AvailablePaymentMethod
|
||||
{
|
||||
return AvailablePaymentMethod::create([
|
||||
'tenant' => $this->tenant->slug,
|
||||
'slug' => $slug,
|
||||
'name' => 'Konto',
|
||||
'description' => null,
|
||||
'active' => $active,
|
||||
'configuration' => $config,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_activation_is_blocked_when_required_options_missing(): void
|
||||
{
|
||||
$method = $this->availableMethod(PaymentMethod::PAYMENT_ACCOUNT_TRANSACTION);
|
||||
|
||||
$response = new UpdateAvailablePaymentMethodAction(new UpdateAvailablePaymentMethodRequest(
|
||||
availablePaymentMethod: $method,
|
||||
name: 'Konto',
|
||||
description: null,
|
||||
active: true,
|
||||
configuration: ['iban' => 'DE123'], // account_owner fehlt
|
||||
))->execute();
|
||||
|
||||
$this->assertFalse($response->success);
|
||||
$this->assertFalse($method->fresh()->active);
|
||||
}
|
||||
|
||||
public function test_activation_succeeds_when_configuration_complete(): void
|
||||
{
|
||||
$method = $this->availableMethod(PaymentMethod::PAYMENT_ACCOUNT_TRANSACTION);
|
||||
|
||||
$response = new UpdateAvailablePaymentMethodAction(new UpdateAvailablePaymentMethodRequest(
|
||||
availablePaymentMethod: $method,
|
||||
name: 'Konto',
|
||||
description: null,
|
||||
active: true,
|
||||
configuration: ['iban' => 'DE123', 'account_owner' => 'Kasse', 'bic' => 'XY', 'evil' => 'x'],
|
||||
))->execute();
|
||||
|
||||
$this->assertTrue($response->success);
|
||||
|
||||
$fresh = $method->fresh();
|
||||
$this->assertTrue($fresh->active);
|
||||
$this->assertSame('DE123', $fresh->configuration['iban']);
|
||||
$this->assertArrayNotHasKey('evil', $fresh->configuration); // unbekannte Keys verworfen
|
||||
}
|
||||
|
||||
public function test_event_assignment_copies_snapshot_and_preserves_overrides(): void
|
||||
{
|
||||
$this->availableMethod(
|
||||
PaymentMethod::PAYMENT_ACCOUNT_TRANSACTION,
|
||||
active: true,
|
||||
config: ['iban' => 'DE-TENANT', 'account_owner' => 'Kasse'],
|
||||
);
|
||||
|
||||
$event = $this->createEvent();
|
||||
|
||||
// 1. Zuweisung -> Snapshot der Tenant-Config landet im Pivot.
|
||||
$this->runUpdateEvent($event, [PaymentMethod::PAYMENT_ACCOUNT_TRANSACTION]);
|
||||
|
||||
$pivotConfig = $event->fresh()->paymentMethods()->first()->pivot->configuration;
|
||||
$this->assertSame('DE-TENANT', $pivotConfig['iban']);
|
||||
|
||||
// 2. Pro-Event-Override setzen.
|
||||
$this->runUpdateEvent($event, [PaymentMethod::PAYMENT_ACCOUNT_TRANSACTION], [
|
||||
PaymentMethod::PAYMENT_ACCOUNT_TRANSACTION => ['iban' => 'DE-EVENT', 'account_owner' => 'Kasse'],
|
||||
]);
|
||||
$this->assertSame('DE-EVENT', $event->fresh()->paymentMethods()->first()->pivot->configuration['iban']);
|
||||
|
||||
// 3. Erneutes Speichern OHNE Override -> Override bleibt erhalten (kein Reset-Wipe).
|
||||
$this->runUpdateEvent($event, [PaymentMethod::PAYMENT_ACCOUNT_TRANSACTION]);
|
||||
$this->assertSame('DE-EVENT', $event->fresh()->paymentMethods()->first()->pivot->configuration['iban']);
|
||||
}
|
||||
|
||||
private function createEvent(): Event
|
||||
{
|
||||
return Event::create([
|
||||
'tenant' => $this->tenant->slug,
|
||||
'name' => 'Event',
|
||||
'identifier' => 'evt-1',
|
||||
'location' => 'Ort',
|
||||
'postal_code' => '00000',
|
||||
'email' => 'e@example.com',
|
||||
'start_date' => '2026-08-01',
|
||||
'end_date' => '2026-08-05',
|
||||
'early_bird_end' => '2026-07-01',
|
||||
'registration_final_end' => '2026-07-20',
|
||||
'early_bird_end_amount_increase' => 0,
|
||||
'account_owner' => 'Owner',
|
||||
'account_iban' => 'DE00',
|
||||
'participation_fee_type' => 'FIXED',
|
||||
'pay_per_day' => false,
|
||||
'pay_direct' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, string> $slugs
|
||||
* @param array<string, array<string, mixed>> $configs
|
||||
*/
|
||||
private function runUpdateEvent(Event $event, array $slugs, array $configs = []): void
|
||||
{
|
||||
$request = new UpdateEventRequest(
|
||||
$event,
|
||||
$event->name,
|
||||
$event->location,
|
||||
$event->postal_code,
|
||||
$event->email,
|
||||
new \DateTime('2026-07-01'),
|
||||
new \DateTime('2026-07-20'),
|
||||
16,
|
||||
false,
|
||||
false,
|
||||
Amount::fromString('0'),
|
||||
Amount::fromString('0'),
|
||||
[],
|
||||
[],
|
||||
$slugs,
|
||||
$configs,
|
||||
);
|
||||
|
||||
$response = new UpdateEventCommand($request)->execute();
|
||||
$this->assertTrue($response->success, $response->message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit;
|
||||
|
||||
use App\Models\PaymentMethod;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class PaymentMethodOptionsTest extends TestCase
|
||||
{
|
||||
public function test_options_for_returns_schema_for_known_slug(): void
|
||||
{
|
||||
$options = PaymentMethod::optionsFor(PaymentMethod::PAYMENT_ACCOUNT_TRANSACTION);
|
||||
|
||||
$this->assertNotEmpty($options);
|
||||
$this->assertSame('account_owner', $options[0]['name']);
|
||||
}
|
||||
|
||||
public function test_options_for_returns_empty_for_unknown_slug(): void
|
||||
{
|
||||
$this->assertSame([], PaymentMethod::optionsFor('DOES_NOT_EXIST'));
|
||||
}
|
||||
|
||||
public function test_required_option_keys_only_returns_required(): void
|
||||
{
|
||||
$keys = PaymentMethod::requiredOptionKeys(PaymentMethod::PAYMENT_ACCOUNT_TRANSACTION);
|
||||
|
||||
$this->assertContains('account_owner', $keys);
|
||||
$this->assertContains('iban', $keys);
|
||||
$this->assertNotContains('bic', $keys); // bic ist optional
|
||||
}
|
||||
|
||||
public function test_sanitize_configuration_drops_unknown_keys(): void
|
||||
{
|
||||
$sanitized = PaymentMethod::sanitizeConfiguration(PaymentMethod::PAYMENT_ACCOUNT_TRANSACTION, [
|
||||
'iban' => 'DE123',
|
||||
'account_owner' => 'Kasse',
|
||||
'evil' => 'x',
|
||||
]);
|
||||
|
||||
$this->assertArrayHasKey('iban', $sanitized);
|
||||
$this->assertArrayHasKey('account_owner', $sanitized);
|
||||
$this->assertArrayNotHasKey('evil', $sanitized);
|
||||
}
|
||||
|
||||
public function test_is_configuration_complete_requires_all_required_options(): void
|
||||
{
|
||||
$slug = PaymentMethod::PAYMENT_ACCOUNT_TRANSACTION;
|
||||
|
||||
$this->assertFalse(PaymentMethod::isConfigurationComplete($slug, []));
|
||||
$this->assertFalse(PaymentMethod::isConfigurationComplete($slug, ['iban' => 'DE123']));
|
||||
$this->assertFalse(PaymentMethod::isConfigurationComplete($slug, ['iban' => 'DE123', 'account_owner' => '']));
|
||||
$this->assertTrue(PaymentMethod::isConfigurationComplete($slug, ['iban' => 'DE123', 'account_owner' => 'Kasse']));
|
||||
}
|
||||
|
||||
public function test_slug_without_options_is_always_complete(): void
|
||||
{
|
||||
$this->assertTrue(PaymentMethod::isConfigurationComplete(PaymentMethod::PAYMENT_NOT_DEFINED, []));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user