Skip to content

Commit 7165819

Browse files
committed
test: add tests for anonymous auth route
- Tests 200 OK on success - Tests 405 Method Not Allowed - Tests 500 on AuthService errors
1 parent ffbb3a0 commit 7165819

File tree

1 file changed

+142
-0
lines changed

1 file changed

+142
-0
lines changed
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
import 'dart:convert';
2+
import 'dart:io';
3+
4+
import 'package:dart_frog/dart_frog.dart';
5+
import 'package:ht_api/src/services/auth_service.dart';
6+
import 'package:ht_shared/ht_shared.dart';
7+
import 'package:mocktail/mocktail.dart';
8+
import 'package:test/test.dart';
9+
10+
import '../../../../helpers/create_mock_request_context.dart';
11+
import '../../../../helpers/mock_classes.dart';
12+
// Import the actual route handler
13+
import '../../../../../routes/api/v1/auth/anonymous.dart' as route;
14+
15+
void main() {
16+
group('POST /api/v1/auth/anonymous', () {
17+
late MockAuthService mockAuthService;
18+
late MockRequest mockRequest;
19+
20+
// Define a sample user and token for success cases
21+
final testUser = User(id: 'anon-123', isAnonymous: true);
22+
const testToken = 'test-auth-token';
23+
final authResult = (user: testUser, token: testToken);
24+
25+
// Expected success response payload
26+
final successPayload = SuccessApiResponse<AuthSuccessResponse>(
27+
data: AuthSuccessResponse(user: testUser, token: testToken),
28+
);
29+
final expectedSuccessBody = jsonEncode(
30+
successPayload.toJson((auth) => auth.toJson()),
31+
);
32+
33+
setUp(() {
34+
mockAuthService = MockAuthService();
35+
mockRequest = MockRequest();
36+
37+
// Default stub for POST method
38+
when(() => mockRequest.method).thenReturn(HttpMethod.post);
39+
// Default stub for headers (can be overridden)
40+
when(() => mockRequest.headers).thenReturn({});
41+
// Default stub for body (can be overridden)
42+
when(() => mockRequest.body()).thenAnswer((_) async => '');
43+
when(() => mockRequest.json()).thenAnswer((_) async => <String, dynamic>{});
44+
});
45+
46+
test('returns 200 OK with user and token on successful anonymous sign-in',
47+
() async {
48+
// Arrange
49+
when(() => mockAuthService.performAnonymousSignIn())
50+
.thenAnswer((_) async => authResult);
51+
52+
final context = createMockRequestContext(
53+
request: mockRequest,
54+
dependencies: {
55+
AuthService: mockAuthService,
56+
},
57+
);
58+
59+
// Act
60+
final response = await route.onRequest(context);
61+
62+
// Assert
63+
expect(response.statusCode, equals(HttpStatus.ok));
64+
expect(
65+
await response.body(),
66+
equals(expectedSuccessBody),
67+
);
68+
expect(
69+
response.headers[HttpHeaders.contentTypeHeader],
70+
equals('application/json'),
71+
);
72+
verify(() => mockAuthService.performAnonymousSignIn()).called(1);
73+
});
74+
75+
test('returns 405 Method Not Allowed for non-POST requests', () async {
76+
// Arrange
77+
when(() => mockRequest.method).thenReturn(HttpMethod.get); // Test GET
78+
final context = createMockRequestContext(
79+
request: mockRequest,
80+
dependencies: {
81+
AuthService: mockAuthService,
82+
},
83+
);
84+
85+
// Act
86+
final response = await route.onRequest(context);
87+
88+
// Assert
89+
expect(response.statusCode, equals(HttpStatus.methodNotAllowed));
90+
verifyNever(() => mockAuthService.performAnonymousSignIn());
91+
});
92+
93+
test('returns 500 Internal Server Error when AuthService throws OperationFailedException',
94+
() async {
95+
// Arrange
96+
const exception = OperationFailedException('Database connection failed');
97+
when(() => mockAuthService.performAnonymousSignIn()).thenThrow(exception);
98+
99+
final context = createMockRequestContext(
100+
request: mockRequest,
101+
dependencies: {
102+
AuthService: mockAuthService,
103+
},
104+
);
105+
106+
// Act & Assert
107+
// Expect the handler to rethrow, letting middleware handle it
108+
expect(
109+
() => route.onRequest(context),
110+
throwsA(isA<OperationFailedException>()),
111+
);
112+
verify(() => mockAuthService.performAnonymousSignIn()).called(1);
113+
// Note: We test the *handler's* behavior (rethrowing).
114+
// The final 500 response format is tested in the error handler middleware tests.
115+
});
116+
117+
test('returns 500 Internal Server Error for unexpected errors', () async {
118+
// Arrange
119+
final exception = Exception('Something unexpected went wrong');
120+
when(() => mockAuthService.performAnonymousSignIn()).thenThrow(exception);
121+
122+
final context = createMockRequestContext(
123+
request: mockRequest,
124+
dependencies: {
125+
AuthService: mockAuthService,
126+
},
127+
);
128+
129+
// Act & Assert
130+
// The handler catches generic exceptions and throws OperationFailedException
131+
expect(
132+
() => route.onRequest(context),
133+
throwsA(isA<OperationFailedException>().having(
134+
(e) => e.message,
135+
'message',
136+
'An unexpected error occurred during anonymous sign-in.',
137+
)),
138+
);
139+
verify(() => mockAuthService.performAnonymousSignIn()).called(1);
140+
});
141+
});
142+
}

0 commit comments

Comments
 (0)