Files
documenso/packages/app-tests/e2e/teams/search-documents.spec.ts
David Nguyen 7f09ba72f4 feat: add envelopes (#2025)
This PR is handles the changes required to support envelopes. The new
envelope editor/signing page will be hidden during release.

The core changes here is to migrate the documents and templates model to
a centralized envelopes model.

Even though Documents and Templates are removed, from the user
perspective they will still exist as we remap envelopes to documents and
templates.
2025-10-14 21:56:36 +11:00

254 lines
7.0 KiB
TypeScript

import { expect, test } from '@playwright/test';
import { DocumentStatus, OrganisationMemberRole, TeamMemberRole } from '@prisma/client';
import { generateDatabaseId } from '@documenso/lib/universal/id';
import { prisma } from '@documenso/prisma';
import { seedDocuments, seedTeamDocuments } from '@documenso/prisma/seed/documents';
import { seedOrganisationMembers } from '@documenso/prisma/seed/organisations';
import { seedTeam, seedTeamMember } from '@documenso/prisma/seed/teams';
import { seedUser } from '@documenso/prisma/seed/users';
import { apiSignin, apiSignout } from '../fixtures/authentication';
import { checkDocumentTabCount } from '../fixtures/documents';
test('[TEAMS]: search respects team document visibility', async ({ page }) => {
const { user: owner, organisation, team } = await seedUser();
const [adminUser, managerUser, memberUser] = await seedOrganisationMembers({
organisationId: organisation.id,
members: [
{
organisationRole: OrganisationMemberRole.ADMIN,
},
{
organisationRole: OrganisationMemberRole.MEMBER, // Org managers = team admins so need to workaround this.
},
{
organisationRole: OrganisationMemberRole.MEMBER,
},
],
});
const managerTeamGroup = await prisma.teamGroup.findFirstOrThrow({
where: {
teamId: team.id,
teamRole: TeamMemberRole.MANAGER,
},
include: {
organisationGroup: true,
},
});
const managerOrganisationMember = await prisma.organisationMember.findFirstOrThrow({
where: {
organisationId: organisation.id,
userId: managerUser.id,
},
});
await prisma.organisationGroupMember.create({
data: {
id: generateDatabaseId('group_member'),
groupId: managerTeamGroup.organisationGroupId,
organisationMemberId: managerOrganisationMember.id,
},
});
await seedDocuments([
{
sender: owner,
teamId: team.id,
recipients: [],
type: DocumentStatus.COMPLETED,
documentOptions: {
visibility: 'EVERYONE',
title: 'Searchable Document for Everyone',
},
},
{
sender: owner,
teamId: team.id,
recipients: [],
type: DocumentStatus.COMPLETED,
documentOptions: {
visibility: 'MANAGER_AND_ABOVE',
title: 'Searchable Document for Managers',
},
},
{
sender: owner,
teamId: team.id,
recipients: [],
type: DocumentStatus.COMPLETED,
documentOptions: {
visibility: 'ADMIN',
title: 'Searchable Document for Admins',
},
},
]);
const testCases = [
{ user: adminUser, visibleDocs: 3 },
{ user: managerUser, visibleDocs: 2 },
{ user: memberUser, visibleDocs: 1 },
];
for (const { user, visibleDocs } of testCases) {
await apiSignin({
page,
email: user.email,
redirectPath: `/t/${team.url}/documents`,
});
await page.getByPlaceholder('Search documents...').fill('Searchable');
await page.waitForURL(/query=Searchable/);
await checkDocumentTabCount(page, 'All', visibleDocs);
await apiSignout({ page });
}
});
test('[TEAMS]: search does not reveal documents from other teams', async ({ page }) => {
const {
team: teamA,
teamOwner: teamAOwner,
teamMember2: teamAMember,
} = await seedTeamDocuments();
const { team: teamB, teamOwner: teamBOwner } = await seedTeamDocuments();
await seedDocuments([
{
sender: teamAOwner,
recipients: [],
type: DocumentStatus.COMPLETED,
teamId: teamA.id,
documentOptions: {
visibility: 'EVERYONE',
title: 'Unique Team A Document',
},
},
{
sender: teamBOwner,
recipients: [],
type: DocumentStatus.COMPLETED,
teamId: teamB.id,
documentOptions: {
visibility: 'EVERYONE',
title: 'Unique Team B Document',
},
},
]);
await apiSignin({
page,
email: teamAMember.email,
redirectPath: `/t/${teamA.url}/documents`,
});
await page.waitForTimeout(100);
await page.getByPlaceholder('Search documents...').fill('Unique');
await page.waitForURL(/query=Unique/);
await checkDocumentTabCount(page, 'All', 1);
await expect(page.getByRole('link', { name: 'Unique Team A Document' })).toBeVisible();
await expect(page.getByRole('link', { name: 'Unique Team B Document' })).not.toBeVisible();
await apiSignout({ page });
});
test('[TEAMS]: search respects recipient visibility regardless of team visibility', async ({
page,
}) => {
const { team, owner } = await seedTeam();
const memberUser = await seedTeamMember({ teamId: team.id, role: TeamMemberRole.MEMBER });
await seedDocuments([
{
sender: owner,
teamId: team.id,
recipients: [memberUser],
type: DocumentStatus.COMPLETED,
documentOptions: {
visibility: 'ADMIN',
title: 'Admin Document with Member Recipient',
},
},
]);
await apiSignin({
page,
email: memberUser.email,
redirectPath: `/t/${team.url}/documents`,
});
await page.getByPlaceholder('Search documents...').fill('Admin Document');
await page.waitForURL(/query=Admin(%20|\+|\s)Document/);
await checkDocumentTabCount(page, 'All', 1);
await expect(
page.getByRole('link', { name: 'Admin Document with Member Recipient' }),
).toBeVisible();
await apiSignout({ page });
});
test('[TEAMS]: search by recipient name respects visibility', async ({ page }) => {
const { team, owner } = await seedTeam();
const adminUser = await seedTeamMember({ teamId: team.id, role: TeamMemberRole.ADMIN });
const memberUser = await seedTeamMember({
teamId: team.id,
role: TeamMemberRole.MEMBER,
name: 'Team Member',
});
const { user: uniqueRecipient } = await seedUser();
await seedDocuments([
{
sender: owner,
recipients: [uniqueRecipient],
type: DocumentStatus.COMPLETED,
teamId: team.id,
documentOptions: {
visibility: 'ADMIN',
title: 'Admin Document for Unique Recipient',
},
},
]);
// Admin should see the document when searching by recipient name
await apiSignin({
page,
email: adminUser.email,
redirectPath: `/t/${team.url}/documents`,
});
await page.getByPlaceholder('Search documents...').fill('Unique Recipient');
await page.waitForURL(/query=Unique(%20|\+|\s)Recipient/);
await checkDocumentTabCount(page, 'All', 1);
await expect(
page.getByRole('link', { name: 'Admin Document for Unique Recipient' }),
).toBeVisible();
await apiSignout({ page });
// Member should not see the document when searching by recipient name
await apiSignin({
page,
email: memberUser.email,
redirectPath: `/t/${team.url}/documents`,
});
await page.getByPlaceholder('Search documents...').fill('Unique Recipient');
await page.waitForURL(/query=Unique(%20|\+|\s)Recipient/);
await checkDocumentTabCount(page, 'All', 0);
await expect(
page.getByRole('link', { name: 'Admin Document for Unique Recipient' }),
).not.toBeVisible();
await apiSignout({ page });
});