Shuffle/app/test/features/auth/domain/auth_domain_test.dart
cschlaefke 3805c71225
Some checks failed
CI / flutter (pull_request) Failing after 44s
CI / web-build (pull_request) Successful in 51s
CI / supabase (pull_request) Successful in 3s
CI / supabase-tests (pull_request) Successful in 29s
CI / e2e (pull_request) Successful in 2m44s
fix(auth): address review findings for smtp-neutral handling
Refs #37

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-03 12:24:25 +01:00

132 lines
4.1 KiB
Dart

import 'package:flutter_test/flutter_test.dart';
import 'package:shuffle/features/auth/domain/auth_failure.dart';
import 'package:shuffle/features/auth/domain/email_link_type.dart';
import 'package:shuffle/features/auth/domain/resend_origin.dart';
void main() {
group('KTO-01 Kriterium 6: resendFailureFor (F12)', () {
const limited = AuthFailure.emailSendLimited();
test('check-email screen treats emailSendLimited as success', () {
expect(resendFailureFor(limited, ResendOrigin.checkEmail), isNull);
});
test('login screen shows the throttling hint', () {
expect(
resendFailureFor(limited, ResendOrigin.login),
const AuthFailure.rateLimited(),
);
});
test('F13: on the check-email screen unexpected (SMTP) is neutral', () {
expect(
resendFailureFor(
const AuthFailure.unexpected(),
ResendOrigin.checkEmail,
),
isNull,
);
for (final origin in ResendOrigin.values) {
expect(
resendFailureFor(const AuthFailure.emailNotConfirmed(), origin),
isNull,
);
}
});
test('S4: at login (account proven) unexpected stays visible', () {
expect(
resendFailureFor(const AuthFailure.unexpected(), ResendOrigin.login),
const AuthFailure.unexpected(),
);
});
test('input errors stay visible', () {
for (final origin in ResendOrigin.values) {
expect(
resendFailureFor(const AuthFailure.invalidEmail(), origin),
const AuthFailure.invalidEmail(),
);
}
});
test('allowlisted failures stay visible', () {
for (final origin in ResendOrigin.values) {
expect(
resendFailureFor(const AuthFailure.rateLimited(), origin),
const AuthFailure.rateLimited(),
);
expect(
resendFailureFor(const AuthFailure.network(), origin),
const AuthFailure.network(),
);
}
});
});
group('KTO-01 Kriterium 4: openEmailInputFailureFor (F12)', () {
test('emailSendLimited counts as success', () {
expect(
openEmailInputFailureFor(const AuthFailure.emailSendLimited()),
isNull,
);
});
test(
'F13: unexpected (SMTP outage) and unknown failures count as success',
() {
for (final failure in [
const AuthFailure.unexpected(),
const AuthFailure.emailNotConfirmed(),
const AuthFailure.invalidCredentials(),
const AuthFailure.linkInvalidOrExpired(),
]) {
expect(openEmailInputFailureFor(failure), isNull, reason: '$failure');
}
},
);
test('F13 allowlist: input, transport and IP throttling stay visible', () {
for (final failure in [
const AuthFailure.invalidEmail(),
const AuthFailure.weakPassword([WeakPasswordReason.length]),
const AuthFailure.registrationRejected(
reason: RegistrationRejectionReason.displayName,
),
const AuthFailure.network(),
const AuthFailure.rateLimited(),
]) {
expect(openEmailInputFailureFor(failure), failure);
}
});
test('registrationRejected without a known reason is neutral', () {
expect(
openEmailInputFailureFor(const AuthFailure.registrationRejected()),
isNull,
);
});
test('rateLimited stays visible', () {
expect(
openEmailInputFailureFor(const AuthFailure.rateLimited()),
const AuthFailure.rateLimited(),
);
});
});
group('KTO-01 Kriterium 8: EmailLinkType.tryParse', () {
test('maps email and signup to confirmation, recovery to recovery', () {
expect(EmailLinkType.tryParse('email'), EmailLinkType.confirmation);
expect(EmailLinkType.tryParse('signup'), EmailLinkType.confirmation);
expect(EmailLinkType.tryParse('recovery'), EmailLinkType.recovery);
});
test('rejects missing and unknown types', () {
expect(EmailLinkType.tryParse(null), isNull);
expect(EmailLinkType.tryParse(''), isNull);
expect(EmailLinkType.tryParse('magiclink'), isNull);
expect(EmailLinkType.tryParse('invite'), isNull);
});
});
}