Skip to content

Commit f0d470e

Browse files
committed
test(gotrue): Add test to verify verifyOTP parameter ordering
1 parent 88ed5d8 commit f0d470e

File tree

1 file changed

+113
-0
lines changed

1 file changed

+113
-0
lines changed

packages/gotrue/test/otp_mock_test.dart

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
import 'dart:convert';
2+
13
import 'package:gotrue/gotrue.dart';
4+
import 'package:http/http.dart';
25
import 'package:test/test.dart';
36

47
import 'mocks/otp_mock_client.dart';
@@ -100,6 +103,34 @@ void main() {
100103
expect(client.currentUser?.email, testEmail);
101104
});
102105

106+
test('verifyOTP() sends correct parameters in request body', () async {
107+
// Test with specific email and token values from the issue
108+
const testOtp = '329169';
109+
const specificEmail = '[email protected]';
110+
111+
// Create a custom mock client that verifies the request body
112+
final verifyingMockClient = VerifyingOtpMockClient(
113+
expectedEmail: specificEmail,
114+
expectedToken: testOtp,
115+
);
116+
117+
final verifyingClient = GoTrueClient(
118+
url: 'https://example.com',
119+
httpClient: verifyingMockClient,
120+
asyncStorage: asyncStorage,
121+
);
122+
123+
// This should succeed if parameters are sent correctly
124+
await verifyingClient.verifyOTP(
125+
email: specificEmail,
126+
token: testOtp,
127+
type: OtpType.email,
128+
);
129+
130+
// Test passes if no exceptions were thrown
131+
expect(verifyingMockClient.requestWasValid, isTrue);
132+
});
133+
103134
test('verifyOTP() with recovery type', () async {
104135
final response = await client.verifyOTP(
105136
email: testEmail,
@@ -602,3 +633,85 @@ void main() {
602633
});
603634
});
604635
}
636+
637+
/// A mock client that verifies the request body contains expected email and token values
638+
class VerifyingOtpMockClient extends BaseClient {
639+
final String expectedEmail;
640+
final String expectedToken;
641+
bool requestWasValid = false;
642+
643+
VerifyingOtpMockClient({
644+
required this.expectedEmail,
645+
required this.expectedToken,
646+
});
647+
648+
@override
649+
Future<StreamedResponse> send(BaseRequest request) async {
650+
if (request.url.toString().contains('/verify') && request is Request) {
651+
final requestBody = json.decode(request.body) as Map<String, dynamic>;
652+
653+
// Verify that email parameter maps to 'email' field
654+
if (requestBody['email'] != expectedEmail) {
655+
throw Exception(
656+
'Expected email "$expectedEmail" in request body "email" field, '
657+
'but got "${requestBody['email']}"'
658+
);
659+
}
660+
661+
// Verify that token parameter maps to 'token' field
662+
if (requestBody['token'] != expectedToken) {
663+
throw Exception(
664+
'Expected token "$expectedToken" in request body "token" field, '
665+
'but got "${requestBody['token']}"'
666+
);
667+
}
668+
669+
// Verify parameters are not swapped
670+
if (requestBody['email'] == expectedToken || requestBody['token'] == expectedEmail) {
671+
throw Exception(
672+
'Parameters appear to be swapped! '
673+
'email field contains: "${requestBody['email']}", '
674+
'token field contains: "${requestBody['token']}"'
675+
);
676+
}
677+
678+
requestWasValid = true;
679+
680+
// Return a valid response
681+
final now = DateTime.now().toIso8601String();
682+
return StreamedResponse(
683+
Stream.value(utf8.encode(jsonEncode({
684+
'access_token': 'mock-access-token',
685+
'token_type': 'bearer',
686+
'expires_in': 3600,
687+
'refresh_token': 'mock-refresh-token',
688+
'user': {
689+
'id': 'mock-user-id',
690+
'aud': 'authenticated',
691+
'role': 'authenticated',
692+
'email': expectedEmail,
693+
'email_confirmed_at': now,
694+
'confirmed_at': now,
695+
'last_sign_in_at': now,
696+
'created_at': now,
697+
'updated_at': now,
698+
'app_metadata': {
699+
'provider': 'email',
700+
'providers': ['email'],
701+
},
702+
'user_metadata': {},
703+
'identities': [],
704+
},
705+
}))),
706+
200,
707+
request: request,
708+
);
709+
}
710+
711+
return StreamedResponse(
712+
Stream.value(utf8.encode(jsonEncode({'error': 'Unhandled request'}))),
713+
404,
714+
request: request,
715+
);
716+
}
717+
}

0 commit comments

Comments
 (0)