feat(registration): send the browser language
Build, Test & Push Frontend / quality-check (push) Successful in 22s
Build, Test & Push Frontend / docker (push) Successful in 25s

This commit is contained in:
lobo committed 2026-10-01 08:30:24 +02:00
1 parent 43968b3b7a
commit b8f70e7578
3 files changed
+16 -1

No files matched your search

+2 -1
View File
@@ -83,7 +83,8 @@ To Be Played is split into three repositories:
- **Appearance**: accent color, corner style, wide layout, page background and banner from your own game art. - **Appearance**: accent color, corner style, wide layout, page background and banner from your own game art.
Saved in Auth, so it follows you to every device. Saved in Auth, so it follows you to every device.
- **Language**: kept in the browser and saved in Auth; after the login Auth's language wins when one is saved. Dark - **Language**: kept in the browser and saved in Auth; after the login Auth's language wins when one is saved. Dark
mode stays per device. mode stays per device. The registration sends the browser language (`de` for a German browser, else `en`): Auth
writes its mails in it and saves it as the user's language.
- **Broken pictures**: a Steam cover or achievement icon that does not load shows a placeholder and is reported - **Broken pictures**: a Steam cover or achievement icon that does not load shows a placeholder and is reported
to Core once per page load (`POST /api/library/broken-images`, only with a session). Core repairs it at night; to Core once per page load (`POST /api/library/broken-images`, only with a session). Core repairs it at night;
a repaired cover comes back as `imageUrl`. a repaired cover comes back as `imageUrl`.
+2
View File
@@ -54,6 +54,8 @@ export default function RegistrationPage() {
password: values.password, password: values.password,
inviteCode: values.inviteCode, inviteCode: values.inviteCode,
displayName: values.displayName, displayName: values.displayName,
// Auth's mails use it: a German browser gets German, every other one English.
language: navigator.language?.toLowerCase().startsWith('de') ? 'de' : 'en',
}), }),
}); });
+12
View File
@@ -30,6 +30,7 @@ function submitValidForm() {
describe('RegistrationPage', () => { describe('RegistrationPage', () => {
afterEach(() => { afterEach(() => {
cleanup(); cleanup();
vi.restoreAllMocks();
}); });
it('shows the wait time when the IP is blocked', async () => { it('shows the wait time when the IP is blocked', async () => {
@@ -50,6 +51,17 @@ describe('RegistrationPage', () => {
expect(JSON.parse(fetch.mock.calls[0][1].body)).not.toHaveProperty('steamId'); expect(JSON.parse(fetch.mock.calls[0][1].body)).not.toHaveProperty('steamId');
}); });
it.each([['de-DE', 'de'], ['de', 'de'], ['en-US', 'en'], ['fr-FR', 'en'], [undefined, 'en']])(
'sends the browser language %s as %s, for the mails', async (browser, sent) => {
vi.spyOn(navigator, 'language', 'get').mockReturnValue(browser);
answerRegistration(400, 'INVALID_INVITATION_CODE');
submitValidForm();
await screen.findByText('REGISTRATION.ERROR_INVALID_INVITE_CODE');
expect(JSON.parse(fetch.mock.calls[0][1].body).language).toBe(sent);
});
it('maps a known backend error to its message', async () => { it('maps a known backend error to its message', async () => {
answerRegistration(400, 'INVALID_INVITATION_CODE'); answerRegistration(400, 'INVALID_INVITATION_CODE');