Sifa professional network frontend (Next.js, React, TailwindCSS)
sifa.id/
1import { describe, it, expect } from 'vitest';
2import { sanitizeHandleInput } from '../../src/lib/handle-utils';
3
4describe('sanitizeHandleInput', () => {
5 it('passes through a full handle unchanged', () => {
6 expect(sanitizeHandleInput('jay.bsky.social')).toBe('jay.bsky.social');
7 });
8
9 it('passes through a custom domain handle', () => {
10 expect(sanitizeHandleInput('alice.custom-pds.example')).toBe('alice.custom-pds.example');
11 });
12
13 it('passes through a DID unchanged', () => {
14 expect(sanitizeHandleInput('did:plc:abc123')).toBe('did:plc:abc123');
15 });
16
17 it('appends .bsky.social to bare usernames', () => {
18 expect(sanitizeHandleInput('jeroenwaelen')).toBe('jeroenwaelen.bsky.social');
19 });
20
21 it('strips https:// URL prefix from PDS domains', () => {
22 expect(sanitizeHandleInput('https://jeroenwaelen.bsky.social')).toBe(
23 'jeroenwaelen.bsky.social',
24 );
25 });
26
27 it('strips http:// URL prefix', () => {
28 expect(sanitizeHandleInput('http://alice.custom-pds.example')).toBe('alice.custom-pds.example');
29 });
30
31 it('strips Bluesky profile URL', () => {
32 expect(sanitizeHandleInput('https://bsky.app/profile/jay.bsky.social')).toBe('jay.bsky.social');
33 });
34
35 it('strips at:// URI', () => {
36 expect(sanitizeHandleInput('at://jay.bsky.social')).toBe('jay.bsky.social');
37 });
38
39 it('strips @ prefix', () => {
40 expect(sanitizeHandleInput('@jay.bsky.social')).toBe('jay.bsky.social');
41 });
42
43 it('strips trailing dot', () => {
44 expect(sanitizeHandleInput('jay.bsky.social.')).toBe('jay.bsky.social');
45 });
46
47 it('lowercases handles', () => {
48 expect(sanitizeHandleInput('Jay.Bsky.Social')).toBe('jay.bsky.social');
49 });
50
51 it('preserves DID case', () => {
52 expect(sanitizeHandleInput('did:plc:AbCdEf')).toBe('did:plc:AbCdEf');
53 });
54
55 it('strips trailing path segments from URLs', () => {
56 expect(sanitizeHandleInput('https://jeroenwaelen.bsky.social/some/path')).toBe(
57 'jeroenwaelen.bsky.social',
58 );
59 });
60
61 it('trims whitespace', () => {
62 expect(sanitizeHandleInput(' jay.bsky.social ')).toBe('jay.bsky.social');
63 });
64
65 it('returns empty string for empty input', () => {
66 expect(sanitizeHandleInput('')).toBe('');
67 expect(sanitizeHandleInput(' ')).toBe('');
68 });
69});