chore: update tests

This commit is contained in:
Mythie
2025-04-21 16:07:19 +10:00
parent 6df8b3aac8
commit cf17fc61bc
18 changed files with 183 additions and 191 deletions
@@ -1,3 +1,5 @@
import { useState } from 'react';
import { zodResolver } from '@hookform/resolvers/zod'; import { zodResolver } from '@hookform/resolvers/zod';
import { Trans } from '@lingui/react/macro'; import { Trans } from '@lingui/react/macro';
import { useForm } from 'react-hook-form'; import { useForm } from 'react-hook-form';
@@ -55,6 +57,8 @@ export function AssistantConfirmationDialog({
allowDictateNextSigner = false, allowDictateNextSigner = false,
defaultNextSigner, defaultNextSigner,
}: ConfirmationDialogProps) { }: ConfirmationDialogProps) {
const [isEditingNextSigner, setIsEditingNextSigner] = useState(false);
const form = useForm<TNextSignerFormSchema>({ const form = useForm<TNextSignerFormSchema>({
resolver: zodResolver(ZNextSignerFormSchema), resolver: zodResolver(ZNextSignerFormSchema),
defaultValues: { defaultValues: {
@@ -107,53 +111,72 @@ export function AssistantConfirmationDialog({
<div className="mt-4 flex flex-col gap-4"> <div className="mt-4 flex flex-col gap-4">
{allowDictateNextSigner && ( {allowDictateNextSigner && (
<div className="my-2"> <div className="mt-4 flex flex-col gap-4">
<p className="text-muted-foreground mb-1 text-sm font-semibold"> {!isEditingNextSigner && (
The next recipient to sign this document will be{' '} <div>
</p> <p className="text-muted-foreground text-sm">
The next recipient to sign this document will be{' '}
<span className="font-semibold">{form.watch('name')}</span> (
<span className="font-semibold">{form.watch('email')}</span>).
</p>
<div className="flex flex-col gap-4 rounded-xl border p-4 md:flex-row"> <Button
<FormField type="button"
control={form.control} className="mt-2"
name="name" variant="outline"
render={({ field }) => ( size="sm"
<FormItem className="flex-1"> onClick={() => setIsEditingNextSigner((prev) => !prev)}
<FormLabel> >
<Trans>Name</Trans> <Trans>Update Recipient</Trans>
</FormLabel> </Button>
<FormControl> </div>
<Input )}
{...field}
className="mt-2"
placeholder="Enter the next signer's name"
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField {isEditingNextSigner && (
control={form.control} <div className="flex flex-col gap-4 md:flex-row">
name="email" <FormField
render={({ field }) => ( control={form.control}
<FormItem className="flex-1"> name="name"
<FormLabel> render={({ field }) => (
<Trans>Email</Trans> <FormItem className="flex-1">
</FormLabel> <FormLabel>
<FormControl> <Trans>Name</Trans>
<Input </FormLabel>
{...field} <FormControl>
type="email" <Input
className="mt-2" {...field}
placeholder="Enter the next signer's email" className="mt-2"
/> placeholder="Enter the next signer's name"
</FormControl> />
<FormMessage /> </FormControl>
</FormItem>
)} <FormMessage />
/> </FormItem>
</div> )}
/>
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem className="flex-1">
<FormLabel>
<Trans>Email</Trans>
</FormLabel>
<FormControl>
<Input
{...field}
type="email"
className="mt-2"
placeholder="Enter the next signer's email"
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
)}
</div> </div>
)} )}
@@ -7,8 +7,6 @@ import { seedUser } from '@documenso/prisma/seed/users';
import { apiSignin } from '../fixtures/authentication'; import { apiSignin } from '../fixtures/authentication';
test.describe.configure({ mode: 'parallel' });
test('[DOCUMENT_AUTH]: should grant access when not required', async ({ page }) => { test('[DOCUMENT_AUTH]: should grant access when not required', async ({ page }) => {
const user = await seedUser(); const user = await seedUser();
@@ -377,8 +377,8 @@ test('[NEXT_RECIPIENT_DICTATION]: should allow assistant to dictate next signer'
// Second recipient should be the new signer // Second recipient should be the new signer
const updatedSigner = updatedDocument.recipients[1]; const updatedSigner = updatedDocument.recipients[1];
expect(updatedSigner.name).toBe('New Signer'); expect(updatedSigner.name).toBe('New Recipient');
expect(updatedSigner.email).toBe('new.signer@example.com'); expect(updatedSigner.email).toBe('new.recipient@example.com');
expect(updatedSigner.signingOrder).toBe(2); expect(updatedSigner.signingOrder).toBe(2);
expect(updatedSigner.signingStatus).toBe(SigningStatus.NOT_SIGNED); expect(updatedSigner.signingStatus).toBe(SigningStatus.NOT_SIGNED);
expect(updatedSigner.role).toBe(RecipientRole.SIGNER); expect(updatedSigner.role).toBe(RecipientRole.SIGNER);
@@ -11,9 +11,8 @@ import { seedUser } from '@documenso/prisma/seed/users';
import { apiSignin } from '../fixtures/authentication'; import { apiSignin } from '../fixtures/authentication';
test.describe.configure({ mode: 'parallel' });
test.describe('[EE_ONLY]', () => { test.describe('[EE_ONLY]', () => {
// eslint-disable-next-line turbo/no-undeclared-env-vars
const enterprisePriceId = process.env.NEXT_PUBLIC_STRIPE_ENTERPRISE_PLAN_MONTHLY_PRICE_ID || ''; const enterprisePriceId = process.env.NEXT_PUBLIC_STRIPE_ENTERPRISE_PLAN_MONTHLY_PRICE_ID || '';
test.beforeEach(() => { test.beforeEach(() => {
@@ -6,9 +6,8 @@ import { seedUser } from '@documenso/prisma/seed/users';
import { apiSignin } from '../fixtures/authentication'; import { apiSignin } from '../fixtures/authentication';
test.describe.configure({ mode: 'parallel' });
test.describe('[EE_ONLY]', () => { test.describe('[EE_ONLY]', () => {
// eslint-disable-next-line turbo/no-undeclared-env-vars
const enterprisePriceId = process.env.NEXT_PUBLIC_STRIPE_ENTERPRISE_PLAN_MONTHLY_PRICE_ID || ''; const enterprisePriceId = process.env.NEXT_PUBLIC_STRIPE_ENTERPRISE_PLAN_MONTHLY_PRICE_ID || '';
test.beforeEach(() => { test.beforeEach(() => {
@@ -7,8 +7,6 @@ import { seedUser } from '@documenso/prisma/seed/users';
import { apiSignin } from '../fixtures/authentication'; import { apiSignin } from '../fixtures/authentication';
test.describe.configure({ mode: 'parallel' });
test('[PUBLIC_PROFILE]: create profile', async ({ page }) => { test('[PUBLIC_PROFILE]: create profile', async ({ page }) => {
const user = await seedUser(); const user = await seedUser();
@@ -6,8 +6,6 @@ import { seedUser } from '@documenso/prisma/seed/users';
import { apiSignin } from '../fixtures/authentication'; import { apiSignin } from '../fixtures/authentication';
test.describe.configure({ mode: 'parallel' });
test('[TEAMS]: create team', async ({ page }) => { test('[TEAMS]: create team', async ({ page }) => {
const user = await seedUser(); const user = await seedUser();
@@ -9,8 +9,6 @@ import { seedUser } from '@documenso/prisma/seed/users';
import { apiSignin, apiSignout } from '../fixtures/authentication'; import { apiSignin, apiSignout } from '../fixtures/authentication';
import { checkDocumentTabCount } from '../fixtures/documents'; import { checkDocumentTabCount } from '../fixtures/documents';
test.describe.configure({ mode: 'parallel' });
test('[TEAMS]: check team documents count', async ({ page }) => { test('[TEAMS]: check team documents count', async ({ page }) => {
const { team, teamMember2 } = await seedTeamDocuments(); const { team, teamMember2 } = await seedTeamDocuments();
@@ -6,8 +6,6 @@ import { seedUser } from '@documenso/prisma/seed/users';
import { apiSignin } from '../fixtures/authentication'; import { apiSignin } from '../fixtures/authentication';
test.describe.configure({ mode: 'parallel' });
test('[TEAMS]: send team email request', async ({ page }) => { test('[TEAMS]: send team email request', async ({ page }) => {
const team = await seedTeam(); const team = await seedTeam();
@@ -4,8 +4,6 @@ import { seedTeam } from '@documenso/prisma/seed/teams';
import { apiSignin } from '../fixtures/authentication'; import { apiSignin } from '../fixtures/authentication';
test.describe.configure({ mode: 'parallel' });
test('[TEAMS]: update the default document visibility in the team global settings', async ({ test('[TEAMS]: update the default document visibility in the team global settings', async ({
page, page,
}) => { }) => {
@@ -6,8 +6,6 @@ import { seedUser } from '@documenso/prisma/seed/users';
import { apiSignin } from '../fixtures/authentication'; import { apiSignin } from '../fixtures/authentication';
test.describe.configure({ mode: 'parallel' });
test('[TEAMS]: update team member role', async ({ page }) => { test('[TEAMS]: update team member role', async ({ page }) => {
const team = await seedTeam({ const team = await seedTeam({
createTeamMembers: 1, createTeamMembers: 1,
@@ -9,8 +9,6 @@ import {
import { apiSignin } from '../fixtures/authentication'; import { apiSignin } from '../fixtures/authentication';
test.describe.configure({ mode: 'parallel' });
test('[TEAMS]: check that default team signature settings are all enabled', async ({ page }) => { test('[TEAMS]: check that default team signature settings are all enabled', async ({ page }) => {
const { team } = await seedTeamDocuments(); const { team } = await seedTeamDocuments();
@@ -149,8 +147,9 @@ test('[TEAMS]: check signature modes work for templates', async ({ page }) => {
await page.getByRole('button', { name: 'Update' }).first().click(); await page.getByRole('button', { name: 'Update' }).first().click();
// Wait for finish // Wait for finish
await page.getByText('Document preferences updated').waitFor({ state: 'visible' }); const toast = page.locator('li[role="status"][data-state="open"]').first();
await page.waitForTimeout(1000); await expect(toast).toBeVisible();
await expect(toast.getByText('Document preferences updated', { exact: true })).toBeVisible();
const template = await seedTeamTemplateWithMeta(team); const template = await seedTeamTemplateWithMeta(team);
@@ -5,8 +5,6 @@ import { seedTeam, seedTeamTransfer } from '@documenso/prisma/seed/teams';
import { apiSignin } from '../fixtures/authentication'; import { apiSignin } from '../fixtures/authentication';
test.describe.configure({ mode: 'parallel' });
test('[TEAMS]: initiate and cancel team transfer', async ({ page }) => { test('[TEAMS]: initiate and cancel team transfer', async ({ page }) => {
const team = await seedTeam({ const team = await seedTeam({
createTeamMembers: 1, createTeamMembers: 1,
@@ -9,8 +9,6 @@ import { seedUser } from '@documenso/prisma/seed/users';
import { apiSignin } from '../fixtures/authentication'; import { apiSignin } from '../fixtures/authentication';
test.describe.configure({ mode: 'parallel' });
test.describe('[EE_ONLY]', () => { test.describe('[EE_ONLY]', () => {
const enterprisePriceId = ''; const enterprisePriceId = '';
@@ -6,9 +6,8 @@ import { seedUser } from '@documenso/prisma/seed/users';
import { apiSignin } from '../fixtures/authentication'; import { apiSignin } from '../fixtures/authentication';
test.describe.configure({ mode: 'parallel' });
test.describe('[EE_ONLY]', () => { test.describe('[EE_ONLY]', () => {
// eslint-disable-next-line turbo/no-undeclared-env-vars
const enterprisePriceId = process.env.NEXT_PUBLIC_STRIPE_ENTERPRISE_PLAN_MONTHLY_PRICE_ID || ''; const enterprisePriceId = process.env.NEXT_PUBLIC_STRIPE_ENTERPRISE_PLAN_MONTHLY_PRICE_ID || '';
test.beforeEach(() => { test.beforeEach(() => {
@@ -1,7 +1,6 @@
import { expect, test } from '@playwright/test'; import { expect, test } from '@playwright/test';
import { DocumentDataType, TeamMemberRole } from '@prisma/client'; import { DocumentDataType, TeamMemberRole } from '@prisma/client';
import fs from 'fs'; import fs from 'fs';
import os from 'os';
import path from 'path'; import path from 'path';
import { extractDocumentAuthMethods } from '@documenso/lib/utils/document-auth'; import { extractDocumentAuthMethods } from '@documenso/lib/utils/document-auth';
@@ -13,23 +12,9 @@ import { seedUser } from '@documenso/prisma/seed/users';
import { apiSignin } from '../fixtures/authentication'; import { apiSignin } from '../fixtures/authentication';
test.describe.configure({ mode: 'parallel' });
const enterprisePriceId = ''; const enterprisePriceId = '';
// Create a temporary PDF file for testing const EXAMPLE_PDF_PATH = path.join(__dirname, '../../../../assets/example.pdf');
function createTempPdfFile() {
const tempDir = os.tmpdir();
const tempFilePath = path.join(tempDir, 'test.pdf');
// Create a simple PDF file with some content
const pdfContent = Buffer.from(
'%PDF-1.4\n1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj 2 0 obj<</Type/Pages/Kids[3 0 R]/Count 1>>endobj 3 0 obj<</Type/Page/MediaBox[0 0 612 792]/Parent 2 0 R>>endobj\nxref\n0 4\n0000000000 65535 f\n0000000009 00000 n\n0000000052 00000 n\n0000000101 00000 n\ntrailer<</Size 4/Root 1 0 R>>\nstartxref\n178\n%%EOF',
);
fs.writeFileSync(tempFilePath, new Uint8Array(pdfContent));
return tempFilePath;
}
/** /**
* 1. Create a template with all settings filled out * 1. Create a template with all settings filled out
@@ -313,67 +298,73 @@ test('[TEMPLATE]: should create a document from a template with custom document'
const template = await seedBlankTemplate(user); const template = await seedBlankTemplate(user);
// Create a temporary PDF file for upload // Create a temporary PDF file for upload
const testPdfPath = createTempPdfFile();
const pdfContent = fs.readFileSync(testPdfPath).toString('base64');
try { const pdfContent = fs.readFileSync(EXAMPLE_PDF_PATH).toString('base64');
await apiSignin({
page,
email: user.email,
redirectPath: `/templates/${template.id}/edit`,
});
// Set template title await apiSignin({
await page.getByLabel('Title').fill('TEMPLATE_WITH_CUSTOM_DOC'); page,
email: user.email,
redirectPath: `/templates/${template.id}/edit`,
});
await page.getByRole('button', { name: 'Continue' }).click(); // Set template title
await expect(page.getByRole('heading', { name: 'Add Placeholder' })).toBeVisible(); await page.getByLabel('Title').fill('TEMPLATE_WITH_CUSTOM_DOC');
// Add a signer await page.getByRole('button', { name: 'Continue' }).click();
await page.getByPlaceholder('Email').fill('recipient@documenso.com'); await expect(page.getByRole('heading', { name: 'Add Placeholder' })).toBeVisible();
await page.getByPlaceholder('Name').fill('Recipient');
await page.getByRole('button', { name: 'Continue' }).click(); // Add a signer
await expect(page.getByRole('heading', { name: 'Add Fields' })).toBeVisible(); await page.getByPlaceholder('Email').fill('recipient@documenso.com');
await page.getByPlaceholder('Name').fill('Recipient');
await page.getByRole('button', { name: 'Save template' }).click(); await page.getByRole('button', { name: 'Continue' }).click();
await expect(page.getByRole('heading', { name: 'Add Fields' })).toBeVisible();
// Use template with custom document await page.getByRole('button', { name: 'Save template' }).click();
await page.waitForURL('/templates');
await page.getByRole('button', { name: 'Use Template' }).click();
// Enable custom document upload and upload file // Use template with custom document
await page.getByLabel('Upload custom document').check(); await page.waitForURL('/templates');
await page.locator('input[type="file"]').setInputFiles(testPdfPath); await page.getByRole('button', { name: 'Use Template' }).click();
// Wait for upload to complete // Enable custom document upload and upload file
await expect(page.getByText(path.basename(testPdfPath))).toBeVisible(); await page.getByLabel('Upload custom document').check();
// Create document with custom document data // Upload document.
await page.getByRole('button', { name: 'Create as draft' }).click(); const [fileChooser] = await Promise.all([
page.waitForEvent('filechooser'),
page.locator('input[type=file]').evaluate((e) => {
if (e instanceof HTMLInputElement) {
e.click();
}
}),
]);
// Review that the document was created with the custom document data await fileChooser.setFiles(EXAMPLE_PDF_PATH);
await page.waitForURL(/documents/);
const documentId = Number(page.url().split('/').pop()); // Wait for upload to complete
await expect(page.getByText(path.basename(EXAMPLE_PDF_PATH))).toBeVisible();
const document = await prisma.document.findFirstOrThrow({ // Create document with custom document data
where: { await page.getByRole('button', { name: 'Create as draft' }).click();
id: documentId,
},
include: {
documentData: true,
},
});
expect(document.title).toEqual('TEMPLATE_WITH_CUSTOM_DOC'); // Review that the document was created with the custom document data
expect(document.documentData.type).toEqual(DocumentDataType.BYTES_64); await page.waitForURL(/documents/);
expect(document.documentData.data).toEqual(pdfContent);
expect(document.documentData.initialData).toEqual(pdfContent); const documentId = Number(page.url().split('/').pop());
} finally {
// Clean up the temporary file const document = await prisma.document.findFirstOrThrow({
fs.unlinkSync(testPdfPath); where: {
} id: documentId,
},
include: {
documentData: true,
},
});
expect(document.title).toEqual('TEMPLATE_WITH_CUSTOM_DOC');
expect(document.documentData.type).toEqual(DocumentDataType.BYTES_64);
expect(document.documentData.data).toEqual(pdfContent);
expect(document.documentData.initialData).toEqual(pdfContent);
}); });
/** /**
@@ -393,69 +384,73 @@ test('[TEMPLATE]: should create a team document from a template with custom docu
}, },
}); });
// Create a temporary PDF file for upload const pdfContent = fs.readFileSync(EXAMPLE_PDF_PATH).toString('base64');
const testPdfPath = createTempPdfFile();
const pdfContent = fs.readFileSync(testPdfPath).toString('base64');
try { await apiSignin({
await apiSignin({ page,
page, email: owner.email,
email: owner.email, redirectPath: `/t/${team.url}/templates/${template.id}/edit`,
redirectPath: `/t/${team.url}/templates/${template.id}/edit`, });
});
// Set template title // Set template title
await page.getByLabel('Title').fill('TEAM_TEMPLATE_WITH_CUSTOM_DOC'); await page.getByLabel('Title').fill('TEAM_TEMPLATE_WITH_CUSTOM_DOC');
await page.getByRole('button', { name: 'Continue' }).click(); await page.getByRole('button', { name: 'Continue' }).click();
await expect(page.getByRole('heading', { name: 'Add Placeholder' })).toBeVisible(); await expect(page.getByRole('heading', { name: 'Add Placeholder' })).toBeVisible();
// Add a signer // Add a signer
await page.getByPlaceholder('Email').fill('recipient@documenso.com'); await page.getByPlaceholder('Email').fill('recipient@documenso.com');
await page.getByPlaceholder('Name').fill('Recipient'); await page.getByPlaceholder('Name').fill('Recipient');
await page.getByRole('button', { name: 'Continue' }).click(); await page.getByRole('button', { name: 'Continue' }).click();
await expect(page.getByRole('heading', { name: 'Add Fields' })).toBeVisible(); await expect(page.getByRole('heading', { name: 'Add Fields' })).toBeVisible();
await page.getByRole('button', { name: 'Save template' }).click(); await page.getByRole('button', { name: 'Save template' }).click();
// Use template with custom document // Use template with custom document
await page.waitForURL(`/t/${team.url}/templates`); await page.waitForURL(`/t/${team.url}/templates`);
await page.getByRole('button', { name: 'Use Template' }).click(); await page.getByRole('button', { name: 'Use Template' }).click();
// Enable custom document upload and upload file // Enable custom document upload and upload file
await page.getByLabel('Upload custom document').check(); await page.getByLabel('Upload custom document').check();
await page.locator('input[type="file"]').setInputFiles(testPdfPath);
// Wait for upload to complete // Upload document.
await expect(page.getByText(path.basename(testPdfPath))).toBeVisible(); const [fileChooser] = await Promise.all([
page.waitForEvent('filechooser'),
page.locator('input[type=file]').evaluate((e) => {
if (e instanceof HTMLInputElement) {
e.click();
}
}),
]);
// Create document with custom document data await fileChooser.setFiles(EXAMPLE_PDF_PATH);
await page.getByRole('button', { name: 'Create as draft' }).click();
// Review that the document was created with the custom document data // Wait for upload to complete
await page.waitForURL(/documents/); await expect(page.getByText(path.basename(EXAMPLE_PDF_PATH))).toBeVisible();
const documentId = Number(page.url().split('/').pop()); // Create document with custom document data
await page.getByRole('button', { name: 'Create as draft' }).click();
const document = await prisma.document.findFirstOrThrow({ // Review that the document was created with the custom document data
where: { await page.waitForURL(/documents/);
id: documentId,
},
include: {
documentData: true,
},
});
expect(document.teamId).toEqual(team.id); const documentId = Number(page.url().split('/').pop());
expect(document.title).toEqual('TEAM_TEMPLATE_WITH_CUSTOM_DOC');
expect(document.documentData.type).toEqual(DocumentDataType.BYTES_64); const document = await prisma.document.findFirstOrThrow({
expect(document.documentData.data).toEqual(pdfContent); where: {
expect(document.documentData.initialData).toEqual(pdfContent); id: documentId,
} finally { },
// Clean up the temporary file include: {
fs.unlinkSync(testPdfPath); documentData: true,
} },
});
expect(document.teamId).toEqual(team.id);
expect(document.title).toEqual('TEAM_TEMPLATE_WITH_CUSTOM_DOC');
expect(document.documentData.type).toEqual(DocumentDataType.BYTES_64);
expect(document.documentData.data).toEqual(pdfContent);
expect(document.documentData.initialData).toEqual(pdfContent);
}); });
/** /**
@@ -23,8 +23,6 @@ const formatTemplatesPath = (teamUrl?: string) =>
const nanoid = customAlphabet('1234567890abcdef', 10); const nanoid = customAlphabet('1234567890abcdef', 10);
test.describe.configure({ mode: 'parallel' });
test('[DIRECT_TEMPLATES]: create direct link for template', async ({ page }) => { test('[DIRECT_TEMPLATES]: create direct link for template', async ({ page }) => {
const team = await seedTeam({ const team = await seedTeam({
createTeamMembers: 1, createTeamMembers: 1,
@@ -6,8 +6,6 @@ import { seedTemplate } from '@documenso/prisma/seed/templates';
import { apiSignin } from '../fixtures/authentication'; import { apiSignin } from '../fixtures/authentication';
test.describe.configure({ mode: 'parallel' });
test('[TEMPLATES]: view templates', async ({ page }) => { test('[TEMPLATES]: view templates', async ({ page }) => {
const team = await seedTeam({ const team = await seedTeam({
createTeamMembers: 1, createTeamMembers: 1,