127 lines
6.3 KiB
PHP
127 lines
6.3 KiB
PHP
<?php
|
||
|
||
namespace Tests\Feature;
|
||
|
||
use App\Models\User;
|
||
use App\Notifications\ResetAccountPassword;
|
||
use App\Notifications\VerifyAccountEmail;
|
||
use App\Support\LocaleFormatting;
|
||
use App\Support\WowData;
|
||
use Illuminate\Mail\Message;
|
||
use Illuminate\Support\Facades\Mail;
|
||
use Inertia\Testing\AssertableInertia as Assert;
|
||
use Tests\TestCase;
|
||
|
||
class LocalizationFeatureTest extends TestCase
|
||
{
|
||
public function test_browser_language_selects_english_for_html_props_and_metadata(): void
|
||
{
|
||
$this->withHeader('Accept-Language', 'en-GB,en;q=0.9,ru;q=0.5')->get('/login')
|
||
->assertOk()->assertHeader('Content-Language', 'en')
|
||
->assertSee('<html lang="en">', false)
|
||
->assertSee('Sign in to your account — MoonWell', false)
|
||
->assertSee('content="en_US"', false)
|
||
->assertInertia(fn (Assert $page) => $page
|
||
->where('locale', 'en')->where('localePreference', 'auto')
|
||
->where('localeUrl', route('locale.update')));
|
||
}
|
||
|
||
public function test_weighted_russian_language_has_priority_over_country(): void
|
||
{
|
||
$this->withHeaders(['Accept-Language' => 'en;q=0.5,ru-RU;q=0.9', 'CF-IPCountry' => 'US'])
|
||
->get('/login')->assertHeader('Content-Language', 'ru');
|
||
}
|
||
|
||
public function test_country_is_used_when_no_supported_browser_language_is_available(): void
|
||
{
|
||
$this->withHeaders(['Accept-Language' => '', 'CF-IPCountry' => 'US'])->get('/login')->assertHeader('Content-Language', 'en');
|
||
$this->withHeaders(['Accept-Language' => '', 'CF-IPCountry' => 'RU'])->get('/login')->assertHeader('Content-Language', 'ru');
|
||
$this->withHeaders(['Accept-Language' => 'fr-FR', 'CF-IPCountry' => ''])->get('/login')->assertHeader('Content-Language', 'en');
|
||
}
|
||
|
||
public function test_rejected_language_preferences_are_not_selected(): void
|
||
{
|
||
$this->withHeaders(['Accept-Language' => 'ru;q=0,en;q=0.8', 'CF-IPCountry' => 'RU'])
|
||
->get('/login')->assertHeader('Content-Language', 'en');
|
||
}
|
||
|
||
public function test_manual_cookie_overrides_browser_and_country_and_invalid_cookie_is_ignored(): void
|
||
{
|
||
$this->withCookie('moonwell_locale', 'ru')->withHeaders(['Accept-Language' => 'en', 'CF-IPCountry' => 'US'])
|
||
->get('/login')->assertHeader('Content-Language', 'ru');
|
||
$this->withCookie('moonwell_locale', 'en')->withHeader('Accept-Language', 'ru')
|
||
->get('/login')->assertHeader('Content-Language', 'en');
|
||
$this->withCookie('moonwell_locale', 'invalid')->withHeader('Accept-Language', 'en')
|
||
->get('/login')->assertHeader('Content-Language', 'en');
|
||
}
|
||
|
||
public function test_switcher_saves_choice_and_auto_removes_it_without_changing_signed_urls(): void
|
||
{
|
||
$destination = '/reset-password/example?email=player%40example.com';
|
||
$this->from($destination)->post('/language', ['locale' => 'en'])
|
||
->assertRedirect($destination)->assertCookie('moonwell_locale', 'en');
|
||
$this->post('/language', ['locale' => 'auto'])->assertCookieExpired('moonwell_locale');
|
||
$this->post('/language', ['locale' => 'invalid'])->assertSessionHasErrors('locale');
|
||
}
|
||
|
||
public function test_english_validation_is_returned_by_web_and_launcher_api(): void
|
||
{
|
||
$this->withHeader('Accept-Language', 'en')->post('/forgot-password', ['email' => 'invalid'])
|
||
->assertSessionHasErrors(['email' => 'Enter a valid email address.']);
|
||
$this->withHeader('Accept-Language', 'en')->postJson('/api/launcher/register', [
|
||
'username' => '!', 'email' => 'invalid', 'password' => '123',
|
||
])->assertUnprocessable()->assertJsonPath('errors.username.0', 'Your username must contain at least 3 characters.');
|
||
}
|
||
|
||
public function test_english_auth_emails_include_english_subject_body_and_language(): void
|
||
{
|
||
app()->setLocale('en');
|
||
$user = new User(['name' => 'PLAYER', 'email' => 'player@example.com']);
|
||
$user->id = 77;
|
||
foreach ([new VerifyAccountEmail, new ResetAccountPassword('example-token')] as $notification) {
|
||
$mail = $notification->toMail($user);
|
||
$this->assertStringNotContainsString('парол', $mail->subject);
|
||
$html = view($mail->view, $mail->viewData)->render();
|
||
$this->assertStringContainsString('<html lang="en">', $html);
|
||
$this->assertStringContainsString('Hi,', $html);
|
||
$this->assertDoesNotMatchRegularExpression('/[А-Яа-яЁё]/u', $html);
|
||
}
|
||
}
|
||
|
||
public function test_game_labels_and_display_numbers_follow_the_locale(): void
|
||
{
|
||
app()->setLocale('en');
|
||
$this->assertSame('Night Elf', WowData::raceName(4));
|
||
$this->assertSame('Game Master', WowData::securityLevelName(2));
|
||
$this->assertSame('1,250.00', LocaleFormatting::number(1250));
|
||
$this->assertSame('2h 0m', WowData::formatPlayedTime(7200));
|
||
}
|
||
|
||
public function test_auth_email_embeds_the_brand_logo_as_an_inline_image(): void
|
||
{
|
||
$user = new User(['name' => 'PLAYER', 'email' => 'player@example.com']);
|
||
$mail = (new ResetAccountPassword('example-token'))->toMail($user);
|
||
|
||
$sent = Mail::mailer('array')->send($mail->view, $mail->viewData, function (Message $message) use ($mail): void {
|
||
$message->to('player@example.com')->subject($mail->subject);
|
||
});
|
||
|
||
$email = $sent->getOriginalMessage();
|
||
$attachments = $email->getAttachments();
|
||
$this->assertCount(1, $attachments);
|
||
$this->assertSame('inline', $attachments[0]->getDisposition());
|
||
$this->assertSame('image', $attachments[0]->getMediaType());
|
||
$this->assertSame('png', $attachments[0]->getMediaSubtype());
|
||
$this->assertStringContainsString('cid:'.$attachments[0]->getContentId(), $email->getHtmlBody());
|
||
$this->assertStringNotContainsString(asset('branding/moonwell-mail-logo.png'), $email->getHtmlBody());
|
||
}
|
||
|
||
public function test_response_varies_by_language_and_cookie_to_avoid_shared_cache_mixups(): void
|
||
{
|
||
$response = $this->withHeader('Accept-Language', 'en')->get('/login')->assertOk();
|
||
$vary = strtolower(implode(', ', $response->headers->all('Vary')));
|
||
$this->assertStringContainsString('accept-language', $vary);
|
||
$this->assertStringContainsString('cookie', $vary);
|
||
}
|
||
}
|