Sifa professional network frontend (Next.js, React, TailwindCSS)
sifa.id/
1import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2import {
3 createExternalAccount,
4 updateExternalAccount,
5 deleteExternalAccount,
6} from '@/lib/profile-api';
7
8const mockFetch = vi.fn();
9
10beforeEach(() => {
11 vi.stubGlobal('fetch', mockFetch);
12});
13
14afterEach(() => {
15 vi.unstubAllGlobals();
16});
17
18describe('createExternalAccount', () => {
19 it('sends POST with correct data', async () => {
20 mockFetch.mockResolvedValue({
21 ok: true,
22 json: () => Promise.resolve({ rkey: 'abc123', feedUrl: null }),
23 });
24
25 const result = await createExternalAccount({
26 platform: 'github',
27 url: 'https://github.com/testuser',
28 });
29
30 expect(result.success).toBe(true);
31 expect(result.rkey).toBe('abc123');
32 expect(mockFetch).toHaveBeenCalledWith(
33 expect.stringContaining('/api/profile/external-accounts'),
34 expect.objectContaining({ method: 'POST' }),
35 );
36 });
37
38 it('returns error on failure', async () => {
39 mockFetch.mockResolvedValue({
40 ok: false,
41 status: 401,
42 json: () => Promise.resolve({ message: 'Unauthorized' }),
43 });
44
45 const result = await createExternalAccount({
46 platform: 'github',
47 url: 'https://github.com/testuser',
48 });
49
50 expect(result.success).toBe(false);
51 });
52});
53
54describe('updateExternalAccount', () => {
55 it('sends PUT with rkey', async () => {
56 mockFetch.mockResolvedValue({ ok: true });
57
58 const result = await updateExternalAccount('abc123', {
59 platform: 'website',
60 url: 'https://example.com',
61 });
62
63 expect(result.success).toBe(true);
64 expect(mockFetch).toHaveBeenCalledWith(
65 expect.stringContaining('/api/profile/external-accounts/abc123'),
66 expect.objectContaining({ method: 'PUT' }),
67 );
68 });
69});
70
71describe('deleteExternalAccount', () => {
72 it('sends DELETE with rkey', async () => {
73 mockFetch.mockResolvedValue({ ok: true });
74
75 const result = await deleteExternalAccount('abc123');
76
77 expect(result.success).toBe(true);
78 expect(mockFetch).toHaveBeenCalledWith(
79 expect.stringContaining('/api/profile/external-accounts/abc123'),
80 expect.objectContaining({ method: 'DELETE' }),
81 );
82 });
83});