inbox-compiled-query.test.ts6.6 KBView on GitHub import { buildInboxCompiledQuery } from '@/modules/threads/lib/inbox-compiled-query';
import type { InboxConfig } from '@/modules/threads/hooks/use-inboxes';
const importantInbox: InboxConfig = {
id: 'important',
name: 'Important',
position: 0,
system: true,
rule: { kind: 'all' },
};
const otherInbox: InboxConfig = {
id: 'other',
name: 'Other',
position: 1,
system: true,
rule: { kind: 'all' },
};
const defaultInbox: InboxConfig = {
id: 'default',
name: 'Inbox',
position: 0,
system: true,
rule: { kind: 'all' },
};
function customInbox(overrides: Partial<InboxConfig>): InboxConfig {
return {
id: 'inbox-cal',
name: 'Calendar',
position: 2,
rule: { kind: 'all_of', clauses: [] },
query: 'from:<email>',
...overrides,
};
}
describe('buildInboxCompiledQuery', () => {
it('falls back to label:INBOX for default inbox with no exclusions', () => {
const result = buildInboxCompiledQuery({
inbox: defaultInbox,
inboxes: [defaultInbox],
hasCategoryPersonal: false,
});
expect(result.compiledQuery).toBe('label:INBOX');
expect(result.inboxName).toBe('Inbox');
expect(result.queryHash).toContain('client-fallback:default');
});
it('prefers an explicit inbox.query for custom inboxes', () => {
const inbox = customInbox({ query: 'from:<email>' });
const result = buildInboxCompiledQuery({
inbox,
inboxes: [defaultInbox, inbox],
hasCategoryPersonal: false,
});
expect(result.compiledQuery).toBe('from:<email>');
});
it("prefers a matching inbox's server compiledQuery + queryHash", () => {
const inbox = customInbox({
id: 'inbox-x',
name: 'X',
query: 'from:fallback',
compiledQuery: 'from:from-server AND label:INBOX',
queryHash: 'sha:abc',
});
const result = buildInboxCompiledQuery({
inbox,
inboxes: [defaultInbox, inbox],
hasCategoryPersonal: false,
});
expect(result.compiledQuery).toBe('from:from-server AND label:INBOX');
expect(result.queryHash).toBe('sha:abc');
});
it('builds the important inbox include clause with category:personal when present', () => {
const result = buildInboxCompiledQuery({
inbox: importantInbox,
inboxes: [importantInbox, otherInbox],
hasCategoryPersonal: true,
});
expect(result.compiledQuery).toContain('label:INBOX');
expect(result.compiledQuery).toContain('category:personal');
});
it('excludes custom inbox queries from the important inbox query', () => {
const inbox = customInbox({ query: 'from:<email>' });
const result = buildInboxCompiledQuery({
inbox: importantInbox,
inboxes: [importantInbox, otherInbox, inbox],
hasCategoryPersonal: false,
});
expect(result.compiledQuery).toContain('-(');
expect(result.compiledQuery).toContain('from:<email>');
});
it('does NOT subtract a custom inbox query when alsoShowInImportant is true', () => {
const inbox = customInbox({
query: 'label:"Cedar/Agent drafts"',
alsoShowInImportant: true,
});
const result = buildInboxCompiledQuery({
inbox: importantInbox,
inboxes: [importantInbox, otherInbox, inbox],
hasCategoryPersonal: false,
});
expect(result.compiledQuery).not.toContain('Cedar/Agent drafts');
});
it('builds the other inbox query as label:INBOX minus the important signals', () => {
const result = buildInboxCompiledQuery({
inbox: otherInbox,
inboxes: [importantInbox, otherInbox],
hasCategoryPersonal: true,
});
expect(result.compiledQuery.startsWith('label:INBOX')).toBe(true);
expect(result.compiledQuery).toContain('category:personal');
expect(result.compiledQuery).toContain('-(');
});
it('uses label:IMPORTANT (not category:personal) when importantSignal=gmail_important', () => {
const result = buildInboxCompiledQuery({
inbox: importantInbox,
inboxes: [importantInbox, otherInbox],
hasCategoryPersonal: true,
importantSignal: 'gmail_important',
});
expect(result.compiledQuery).toContain('label:IMPORTANT');
expect(result.compiledQuery).not.toContain('category:personal');
});
it('subtracts label:IMPORTANT (not category:personal) from the other inbox when signal=gmail_important', () => {
const result = buildInboxCompiledQuery({
inbox: otherInbox,
inboxes: [importantInbox, otherInbox],
hasCategoryPersonal: true,
importantSignal: 'gmail_important',
});
expect(result.compiledQuery).toContain('label:IMPORTANT');
expect(result.compiledQuery).not.toContain('category:personal');
expect(result.compiledQuery.startsWith('label:INBOX')).toBe(true);
expect(result.compiledQuery).toContain('-(');
});
// A CRM-filtered inbox keeps its real rule in `conversationFilter` and carries a
// bare `label:INBOX` as its mailbox-scope anchor. If the exclusion builder ever
// treats that anchor as a business-intent clause, the default inbox compiles to
// `label:INBOX -(label:INBOX)` and the user's whole Inbox renders empty.
describe('CRM-filtered inboxes are never subtracted from Inbox', () => {
const pipelineInbox = customInbox({
id: 'inbox-pipeline',
name: 'Pipeline',
query: 'label:INBOX',
conversationFilter: { filters: { aopIds: ['aop-deals'] } },
});
it('does not empty the default inbox, even with alsoShowInImportant off', () => {
const result = buildInboxCompiledQuery({
inbox: defaultInbox,
inboxes: [defaultInbox, { ...pipelineInbox, alsoShowInImportant: false }],
hasCategoryPersonal: true,
});
expect(result.compiledQuery).toBe('label:INBOX');
expect(result.compiledQuery).not.toContain('-(');
});
it('does not empty the important inbox either', () => {
const result = buildInboxCompiledQuery({
inbox: importantInbox,
inboxes: [importantInbox, { ...pipelineInbox, alsoShowInImportant: false }],
hasCategoryPersonal: true,
});
expect(result.compiledQuery).not.toContain('-(label:INBOX)');
});
it('still subtracts a PLAIN custom inbox sharing the same query text', () => {
const plain = customInbox({ id: 'inbox-plain', query: 'label:INBOX' });
const result = buildInboxCompiledQuery({
inbox: defaultInbox,
inboxes: [defaultInbox, { ...plain, alsoShowInImportant: false }],
hasCategoryPersonal: true,
});
// Proves the guard keys off `conversationFilter`, not off the query string.
expect(result.compiledQuery).toBe('label:INBOX -(label:INBOX)');
});
});
});