mirror of
https://github.com/documenso/documenso.git
synced 2025-11-13 00:03:33 +10:00
265 lines
8.6 KiB
TypeScript
265 lines
8.6 KiB
TypeScript
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);
|
|
});
|
|
});
|