From 39974a766b2fc677530565b4f959a67c4d5dbaca Mon Sep 17 00:00:00 2001 From: rissrice2105-agent Date: Mon, 13 Jul 2026 12:52:10 -0600 Subject: [PATCH] fix(users): exclude current user from search --- src/app/api/users/search/route.js | 4 +-- src/app/api/users/search/route.test.js | 45 ++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 src/app/api/users/search/route.test.js diff --git a/src/app/api/users/search/route.js b/src/app/api/users/search/route.js index e8c49493..e5a70ab3 100644 --- a/src/app/api/users/search/route.js +++ b/src/app/api/users/search/route.js @@ -36,7 +36,7 @@ export async function GET(request, { params } = {}) { .from('users') .select('id, username, display_name, avatar_url, phone_number, unique_identifier') .or(`username.ilike.%${sanitizedQuery}%,display_name.ilike.%${sanitizedQuery}%,phone_number.ilike.%${sanitizedQuery}%,unique_identifier.ilike.%${sanitizedQuery}%`) - .neq('id', user.id) // Exclude current user + .neq('auth_user_id', user.id) // Exclude current user by the auth UUID .limit(50); // Get more results for better sorting if (error) { @@ -105,4 +105,4 @@ export async function GET(request, { params } = {}) { console.error('API error:', error); return NextResponse.json({ error: 'Internal server error' }, { status: 500 }); } -} \ No newline at end of file +} diff --git a/src/app/api/users/search/route.test.js b/src/app/api/users/search/route.test.js new file mode 100644 index 00000000..be4e64d1 --- /dev/null +++ b/src/app/api/users/search/route.test.js @@ -0,0 +1,45 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest'; + +const mocks = vi.hoisted(() => ({ + getUser: vi.fn(), + from: vi.fn(), + select: vi.fn(), + or: vi.fn(), + neq: vi.fn(), + limit: vi.fn(), + createSupabaseServerClient: vi.fn() +})); + +vi.mock('@/lib/supabase.js', () => ({ + createSupabaseServerClient: mocks.createSupabaseServerClient +})); + +describe('user search', () => { + beforeEach(() => { + vi.resetModules(); + vi.clearAllMocks(); + + mocks.getUser.mockResolvedValue({ + data: { user: { id: 'auth-user-1' } }, + error: null + }); + mocks.from.mockReturnValue({ select: mocks.select }); + mocks.select.mockReturnValue({ or: mocks.or }); + mocks.or.mockReturnValue({ neq: mocks.neq }); + mocks.neq.mockReturnValue({ limit: mocks.limit }); + mocks.limit.mockResolvedValue({ data: [], error: null }); + mocks.createSupabaseServerClient.mockResolvedValue({ + auth: { getUser: mocks.getUser }, + from: mocks.from + }); + }); + + it('excludes the authenticated user with the auth_user_id column', async () => { + const { GET } = await import('./route.js'); + + const response = await GET(new Request('https://example.com/api/users/search?q=alice')); + + expect(response.status).toBe(200); + expect(mocks.neq).toHaveBeenCalledWith('auth_user_id', 'auth-user-1'); + }); +});