Show accepted signup delivery without a second send step (#62)
This commit is contained in:
1 parent
e84d2d1ad3
commit
3af60f38b1
19 files changed
+421
-69
No files matched your search
@@ -142,11 +142,11 @@ void main() {
|
||||
.isSimulated,
|
||||
isTrue,
|
||||
);
|
||||
expect(
|
||||
(await const DummySignupService(delay: Duration.zero).signup(signup))
|
||||
.isSimulated,
|
||||
isTrue,
|
||||
);
|
||||
final accepted = await const DummySignupService(delay: Duration.zero)
|
||||
.signup(signup);
|
||||
expect(accepted.isSimulated, isTrue);
|
||||
expect(accepted.delivery?.email, 'a@example.com');
|
||||
expect(accepted.delivery?.isSimulated, isTrue);
|
||||
await expectLater(
|
||||
const DummyLoginService(
|
||||
delay: Duration.zero,
|
||||
|
||||
@@ -89,35 +89,48 @@ void main() {
|
||||
expect(keys[0], keys[1]);
|
||||
},
|
||||
);
|
||||
test('signup receipt avoids duplicate delivery and subsequent resend reaches API', () async {
|
||||
final paths = <String>[];
|
||||
final service = BackendAuthServices(
|
||||
baseUri: Uri.parse('https://api.example/api/v1'),
|
||||
clientId: 'web',
|
||||
client: MockClient((request) async {
|
||||
paths.add(request.url.path);
|
||||
if (request.url.path.endsWith('/signup')) {
|
||||
expect(jsonDecode(request.body)['password'], ' password preserved ');
|
||||
return response({'userId': 'user'});
|
||||
}
|
||||
return response({'accepted': true});
|
||||
}),
|
||||
);
|
||||
addTearDown(service.close);
|
||||
final result = await service.signup(
|
||||
const SignupRequest(
|
||||
name: 'User',
|
||||
email: 'USER@example.com',
|
||||
password: ' password preserved ',
|
||||
locale: 'en',
|
||||
),
|
||||
);
|
||||
expect(result.isSimulated, isFalse);
|
||||
await service.send(email: 'user@example.com', locale: 'en');
|
||||
expect(paths, ['/api/v1/accounts/signup']);
|
||||
await service.send(email: 'user@example.com', locale: 'en');
|
||||
expect(paths.last, '/api/v1/accounts/verification/send');
|
||||
});
|
||||
test(
|
||||
'signup returns its receipt and every explicit resend reaches API',
|
||||
() async {
|
||||
final paths = <String>[];
|
||||
final service = BackendAuthServices(
|
||||
baseUri: Uri.parse('https://api.example/api/v1'),
|
||||
clientId: 'web',
|
||||
client: MockClient((request) async {
|
||||
paths.add(request.url.path);
|
||||
if (request.url.path.endsWith('/signup')) {
|
||||
expect(
|
||||
jsonDecode(request.body)['password'],
|
||||
' password preserved ',
|
||||
);
|
||||
return response({'userId': 'user'});
|
||||
}
|
||||
return response({'accepted': true});
|
||||
}),
|
||||
);
|
||||
addTearDown(service.close);
|
||||
final result = await service.signup(
|
||||
const SignupRequest(
|
||||
name: 'User',
|
||||
email: 'USER@example.com',
|
||||
password: ' password preserved ',
|
||||
locale: 'en',
|
||||
),
|
||||
);
|
||||
expect(result.isSimulated, isFalse);
|
||||
expect(result.delivery?.email, 'user@example.com');
|
||||
expect(result.delivery?.isSimulated, isFalse);
|
||||
expect(paths, ['/api/v1/accounts/signup']);
|
||||
await service.send(email: 'user@example.com', locale: 'en');
|
||||
expect(paths, [
|
||||
'/api/v1/accounts/signup',
|
||||
'/api/v1/accounts/verification/send',
|
||||
]);
|
||||
await service.send(email: 'user@example.com', locale: 'en');
|
||||
expect(paths.last, '/api/v1/accounts/verification/send');
|
||||
expect(paths, hasLength(3));
|
||||
},
|
||||
);
|
||||
test('login confirms backend session only after factor and consumes local grant once', () async {
|
||||
final now = DateTime.now();
|
||||
var verified = false;
|
||||
|
||||
@@ -28,6 +28,36 @@ class PendingService implements VerificationService {
|
||||
}
|
||||
|
||||
void main() {
|
||||
test(
|
||||
'accepted delivery initializes sent state without calling the service',
|
||||
() async {
|
||||
final service = PendingService();
|
||||
final provider = VerificationProvider(
|
||||
service,
|
||||
delivery: const VerificationDelivery(
|
||||
email: 'ada@example.com',
|
||||
isSimulated: false,
|
||||
),
|
||||
);
|
||||
addTearDown(provider.dispose);
|
||||
expect(provider.state.status, VerificationStatus.sent);
|
||||
expect(provider.state.isSimulated, isFalse);
|
||||
expect(provider.state.result, isNull);
|
||||
expect(service.calls, 0);
|
||||
final resend = provider.send(email: 'ada@example.com', locale: 'en');
|
||||
expect(provider.state.status, VerificationStatus.sending);
|
||||
expect(service.calls, 1);
|
||||
service.pending.completeError(
|
||||
const VerificationException(VerificationError.internal),
|
||||
);
|
||||
await resend;
|
||||
expect(provider.state.status, VerificationStatus.error);
|
||||
expect(provider.state.result, isNull);
|
||||
provider.reset();
|
||||
expect(provider.state.status, VerificationStatus.idle);
|
||||
},
|
||||
);
|
||||
|
||||
for (final scenario in {
|
||||
'demo-valid': VerificationStatus.verified,
|
||||
'demo-expired': VerificationStatus.expired,
|
||||
|
||||
Reference in new issue
Block a user