seed(CurrencySeeder::class); }); function jackpotAdjustAdminToken(): string { $admin = AdminUser::query()->create([ 'username' => 'jackpot_adjust_admin', 'name' => 'Jackpot Adjust', 'email' => null, 'password' => Hash::make('secret-strong'), 'status' => 0, ]); grantSuperAdminRole($admin); return $admin->createToken('test', ['*'], now()->addDay())->plainTextToken; } test('admin cannot set current_amount via pool update', function (): void { $pool = JackpotPool::query()->where('currency_code', 'NPR')->firstOrFail(); $token = jackpotAdjustAdminToken(); $this->withHeader('Authorization', 'Bearer '.$token) ->putJson('/api/v1/admin/jackpot/pools/'.$pool->id, [ 'current_amount' => 9_999_999, ]) ->assertStatus(422); }); test('admin can apply jackpot pool balance adjustment with ledger row', function (): void { $pool = JackpotPool::query()->where('currency_code', 'NPR')->firstOrFail(); $pool->forceFill(['current_amount' => 1_000])->save(); $token = jackpotAdjustAdminToken(); $this->withHeader('Authorization', 'Bearer '.$token) ->postJson('/api/v1/admin/jackpot/pools/'.$pool->id.'/adjustments', [ 'amount_delta' => 500, 'reason' => 'manual top-up after reconciliation', ]) ->assertOk() ->assertJsonPath('data.pool.current_amount', 1_500) ->assertJsonPath('data.adjustment.amount_delta', 500) ->assertJsonPath('data.adjustment.balance_before', 1_000) ->assertJsonPath('data.adjustment.balance_after', 1_500); expect(JackpotPoolAdjustment::query()->where('jackpot_pool_id', $pool->id)->count())->toBe(1); expect( AuditLog::query() ->where('module_code', 'jackpot') ->where('action_code', 'adjust_balance') ->exists(), )->toBeTrue(); }); test('admin jackpot adjustment rejects negative balance', function (): void { $pool = JackpotPool::query()->where('currency_code', 'NPR')->firstOrFail(); $pool->forceFill(['current_amount' => 100])->save(); $token = jackpotAdjustAdminToken(); $this->withHeader('Authorization', 'Bearer '.$token) ->postJson('/api/v1/admin/jackpot/pools/'.$pool->id.'/adjustments', [ 'amount_delta' => -200, 'reason' => 'correction', ]) ->assertStatus(422); expect((int) $pool->fresh()->current_amount)->toBe(100); }); test('admin can list jackpot pool adjustments', function (): void { $pool = JackpotPool::query()->where('currency_code', 'NPR')->firstOrFail(); $admin = AdminUser::query()->create([ 'username' => 'adj_list_admin', 'name' => 'List', 'email' => null, 'password' => Hash::make('secret-strong'), 'status' => 0, ]); grantSuperAdminRole($admin); $token = $admin->createToken('test', ['*'], now()->addDay())->plainTextToken; JackpotPoolAdjustment::query()->create([ 'adjustment_no' => 'JA_TEST_1', 'jackpot_pool_id' => $pool->id, 'admin_user_id' => $admin->id, 'amount_delta' => 50, 'balance_before' => 0, 'balance_after' => 50, 'reason' => 'seed', ]); $this->withHeader('Authorization', 'Bearer '.$token) ->getJson('/api/v1/admin/jackpot/pools/'.$pool->id.'/adjustments') ->assertOk() ->assertJsonPath('data.total', 1) ->assertJsonPath('data.items.0.adjustment_no', 'JA_TEST_1'); });