A calm place to write long-form, and publish it to the open social web. skypress.blog/
0

Configure Feed

Select the types of activity you want to include in your feed.

at trunk 2.6 kB View raw
1import { describe, expect, it } from 'vitest'; 2import { detectBioSegments, safeHttpHref } from './rich-text'; 3 4describe( 'detectBioSegments', () => { 5 it( 'returns a single text segment for plain prose', () => { 6 expect( detectBioSegments( 'Just a writer.' ) ).toEqual( [ 7 { type: 'text', text: 'Just a writer.' }, 8 ] ); 9 } ); 10 11 it( 'returns an empty array for blank input', () => { 12 expect( detectBioSegments( ' ' ) ).toEqual( [] ); 13 } ); 14 15 it( 'linkifies a full URL and keeps trailing punctuation out of the link', () => { 16 expect( detectBioSegments( 'Visit https://example.com.' ) ).toEqual( [ 17 { type: 'text', text: 'Visit ' }, 18 { type: 'link', text: 'https://example.com', href: 'https://example.com' }, 19 { type: 'text', text: '.' }, 20 ] ); 21 } ); 22 23 it( 'linkifies a bare domain with an https href and bare display text', () => { 24 expect( detectBioSegments( 'example.com' ) ).toEqual( [ 25 { type: 'link', text: 'example.com', href: 'https://example.com' }, 26 ] ); 27 } ); 28 29 it( 'links a mention to its Bluesky profile by handle', () => { 30 expect( detectBioSegments( 'hi @alice.bsky.social' ) ).toEqual( [ 31 { type: 'text', text: 'hi ' }, 32 { 33 type: 'link', 34 text: '@alice.bsky.social', 35 href: 'https://mu.social/profile/alice.bsky.social', 36 }, 37 ] ); 38 } ); 39 40 it( 'links a hashtag to its Bluesky hashtag page', () => { 41 expect( detectBioSegments( 'love #design' ) ).toEqual( [ 42 { type: 'text', text: 'love ' }, 43 { type: 'link', text: '#design', href: 'https://mu.social/hashtag/design' }, 44 ] ); 45 } ); 46 47 it( 'orders mixed text, url, mention and tag segments correctly', () => { 48 expect( 49 detectBioSegments( 'me @alice.bsky.social #design example.com' ) 50 ).toEqual( [ 51 { type: 'text', text: 'me ' }, 52 { 53 type: 'link', 54 text: '@alice.bsky.social', 55 href: 'https://mu.social/profile/alice.bsky.social', 56 }, 57 { type: 'text', text: ' ' }, 58 { type: 'link', text: '#design', href: 'https://mu.social/hashtag/design' }, 59 { type: 'text', text: ' ' }, 60 { type: 'link', text: 'example.com', href: 'https://example.com' }, 61 ] ); 62 } ); 63} ); 64 65describe( 'safeHttpHref', () => { 66 it( 'passes http and https through unchanged', () => { 67 expect( safeHttpHref( 'https://example.com' ) ).toBe( 'https://example.com' ); 68 expect( safeHttpHref( 'http://example.com/x' ) ).toBe( 'http://example.com/x' ); 69 } ); 70 71 it( 'rejects non-http(s) schemes and garbage', () => { 72 expect( safeHttpHref( 'javascript:alert(1)' ) ).toBeNull(); 73 expect( safeHttpHref( 'ftp://example.com' ) ).toBeNull(); 74 expect( safeHttpHref( 'not a url' ) ).toBeNull(); 75 } ); 76} );