feat: 增强后台设置校验、代理权限控制与财务审计能力

This commit is contained in:
2026-06-09 13:44:08 +08:00
parent 8d5d7f5b17
commit 41b964a606
25 changed files with 894 additions and 49 deletions

View File

@@ -157,3 +157,56 @@ test('non payout manager cannot update single settlement setting', function ():
expect(LotterySetting::query()->where('setting_key', 'settlement.auto_approve_on_tick')->value('value_json'))->toBeTrue();
});
test('wallet limits must be positive integer minor units', function (): void {
LotterySettings::put('wallet.transfer_in_min_minor', 100, 'wallet');
$token = settingsAdminToken();
$this->withHeader('Authorization', 'Bearer '.$token)
->putJson('/api/v1/admin/settings/batch', [
'items' => [
['key' => 'wallet.transfer_in_min_minor', 'value' => 0],
],
])
->assertUnprocessable();
expect(LotterySetting::query()->where('setting_key', 'wallet.transfer_in_min_minor')->value('value_json'))->toBe(100);
});
test('wallet max limit cannot be less than current min limit', function (): void {
LotterySettings::put('wallet.transfer_in_min_minor', 100, 'wallet');
LotterySettings::put('wallet.transfer_in_max_minor', 10_000, 'wallet');
$token = settingsAdminToken();
$this->withHeader('Authorization', 'Bearer '.$token)
->putJson('/api/v1/admin/settings/wallet.transfer_in_max_minor', [
'value' => 50,
])
->assertUnprocessable();
expect(LotterySetting::query()->where('setting_key', 'wallet.transfer_in_max_minor')->value('value_json'))->toBe(10_000);
});
test('settings updates require permission for their setting group', function (): void {
LotterySettings::put('draw.interval_minutes', 5, 'draw');
LotterySettings::put('frontend.play_rules_html_zh', '<div>old</div>', 'frontend');
$token = settingsReadOnlyToken();
$this->withHeader('Authorization', 'Bearer '.$token)
->putJson('/api/v1/admin/settings/draw.interval_minutes', [
'value' => 10,
])
->assertForbidden();
$this->withHeader('Authorization', 'Bearer '.$token)
->putJson('/api/v1/admin/settings/frontend.play_rules_html_zh', [
'value' => '<div>new</div>',
])
->assertOk();
expect(LotterySetting::query()->where('setting_key', 'draw.interval_minutes')->value('value_json'))->toBe(5)
->and(LotterySetting::query()->where('setting_key', 'frontend.play_rules_html_zh')->value('value_json'))->toBe('<div>new</div>');
});