feat: add organisations (#1820)

This commit is contained in:
David Nguyen
2025-06-10 11:49:52 +10:00
committed by GitHub
parent 0b37f19641
commit e6dc237ad2
631 changed files with 37616 additions and 25695 deletions

View File

@ -5,15 +5,12 @@ import path from 'path';
import { extractDocumentAuthMethods } from '@documenso/lib/utils/document-auth';
import { prisma } from '@documenso/prisma';
import { seedUserSubscription } from '@documenso/prisma/seed/subscriptions';
import { seedTeam } from '@documenso/prisma/seed/teams';
import { seedTeam, seedTeamMember } from '@documenso/prisma/seed/teams';
import { seedBlankTemplate } from '@documenso/prisma/seed/templates';
import { seedUser } from '@documenso/prisma/seed/users';
import { apiSignin } from '../fixtures/authentication';
const enterprisePriceId = '';
const EXAMPLE_PDF_PATH = path.join(__dirname, '../../../../assets/example.pdf');
/**
@ -26,21 +23,13 @@ const EXAMPLE_PDF_PATH = path.join(__dirname, '../../../../assets/example.pdf');
* If you update this test please update that test as well.
*/
test('[TEMPLATE]: should create a document from a template', async ({ page }) => {
const user = await seedUser();
const template = await seedBlankTemplate(user);
const isBillingEnabled =
process.env.NEXT_PUBLIC_FEATURE_BILLING_ENABLED === 'true' && enterprisePriceId;
await seedUserSubscription({
userId: user.id,
priceId: enterprisePriceId,
});
const { user, team } = await seedUser();
const template = await seedBlankTemplate(user, team.id);
await apiSignin({
page,
email: user.email,
redirectPath: `/templates/${template.id}/edit`,
redirectPath: `/t/${team.url}/templates/${template.id}/edit`,
});
// Set template title.
@ -51,13 +40,6 @@ test('[TEMPLATE]: should create a document from a template', async ({ page }) =>
await page.getByRole('option').filter({ hasText: 'Require account' }).click();
await expect(page.getByTestId('documentAccessSelectValue')).toContainText('Require account');
// Set EE action auth.
if (isBillingEnabled) {
await page.getByTestId('documentActionSelectValue').click();
await page.getByRole('option').filter({ hasText: 'Require passkey' }).click();
await expect(page.getByTestId('documentActionSelectValue')).toContainText('Require passkey');
}
// Set email options.
await page.getByRole('button', { name: 'Email Options' }).click();
await page.getByLabel('Subject (Optional)').fill('SUBJECT');
@ -82,25 +64,18 @@ test('[TEMPLATE]: should create a document from a template', async ({ page }) =>
await page.getByPlaceholder('Email').nth(1).fill('recipient2@documenso.com');
await page.getByPlaceholder('Name').nth(1).fill('Recipient 2');
// Apply require passkey for Recipient 1.
if (isBillingEnabled) {
await page.getByLabel('Show advanced settings').check();
await page.getByTestId('documentActionSelectValue').click();
await page.getByRole('option').filter({ hasText: 'Require passkey' }).click();
}
await page.getByRole('button', { name: 'Continue' }).click();
await expect(page.getByRole('heading', { name: 'Add Fields' })).toBeVisible();
await page.getByRole('button', { name: 'Save template' }).click();
// Use template
await page.waitForURL('/templates');
await page.waitForURL(`/t/${team.url}/templates`);
await page.getByRole('button', { name: 'Use Template' }).click();
await page.getByRole('button', { name: 'Create as draft' }).click();
// Review that the document was created with the correct values.
await page.waitForURL(/documents/);
await page.waitForURL(new RegExp(`/t/${team.url}/documents/\\d+`));
const documentId = Number(page.url().split('/').pop());
@ -121,10 +96,6 @@ test('[TEMPLATE]: should create a document from a template', async ({ page }) =>
expect(document.title).toEqual('TEMPLATE_TITLE');
expect(documentAuth.documentAuthOption.globalAccessAuth).toContain('ACCOUNT');
if (isBillingEnabled) {
expect(documentAuth.documentAuthOption.globalActionAuth).toContain('PASSKEY');
}
expect(document.documentMeta?.dateFormat).toEqual('dd/MM/yyyy hh:mm a');
expect(document.documentMeta?.message).toEqual('MESSAGE');
expect(document.documentMeta?.redirectUrl).toEqual('https://documenso.com');
@ -144,10 +115,6 @@ test('[TEMPLATE]: should create a document from a template', async ({ page }) =>
recipientAuth: recipientTwo.authOptions,
});
if (isBillingEnabled) {
expect(recipientOneAuth.derivedRecipientActionAuth).toContain('PASSKEY');
}
expect(recipientOneAuth.derivedRecipientAccessAuth).toContain('ACCOUNT');
expect(recipientTwoAuth.derivedRecipientAccessAuth).toContain('ACCOUNT');
});
@ -156,23 +123,11 @@ test('[TEMPLATE]: should create a document from a template', async ({ page }) =>
* This is a direct copy paste of the above test but for teams.
*/
test('[TEMPLATE]: should create a team document from a team template', async ({ page }) => {
const { owner, ...team } = await seedTeam({
const { team, owner, organisation } = await seedTeam({
createTeamMembers: 2,
});
const template = await seedBlankTemplate(owner, {
createTemplateOptions: {
teamId: team.id,
},
});
const isBillingEnabled =
process.env.NEXT_PUBLIC_FEATURE_BILLING_ENABLED === 'true' && enterprisePriceId;
await seedUserSubscription({
userId: owner.id,
priceId: enterprisePriceId,
});
const template = await seedBlankTemplate(owner, team.id);
await apiSignin({
page,
@ -188,13 +143,6 @@ test('[TEMPLATE]: should create a team document from a team template', async ({
await page.getByRole('option').filter({ hasText: 'Require account' }).click();
await expect(page.getByTestId('documentAccessSelectValue')).toContainText('Require account');
// Set EE action auth.
if (isBillingEnabled) {
await page.getByTestId('documentActionSelectValue').click();
await page.getByRole('option').filter({ hasText: 'Require passkey' }).click();
await expect(page.getByTestId('documentActionSelectValue')).toContainText('Require passkey');
}
// Set email options.
await page.getByRole('button', { name: 'Email Options' }).click();
await page.getByLabel('Subject (Optional)').fill('SUBJECT');
@ -219,13 +167,6 @@ test('[TEMPLATE]: should create a team document from a team template', async ({
await page.getByPlaceholder('Email').nth(1).fill('recipient2@documenso.com');
await page.getByPlaceholder('Name').nth(1).fill('Recipient 2');
// Apply require passkey for Recipient 1.
if (isBillingEnabled) {
await page.getByLabel('Show advanced settings').check();
await page.getByTestId('documentActionSelectValue').click();
await page.getByRole('option').filter({ hasText: 'Require passkey' }).click();
}
await page.getByRole('button', { name: 'Continue' }).click();
await expect(page.getByRole('heading', { name: 'Add Fields' })).toBeVisible();
@ -237,7 +178,7 @@ test('[TEMPLATE]: should create a team document from a team template', async ({
await page.getByRole('button', { name: 'Create as draft' }).click();
// Review that the document was created with the correct values.
await page.waitForURL(/documents/);
await page.waitForURL(new RegExp(`/t/${team.url}/documents/\\d+`));
const documentId = Number(page.url().split('/').pop());
@ -259,11 +200,6 @@ test('[TEMPLATE]: should create a team document from a team template', async ({
expect(document.title).toEqual('TEMPLATE_TITLE');
expect(documentAuth.documentAuthOption.globalAccessAuth).toContain('ACCOUNT');
if (isBillingEnabled) {
expect(documentAuth.documentAuthOption.globalActionAuth).toContain('PASSKEY');
}
expect(document.documentMeta?.dateFormat).toEqual('dd/MM/yyyy hh:mm a');
expect(document.documentMeta?.message).toEqual('MESSAGE');
expect(document.documentMeta?.redirectUrl).toEqual('https://documenso.com');
@ -283,10 +219,6 @@ test('[TEMPLATE]: should create a team document from a team template', async ({
recipientAuth: recipientTwo.authOptions,
});
if (isBillingEnabled) {
expect(recipientOneAuth.derivedRecipientActionAuth).toContain('PASSKEY');
}
expect(recipientOneAuth.derivedRecipientAccessAuth).toContain('ACCOUNT');
expect(recipientTwoAuth.derivedRecipientAccessAuth).toContain('ACCOUNT');
});
@ -298,8 +230,8 @@ test('[TEMPLATE]: should create a team document from a team template', async ({
test('[TEMPLATE]: should create a document from a template with custom document', async ({
page,
}) => {
const user = await seedUser();
const template = await seedBlankTemplate(user);
const { user, team } = await seedUser();
const template = await seedBlankTemplate(user, team.id);
// Create a temporary PDF file for upload
@ -308,7 +240,7 @@ test('[TEMPLATE]: should create a document from a template with custom document'
await apiSignin({
page,
email: user.email,
redirectPath: `/templates/${template.id}/edit`,
redirectPath: `/t/${team.url}/templates/${template.id}/edit`,
});
// Set template title
@ -327,7 +259,7 @@ test('[TEMPLATE]: should create a document from a template with custom document'
await page.getByRole('button', { name: 'Save template' }).click();
// Use template with custom document
await page.waitForURL('/templates');
await page.waitForURL(`/t/${team.url}/templates`);
await page.getByRole('button', { name: 'Use Template' }).click();
// Enable custom document upload and upload file
@ -352,7 +284,7 @@ test('[TEMPLATE]: should create a document from a template with custom document'
await page.getByRole('button', { name: 'Create as draft' }).click();
// Review that the document was created with the custom document data
await page.waitForURL(/documents/);
await page.waitForURL(new RegExp(`/t/${team.url}/documents/\\d+`));
const documentId = Number(page.url().split('/').pop());
@ -378,15 +310,11 @@ test('[TEMPLATE]: should create a document from a template with custom document'
test('[TEMPLATE]: should create a team document from a template with custom document', async ({
page,
}) => {
const { owner, ...team } = await seedTeam({
const { team, owner, organisation } = await seedTeam({
createTeamMembers: 2,
});
const template = await seedBlankTemplate(owner, {
createTemplateOptions: {
teamId: team.id,
},
});
const template = await seedBlankTemplate(owner, team.id);
const pdfContent = fs.readFileSync(EXAMPLE_PDF_PATH).toString('base64');
@ -437,7 +365,7 @@ test('[TEMPLATE]: should create a team document from a template with custom docu
await page.getByRole('button', { name: 'Create as draft' }).click();
// Review that the document was created with the custom document data
await page.waitForURL(/documents/);
await page.waitForURL(new RegExp(`/t/${team.url}/documents/\\d+`));
const documentId = Number(page.url().split('/').pop());
@ -464,13 +392,13 @@ test('[TEMPLATE]: should create a team document from a template with custom docu
test('[TEMPLATE]: should create a document from a template using template document when custom document is not enabled', async ({
page,
}) => {
const user = await seedUser();
const template = await seedBlankTemplate(user);
const { user, team } = await seedUser();
const template = await seedBlankTemplate(user, team.id);
await apiSignin({
page,
email: user.email,
redirectPath: `/templates/${template.id}/edit`,
redirectPath: `/t/${team.url}/templates/${template.id}/edit`,
});
// Set template title
@ -489,7 +417,7 @@ test('[TEMPLATE]: should create a document from a template using template docume
await page.getByRole('button', { name: 'Save template' }).click();
// Use template without custom document
await page.waitForURL('/templates');
await page.waitForURL(`/t/${team.url}/templates`);
await page.getByRole('button', { name: 'Use Template' }).click();
// Verify custom document upload is not checked by default
@ -499,7 +427,7 @@ test('[TEMPLATE]: should create a document from a template using template docume
await page.getByRole('button', { name: 'Create as draft' }).click();
// Review that the document was created with the template's document data
await page.waitForURL(/documents/);
await page.waitForURL(new RegExp(`/t/${team.url}/documents/\\d+`));
const documentId = Number(page.url().split('/').pop());
@ -532,15 +460,11 @@ test('[TEMPLATE]: should create a document from a template using template docume
test('[TEMPLATE]: should persist document visibility when creating from template', async ({
page,
}) => {
const { owner, ...team } = await seedTeam({
const { team, owner, organisation } = await seedTeam({
createTeamMembers: 2,
});
const template = await seedBlankTemplate(owner, {
createTemplateOptions: {
teamId: team.id,
},
});
const template = await seedBlankTemplate(owner, team.id);
await apiSignin({
page,
@ -569,17 +493,11 @@ test('[TEMPLATE]: should persist document visibility when creating from template
await page.getByRole('button', { name: 'Save template' }).click();
// Test creating document as team manager
await prisma.teamMember.update({
where: {
id: team.members[1].id,
},
data: {
role: TeamMemberRole.MANAGER,
},
const managerUser = await seedTeamMember({
teamId: team.id,
role: TeamMemberRole.MANAGER,
});
const managerUser = team.members[1].user;
await apiSignin({
page,
email: managerUser.email,
@ -590,7 +508,7 @@ test('[TEMPLATE]: should persist document visibility when creating from template
await page.getByRole('button', { name: 'Create as draft' }).click();
// Review that the document was created with the correct visibility
await page.waitForURL(/documents/);
await page.waitForURL(new RegExp(`/t/${team.url}/documents/\\d+`));
const documentId = Number(page.url().split('/').pop());
@ -605,7 +523,11 @@ test('[TEMPLATE]: should persist document visibility when creating from template
expect(document.teamId).toEqual(team.id);
// Test that regular member cannot create document from restricted template
const memberUser = team.members[2].user;
const memberUser = await seedTeamMember({
teamId: team.id,
role: TeamMemberRole.MEMBER,
});
await apiSignin({
page,
email: memberUser.email,