feat: 增强玩家 API,新增 locale 和时间字段,更新钱包 API 以支持可用余额计算,添加错误码与多语言支持
This commit is contained in:
@@ -18,13 +18,26 @@ test('player me returns profile with dev bearer', function () {
|
||||
'status' => 0,
|
||||
]);
|
||||
|
||||
$this->withHeader('Authorization', 'Bearer dev:'.$player->id)
|
||||
$this->withHeaders([
|
||||
'Authorization' => 'Bearer dev:'.$player->id,
|
||||
'X-Locale' => 'zh',
|
||||
])
|
||||
->getJson('/api/v1/player/me')
|
||||
->assertOk()
|
||||
->assertJsonPath('code', ErrorCode::Success->value)
|
||||
->assertJsonPath('data.id', $player->id)
|
||||
->assertJsonPath('data.site_player_id', 'uid-42')
|
||||
->assertJsonPath('data.username', 'alice');
|
||||
->assertJsonPath('data.username', 'alice')
|
||||
->assertJsonPath('data.locale', 'zh')
|
||||
->assertJsonStructure([
|
||||
'data' => [
|
||||
'last_login_at',
|
||||
'created_at',
|
||||
],
|
||||
]);
|
||||
|
||||
$player->refresh();
|
||||
expect($player->last_login_at)->not->toBeNull();
|
||||
});
|
||||
|
||||
test('player auth missing bearer returns localized sso 8001', function () {
|
||||
@@ -68,3 +81,45 @@ test('player me works with main site jwt when dev bypass is off', function () {
|
||||
->assertOk()
|
||||
->assertJsonPath('data.site_player_id', 'jwt-user-1');
|
||||
});
|
||||
|
||||
test('jwt first successful login auto-registers player mapping', function () {
|
||||
config(['lottery.player_auth.dev_bypass' => false]);
|
||||
config(['lottery.main_site.sso_jwt_secret' => 'jwt-test-secret']);
|
||||
|
||||
expect(Player::query()->count())->toBe(0);
|
||||
|
||||
$jwt = JWT::encode([
|
||||
'site_code' => 'main',
|
||||
'site_player_id' => 'brand-new-sso-1',
|
||||
'exp' => time() + 3600,
|
||||
], 'jwt-test-secret', 'HS256');
|
||||
|
||||
$this->withHeader('Authorization', 'Bearer '.$jwt)
|
||||
->getJson('/api/v1/player/me')
|
||||
->assertOk()
|
||||
->assertJsonPath('data.site_player_id', 'brand-new-sso-1')
|
||||
->assertJsonPath('data.default_currency', 'NPR');
|
||||
|
||||
expect(Player::query()->where('site_player_id', 'brand-new-sso-1')->count())->toBe(1);
|
||||
});
|
||||
|
||||
test('player me rejects non-active status with 8005', function () {
|
||||
$code = ErrorCode::PlayerAccountSuspended->value;
|
||||
$player = Player::query()->create([
|
||||
'site_code' => 'main',
|
||||
'site_player_id' => 'frozen-1',
|
||||
'username' => null,
|
||||
'nickname' => null,
|
||||
'default_currency' => 'NPR',
|
||||
'status' => 1,
|
||||
]);
|
||||
|
||||
$this->withHeaders([
|
||||
'Authorization' => 'Bearer dev:'.$player->id,
|
||||
'Accept-Language' => 'zh-CN,zh;q=0.9',
|
||||
])
|
||||
->getJson('/api/v1/player/me')
|
||||
->assertStatus(403)
|
||||
->assertJsonPath('code', $code)
|
||||
->assertJsonPath('msg', __("sso.$code", [], 'zh'));
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user