1
- import 'dart:convert' ;
2
1
import 'dart:io' ;
3
2
4
3
import 'package:dart_frog/dart_frog.dart' ;
@@ -12,7 +11,8 @@ import '../../../../../routes/api/v1/countries/index.dart' as route;
12
11
// --- Mocks ---
13
12
class _MockRequestContext extends Mock implements RequestContext {}
14
13
15
- class _MockHttpRequest extends Mock implements Request {} // Use dart_frog Request
14
+ class _MockHttpRequest extends Mock
15
+ implements Request {} // Use dart_frog Request
16
16
17
17
class _MockHtCountriesClient extends Mock implements HtCountriesClient {}
18
18
// --- End Mocks ---
@@ -98,7 +98,7 @@ void main() {
98
98
).called (1 );
99
99
});
100
100
101
- test ('uses max limit when limit parameter exceeds max' , () async {
101
+ test ('uses max limit when limit parameter exceeds max' , () async {
102
102
final countries = createSampleCountries (5 );
103
103
// Limit is 150, should be clamped to 100 (defined in route)
104
104
uri = Uri .parse ('http://localhost/api/v1/countries?limit=150' );
@@ -148,20 +148,25 @@ void main() {
148
148
equals ('Invalid query parameter: "limit" must be an integer.' ),
149
149
);
150
150
verifyNever (
151
- () => mockClient.fetchCountries (limit: any (named: 'limit' ), startAfterId: any (named: 'startAfterId' )),
151
+ () => mockClient.fetchCountries (
152
+ limit: any (named: 'limit' ),
153
+ startAfterId: any (named: 'startAfterId' ),
154
+ ),
152
155
);
153
156
});
154
157
155
- // Add test for client throwing CountryFetchFailure (handled by global handler)
158
+ // Add test for client throwing CountryFetchFailure
159
+ //(handled by global handler)
156
160
test ('lets CountryFetchFailure bubble up (handled globally)' , () async {
157
161
uri = Uri .parse ('http://localhost/api/v1/countries?limit=10' );
158
162
when (() => request.uri).thenReturn (uri);
159
- final exception = CountryFetchFailure ('DB error' );
163
+ const exception = CountryFetchFailure ('DB error' );
160
164
when (
161
165
() => mockClient.fetchCountries (limit: 10 , startAfterId: null ),
162
166
).thenThrow (exception);
163
167
164
- // Expect the specific exception to be thrown, letting the global handler catch it
168
+ // Expect the specific exception to be thrown, letting the global handler
169
+ // catch it
165
170
expect (
166
171
() => route.onRequest (context),
167
172
throwsA (isA <CountryFetchFailure >()),
@@ -183,7 +188,6 @@ void main() {
183
188
// Remove 'id' as it's generated by client/constructor usually
184
189
final requestJson = Map <String , dynamic >.from (newCountryJson)..remove ('id' );
185
190
186
-
187
191
setUp (() {
188
192
// Set request method for all POST tests in this group
189
193
when (() => request.method).thenReturn (HttpMethod .post);
@@ -215,7 +219,7 @@ void main() {
215
219
test ('returns 400 Bad Request for invalid JSON body' , () async {
216
220
// Override request.json stub to throw format exception
217
221
when (() => request.json ()).thenThrow (
218
- FormatException ('Unexpected character' ),
222
+ const FormatException ('Unexpected character' ),
219
223
);
220
224
221
225
final response = await route.onRequest (context);
@@ -228,10 +232,11 @@ void main() {
228
232
verifyNever (() => mockClient.createCountry (any ()));
229
233
});
230
234
231
- test ('returns 400 Bad Request for invalid country data structure' , () async {
232
- // Provide JSON missing a required field
233
- final invalidJson = {'iso_code' : 'DE' , 'flag_url' : '...' }; // Missing name
234
- when (() => request.json ()).thenAnswer ((_) async => invalidJson);
235
+ test ('returns 400 Bad Request for invalid country data structure' ,
236
+ () async {
237
+ // Provide JSON missing a required field
238
+ final invalidJson = {'iso_code' : 'DE' , 'flag_url' : '...' }; // Missing name
239
+ when (() => request.json ()).thenAnswer ((_) async => invalidJson);
235
240
236
241
final response = await route.onRequest (context);
237
242
@@ -243,9 +248,10 @@ void main() {
243
248
verifyNever (() => mockClient.createCountry (any ()));
244
249
});
245
250
246
- // Add test for client throwing CountryCreateFailure (handled by global handler)
247
- test ('lets CountryCreateFailure bubble up (handled globally)' , () async {
248
- final exception = CountryCreateFailure ('Duplicate entry' );
251
+ // Add test for client throwing CountryCreateFailure
252
+ // (handled by global handler)
253
+ test ('lets CountryCreateFailure bubble up (handled globally)' , () async {
254
+ const exception = CountryCreateFailure ('Duplicate entry' );
249
255
when (() => mockClient.createCountry (any ())).thenThrow (exception);
250
256
251
257
// Expect the specific exception to be thrown
@@ -258,7 +264,7 @@ void main() {
258
264
});
259
265
});
260
266
261
- test ('returns 405 Method Not Allowed for unsupported methods' , () async {
267
+ test ('returns 405 Method Not Allowed for unsupported methods' , () async {
262
268
// Test with PUT, DELETE etc.
263
269
when (() => request.method).thenReturn (HttpMethod .put);
264
270
final responsePut = await route.onRequest (context);
@@ -268,7 +274,12 @@ void main() {
268
274
final responseDelete = await route.onRequest (context);
269
275
expect (responseDelete.statusCode, equals (HttpStatus .methodNotAllowed));
270
276
271
- verifyNever (() => mockClient.fetchCountries (limit: any (named: 'limit' ), startAfterId: any (named: 'startAfterId' )));
272
- verifyNever (() => mockClient.createCountry (any ()));
277
+ verifyNever (
278
+ () => mockClient.fetchCountries (
279
+ limit: any (named: 'limit' ),
280
+ startAfterId: any (named: 'startAfterId' ),
281
+ ),
282
+ );
283
+ verifyNever (() => mockClient.createCountry (any ()));
273
284
});
274
285
}
0 commit comments