sh-mcp/packages/gmail/test/dev-client.test.ts

98 lines
3.2 KiB
TypeScript
Raw Normal View History

import { describe, it, expect } from 'vitest';
import { InMemoryGmailClient } from '../src/dev-client.js';
describe('InMemoryGmailClient', () => {
describe('searchInbox', () => {
it('matches a case-insensitive substring against subject/snippet', async () => {
const client = new InMemoryGmailClient();
const results = await client.searchInbox({
userSub: 'lauren@seahavenind.com',
query: 'INVOICE',
maxResults: 10,
});
expect(results.map((m) => m.id)).toEqual(['msg-l-1']);
});
it('matches against the snippet body too', async () => {
const client = new InMemoryGmailClient();
const results = await client.searchInbox({
userSub: 'lauren@seahavenind.com',
query: 'walkthrough',
maxResults: 10,
});
expect(results.map((m) => m.id)).toEqual(['msg-l-2']);
});
it('caps results at maxResults', async () => {
const client = new InMemoryGmailClient();
const results = await client.searchInbox({
userSub: 'lauren@seahavenind.com',
query: '',
maxResults: 1,
});
expect(results).toHaveLength(1);
});
it("is partitioned by userSub — lauren cannot see adam's mail", async () => {
const client = new InMemoryGmailClient();
const results = await client.searchInbox({
userSub: 'lauren@seahavenind.com',
query: 'check #2087',
maxResults: 10,
});
expect(results).toEqual([]);
const adamResults = await client.searchInbox({
userSub: 'adam@seahavenind.com',
query: 'check #2087',
maxResults: 10,
});
expect(adamResults.map((m) => m.id)).toEqual(['msg-a-1']);
});
it('returns an empty list for an unknown sub', async () => {
const client = new InMemoryGmailClient();
const results = await client.searchInbox({
userSub: 'nobody@example.com',
query: 'invoice',
maxResults: 10,
});
expect(results).toEqual([]);
});
});
describe('getThreadDetail', () => {
it('returns an owned thread', async () => {
const client = new InMemoryGmailClient();
const thread = await client.getThreadDetail({
userSub: 'lauren@seahavenind.com',
threadId: 'thr-l-1',
});
expect(thread.threadId).toBe('thr-l-1');
expect(thread.subject).toBe('Invoice #4821 from Coastal Supply');
expect(thread.messages).toHaveLength(1);
});
it('throws for an unknown threadId', async () => {
const client = new InMemoryGmailClient();
await expect(
client.getThreadDetail({ userSub: 'lauren@seahavenind.com', threadId: 'thr-missing' }),
).rejects.toThrow(/not found/);
});
it('throws when the thread is not owned by the caller', async () => {
const client = new InMemoryGmailClient();
await expect(
client.getThreadDetail({ userSub: 'lauren@seahavenind.com', threadId: 'thr-a-1' }),
).rejects.toThrow(/not found/);
});
it('throws for an unknown user', async () => {
const client = new InMemoryGmailClient();
await expect(
client.getThreadDetail({ userSub: 'nobody@example.com', threadId: 'thr-l-1' }),
).rejects.toThrow(/not found/);
});
});
});