mirror of
https://github.com/documenso/documenso.git
synced 2026-07-14 23:07:13 +10:00
287 lines
9.0 KiB
TypeScript
287 lines
9.0 KiB
TypeScript
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
|
import { createApiToken } from '@documenso/lib/server-only/public-api/create-api-token';
|
|
import { prisma } from '@documenso/prisma';
|
|
import { EnvelopeType, RecipientRole } from '@documenso/prisma/client';
|
|
import { seedPendingDocument } from '@documenso/prisma/seed/documents';
|
|
import { seedUser } from '@documenso/prisma/seed/users';
|
|
import type {
|
|
TCreateEnvelopePayload,
|
|
TCreateEnvelopeResponse,
|
|
} from '@documenso/trpc/server/envelope-router/create-envelope.types';
|
|
import type { TDistributeEnvelopeRequest } from '@documenso/trpc/server/envelope-router/distribute-envelope.types';
|
|
import { expect, test } from '@playwright/test';
|
|
|
|
import { apiSignin } from '../fixtures/authentication';
|
|
import { openDropdownMenu } from '../fixtures/generic';
|
|
|
|
const WEBAPP_BASE_URL = NEXT_PUBLIC_WEBAPP_URL();
|
|
const baseUrl = `${WEBAPP_BASE_URL}/api/v2-beta`;
|
|
|
|
const examplePdf = fs.readFileSync(path.join(__dirname, '../../../../assets/example.pdf'));
|
|
|
|
test.describe.configure({ mode: 'parallel' });
|
|
|
|
test('[ENVELOPE_EXPIRATION]: sending document sets expiresAt on recipients', async ({ request }) => {
|
|
const { user, team } = await seedUser();
|
|
|
|
const { token } = await createApiToken({
|
|
userId: user.id,
|
|
teamId: team.id,
|
|
tokenName: 'test-expiration-send',
|
|
expiresIn: null,
|
|
});
|
|
|
|
const createPayload: TCreateEnvelopePayload = {
|
|
type: EnvelopeType.DOCUMENT,
|
|
title: '[TEST] Expiration Send Test',
|
|
recipients: [
|
|
{
|
|
email: 'signer-expiry@test.documenso.com',
|
|
name: 'Signer Expiry',
|
|
role: RecipientRole.SIGNER,
|
|
fields: [
|
|
{
|
|
type: 'SIGNATURE',
|
|
page: 1,
|
|
positionX: 10,
|
|
positionY: 10,
|
|
width: 10,
|
|
height: 5,
|
|
fieldMeta: { type: 'signature' },
|
|
},
|
|
],
|
|
},
|
|
],
|
|
};
|
|
|
|
const formData = new FormData();
|
|
formData.append('payload', JSON.stringify(createPayload));
|
|
formData.append('files', new File([examplePdf], 'example.pdf', { type: 'application/pdf' }));
|
|
|
|
const createRes = await request.post(`${baseUrl}/envelope/create`, {
|
|
headers: { Authorization: `Bearer ${token}` },
|
|
multipart: formData,
|
|
});
|
|
|
|
expect(createRes.ok()).toBeTruthy();
|
|
|
|
const { id: envelopeId }: TCreateEnvelopeResponse = await createRes.json();
|
|
|
|
const distributeRes = await request.post(`${baseUrl}/envelope/distribute`, {
|
|
headers: { Authorization: `Bearer ${token}` },
|
|
data: { envelopeId } satisfies TDistributeEnvelopeRequest,
|
|
});
|
|
|
|
expect(distributeRes.ok()).toBeTruthy();
|
|
|
|
// Check that recipients now have expiresAt set.
|
|
const recipients = await prisma.recipient.findMany({
|
|
where: { envelopeId },
|
|
});
|
|
|
|
expect(recipients.length).toBe(1);
|
|
expect(recipients[0].expiresAt).not.toBeNull();
|
|
|
|
// The default expiration period is 3 months. Verify it's roughly correct.
|
|
const expiresAt = recipients[0].expiresAt!;
|
|
const now = new Date();
|
|
const diffMs = expiresAt.getTime() - now.getTime();
|
|
const diffDays = diffMs / (1000 * 60 * 60 * 24);
|
|
|
|
// 3 months is roughly 89-92 days. Allow a generous range.
|
|
expect(diffDays).toBeGreaterThan(80);
|
|
expect(diffDays).toBeLessThan(100);
|
|
});
|
|
|
|
test('[ENVELOPE_EXPIRATION]: sending document with custom org expiration period', async ({ request }) => {
|
|
const { user, organisation, team } = await seedUser();
|
|
|
|
// Set org expiration to 7 days.
|
|
await prisma.organisationGlobalSettings.update({
|
|
where: { id: organisation.organisationGlobalSettingsId },
|
|
data: { envelopeExpirationPeriod: { unit: 'day', amount: 7 } },
|
|
});
|
|
|
|
const { token } = await createApiToken({
|
|
userId: user.id,
|
|
teamId: team.id,
|
|
tokenName: 'test-expiration-custom',
|
|
expiresIn: null,
|
|
});
|
|
|
|
const createPayload: TCreateEnvelopePayload = {
|
|
type: EnvelopeType.DOCUMENT,
|
|
title: '[TEST] Custom Expiration Send Test',
|
|
recipients: [
|
|
{
|
|
email: 'signer-custom@test.documenso.com',
|
|
name: 'Signer Custom',
|
|
role: RecipientRole.SIGNER,
|
|
fields: [
|
|
{
|
|
type: 'SIGNATURE',
|
|
page: 1,
|
|
positionX: 10,
|
|
positionY: 10,
|
|
width: 10,
|
|
height: 5,
|
|
fieldMeta: { type: 'signature' },
|
|
},
|
|
],
|
|
},
|
|
],
|
|
};
|
|
|
|
const formData = new FormData();
|
|
formData.append('payload', JSON.stringify(createPayload));
|
|
formData.append('files', new File([examplePdf], 'example.pdf', { type: 'application/pdf' }));
|
|
|
|
const createRes = await request.post(`${baseUrl}/envelope/create`, {
|
|
headers: { Authorization: `Bearer ${token}` },
|
|
multipart: formData,
|
|
});
|
|
|
|
expect(createRes.ok()).toBeTruthy();
|
|
|
|
const { id: envelopeId }: TCreateEnvelopeResponse = await createRes.json();
|
|
|
|
const distributeRes = await request.post(`${baseUrl}/envelope/distribute`, {
|
|
headers: { Authorization: `Bearer ${token}` },
|
|
data: { envelopeId } satisfies TDistributeEnvelopeRequest,
|
|
});
|
|
|
|
expect(distributeRes.ok()).toBeTruthy();
|
|
|
|
const recipients = await prisma.recipient.findMany({
|
|
where: { envelopeId },
|
|
});
|
|
|
|
expect(recipients.length).toBe(1);
|
|
expect(recipients[0].expiresAt).not.toBeNull();
|
|
|
|
// 7 days expiration.
|
|
const expiresAt = recipients[0].expiresAt!;
|
|
const now = new Date();
|
|
const diffMs = expiresAt.getTime() - now.getTime();
|
|
const diffDays = diffMs / (1000 * 60 * 60 * 24);
|
|
|
|
expect(diffDays).toBeGreaterThan(6);
|
|
expect(diffDays).toBeLessThan(8);
|
|
});
|
|
|
|
test('[ENVELOPE_EXPIRATION]: sending document with expiration disabled', async ({ request }) => {
|
|
const { user, organisation, team } = await seedUser();
|
|
|
|
// Disable expiration at org level.
|
|
await prisma.organisationGlobalSettings.update({
|
|
where: { id: organisation.organisationGlobalSettingsId },
|
|
data: { envelopeExpirationPeriod: { disabled: true } },
|
|
});
|
|
|
|
const { token } = await createApiToken({
|
|
userId: user.id,
|
|
teamId: team.id,
|
|
tokenName: 'test-expiration-disabled',
|
|
expiresIn: null,
|
|
});
|
|
|
|
const createPayload: TCreateEnvelopePayload = {
|
|
type: EnvelopeType.DOCUMENT,
|
|
title: '[TEST] Disabled Expiration Send Test',
|
|
recipients: [
|
|
{
|
|
email: 'signer-disabled@test.documenso.com',
|
|
name: 'Signer Disabled',
|
|
role: RecipientRole.SIGNER,
|
|
fields: [
|
|
{
|
|
type: 'SIGNATURE',
|
|
page: 1,
|
|
positionX: 10,
|
|
positionY: 10,
|
|
width: 10,
|
|
height: 5,
|
|
fieldMeta: { type: 'signature' },
|
|
},
|
|
],
|
|
},
|
|
],
|
|
};
|
|
|
|
const formData = new FormData();
|
|
formData.append('payload', JSON.stringify(createPayload));
|
|
formData.append('files', new File([examplePdf], 'example.pdf', { type: 'application/pdf' }));
|
|
|
|
const createRes = await request.post(`${baseUrl}/envelope/create`, {
|
|
headers: { Authorization: `Bearer ${token}` },
|
|
multipart: formData,
|
|
});
|
|
|
|
expect(createRes.ok()).toBeTruthy();
|
|
|
|
const { id: envelopeId }: TCreateEnvelopeResponse = await createRes.json();
|
|
|
|
const distributeRes = await request.post(`${baseUrl}/envelope/distribute`, {
|
|
headers: { Authorization: `Bearer ${token}` },
|
|
data: { envelopeId } satisfies TDistributeEnvelopeRequest,
|
|
});
|
|
|
|
expect(distributeRes.ok()).toBeTruthy();
|
|
|
|
const recipients = await prisma.recipient.findMany({
|
|
where: { envelopeId },
|
|
});
|
|
|
|
expect(recipients.length).toBe(1);
|
|
expect(recipients[0].expiresAt).toBeNull();
|
|
});
|
|
|
|
test('[ENVELOPE_EXPIRATION]: resending refreshes expiresAt', async ({ page }) => {
|
|
const { user, team } = await seedUser();
|
|
|
|
const document = await seedPendingDocument(user, team.id, ['resend-target@test.documenso.com']);
|
|
|
|
const recipient = document.recipients[0];
|
|
|
|
// Set an initial expiresAt that's 1 day from now.
|
|
const initialExpiresAt = new Date(Date.now() + 24 * 60 * 60 * 1000);
|
|
|
|
await prisma.recipient.update({
|
|
where: { id: recipient.id },
|
|
data: { expiresAt: initialExpiresAt },
|
|
});
|
|
|
|
await apiSignin({
|
|
page,
|
|
email: user.email,
|
|
redirectPath: `/t/${team.url}/documents?status=PENDING`,
|
|
});
|
|
|
|
// Open the document action menu and click Resend.
|
|
const actionBtn = page.getByTestId('document-table-action-btn').first();
|
|
await expect(actionBtn).toBeAttached();
|
|
await openDropdownMenu(page, actionBtn);
|
|
await expect(page.getByRole('menuitem', { name: 'Resend' })).toBeVisible();
|
|
await page.getByRole('menuitem', { name: 'Resend' }).click();
|
|
|
|
// Select the recipient and send.
|
|
await page.getByLabel('test.documenso.com').first().click();
|
|
await page.getByRole('button', { name: 'Send reminder' }).click();
|
|
|
|
await expect(page.getByText('Document re-sent', { exact: true })).toBeVisible({
|
|
timeout: 10_000,
|
|
});
|
|
|
|
// Verify expiresAt was refreshed.
|
|
await expect(async () => {
|
|
const updatedRecipient = await prisma.recipient.findUniqueOrThrow({
|
|
where: { id: recipient.id },
|
|
});
|
|
|
|
expect(updatedRecipient.expiresAt).not.toBeNull();
|
|
expect(updatedRecipient.expiresAt!.getTime()).toBeGreaterThan(initialExpiresAt.getTime());
|
|
}).toPass({ timeout: 10_000 });
|
|
});
|