fix: standardize punctuation
This commit is contained in:
@@ -69,7 +69,7 @@ describe('dev-jmap mock server', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /api — Mailbox/get', () => {
|
||||
describe('POST /api - Mailbox/get', () => {
|
||||
it('should return list of mailboxes', async () => {
|
||||
const req = makeRequest('http://localhost:3000/api/dev-jmap/api', {
|
||||
method: 'POST',
|
||||
@@ -88,7 +88,7 @@ describe('dev-jmap mock server', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /api — Email/query', () => {
|
||||
describe('POST /api - Email/query', () => {
|
||||
it('should filter by mailbox', async () => {
|
||||
const req = makeRequest('http://localhost:3000/api/dev-jmap/api', {
|
||||
method: 'POST',
|
||||
@@ -117,7 +117,7 @@ describe('dev-jmap mock server', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /api — Email/get', () => {
|
||||
describe('POST /api - Email/get', () => {
|
||||
it('should return emails by ids', async () => {
|
||||
const req = makeRequest('http://localhost:3000/api/dev-jmap/api', {
|
||||
method: 'POST',
|
||||
@@ -150,7 +150,7 @@ describe('dev-jmap mock server', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /api — Email/set', () => {
|
||||
describe('POST /api - Email/set', () => {
|
||||
it('should update email keywords', async () => {
|
||||
const req = makeRequest('http://localhost:3000/api/dev-jmap/api', {
|
||||
method: 'POST',
|
||||
@@ -166,7 +166,7 @@ describe('dev-jmap mock server', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /api — Identity/get', () => {
|
||||
describe('POST /api - Identity/get', () => {
|
||||
it('should return identities', async () => {
|
||||
const req = makeRequest('http://localhost:3000/api/dev-jmap/api', {
|
||||
method: 'POST',
|
||||
@@ -183,7 +183,7 @@ describe('dev-jmap mock server', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /api — unknown method', () => {
|
||||
describe('POST /api - unknown method', () => {
|
||||
it('should return error for unknown methods', async () => {
|
||||
const req = makeRequest('http://localhost:3000/api/dev-jmap/api', {
|
||||
method: 'POST',
|
||||
@@ -199,7 +199,7 @@ describe('dev-jmap mock server', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /api — back-references', () => {
|
||||
describe('POST /api - back-references', () => {
|
||||
it('should resolve #ids from Email/query result', async () => {
|
||||
const req = makeRequest('http://localhost:3000/api/dev-jmap/api', {
|
||||
method: 'POST',
|
||||
@@ -220,7 +220,7 @@ describe('dev-jmap mock server', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /api — invalid request', () => {
|
||||
describe('POST /api - invalid request', () => {
|
||||
it('should return 400 for missing methodCalls', async () => {
|
||||
const req = makeRequest('http://localhost:3000/api/dev-jmap/api', {
|
||||
method: 'POST',
|
||||
|
||||
@@ -68,7 +68,7 @@ describe('JMAPClient resilience', () => {
|
||||
return client;
|
||||
}
|
||||
|
||||
describe('authenticatedFetch — network error retry', () => {
|
||||
describe('authenticatedFetch - network error retry', () => {
|
||||
it('retries once on transient network error', async () => {
|
||||
const client = await createConnectedClient();
|
||||
const echoResponse = { methodResponses: [['Core/echo', { ping: 'pong' }, '0']] };
|
||||
@@ -95,7 +95,7 @@ describe('JMAPClient resilience', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('authenticatedFetch — basic auth 401 session refresh', () => {
|
||||
describe('authenticatedFetch - basic auth 401 session refresh', () => {
|
||||
it('refreshes session and retries on 401 for API requests', async () => {
|
||||
const client = await createConnectedClient();
|
||||
const refreshedSession = makeSession({ apiUrl: 'https://mail.example.com/jmap/api-v2' });
|
||||
@@ -138,12 +138,12 @@ describe('JMAPClient resilience', () => {
|
||||
|
||||
// connect() should throw without trying to refresh session (would cause infinite recursion)
|
||||
await expect(client.connect()).rejects.toThrow('Invalid username or password');
|
||||
// Only one fetch call — no refresh attempt
|
||||
// Only one fetch call - no refresh attempt
|
||||
expect(fetchSpy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('authenticatedFetch — bearer token refresh', () => {
|
||||
describe('authenticatedFetch - bearer token refresh', () => {
|
||||
it('refreshes token and retries on 401 for bearer mode', async () => {
|
||||
const tokenRefresh = vi.fn().mockResolvedValue('new-token-456');
|
||||
const session = makeSession();
|
||||
@@ -172,7 +172,7 @@ describe('JMAPClient resilience', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('authenticatedFetch — 429 rate limiting', () => {
|
||||
describe('authenticatedFetch - 429 rate limiting', () => {
|
||||
it('stops sending authenticated requests until the retry window expires', async () => {
|
||||
const client = await createConnectedClient();
|
||||
|
||||
@@ -258,7 +258,7 @@ describe('JMAPClient resilience', () => {
|
||||
// So ping throws, keep-alive catches it, fires false
|
||||
// Then reconnect → connect() → authenticatedFetch(sessionUrl) succeeds
|
||||
fetchSpy
|
||||
// ping fails — network error, retry also fails
|
||||
// ping fails - network error, retry also fails
|
||||
.mockRejectedValueOnce(new TypeError('Failed to fetch'))
|
||||
.mockRejectedValueOnce(new TypeError('Failed to fetch'))
|
||||
// reconnect → connect() → session URL succeeds
|
||||
|
||||
@@ -267,13 +267,13 @@ describe('GitHub #118: duplicate subfolder names cause depth-4 orphaning', () =>
|
||||
it('should keep nested folders when a subfolder has the same name as a role mailbox', () => {
|
||||
// Reporter's exact scenario: two subfolders with the same name.
|
||||
// The dedup uses substring matching and removes non-role folders whose name
|
||||
// matches a role folder — even if they're deep in the tree with children.
|
||||
// matches a role folder - even if they're deep in the tree with children.
|
||||
const mailboxes = [
|
||||
makeMailbox({ id: 'inbox', name: 'Inbox', role: 'inbox' }),
|
||||
makeMailbox({ id: 'sent-role', name: 'Sent', role: 'sent' }),
|
||||
// User-created subfolder also named "Sent" nested under Inbox
|
||||
makeMailbox({ id: 'sent-custom', name: 'Sent', parentId: 'inbox' }),
|
||||
// Child of the custom "Sent" folder — becomes orphaned if parent is deduped
|
||||
// Child of the custom "Sent" folder - becomes orphaned if parent is deduped
|
||||
makeMailbox({ id: 'sent-child', name: 'Archive', parentId: 'sent-custom' }),
|
||||
];
|
||||
|
||||
@@ -281,7 +281,7 @@ describe('GitHub #118: duplicate subfolder names cause depth-4 orphaning', () =>
|
||||
const flat = flattenMailboxTree(tree);
|
||||
const rootIds = tree.map(n => n.id);
|
||||
|
||||
// sent-custom MUST be kept because it has children — removing it orphans sent-child
|
||||
// sent-custom MUST be kept because it has children - removing it orphans sent-child
|
||||
const sentCustom = flat.find(n => n.id === 'sent-custom');
|
||||
expect(sentCustom).toBeDefined();
|
||||
expect(sentCustom!.depth).toBe(1); // nested under Inbox
|
||||
@@ -293,7 +293,7 @@ describe('GitHub #118: duplicate subfolder names cause depth-4 orphaning', () =>
|
||||
});
|
||||
|
||||
it('should keep nested folders when name is substring of a role name', () => {
|
||||
// "Draft" is a substring of "Drafts" — dedup removes it, orphaning children
|
||||
// "Draft" is a substring of "Drafts" - dedup removes it, orphaning children
|
||||
const mailboxes = [
|
||||
makeMailbox({ id: 'inbox', name: 'Inbox', role: 'inbox' }),
|
||||
makeMailbox({ id: 'drafts-role', name: 'Drafts', role: 'drafts' }),
|
||||
@@ -343,22 +343,22 @@ describe('GitHub #118: duplicate subfolder names cause depth-4 orphaning', () =>
|
||||
|
||||
it('should only dedup root-level non-role mailboxes that duplicate role mailboxes', () => {
|
||||
// Dedup should only remove mailboxes that are BOTH:
|
||||
// 1. At root level (no parentId) — same structural position as role mailbox
|
||||
// 1. At root level (no parentId) - same structural position as role mailbox
|
||||
// 2. Name-matching a role mailbox
|
||||
// Nested mailboxes with matching names should always be kept.
|
||||
const mailboxes = [
|
||||
makeMailbox({ id: 'inbox', name: 'Inbox', role: 'inbox' }),
|
||||
makeMailbox({ id: 'sent-role', name: 'Sent', role: 'sent' }),
|
||||
makeMailbox({ id: 'sent-dup', name: 'Sent Mail' }), // root-level duplicate — OK to remove
|
||||
makeMailbox({ id: 'sent-dup', name: 'Sent Mail' }), // root-level duplicate - OK to remove
|
||||
makeMailbox({ id: 'proj', name: 'Projects', parentId: 'inbox' }),
|
||||
makeMailbox({ id: 'sent-nested', name: 'Sent', parentId: 'proj' }), // nested — must keep
|
||||
makeMailbox({ id: 'sent-nested', name: 'Sent', parentId: 'proj' }), // nested - must keep
|
||||
makeMailbox({ id: 'report', name: 'Report', parentId: 'sent-nested' }),
|
||||
];
|
||||
|
||||
const tree = buildMailboxTree(mailboxes);
|
||||
const flat = flattenMailboxTree(tree);
|
||||
|
||||
// "Sent Mail" at root (no parentId) can be deduped — that's fine
|
||||
// "Sent Mail" at root (no parentId) can be deduped - that's fine
|
||||
// But "Sent" nested under Projects must be kept
|
||||
const sentNested = flat.find(n => n.id === 'sent-nested');
|
||||
expect(sentNested).toBeDefined();
|
||||
@@ -377,7 +377,7 @@ describe('mailbox orphan behavior (missing parent)', () => {
|
||||
const mailboxes = [
|
||||
makeMailbox({ id: 'inbox', name: 'INBOX', role: 'inbox' }),
|
||||
makeMailbox({ id: 'privat', name: 'PRIVAT', parentId: 'inbox' }),
|
||||
// 'bookings' is MISSING — simulating truncated JMAP response
|
||||
// 'bookings' is MISSING - simulating truncated JMAP response
|
||||
makeMailbox({ id: 'hotel2', name: 'HOTEL2', parentId: 'bookings' }),
|
||||
makeMailbox({ id: 'restaurant', name: 'RESTAURANT', parentId: 'hotel2' }),
|
||||
];
|
||||
|
||||
@@ -92,7 +92,7 @@ describe('oauth/discovery', () => {
|
||||
expect(consoleSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('caches results — second call for same server URL does not re-fetch', async () => {
|
||||
it('caches results - second call for same server URL does not re-fetch', async () => {
|
||||
vi.stubGlobal('fetch', vi.fn().mockResolvedValueOnce({
|
||||
ok: true,
|
||||
json: () => Promise.resolve(VALID_METADATA),
|
||||
|
||||
Reference in New Issue
Block a user