feat: channels on the direct-IIOS path — kernel-client + KernelClientAdapter
- iios-kernel-client: RestClient.discoverThreads (GET /v1/threads/discover) + leaveThread (DELETE /v1/threads/:id/me); DiscoveredThread type - KernelClientAdapter implements the four channel methods: browseChannels maps discovered public channels → ChannelSummary; createChannel → createThread (membership=channel, ADMIN, visibility/topic metadata); joinChannel → socket.openThread (governed public self-join); leaveChannel → rest.leaveThread - adapter channel test over the fake transport (13 kernel-adapter tests); 57 green Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
// layer is faked (via kernel-client's own SocketLike seam), so the facade's wire mapping is
|
||||
// exercised for real. No live IIOS required.
|
||||
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { MessageSocket } from '@insignia/iios-kernel-client';
|
||||
import type { Message as KernelMessage, SocketLike } from '@insignia/iios-kernel-client';
|
||||
import { runAdapterConformance } from '../conformance';
|
||||
@@ -113,6 +114,20 @@ function makeFakeRest(): RestPort {
|
||||
async addParticipant() {
|
||||
/* governed server-side; a fake always allows */
|
||||
},
|
||||
async discoverThreads() {
|
||||
return [
|
||||
{
|
||||
threadId: 'th_pub',
|
||||
subject: 'general',
|
||||
metadata: { membership: 'channel', visibility: 'public', topic: 'Company-wide' },
|
||||
participantCount: 3,
|
||||
joined: false,
|
||||
},
|
||||
];
|
||||
},
|
||||
async leaveThread(threadId) {
|
||||
return { threadId, participantCount: 0 };
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -122,3 +137,17 @@ function makeAdapter(): KernelClientAdapter {
|
||||
}
|
||||
|
||||
runAdapterConformance({ makeAdapter, seededThreadId: SEEDED, openWith: ['pp_a'] });
|
||||
|
||||
describe('KernelClientAdapter channels', () => {
|
||||
it('browse maps discovered public channels; create/join/leave delegate to the transport', async () => {
|
||||
const adapter = makeAdapter();
|
||||
const list = await adapter.browseChannels!();
|
||||
expect(list[0]).toMatchObject({ threadId: 'th_pub', name: 'general', visibility: 'public', joined: false, memberCount: 3, topic: 'Company-wide' });
|
||||
|
||||
const { threadId } = await adapter.createChannel!({ name: 'design', topic: 'UI', visibility: 'public' });
|
||||
expect(typeof threadId).toBe('string');
|
||||
|
||||
await expect(adapter.joinChannel!('th_pub')).resolves.toBeUndefined();
|
||||
await expect(adapter.leaveChannel!('th_pub')).resolves.toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user