postJson('/api/v3/invites', ['email' => 'locale@example.test', 'code' => '000000'], $headers); } it('falls back to en without Accept-Language', function () { wrongCode() ->assertStatus(422) ->assertJsonPath('errors.code.0', 'The verification code is incorrect or has expired.') ->assertHeader('Content-Language', 'en'); }); it('localizes messages and validation errors to zh-Hans', function () { wrongCode(['Accept-Language' => 'zh-Hans']) ->assertJsonPath('errors.code.0', '验证码不正确或已过期。') ->assertJsonPath('detail', '验证码不正确或已过期。') ->assertHeader('Content-Language', 'zh-Hans'); $this->postJson('/api/v3/sessions', [], ['Accept-Language' => 'zh-Hans']) ->assertStatus(422) ->assertJsonPath('errors.login.0', 'login 字段是必填项。'); }); it('keeps the Problem title in English', function () { $title = wrongCode(['Accept-Language' => 'zh-Hans'])->json('title'); expect($title)->toBe(wrongCode()->json('title')); }); it('maps regional Chinese tags to simplified and traditional', function (string $header, string $expected) { wrongCode(['Accept-Language' => $header])->assertJsonPath('errors.code.0', $expected); })->with([ 'zh-CN' => ['zh-CN', '验证码不正确或已过期。'], 'zh-TW' => ['zh-TW', '驗證碼不正確或已過期。'], 'zh-Hant-HK' => ['zh-Hant-HK', '驗證碼不正確或已過期。'], ]); it('honours q values and skips unsupported languages', function () { wrongCode(['Accept-Language' => 'fr-FR, en;q=0.5, zh-CN;q=0.9']) ->assertHeader('Content-Language', 'zh-Hans'); wrongCode(['Accept-Language' => 'fr-FR, de']) ->assertHeader('Content-Language', 'en'); }); it('marks responses as varying by Accept-Language', function () { $vary = wrongCode(['Accept-Language' => 'zh-Hans'])->headers->get('Vary'); expect($vary)->toContain('Accept-Language'); }); it('does not set cookies', function () { expect(wrongCode(['Accept-Language' => 'zh-Hans'])->headers->getCookies())->toBeEmpty(); });