Fixed-wording tests for the generic credentials error, redacted toString for login/register state, shared AuthFailure.isRetryable, autofill context finished even when the router removes the screen, stricter from validation (encoded and control-character variants), more widget tests. Refs #1 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
43 lines
1.8 KiB
Dart
43 lines
1.8 KiB
Dart
import 'package:shuffle/core/l10n/l10n.dart';
|
|
import 'package:shuffle/features/auth/domain/auth_failure.dart';
|
|
|
|
/// User-facing text of an [AuthFailure] (Spec #1 § 4.4, texts from
|
|
/// `docs/design/auth-screens.md`).
|
|
///
|
|
/// `emailSendLimited` has no text of its own: screens treat it as success
|
|
/// (F12) or convert it to `rateLimited` beforehand.
|
|
String authFailureMessage(AppLocalizations l10n, AuthFailure failure) =>
|
|
switch (failure) {
|
|
InvalidCredentials() => l10n.authErrorInvalidCredentials,
|
|
EmailNotConfirmed() => l10n.authErrorEmailNotConfirmed,
|
|
EmailSendLimited() || RateLimited() => l10n.authErrorRateLimited,
|
|
WeakPassword(:final reasons) => weakPasswordMessage(l10n, reasons),
|
|
SamePassword() => l10n.authErrorSamePassword,
|
|
LinkInvalidOrExpired() => l10n.authErrorLinkInvalidOrExpired,
|
|
InvalidEmail() => l10n.authErrorEmailInvalid,
|
|
RegistrationRejected() => l10n.authErrorRegistrationRejected,
|
|
NetworkFailure() => l10n.authErrorNetwork,
|
|
Unexpected() => l10n.authErrorUnexpected,
|
|
};
|
|
|
|
/// One sentence per distinct reason; an empty list gets the generic text.
|
|
String weakPasswordMessage(
|
|
AppLocalizations l10n,
|
|
List<WeakPasswordReason> reasons,
|
|
) {
|
|
final texts = <String>{
|
|
for (final reason in reasons)
|
|
switch (reason) {
|
|
WeakPasswordReason.length => l10n.authErrorWeakPasswordLength,
|
|
WeakPasswordReason.pwned => l10n.authErrorWeakPasswordPwned,
|
|
WeakPasswordReason.characters ||
|
|
WeakPasswordReason.unknown => l10n.authErrorWeakPasswordCharacters,
|
|
},
|
|
};
|
|
return texts.isEmpty ? l10n.authErrorWeakPasswordCharacters : texts.join(' ');
|
|
}
|
|
|
|
/// Failures the user can fix by simply trying again (offline, unexpected).
|
|
extension AuthFailureRetry on AuthFailure {
|
|
bool get isRetryable => this is NetworkFailure || this is Unexpected;
|
|
}
|