Skip to content

Commit 321b0f8

Browse files
committed
test: add verification code storage tests
- Tests for code generation and validation - Covers expiry and removal scenarios
1 parent c39acc0 commit 321b0f8

File tree

1 file changed

+103
-0
lines changed

1 file changed

+103
-0
lines changed
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import 'package:ht_api/src/services/verification_code_storage_service.dart';
2+
import 'package:test/test.dart';
3+
4+
void main() {
5+
group('InMemoryVerificationCodeStorageService', () {
6+
late InMemoryVerificationCodeStorageService service;
7+
const testIdentifier = '[email protected]';
8+
const shortExpiry = Duration(milliseconds: 50); // Short expiry for testing
9+
10+
setUp(() {
11+
service = InMemoryVerificationCodeStorageService();
12+
});
13+
14+
tearDown(() {
15+
service.dispose(); // Ensure cleanup timer is cancelled
16+
});
17+
18+
test('generateAndStoreCode returns a 6-digit code and stores it', () async {
19+
final code = await service.generateAndStoreCode(testIdentifier);
20+
21+
expect(code, isA<String>());
22+
expect(code.length, equals(6));
23+
expect(int.tryParse(code), isNotNull); // Check if it's numeric
24+
25+
// Validate internally (should succeed immediately after generation)
26+
final isValid = await service.validateCode(testIdentifier, code);
27+
// Note: validateCode removes the code upon success, so we can't re-validate
28+
expect(isValid, isTrue);
29+
30+
// Check if removed after validation
31+
final isValidAgain = await service.validateCode(testIdentifier, code);
32+
expect(isValidAgain, isFalse);
33+
});
34+
35+
test('validateCode returns true for correct code within expiry', () async {
36+
final code = await service.generateAndStoreCode(
37+
testIdentifier,
38+
expiry: const Duration(seconds: 1), // Longer expiry for this test
39+
);
40+
final isValid = await service.validateCode(testIdentifier, code);
41+
expect(isValid, isTrue);
42+
});
43+
44+
test('validateCode returns false for incorrect code', () async {
45+
await service.generateAndStoreCode(testIdentifier);
46+
final isValid = await service.validateCode(testIdentifier, '000000');
47+
expect(isValid, isFalse);
48+
});
49+
50+
test('validateCode returns false for expired code', () async {
51+
final code = await service.generateAndStoreCode(
52+
testIdentifier,
53+
expiry: shortExpiry,
54+
);
55+
// Wait for the code to expire
56+
await Future<void>.delayed(shortExpiry * 1.5);
57+
final isValid = await service.validateCode(testIdentifier, code);
58+
expect(isValid, isFalse);
59+
});
60+
61+
test('validateCode returns false for non-existent identifier', () async {
62+
final isValid = await service.validateCode('[email protected]', '123456');
63+
expect(isValid, isFalse);
64+
});
65+
66+
67+
test('validateCode removes code after successful validation', () async {
68+
final code = await service.generateAndStoreCode(
69+
testIdentifier,
70+
expiry: const Duration(seconds: 1),
71+
);
72+
// First validation succeeds and removes code
73+
final isValidFirst = await service.validateCode(testIdentifier, code);
74+
expect(isValidFirst, isTrue);
75+
76+
// Second validation fails because code was removed
77+
final isValidSecond = await service.validateCode(testIdentifier, code);
78+
expect(isValidSecond, isFalse);
79+
});
80+
81+
test('removeCode removes the stored code', () async {
82+
final code = await service.generateAndStoreCode(testIdentifier);
83+
await service.removeCode(testIdentifier);
84+
final isValid = await service.validateCode(testIdentifier, code);
85+
expect(isValid, isFalse); // Should be false as code was removed
86+
});
87+
88+
test('removeCode does nothing for non-existent identifier', () async {
89+
// Expect no errors when removing a non-existent code
90+
await expectLater(
91+
() => service.removeCode('[email protected]'),
92+
completes,
93+
);
94+
});
95+
96+
// Note: Testing the automatic cleanup timer (`_cleanupExpiredCodes`)
97+
// directly is tricky without exposing internal state or using more
98+
// advanced testing techniques like fake_async.
99+
// However, the 'validateCode returns false for expired code' test
100+
// implicitly verifies that expired codes are handled correctly,
101+
// either by direct expiry check or eventual cleanup.
102+
});
103+
}

0 commit comments

Comments
 (0)