From 0a04abe09ec566d3363300fbb5a8c8207badf36c Mon Sep 17 00:00:00 2001 From: Jermaine Date: Sun, 16 Mar 2025 06:46:48 -0400 Subject: [PATCH 1/3] feat: enhance upsert logic to support onConflict columns --- lib/src/mock_supabase_http_client.dart | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/lib/src/mock_supabase_http_client.dart b/lib/src/mock_supabase_http_client.dart index ebeab1c..b354ec5 100644 --- a/lib/src/mock_supabase_http_client.dart +++ b/lib/src/mock_supabase_http_client.dart @@ -434,13 +434,27 @@ class MockSupabaseHttpClient extends BaseClient { ? List>.from(data) : [Map.from(data)]; + // Get the onConflict columns + final onConflictColumns = + (request.url.queryParameters['on_conflict'] ?? 'id') + .split(',') + .map((e) => e.trim()) + .toList(); + // Upsert each item final results = items.map((item) { - final id = item['id']; - if (id != null) { - final index = - _database[tableKey]!.indexWhere((dbItem) => dbItem['id'] == id); + // Check if all onConflictColumns are set in item + final shouldUpdate = + onConflictColumns.every((column) => item[column] != null); + + if (shouldUpdate) { + // Find the index for an item that matches all onConflictColumns + final index = _database[tableKey]!.indexWhere((dbItem) => + onConflictColumns + .every((column) => dbItem[column] == item[column])); + if (index != -1) { + // Update the item in the database _database[tableKey]![index] = { ..._database[tableKey]![index], ...item From 2ebc81a33246aca9321a4962df619fa78562eb22 Mon Sep 17 00:00:00 2001 From: Jermaine Date: Sun, 16 Mar 2025 06:46:58 -0400 Subject: [PATCH 2/3] test: add upsert tests for single and multiple onConflict columns --- test/mock_supabase_http_client_test.dart | 44 ++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/test/mock_supabase_http_client_test.dart b/test/mock_supabase_http_client_test.dart index 63a158d..ce3f201 100644 --- a/test/mock_supabase_http_client_test.dart +++ b/test/mock_supabase_http_client_test.dart @@ -59,6 +59,50 @@ void main() { expect(postsUfterUpdate.first, {'id': 1, 'title': 'Updated post'}); }); + test('Upsert with single onConflict column, not id', () async { + final data = {'user_id': 1, 'name': 'John Doe'}; + const table = 'users'; + // Insert a record + await mockSupabase.from(table).insert(data); + final users = await mockSupabase.from(table).select(); + expect(users.first, data); + + final updatedData = { + ...data, + 'name': 'James Bond', + }; + await mockSupabase.from(table).upsert( + updatedData, + onConflict: 'user_id', + ); + final usersAfterUpdate = + await mockSupabase.from(table).select().eq('user_id', 1); + print(usersAfterUpdate.length); + expect(usersAfterUpdate.length, 1); + expect(usersAfterUpdate.first, updatedData); + }); + + test('Upsert with multiple onConflict columns', () async { + final data = {'user': 2, 'post': 1, 'title': 'Initial post'}; + // Test upserting a record + await mockSupabase.from('posts').insert(data); + final posts = await mockSupabase.from('posts').select(); + expect(posts.first, data); + + final updatedData = { + ...data, + 'title': 'Updated post', + }; + await mockSupabase.from('posts').upsert( + updatedData, + onConflict: 'user, post', + ); + final postsAfterUpdate = + await mockSupabase.from('posts').select().eq('user', 2).eq('post', 1); + expect(postsAfterUpdate.length, 1); + expect(postsAfterUpdate.first, updatedData); + }); + test('Upsert then select', () async { // Test upserting a record await mockSupabase From 903c9d66546769c2c4bd65f88157ff2cad8bdbdb Mon Sep 17 00:00:00 2001 From: Jermaine Date: Sun, 16 Mar 2025 06:49:42 -0400 Subject: [PATCH 3/3] chore: remove debug print statement from upsert test --- test/mock_supabase_http_client_test.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/test/mock_supabase_http_client_test.dart b/test/mock_supabase_http_client_test.dart index ce3f201..5917eaa 100644 --- a/test/mock_supabase_http_client_test.dart +++ b/test/mock_supabase_http_client_test.dart @@ -77,7 +77,6 @@ void main() { ); final usersAfterUpdate = await mockSupabase.from(table).select().eq('user_id', 1); - print(usersAfterUpdate.length); expect(usersAfterUpdate.length, 1); expect(usersAfterUpdate.first, updatedData); });