Skip to content

Commit 3ed7385

Browse files
cursoragentjoepio
andcommitted
test: cover invite session-drive selection
Extract inviteSessionDrive so a child invite cannot land on an unread parent. Unit tests pin drive-level vs child-resource behavior. Co-authored-by: joepmeindertsma <joepmeindertsma@gmail.com>
1 parent b71a7ca commit 3ed7385

4 files changed

Lines changed: 67 additions & 3 deletions

File tree

TESTING_COVERAGE.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@ Both matter because `iroh_transport` holds the router and node identity in
139139
|---|---|---|
140140
| Extract agent mentions from TipTap JSON / chat text | glue | `browser/lib/src/mentions.test.ts` |
141141
| Populate includes NotificationItem / watches ontology | unit | `populate::notifications_ontology_is_populated` |
142+
| Child invite keeps session on private drive | unit | `inviteSessionDrive.test.ts` |
143+
| Drive-level invite activates the granted host | unit | same |
144+
| Chatroom invite sidebar is `{name}'s Drive` | flow | `browser/e2e/tests/e2e.spec.ts` (`chatroom` @smoke) |
142145
| Sidebar Notifications + empty inbox | flow | `browser/e2e/tests/notifications.spec.ts` |
143146
| `/app/dev-drive` workspace ≠ personal inbox drive | flow | `notifications.spec.ts` (`dev-drive workspace is not the personal inbox drive`) |
144147
| Seeded NotificationItem appears with unread badge | flow | `notifications.spec.ts` |
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { describe, expect, it } from 'vitest';
2+
import { inviteSessionDrive } from './inviteSessionDrive';
3+
4+
const PRIVATE = 'did:ad:private';
5+
const HOST = 'did:ad:host';
6+
7+
describe('inviteSessionDrive', () => {
8+
it('keeps a child invite on the private drive even when ancestry named a host', () => {
9+
expect(
10+
inviteSessionDrive({
11+
privateDrive: PRIVATE,
12+
hostDrive: HOST,
13+
destinationIsDrive: false,
14+
}),
15+
).toBe(PRIVATE);
16+
});
17+
18+
it('lands a drive-level invite on the host', () => {
19+
expect(
20+
inviteSessionDrive({
21+
privateDrive: PRIVATE,
22+
hostDrive: HOST,
23+
destinationIsDrive: true,
24+
}),
25+
).toBe(HOST);
26+
});
27+
28+
it('falls back to the private drive if a drive invite has no host bookmark', () => {
29+
expect(
30+
inviteSessionDrive({
31+
privateDrive: PRIVATE,
32+
destinationIsDrive: true,
33+
}),
34+
).toBe(PRIVATE);
35+
});
36+
37+
it('is undefined when neither drive resolved', () => {
38+
expect(inviteSessionDrive({ destinationIsDrive: false })).toBeUndefined();
39+
});
40+
});
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/** Drives persistAgentAfterInvite hands to activateDrive. */
2+
export type InviteSessionDrives = {
3+
privateDrive?: string;
4+
hostDrive?: string;
5+
destinationIsDrive?: boolean;
6+
};
7+
8+
/**
9+
* Session drive after accepting an invite.
10+
*
11+
* Drive-level invites land on the granted host. Child invites (chatroom,
12+
* document) grant the destination, not the parent — stay on the invitee's
13+
* private drive rather than an unreadable host (`Unauthorized` / truncated
14+
* DID in the sidebar).
15+
*/
16+
export function inviteSessionDrive(
17+
drives: InviteSessionDrives,
18+
): string | undefined {
19+
return drives.destinationIsDrive
20+
? (drives.hostDrive ?? drives.privateDrive)
21+
: drives.privateDrive;
22+
}

browser/data-browser/src/views/InvitePage.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import { Logo } from '../components/Logo';
2929
import { useId, useState, type JSX } from 'react';
3030
import { useNavigate } from '@tanstack/react-router';
3131
import { getResourcesDrive } from '@helpers/getResourcesDrive';
32+
import { inviteSessionDrive } from '@helpers/inviteSessionDrive';
3233
import { fetchPrivateDriveSubject } from '@helpers/privateDrive';
3334
import { saveAgentToIDB } from '@helpers/agentStorage';
3435
import { Dialog, useDialog } from '@components/Dialog';
@@ -236,9 +237,7 @@ function InvitePage({ resource }: ResourcePageProps): JSX.Element {
236237
hostDrive?: string;
237238
destinationIsDrive?: boolean;
238239
}): boolean => {
239-
const target = drives.destinationIsDrive
240-
? (drives.hostDrive ?? drives.privateDrive)
241-
: drives.privateDrive;
240+
const target = inviteSessionDrive(drives);
242241

243242
if (!target) {
244243
return false;

0 commit comments

Comments
 (0)