tane/apps/app_seeds/test/services/locale_store_test.dart
vjrj c9c764e624 feat(i18n): add Asturian (asturianu) as a language
Adds Asturianu, translated in full (345 strings), plus the wiring to
make a minority language work end to end — the OS language picker is an
unreliable way to reach it, so the in-app choice must be explicit and
remembered.

- Model Asturian as the real `ast` locale (honest, international-by-design),
  not a fake `es-AST` region — slang rejects a 3-letter region anyway.
- Flutter ships no Material/Cupertino/intl localizations for `ast`, so map
  the framework chrome to Spanish (`materialLocaleFor`); the app's own text
  stays Asturian via slang. Fixes an "Invalid locale ast" crash when the
  auto-backup date was formatted with intl.
- Persist the picked language in the keystore (LocaleStore) and restore it
  at startup so it survives restarts and wins over the device locale.
- Settings: add the Asturianu tile; compare the full AppLocale so `es` and
  `ast` aren't both marked selected.

Tests: LocaleStore round-trip, locale switch + Spanish-chrome fallback,
and a regression for the intl date crash under Asturian.
2026-07-10 15:43:33 +02:00

54 lines
1.7 KiB
Dart

import 'package:flutter_test/flutter_test.dart';
import 'package:tane/i18n/strings.g.dart';
import 'package:tane/security/secret_store.dart';
import 'package:tane/services/locale_store.dart';
/// In-memory [SecretStore] for tests.
class FakeSecretStore implements SecretStore {
final Map<String, String> _data = {};
@override
Future<String?> read(String key) async => _data[key];
@override
Future<void> write(String key, String value) async => _data[key] = value;
}
void main() {
// setLocale/useDeviceLocale touch the Flutter locale, which needs a binding.
TestWidgetsFlutterBinding.ensureInitialized();
late FakeSecretStore secrets;
late LocaleStore store;
setUp(() {
secrets = FakeSecretStore();
store = LocaleStore(secrets);
});
test('no choice saved yet → follows the device (null)', () async {
expect(await store.saved(), isNull);
});
test('picking Asturian persists it and applies it', () async {
await store.setLocale(AppLocale.ast);
expect(await store.saved(), AppLocale.ast);
expect(LocaleSettings.currentLocale, AppLocale.ast);
// Asturian is modelled as its real `ast` code so the schema stays honest;
// Material chrome borrows Spanish elsewhere (see app.dart).
expect(AppLocale.ast.languageCode, 'ast');
});
test('choosing "system language" forgets the explicit choice', () async {
await store.setLocale(AppLocale.es);
expect(await store.saved(), AppLocale.es);
await store.useDeviceLocale();
expect(await store.saved(), isNull);
});
test('an unknown stored tag reads as "follow the device", never throws',
() async {
await secrets.write('tane.locale', 'zz-ZZ-removed-in-a-later-build');
expect(await store.saved(), isNull);
});
}