A calm place to write long-form, and publish it to the open social web.
skypress.blog/
1import { describe, it, expect } from 'vitest';
2import { createElement } from 'react';
3import { renderToStaticMarkup } from 'react-dom/server';
4import { ActionsGate } from './PostActions';
5import { AuthContext, type AuthContextValue } from '../lib/auth/AuthProvider';
6
7const PROPS = { postUri: 'at://did:plc:writer/app.bsky.feed.post/3kpost', postCid: 'bafypost' };
8
9/** Render ActionsGate under a hand-rolled auth context (bypasses real OAuth). */
10function renderGate( auth: Partial< AuthContextValue > ): string {
11 const value: AuthContextValue = {
12 status: 'signed-out',
13 agent: null,
14 did: null,
15 handle: null,
16 displayName: null,
17 avatar: null,
18 pdsUrl: null,
19 error: null,
20 signIn: async () => {},
21 signOut: async () => {},
22 ...auth,
23 };
24 return renderToStaticMarkup(
25 createElement( AuthContext.Provider, { value }, createElement( ActionsGate, PROPS ) )
26 );
27}
28
29describe( 'PostActions render branches', () => {
30 it( 'shows a loading state while auth initialises', () => {
31 expect( renderGate( { status: 'loading' } ) ).toContain( 'Loading actions…' );
32 } );
33
34 it( 'prompts sign-in (with the public-actions note) when signed out', () => {
35 const markup = renderGate( { status: 'signed-out' } );
36 expect( markup ).toContain( 'Sign in to react' );
37 expect( markup.toLowerCase() ).toContain( 'public' );
38 // Even signed-out, the thread is linkable on Bluesky.
39 expect( markup ).toContain( 'bsky.app/profile/did:plc:writer/post/3kpost' );
40 } );
41
42 it( 'renders the four actions when signed in', () => {
43 const markup = renderGate( {
44 status: 'signed-in',
45 agent: {} as never,
46 did: 'did:plc:reader',
47 handle: 'reader.test',
48 } );
49 expect( markup ).toContain( 'Like' );
50 expect( markup ).toContain( 'Repost' );
51 expect( markup ).toContain( 'Quote' );
52 expect( markup ).toContain( 'Reply' );
53 expect( markup.toLowerCase() ).toContain( 'public' );
54 } );
55
56 it( 'surfaces a sign-in error while still signed out (signIn sets error, not status)', () => {
57 // AuthProvider.signIn reports invalid handles / sign-in failures via `error`
58 // without flipping `status` to 'error', so the affordance must show it regardless.
59 const markup = renderGate( {
60 status: 'signed-out',
61 error: 'Enter a handle (alice.bsky.social), a DID, or a PDS URL.',
62 } );
63 expect( markup ).toContain( 'Enter a handle' );
64 expect( markup ).toContain( 'role="alert"' );
65 } );
66} );