Skip to content

Commit a359088

Browse files
committed
test: add HtEmailRepository tests
- Implemented unit tests - Covers success and error cases - Uses mocktail for mocking
1 parent 8510da6 commit a359088

File tree

1 file changed

+180
-0
lines changed

1 file changed

+180
-0
lines changed
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,181 @@
1+
// test/src/ht_email_repository_test.dart
2+
import 'package:ht_email_client/ht_email_client.dart';
3+
import 'package:ht_email_repository/ht_email_repository.dart';
4+
import 'package:ht_shared/ht_shared.dart'; // For HtHttpException and subtypes
5+
import 'package:mocktail/mocktail.dart';
6+
import 'package:test/test.dart';
17

8+
// Mock for the HtEmailClient dependency
9+
class MockHtEmailClient extends Mock implements HtEmailClient {}
10+
11+
void main() {
12+
group('HtEmailRepository', () {
13+
late HtEmailClient mockEmailClient;
14+
late HtEmailRepository emailRepository;
15+
16+
const testEmail = '[email protected]';
17+
const testOtpCode = '123456';
18+
19+
setUp(() {
20+
mockEmailClient = MockHtEmailClient();
21+
emailRepository = HtEmailRepository(emailClient: mockEmailClient);
22+
23+
// Register fallback values for any() matchers if needed,
24+
// especially for parameters with default values or complex types.
25+
// Example: registerFallbackValue(Uri.parse('http://example.com'));
26+
});
27+
28+
// Teardown can be used to reset mocks after each test if necessary
29+
// tearDown(() {
30+
// reset(mockEmailClient);
31+
// });
32+
33+
test('can be instantiated', () {
34+
expect(HtEmailRepository(emailClient: MockHtEmailClient()), isNotNull);
35+
});
36+
37+
group('sendOtpEmail', () {
38+
test('calls sendOtpEmail on client successfully', () async {
39+
// Arrange
40+
when(
41+
() => mockEmailClient.sendOtpEmail(
42+
recipientEmail: any(named: 'recipientEmail'),
43+
otpCode: any(named: 'otpCode'),
44+
),
45+
).thenAnswer((_) async {}); // Simulate successful void return
46+
47+
// Act
48+
await emailRepository.sendOtpEmail(
49+
recipientEmail: testEmail,
50+
otpCode: testOtpCode,
51+
);
52+
53+
// Assert
54+
verify(
55+
() => mockEmailClient.sendOtpEmail(
56+
recipientEmail: testEmail,
57+
otpCode: testOtpCode,
58+
),
59+
).called(1);
60+
// Verify no other methods were called on the mock
61+
verifyNoMoreInteractions(mockEmailClient);
62+
});
63+
64+
test('propagates NetworkException from client', () async {
65+
// Arrange
66+
final exception = NetworkException();
67+
when(
68+
() => mockEmailClient.sendOtpEmail(
69+
recipientEmail: any(named: 'recipientEmail'),
70+
otpCode: any(named: 'otpCode'),
71+
),
72+
).thenThrow(exception); // Simulate client throwing the exception
73+
74+
// Act & Assert
75+
expect(
76+
() => emailRepository.sendOtpEmail(
77+
recipientEmail: testEmail,
78+
otpCode: testOtpCode,
79+
),
80+
throwsA(exception), // Expect the exact exception to be propagated
81+
);
82+
83+
// Verify the client method was called
84+
verify(
85+
() => mockEmailClient.sendOtpEmail(
86+
recipientEmail: testEmail,
87+
otpCode: testOtpCode,
88+
),
89+
).called(1);
90+
verifyNoMoreInteractions(mockEmailClient);
91+
});
92+
93+
test('propagates InvalidInputException from client', () async {
94+
// Arrange
95+
final exception = InvalidInputException('Invalid email format');
96+
when(
97+
() => mockEmailClient.sendOtpEmail(
98+
recipientEmail: any(named: 'recipientEmail'),
99+
otpCode: any(named: 'otpCode'),
100+
),
101+
).thenThrow(exception);
102+
103+
// Act & Assert
104+
expect(
105+
() => emailRepository.sendOtpEmail(
106+
recipientEmail: testEmail,
107+
otpCode: testOtpCode,
108+
),
109+
throwsA(exception),
110+
);
111+
112+
// Verify
113+
verify(
114+
() => mockEmailClient.sendOtpEmail(
115+
recipientEmail: testEmail,
116+
otpCode: testOtpCode,
117+
),
118+
).called(1);
119+
verifyNoMoreInteractions(mockEmailClient);
120+
});
121+
122+
test('propagates ServerException from client', () async {
123+
// Arrange
124+
final exception = ServerException('Email service unavailable');
125+
when(
126+
() => mockEmailClient.sendOtpEmail(
127+
recipientEmail: any(named: 'recipientEmail'),
128+
otpCode: any(named: 'otpCode'),
129+
),
130+
).thenThrow(exception);
131+
132+
// Act & Assert
133+
expect(
134+
() => emailRepository.sendOtpEmail(
135+
recipientEmail: testEmail,
136+
otpCode: testOtpCode,
137+
),
138+
throwsA(exception),
139+
);
140+
141+
// Verify
142+
verify(
143+
() => mockEmailClient.sendOtpEmail(
144+
recipientEmail: testEmail,
145+
otpCode: testOtpCode,
146+
),
147+
).called(1);
148+
verifyNoMoreInteractions(mockEmailClient);
149+
});
150+
151+
test('propagates OperationFailedException from client', () async {
152+
// Arrange
153+
final exception = OperationFailedException('Unknown sending error');
154+
when(
155+
() => mockEmailClient.sendOtpEmail(
156+
recipientEmail: any(named: 'recipientEmail'),
157+
otpCode: any(named: 'otpCode'),
158+
),
159+
).thenThrow(exception);
160+
161+
// Act & Assert
162+
expect(
163+
() => emailRepository.sendOtpEmail(
164+
recipientEmail: testEmail,
165+
otpCode: testOtpCode,
166+
),
167+
throwsA(exception),
168+
);
169+
170+
// Verify
171+
verify(
172+
() => mockEmailClient.sendOtpEmail(
173+
recipientEmail: testEmail,
174+
otpCode: testOtpCode,
175+
),
176+
).called(1);
177+
verifyNoMoreInteractions(mockEmailClient);
178+
});
179+
}); // End group 'sendOtpEmail'
180+
}); // End group 'HtEmailRepository'
181+
} // End main

0 commit comments

Comments
 (0)