Sifa professional network frontend (Next.js, React, TailwindCSS) sifa.id/
at main 78 lines 2.7 kB view raw
1import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; 2import { updateProfileSelf, createRecord, updateRecord, deleteRecord } from '@/lib/profile-api'; 3 4const mockFetch = vi.fn(); 5 6beforeEach(() => { 7 vi.stubGlobal('fetch', mockFetch); 8}); 9 10afterEach(() => { 11 vi.unstubAllGlobals(); 12}); 13 14describe('profile-api', () => { 15 it('updateProfileSelf sends PUT with data', async () => { 16 mockFetch.mockResolvedValue({ ok: true }); 17 const result = await updateProfileSelf({ headline: 'Developer' }); 18 expect(result.success).toBe(true); 19 expect(mockFetch).toHaveBeenCalledWith( 20 expect.stringContaining('/api/profile/self'), 21 expect.objectContaining({ method: 'PUT' }), 22 ); 23 }); 24 25 it('createRecord sends POST and returns rkey', async () => { 26 mockFetch.mockResolvedValue({ 27 ok: true, 28 json: () => Promise.resolve({ rkey: 'tid123' }), 29 }); 30 const result = await createRecord('id.sifa.profile.position', { title: 'Eng' }); 31 expect(result.success).toBe(true); 32 expect(result.rkey).toBe('tid123'); 33 expect(mockFetch).toHaveBeenCalledWith( 34 expect.stringContaining('/api/profile/records/id.sifa.profile.position'), 35 expect.objectContaining({ method: 'POST' }), 36 ); 37 }); 38 39 it('updateRecord sends PUT with rkey', async () => { 40 mockFetch.mockResolvedValue({ ok: true }); 41 const result = await updateRecord('id.sifa.profile.position', 'abc123', { 42 title: 'Senior Eng', 43 }); 44 expect(result.success).toBe(true); 45 expect(mockFetch).toHaveBeenCalledWith( 46 expect.stringContaining('/api/profile/records/id.sifa.profile.position/abc123'), 47 expect.objectContaining({ method: 'PUT' }), 48 ); 49 }); 50 51 it('deleteRecord sends DELETE', async () => { 52 mockFetch.mockResolvedValue({ ok: true }); 53 const result = await deleteRecord('id.sifa.profile.position', 'abc123'); 54 expect(result.success).toBe(true); 55 expect(mockFetch).toHaveBeenCalledWith( 56 expect.stringContaining('/api/profile/records/id.sifa.profile.position/abc123'), 57 expect.objectContaining({ method: 'DELETE' }), 58 ); 59 }); 60 61 it('returns error on failed request', async () => { 62 mockFetch.mockResolvedValue({ 63 ok: false, 64 status: 401, 65 json: () => Promise.resolve({ message: 'Unauthorized' }), 66 }); 67 const result = await updateProfileSelf({ headline: 'Test' }); 68 expect(result.success).toBe(false); 69 expect(result.error).toBe('Unauthorized'); 70 }); 71 72 it('handles network errors', async () => { 73 mockFetch.mockRejectedValue(new Error('Network failure')); 74 const result = await updateProfileSelf({ headline: 'Test' }); 75 expect(result.success).toBe(false); 76 expect(result.error).toBe('Network error'); 77 }); 78});