@@ -2,55 +2,96 @@ import 'dart:convert';
22
33import 'package:http/http.dart' ;
44
5+ import 'mock_supabase_database.dart' ;
6+
57class MockSupabaseHttpClient extends BaseClient {
68 final Map <String , List <Map <String , dynamic >>> _database = {};
9+ final Map <
10+ String ,
11+ dynamic Function (
12+ MockSupabaseDatabase database, Map <String , dynamic >? params)>
13+ _rpcFunctions = {};
714
815 MockSupabaseHttpClient ();
916
1017 void reset () {
11- // Clear the mock database
18+ // Clear the mock database and RPC functions
1219 _database.clear ();
20+ _rpcFunctions.clear ();
21+ }
22+
23+ void registerRpcFunction (
24+ String name,
25+ dynamic Function (
26+ MockSupabaseDatabase database, Map <String , dynamic >? params)
27+ function) {
28+ _rpcFunctions[name] = function;
1329 }
1430
1531 @override
1632 Future <StreamedResponse > send (BaseRequest request) async {
17- // Extract the table name from the URL
18- final tableName = _extractTableName (
19- url: request.url,
20- headers: request.headers,
21- method: request.method,
22- );
33+ // Decode the request body if it's not a GET, DELETE, or HEAD request
34+ dynamic body;
35+ if (request.method != 'GET' &&
36+ request.method != 'DELETE' &&
37+ request.method != 'HEAD' &&
38+ request is Request ) {
39+ final String requestBody =
40+ await request.finalize ().transform (utf8.decoder).join ();
41+ if (requestBody.isNotEmpty) {
42+ body = jsonDecode (requestBody);
43+ }
44+ }
45+
46+ // Extract the table name or RPC function name from the URL
47+ final pathSegments = request.url.pathSegments;
48+ final restIndex = pathSegments.indexOf ('v1' );
49+ if (restIndex != - 1 && restIndex < pathSegments.length - 1 ) {
50+ final resourceName = pathSegments[restIndex + 1 ];
51+
52+ if (resourceName == 'rpc' ) {
53+ // Handle RPC call
54+ if (pathSegments.length > restIndex + 2 ) {
55+ final functionName = pathSegments[restIndex + 2 ];
56+ return _handleRpc (functionName, request, body);
57+ } else {
58+ return _createResponse ({'error' : 'RPC function name not provided' },
59+ statusCode: 400 , request: request);
60+ }
61+ } else {
62+ // Handle regular database operations
63+ final tableName = _extractTableName (
64+ url: request.url,
65+ headers: request.headers,
66+ method: request.method,
67+ );
2368
24- // Decode the request body if it's not a GET request
25- final body = (request.method != 'GET' &&
26- request.method != 'DELETE' &&
27- request.method != 'HEAD' ) &&
28- request is Request
29- ? jsonDecode (await request.finalize ().transform (utf8.decoder).join ())
30- : null ;
31-
32- // Handle different HTTP methods
33- switch (request.method) {
34- case 'POST' :
35- // Handle upsert if the Prefer header is set
36- final preferHeader = request.headers['Prefer' ];
37- if (preferHeader != null &&
38- preferHeader.contains ('resolution=merge-duplicates' )) {
39- return _handleUpsert (tableName, body, request);
69+ // Handle different HTTP methods
70+ switch (request.method) {
71+ case 'POST' :
72+ // Handle upsert if the Prefer header is set
73+ final preferHeader = request.headers['Prefer' ];
74+ if (preferHeader != null &&
75+ preferHeader.contains ('resolution=merge-duplicates' )) {
76+ return _handleUpsert (tableName, body, request);
77+ }
78+ return _handleInsert (tableName, body, request);
79+ case 'PATCH' :
80+ return _handleUpdate (tableName, body, request);
81+ case 'DELETE' :
82+ return _handleDelete (tableName, body, request);
83+ case 'GET' :
84+ return _handleSelect (
85+ tableName, request.url.queryParameters, request);
86+ case 'HEAD' :
87+ return _handleHead (tableName, request.url.queryParameters, request);
88+ default :
89+ return _createResponse ({'error' : 'Method not allowed' },
90+ statusCode: 405 , request: request);
4091 }
41- return _handleInsert (tableName, body, request);
42- case 'PATCH' :
43- return _handleUpdate (tableName, body, request);
44- case 'DELETE' :
45- return _handleDelete (tableName, body, request);
46- case 'GET' :
47- return _handleSelect (tableName, request.url.queryParameters, request);
48- case 'HEAD' :
49- return _handleHead (tableName, request.url.queryParameters, request);
50- default :
51- return _createResponse ({'error' : 'Method not allowed' },
52- statusCode: 405 , request: request);
92+ }
5393 }
94+ throw Exception ('Invalid URL format: unable to extract table name' );
5495 }
5596
5697 String _extractTableName ({
@@ -706,4 +747,23 @@ class MockSupabaseHttpClient extends BaseClient {
706747 request: request,
707748 );
708749 }
750+
751+ StreamedResponse _handleRpc (
752+ String functionName, BaseRequest request, dynamic body) {
753+ if (! _rpcFunctions.containsKey (functionName)) {
754+ return _createResponse ({'error' : 'RPC function not found' },
755+ statusCode: 404 , request: request);
756+ }
757+
758+ final function = _rpcFunctions[functionName]! ;
759+
760+ try {
761+ final mockDatabase = MockSupabaseDatabase (_database);
762+ final result = function (mockDatabase, body);
763+ return _createResponse (result, request: request);
764+ } catch (e) {
765+ return _createResponse ({'error' : 'RPC function execution failed: $e ' },
766+ statusCode: 500 , request: request);
767+ }
768+ }
709769}
0 commit comments