mirror of
https://github.com/documenso/documenso.git
synced 2025-11-14 08:42:12 +10:00
fix: add regression test
This commit is contained in:
264
packages/app-tests/e2e/api/v2/envelopes-api.spec.ts
Normal file
264
packages/app-tests/e2e/api/v2/envelopes-api.spec.ts
Normal file
@ -0,0 +1,264 @@
|
||||
import { expect, test } from '@playwright/test';
|
||||
import type { Team, User } from '@prisma/client';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import { incrementDocumentId } from '@documenso/lib/server-only/envelope/increment-id';
|
||||
import { createApiToken } from '@documenso/lib/server-only/public-api/create-api-token';
|
||||
import { prefixedId } from '@documenso/lib/universal/id';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import {
|
||||
DocumentSource,
|
||||
DocumentVisibility,
|
||||
EnvelopeType,
|
||||
RecipientRole,
|
||||
} from '@documenso/prisma/client';
|
||||
import { seedUser } from '@documenso/prisma/seed/users';
|
||||
import type { TCreateEnvelopeItemsRequest } from '@documenso/trpc/server/envelope-router/create-envelope-items.types';
|
||||
import type { TCreateEnvelopeRecipientsRequest } from '@documenso/trpc/server/envelope-router/envelope-recipients/create-envelope-recipients.types';
|
||||
import type { TGetEnvelopeResponse } from '@documenso/trpc/server/envelope-router/get-envelope.types';
|
||||
import type { TUpdateEnvelopeRequest } from '@documenso/trpc/server/envelope-router/update-envelope.types';
|
||||
|
||||
import { formatAlignmentTestFields } from '../../../constants/field-alignment-pdf';
|
||||
import { FIELD_META_TEST_FIELDS } from '../../../constants/field-meta-pdf';
|
||||
|
||||
const WEBAPP_BASE_URL = NEXT_PUBLIC_WEBAPP_URL();
|
||||
const baseUrl = `${WEBAPP_BASE_URL}/api/v2-beta`;
|
||||
|
||||
test.describe.configure({
|
||||
mode: 'parallel',
|
||||
});
|
||||
|
||||
test.describe('API V2 Envelopes', () => {
|
||||
let userA: User, teamA: Team, userB: User, teamB: Team, tokenA: string, tokenB: string;
|
||||
|
||||
test.beforeEach(async () => {
|
||||
({ user: userA, team: teamA } = await seedUser());
|
||||
({ token: tokenA } = await createApiToken({
|
||||
userId: userA.id,
|
||||
teamId: teamA.id,
|
||||
tokenName: 'userA',
|
||||
expiresIn: null,
|
||||
}));
|
||||
|
||||
({ user: userB, team: teamB } = await seedUser());
|
||||
({ token: tokenB } = await createApiToken({
|
||||
userId: userB.id,
|
||||
teamId: teamB.id,
|
||||
tokenName: 'userB',
|
||||
expiresIn: null,
|
||||
}));
|
||||
});
|
||||
|
||||
/**
|
||||
* Creates envelopes with the two field test PDFs.
|
||||
*/
|
||||
test('Envelope full test', async ({ request }) => {
|
||||
// Step 1: Create initial envelope with Prisma (with first envelope item)
|
||||
const alignmentPdf = fs
|
||||
.readFileSync(path.join(__dirname, '../../../../../assets/field-font-alignment.pdf'))
|
||||
.toString('base64');
|
||||
|
||||
const fieldMetaPdf = fs
|
||||
.readFileSync(path.join(__dirname, '../../../../../assets/field-meta.pdf'))
|
||||
.toString('base64');
|
||||
|
||||
const alignmentDocumentData = await prisma.documentData.create({
|
||||
data: {
|
||||
type: 'BYTES_64',
|
||||
data: alignmentPdf,
|
||||
initialData: alignmentPdf,
|
||||
},
|
||||
});
|
||||
|
||||
const documentId = await incrementDocumentId();
|
||||
const documentMeta = await prisma.documentMeta.create({
|
||||
data: {},
|
||||
});
|
||||
|
||||
const createdEnvelope = await prisma.envelope.create({
|
||||
data: {
|
||||
id: prefixedId('envelope'),
|
||||
secondaryId: documentId.formattedDocumentId,
|
||||
internalVersion: 2,
|
||||
type: EnvelopeType.DOCUMENT,
|
||||
documentMetaId: documentMeta.id,
|
||||
source: DocumentSource.DOCUMENT,
|
||||
title: `Envelope Full Field Test`,
|
||||
status: 'DRAFT',
|
||||
userId: userA.id,
|
||||
teamId: teamA.id,
|
||||
envelopeItems: {
|
||||
create: {
|
||||
id: prefixedId('envelope_item'),
|
||||
title: `Alignment Test`,
|
||||
documentDataId: alignmentDocumentData.id,
|
||||
order: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
include: {
|
||||
envelopeItems: true,
|
||||
},
|
||||
});
|
||||
|
||||
// Step 2: Create second envelope item via API
|
||||
const fieldMetaDocumentData = await prisma.documentData.create({
|
||||
data: {
|
||||
type: 'BYTES_64',
|
||||
data: fieldMetaPdf,
|
||||
initialData: fieldMetaPdf,
|
||||
},
|
||||
});
|
||||
|
||||
const createEnvelopeItemsRequest: TCreateEnvelopeItemsRequest = {
|
||||
envelopeId: createdEnvelope.id,
|
||||
data: [
|
||||
{
|
||||
title: 'Field Meta Test',
|
||||
documentDataId: fieldMetaDocumentData.id,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const createItemsRes = await request.post(`${baseUrl}/envelope/item/create-many`, {
|
||||
headers: { Authorization: `Bearer ${tokenA}` },
|
||||
data: createEnvelopeItemsRequest,
|
||||
});
|
||||
|
||||
expect(createItemsRes.ok()).toBeTruthy();
|
||||
expect(createItemsRes.status()).toBe(200);
|
||||
|
||||
// Step 3: Update envelope via API
|
||||
const updateEnvelopeRequest: TUpdateEnvelopeRequest = {
|
||||
envelopeId: createdEnvelope.id,
|
||||
envelopeType: EnvelopeType.DOCUMENT,
|
||||
data: {
|
||||
title: 'Envelope Full Field Test',
|
||||
visibility: DocumentVisibility.MANAGER_AND_ABOVE,
|
||||
},
|
||||
};
|
||||
|
||||
const updateRes = await request.post(`${baseUrl}/envelope/update`, {
|
||||
headers: { Authorization: `Bearer ${tokenA}` },
|
||||
data: updateEnvelopeRequest,
|
||||
});
|
||||
|
||||
expect(updateRes.ok()).toBeTruthy();
|
||||
expect(updateRes.status()).toBe(200);
|
||||
|
||||
// Step 4: Create recipient via API
|
||||
const createRecipientsRequest: TCreateEnvelopeRecipientsRequest = {
|
||||
envelopeId: createdEnvelope.id,
|
||||
data: [
|
||||
{
|
||||
email: userA.email,
|
||||
name: userA.name || '',
|
||||
role: RecipientRole.SIGNER,
|
||||
accessAuth: [],
|
||||
actionAuth: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const createRecipientsRes = await request.post(`${baseUrl}/envelope/recipient/create-many`, {
|
||||
headers: { Authorization: `Bearer ${tokenA}` },
|
||||
data: createRecipientsRequest,
|
||||
});
|
||||
|
||||
expect(createRecipientsRes.ok()).toBeTruthy();
|
||||
expect(createRecipientsRes.status()).toBe(200);
|
||||
|
||||
// Step 5: Get envelope to retrieve recipients and envelope items
|
||||
const getRes = await request.get(`${baseUrl}/envelope/${createdEnvelope.id}`, {
|
||||
headers: { Authorization: `Bearer ${tokenA}` },
|
||||
});
|
||||
|
||||
expect(getRes.ok()).toBeTruthy();
|
||||
expect(getRes.status()).toBe(200);
|
||||
|
||||
const envelopeResponse = (await getRes.json()) as TGetEnvelopeResponse;
|
||||
|
||||
const recipientId = envelopeResponse.recipients[0].id;
|
||||
const alignmentItem = envelopeResponse.envelopeItems.find(
|
||||
(item: { order: number }) => item.order === 1,
|
||||
);
|
||||
const fieldMetaItem = envelopeResponse.envelopeItems.find(
|
||||
(item: { order: number }) => item.order === 2,
|
||||
);
|
||||
|
||||
expect(recipientId).toBeDefined();
|
||||
expect(alignmentItem).toBeDefined();
|
||||
expect(fieldMetaItem).toBeDefined();
|
||||
|
||||
if (!alignmentItem || !fieldMetaItem) {
|
||||
throw new Error('Envelope items not found');
|
||||
}
|
||||
|
||||
// Step 6: Create fields for first PDF (alignment fields)
|
||||
const alignmentFieldsRequest = {
|
||||
envelopeId: createdEnvelope.id,
|
||||
data: formatAlignmentTestFields.map((field) => ({
|
||||
recipientId,
|
||||
envelopeItemId: alignmentItem.id,
|
||||
type: field.type,
|
||||
page: field.page,
|
||||
positionX: field.positionX,
|
||||
positionY: field.positionY,
|
||||
width: field.width,
|
||||
height: field.height,
|
||||
fieldMeta: field.fieldMeta,
|
||||
})),
|
||||
};
|
||||
|
||||
const createAlignmentFieldsRes = await request.post(`${baseUrl}/envelope/field/create-many`, {
|
||||
headers: { Authorization: `Bearer ${tokenA}` },
|
||||
data: alignmentFieldsRequest,
|
||||
});
|
||||
|
||||
expect(createAlignmentFieldsRes.ok()).toBeTruthy();
|
||||
expect(createAlignmentFieldsRes.status()).toBe(200);
|
||||
|
||||
// Step 7: Create fields for second PDF (field-meta fields)
|
||||
const fieldMetaFieldsRequest = {
|
||||
envelopeId: createdEnvelope.id,
|
||||
data: FIELD_META_TEST_FIELDS.map((field) => ({
|
||||
recipientId,
|
||||
envelopeItemId: fieldMetaItem.id,
|
||||
type: field.type,
|
||||
page: field.page,
|
||||
positionX: field.positionX,
|
||||
positionY: field.positionY,
|
||||
width: field.width,
|
||||
height: field.height,
|
||||
fieldMeta: field.fieldMeta,
|
||||
})),
|
||||
};
|
||||
|
||||
const createFieldMetaFieldsRes = await request.post(`${baseUrl}/envelope/field/create-many`, {
|
||||
headers: { Authorization: `Bearer ${tokenA}` },
|
||||
data: fieldMetaFieldsRequest,
|
||||
});
|
||||
|
||||
expect(createFieldMetaFieldsRes.ok()).toBeTruthy();
|
||||
expect(createFieldMetaFieldsRes.status()).toBe(200);
|
||||
|
||||
// Step 8: Verify final envelope structure
|
||||
const finalGetRes = await request.get(`${baseUrl}/envelope/${createdEnvelope.id}`, {
|
||||
headers: { Authorization: `Bearer ${tokenA}` },
|
||||
});
|
||||
|
||||
expect(finalGetRes.ok()).toBeTruthy();
|
||||
const finalEnvelope = (await finalGetRes.json()) as TGetEnvelopeResponse;
|
||||
|
||||
// Verify structure
|
||||
expect(finalEnvelope.envelopeItems.length).toBe(2);
|
||||
expect(finalEnvelope.recipients.length).toBe(1);
|
||||
expect(finalEnvelope.fields.length).toBe(
|
||||
formatAlignmentTestFields.length + FIELD_META_TEST_FIELDS.length,
|
||||
);
|
||||
expect(finalEnvelope.title).toBe('Envelope Full Field Test');
|
||||
expect(finalEnvelope.type).toBe(EnvelopeType.DOCUMENT);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user