Sifa professional network API (Fastify, AT Protocol, Jetstream)
sifa.id/
1import { describe, it, expect } from 'vitest';
2import { resolveProfileFields } from '../../src/lib/resolve-profile.js';
3
4describe('resolveProfileFields', () => {
5 const source = {
6 headline: 'ATProto headline',
7 about: 'ATProto bio text',
8 displayName: 'Alice',
9 avatarUrl: 'https://bsky.example/avatar.jpg',
10 };
11
12 it('returns source values when no overrides exist', () => {
13 const result = resolveProfileFields(source, {
14 headline: null,
15 about: null,
16 displayName: null,
17 avatarUrl: null,
18 });
19 expect(result.headline).toBe('ATProto headline');
20 expect(result.about).toBe('ATProto bio text');
21 expect(result.displayName).toBe('Alice');
22 expect(result.avatarUrl).toBe('https://bsky.example/avatar.jpg');
23 expect(result.hasDisplayNameOverride).toBe(false);
24 expect(result.hasAvatarUrlOverride).toBe(false);
25 });
26
27 it('uses override when present', () => {
28 const result = resolveProfileFields(source, {
29 headline: 'Custom headline',
30 about: null,
31 displayName: null,
32 avatarUrl: null,
33 });
34 expect(result.headline).toBe('Custom headline');
35 expect(result.about).toBe('ATProto bio text');
36 });
37
38 it('uses override for both fields', () => {
39 const result = resolveProfileFields(source, {
40 headline: 'Custom headline',
41 about: 'Custom about',
42 displayName: null,
43 avatarUrl: null,
44 });
45 expect(result.headline).toBe('Custom headline');
46 expect(result.about).toBe('Custom about');
47 });
48
49 it('handles null source with override', () => {
50 const result = resolveProfileFields(
51 { headline: null, about: null, displayName: null, avatarUrl: null },
52 { headline: 'Override', about: null, displayName: null, avatarUrl: null },
53 );
54 expect(result.headline).toBe('Override');
55 expect(result.about).toBeNull();
56 });
57
58 it('handles null source and null override', () => {
59 const result = resolveProfileFields(
60 { headline: null, about: null, displayName: null, avatarUrl: null },
61 { headline: null, about: null, displayName: null, avatarUrl: null },
62 );
63 expect(result.headline).toBeNull();
64 expect(result.about).toBeNull();
65 expect(result.displayName).toBeNull();
66 expect(result.avatarUrl).toBeNull();
67 });
68
69 it('returns hasOverride true when any override is set', () => {
70 const result = resolveProfileFields(source, {
71 headline: 'Custom',
72 about: null,
73 displayName: null,
74 avatarUrl: null,
75 });
76 expect(result.hasHeadlineOverride).toBe(true);
77 expect(result.hasAboutOverride).toBe(false);
78 });
79
80 it('returns hasOverride false when no overrides', () => {
81 const result = resolveProfileFields(source, {
82 headline: null,
83 about: null,
84 displayName: null,
85 avatarUrl: null,
86 });
87 expect(result.hasHeadlineOverride).toBe(false);
88 expect(result.hasAboutOverride).toBe(false);
89 });
90
91 it('returns override displayName and avatarUrl when set', () => {
92 const result = resolveProfileFields(source, {
93 headline: null,
94 about: null,
95 displayName: 'Bob',
96 avatarUrl: 'https://sifa.id/uploads/avatars/test.webp',
97 });
98 expect(result.displayName).toBe('Bob');
99 expect(result.avatarUrl).toBe('https://sifa.id/uploads/avatars/test.webp');
100 expect(result.hasDisplayNameOverride).toBe(true);
101 expect(result.hasAvatarUrlOverride).toBe(true);
102 });
103
104 it('mixes overrides and source values across all fields', () => {
105 const result = resolveProfileFields(
106 { headline: 'src', about: 'src', displayName: 'Alice', avatarUrl: null },
107 { headline: null, about: 'override about', displayName: 'Bob', avatarUrl: null },
108 );
109 expect(result.displayName).toBe('Bob');
110 expect(result.avatarUrl).toBeNull();
111 expect(result.headline).toBe('src');
112 expect(result.about).toBe('override about');
113 expect(result.hasDisplayNameOverride).toBe(true);
114 expect(result.hasAvatarUrlOverride).toBe(false);
115 });
116});