diff --git a/src/app/api/chat/groups/route.js b/src/app/api/chat/groups/route.js index add12478..f4bee02e 100644 --- a/src/app/api/chat/groups/route.js +++ b/src/app/api/chat/groups/route.js @@ -2,7 +2,7 @@ import { NextResponse } from 'next/server'; import { createSupabaseServerClient } from '@/lib/supabase.js'; -export async function GET(request, { params } = {}) { +export async function GET() { try { const supabase = await createSupabaseServerClient(); @@ -12,9 +12,19 @@ export async function GET(request, { params } = {}) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } + const { data: userProfile, error: profileError } = await supabase + .from('users') + .select('id') + .eq('auth_user_id', user.id) + .single(); + + if (profileError || !userProfile) { + return NextResponse.json({ error: 'User not found' }, { status: 404 }); + } + // Call the user groups function const { data, error } = await supabase.rpc('get_user_groups', { - user_uuid: user.id + user_uuid: userProfile.id }); if (error) { @@ -27,4 +37,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/chat/groups/route.test.js b/src/app/api/chat/groups/route.test.js new file mode 100644 index 00000000..325d3d83 --- /dev/null +++ b/src/app/api/chat/groups/route.test.js @@ -0,0 +1,81 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest'; + +const mocks = vi.hoisted(() => ({ + getUser: vi.fn(), + from: vi.fn(), + userEq: vi.fn(), + rpc: vi.fn() +})); + +vi.mock('@/lib/supabase.js', () => ({ + createSupabaseServerClient: vi.fn(async () => ({ + auth: { getUser: mocks.getUser }, + from: mocks.from, + rpc: mocks.rpc + })) +})); + +function createUserQuery(result) { + const query = { + select: vi.fn(() => query), + eq: mocks.userEq, + single: vi.fn().mockResolvedValue(result) + }; + mocks.userEq.mockReturnValue(query); + return query; +} + +describe('GET /api/chat/groups', () => { + beforeEach(() => { + vi.resetModules(); + vi.clearAllMocks(); + mocks.getUser.mockResolvedValue({ + data: { user: { id: 'auth-user-id' } }, + error: null + }); + mocks.from.mockImplementation((table) => { + if (table === 'users') { + return createUserQuery({ + data: { id: 'internal-user-id' }, + error: null + }); + } + + throw new Error(`Unexpected table: ${table}`); + }); + mocks.rpc.mockResolvedValue({ + data: [{ group_id: 'group-1', group_name: 'Friends' }], + error: null + }); + }); + + it('loads groups with the internal user id resolved from auth_user_id', async () => { + const { GET } = await import('./route.js'); + const response = await GET(new Request('https://qrypt.chat/api/chat/groups')); + const body = await response.json(); + + expect(response.status).toBe(200); + expect(body.groups).toEqual([{ group_id: 'group-1', group_name: 'Friends' }]); + expect(mocks.userEq).toHaveBeenCalledWith('auth_user_id', 'auth-user-id'); + expect(mocks.rpc).toHaveBeenCalledWith('get_user_groups', { + user_uuid: 'internal-user-id' + }); + }); + + it('returns 404 without calling the RPC when the internal profile is missing', async () => { + mocks.from.mockImplementation((table) => { + if (table === 'users') { + return createUserQuery({ data: null, error: { message: 'not found' } }); + } + + throw new Error(`Unexpected table: ${table}`); + }); + + const { GET } = await import('./route.js'); + const response = await GET(new Request('https://qrypt.chat/api/chat/groups')); + + expect(response.status).toBe(404); + expect(await response.json()).toEqual({ error: 'User not found' }); + expect(mocks.rpc).not.toHaveBeenCalled(); + }); +});