A calm place to write long-form, and publish it to the open social web.
skypress.blog/
1import { afterEach, describe, expect, it, vi } from 'vitest';
2import { resolveHandleToDid } from './identity';
3
4/**
5 * The read path takes the author straight from the URL (`/@<author>`) and uses it as a
6 * resolver fetch host. These tests lock in that a non-handle-shaped value (path/port/
7 * query/scheme smuggling) is rejected BEFORE any network request — so the worker can't be
8 * turned into a request proxy. `safeFetch` is the internal-host backstop; this is the
9 * syntactic gate in front of it.
10 */
11describe( 'resolveHandleToDid — read-path input validation', () => {
12 afterEach( () => {
13 vi.unstubAllGlobals();
14 } );
15
16 it( 'rejects non-handle input without making any network request', async () => {
17 const fetchSpy = vi.fn();
18 vi.stubGlobal( 'fetch', fetchSpy );
19
20 for ( const bad of [
21 'evil.com/.well-known/atproto-did',
22 'evil.com?x=y',
23 'evil.com:8080',
24 'http://evil.com',
25 'user@evil.com',
26 '',
27 ' ',
28 'notahandle',
29 ] ) {
30 expect( await resolveHandleToDid( bad ) ).toBeNull();
31 }
32 expect( fetchSpy ).not.toHaveBeenCalled();
33 } );
34
35 it( 'returns a DID unchanged without a network request', async () => {
36 const fetchSpy = vi.fn();
37 vi.stubGlobal( 'fetch', fetchSpy );
38
39 expect( await resolveHandleToDid( 'did:plc:abc123' ) ).toBe( 'did:plc:abc123' );
40 expect( fetchSpy ).not.toHaveBeenCalled();
41 } );
42} );