Sifa professional network frontend (Next.js, React, TailwindCSS)
sifa.id/
1import { render, screen } from '@testing-library/react';
2import userEvent from '@testing-library/user-event';
3import { describe, it, expect } from 'vitest';
4import { ActivityTooltip } from './activity-tooltip';
5
6describe('ActivityTooltip', () => {
7 it('shows tooltip on hover', async () => {
8 render(
9 <ActivityTooltip
10 appName="Tangled"
11 tooltipDescription="Git hosting on the AT Protocol."
12 appUrl="https://tangled.sh"
13 >
14 <button>Tangled</button>
15 </ActivityTooltip>,
16 );
17 await userEvent.hover(screen.getByRole('button'));
18 const tooltip = screen.getByRole('tooltip');
19 expect(tooltip.textContent).toContain('Git hosting on the AT Protocol.');
20 });
21
22 it('shows network note for shared namespaces', async () => {
23 render(
24 <ActivityTooltip
25 appName="Bluesky network"
26 tooltipDescription="Social networking on the AT Protocol."
27 tooltipNetworkNote="Posted using a Bluesky-compatible app. The specific client is unknown."
28 appUrl="https://bsky.app"
29 >
30 <button>Bluesky network</button>
31 </ActivityTooltip>,
32 );
33 await userEvent.hover(screen.getByRole('button'));
34 const tooltip = screen.getByRole('tooltip');
35 expect(tooltip.textContent).toContain('Social networking on the AT Protocol.');
36 expect(tooltip.textContent).toContain('The specific client is unknown.');
37 });
38
39 it('shows outbound link when appUrl provided', async () => {
40 render(
41 <ActivityTooltip
42 appName="Tangled"
43 tooltipDescription="Git hosting on the AT Protocol."
44 appUrl="https://tangled.sh"
45 >
46 <button>Tangled</button>
47 </ActivityTooltip>,
48 );
49 await userEvent.hover(screen.getByRole('button'));
50 const link = screen.getByRole('link');
51 expect(link.getAttribute('href')).toBe('https://tangled.sh');
52 });
53
54 it('omits link when no appUrl', async () => {
55 render(
56 <ActivityTooltip
57 appName="AT Protocol"
58 tooltipDescription="Activity from an AT Protocol app that Sifa doesn't recognize yet."
59 >
60 <button>AT Protocol</button>
61 </ActivityTooltip>,
62 );
63 await userEvent.hover(screen.getByRole('button'));
64 expect(screen.queryByRole('link')).toBeNull();
65 });
66
67 it('hides tooltip on mouse leave', async () => {
68 render(
69 <ActivityTooltip appName="Tangled" tooltipDescription="Git hosting on the AT Protocol.">
70 <button>Tangled</button>
71 </ActivityTooltip>,
72 );
73 const user = userEvent.setup();
74 await user.hover(screen.getByRole('button'));
75 expect(screen.getByRole('tooltip')).toBeDefined();
76 await user.unhover(screen.getByRole('button'));
77 // Wait for the 150ms delay
78 await new Promise((r) => setTimeout(r, 200));
79 expect(screen.queryByRole('tooltip')).toBeNull();
80 });
81});