mirror of
https://github.com/hanzoai/sign.git
synced 2026-10-21 01:21:51 +00:00
test(e2e): type the specs against the schema and types they run on
packages/app-tests has no typecheck script, and 10 errors had collected in its specs. None changes what a spec sends or checks: - Two API specs map over create-many's JSON, which Playwright types as any, so the callback's parameters were implicitly any. The responses are typed as TCreateEnvelopeRecipientsResponse, as the file already types its other responses. - A PDF built with Buffer.from(Uint8Array) is a Buffer<ArrayBuffer>; its helpers said Buffer, which @types/node 26 reads as possibly shared memory, and a Blob takes no shared memory. - The seed's updateDocumentOptions was typed as Prisma's unchecked update input, which has no relation fields, while the dictation specs upsert documentMeta through it — which Prisma takes as the checked input. It is typed as EnvelopeUpdateInput; every caller passes fields that input has. - A spec typed a seeded document as Document, a model the schema replaced with Envelope. - The alignment spec picked each field's type and fieldMeta apart, which loses which meta goes with which type; it drops the two keys the payload does not take and spreads the rest, and types the payload as the schema's input, which is what a client sends. Co-authored-by: Hanzo Dev <[email protected]>
This commit is contained in:
@@ -25,7 +25,10 @@ import type {
|
||||
TCreateEnvelopeResponse,
|
||||
} from '@hanzo/esign-trpc/server/envelope-router/create-envelope.types';
|
||||
import type { TDistributeEnvelopeRequest } from '@hanzo/esign-trpc/server/envelope-router/distribute-envelope.types';
|
||||
import type { TCreateEnvelopeRecipientsRequest } from '@hanzo/esign-trpc/server/envelope-router/envelope-recipients/create-envelope-recipients.types';
|
||||
import type {
|
||||
TCreateEnvelopeRecipientsRequest,
|
||||
TCreateEnvelopeRecipientsResponse,
|
||||
} from '@hanzo/esign-trpc/server/envelope-router/envelope-recipients/create-envelope-recipients.types';
|
||||
import type { TUpdateEnvelopeRecipientsRequest } from '@hanzo/esign-trpc/server/envelope-router/envelope-recipients/update-envelope-recipients.types';
|
||||
import type { TFindEnvelopesResponse } from '@hanzo/esign-trpc/server/envelope-router/find-envelopes.types';
|
||||
import type { TGetEnvelopeResponse } from '@hanzo/esign-trpc/server/envelope-router/get-envelope.types';
|
||||
@@ -813,7 +816,8 @@ test.describe('API V2 Envelopes', () => {
|
||||
expect(createRecipientsRes.ok()).toBeTruthy();
|
||||
expect(createRecipientsRes.status()).toBe(200);
|
||||
|
||||
const recipientsResponse = await createRecipientsRes.json();
|
||||
const recipientsResponse: TCreateEnvelopeRecipientsResponse =
|
||||
await createRecipientsRes.json();
|
||||
const recipient = recipientsResponse.data[0];
|
||||
|
||||
expect(recipient.email).toBe('');
|
||||
@@ -903,7 +907,8 @@ test.describe('API V2 Envelopes', () => {
|
||||
});
|
||||
|
||||
expect(createRecipientsRes.ok()).toBeTruthy();
|
||||
const recipientsResponse = await createRecipientsRes.json();
|
||||
const recipientsResponse: TCreateEnvelopeRecipientsResponse =
|
||||
await createRecipientsRes.json();
|
||||
const recipient = recipientsResponse.data[0];
|
||||
|
||||
expect(recipient.email).toBe('');
|
||||
@@ -1047,7 +1052,8 @@ test.describe('API V2 Envelopes', () => {
|
||||
});
|
||||
|
||||
expect(createRecipientsRes.ok()).toBeTruthy();
|
||||
const recipientsResponse = await createRecipientsRes.json();
|
||||
const recipientsResponse: TCreateEnvelopeRecipientsResponse =
|
||||
await createRecipientsRes.json();
|
||||
const recipients = recipientsResponse.data;
|
||||
|
||||
expect(recipients.length).toBe(4);
|
||||
@@ -1142,7 +1148,8 @@ test.describe('API V2 Envelopes', () => {
|
||||
});
|
||||
|
||||
expect(createRecipientsRes.ok()).toBeTruthy();
|
||||
const recipientsResponse = await createRecipientsRes.json();
|
||||
const recipientsResponse: TCreateEnvelopeRecipientsResponse =
|
||||
await createRecipientsRes.json();
|
||||
const recipients = recipientsResponse.data;
|
||||
|
||||
// Get envelope to assign fields
|
||||
@@ -1247,7 +1254,8 @@ test.describe('API V2 Envelopes', () => {
|
||||
});
|
||||
|
||||
expect(createRecipientsRes.ok()).toBeTruthy();
|
||||
const recipientsResponse = await createRecipientsRes.json();
|
||||
const recipientsResponse: TCreateEnvelopeRecipientsResponse =
|
||||
await createRecipientsRes.json();
|
||||
const recipient = recipientsResponse.data[0];
|
||||
|
||||
// Get envelope to assign fields
|
||||
|
||||
@@ -145,7 +145,7 @@ test.describe('Placeholder-based field creation', () => {
|
||||
/**
|
||||
* Create a PDF with the same placeholder appearing multiple times at different locations.
|
||||
*/
|
||||
const createPdfWithDuplicatePlaceholders = async (): Promise<Buffer> => {
|
||||
const createPdfWithDuplicatePlaceholders = async (): Promise<Buffer<ArrayBuffer>> => {
|
||||
const pdf = PDF.create();
|
||||
const page = pdf.addPage({ size: 'letter' });
|
||||
|
||||
@@ -161,7 +161,7 @@ test.describe('Placeholder-based field creation', () => {
|
||||
|
||||
const createEnvelopeWithPdfBuffer = async (
|
||||
request: APIRequestContext,
|
||||
pdfBuffer: Buffer,
|
||||
pdfBuffer: Buffer<ArrayBuffer>,
|
||||
filename: string,
|
||||
): Promise<TCreateEnvelopeResponse> => {
|
||||
const formData = new FormData();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { type Page, expect, test } from '@playwright/test';
|
||||
import type { Document, Team } from '@prisma/client';
|
||||
import type { Envelope, Team } from '@prisma/client';
|
||||
|
||||
import { PDF_VIEWER_PAGE_SELECTOR } from '@hanzo/esign-lib/constants/pdf-viewer';
|
||||
import { prisma } from '@hanzo/esign-prisma';
|
||||
@@ -15,7 +15,7 @@ import { signSignaturePad } from '../fixtures/signature';
|
||||
const completeDocumentFlowWithDuplicateRecipients = async (options: {
|
||||
page: Page;
|
||||
team: Team;
|
||||
document: Document;
|
||||
document: Envelope;
|
||||
}) => {
|
||||
const { page, team, document } = options;
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import path from 'node:path';
|
||||
import * as pdfjsLib from 'pdfjs-dist/legacy/build/pdf.mjs';
|
||||
import pixelMatch from 'pixelmatch';
|
||||
import { PNG } from 'pngjs';
|
||||
import type { z } from 'zod';
|
||||
|
||||
import { getEnvelopeItemPdfUrl } from '@hanzo/esign-lib/utils/envelope-download';
|
||||
import { prisma } from '@hanzo/esign-prisma';
|
||||
@@ -18,8 +19,8 @@ import { isBase64Image } from '../../../lib/constants/signatures';
|
||||
import { createApiToken } from '../../../lib/server-only/public-api/create-api-token';
|
||||
import { RecipientRole } from '../../../prisma/generated/types';
|
||||
import type {
|
||||
TCreateEnvelopePayload,
|
||||
TCreateEnvelopeResponse,
|
||||
ZCreateEnvelopePayloadSchema,
|
||||
} from '../../../trpc/server/envelope-router/create-envelope.types';
|
||||
import type { TDistributeEnvelopeRequest } from '../../../trpc/server/envelope-router/distribute-envelope.types';
|
||||
import { ALIGNMENT_TEST_FIELDS } from '../../constants/field-alignment-pdf';
|
||||
@@ -77,29 +78,22 @@ test('field placement visual regression', async ({ page, request }, testInfo) =>
|
||||
|
||||
const formData = new FormData();
|
||||
|
||||
const fieldMetaFields = FIELD_META_TEST_FIELDS.map((field) => ({
|
||||
identifier: 'field-meta',
|
||||
type: field.type,
|
||||
page: field.page,
|
||||
positionX: field.positionX,
|
||||
positionY: field.positionY,
|
||||
width: field.width,
|
||||
height: field.height,
|
||||
fieldMeta: field.fieldMeta,
|
||||
}));
|
||||
const fieldMetaFields = FIELD_META_TEST_FIELDS.map(
|
||||
({ customText: _customText, signature: _signature, ...field }) => ({
|
||||
identifier: 'field-meta',
|
||||
...field,
|
||||
}),
|
||||
);
|
||||
|
||||
const alignmentFields = ALIGNMENT_TEST_FIELDS.map((field) => ({
|
||||
identifier: 'alignment-pdf',
|
||||
type: field.type,
|
||||
page: field.page,
|
||||
positionX: field.positionX,
|
||||
positionY: field.positionY,
|
||||
width: field.width,
|
||||
height: field.height,
|
||||
fieldMeta: field.fieldMeta,
|
||||
}));
|
||||
const alignmentFields = ALIGNMENT_TEST_FIELDS.map(
|
||||
({ customText: _customText, signature: _signature, ...field }) => ({
|
||||
identifier: 'alignment-pdf',
|
||||
...field,
|
||||
}),
|
||||
);
|
||||
|
||||
const createEnvelopePayload: TCreateEnvelopePayload = {
|
||||
// What the client sends: the schema's input, before the server fills in defaults.
|
||||
const createEnvelopePayload: z.input<typeof ZCreateEnvelopePayloadSchema> = {
|
||||
type: EnvelopeType.DOCUMENT,
|
||||
title: 'Envelope Full Field Test',
|
||||
recipients: [
|
||||
|
||||
@@ -480,7 +480,7 @@ export const seedPendingDocumentNoFields = async ({
|
||||
owner: User;
|
||||
recipients: (User | string)[];
|
||||
teamId: number;
|
||||
updateDocumentOptions?: Partial<Prisma.EnvelopeUncheckedUpdateInput>;
|
||||
updateDocumentOptions?: Partial<Prisma.EnvelopeUpdateInput>;
|
||||
}) => {
|
||||
const document = await seedBlankDocument(owner, teamId);
|
||||
|
||||
@@ -537,7 +537,7 @@ export const seedPendingDocumentWithFullFields = async ({
|
||||
owner: User;
|
||||
recipients: (User | string)[];
|
||||
recipientsCreateOptions?: Partial<Prisma.RecipientUncheckedCreateInput>[];
|
||||
updateDocumentOptions?: Partial<Prisma.EnvelopeUncheckedUpdateInput>;
|
||||
updateDocumentOptions?: Partial<Prisma.EnvelopeUpdateInput>;
|
||||
fields?: FieldType[];
|
||||
teamId: number;
|
||||
}) => {
|
||||
|
||||
Reference in New Issue
Block a user