feat: migrate templates and documents to envelope model

This commit is contained in:
David Nguyen
2025-09-11 18:23:38 +10:00
parent eec2307634
commit bf89bc781b
234 changed files with 8677 additions and 6054 deletions

View File

@ -2,6 +2,7 @@ import { expect, test } from '@playwright/test';
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
import { createApiToken } from '@documenso/lib/server-only/public-api/create-api-token';
import { mapSecondaryIdToDocumentId } from '@documenso/lib/utils/envelope';
import { prisma } from '@documenso/prisma';
import { seedPendingDocumentWithFullFields } from '@documenso/prisma/seed/documents';
import { seedUser } from '@documenso/prisma/seed/users';
@ -25,7 +26,7 @@ test.describe('Document API', () => {
// Test with sendCompletionEmails: false
const response = await request.post(
`${NEXT_PUBLIC_WEBAPP_URL()}/api/v1/documents/${document.id}/send`,
`${NEXT_PUBLIC_WEBAPP_URL()}/api/v1/documents/${mapSecondaryIdToDocumentId(document.secondaryId)}/send`,
{
headers: {
Authorization: `Bearer ${token}`,
@ -41,7 +42,7 @@ test.describe('Document API', () => {
expect(response.status()).toBe(200);
// Verify email settings were updated
const updatedDocument = await prisma.document.findUnique({
const updatedDocument = await prisma.envelope.findUnique({
where: { id: document.id },
include: { documentMeta: true },
});
@ -53,7 +54,7 @@ test.describe('Document API', () => {
// Test with sendCompletionEmails: true
const response2 = await request.post(
`${NEXT_PUBLIC_WEBAPP_URL()}/api/v1/documents/${document.id}/send`,
`${NEXT_PUBLIC_WEBAPP_URL()}/api/v1/documents/${mapSecondaryIdToDocumentId(document.secondaryId)}/send`,
{
headers: {
Authorization: `Bearer ${token}`,
@ -69,7 +70,7 @@ test.describe('Document API', () => {
expect(response2.status()).toBe(200);
// Verify email settings were updated
const updatedDocument2 = await prisma.document.findUnique({
const updatedDocument2 = await prisma.envelope.findUnique({
where: { id: document.id },
include: { documentMeta: true },
});
@ -93,16 +94,16 @@ test.describe('Document API', () => {
// Set initial email settings
await prisma.documentMeta.upsert({
where: { documentId: document.id },
where: { id: document.documentMetaId },
create: {
documentId: document.id,
id: document.documentMetaId,
emailSettings: {
documentCompleted: true,
ownerDocumentCompleted: false,
},
},
update: {
documentId: document.id,
id: document.documentMetaId,
emailSettings: {
documentCompleted: true,
ownerDocumentCompleted: false,
@ -118,7 +119,7 @@ test.describe('Document API', () => {
});
const response = await request.post(
`${NEXT_PUBLIC_WEBAPP_URL()}/api/v1/documents/${document.id}/send`,
`${NEXT_PUBLIC_WEBAPP_URL()}/api/v1/documents/${mapSecondaryIdToDocumentId(document.secondaryId)}/send`,
{
headers: {
Authorization: `Bearer ${token}`,
@ -134,7 +135,7 @@ test.describe('Document API', () => {
expect(response.status()).toBe(200);
// Verify email settings were not modified
const updatedDocument = await prisma.document.findUnique({
const updatedDocument = await prisma.envelope.findUnique({
where: { id: document.id },
include: { documentMeta: true },
});

View File

@ -3,6 +3,11 @@ import { expect, test } from '@playwright/test';
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
import { createApiToken } from '@documenso/lib/server-only/public-api/create-api-token';
import type { TCheckboxFieldMeta, TRadioFieldMeta } from '@documenso/lib/types/field-meta';
import {
mapDocumentIdToSecondaryId,
mapSecondaryIdToDocumentId,
mapSecondaryIdToTemplateId,
} from '@documenso/lib/utils/envelope';
import { prisma } from '@documenso/prisma';
import { FieldType, RecipientRole } from '@documenso/prisma/client';
import { seedBlankTemplate } from '@documenso/prisma/seed/templates';
@ -35,10 +40,12 @@ test.describe('Template Field Prefill API v1', () => {
},
});
const firstEnvelopeItem = template.envelopeItems[0];
// 4. Create a recipient for the template
const recipient = await prisma.recipient.create({
data: {
templateId: template.id,
envelopeId: template.id,
email: 'recipient@example.com',
name: 'Test Recipient',
role: RecipientRole.SIGNER,
@ -53,7 +60,8 @@ test.describe('Template Field Prefill API v1', () => {
// Add TEXT field
const textField = await prisma.field.create({
data: {
templateId: template.id,
envelopeId: template.id,
envelopeItemId: firstEnvelopeItem.id,
recipientId: recipient.id,
type: FieldType.TEXT,
page: 1,
@ -73,7 +81,8 @@ test.describe('Template Field Prefill API v1', () => {
// Add NUMBER field
const numberField = await prisma.field.create({
data: {
templateId: template.id,
envelopeId: template.id,
envelopeItemId: firstEnvelopeItem.id,
recipientId: recipient.id,
type: FieldType.NUMBER,
page: 1,
@ -93,7 +102,8 @@ test.describe('Template Field Prefill API v1', () => {
// Add RADIO field
const radioField = await prisma.field.create({
data: {
templateId: template.id,
envelopeId: template.id,
envelopeItemId: firstEnvelopeItem.id,
recipientId: recipient.id,
type: FieldType.RADIO,
page: 1,
@ -117,7 +127,8 @@ test.describe('Template Field Prefill API v1', () => {
// Add CHECKBOX field
const checkboxField = await prisma.field.create({
data: {
templateId: template.id,
envelopeId: template.id,
envelopeItemId: firstEnvelopeItem.id,
recipientId: recipient.id,
type: FieldType.CHECKBOX,
page: 1,
@ -141,7 +152,8 @@ test.describe('Template Field Prefill API v1', () => {
// Add DROPDOWN field
const dropdownField = await prisma.field.create({
data: {
templateId: template.id,
envelopeId: template.id,
envelopeItemId: firstEnvelopeItem.id,
recipientId: recipient.id,
type: FieldType.DROPDOWN,
page: 1,
@ -166,11 +178,13 @@ test.describe('Template Field Prefill API v1', () => {
});
// 7. Navigate to the template
await page.goto(`${WEBAPP_BASE_URL}/templates/${template.id}`);
await page.goto(
`${WEBAPP_BASE_URL}/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}`,
);
// 8. Create a document from the template with prefilled fields
const response = await request.post(
`${WEBAPP_BASE_URL}/api/v1/templates/${template.id}/generate-document`,
`${WEBAPP_BASE_URL}/api/v1/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}/generate-document`,
{
headers: {
Authorization: `Bearer ${token}`,
@ -229,9 +243,9 @@ test.describe('Template Field Prefill API v1', () => {
expect(responseData.documentId).toBeDefined();
// 9. Verify the document was created with prefilled fields
const document = await prisma.document.findUnique({
const document = await prisma.envelope.findUnique({
where: {
id: responseData.documentId,
secondaryId: mapDocumentIdToSecondaryId(responseData.documentId),
},
include: {
fields: true,
@ -240,6 +254,10 @@ test.describe('Template Field Prefill API v1', () => {
expect(document).not.toBeNull();
if (!document) {
throw new Error('Document not found');
}
// 10. Verify each field has the correct prefilled values
const documentTextField = document?.fields.find(
(field) => field.type === FieldType.TEXT && field.fieldMeta?.type === 'text',
@ -297,14 +315,14 @@ test.describe('Template Field Prefill API v1', () => {
// 11. Sign in as the recipient and verify the prefilled fields are visible
const documentRecipient = await prisma.recipient.findFirst({
where: {
documentId: document?.id,
envelopeId: document?.id,
email: 'recipient@example.com',
},
});
// Send the document to the recipient
const sendResponse = await request.post(
`${WEBAPP_BASE_URL}/api/v1/documents/${document?.id}/send`,
`${WEBAPP_BASE_URL}/api/v1/documents/${mapSecondaryIdToDocumentId(document.secondaryId)}/send`,
{
headers: {
Authorization: `Bearer ${token}`,
@ -367,10 +385,12 @@ test.describe('Template Field Prefill API v1', () => {
},
});
const firstEnvelopeItem = template.envelopeItems[0];
// 4. Create a recipient for the template
const recipient = await prisma.recipient.create({
data: {
templateId: template.id,
envelopeId: template.id,
email: 'recipient@example.com',
name: 'Test Recipient',
role: RecipientRole.SIGNER,
@ -385,7 +405,8 @@ test.describe('Template Field Prefill API v1', () => {
// Add TEXT field
await prisma.field.create({
data: {
templateId: template.id,
envelopeId: template.id,
envelopeItemId: firstEnvelopeItem.id,
recipientId: recipient.id,
type: FieldType.TEXT,
page: 1,
@ -405,7 +426,8 @@ test.describe('Template Field Prefill API v1', () => {
// Add NUMBER field
await prisma.field.create({
data: {
templateId: template.id,
envelopeId: template.id,
envelopeItemId: firstEnvelopeItem.id,
recipientId: recipient.id,
type: FieldType.NUMBER,
page: 1,
@ -429,11 +451,13 @@ test.describe('Template Field Prefill API v1', () => {
});
// 7. Navigate to the template
await page.goto(`${WEBAPP_BASE_URL}/templates/${template.id}`);
await page.goto(
`${WEBAPP_BASE_URL}/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}`,
);
// 8. Create a document from the template without prefilled fields
const response = await request.post(
`${WEBAPP_BASE_URL}/api/v1/templates/${template.id}/generate-document`,
`${WEBAPP_BASE_URL}/api/v1/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}/generate-document`,
{
headers: {
Authorization: `Bearer ${token}`,
@ -461,9 +485,9 @@ test.describe('Template Field Prefill API v1', () => {
expect(responseData.documentId).toBeDefined();
// 9. Verify the document was created with default fields
const document = await prisma.document.findUnique({
const document = await prisma.envelope.findUnique({
where: {
id: responseData.documentId,
secondaryId: mapDocumentIdToSecondaryId(responseData.documentId),
},
include: {
fields: true,
@ -472,6 +496,10 @@ test.describe('Template Field Prefill API v1', () => {
expect(document).not.toBeNull();
if (!document) {
throw new Error('Document not found');
}
// 10. Verify fields have their default values
const documentTextField = document?.fields.find((field) => field.type === FieldType.TEXT);
expect(documentTextField?.fieldMeta).toMatchObject({
@ -488,7 +516,7 @@ test.describe('Template Field Prefill API v1', () => {
// 11. Sign in as the recipient and verify the default fields are visible
const documentRecipient = await prisma.recipient.findFirst({
where: {
documentId: document?.id,
envelopeId: document?.id,
email: 'recipient@example.com',
},
});
@ -496,7 +524,7 @@ test.describe('Template Field Prefill API v1', () => {
expect(documentRecipient).not.toBeNull();
const sendResponse = await request.post(
`${WEBAPP_BASE_URL}/api/v1/documents/${document?.id}/send`,
`${WEBAPP_BASE_URL}/api/v1/documents/${mapSecondaryIdToDocumentId(document.secondaryId)}/send`,
{
headers: {
Authorization: `Bearer ${token}`,
@ -539,10 +567,12 @@ test.describe('Template Field Prefill API v1', () => {
},
});
const firstEnvelopeItem = template.envelopeItems[0];
// 4. Create a recipient for the template
const recipient = await prisma.recipient.create({
data: {
templateId: template.id,
envelopeId: template.id,
email: 'recipient@example.com',
name: 'Test Recipient',
role: RecipientRole.SIGNER,
@ -556,7 +586,8 @@ test.describe('Template Field Prefill API v1', () => {
// 5. Add a field to the template
const field = await prisma.field.create({
data: {
templateId: template.id,
envelopeId: template.id,
envelopeItemId: firstEnvelopeItem.id,
recipientId: recipient.id,
type: FieldType.RADIO,
page: 1,
@ -579,7 +610,7 @@ test.describe('Template Field Prefill API v1', () => {
// 6. Try to create a document with invalid prefill value
const response = await request.post(
`${WEBAPP_BASE_URL}/api/v1/templates/${template.id}/generate-document`,
`${WEBAPP_BASE_URL}/api/v1/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}/generate-document`,
{
headers: {
Authorization: `Bearer ${token}`,

View File

@ -3,6 +3,11 @@ import { expect, test } from '@playwright/test';
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
import { createApiToken } from '@documenso/lib/server-only/public-api/create-api-token';
import type { TCheckboxFieldMeta, TRadioFieldMeta } from '@documenso/lib/types/field-meta';
import {
mapDocumentIdToSecondaryId,
mapSecondaryIdToDocumentId,
mapSecondaryIdToTemplateId,
} from '@documenso/lib/utils/envelope';
import { prisma } from '@documenso/prisma';
import { FieldType, RecipientRole } from '@documenso/prisma/client';
import { seedBlankTemplate } from '@documenso/prisma/seed/templates';
@ -35,10 +40,12 @@ test.describe('Template Field Prefill API v2', () => {
},
});
const firstEnvelopeItem = template.envelopeItems[0];
// 4. Create a recipient for the template
const recipient = await prisma.recipient.create({
data: {
templateId: template.id,
envelopeId: template.id,
email: 'recipient@example.com',
name: 'Test Recipient',
role: RecipientRole.SIGNER,
@ -53,7 +60,8 @@ test.describe('Template Field Prefill API v2', () => {
// Add TEXT field
const textField = await prisma.field.create({
data: {
templateId: template.id,
envelopeId: template.id,
envelopeItemId: firstEnvelopeItem.id,
recipientId: recipient.id,
type: FieldType.TEXT,
page: 1,
@ -73,7 +81,8 @@ test.describe('Template Field Prefill API v2', () => {
// Add NUMBER field
const numberField = await prisma.field.create({
data: {
templateId: template.id,
envelopeId: template.id,
envelopeItemId: firstEnvelopeItem.id,
recipientId: recipient.id,
type: FieldType.NUMBER,
page: 1,
@ -93,7 +102,8 @@ test.describe('Template Field Prefill API v2', () => {
// Add RADIO field
const radioField = await prisma.field.create({
data: {
templateId: template.id,
envelopeId: template.id,
envelopeItemId: firstEnvelopeItem.id,
recipientId: recipient.id,
type: FieldType.RADIO,
page: 1,
@ -117,7 +127,8 @@ test.describe('Template Field Prefill API v2', () => {
// Add CHECKBOX field
const checkboxField = await prisma.field.create({
data: {
templateId: template.id,
envelopeId: template.id,
envelopeItemId: firstEnvelopeItem.id,
recipientId: recipient.id,
type: FieldType.CHECKBOX,
page: 1,
@ -141,7 +152,8 @@ test.describe('Template Field Prefill API v2', () => {
// Add DROPDOWN field
const dropdownField = await prisma.field.create({
data: {
templateId: template.id,
envelopeId: template.id,
envelopeItemId: firstEnvelopeItem.id,
recipientId: recipient.id,
type: FieldType.DROPDOWN,
page: 1,
@ -166,7 +178,9 @@ test.describe('Template Field Prefill API v2', () => {
});
// 7. Navigate to the template
await page.goto(`${WEBAPP_BASE_URL}/templates/${template.id}`);
await page.goto(
`${WEBAPP_BASE_URL}/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}`,
);
// 8. Create a document from the template with prefilled fields using v2 API
const response = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/template/use`, {
@ -175,7 +189,7 @@ test.describe('Template Field Prefill API v2', () => {
'Content-Type': 'application/json',
},
data: {
templateId: template.id,
templateId: mapSecondaryIdToTemplateId(template.secondaryId),
recipients: [
{
id: recipient.id,
@ -226,9 +240,9 @@ test.describe('Template Field Prefill API v2', () => {
expect(responseData.id).toBeDefined();
// 9. Verify the document was created with prefilled fields
const document = await prisma.document.findUnique({
const document = await prisma.envelope.findUnique({
where: {
id: responseData.id,
secondaryId: mapDocumentIdToSecondaryId(responseData.id),
},
include: {
fields: true,
@ -237,6 +251,10 @@ test.describe('Template Field Prefill API v2', () => {
expect(document).not.toBeNull();
if (!document) {
throw new Error('Document not found');
}
// 10. Verify each field has the correct prefilled values
const documentTextField = document?.fields.find(
(field) => field.type === FieldType.TEXT && field.fieldMeta?.type === 'text',
@ -297,7 +315,7 @@ test.describe('Template Field Prefill API v2', () => {
'Content-Type': 'application/json',
},
data: {
documentId: document?.id,
documentId: mapSecondaryIdToDocumentId(document?.secondaryId),
meta: {
subject: 'Test Subject',
message: 'Test Message',
@ -311,7 +329,7 @@ test.describe('Template Field Prefill API v2', () => {
// 11. Sign in as the recipient and verify the prefilled fields are visible
const documentRecipient = await prisma.recipient.findFirst({
where: {
documentId: document?.id,
envelopeId: document?.id,
email: 'recipient@example.com',
},
});
@ -364,10 +382,12 @@ test.describe('Template Field Prefill API v2', () => {
},
});
const firstEnvelopeItem = template.envelopeItems[0];
// 4. Create a recipient for the template
const recipient = await prisma.recipient.create({
data: {
templateId: template.id,
envelopeId: template.id,
email: 'recipient@example.com',
name: 'Test Recipient',
role: RecipientRole.SIGNER,
@ -382,7 +402,8 @@ test.describe('Template Field Prefill API v2', () => {
// Add TEXT field
await prisma.field.create({
data: {
templateId: template.id,
envelopeId: template.id,
envelopeItemId: firstEnvelopeItem.id,
recipientId: recipient.id,
type: FieldType.TEXT,
page: 1,
@ -402,7 +423,8 @@ test.describe('Template Field Prefill API v2', () => {
// Add NUMBER field
await prisma.field.create({
data: {
templateId: template.id,
envelopeId: template.id,
envelopeItemId: firstEnvelopeItem.id,
recipientId: recipient.id,
type: FieldType.NUMBER,
page: 1,
@ -426,7 +448,9 @@ test.describe('Template Field Prefill API v2', () => {
});
// 7. Navigate to the template
await page.goto(`${WEBAPP_BASE_URL}/templates/${template.id}`);
await page.goto(
`${WEBAPP_BASE_URL}/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}`,
);
// 8. Create a document from the template without prefilled fields using v2 API
const response = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/template/use`, {
@ -435,7 +459,7 @@ test.describe('Template Field Prefill API v2', () => {
'Content-Type': 'application/json',
},
data: {
templateId: template.id,
templateId: mapSecondaryIdToTemplateId(template.secondaryId),
recipients: [
{
id: recipient.id,
@ -454,9 +478,9 @@ test.describe('Template Field Prefill API v2', () => {
expect(responseData.id).toBeDefined();
// 9. Verify the document was created with default fields
const document = await prisma.document.findUnique({
const document = await prisma.envelope.findUnique({
where: {
id: responseData.id,
secondaryId: mapDocumentIdToSecondaryId(responseData.id),
},
include: {
fields: true,
@ -465,6 +489,10 @@ test.describe('Template Field Prefill API v2', () => {
expect(document).not.toBeNull();
if (!document) {
throw new Error('Document not found');
}
// 10. Verify fields have their default values
const documentTextField = document?.fields.find((field) => field.type === FieldType.TEXT);
expect(documentTextField?.fieldMeta).toMatchObject({
@ -484,7 +512,7 @@ test.describe('Template Field Prefill API v2', () => {
'Content-Type': 'application/json',
},
data: {
documentId: document?.id,
documentId: mapSecondaryIdToDocumentId(document?.secondaryId),
meta: {
subject: 'Test Subject',
message: 'Test Message',
@ -498,7 +526,7 @@ test.describe('Template Field Prefill API v2', () => {
// 11. Sign in as the recipient and verify the default fields are visible
const documentRecipient = await prisma.recipient.findFirst({
where: {
documentId: document?.id,
envelopeId: document?.id,
email: 'recipient@example.com',
},
});
@ -531,10 +559,12 @@ test.describe('Template Field Prefill API v2', () => {
},
});
const firstEnvelopeItem = template.envelopeItems[0];
// 4. Create a recipient for the template
const recipient = await prisma.recipient.create({
data: {
templateId: template.id,
envelopeId: template.id,
email: 'recipient@example.com',
name: 'Test Recipient',
role: RecipientRole.SIGNER,
@ -548,7 +578,8 @@ test.describe('Template Field Prefill API v2', () => {
// 5. Add a field to the template
const field = await prisma.field.create({
data: {
templateId: template.id,
envelopeId: template.id,
envelopeItemId: firstEnvelopeItem.id,
recipientId: recipient.id,
type: FieldType.RADIO,
page: 1,
@ -576,7 +607,7 @@ test.describe('Template Field Prefill API v2', () => {
'Content-Type': 'application/json',
},
data: {
templateId: template.id,
templateId: mapSecondaryIdToTemplateId(template.secondaryId),
recipients: [
{
id: recipient.id,

View File

@ -19,7 +19,7 @@ test('[DOCUMENT_AUTH]: should grant access when not required', async ({ page })
const recipients = await prisma.recipient.findMany({
where: {
documentId: document.id,
envelopeId: document.id,
},
});
@ -52,7 +52,7 @@ test('[DOCUMENT_AUTH]: should allow or deny access when required', async ({ page
const recipients = await prisma.recipient.findMany({
where: {
documentId: document.id,
envelopeId: document.id,
},
});

View File

@ -85,7 +85,7 @@ test('[NEXT_RECIPIENT_DICTATION]: should allow updating next recipient when dict
await page.waitForURL(`${signUrl}/complete`);
// Verify document and recipient states
const updatedDocument = await prisma.document.findUniqueOrThrow({
const updatedDocument = await prisma.envelope.findUniqueOrThrow({
where: { id: document.id },
include: {
recipients: {
@ -172,7 +172,7 @@ test('[NEXT_RECIPIENT_DICTATION]: should not show dictation UI when disabled', a
// Verify document and recipient states
const updatedDocument = await prisma.document.findUniqueOrThrow({
const updatedDocument = await prisma.envelope.findUniqueOrThrow({
where: { id: document.id },
include: {
recipients: {
@ -259,7 +259,7 @@ test('[NEXT_RECIPIENT_DICTATION]: should work with parallel signing flow', async
// Verify final document and recipient states
await expect(async () => {
const updatedDocument = await prisma.document.findUniqueOrThrow({
const updatedDocument = await prisma.envelope.findUniqueOrThrow({
where: { id: document.id },
include: {
recipients: {
@ -362,7 +362,7 @@ test('[NEXT_RECIPIENT_DICTATION]: should allow assistant to dictate next signer'
// Verify document and recipient states
await expect(async () => {
const updatedDocument = await prisma.document.findUniqueOrThrow({
const updatedDocument = await prisma.envelope.findUniqueOrThrow({
where: { id: document.id },
include: {
recipients: {

View File

@ -1,5 +1,6 @@
import { expect, test } from '@playwright/test';
import { mapSecondaryIdToDocumentId } from '@documenso/lib/utils/envelope';
import {
seedBlankDocument,
seedDraftDocument,
@ -16,7 +17,7 @@ test('[DOCUMENT_FLOW]: add settings', async ({ page }) => {
await apiSignin({
page,
email: user.email,
redirectPath: `/t/${team.url}/documents/${document.id}/edit`,
redirectPath: `/t/${team.url}/documents/${mapSecondaryIdToDocumentId(document.secondaryId)}/edit`,
});
// Set title.
@ -52,13 +53,15 @@ test('[DOCUMENT_FLOW]: title should be disabled depending on document status', a
await apiSignin({
page,
email: user.email,
redirectPath: `/t/${team.url}/documents/${pendingDocument.id}/edit`,
redirectPath: `/t/${team.url}/documents/${mapSecondaryIdToDocumentId(pendingDocument.secondaryId)}/edit`,
});
// Should be disabled for pending documents.
await expect(page.getByLabel('Title')).toBeDisabled();
// Should be enabled for draft documents.
await page.goto(`/t/${team.url}/documents/${draftDocument.id}/edit`);
await page.goto(
`/t/${team.url}/documents/${mapSecondaryIdToDocumentId(draftDocument.secondaryId)}/edit`,
);
await expect(page.getByLabel('Title')).toBeEnabled();
});

View File

@ -1,5 +1,6 @@
import { expect, test } from '@playwright/test';
import { mapSecondaryIdToDocumentId } from '@documenso/lib/utils/envelope';
import { seedBlankDocument } from '@documenso/prisma/seed/documents';
import { seedUser } from '@documenso/prisma/seed/users';
@ -12,7 +13,7 @@ test('[DOCUMENT_FLOW]: add signers', async ({ page }) => {
await apiSignin({
page,
email: user.email,
redirectPath: `/t/${team.url}/documents/${document.id}/edit`,
redirectPath: `/t/${team.url}/documents/${mapSecondaryIdToDocumentId(document.secondaryId)}/edit`,
});
// Save the settings by going to the next step.

View File

@ -9,7 +9,10 @@ import {
import { DateTime } from 'luxon';
import path from 'node:path';
import { getRecipientByEmail } from '@documenso/lib/server-only/recipient/get-recipient-by-email';
import {
mapDocumentIdToSecondaryId,
mapSecondaryIdToDocumentId,
} from '@documenso/lib/utils/envelope';
import { prisma } from '@documenso/prisma';
import {
seedBlankDocument,
@ -23,7 +26,7 @@ import { signSignaturePad } from '../fixtures/signature';
// Can't use the function in server-only/document due to it indirectly using
// require imports.
const getDocumentByToken = async (token: string) => {
return await prisma.document.findFirstOrThrow({
return await prisma.envelope.findFirstOrThrow({
where: {
recipients: {
some: {
@ -69,7 +72,7 @@ test('[DOCUMENT_FLOW]: should be able to create a document', async ({ page }) =>
await apiSignin({
page,
email: user.email,
redirectPath: `/t/${team.url}/documents/${document.id}/edit`,
redirectPath: `/t/${team.url}/documents/${mapSecondaryIdToDocumentId(document.secondaryId)}/edit`,
});
const documentTitle = `example-${Date.now()}.pdf`;
@ -130,7 +133,7 @@ test('[DOCUMENT_FLOW]: should be able to create a document with multiple recipie
await apiSignin({
page,
email: user.email,
redirectPath: `/t/${team.url}/documents/${document.id}/edit`,
redirectPath: `/t/${team.url}/documents/${mapSecondaryIdToDocumentId(document.secondaryId)}/edit`,
});
const documentTitle = `example-${Date.now()}.pdf`;
@ -215,7 +218,7 @@ test('[DOCUMENT_FLOW]: should be able to create a document with multiple recipie
await apiSignin({
page,
email: user.email,
redirectPath: `/t/${team.url}/documents/${document.id}/edit`,
redirectPath: `/t/${team.url}/documents/${mapSecondaryIdToDocumentId(document.secondaryId)}/edit`,
});
// Set title
@ -313,7 +316,7 @@ test('[DOCUMENT_FLOW]: should not be able to create a document without signature
await apiSignin({
page,
email: user.email,
redirectPath: `/t/${team.url}/documents/${document.id}/edit`,
redirectPath: `/t/${team.url}/documents/${mapSecondaryIdToDocumentId(document.secondaryId)}/edit`,
});
const documentTitle = `example-${Date.now()}.pdf`;
@ -401,7 +404,7 @@ test('[DOCUMENT_FLOW]: should be able to create, send with redirect url, sign a
await apiSignin({
page,
email: user.email,
redirectPath: `/t/${team.url}/documents/${document.id}/edit`,
redirectPath: `/t/${team.url}/documents/${mapSecondaryIdToDocumentId(document.secondaryId)}/edit`,
});
const documentTitle = `example-${Date.now()}.pdf`;
@ -442,9 +445,13 @@ test('[DOCUMENT_FLOW]: should be able to create, send with redirect url, sign a
const url = page.url().split('/');
const documentId = url[url.length - 1];
const { token } = await getRecipientByEmail({
email: 'user1@example.com',
documentId: Number(documentId),
const { token } = await prisma.recipient.findFirstOrThrow({
where: {
envelope: {
secondaryId: mapDocumentIdToSecondaryId(Number(documentId)),
},
email: 'user1@example.com',
},
});
await page.goto(`/sign/${token}`);
@ -500,7 +507,7 @@ test('[DOCUMENT_FLOW]: should be able to sign a document with custom date', asyn
recipient: {
email: 'user1@example.com',
},
documentId: Number(document.id),
envelopeId: document.id,
},
});
@ -525,7 +532,7 @@ test('[DOCUMENT_FLOW]: should be able to create and sign a document with 3 recip
await apiSignin({
page,
email: user.email,
redirectPath: `/t/${team.url}/documents/${document.id}/edit`,
redirectPath: `/t/${team.url}/documents/${mapSecondaryIdToDocumentId(document.secondaryId)}/edit`,
});
const documentTitle = `Sequential-Signing-${Date.now()}.pdf`;
@ -587,7 +594,7 @@ test('[DOCUMENT_FLOW]: should be able to create and sign a document with 3 recip
await expect(page.getByRole('link', { name: documentTitle })).toBeVisible();
const createdDocument = await prisma.document.findFirst({
const createdDocument = await prisma.envelope.findFirst({
where: { title: documentTitle },
include: { recipients: true },
});
@ -602,13 +609,13 @@ test('[DOCUMENT_FLOW]: should be able to create and sign a document with 3 recip
expect(recipient).not.toBeNull();
const fields = await prisma.field.findMany({
where: { recipientId: recipient?.id, documentId: createdDocument?.id },
where: { recipientId: recipient?.id, envelopeId: createdDocument?.id },
});
const recipientField = fields[0];
if (i > 0) {
const previousRecipient = await prisma.recipient.findFirst({
where: { email: `user${i}@example.com`, documentId: createdDocument?.id },
where: { email: `user${i}@example.com`, envelopeId: createdDocument?.id },
});
expect(previousRecipient?.signingStatus).toBe(SigningStatus.SIGNED);
@ -636,7 +643,7 @@ test('[DOCUMENT_FLOW]: should be able to create and sign a document with 3 recip
// Wait for the document to be signed.
await page.waitForTimeout(10000);
const finalDocument = await prisma.document.findFirst({
const finalDocument = await prisma.envelope.findFirst({
where: { id: createdDocument?.id },
});
@ -648,18 +655,20 @@ test('[DOCUMENT_FLOW]: should prevent out-of-order signing in sequential mode',
}) => {
const { user, team } = await seedUser();
const { recipients } = await seedPendingDocumentWithFullFields({
const { document, recipients } = await seedPendingDocumentWithFullFields({
teamId: team.id,
owner: user,
recipients: ['user1@example.com', 'user2@example.com', 'user3@example.com'],
fields: [FieldType.SIGNATURE],
recipientsCreateOptions: [{ signingOrder: 1 }, { signingOrder: 2 }, { signingOrder: 3 }],
updateDocumentOptions: {
documentMeta: {
create: {
signingOrder: DocumentSigningOrder.SEQUENTIAL,
},
},
});
await prisma.documentMeta.update({
where: {
id: document.documentMetaId,
},
data: {
signingOrder: DocumentSigningOrder.SEQUENTIAL,
},
});

View File

@ -1,6 +1,7 @@
import { expect, test } from '@playwright/test';
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
import { mapSecondaryIdToDocumentId } from '@documenso/lib/utils/envelope';
import {
seedBlankDocument,
seedCompletedDocument,
@ -27,7 +28,9 @@ test.describe('Unauthorized Access to Documents', () => {
redirectPath: `/t/${team.url}/documents`,
});
await page.goto(`${NEXT_PUBLIC_WEBAPP_URL()}/t/${team.url}/documents/${document.id}`);
await page.goto(
`${NEXT_PUBLIC_WEBAPP_URL()}/t/${team.url}/documents/${mapSecondaryIdToDocumentId(document.secondaryId)}`,
);
await expect(page.getByRole('heading', { name: 'Oops! Something went wrong.' })).toBeVisible();
});
@ -40,10 +43,12 @@ test.describe('Unauthorized Access to Documents', () => {
await apiSignin({
page,
email: unauthorizedUser.email,
redirectPath: `/t/${team.url}/documents/${document.id}/edit`,
redirectPath: `/t/${team.url}/documents/${mapSecondaryIdToDocumentId(document.secondaryId)}/edit`,
});
await page.goto(`${NEXT_PUBLIC_WEBAPP_URL()}/t/${team.url}/documents/${document.id}/edit`);
await page.goto(
`${NEXT_PUBLIC_WEBAPP_URL()}/t/${team.url}/documents/${mapSecondaryIdToDocumentId(document.secondaryId)}/edit`,
);
await expect(page.getByRole('heading', { name: 'Oops! Something went wrong.' })).toBeVisible();
});
@ -57,10 +62,12 @@ test.describe('Unauthorized Access to Documents', () => {
await apiSignin({
page,
email: unauthorizedUser.email,
redirectPath: `/t/${team.url}/documents/${document.id}`,
redirectPath: `/t/${team.url}/documents/${mapSecondaryIdToDocumentId(document.secondaryId)}`,
});
await page.goto(`${NEXT_PUBLIC_WEBAPP_URL()}/t/${team.url}/documents/${document.id}`);
await page.goto(
`${NEXT_PUBLIC_WEBAPP_URL()}/t/${team.url}/documents/${mapSecondaryIdToDocumentId(document.secondaryId)}`,
);
await expect(page.getByRole('heading', { name: 'Oops! Something went wrong.' })).toBeVisible();
});
@ -74,10 +81,12 @@ test.describe('Unauthorized Access to Documents', () => {
await apiSignin({
page,
email: unauthorizedUser.email,
redirectPath: `/t/${team.url}/documents/${document.id}/edit`,
redirectPath: `/t/${team.url}/documents/${mapSecondaryIdToDocumentId(document.secondaryId)}/edit`,
});
await page.goto(`${NEXT_PUBLIC_WEBAPP_URL()}/t/${team.url}/documents/${document.id}/edit`);
await page.goto(
`${NEXT_PUBLIC_WEBAPP_URL()}/t/${team.url}/documents/${mapSecondaryIdToDocumentId(document.secondaryId)}/edit`,
);
await expect(page.getByRole('heading', { name: 'Oops! Something went wrong.' })).toBeVisible();
});
@ -91,10 +100,12 @@ test.describe('Unauthorized Access to Documents', () => {
await apiSignin({
page,
email: unauthorizedUser.email,
redirectPath: `/t/${team.url}/documents/${document.id}`,
redirectPath: `/t/${team.url}/documents/${mapSecondaryIdToDocumentId(document.secondaryId)}`,
});
await page.goto(`${NEXT_PUBLIC_WEBAPP_URL()}/t/${team.url}/documents/${document.id}`);
await page.goto(
`${NEXT_PUBLIC_WEBAPP_URL()}/t/${team.url}/documents/${mapSecondaryIdToDocumentId(document.secondaryId)}`,
);
await expect(page.getByRole('heading', { name: 'Oops! Something went wrong.' })).toBeVisible();
});
});

View File

@ -28,7 +28,9 @@ test.describe('Signing Certificate Tests', () => {
const documentData = await prisma.documentData
.findFirstOrThrow({
where: {
id: document.documentDataId,
envelopeItem: {
envelopeId: document.id,
},
},
})
.then(async (data) => getFile(data));
@ -65,12 +67,21 @@ test.describe('Signing Certificate Tests', () => {
await page.waitForTimeout(2500);
// Get the completed document
const completedDocument = await prisma.document.findFirstOrThrow({
const completedDocument = await prisma.envelope.findFirstOrThrow({
where: { id: document.id },
include: { documentData: true },
include: {
envelopeItems: {
include: {
documentData: true,
},
},
},
});
const completedDocumentData = await getFile(completedDocument.documentData);
// Todo: Envelopes
const firstDocumentData = completedDocument.envelopeItems[0].documentData;
const completedDocumentData = await getFile(firstDocumentData);
// Load the PDF and check number of pages
const pdfDoc = await PDFDocument.load(completedDocumentData);
@ -110,7 +121,9 @@ test.describe('Signing Certificate Tests', () => {
const documentData = await prisma.documentData
.findFirstOrThrow({
where: {
id: document.documentDataId,
envelopeItem: {
envelopeId: document.id,
},
},
})
.then(async (data) => getFile(data));
@ -145,12 +158,21 @@ test.describe('Signing Certificate Tests', () => {
await page.waitForTimeout(2500);
// Get the completed document
const completedDocument = await prisma.document.findFirstOrThrow({
const completedDocument = await prisma.envelope.findFirstOrThrow({
where: { id: document.id },
include: { documentData: true },
include: {
envelopeItems: {
include: {
documentData: true,
},
},
},
});
const completedDocumentData = await getFile(completedDocument.documentData);
// Todo: Envelopes
const firstDocumentData = completedDocument.envelopeItems[0].documentData;
const completedDocumentData = await getFile(firstDocumentData);
// Load the PDF and check number of pages
const completedPdf = await PDFDocument.load(completedDocumentData);
@ -190,7 +212,9 @@ test.describe('Signing Certificate Tests', () => {
const documentData = await prisma.documentData
.findFirstOrThrow({
where: {
id: document.documentDataId,
envelopeItem: {
envelopeId: document.id,
},
},
})
.then(async (data) => getFile(data));
@ -225,12 +249,18 @@ test.describe('Signing Certificate Tests', () => {
await page.waitForTimeout(2500);
// Get the completed document
const completedDocument = await prisma.document.findFirstOrThrow({
const completedDocument = await prisma.envelope.findFirstOrThrow({
where: { id: document.id },
include: { documentData: true },
include: {
envelopeItems: {
include: {
documentData: true,
},
},
},
});
const completedDocumentData = await getFile(completedDocument.documentData);
const completedDocumentData = await getFile(completedDocument.envelopeItems[0].documentData);
// Load the PDF and check number of pages
const completedPdf = await PDFDocument.load(completedDocumentData);

View File

@ -383,12 +383,10 @@ test('[TEAMS]: can create a template inside a template folder', async ({ page })
await page.waitForTimeout(3000);
await page.getByRole('button', { name: 'Create' }).click();
await page.waitForTimeout(1000);
// Expect redirect.
await expect(page.getByText('documenso-supporter-pledge.pdf')).toBeVisible();
// Return to folder and verify file is visible.
await page.goto(`/t/${team.url}/templates/f/${folder.id}`);
await expect(page.getByText('documenso-supporter-pledge.pdf')).toBeVisible();
});

View File

@ -96,7 +96,7 @@ test('[ORGANISATIONS]: manage document preferences', async ({ page }) => {
const documentMeta = await prisma.documentMeta.findFirstOrThrow({
where: {
documentId: document.id,
id: document.documentMetaId,
},
});
@ -272,7 +272,7 @@ test('[ORGANISATIONS]: manage email preferences', async ({ page }) => {
const teamOverrideDocumentMeta = await prisma.documentMeta.findFirstOrThrow({
where: {
documentId: teamOverrideDocument.id,
id: teamOverrideDocument.documentMetaId,
},
});
@ -317,7 +317,7 @@ test('[ORGANISATIONS]: manage email preferences', async ({ page }) => {
const documentMeta = await prisma.documentMeta.findFirstOrThrow({
where: {
documentId: document.id,
id: document.documentMetaId,
},
});

View File

@ -1,6 +1,7 @@
import { expect, test } from '@playwright/test';
import { DocumentStatus, DocumentVisibility, TeamMemberRole } from '@prisma/client';
import { mapSecondaryIdToDocumentId } from '@documenso/lib/utils/envelope';
import {
seedBlankDocument,
seedDocuments,
@ -750,7 +751,7 @@ test('[TEAMS]: check that ADMIN role can change document visibility', async ({ p
await apiSignin({
page,
email: adminUser.email,
redirectPath: `/t/${team.url}/documents/${document.id}/edit`,
redirectPath: `/t/${team.url}/documents/${mapSecondaryIdToDocumentId(document.secondaryId)}/edit`,
});
await page.getByTestId('documentVisibilitySelectValue').click();
@ -784,7 +785,7 @@ test('[TEAMS]: check that MEMBER role cannot change visibility of EVERYONE docum
await apiSignin({
page,
email: teamMember.email,
redirectPath: `/t/${team.url}/documents/${document.id}/edit`,
redirectPath: `/t/${team.url}/documents/${mapSecondaryIdToDocumentId(document.secondaryId)}/edit`,
});
await expect(page.getByTestId('documentVisibilitySelectValue')).toHaveText('Everyone');
@ -810,7 +811,7 @@ test('[TEAMS]: check that MEMBER role cannot change visibility of MANAGER_AND_AB
await apiSignin({
page,
email: teamMember.email,
redirectPath: `/t/${team.url}/documents/${document.id}/edit`,
redirectPath: `/t/${team.url}/documents/${mapSecondaryIdToDocumentId(document.secondaryId)}/edit`,
});
await expect(page.getByTestId('documentVisibilitySelectValue')).toHaveText('Managers and above');
@ -836,7 +837,7 @@ test('[TEAMS]: check that MEMBER role cannot change visibility of ADMIN document
await apiSignin({
page,
email: teamMember.email,
redirectPath: `/t/${team.url}/documents/${document.id}/edit`,
redirectPath: `/t/${team.url}/documents/${mapSecondaryIdToDocumentId(document.secondaryId)}/edit`,
});
await expect(page.getByTestId('documentVisibilitySelectValue')).toHaveText('Admins only');
@ -862,7 +863,7 @@ test('[TEAMS]: check that MANAGER role cannot change visibility of ADMIN documen
await apiSignin({
page,
email: teamManager.email,
redirectPath: `/t/${team.url}/documents/${document.id}/edit`,
redirectPath: `/t/${team.url}/documents/${mapSecondaryIdToDocumentId(document.secondaryId)}/edit`,
});
await expect(page.getByTestId('documentVisibilitySelectValue')).toHaveText('Admins only');

View File

@ -1,5 +1,9 @@
import { expect, test } from '@playwright/test';
import {
mapSecondaryIdToDocumentId,
mapSecondaryIdToTemplateId,
} from '@documenso/lib/utils/envelope';
import { prisma } from '@documenso/prisma';
import {
seedTeamDocumentWithMeta,
@ -21,7 +25,9 @@ test('[TEAMS]: check that default team signature settings are all enabled', asyn
const document = await seedTeamDocumentWithMeta(team);
// Create a document and check the settings
await page.goto(`/t/${team.url}/documents/${document.id}/edit`);
await page.goto(
`/t/${team.url}/documents/${mapSecondaryIdToDocumentId(document.secondaryId)}/edit`,
);
// Verify that the settings match
await page.getByRole('button', { name: 'Advanced Options' }).click();
@ -154,7 +160,7 @@ test('[TEAMS]: check signature modes work for templates', async ({ page }) => {
const template = await seedTeamTemplateWithMeta(team);
await page.goto(`/t/${team.url}/templates/${template.id}`);
await page.goto(`/t/${team.url}/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}`);
await page.getByRole('button', { name: 'Use' }).click();
// Check the send document checkbox to true
@ -162,9 +168,10 @@ test('[TEAMS]: check signature modes work for templates', async ({ page }) => {
await page.getByRole('button', { name: 'Create and send' }).click();
await page.waitForTimeout(1000);
const document = await prisma.document.findFirst({
const document = await prisma.envelope.findFirst({
where: {
templateId: template.id,
// Created from template
templateId: mapSecondaryIdToTemplateId(template.secondaryId),
},
include: {
documentMeta: true,

View File

@ -1,6 +1,7 @@
import { expect, test } from '@playwright/test';
import { TeamMemberRole } from '@prisma/client';
import { mapSecondaryIdToTemplateId } from '@documenso/lib/utils/envelope';
import { seedTeam, seedTeamMember } from '@documenso/prisma/seed/teams';
import { seedBlankTemplate } from '@documenso/prisma/seed/templates';
import { seedUser } from '@documenso/prisma/seed/users';
@ -14,7 +15,7 @@ test('[TEMPLATE_FLOW]: add settings', async ({ page }) => {
await apiSignin({
page,
email: user.email,
redirectPath: `/t/${team.url}/templates/${template.id}/edit`,
redirectPath: `/t/${team.url}/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}/edit`,
});
// Set title.
@ -48,7 +49,7 @@ test('[TEMPLATE_FLOW] add document visibility settings', async ({ page }) => {
await apiSignin({
page,
email: user.email,
redirectPath: `/t/${team.url}/templates/${template.id}/edit`,
redirectPath: `/t/${team.url}/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}/edit`,
});
// Set document visibility.
@ -63,7 +64,9 @@ test('[TEMPLATE_FLOW] add document visibility settings', async ({ page }) => {
await expect(page.getByRole('heading', { name: 'Add Placeholders' })).toBeVisible();
// Navigate back to the edit page to check that the settings are saved correctly.
await page.goto(`/t/${team.url}/templates/${template.id}/edit`);
await page.goto(
`/t/${team.url}/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}/edit`,
);
await expect(page.getByRole('heading', { name: 'General' })).toBeVisible();
await expect(page.getByTestId('documentVisibilitySelectValue')).toContainText(
@ -96,7 +99,7 @@ test('[TEMPLATE_FLOW] team member visibility permissions', async ({ page }) => {
await apiSignin({
page,
email: managerUser.email,
redirectPath: `/t/${team.url}/templates/${template.id}/edit`,
redirectPath: `/t/${team.url}/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}/edit`,
});
// Manager should be able to set visibility to managers and above
@ -115,11 +118,12 @@ test('[TEMPLATE_FLOW] team member visibility permissions', async ({ page }) => {
await apiSignin({
page,
email: memberUser.email,
redirectPath: `/t/${team.url}/templates/${template.id}/edit`,
redirectPath: `/t/${team.url}/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}/edit`,
});
// Regular member should not be able to modify visibility when set to managers and above
await expect(page.getByTestId('documentVisibilitySelectValue')).toBeDisabled();
// A regular member should not be able to see the template.
// They should be redirected to the templates page.
expect(new URL(page.url()).pathname).toBe(`/t/${team.url}/templates`);
// Create a new template with 'everyone' visibility
const everyoneTemplate = await seedBlankTemplate(owner, team.id, {
@ -130,7 +134,9 @@ test('[TEMPLATE_FLOW] team member visibility permissions', async ({ page }) => {
});
// Navigate to the new template
await page.goto(`/t/${team.url}/templates/${everyoneTemplate.id}/edit`);
await page.goto(
`/t/${team.url}/templates/${mapSecondaryIdToTemplateId(everyoneTemplate.secondaryId)}/edit`,
);
// Regular member should be able to see but not modify visibility
await expect(page.getByTestId('documentVisibilitySelectValue')).toBeDisabled();

View File

@ -1,5 +1,6 @@
import { expect, test } from '@playwright/test';
import { mapSecondaryIdToTemplateId } from '@documenso/lib/utils/envelope';
import { seedBlankTemplate } from '@documenso/prisma/seed/templates';
import { seedUser } from '@documenso/prisma/seed/users';
@ -29,7 +30,7 @@ import { apiSignin } from '../fixtures/authentication';
// await apiSignin({
// page,
// email: user.email,
// redirectPath: `/templates/${template.id}/edit`,
// redirectPath: `/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}/edit`,
// });
// // Save the settings by going to the next step.
@ -79,7 +80,7 @@ test('[TEMPLATE_FLOW]: add placeholder', async ({ page }) => {
await apiSignin({
page,
email: user.email,
redirectPath: `/t/${team.url}/templates/${template.id}/edit`,
redirectPath: `/t/${team.url}/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}/edit`,
});
// Save the settings by going to the next step.

View File

@ -4,6 +4,10 @@ import fs from 'fs';
import path from 'path';
import { extractDocumentAuthMethods } from '@documenso/lib/utils/document-auth';
import {
mapDocumentIdToSecondaryId,
mapSecondaryIdToTemplateId,
} from '@documenso/lib/utils/envelope';
import { prisma } from '@documenso/prisma';
import { seedTeam, seedTeamMember } from '@documenso/prisma/seed/teams';
import { seedBlankTemplate } from '@documenso/prisma/seed/templates';
@ -29,7 +33,7 @@ test('[TEMPLATE]: should create a document from a template', async ({ page }) =>
await apiSignin({
page,
email: user.email,
redirectPath: `/t/${team.url}/templates/${template.id}/edit`,
redirectPath: `/t/${team.url}/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}/edit`,
});
// Set template title.
@ -79,9 +83,9 @@ test('[TEMPLATE]: should create a document from a template', async ({ page }) =>
const documentId = Number(page.url().split('/').pop());
const document = await prisma.document.findFirstOrThrow({
const document = await prisma.envelope.findFirstOrThrow({
where: {
id: documentId,
secondaryId: mapDocumentIdToSecondaryId(documentId),
},
include: {
recipients: true,
@ -132,7 +136,7 @@ test('[TEMPLATE]: should create a team document from a team template', async ({
await apiSignin({
page,
email: owner.email,
redirectPath: `/t/${team.url}/templates/${template.id}/edit`,
redirectPath: `/t/${team.url}/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}/edit`,
});
// Set template title.
@ -182,9 +186,9 @@ test('[TEMPLATE]: should create a team document from a team template', async ({
const documentId = Number(page.url().split('/').pop());
const document = await prisma.document.findFirstOrThrow({
const document = await prisma.envelope.findFirstOrThrow({
where: {
id: documentId,
secondaryId: mapDocumentIdToSecondaryId(documentId),
},
include: {
recipients: true,
@ -240,7 +244,7 @@ test('[TEMPLATE]: should create a document from a template with custom document'
await apiSignin({
page,
email: user.email,
redirectPath: `/t/${team.url}/templates/${template.id}/edit`,
redirectPath: `/t/${team.url}/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}/edit`,
});
// Set template title
@ -288,30 +292,36 @@ test('[TEMPLATE]: should create a document from a template with custom document'
const documentId = Number(page.url().split('/').pop());
const document = await prisma.document.findFirstOrThrow({
const document = await prisma.envelope.findFirstOrThrow({
where: {
id: documentId,
secondaryId: mapDocumentIdToSecondaryId(documentId),
},
include: {
documentData: true,
envelopeItems: {
include: {
documentData: true,
},
},
},
});
const firstDocumentData = document.envelopeItems[0].documentData;
const expectedDocumentDataType =
process.env.NEXT_PUBLIC_UPLOAD_TRANSPORT === 's3'
? DocumentDataType.S3_PATH
: DocumentDataType.BYTES_64;
expect(document.title).toEqual('TEMPLATE_WITH_CUSTOM_DOC');
expect(document.documentData.type).toEqual(expectedDocumentDataType);
expect(firstDocumentData.type).toEqual(expectedDocumentDataType);
if (expectedDocumentDataType === DocumentDataType.BYTES_64) {
expect(document.documentData.data).toEqual(pdfContent);
expect(document.documentData.initialData).toEqual(pdfContent);
expect(firstDocumentData.data).toEqual(pdfContent);
expect(firstDocumentData.initialData).toEqual(pdfContent);
} else {
// For S3, we expect the data/initialData to be the S3 path (non-empty string)
expect(document.documentData.data).toBeTruthy();
expect(document.documentData.initialData).toBeTruthy();
expect(firstDocumentData.data).toBeTruthy();
expect(firstDocumentData.initialData).toBeTruthy();
}
});
@ -333,7 +343,7 @@ test('[TEMPLATE]: should create a team document from a template with custom docu
await apiSignin({
page,
email: owner.email,
redirectPath: `/t/${team.url}/templates/${template.id}/edit`,
redirectPath: `/t/${team.url}/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}/edit`,
});
// Set template title
@ -381,12 +391,16 @@ test('[TEMPLATE]: should create a team document from a template with custom docu
const documentId = Number(page.url().split('/').pop());
const document = await prisma.document.findFirstOrThrow({
const document = await prisma.envelope.findFirstOrThrow({
where: {
id: documentId,
secondaryId: mapDocumentIdToSecondaryId(documentId),
},
include: {
documentData: true,
envelopeItems: {
include: {
documentData: true,
},
},
},
});
@ -395,17 +409,19 @@ test('[TEMPLATE]: should create a team document from a template with custom docu
? DocumentDataType.S3_PATH
: DocumentDataType.BYTES_64;
const firstDocumentData = document.envelopeItems[0].documentData;
expect(document.teamId).toEqual(team.id);
expect(document.title).toEqual('TEAM_TEMPLATE_WITH_CUSTOM_DOC');
expect(document.documentData.type).toEqual(expectedDocumentDataType);
expect(firstDocumentData.type).toEqual(expectedDocumentDataType);
if (expectedDocumentDataType === DocumentDataType.BYTES_64) {
expect(document.documentData.data).toEqual(pdfContent);
expect(document.documentData.initialData).toEqual(pdfContent);
expect(firstDocumentData.data).toEqual(pdfContent);
expect(firstDocumentData.initialData).toEqual(pdfContent);
} else {
// For S3, we expect the data/initialData to be the S3 path (non-empty string)
expect(document.documentData.data).toBeTruthy();
expect(document.documentData.initialData).toBeTruthy();
expect(firstDocumentData.data).toBeTruthy();
expect(firstDocumentData.initialData).toBeTruthy();
}
});
@ -422,7 +438,7 @@ test('[TEMPLATE]: should create a document from a template using template docume
await apiSignin({
page,
email: user.email,
redirectPath: `/t/${team.url}/templates/${template.id}/edit`,
redirectPath: `/t/${team.url}/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}/edit`,
});
// Set template title
@ -455,30 +471,40 @@ test('[TEMPLATE]: should create a document from a template using template docume
const documentId = Number(page.url().split('/').pop());
const document = await prisma.document.findFirstOrThrow({
const document = await prisma.envelope.findFirstOrThrow({
where: {
id: documentId,
secondaryId: mapDocumentIdToSecondaryId(documentId),
},
include: {
documentData: true,
envelopeItems: {
include: {
documentData: true,
},
},
},
});
const templateWithData = await prisma.template.findFirstOrThrow({
const firstDocumentData = document.envelopeItems[0].documentData;
const templateWithData = await prisma.envelope.findFirstOrThrow({
where: {
id: template.id,
},
include: {
templateDocumentData: true,
envelopeItems: {
include: {
documentData: true,
},
},
},
});
expect(document.title).toEqual('TEMPLATE_WITH_ORIGINAL_DOC');
expect(document.documentData.data).toEqual(templateWithData.templateDocumentData.data);
expect(document.documentData.initialData).toEqual(
templateWithData.templateDocumentData.initialData,
expect(firstDocumentData.data).toEqual(templateWithData.envelopeItems[0].documentData.data);
expect(firstDocumentData.initialData).toEqual(
templateWithData.envelopeItems[0].documentData.initialData,
);
expect(document.documentData.type).toEqual(templateWithData.templateDocumentData.type);
expect(firstDocumentData.type).toEqual(templateWithData.envelopeItems[0].documentData.type);
});
test('[TEMPLATE]: should persist document visibility when creating from template', async ({
@ -493,7 +519,7 @@ test('[TEMPLATE]: should persist document visibility when creating from template
await apiSignin({
page,
email: owner.email,
redirectPath: `/t/${team.url}/templates/${template.id}/edit`,
redirectPath: `/t/${team.url}/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}/edit`,
});
// Set template title and visibility
@ -536,9 +562,16 @@ test('[TEMPLATE]: should persist document visibility when creating from template
const documentId = Number(page.url().split('/').pop());
const document = await prisma.document.findFirstOrThrow({
const document = await prisma.envelope.findFirstOrThrow({
where: {
id: documentId,
secondaryId: mapDocumentIdToSecondaryId(documentId),
},
include: {
envelopeItems: {
include: {
documentData: true,
},
},
},
});

View File

@ -3,6 +3,7 @@ import { customAlphabet } from 'nanoid';
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
import { createDocumentAuthOptions } from '@documenso/lib/utils/document-auth';
import { mapSecondaryIdToTemplateId } from '@documenso/lib/utils/envelope';
import { formatDirectTemplatePath } from '@documenso/lib/utils/templates';
import { seedTeam } from '@documenso/prisma/seed/teams';
import { seedDirectTemplate, seedTemplate } from '@documenso/prisma/seed/templates';
@ -34,7 +35,7 @@ test('[DIRECT_TEMPLATES]: create direct link for template', async ({ page }) =>
redirectPath: `/t/${team.url}/templates`,
});
const url = `${NEXT_PUBLIC_WEBAPP_URL()}/t/${team.url}/templates/${teamTemplate.id}`;
const url = `${NEXT_PUBLIC_WEBAPP_URL()}/t/${team.url}/templates/${mapSecondaryIdToTemplateId(teamTemplate.secondaryId)}`;
// Owner should see list of templates with no direct link badge.
await page.goto(url);

View File

@ -1,6 +1,7 @@
import { expect, test } from '@playwright/test';
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
import { mapSecondaryIdToTemplateId } from '@documenso/lib/utils/envelope';
import { seedBlankTemplate } from '@documenso/prisma/seed/templates';
import { seedUser } from '@documenso/prisma/seed/users';
@ -20,10 +21,12 @@ test.describe('Unauthorized Access to Templates', () => {
await apiSignin({
page,
email: unauthorizedUser.email,
redirectPath: `/t/${team.url}/templates/${template.id}`,
redirectPath: `/t/${team.url}/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}`,
});
await page.goto(`${NEXT_PUBLIC_WEBAPP_URL()}/t/${team.url}/templates/${template.id}`);
await page.goto(
`${NEXT_PUBLIC_WEBAPP_URL()}/t/${team.url}/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}`,
);
await expect(page.getByRole('heading', { name: 'Oops! Something went wrong.' })).toBeVisible();
});
@ -36,10 +39,12 @@ test.describe('Unauthorized Access to Templates', () => {
await apiSignin({
page,
email: unauthorizedUser.email,
redirectPath: `/t/${team.url}/templates/${template.id}/edit`,
redirectPath: `/t/${team.url}/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}/edit`,
});
await page.goto(`${NEXT_PUBLIC_WEBAPP_URL()}/t/${team.url}/templates/${template.id}/edit`);
await page.goto(
`${NEXT_PUBLIC_WEBAPP_URL()}/t/${team.url}/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}/edit`,
);
await expect(page.getByRole('heading', { name: 'Oops! Something went wrong.' })).toBeVisible();
});
});