Files
zeekay 00ea559815 feat(docusign): Hanzo AI for DocuSign — AI over agreements (@hanzo/docusign)
Extension-App panel + Connect webhook that summarize, extract key terms,
risk-flag clauses, and draft memos over DocuSign envelopes, on the shared
@hanzo/ai + @hanzo/iam foundation over api.hanzo.ai /v1.

- OAuth Authorization Code Grant (account-d/account.docusign.com), server-side
  client_secret, base_uri discovery via /oauth/userinfo (pure shaping).
- eSignature REST v2.1 wrappers (envelopes, documents, combined PDF).
- Connect webhook: X-DocuSign-Signature-N HMAC-SHA256 verify over raw body,
  constant-time, multi-key; envelope-completed auto-summarize pipeline.
- PDF text extraction (pdf.js, pure itemsToText), document windowing/truncation,
  one 'ask' path shared by the four actions, the panel, and the webhook.
- 103 vitest tests (config, oauth, api, webhook HMAC, pdf, hanzo, actions,
  envelope pipeline, panel). tsc clean, esbuild build green.
- Registers packages/docusign in pnpm-workspace.yaml (one line).
2026-07-03 19:40:52 -07:00

36 lines
1.4 KiB
TypeScript

import { describe, it, expect } from 'vitest';
import { parseLaunchContext, asPages, panelTitle } from '../src/panel';
describe('parseLaunchContext', () => {
it('reads envelopeId/accountId/title from the launch query', () => {
const ctx = parseLaunchContext('?envelopeId=env-9&accountId=acct-1&title=MSA');
expect(ctx).toEqual({ envelopeId: 'env-9', accountId: 'acct-1', title: 'MSA' });
});
it('accepts the snake_case + emailSubject variants', () => {
const ctx = parseLaunchContext('?envelope_id=e&account_id=a&emailSubject=Please%20sign');
expect(ctx.envelopeId).toBe('e');
expect(ctx.accountId).toBe('a');
expect(ctx.title).toBe('Please sign');
});
it('is empty when the panel is opened without context', () => {
expect(parseLaunchContext('')).toEqual({ envelopeId: '', accountId: '', title: '' });
});
});
describe('asPages', () => {
it('wraps pasted text as a single page', () => {
expect(asPages(' hello ')).toEqual([{ page: 1, text: 'hello' }]);
});
it('is empty for blank text', () => {
expect(asPages(' ')).toEqual([]);
});
});
describe('panelTitle', () => {
it('prefers the subject, then the envelope id, then a default', () => {
expect(panelTitle({ envelopeId: 'e', accountId: '', title: 'MSA' })).toBe('MSA');
expect(panelTitle({ envelopeId: 'e', accountId: '', title: '' })).toBe('Envelope e');
expect(panelTitle({ envelopeId: '', accountId: '', title: '' })).toBe('Agreement');
});
});