mirror of
https://github.com/documenso/documenso.git
synced 2026-10-04 02:33:54 +10:00
chore: remove issue 2766 test changes
This commit is contained in:
@@ -1,85 +0,0 @@
|
||||
import { nanoid } from '@documenso/lib/universal/id';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { expect, test } from '@playwright/test';
|
||||
|
||||
import {
|
||||
addEnvelopeItemPdf,
|
||||
getEnvelopeEditorSettingsTrigger,
|
||||
openDocumentEnvelopeEditor,
|
||||
openEmbeddedEnvelopeEditor,
|
||||
openTemplateEnvelopeEditor,
|
||||
persistEmbeddedEnvelope,
|
||||
setRecipientEmail,
|
||||
type TEnvelopeEditorSurface,
|
||||
} from '../fixtures/envelope-editor';
|
||||
import { expectToastTextToBeVisible } from '../fixtures/generic';
|
||||
|
||||
const runAttachmentSettingsFlow = async (surface: TEnvelopeEditorSurface) => {
|
||||
const { root, isEmbedded } = surface;
|
||||
const externalId = `e2e-email-attachments-${nanoid()}`;
|
||||
|
||||
if (isEmbedded && !surface.envelopeId) {
|
||||
await addEnvelopeItemPdf(root);
|
||||
await setRecipientEmail(root, 0, 'signer@example.com');
|
||||
}
|
||||
|
||||
for (const attachDocument of [false, true, false]) {
|
||||
await getEnvelopeEditorSettingsTrigger(root).click();
|
||||
await root.locator('input[name="externalId"]').fill(externalId);
|
||||
await root.getByRole('button', { name: 'Notifications' }).click();
|
||||
const attachmentControl = root.getByRole('checkbox', { name: 'Attach completed document PDFs to emails' });
|
||||
await expect(attachmentControl).toBeChecked({ checked: !attachDocument });
|
||||
await attachmentControl.setChecked(attachDocument);
|
||||
await expect(root.locator('#documentCompleted')).toBeChecked();
|
||||
await expect(root.locator('#ownerDocumentCompleted')).toBeChecked();
|
||||
await root.getByRole('button', { name: 'Update', exact: true }).click();
|
||||
|
||||
if (!isEmbedded) {
|
||||
await expectToastTextToBeVisible(root, 'Envelope updated');
|
||||
const meta = await prisma.envelope.findUniqueOrThrow({
|
||||
where: { id: surface.envelopeId },
|
||||
include: { documentMeta: true },
|
||||
});
|
||||
expect(meta.documentMeta.emailSettings).toMatchObject({ attachDocument });
|
||||
await root.reload();
|
||||
}
|
||||
}
|
||||
|
||||
if (isEmbedded) {
|
||||
await persistEmbeddedEnvelope(surface);
|
||||
}
|
||||
|
||||
const envelope = await prisma.envelope.findFirstOrThrow({
|
||||
where: { externalId, userId: surface.userId, teamId: surface.teamId, type: surface.envelopeType },
|
||||
include: { documentMeta: true },
|
||||
});
|
||||
expect(envelope.documentMeta.emailSettings).toMatchObject({
|
||||
attachDocument: false,
|
||||
documentCompleted: true,
|
||||
ownerDocumentCompleted: true,
|
||||
});
|
||||
};
|
||||
|
||||
test.describe('document editor', () => {
|
||||
test('save email attachment opt-out and toggle back', async ({ page }) => {
|
||||
await runAttachmentSettingsFlow(await openDocumentEnvelopeEditor(page));
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('template editor', () => {
|
||||
test('save email attachment opt-out and toggle back', async ({ page }) => {
|
||||
await runAttachmentSettingsFlow(await openTemplateEnvelopeEditor(page));
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('embedded create', () => {
|
||||
test('save email attachment opt-out and toggle back', async ({ page }) => {
|
||||
await runAttachmentSettingsFlow(await openEmbeddedEnvelopeEditor(page, { envelopeType: 'DOCUMENT' }));
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('embedded edit', () => {
|
||||
test('save email attachment opt-out and toggle back', async ({ page }) => {
|
||||
await runAttachmentSettingsFlow(await openEmbeddedEnvelopeEditor(page, { envelopeType: 'TEMPLATE', mode: 'edit' }));
|
||||
});
|
||||
});
|
||||
@@ -215,8 +215,6 @@ test('[ORGANISATIONS]: manage email preferences', async ({ page }) => {
|
||||
await page.getByRole('textbox', { name: 'Reply to email' }).click();
|
||||
await page.getByRole('textbox', { name: 'Reply to email' }).fill('organisation@documenso.com');
|
||||
|
||||
await page.getByRole('checkbox', { name: 'Attach completed document PDFs to emails' }).uncheck();
|
||||
|
||||
// Update email document settings by enabling/disabling some checkboxes
|
||||
await page.getByRole('checkbox', { name: 'Email the owner when a recipient signs' }).uncheck();
|
||||
await page.getByRole('checkbox', { name: 'Email the signer if the document is still pending' }).uncheck();
|
||||
@@ -232,7 +230,6 @@ test('[ORGANISATIONS]: manage email preferences', async ({ page }) => {
|
||||
// Check that the team settings have inherited these values.
|
||||
expect(teamSettings.emailReplyTo).toEqual('organisation@documenso.com');
|
||||
expect(teamSettings.emailDocumentSettings).toEqual({
|
||||
attachDocument: false,
|
||||
recipientSigningRequest: true,
|
||||
recipientRemoved: true,
|
||||
recipientSigned: false, // unchecked
|
||||
@@ -276,7 +273,6 @@ test('[ORGANISATIONS]: manage email preferences', async ({ page }) => {
|
||||
// Check that the team settings have overridden the organisation values.
|
||||
expect(updatedTeamSettings.emailReplyTo).toEqual('team@example.com');
|
||||
expect(updatedTeamSettings.emailDocumentSettings).toEqual({
|
||||
attachDocument: true,
|
||||
recipientSigned: true,
|
||||
recipientSigningRequest: false,
|
||||
recipientRemoved: true,
|
||||
@@ -299,7 +295,6 @@ test('[ORGANISATIONS]: manage email preferences', async ({ page }) => {
|
||||
|
||||
expect(teamOverrideDocumentMeta.emailReplyTo).toEqual('team@example.com');
|
||||
expect(teamOverrideDocumentMeta.emailSettings).toEqual({
|
||||
attachDocument: true,
|
||||
recipientSigned: true,
|
||||
recipientSigningRequest: false,
|
||||
recipientRemoved: true,
|
||||
@@ -327,7 +322,6 @@ test('[ORGANISATIONS]: manage email preferences', async ({ page }) => {
|
||||
// Check that the team settings now inherit from organisation again.
|
||||
expect(inheritedTeamSettings.emailReplyTo).toEqual('organisation@documenso.com');
|
||||
expect(inheritedTeamSettings.emailDocumentSettings).toEqual({
|
||||
attachDocument: false,
|
||||
recipientSigningRequest: true,
|
||||
recipientRemoved: true,
|
||||
recipientSigned: false,
|
||||
@@ -350,7 +344,6 @@ test('[ORGANISATIONS]: manage email preferences', async ({ page }) => {
|
||||
|
||||
expect(documentMeta.emailReplyTo).toEqual('organisation@documenso.com');
|
||||
expect(documentMeta.emailSettings).toEqual({
|
||||
attachDocument: false,
|
||||
recipientSigningRequest: true,
|
||||
recipientRemoved: true,
|
||||
recipientSigned: false,
|
||||
@@ -361,22 +354,4 @@ test('[ORGANISATIONS]: manage email preferences', async ({ page }) => {
|
||||
ownerDocumentCompleted: true,
|
||||
ownerDocumentCreated: true,
|
||||
});
|
||||
|
||||
// Re-enable attachments and verify that inherited defaults change only for new documents.
|
||||
await page.goto(`/o/${organisation.url}/settings/email`);
|
||||
const attachmentControl = page.getByRole('checkbox', { name: 'Attach completed document PDFs to emails' });
|
||||
await expect(attachmentControl).not.toBeChecked();
|
||||
await attachmentControl.check();
|
||||
await page.getByRole('button', { name: 'Save changes' }).first().click();
|
||||
await expect(page.getByText('Your email preferences have been updated').first()).toBeVisible();
|
||||
await page.reload();
|
||||
await expect(attachmentControl).toBeChecked();
|
||||
|
||||
const restoredSettings = await getTeamSettings({ teamId: team.id });
|
||||
expect(restoredSettings.emailDocumentSettings.attachDocument).toBe(true);
|
||||
const newDocument = await seedTeamDocumentWithMeta(team);
|
||||
const newMeta = await prisma.documentMeta.findUniqueOrThrow({ where: { id: newDocument.documentMetaId } });
|
||||
expect(newMeta.emailSettings?.attachDocument).toBe(true);
|
||||
const existingMeta = await prisma.documentMeta.findUniqueOrThrow({ where: { id: document.documentMetaId } });
|
||||
expect(existingMeta.emailSettings?.attachDocument).toBe(false);
|
||||
});
|
||||
|
||||
@@ -1,190 +0,0 @@
|
||||
import { DocumentDistributionMethod, DocumentSource, RecipientRole } from '@prisma/client';
|
||||
import type { ReactElement } from 'react';
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { DEFAULT_DOCUMENT_EMAIL_SETTINGS } from '../../../types/document-email';
|
||||
import type { JobRunIO } from '../../client/_internal/job';
|
||||
import { run } from './send-document-completed-emails.handler';
|
||||
|
||||
const mocks = vi.hoisted(() => ({
|
||||
findEnvelope: vi.fn(),
|
||||
createAuditLog: vi.fn(),
|
||||
findEnvelopeItems: vi.fn(),
|
||||
getEmailContext: vi.fn(),
|
||||
getFile: vi.fn(),
|
||||
sendMail: vi.fn(),
|
||||
checkLimits: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('@documenso/prisma', () => ({
|
||||
prisma: {
|
||||
envelope: { findUnique: mocks.findEnvelope },
|
||||
envelopeItem: { findMany: mocks.findEnvelopeItems },
|
||||
documentAuditLog: { create: mocks.createAuditLog },
|
||||
},
|
||||
}));
|
||||
vi.mock('@documenso/email/templates/document-completed', () => ({
|
||||
DocumentCompletedEmailTemplate: () => null,
|
||||
}));
|
||||
vi.mock('../../../client-only/providers/i18n-server', () => ({
|
||||
getI18nInstance: async () => ({ _: () => 'Signing Complete!' }),
|
||||
}));
|
||||
vi.mock('../../../constants/app', () => ({ NEXT_PUBLIC_WEBAPP_URL: () => 'http://localhost:3000' }));
|
||||
vi.mock('../../../server-only/email/get-email-context', () => ({ getEmailContext: mocks.getEmailContext }));
|
||||
vi.mock('../../../server-only/rate-limit/assert-organisation-rates-and-limits', () => ({
|
||||
assertOrganisationRatesAndLimits: mocks.checkLimits,
|
||||
}));
|
||||
vi.mock('../../../universal/upload/get-file.server', () => ({ getFileServerSide: mocks.getFile }));
|
||||
vi.mock('../../../utils/document-audit-logs', () => ({ createDocumentAuditLogData: (data: unknown) => data }));
|
||||
vi.mock('../../../utils/teams', () => ({ formatDocumentsPath: () => '/t/test-team/documents' }));
|
||||
vi.mock('../../../utils/render-email-with-i18n', () => ({
|
||||
renderEmailWithI18N: async (template: ReactElement<{ downloadLink: string }>) => template.props.downloadLink,
|
||||
}));
|
||||
|
||||
const createEnvelope = (distributionMethod: DocumentDistributionMethod = DocumentDistributionMethod.EMAIL) => ({
|
||||
id: 'envelope_test',
|
||||
secondaryId: 'document_1',
|
||||
teamId: 1,
|
||||
internalVersion: 2,
|
||||
title: 'Confidential document',
|
||||
source: DocumentSource.DOCUMENT,
|
||||
team: { id: 1, url: 'test-team' },
|
||||
user: { id: 1, name: 'Owner', email: 'owner@example.com', disabled: false },
|
||||
documentMeta: {
|
||||
distributionMethod,
|
||||
emailSettings: { ...DEFAULT_DOCUMENT_EMAIL_SETTINGS },
|
||||
},
|
||||
envelopeItems: [
|
||||
{ title: 'First document', documentData: { id: 'file_1', type: 'S3', data: 'file_1' } },
|
||||
{ title: 'Second document', documentData: { id: 'file_2', type: 'BYTES', data: 'file_2' } },
|
||||
],
|
||||
recipients: [
|
||||
{ id: 2, name: 'Signer', email: 'signer@example.com', role: RecipientRole.SIGNER, token: 'signer-token' },
|
||||
{ id: 3, name: 'CC', email: 'cc@example.com', role: RecipientRole.CC, token: 'cc-token' },
|
||||
],
|
||||
});
|
||||
|
||||
let envelope = createEnvelope();
|
||||
const io = { logger: { warn: vi.fn() } } as unknown as JobRunIO;
|
||||
const runJob = () => run({ payload: { envelopeId: envelope.id }, io });
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
envelope = createEnvelope();
|
||||
mocks.findEnvelope.mockImplementation(async () => envelope);
|
||||
mocks.findEnvelopeItems.mockImplementation(async () => envelope.envelopeItems);
|
||||
mocks.getFile.mockResolvedValue(new Uint8Array([1, 2, 3]));
|
||||
mocks.getEmailContext.mockResolvedValue({
|
||||
branding: {},
|
||||
emailLanguage: 'en',
|
||||
senderEmail: 'sender@example.com',
|
||||
replyToEmail: 'reply@example.com',
|
||||
organisationId: 'org_test',
|
||||
claims: {},
|
||||
emailsDisabled: false,
|
||||
emailTransport: { sendMail: mocks.sendMail },
|
||||
});
|
||||
});
|
||||
|
||||
describe('completion email document attachments', () => {
|
||||
it('keeps email content, links, audit logs, and CC metering when PDFs are disabled', async () => {
|
||||
envelope.documentMeta.emailSettings.attachDocument = false;
|
||||
// Loading a PDF would fail: link-only email must still succeed.
|
||||
mocks.getFile.mockRejectedValue(new Error('PDF storage unavailable'));
|
||||
|
||||
await runJob();
|
||||
|
||||
expect(mocks.findEnvelopeItems).not.toHaveBeenCalled();
|
||||
expect(mocks.getFile).not.toHaveBeenCalled();
|
||||
expect(mocks.sendMail).toHaveBeenCalledTimes(3);
|
||||
const emails = mocks.sendMail.mock.calls.map(([email]) => email);
|
||||
expect(emails.map((email) => email.to[0].address)).toEqual([
|
||||
'owner@example.com',
|
||||
'signer@example.com',
|
||||
'cc@example.com',
|
||||
]);
|
||||
for (const email of emails) {
|
||||
expect(email).toMatchObject({ attachments: [], subject: 'Signing Complete!' });
|
||||
expect(email.html).toBe(email.text);
|
||||
}
|
||||
expect(emails[0].html).toBe('http://localhost:3000/t/test-team/documents/envelope_test');
|
||||
expect(emails[1].html).toBe('http://localhost:3000/sign/signer-token/complete');
|
||||
expect(emails[2].html).toBe('http://localhost:3000/sign/cc-token/complete');
|
||||
expect(mocks.createAuditLog).toHaveBeenCalledTimes(3);
|
||||
expect(mocks.checkLimits).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it.each([true, undefined])('attaches all PDFs by default and when enabled (%s)', async (attachDocument) => {
|
||||
mocks.findEnvelope.mockResolvedValue({
|
||||
...envelope,
|
||||
documentMeta: { ...envelope.documentMeta, emailSettings: { attachDocument } },
|
||||
});
|
||||
|
||||
await runJob();
|
||||
|
||||
expect(mocks.getFile).toHaveBeenCalledTimes(2);
|
||||
expect(mocks.sendMail).toHaveBeenCalledTimes(3);
|
||||
for (const [email] of mocks.sendMail.mock.calls) {
|
||||
expect(email.attachments).toEqual([
|
||||
{ filename: 'First document.pdf', content: Buffer.from([1, 2, 3]), contentType: 'application/pdf' },
|
||||
{ filename: 'Second document.pdf', content: Buffer.from([1, 2, 3]), contentType: 'application/pdf' },
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
it('retains legacy single-document filenames', async () => {
|
||||
envelope.internalVersion = 1;
|
||||
envelope.envelopeItems = [envelope.envelopeItems[0]];
|
||||
await runJob();
|
||||
expect(mocks.sendMail.mock.calls[0][0].attachments[0].filename).toBe('Confidential document.pdf');
|
||||
});
|
||||
|
||||
it('sends link-only owner emails when recipient emails are disabled', async () => {
|
||||
envelope.documentMeta.emailSettings.attachDocument = false;
|
||||
envelope.documentMeta.emailSettings.documentCompleted = false;
|
||||
await runJob();
|
||||
expect(mocks.findEnvelopeItems).not.toHaveBeenCalled();
|
||||
expect(mocks.getFile).not.toHaveBeenCalled();
|
||||
expect(mocks.sendMail).toHaveBeenCalledOnce();
|
||||
expect(mocks.sendMail.mock.calls[0][0].to[0].address).toBe('owner@example.com');
|
||||
});
|
||||
|
||||
it('sends link-only recipient emails when owner emails are disabled', async () => {
|
||||
envelope.documentMeta.emailSettings.attachDocument = false;
|
||||
envelope.documentMeta.emailSettings.ownerDocumentCompleted = false;
|
||||
await runJob();
|
||||
expect(mocks.findEnvelopeItems).not.toHaveBeenCalled();
|
||||
expect(mocks.getFile).not.toHaveBeenCalled();
|
||||
expect(mocks.sendMail).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it('sends a single link-only completion email when the owner is also a recipient', async () => {
|
||||
envelope.documentMeta.emailSettings.attachDocument = false;
|
||||
envelope.recipients[0].email = envelope.user.email;
|
||||
await runJob();
|
||||
expect(mocks.sendMail).toHaveBeenCalledTimes(2);
|
||||
expect(mocks.sendMail.mock.calls[0][0]).toMatchObject({
|
||||
to: [{ address: 'owner@example.com' }],
|
||||
attachments: [],
|
||||
html: 'http://localhost:3000/t/test-team/documents/envelope_test',
|
||||
});
|
||||
});
|
||||
|
||||
it('preserves owner-only link emails when distribution is NONE', async () => {
|
||||
envelope.documentMeta.distributionMethod = DocumentDistributionMethod.NONE;
|
||||
envelope.documentMeta.emailSettings.attachDocument = false;
|
||||
await runJob();
|
||||
expect(mocks.findEnvelopeItems).not.toHaveBeenCalled();
|
||||
expect(mocks.getFile).not.toHaveBeenCalled();
|
||||
expect(mocks.sendMail).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it('does not load PDFs or send mail when both completion emails are disabled', async () => {
|
||||
envelope.documentMeta.emailSettings.documentCompleted = false;
|
||||
envelope.documentMeta.emailSettings.ownerDocumentCompleted = false;
|
||||
await runJob();
|
||||
expect(mocks.findEnvelopeItems).not.toHaveBeenCalled();
|
||||
expect(mocks.getFile).not.toHaveBeenCalled();
|
||||
expect(mocks.sendMail).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -1,101 +0,0 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { ZCreateDocumentMutationSchema, ZGenerateDocumentFromTemplateMutationSchema } from '../../api/v1/schema';
|
||||
import { ZCreateDocumentPayloadSchema } from '../../trpc/server/document-router/create-document.types';
|
||||
import { ZCreateEnvelopePayloadSchema } from '../../trpc/server/envelope-router/create-envelope.types';
|
||||
import { ZUpdateEnvelopeRequestSchema } from '../../trpc/server/envelope-router/update-envelope.types';
|
||||
import { ZUseEnvelopePayloadSchema } from '../../trpc/server/envelope-router/use-envelope.types';
|
||||
import { ZUpdateOrganisationSettingsRequestSchema } from '../../trpc/server/organisation-router/update-organisation-settings.types';
|
||||
import { ZUpdateTeamSettingsRequestSchema } from '../../trpc/server/team-router/update-team-settings.types';
|
||||
import {
|
||||
ZCreateDocumentFromTemplateRequestSchema,
|
||||
ZCreateTemplateV2RequestSchema,
|
||||
} from '../../trpc/server/template-router/schema';
|
||||
|
||||
const requestCases = [
|
||||
{
|
||||
name: 'v1 document creation',
|
||||
schema: ZCreateDocumentMutationSchema,
|
||||
body: { title: 'Document', recipients: [] },
|
||||
field: 'meta',
|
||||
},
|
||||
{
|
||||
name: 'v1 template use',
|
||||
schema: ZGenerateDocumentFromTemplateMutationSchema,
|
||||
body: { recipients: [] },
|
||||
field: 'meta',
|
||||
},
|
||||
{ name: 'document creation', schema: ZCreateDocumentPayloadSchema, body: { title: 'Document' }, field: 'meta' },
|
||||
{
|
||||
name: 'envelope creation',
|
||||
schema: ZCreateEnvelopePayloadSchema,
|
||||
body: { title: 'Document', type: 'DOCUMENT' },
|
||||
field: 'meta',
|
||||
},
|
||||
{
|
||||
name: 'envelope update',
|
||||
schema: ZUpdateEnvelopeRequestSchema,
|
||||
body: { envelopeId: 'envelope_test' },
|
||||
field: 'meta',
|
||||
},
|
||||
{
|
||||
name: 'envelope template use',
|
||||
schema: ZUseEnvelopePayloadSchema,
|
||||
body: { envelopeId: 'envelope_test' },
|
||||
field: 'override',
|
||||
},
|
||||
{ name: 'template creation', schema: ZCreateTemplateV2RequestSchema, body: { title: 'Template' }, field: 'meta' },
|
||||
{
|
||||
name: 'document from template',
|
||||
schema: ZCreateDocumentFromTemplateRequestSchema,
|
||||
body: { templateId: 1, recipients: [] },
|
||||
field: 'override',
|
||||
},
|
||||
] as const;
|
||||
|
||||
describe.each(requestCases)('$name email settings API', ({ schema, body, field }) => {
|
||||
it.each([true, false])('accepts and retains attachDocument=%s', (attachDocument) => {
|
||||
const request = { ...body, [field]: { emailSettings: { attachDocument } } };
|
||||
const result = schema.parse(request);
|
||||
expect(result).toMatchObject({ [field]: { emailSettings: { attachDocument } } });
|
||||
});
|
||||
|
||||
it('rejects non-boolean attachment controls instead of enabling attachments', () => {
|
||||
const request = { ...body, [field]: { emailSettings: { attachDocument: 'false' } } };
|
||||
expect(schema.safeParse(request).success).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('default email settings API', () => {
|
||||
it.each([true, false])('retains organisation and team attachment defaults (%s)', (attachDocument) => {
|
||||
expect(
|
||||
ZUpdateOrganisationSettingsRequestSchema.parse({
|
||||
organisationId: 'org_test',
|
||||
data: { emailDocumentSettings: { attachDocument } },
|
||||
}),
|
||||
).toMatchObject({ data: { emailDocumentSettings: { attachDocument } } });
|
||||
expect(
|
||||
ZUpdateTeamSettingsRequestSchema.parse({ teamId: 1, data: { emailDocumentSettings: { attachDocument } } }),
|
||||
).toMatchObject({ data: { emailDocumentSettings: { attachDocument } } });
|
||||
});
|
||||
|
||||
it('rejects malformed organisation and team defaults', () => {
|
||||
expect(
|
||||
ZUpdateOrganisationSettingsRequestSchema.safeParse({
|
||||
organisationId: 'org_test',
|
||||
data: { emailDocumentSettings: { attachDocument: 'false' } },
|
||||
}).success,
|
||||
).toBe(false);
|
||||
expect(
|
||||
ZUpdateTeamSettingsRequestSchema.safeParse({
|
||||
teamId: 1,
|
||||
data: { emailDocumentSettings: { attachDocument: 'false' } },
|
||||
}).success,
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it('retains null as the team inheritance control', () => {
|
||||
expect(ZUpdateTeamSettingsRequestSchema.parse({ teamId: 1, data: { emailDocumentSettings: null } })).toMatchObject({
|
||||
data: { emailDocumentSettings: null },
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,94 +0,0 @@
|
||||
import { DocumentDistributionMethod, type DocumentMeta } from '@prisma/client';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { extractDerivedDocumentMeta } from '../utils/document';
|
||||
import { generateDefaultOrganisationSettings } from '../utils/organisations';
|
||||
import { extractDerivedTeamSettings, generateDefaultTeamSettings } from '../utils/teams';
|
||||
import {
|
||||
DEFAULT_DOCUMENT_EMAIL_SETTINGS,
|
||||
extractDerivedDocumentEmailSettings,
|
||||
ZDocumentEmailSettingsInputSchema,
|
||||
ZDocumentEmailSettingsSchema,
|
||||
} from './document-email';
|
||||
import { ZDocumentMetaCreateSchema, ZDocumentMetaUpdateSchema } from './document-meta';
|
||||
|
||||
describe('document email attachments', () => {
|
||||
it('keeps attachments enabled for absent and legacy settings', () => {
|
||||
expect(extractDerivedDocumentEmailSettings().attachDocument).toBe(true);
|
||||
expect(ZDocumentEmailSettingsSchema.parse(null).attachDocument).toBe(true);
|
||||
expect(ZDocumentEmailSettingsInputSchema.parse({ documentCompleted: false })).toMatchObject({
|
||||
attachDocument: true,
|
||||
documentCompleted: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('disables attachments independently of notification events', () => {
|
||||
expect(ZDocumentEmailSettingsInputSchema.parse({ attachDocument: false })).toEqual({
|
||||
...DEFAULT_DOCUMENT_EMAIL_SETTINGS,
|
||||
attachDocument: false,
|
||||
});
|
||||
});
|
||||
|
||||
it.each(['false', 0, null, [], {}])('rejects invalid attachment values: %j', (attachDocument) => {
|
||||
expect(ZDocumentEmailSettingsInputSchema.safeParse({ attachDocument }).success).toBe(false);
|
||||
expect(ZDocumentMetaCreateSchema.safeParse({ emailSettings: { attachDocument } }).success).toBe(false);
|
||||
expect(ZDocumentMetaUpdateSchema.safeParse({ emailSettings: { attachDocument } }).success).toBe(false);
|
||||
});
|
||||
|
||||
it('does not replace an explicit opt-out with defaults when another input is invalid', () => {
|
||||
expect(
|
||||
ZDocumentMetaCreateSchema.safeParse({
|
||||
emailSettings: { attachDocument: false, documentCompleted: 'true' },
|
||||
}).success,
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it('preserves the owner attachment setting when email distribution is disabled', () => {
|
||||
const settings = extractDerivedDocumentEmailSettings({
|
||||
distributionMethod: DocumentDistributionMethod.NONE,
|
||||
emailSettings: { ...DEFAULT_DOCUMENT_EMAIL_SETTINGS, attachDocument: false },
|
||||
} as DocumentMeta);
|
||||
|
||||
expect(settings).toMatchObject({
|
||||
attachDocument: false,
|
||||
documentCompleted: false,
|
||||
ownerDocumentCompleted: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('inherits organisation defaults, allows team overrides, and restores inheritance', () => {
|
||||
const organisationSettings = generateDefaultOrganisationSettings();
|
||||
organisationSettings.emailDocumentSettings = { ...DEFAULT_DOCUMENT_EMAIL_SETTINGS, attachDocument: false };
|
||||
const teamSettings = generateDefaultTeamSettings();
|
||||
|
||||
const inherited = extractDerivedTeamSettings(organisationSettings, teamSettings);
|
||||
expect(extractDerivedDocumentMeta(inherited, undefined).emailSettings.attachDocument).toBe(false);
|
||||
|
||||
teamSettings.emailDocumentSettings = { ...DEFAULT_DOCUMENT_EMAIL_SETTINGS, attachDocument: true };
|
||||
const overridden = extractDerivedTeamSettings(organisationSettings, teamSettings);
|
||||
expect(extractDerivedDocumentMeta(overridden, undefined).emailSettings.attachDocument).toBe(true);
|
||||
|
||||
teamSettings.emailDocumentSettings = null;
|
||||
expect(
|
||||
extractDerivedDocumentMeta(extractDerivedTeamSettings(organisationSettings, teamSettings), undefined)
|
||||
.emailSettings.attachDocument,
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it('allows a document or template to override inherited attachment defaults in either direction', () => {
|
||||
const settings = generateDefaultOrganisationSettings();
|
||||
|
||||
expect(
|
||||
extractDerivedDocumentMeta(settings, {
|
||||
emailSettings: { ...DEFAULT_DOCUMENT_EMAIL_SETTINGS, attachDocument: false },
|
||||
}).emailSettings.attachDocument,
|
||||
).toBe(false);
|
||||
|
||||
settings.emailDocumentSettings = { ...DEFAULT_DOCUMENT_EMAIL_SETTINGS, attachDocument: false };
|
||||
expect(
|
||||
extractDerivedDocumentMeta(settings, {
|
||||
emailSettings: { ...DEFAULT_DOCUMENT_EMAIL_SETTINGS, attachDocument: true },
|
||||
}).emailSettings.attachDocument,
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user