mirror of
https://github.com/documenso/documenso.git
synced 2026-08-26 00:02:43 +10:00
fix: sort CC recipients last (#2930)
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
import { nanoid } from '@documenso/lib/universal/id';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { seedBlankDocument } from '@documenso/prisma/seed/documents';
|
||||
import { seedUser } from '@documenso/prisma/seed/users';
|
||||
import type { Page } from '@playwright/test';
|
||||
import { expect, test } from '@playwright/test';
|
||||
import { DocumentSigningOrder, RecipientRole } from '@prisma/client';
|
||||
|
||||
import { apiSignin } from '../fixtures/authentication';
|
||||
import {
|
||||
assertRecipientRole,
|
||||
getRecipientEmailInputs,
|
||||
getRecipientRows,
|
||||
getSigningOrderInputs,
|
||||
openDocumentEnvelopeEditor,
|
||||
setRecipientEmail,
|
||||
setRecipientName,
|
||||
setRecipientRole,
|
||||
toggleSigningOrder,
|
||||
} from '../fixtures/envelope-editor';
|
||||
|
||||
const SIGNER_A = { email: 'cc-order-signer-a@example.com', name: 'Signer A' };
|
||||
const SIGNER_B = { email: 'cc-order-signer-b@example.com', name: 'Signer B' };
|
||||
const CC_RECIPIENT = { email: 'cc-order-cc@example.com', name: 'CC Recipient' };
|
||||
|
||||
const assertCcDisplayedLastWithNoOrderInput = async (root: Page) => {
|
||||
// CC recipient is displayed last despite being added/stored mid-list.
|
||||
await expect(getRecipientEmailInputs(root)).toHaveCount(3);
|
||||
await expect(getRecipientEmailInputs(root).nth(0)).toHaveValue(SIGNER_A.email);
|
||||
await expect(getRecipientEmailInputs(root).nth(1)).toHaveValue(SIGNER_B.email);
|
||||
await expect(getRecipientEmailInputs(root).nth(2)).toHaveValue(CC_RECIPIENT.email);
|
||||
|
||||
await assertRecipientRole(root, 0, 'Needs to sign');
|
||||
await assertRecipientRole(root, 1, 'Needs to sign');
|
||||
await assertRecipientRole(root, 2, 'Receives copy');
|
||||
|
||||
// Only the two signers have signing order inputs, showing 1 and 2.
|
||||
await expect(getSigningOrderInputs(root)).toHaveCount(2);
|
||||
await expect(getSigningOrderInputs(root).nth(0)).toHaveValue('1');
|
||||
await expect(getSigningOrderInputs(root).nth(1)).toHaveValue('2');
|
||||
|
||||
// The CC row itself renders no signing order input (placeholder div instead).
|
||||
const ccRow = getRecipientRows(root).nth(2);
|
||||
await expect(ccRow.locator('[data-testid="signing-order-input"]')).toHaveCount(0);
|
||||
};
|
||||
|
||||
test.describe('document editor', () => {
|
||||
test('CC recipient added mid-list is displayed last with no signing order input', async ({ page }) => {
|
||||
const surface = await openDocumentEnvelopeEditor(page);
|
||||
const { root } = surface;
|
||||
|
||||
await toggleSigningOrder(root, true);
|
||||
|
||||
// Add signer A into the initial empty row.
|
||||
await setRecipientEmail(root, 0, SIGNER_A.email);
|
||||
await setRecipientName(root, 0, SIGNER_A.name);
|
||||
|
||||
// Add the CC recipient second.
|
||||
await root.getByRole('button', { name: 'Add Signer' }).click();
|
||||
await setRecipientEmail(root, 1, CC_RECIPIENT.email);
|
||||
await setRecipientName(root, 1, CC_RECIPIENT.name);
|
||||
await setRecipientRole(root, 1, 'Receives copy');
|
||||
|
||||
// Once the row becomes CC, its signing order input disappears.
|
||||
await expect(getSigningOrderInputs(root)).toHaveCount(1);
|
||||
|
||||
// Add signer B third. The new row is inserted before the CC recipient,
|
||||
// which is kept last by the client-side sorting.
|
||||
await root.getByRole('button', { name: 'Add Signer' }).click();
|
||||
await expect(getRecipientEmailInputs(root).nth(2)).toHaveValue(CC_RECIPIENT.email);
|
||||
|
||||
await setRecipientEmail(root, 1, SIGNER_B.email);
|
||||
await setRecipientName(root, 1, SIGNER_B.name);
|
||||
|
||||
await assertCcDisplayedLastWithNoOrderInput(root);
|
||||
|
||||
// The editor autosaves with a debounce, poll the DB until all three
|
||||
// recipients have been persisted before reloading the page.
|
||||
await expect
|
||||
.poll(
|
||||
async () => {
|
||||
const recipients = await prisma.recipient.findMany({
|
||||
where: { envelopeId: surface.envelopeId },
|
||||
});
|
||||
|
||||
return recipients.length;
|
||||
},
|
||||
{ timeout: 15_000 },
|
||||
)
|
||||
.toBe(3);
|
||||
|
||||
// Reload the editor and assert the CC recipient is still displayed last.
|
||||
await root.reload();
|
||||
await expect(root.getByRole('heading', { name: 'Recipients' })).toBeVisible();
|
||||
|
||||
await assertCcDisplayedLastWithNoOrderInput(root);
|
||||
});
|
||||
|
||||
test('CC recipient seeded with mid-list signing order is displayed last', async ({ page }) => {
|
||||
const { user, team } = await seedUser();
|
||||
|
||||
const document = await seedBlankDocument(user, team.id, {
|
||||
internalVersion: 2,
|
||||
});
|
||||
|
||||
// Seed a CC recipient directly in the DB with a mid-list signing order
|
||||
// (2 of 3) BEFORE opening the editor, so the editor's autosave cannot
|
||||
// race with the seeded recipients, and assert the editor renders it last.
|
||||
await prisma.envelope.update({
|
||||
where: { id: document.id },
|
||||
data: {
|
||||
documentMeta: {
|
||||
update: { signingOrder: DocumentSigningOrder.SEQUENTIAL },
|
||||
},
|
||||
recipients: {
|
||||
createMany: {
|
||||
data: [
|
||||
{
|
||||
email: SIGNER_A.email,
|
||||
name: SIGNER_A.name,
|
||||
token: nanoid(),
|
||||
role: RecipientRole.SIGNER,
|
||||
signingOrder: 1,
|
||||
},
|
||||
{
|
||||
email: CC_RECIPIENT.email,
|
||||
name: CC_RECIPIENT.name,
|
||||
token: nanoid(),
|
||||
role: RecipientRole.CC,
|
||||
signingOrder: 2,
|
||||
},
|
||||
{
|
||||
email: SIGNER_B.email,
|
||||
name: SIGNER_B.name,
|
||||
token: nanoid(),
|
||||
role: RecipientRole.SIGNER,
|
||||
signingOrder: 3,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await apiSignin({
|
||||
page,
|
||||
email: user.email,
|
||||
redirectPath: `/t/${team.url}/documents/${document.id}/edit?step=uploadAndRecipients`,
|
||||
});
|
||||
|
||||
await expect(page.getByRole('heading', { name: 'Recipients' })).toBeVisible();
|
||||
|
||||
await assertCcDisplayedLastWithNoOrderInput(page);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user