mirror of
https://github.com/documenso/documenso.git
synced 2025-11-12 15:53:02 +10:00
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.
254 lines
7.0 KiB
TypeScript
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 });
|
|
});
|