UNPKG

@accounter/server

Version:
116 lines 6.32 kB
import { describe, expect, it, vi } from 'vitest'; import { GraphQLError } from 'graphql'; import { ScopeProvider } from '../../auth/providers/scope.provider.js'; import { EmailIngestionAliasProvider } from '../providers/email-ingestion-alias.provider.js'; import { emailIngestionAliasResolver } from '../resolvers/email-ingestion-alias.resolver.js'; const row = { id: 'alias-uuid-1', alias: 'invoice@tenant.example.com', owner_id: 'tenant-uuid-1', is_active: true, created_at: new Date('2026-01-01T00:00:00.000Z'), updated_at: new Date('2026-01-02T00:00:00.000Z'), }; function makeInjector(opts) { const scopeProvider = { getReadScope: vi.fn().mockResolvedValue(['tenant-uuid-1']), resolveWriteTarget: vi.fn().mockResolvedValue('tenant-uuid-1'), ...opts.scope, }; const aliasProvider = { listAliases: vi.fn().mockResolvedValue([row]), createAlias: vi.fn().mockResolvedValue({ success: true, alias: row }), setAliasActive: vi.fn().mockResolvedValue({ success: true, alias: row }), ...opts.alias, }; return { get: (token) => { if (token === ScopeProvider) return scopeProvider; if (token === EmailIngestionAliasProvider) return aliasProvider; throw new Error(`Unexpected provider: ${String(token)}`); }, }; } describe('Query.emailIngestionAliases', () => { const resolver = emailIngestionAliasResolver.Query.emailIngestionAliases; it('narrows scope by businessId arg and maps rows to GraphQL shape', async () => { const getReadScope = vi.fn().mockResolvedValue(['tenant-uuid-1']); const injector = makeInjector({ scope: { getReadScope } }); const result = await resolver({}, { businessId: 'tenant-uuid-1' }, { injector }, {}); expect(getReadScope).toHaveBeenCalledWith(['tenant-uuid-1']); expect(result).toEqual([ { __typename: 'EmailIngestionAlias', id: 'alias-uuid-1', alias: 'invoice@tenant.example.com', ownerId: 'tenant-uuid-1', isActive: true, createdAt: '2026-01-01T00:00:00.000Z', updatedAt: '2026-01-02T00:00:00.000Z', }, ]); }); it('defaults to full read scope when no businessId is given', async () => { const getReadScope = vi.fn().mockResolvedValue(['a', 'b']); const listAliases = vi.fn().mockResolvedValue([]); const injector = makeInjector({ scope: { getReadScope }, alias: { listAliases } }); await resolver({}, {}, { injector }, {}); expect(getReadScope).toHaveBeenCalledWith(undefined); expect(listAliases).toHaveBeenCalledWith(['a', 'b']); }); }); describe('Mutation.createEmailIngestionAlias', () => { const resolver = emailIngestionAliasResolver.Mutation.createEmailIngestionAlias; it('validates write target, trims the alias, and returns the created alias', async () => { const resolveWriteTarget = vi.fn().mockResolvedValue('tenant-uuid-1'); const createAlias = vi.fn().mockResolvedValue({ success: true, alias: row }); const injector = makeInjector({ scope: { resolveWriteTarget }, alias: { createAlias } }); const result = await resolver({}, { input: { alias: ' invoice@tenant.example.com ', businessId: 'tenant-uuid-1' } }, { injector }, {}); expect(resolveWriteTarget).toHaveBeenCalledWith('tenant-uuid-1'); expect(createAlias).toHaveBeenCalledWith('invoice@tenant.example.com', 'tenant-uuid-1'); expect(result).toMatchObject({ __typename: 'EmailIngestionAlias', id: 'alias-uuid-1' }); }); it('returns CommonError for an empty alias without touching the provider', async () => { const createAlias = vi.fn(); const injector = makeInjector({ alias: { createAlias } }); const result = await resolver({}, { input: { alias: ' ', businessId: 'tenant-uuid-1' } }, { injector }, {}); expect(result).toMatchObject({ __typename: 'CommonError' }); expect(createAlias).not.toHaveBeenCalled(); }); it('surfaces a provider conflict as CommonError', async () => { const createAlias = vi .fn() .mockResolvedValue({ success: false, message: 'Alias "x" is already in use' }); const injector = makeInjector({ alias: { createAlias } }); const result = await resolver({}, { input: { alias: 'x', businessId: 'tenant-uuid-1' } }, { injector }, {}); expect(result).toMatchObject({ __typename: 'CommonError', message: expect.stringContaining('in use') }); }); it('propagates authorization failures from resolveWriteTarget', async () => { const resolveWriteTarget = vi.fn().mockRejectedValue(new GraphQLError('FORBIDDEN')); const injector = makeInjector({ scope: { resolveWriteTarget } }); await expect(resolver({}, { input: { alias: 'x', businessId: 'other' } }, { injector }, {})).rejects.toThrow(GraphQLError); }); }); describe('Mutation.setEmailIngestionAliasActive', () => { const resolver = emailIngestionAliasResolver.Mutation.setEmailIngestionAliasActive; it('returns the updated alias on success', async () => { const setAliasActive = vi .fn() .mockResolvedValue({ success: true, alias: { ...row, is_active: false } }); const injector = makeInjector({ alias: { setAliasActive } }); const result = await resolver({}, { id: 'alias-uuid-1', isActive: false }, { injector }, {}); expect(setAliasActive).toHaveBeenCalledWith('alias-uuid-1', false); expect(result).toMatchObject({ __typename: 'EmailIngestionAlias', isActive: false }); }); it('returns CommonError when the alias is not found / not owned', async () => { const setAliasActive = vi .fn() .mockResolvedValue({ success: false, message: 'Alias not found or not authorized' }); const injector = makeInjector({ alias: { setAliasActive } }); const result = await resolver({}, { id: 'missing', isActive: true }, { injector }, {}); expect(result).toMatchObject({ __typename: 'CommonError' }); }); }); //# sourceMappingURL=email-ingestion-alias.resolver.test.js.map