132 lines
4.1 KiB
Dart
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);
|
|
});
|
|
});
|
|
}
|