Coves frontend - a photon fork
1import { describe, it, expect } from 'vitest'
2import type { EmbedImage } from '$lib/api/coves/types'
3import { parseProxyUrl, withPreset, imageUrl } from './image-proxy'
4
5describe('parseProxyUrl', () => {
6 it('parses a relative proxy URL', () => {
7 const result = parseProxyUrl(
8 '/img/avatar_small/plain/did:plc:abc123/bafkrei456',
9 )
10 expect(result).toEqual({
11 preset: 'avatar_small',
12 did: 'did:plc:abc123',
13 cid: 'bafkrei456',
14 })
15 })
16
17 it('parses a full proxy URL with base domain', () => {
18 const result = parseProxyUrl(
19 'https://coves.social/img/content_full/plain/did:plc:xyz/bafyrei789',
20 )
21 expect(result).toEqual({
22 preset: 'content_full',
23 did: 'did:plc:xyz',
24 cid: 'bafyrei789',
25 })
26 })
27
28 it('returns null for non-proxy URLs', () => {
29 expect(parseProxyUrl('https://example.com/image.jpg')).toBeNull()
30 expect(parseProxyUrl('')).toBeNull()
31 expect(parseProxyUrl('not-a-url')).toBeNull()
32 })
33
34 it('returns null for PDS blob URLs', () => {
35 expect(
36 parseProxyUrl(
37 'https://pds.example.com/xrpc/com.atproto.sync.getBlob?did=abc&cid=xyz',
38 ),
39 ).toBeNull()
40 })
41
42 it('parses a proxy URL with did:web: DID method', () => {
43 const result = parseProxyUrl(
44 'https://coves.social/img/avatar/plain/did:web:example.com/bafkrei456',
45 )
46 expect(result).toEqual({
47 preset: 'avatar',
48 did: 'did:web:example.com',
49 cid: 'bafkrei456',
50 })
51 })
52})
53
54describe('withPreset', () => {
55 it('swaps preset on a relative proxy URL', () => {
56 expect(
57 withPreset('/img/avatar_small/plain/did:plc:abc/bafkrei123', 'avatar'),
58 ).toBe('/img/avatar/plain/did:plc:abc/bafkrei123')
59 })
60
61 it('swaps preset on a full proxy URL', () => {
62 expect(
63 withPreset(
64 'https://coves.social/img/content_preview/plain/did:plc:xyz/bafyrei456',
65 'content_full',
66 ),
67 ).toBe('https://coves.social/img/content_full/plain/did:plc:xyz/bafyrei456')
68 })
69
70 it('returns non-proxy URLs unchanged', () => {
71 const pdsUrl =
72 'https://pds.example.com/xrpc/com.atproto.sync.getBlob?did=abc&cid=xyz'
73 expect(withPreset(pdsUrl, 'content_full')).toBe(pdsUrl)
74 })
75
76 it('returns empty string unchanged', () => {
77 expect(withPreset('', 'avatar')).toBe('')
78 })
79
80 it('strips query strings when swapping preset', () => {
81 const url =
82 'https://coves.social/img/avatar/plain/did:plc:abc/bafkrei123?format=webp'
83 const result = withPreset(url, 'content_full')
84 expect(result).toBe(
85 'https://coves.social/img/content_full/plain/did:plc:abc/bafkrei123',
86 )
87 })
88})
89
90describe('imageUrl', () => {
91 it('returns thumb when available for thumb variant', () => {
92 const img: EmbedImage = {
93 image: 'https://original.com/pic.jpg',
94 thumb: 'https://proxy.com/img/content_preview/plain/did:plc:a/baf1',
95 fullsize: 'https://proxy.com/img/content_full/plain/did:plc:a/baf1',
96 }
97 expect(imageUrl(img, 'thumb')).toBe(img.thumb)
98 })
99
100 it('returns fullsize when available for fullsize variant', () => {
101 const img: EmbedImage = {
102 image: 'https://original.com/pic.jpg',
103 thumb: 'https://proxy.com/img/content_preview/plain/did:plc:a/baf1',
104 fullsize: 'https://proxy.com/img/content_full/plain/did:plc:a/baf1',
105 }
106 expect(imageUrl(img, 'fullsize')).toBe(img.fullsize)
107 })
108
109 it('falls back to image when thumb is undefined', () => {
110 const img: EmbedImage = { image: 'https://original.com/pic.jpg' }
111 expect(imageUrl(img, 'thumb')).toBe(img.image)
112 })
113
114 it('falls back to image when fullsize is undefined', () => {
115 const img: EmbedImage = { image: 'https://original.com/pic.jpg' }
116 expect(imageUrl(img, 'fullsize')).toBe(img.image)
117 })
118
119 it('defaults to thumb variant', () => {
120 const img: EmbedImage = {
121 image: 'https://original.com/pic.jpg',
122 thumb: 'https://proxy.com/thumb',
123 }
124 expect(imageUrl(img)).toBe(img.thumb)
125 })
126
127 it('falls back to image when thumb is empty string', () => {
128 const img: EmbedImage = {
129 image: 'https://original.com/pic.jpg',
130 thumb: '',
131 }
132 expect(imageUrl(img, 'thumb')).toBe(img.image)
133 })
134
135 it('falls back to image when fullsize is empty string', () => {
136 const img: EmbedImage = {
137 image: 'https://original.com/pic.jpg',
138 fullsize: '',
139 }
140 expect(imageUrl(img, 'fullsize')).toBe(img.image)
141 })
142})