- UserMakeOrder: bestaetigte Einmal-Artikel in den Yard, is_abo_addon auf ShoppingOrderItem; amount bleibt reiner Abo-Betrag (Reihenfolge) - AboOneTimeService::purgeAfterExecution: loescht alle Einmal-Artikel und rechnet Comp-Produkte neu - nur im Erfolgszweig (Cron + Retry) - User-Retry in Sales Center und Portal mit Berechtigungspruefung, gemeinsames Confirm-Modal; Admin-Retry unveraendert - Tests: AboMakeOrderOneTimeTest, AboUserRetryTest; Plan-Doku Phase 4 Co-authored-by: Cursor <cursoragent@cursor.com>
78 lines
2.5 KiB
PHP
78 lines
2.5 KiB
PHP
<?php
|
|
|
|
use App\Http\Controllers\User\AboController;
|
|
use App\Models\UserAbo;
|
|
use App\Repositories\AboRepository;
|
|
use App\Services\AboRetryPaymentService;
|
|
use App\User;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Route;
|
|
use Symfony\Component\HttpKernel\Exception\HttpException;
|
|
|
|
use function Pest\Laravel\mock;
|
|
|
|
uses(Tests\TestCase::class, RefreshDatabase::class);
|
|
|
|
function makeRetryOwnerAbo(): array
|
|
{
|
|
$owner = User::forceCreate([
|
|
'email' => 'owner-'.uniqid('', true).'@example.com',
|
|
'password' => bcrypt('secret'),
|
|
'lang' => 'de',
|
|
]);
|
|
|
|
$abo = UserAbo::create([
|
|
'user_id' => $owner->id,
|
|
'member_id' => $owner->id,
|
|
'shopping_user_id' => 1,
|
|
'is_for' => 'me',
|
|
'email' => $owner->email,
|
|
'payone_userid' => 900300,
|
|
'clearingtype' => 'cc',
|
|
'active' => true,
|
|
'status' => 3,
|
|
'abo_interval' => 5,
|
|
'next_date' => now()->toDateString(),
|
|
]);
|
|
|
|
return ['owner' => $owner, 'abo' => $abo];
|
|
}
|
|
|
|
it('führt den User-Retry für den eigenen Abo aus und leitet zur Detailseite zurück', function () {
|
|
// Domain-Routen werden hostabhängig geladen; Stub für den Redirect der Methode.
|
|
Route::get('/user/abos/detail/{view}/{id}', fn () => '')->name('user_abos_detail');
|
|
app('router')->getRoutes()->refreshNameLookups();
|
|
|
|
$fixture = makeRetryOwnerAbo();
|
|
$this->actingAs($fixture['owner']);
|
|
|
|
mock(AboRetryPaymentService::class)
|
|
->shouldReceive('retry')
|
|
->once()
|
|
->andReturn(['success' => true, 'message' => 'OK']);
|
|
|
|
$controller = new AboController(app(AboRepository::class));
|
|
$response = $controller->retryPayment('me', $fixture['abo']->id, app(AboRetryPaymentService::class));
|
|
|
|
expect($response->getTargetUrl())->toContain('/user/abos/detail/me/'.$fixture['abo']->id);
|
|
expect(session('alert-success'))->toBe('OK');
|
|
});
|
|
|
|
it('verhindert den User-Retry für ein fremdes Abo (403)', function () {
|
|
$fixture = makeRetryOwnerAbo();
|
|
|
|
$stranger = User::forceCreate([
|
|
'email' => 'stranger-'.uniqid('', true).'@example.com',
|
|
'password' => bcrypt('secret'),
|
|
'lang' => 'de',
|
|
]);
|
|
$this->actingAs($stranger);
|
|
|
|
$service = mock(AboRetryPaymentService::class);
|
|
$service->shouldNotReceive('retry');
|
|
|
|
$controller = new AboController(app(AboRepository::class));
|
|
|
|
expect(fn () => $controller->retryPayment('me', $fixture['abo']->id, $service))
|
|
->toThrow(HttpException::class);
|
|
});
|