@@ -282,4 +282,208 @@ void main() {
282282 expect (xClientInfoHeader, 'supabase-flutter/0.0.0' );
283283 });
284284 });
285+
286+ group ('Client Advanced Features' , () {
287+ late SupabaseClient supabase;
288+ const supabaseUrl = 'https://example.supabase.co' ;
289+ const supabaseKey = 'test-key' ;
290+
291+ setUp (() {
292+ supabase = SupabaseClient (supabaseUrl, supabaseKey);
293+ });
294+
295+ tearDown (() async {
296+ await supabase.dispose ();
297+ });
298+
299+ group ('Headers Management' , () {
300+ test ('should update headers and propagate to all clients' , () {
301+ final newHeaders = {'Custom-Header' : 'custom-value' };
302+ supabase.headers = newHeaders;
303+
304+ expect (supabase.headers['Custom-Header' ], 'custom-value' );
305+ expect (supabase.rest.headers['Custom-Header' ], 'custom-value' );
306+ expect (supabase.functions.headers['Custom-Header' ], 'custom-value' );
307+ expect (supabase.storage.headers['Custom-Header' ], 'custom-value' );
308+ expect (supabase.realtime.headers['Custom-Header' ], 'custom-value' );
309+ });
310+
311+ test ('should preserve default headers when setting custom headers' , () {
312+ final newHeaders = {'Custom-Header' : 'custom-value' };
313+ supabase.headers = newHeaders;
314+
315+ expect (supabase.headers['X-Client-Info' ], startsWith ('supabase-dart/' ));
316+ });
317+
318+ test ('should not update auth headers when using custom access token' , () {
319+ final customTokenClient = SupabaseClient (
320+ supabaseUrl,
321+ supabaseKey,
322+ accessToken: () async => 'custom-token' ,
323+ );
324+
325+ final newHeaders = {'Custom-Header' : 'custom-value' };
326+ customTokenClient.headers = newHeaders;
327+
328+ expect (customTokenClient.headers['Custom-Header' ], 'custom-value' );
329+ });
330+ });
331+
332+ group ('Error Handling' , () {
333+ test (
334+ 'should throw AuthException when accessing auth with custom access token' ,
335+ () {
336+ final customTokenClient = SupabaseClient (
337+ supabaseUrl,
338+ supabaseKey,
339+ accessToken: () async => 'custom-token' ,
340+ );
341+
342+ expect (
343+ () => customTokenClient.auth,
344+ throwsA (isA <AuthException >()),
345+ );
346+ });
347+ });
348+
349+ group ('Schema Support' , () {
350+ test ('should create query builder with custom schema' , () {
351+ final customSchema = supabase.schema ('custom' );
352+ expect (customSchema, isA <SupabaseQuerySchema >());
353+
354+ final queryBuilder = customSchema.from ('table' );
355+ expect (queryBuilder, isA <SupabaseQueryBuilder >());
356+ });
357+
358+ test ('should handle nested schema calls' , () {
359+ final schema1 = supabase.schema ('schema1' );
360+ final schema2 = schema1.schema ('schema2' );
361+
362+ expect (schema2, isA <SupabaseQuerySchema >());
363+ });
364+ });
365+
366+ group ('RPC Support' , () {
367+ test ('should create RPC call' , () {
368+ final rpcCall = supabase.rpc ('test_function' );
369+ expect (rpcCall, isA <PostgrestFilterBuilder >());
370+ });
371+
372+ test ('should create RPC call with parameters' , () {
373+ final rpcCall =
374+ supabase.rpc ('test_function' , params: {'param' : 'value' });
375+ expect (rpcCall, isA <PostgrestFilterBuilder >());
376+ });
377+
378+ test ('should create RPC call with get flag' , () {
379+ final rpcCall = supabase.rpc ('test_function' , params: {}, get : true );
380+ expect (rpcCall, isA <PostgrestFilterBuilder >());
381+ });
382+ });
383+
384+ group ('Client Options' , () {
385+ test ('should accept custom Postgrest options' , () {
386+ final client = SupabaseClient (
387+ supabaseUrl,
388+ supabaseKey,
389+ postgrestOptions: PostgrestClientOptions (schema: 'custom_schema' ),
390+ );
391+
392+ expect (client, isA <SupabaseClient >());
393+ });
394+
395+ test ('should accept custom Auth options' , () {
396+ final client = SupabaseClient (
397+ supabaseUrl,
398+ supabaseKey,
399+ authOptions: AuthClientOptions (autoRefreshToken: false ),
400+ );
401+
402+ expect (client, isA <SupabaseClient >());
403+ });
404+
405+ test ('should accept custom Storage options' , () {
406+ final client = SupabaseClient (
407+ supabaseUrl,
408+ supabaseKey,
409+ storageOptions: StorageClientOptions (retryAttempts: 5 ),
410+ );
411+
412+ expect (client, isA <SupabaseClient >());
413+ });
414+
415+ test ('should accept custom Realtime options' , () {
416+ final client = SupabaseClient (
417+ supabaseUrl,
418+ supabaseKey,
419+ realtimeClientOptions:
420+ RealtimeClientOptions (logLevel: RealtimeLogLevel .debug),
421+ );
422+
423+ expect (client, isA <SupabaseClient >());
424+ });
425+ });
426+
427+ group ('Dispose' , () {
428+ test ('should properly dispose all resources' , () async {
429+ final client = SupabaseClient (supabaseUrl, supabaseKey);
430+
431+ // Should not throw
432+ await client.dispose ();
433+ });
434+ });
435+ });
436+
437+ group ('Query Schema' , () {
438+ late SupabaseClient supabase;
439+ const supabaseUrl = 'https://example.supabase.co' ;
440+ const supabaseKey = 'test-key' ;
441+
442+ setUp (() {
443+ supabase = SupabaseClient (supabaseUrl, supabaseKey);
444+ });
445+
446+ tearDown (() async {
447+ await supabase.dispose ();
448+ });
449+
450+ test ('should create SupabaseQueryBuilder from schema' , () {
451+ final schema = supabase.schema ('custom_schema' );
452+ final queryBuilder = schema.from ('test_table' );
453+
454+ expect (queryBuilder, isA <SupabaseQueryBuilder >());
455+ });
456+
457+ test ('should create nested schemas' , () {
458+ final schema1 = supabase.schema ('schema1' );
459+ final schema2 = schema1.schema ('schema2' );
460+
461+ expect (schema2, isA <SupabaseQuerySchema >());
462+ });
463+ });
464+
465+ group ('Query Builder' , () {
466+ late SupabaseClient supabase;
467+ const supabaseUrl = 'https://example.supabase.co' ;
468+ const supabaseKey = 'test-key' ;
469+
470+ setUp (() {
471+ supabase = SupabaseClient (supabaseUrl, supabaseKey);
472+ });
473+
474+ tearDown (() async {
475+ await supabase.dispose ();
476+ });
477+
478+ group ('Stream Creation' , () {
479+ test ('should throw assertion error for empty primary key' , () {
480+ final queryBuilder = supabase.from ('test_table' );
481+
482+ expect (
483+ () => queryBuilder.stream (primaryKey: []),
484+ throwsA (isA <AssertionError >()),
485+ );
486+ });
487+ });
488+ });
285489}
0 commit comments