mirror of
https://github.com/documenso/documenso.git
synced 2026-07-26 09:54:51 +10:00
fix: lint project (#2693)
This commit is contained in:
@@ -1,19 +1,14 @@
|
||||
import type { Page } from '@playwright/test';
|
||||
import { expect, test } from '@playwright/test';
|
||||
import { OrganisationMemberRole, TeamMemberRole } from '@prisma/client';
|
||||
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import { generateDatabaseId } from '@documenso/lib/universal/id';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { DocumentStatus } from '@documenso/prisma/client';
|
||||
import {
|
||||
seedCompletedDocument,
|
||||
seedDocuments,
|
||||
seedPendingDocument,
|
||||
} from '@documenso/prisma/seed/documents';
|
||||
import { seedCompletedDocument, seedDocuments, seedPendingDocument } 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 type { Page } from '@playwright/test';
|
||||
import { expect, test } from '@playwright/test';
|
||||
import { OrganisationMemberRole, TeamMemberRole } from '@prisma/client';
|
||||
|
||||
import { apiSignin, apiSignout } from '../../fixtures/authentication';
|
||||
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
import type { Page } from '@playwright/test';
|
||||
import { expect, test } from '@playwright/test';
|
||||
import { OrganisationMemberRole, TeamMemberRole } from '@prisma/client';
|
||||
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import { generateDatabaseId } from '@documenso/lib/universal/id';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
@@ -9,6 +5,9 @@ import { seedOrganisationMembers } from '@documenso/prisma/seed/organisations';
|
||||
import { seedTeam, seedTeamMember } from '@documenso/prisma/seed/teams';
|
||||
import { seedBlankTemplate } from '@documenso/prisma/seed/templates';
|
||||
import { seedUser } from '@documenso/prisma/seed/users';
|
||||
import type { Page } from '@playwright/test';
|
||||
import { expect, test } from '@playwright/test';
|
||||
import { OrganisationMemberRole, TeamMemberRole } from '@prisma/client';
|
||||
|
||||
import { apiSignin, apiSignout } from '../../fixtures/authentication';
|
||||
|
||||
@@ -171,9 +170,7 @@ test.describe('Template Search - Cross-Team Isolation', () => {
|
||||
// ─── Recipient Email Search ──────────────────────────────────────────────────
|
||||
|
||||
test.describe('Template Search - Recipient Email', () => {
|
||||
test('should find templates by recipient email within team but not cross-team', async ({
|
||||
page,
|
||||
}) => {
|
||||
test('should find templates by recipient email within team but not cross-team', async ({ page }) => {
|
||||
const { team: teamA, owner: ownerA } = await seedTeam();
|
||||
const adminUserA = await seedTeamMember({ teamId: teamA.id, role: TeamMemberRole.ADMIN });
|
||||
const { team: teamB, owner: ownerB } = await seedTeam();
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
import { expect, test } from '@playwright/test';
|
||||
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import { createApiToken } from '@documenso/lib/server-only/public-api/create-api-token';
|
||||
import { mapSecondaryIdToDocumentId } from '@documenso/lib/utils/envelope';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { FieldType, RecipientRole } from '@documenso/prisma/client';
|
||||
import {
|
||||
seedBlankDocument,
|
||||
seedPendingDocumentWithFullFields,
|
||||
} from '@documenso/prisma/seed/documents';
|
||||
import { seedBlankDocument, seedPendingDocumentWithFullFields } from '@documenso/prisma/seed/documents';
|
||||
import { seedUser } from '@documenso/prisma/seed/users';
|
||||
import { expect, test } from '@playwright/test';
|
||||
|
||||
test.describe('Document API', () => {
|
||||
test('sendDocument: should respect sendCompletionEmails setting', async ({ request }) => {
|
||||
@@ -193,9 +189,7 @@ test.describe('Document API', () => {
|
||||
expect(response.status()).toBe(400);
|
||||
});
|
||||
|
||||
test('sendDocument: should fail when signer has only non-signature fields', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('sendDocument: should fail when signer has only non-signature fields', async ({ request }) => {
|
||||
const { user, team } = await seedUser();
|
||||
|
||||
// Create a blank document and get it with envelope items
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { expect, test } from '@playwright/test';
|
||||
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import { createApiToken } from '@documenso/lib/server-only/public-api/create-api-token';
|
||||
import type { TCheckboxFieldMeta, TRadioFieldMeta } from '@documenso/lib/types/field-meta';
|
||||
@@ -12,16 +10,14 @@ import { prisma } from '@documenso/prisma';
|
||||
import { FieldType, RecipientRole } from '@documenso/prisma/client';
|
||||
import { seedBlankTemplate } from '@documenso/prisma/seed/templates';
|
||||
import { seedUser } from '@documenso/prisma/seed/users';
|
||||
import { expect, test } from '@playwright/test';
|
||||
|
||||
import { apiSignin } from '../../fixtures/authentication';
|
||||
|
||||
const WEBAPP_BASE_URL = NEXT_PUBLIC_WEBAPP_URL();
|
||||
|
||||
test.describe('Template Field Prefill API v1', () => {
|
||||
test('should create a document from template with prefilled fields', async ({
|
||||
page,
|
||||
request,
|
||||
}) => {
|
||||
test('should create a document from template with prefilled fields', async ({ page, request }) => {
|
||||
// 1. Create a user
|
||||
const { user, team } = await seedUser();
|
||||
|
||||
@@ -196,9 +192,7 @@ test.describe('Template Field Prefill API v1', () => {
|
||||
});
|
||||
|
||||
// 7. Navigate to the template
|
||||
await page.goto(
|
||||
`${WEBAPP_BASE_URL}/t/${team.url}/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}`,
|
||||
);
|
||||
await page.goto(`${WEBAPP_BASE_URL}/t/${team.url}/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}`);
|
||||
|
||||
// 8. Create a document from the template with prefilled fields
|
||||
const response = await request.post(
|
||||
@@ -381,10 +375,7 @@ test.describe('Template Field Prefill API v1', () => {
|
||||
await expect(page.getByText('Select B')).toBeVisible();
|
||||
});
|
||||
|
||||
test('should create a document from template without prefilled fields', async ({
|
||||
page,
|
||||
request,
|
||||
}) => {
|
||||
test('should create a document from template without prefilled fields', async ({ page, request }) => {
|
||||
// 1. Create a user
|
||||
const { user, team } = await seedUser();
|
||||
|
||||
@@ -487,9 +478,7 @@ test.describe('Template Field Prefill API v1', () => {
|
||||
});
|
||||
|
||||
// 7. Navigate to the template
|
||||
await page.goto(
|
||||
`${WEBAPP_BASE_URL}/t/${team.url}/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}`,
|
||||
);
|
||||
await page.goto(`${WEBAPP_BASE_URL}/t/${team.url}/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}`);
|
||||
|
||||
// 8. Create a document from the template without prefilled fields
|
||||
const response = await request.post(
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
import { expect, test } from '@playwright/test';
|
||||
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import { createApiToken } from '@documenso/lib/server-only/public-api/create-api-token';
|
||||
import {
|
||||
mapSecondaryIdToDocumentId,
|
||||
mapSecondaryIdToTemplateId,
|
||||
} from '@documenso/lib/utils/envelope';
|
||||
import { mapSecondaryIdToDocumentId, mapSecondaryIdToTemplateId } from '@documenso/lib/utils/envelope';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { DocumentDataType, FieldType } from '@documenso/prisma/client';
|
||||
import {
|
||||
@@ -16,6 +11,7 @@ import {
|
||||
} from '@documenso/prisma/seed/documents';
|
||||
import { seedBlankTemplate, seedTemplate } from '@documenso/prisma/seed/templates';
|
||||
import { seedUser } from '@documenso/prisma/seed/users';
|
||||
import { expect, test } from '@playwright/test';
|
||||
|
||||
const WEBAPP_BASE_URL = NEXT_PUBLIC_WEBAPP_URL();
|
||||
|
||||
@@ -25,9 +21,7 @@ test.describe.configure({
|
||||
|
||||
test.describe('Document Access API V1', () => {
|
||||
test.describe('Document GET endpoint', () => {
|
||||
test('should block unauthorized access to documents not owned by the user', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should block unauthorized access to documents not owned by the user', async ({ request }) => {
|
||||
const { user: userA, team: teamA } = await seedUser();
|
||||
|
||||
const { user: userB, team: teamB } = await seedUser();
|
||||
@@ -319,9 +313,7 @@ test.describe('Document Access API V1', () => {
|
||||
});
|
||||
|
||||
test.describe('Document recipients POST endpoint', () => {
|
||||
test('should block unauthorized access to document recipients endpoint', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should block unauthorized access to document recipients endpoint', async ({ request }) => {
|
||||
const { user: userA, team: teamA } = await seedUser();
|
||||
|
||||
const { user: userB, team: teamB } = await seedUser();
|
||||
@@ -371,9 +363,7 @@ test.describe('Document Access API V1', () => {
|
||||
});
|
||||
|
||||
test.describe('Document recipients PATCH endpoint', () => {
|
||||
test('should block unauthorized access to PATCH on recipients endpoint', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should block unauthorized access to PATCH on recipients endpoint', async ({ request }) => {
|
||||
const { user: userA, team: teamA } = await seedUser();
|
||||
|
||||
const { user: userB, team: teamB } = await seedUser();
|
||||
@@ -459,9 +449,7 @@ test.describe('Document Access API V1', () => {
|
||||
});
|
||||
|
||||
test.describe('Document recipients DELETE endpoint', () => {
|
||||
test('should block unauthorized access to DELETE on recipients endpoint', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should block unauthorized access to DELETE on recipients endpoint', async ({ request }) => {
|
||||
const { user: userA, team: teamA } = await seedUser();
|
||||
|
||||
const { user: userB, team: teamB } = await seedUser();
|
||||
@@ -972,9 +960,7 @@ test.describe('Document Access API V1', () => {
|
||||
|
||||
expect(resB.ok()).toBeTruthy();
|
||||
expect(resB.status()).toBe(200);
|
||||
expect(reqData.documents.every((doc: { userId: number }) => doc.userId !== userA.id)).toBe(
|
||||
true,
|
||||
);
|
||||
expect(reqData.documents.every((doc: { userId: number }) => doc.userId !== userA.id)).toBe(true);
|
||||
expect(reqData.documents.length).toBe(0);
|
||||
expect(reqData.totalPages).toBe(0);
|
||||
});
|
||||
@@ -999,9 +985,7 @@ test.describe('Document Access API V1', () => {
|
||||
expect(resA.ok()).toBeTruthy();
|
||||
expect(resA.status()).toBe(200);
|
||||
expect(reqData.documents.length).toBeGreaterThan(0);
|
||||
expect(reqData.documents.every((doc: { userId: number }) => doc.userId === userA.id)).toBe(
|
||||
true,
|
||||
);
|
||||
expect(reqData.documents.every((doc: { userId: number }) => doc.userId === userA.id)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1027,9 +1011,7 @@ test.describe('Document Access API V1', () => {
|
||||
|
||||
expect(resB.ok()).toBeTruthy();
|
||||
expect(resB.status()).toBe(200);
|
||||
expect(reqData.templates.every((tpl: { userId: number }) => tpl.userId !== userA.id)).toBe(
|
||||
true,
|
||||
);
|
||||
expect(reqData.templates.every((tpl: { userId: number }) => tpl.userId !== userA.id)).toBe(true);
|
||||
expect(reqData.templates.length).toBe(0);
|
||||
expect(reqData.totalPages).toBe(0);
|
||||
});
|
||||
@@ -1054,16 +1036,12 @@ test.describe('Document Access API V1', () => {
|
||||
expect(resA.ok()).toBeTruthy();
|
||||
expect(resA.status()).toBe(200);
|
||||
expect(reqData.templates.length).toBeGreaterThan(0);
|
||||
expect(reqData.templates.every((tpl: { userId: number }) => tpl.userId === userA.id)).toBe(
|
||||
true,
|
||||
);
|
||||
expect(reqData.templates.every((tpl: { userId: number }) => tpl.userId === userA.id)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Create document from template endpoint', () => {
|
||||
test('should block unauthorized access to create-document-from-template endpoint', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should block unauthorized access to create-document-from-template endpoint', async ({ request }) => {
|
||||
const { user: userA, team: teamA } = await seedUser();
|
||||
|
||||
const { user: userB, team: teamB } = await seedUser();
|
||||
@@ -1104,9 +1082,7 @@ test.describe('Document Access API V1', () => {
|
||||
expect(resB.status()).toBe(401);
|
||||
});
|
||||
|
||||
test('should allow authorized access to create-document-from-template endpoint', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should allow authorized access to create-document-from-template endpoint', async ({ request }) => {
|
||||
const { user: userA, team: teamA } = await seedUser();
|
||||
const { token: tokenA } = await createApiToken({
|
||||
userId: userA.id,
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import { type APIRequestContext, expect, test } from '@playwright/test';
|
||||
import type { Team, User } from '@prisma/client';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import { createApiToken } from '@documenso/lib/server-only/public-api/create-api-token';
|
||||
import { EnvelopeType, FieldType, RecipientRole } from '@documenso/prisma/client';
|
||||
@@ -13,6 +10,8 @@ import type {
|
||||
} from '@documenso/trpc/server/envelope-router/create-envelope.types';
|
||||
import type { TCreateEnvelopeRecipientsRequest } from '@documenso/trpc/server/envelope-router/envelope-recipients/create-envelope-recipients.types';
|
||||
import type { TGetEnvelopeResponse } from '@documenso/trpc/server/envelope-router/get-envelope.types';
|
||||
import { type APIRequestContext, expect, test } from '@playwright/test';
|
||||
import type { Team, User } from '@prisma/client';
|
||||
|
||||
const WEBAPP_BASE_URL = NEXT_PUBLIC_WEBAPP_URL();
|
||||
const baseUrl = `${WEBAPP_BASE_URL}/api/v2-beta`;
|
||||
@@ -138,9 +137,7 @@ test.describe('Envelope distribute validation', () => {
|
||||
expect(errorResponse.message).toContain('Signers must have at least one signature field');
|
||||
});
|
||||
|
||||
test('should fail to distribute when signer has non-signature fields only', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should fail to distribute when signer has non-signature fields only', async ({ request }) => {
|
||||
const envelope = await createEnvelope(request, token);
|
||||
const envelopeData = await getEnvelope(request, token, envelope.id);
|
||||
|
||||
@@ -321,9 +318,7 @@ test.describe('Envelope distribute validation', () => {
|
||||
expect(distributeRes.status()).toBe(200);
|
||||
});
|
||||
|
||||
test('should fail when one of multiple signers is missing signature field', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should fail when one of multiple signers is missing signature field', async ({ request }) => {
|
||||
const envelope = await createEnvelope(request, token);
|
||||
const envelopeData = await getEnvelope(request, token, envelope.id);
|
||||
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
import { expect, test } from '@playwright/test';
|
||||
import type { APIRequestContext } from 'playwright-core';
|
||||
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import type { CreateEmbeddingPresignTokenOptions } from '@documenso/lib/server-only/embedding-presign/create-embedding-presign-token';
|
||||
import type { VerifyEmbeddingPresignTokenOptions } from '@documenso/lib/server-only/embedding-presign/verify-embedding-presign-token';
|
||||
import { createApiToken } from '@documenso/lib/server-only/public-api/create-api-token';
|
||||
import { seedUser } from '@documenso/prisma/seed/users';
|
||||
import { expect, test } from '@playwright/test';
|
||||
import type { APIRequestContext } from 'playwright-core';
|
||||
|
||||
test.describe('Embedding Presign API', () => {
|
||||
test('createEmbeddingPresignToken: should create a token with default expiration', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('createEmbeddingPresignToken: should create a token with default expiration', async ({ request }) => {
|
||||
const { user, team } = await seedUser();
|
||||
|
||||
const { token } = await createApiToken({
|
||||
@@ -34,9 +31,7 @@ test.describe('Embedding Presign API', () => {
|
||||
expect(responseData.expiresIn).toBe(3600); // Default 1 hour in seconds
|
||||
});
|
||||
|
||||
test('createEmbeddingPresignToken: should create a token with custom expiration', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('createEmbeddingPresignToken: should create a token with custom expiration', async ({ request }) => {
|
||||
const { user, team } = await seedUser();
|
||||
|
||||
const { token } = await createApiToken({
|
||||
@@ -187,9 +182,7 @@ test.describe('Embedding Presign API', () => {
|
||||
expect(verifyResponseData.success).toBe(true);
|
||||
});
|
||||
|
||||
test('verifyEmbeddingPresignToken: should reject a scope mismatched token', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('verifyEmbeddingPresignToken: should reject a scope mismatched token', async ({ request }) => {
|
||||
const { user, team } = await seedUser();
|
||||
|
||||
const { token } = await createApiToken({
|
||||
@@ -233,19 +226,16 @@ const createPresignToken = async (
|
||||
apiToken: string,
|
||||
data?: Partial<CreateEmbeddingPresignTokenOptions>,
|
||||
) => {
|
||||
return await request.post(
|
||||
`${NEXT_PUBLIC_WEBAPP_URL()}/api/v2-beta/embedding/create-presign-token`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${apiToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: {
|
||||
apiToken,
|
||||
...data,
|
||||
},
|
||||
return await request.post(`${NEXT_PUBLIC_WEBAPP_URL()}/api/v2-beta/embedding/create-presign-token`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${apiToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
);
|
||||
data: {
|
||||
apiToken,
|
||||
...data,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const verifyPresignToken = async (
|
||||
@@ -253,14 +243,11 @@ const verifyPresignToken = async (
|
||||
apiToken: string,
|
||||
data: VerifyEmbeddingPresignTokenOptions,
|
||||
) => {
|
||||
return await request.post(
|
||||
`${NEXT_PUBLIC_WEBAPP_URL()}/api/v2-beta/embedding/verify-presign-token`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${apiToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data,
|
||||
return await request.post(`${NEXT_PUBLIC_WEBAPP_URL()}/api/v2-beta/embedding/verify-presign-token`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${apiToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
);
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
import { type APIRequestContext, expect, test } from '@playwright/test';
|
||||
import type { Team, User } from '@prisma/client';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { pick } from 'remeda';
|
||||
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import { createApiToken } from '@documenso/lib/server-only/public-api/create-api-token';
|
||||
import { DocumentAccessAuth } from '@documenso/lib/types/document-auth';
|
||||
@@ -19,17 +15,20 @@ import {
|
||||
RecipientRole,
|
||||
} from '@documenso/prisma/client';
|
||||
import { seedUser } from '@documenso/prisma/seed/users';
|
||||
import type { TCreateEnvelopeItemsPayload } from '@documenso/trpc/server/envelope-router/create-envelope-items.types';
|
||||
import type {
|
||||
TCreateEnvelopePayload,
|
||||
TCreateEnvelopeResponse,
|
||||
} from '@documenso/trpc/server/envelope-router/create-envelope.types';
|
||||
import type { TCreateEnvelopeItemsPayload } from '@documenso/trpc/server/envelope-router/create-envelope-items.types';
|
||||
import type { TDistributeEnvelopeRequest } from '@documenso/trpc/server/envelope-router/distribute-envelope.types';
|
||||
import type { TCreateEnvelopeRecipientsRequest } from '@documenso/trpc/server/envelope-router/envelope-recipients/create-envelope-recipients.types';
|
||||
import type { TUpdateEnvelopeRecipientsRequest } from '@documenso/trpc/server/envelope-router/envelope-recipients/update-envelope-recipients.types';
|
||||
import type { TFindEnvelopesResponse } from '@documenso/trpc/server/envelope-router/find-envelopes.types';
|
||||
import type { TGetEnvelopeResponse } from '@documenso/trpc/server/envelope-router/get-envelope.types';
|
||||
import type { TUpdateEnvelopeRequest } from '@documenso/trpc/server/envelope-router/update-envelope.types';
|
||||
import { type APIRequestContext, expect, test } from '@playwright/test';
|
||||
import type { Team, User } from '@prisma/client';
|
||||
import { pick } from 'remeda';
|
||||
|
||||
import { ALIGNMENT_TEST_FIELDS } from '../../../constants/field-alignment-pdf';
|
||||
import { FIELD_META_TEST_FIELDS } from '../../../constants/field-meta-pdf';
|
||||
@@ -94,9 +93,7 @@ test.describe('API V2 Envelopes', () => {
|
||||
const files = [
|
||||
{
|
||||
name: 'field-font-alignment.pdf',
|
||||
data: fs.readFileSync(
|
||||
path.join(__dirname, '../../../../../assets/field-font-alignment.pdf'),
|
||||
),
|
||||
data: fs.readFileSync(path.join(__dirname, '../../../../../assets/field-font-alignment.pdf')),
|
||||
},
|
||||
];
|
||||
|
||||
@@ -232,9 +229,7 @@ test.describe('API V2 Envelopes', () => {
|
||||
},
|
||||
{
|
||||
name: 'field-font-alignment.pdf',
|
||||
data: fs.readFileSync(
|
||||
path.join(__dirname, '../../../../../assets/field-font-alignment.pdf'),
|
||||
),
|
||||
data: fs.readFileSync(path.join(__dirname, '../../../../../assets/field-font-alignment.pdf')),
|
||||
},
|
||||
];
|
||||
|
||||
@@ -294,15 +289,11 @@ test.describe('API V2 Envelopes', () => {
|
||||
expect(envelope.documentMeta.dateFormat).toBe(payload.meta.dateFormat);
|
||||
expect(envelope.documentMeta.distributionMethod).toBe(payload.meta.distributionMethod);
|
||||
expect(envelope.documentMeta.signingOrder).toBe(payload.meta.signingOrder);
|
||||
expect(envelope.documentMeta.allowDictateNextSigner).toBe(
|
||||
payload.meta.allowDictateNextSigner,
|
||||
);
|
||||
expect(envelope.documentMeta.allowDictateNextSigner).toBe(payload.meta.allowDictateNextSigner);
|
||||
expect(envelope.documentMeta.redirectUrl).toBe(payload.meta.redirectUrl);
|
||||
expect(envelope.documentMeta.language).toBe(payload.meta.language);
|
||||
expect(envelope.documentMeta.typedSignatureEnabled).toBe(payload.meta.typedSignatureEnabled);
|
||||
expect(envelope.documentMeta.uploadSignatureEnabled).toBe(
|
||||
payload.meta.uploadSignatureEnabled,
|
||||
);
|
||||
expect(envelope.documentMeta.uploadSignatureEnabled).toBe(payload.meta.uploadSignatureEnabled);
|
||||
expect(envelope.documentMeta.drawSignatureEnabled).toBe(payload.meta.drawSignatureEnabled);
|
||||
expect(envelope.documentMeta.emailReplyTo).toBe(payload.meta.emailReplyTo);
|
||||
expect(envelope.documentMeta.emailSettings).toEqual(payload.meta.emailSettings);
|
||||
@@ -324,9 +315,7 @@ test.describe('API V2 Envelopes', () => {
|
||||
role: recipient.role,
|
||||
signingOrder: recipient.signingOrder,
|
||||
accessAuth: recipient.authOptions?.accessAuth,
|
||||
}).toEqual(
|
||||
pick(payload.recipients[0], ['email', 'name', 'role', 'signingOrder', 'accessAuth']),
|
||||
);
|
||||
}).toEqual(pick(payload.recipients[0], ['email', 'name', 'role', 'signingOrder', 'accessAuth']));
|
||||
|
||||
expect({
|
||||
type: field.type,
|
||||
@@ -335,16 +324,7 @@ test.describe('API V2 Envelopes', () => {
|
||||
positionY: field.positionY.toNumber(),
|
||||
width: field.width.toNumber(),
|
||||
height: field.height.toNumber(),
|
||||
}).toEqual(
|
||||
pick(payload.recipients[0].fields[0], [
|
||||
'type',
|
||||
'page',
|
||||
'positionX',
|
||||
'positionY',
|
||||
'width',
|
||||
'height',
|
||||
]),
|
||||
);
|
||||
}).toEqual(pick(payload.recipients[0].fields[0], ['type', 'page', 'positionX', 'positionY', 'width', 'height']));
|
||||
|
||||
// Expect string based ID to work.
|
||||
expect(field.envelopeItemId).toBe(
|
||||
@@ -363,13 +343,9 @@ test.describe('API V2 Envelopes', () => {
|
||||
*/
|
||||
test('Envelope full test', async ({ request }) => {
|
||||
// Step 1: Create initial envelope with Prisma (with first envelope item)
|
||||
const alignmentPdf = fs.readFileSync(
|
||||
path.join(__dirname, '../../../../../assets/field-font-alignment.pdf'),
|
||||
);
|
||||
const alignmentPdf = fs.readFileSync(path.join(__dirname, '../../../../../assets/field-font-alignment.pdf'));
|
||||
|
||||
const fieldMetaPdf = fs.readFileSync(
|
||||
path.join(__dirname, '../../../../../assets/field-meta.pdf'),
|
||||
);
|
||||
const fieldMetaPdf = fs.readFileSync(path.join(__dirname, '../../../../../assets/field-meta.pdf'));
|
||||
|
||||
const formData = new FormData();
|
||||
|
||||
@@ -382,10 +358,7 @@ test.describe('API V2 Envelopes', () => {
|
||||
);
|
||||
|
||||
// Only add one file for now.
|
||||
formData.append(
|
||||
'files',
|
||||
new File([alignmentPdf], 'field-font-alignment.pdf', { type: 'application/pdf' }),
|
||||
);
|
||||
formData.append('files', new File([alignmentPdf], 'field-font-alignment.pdf', { type: 'application/pdf' }));
|
||||
|
||||
const createEnvelopeRequest = await request.post(`${baseUrl}/envelope/create`, {
|
||||
headers: { Authorization: `Bearer ${tokenA}` },
|
||||
@@ -418,10 +391,7 @@ test.describe('API V2 Envelopes', () => {
|
||||
|
||||
const createEnvelopeItemFormData = new FormData();
|
||||
createEnvelopeItemFormData.append('payload', JSON.stringify(createEnvelopeItemsPayload));
|
||||
createEnvelopeItemFormData.append(
|
||||
'files',
|
||||
new File([fieldMetaPdf], 'field-meta.pdf', { type: 'application/pdf' }),
|
||||
);
|
||||
createEnvelopeItemFormData.append('files', new File([fieldMetaPdf], 'field-meta.pdf', { type: 'application/pdf' }));
|
||||
|
||||
const createItemsRes = await request.post(`${baseUrl}/envelope/item/create-many`, {
|
||||
headers: { Authorization: `Bearer ${tokenA}` },
|
||||
@@ -481,12 +451,8 @@ test.describe('API V2 Envelopes', () => {
|
||||
const envelopeResponse = (await getRes.json()) as TGetEnvelopeResponse;
|
||||
|
||||
const recipientId = envelopeResponse.recipients[0].id;
|
||||
const alignmentItem = envelopeResponse.envelopeItems.find(
|
||||
(item: { order: number }) => item.order === 1,
|
||||
);
|
||||
const fieldMetaItem = envelopeResponse.envelopeItems.find(
|
||||
(item: { order: number }) => item.order === 2,
|
||||
);
|
||||
const alignmentItem = envelopeResponse.envelopeItems.find((item: { order: number }) => item.order === 1);
|
||||
const fieldMetaItem = envelopeResponse.envelopeItems.find((item: { order: number }) => item.order === 2);
|
||||
|
||||
expect(recipientId).toBeDefined();
|
||||
expect(alignmentItem).toBeDefined();
|
||||
@@ -555,9 +521,7 @@ test.describe('API V2 Envelopes', () => {
|
||||
// Verify structure
|
||||
expect(finalEnvelope.envelopeItems.length).toBe(2);
|
||||
expect(finalEnvelope.recipients.length).toBe(1);
|
||||
expect(finalEnvelope.fields.length).toBe(
|
||||
ALIGNMENT_TEST_FIELDS.length + FIELD_META_TEST_FIELDS.length,
|
||||
);
|
||||
expect(finalEnvelope.fields.length).toBe(ALIGNMENT_TEST_FIELDS.length + FIELD_META_TEST_FIELDS.length);
|
||||
expect(finalEnvelope.title).toBe('Envelope Full Field Test');
|
||||
expect(finalEnvelope.type).toBe(EnvelopeType.DOCUMENT);
|
||||
|
||||
@@ -568,17 +532,11 @@ test.describe('API V2 Envelopes', () => {
|
||||
});
|
||||
|
||||
test.describe('Envelope find endpoint', () => {
|
||||
const createEnvelope = async (
|
||||
request: APIRequestContext,
|
||||
token: string,
|
||||
payload: TCreateEnvelopePayload,
|
||||
) => {
|
||||
const createEnvelope = async (request: APIRequestContext, token: string, payload: TCreateEnvelopePayload) => {
|
||||
const formData = new FormData();
|
||||
formData.append('payload', JSON.stringify(payload));
|
||||
|
||||
const pdfData = fs.readFileSync(
|
||||
path.join(__dirname, '../../../../../assets/field-font-alignment.pdf'),
|
||||
);
|
||||
const pdfData = fs.readFileSync(path.join(__dirname, '../../../../../assets/field-font-alignment.pdf'));
|
||||
formData.append('files', new File([pdfData], 'test.pdf', { type: 'application/pdf' }));
|
||||
|
||||
const res = await request.post(`${baseUrl}/envelope/create`, {
|
||||
@@ -1199,9 +1157,7 @@ test.describe('API V2 Envelopes', () => {
|
||||
expect(distributeResponse.recipients[1].signingUrl).toBeTruthy();
|
||||
});
|
||||
|
||||
test('Distribute envelope with empty email recipient and auth requirements fails', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('Distribute envelope with empty email recipient and auth requirements fails', async ({ request }) => {
|
||||
const payload = {
|
||||
type: EnvelopeType.DOCUMENT,
|
||||
title: 'Document with Auth Requirements',
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
import { expect, test } from '@playwright/test';
|
||||
import type { Team, User } from '@prisma/client';
|
||||
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import { createApiToken } from '@documenso/lib/server-only/public-api/create-api-token';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
@@ -15,6 +12,8 @@ import {
|
||||
import { seedTeam, seedTeamEmail, seedTeamMember } from '@documenso/prisma/seed/teams';
|
||||
import { seedUser } from '@documenso/prisma/seed/users';
|
||||
import type { TFindDocumentsResponse } from '@documenso/trpc/server/document-router/find-documents.types';
|
||||
import { expect, test } from '@playwright/test';
|
||||
import type { Team, User } from '@prisma/client';
|
||||
|
||||
import { apiSignin } from '../../fixtures/authentication';
|
||||
|
||||
@@ -78,9 +77,7 @@ test.describe('Find Documents API - Personal Context', () => {
|
||||
expect(json!.totalPages).toBe(0);
|
||||
});
|
||||
|
||||
test('should return only documents owned by the user and not the other user', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should return only documents owned by the user and not the other user', async ({ request }) => {
|
||||
// The v2 API token scopes to a team. A personal team token only returns
|
||||
// docs belonging to that team — cross-team received docs are NOT included.
|
||||
await seedDraftDocument(userA, teamA.id, [], {
|
||||
@@ -287,9 +284,7 @@ test.describe('Find Documents API - Personal Context', () => {
|
||||
expect(json!.data[0].title).toBe('Quarterly Report 2024');
|
||||
});
|
||||
|
||||
test('should search by recipient email and not return docs with different recipients', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should search by recipient email and not return docs with different recipients', async ({ request }) => {
|
||||
const { user: userC } = await seedUser();
|
||||
|
||||
await seedPendingDocument(userA, teamA.id, [userB], {
|
||||
@@ -404,9 +399,7 @@ test.describe('Find Documents API - Personal Context', () => {
|
||||
}
|
||||
});
|
||||
|
||||
test('should only show root-level documents when no folderId is provided', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should only show root-level documents when no folderId is provided', async ({ request }) => {
|
||||
const folder = await prisma.folder.create({
|
||||
data: {
|
||||
name: 'Test Folder',
|
||||
@@ -499,9 +492,7 @@ test.describe('Find Documents API - Personal Context', () => {
|
||||
expect(doc.recipients[0].email).toBe(userB.email);
|
||||
});
|
||||
|
||||
test('should not return deleted documents but should return non-deleted ones', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should not return deleted documents but should return non-deleted ones', async ({ request }) => {
|
||||
const deletedDoc = await seedDraftDocument(userA, teamA.id, [], {
|
||||
createDocumentOptions: { title: 'Deleted Document' },
|
||||
});
|
||||
@@ -562,9 +553,7 @@ test.describe('Find Documents API - Personal Context', () => {
|
||||
});
|
||||
|
||||
test.describe('Find Documents API - Team Context', () => {
|
||||
test('should return team documents for team members and exclude non-team docs', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should return team documents for team members and exclude non-team docs', async ({ request }) => {
|
||||
const { team, owner } = await seedTeam();
|
||||
|
||||
const member = await seedTeamMember({ teamId: team.id, role: TeamMemberRole.ADMIN });
|
||||
@@ -723,9 +712,7 @@ test.describe('Find Documents API - Team Context', () => {
|
||||
expect(json!.count).toBe(2);
|
||||
});
|
||||
|
||||
test('should enforce visibility across admin and manager levels with adequate data', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should enforce visibility across admin and manager levels with adequate data', async ({ request }) => {
|
||||
// Note: MEMBER role cannot create API tokens (requires MANAGE_TEAM permission).
|
||||
// MEMBER visibility is tested in the UI test file instead.
|
||||
const { team, owner } = await seedTeam();
|
||||
@@ -978,9 +965,7 @@ test.describe('Find Documents API - Team with Team Email', () => {
|
||||
expect(titles).not.toContain('External Noise Doc');
|
||||
});
|
||||
|
||||
test('team email documents should respect visibility rules with adequate controls', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('team email documents should respect visibility rules with adequate controls', async ({ request }) => {
|
||||
const { team } = await seedTeam();
|
||||
|
||||
const teamEmail = `team-vis-email-${team.id}@test.documenso.com`;
|
||||
@@ -1033,9 +1018,7 @@ test.describe('Find Documents API - Team with Team Email', () => {
|
||||
});
|
||||
|
||||
test.describe('Find Documents API - Deleted Document Handling', () => {
|
||||
test('should not show soft-deleted documents for owner but show non-deleted ones', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should not show soft-deleted documents for owner but show non-deleted ones', async ({ request }) => {
|
||||
const { user, team } = await seedUser();
|
||||
|
||||
const deletedDoc = await seedPendingDocument(user, team.id, [], {
|
||||
@@ -1068,9 +1051,7 @@ test.describe('Find Documents API - Deleted Document Handling', () => {
|
||||
expect(titles).not.toContain('Soft Deleted by Owner');
|
||||
});
|
||||
|
||||
test('should not show documents where owner soft-deleted their copy in personal context', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should not show documents where owner soft-deleted their copy in personal context', async ({ request }) => {
|
||||
// In personal context, documentDeletedAt on recipient hides the doc for that user.
|
||||
// Note: the v2 API scopes to a team, so we test this by having the owner
|
||||
// soft-delete a doc from their own personal team.
|
||||
@@ -1102,9 +1083,7 @@ test.describe('Find Documents API - Deleted Document Handling', () => {
|
||||
expect(titles).not.toContain('Owner Soft Deleted');
|
||||
});
|
||||
|
||||
test('should not show deleted team documents for any team member but show non-deleted ones', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should not show deleted team documents for any team member but show non-deleted ones', async ({ request }) => {
|
||||
const { team, owner } = await seedTeam();
|
||||
const member = await seedTeamMember({ teamId: team.id, role: TeamMemberRole.ADMIN });
|
||||
|
||||
@@ -1198,9 +1177,7 @@ test.describe('Find Documents API - Edge Cases', () => {
|
||||
expect(res.ok()).toBeFalsy();
|
||||
});
|
||||
|
||||
test('personal documents should not appear in team context even with adequate team data', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('personal documents should not appear in team context even with adequate team data', async ({ request }) => {
|
||||
const { team, owner } = await seedTeam();
|
||||
|
||||
const teamMember = await seedTeamMember({
|
||||
@@ -1276,9 +1253,7 @@ const trpcQuery = async (
|
||||
};
|
||||
|
||||
test.describe('Find Documents API - Adversarial: x-team-id Header Spoofing', () => {
|
||||
test('should reject request when user spoofs x-team-id to a team they do not belong to', async ({
|
||||
page,
|
||||
}) => {
|
||||
test('should reject request when user spoofs x-team-id to a team they do not belong to', async ({ page }) => {
|
||||
// Setup: two separate teams with documents
|
||||
const { team: teamA, owner: ownerA } = await seedTeam();
|
||||
const { team: teamB, owner: ownerB } = await seedTeam();
|
||||
@@ -1365,9 +1340,7 @@ test.describe('Find Documents API - Adversarial: x-team-id Header Spoofing', ()
|
||||
});
|
||||
|
||||
test.describe('Find Documents API - Adversarial: Cross-Team folderId', () => {
|
||||
test('should NOT return documents from another team when folderId belongs to that team', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should NOT return documents from another team when folderId belongs to that team', async ({ request }) => {
|
||||
// Setup: two teams each with a folder and documents
|
||||
const { user: userA, team: teamA } = await seedUser();
|
||||
const { user: userB, team: teamB } = await seedUser();
|
||||
@@ -1452,9 +1425,7 @@ test.describe('Find Documents API - Adversarial: Cross-Team folderId', () => {
|
||||
});
|
||||
|
||||
test.describe('Find Documents API - Adversarial: Cross-Team senderIds', () => {
|
||||
test('should NOT return documents when senderIds contains users from another team', async ({
|
||||
page,
|
||||
}) => {
|
||||
test('should NOT return documents when senderIds contains users from another team', async ({ page }) => {
|
||||
const { team: teamA, owner: ownerA } = await seedTeam();
|
||||
const { team: teamB, owner: ownerB } = await seedTeam();
|
||||
|
||||
@@ -1495,9 +1466,7 @@ test.describe('Find Documents API - Adversarial: Cross-Team senderIds', () => {
|
||||
expect(docs2[0].title).toBe('TeamA Doc by OwnerA');
|
||||
});
|
||||
|
||||
test('senderIds with mix of valid and cross-team userIds should only return matching team docs', async ({
|
||||
page,
|
||||
}) => {
|
||||
test('senderIds with mix of valid and cross-team userIds should only return matching team docs', async ({ page }) => {
|
||||
const { team, owner } = await seedTeam();
|
||||
const member = await seedTeamMember({ teamId: team.id, role: TeamMemberRole.ADMIN });
|
||||
const { user: outsider } = await seedUser();
|
||||
@@ -1542,9 +1511,7 @@ test.describe('Find Documents API - Adversarial: Cross-Team senderIds', () => {
|
||||
});
|
||||
|
||||
test.describe('Find Documents API - Adversarial: Cross-Team templateId', () => {
|
||||
test('should NOT return documents from another team when filtering by their templateId', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should NOT return documents from another team when filtering by their templateId', async ({ request }) => {
|
||||
const { user: userA, team: teamA } = await seedUser();
|
||||
const { user: userB, team: teamB } = await seedUser();
|
||||
|
||||
|
||||
@@ -1,15 +1,7 @@
|
||||
import { expect, test } from '@playwright/test';
|
||||
import type { Team, User } from '@prisma/client';
|
||||
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import { createApiToken } from '@documenso/lib/server-only/public-api/create-api-token';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import {
|
||||
DocumentStatus,
|
||||
DocumentVisibility,
|
||||
EnvelopeType,
|
||||
TeamMemberRole,
|
||||
} from '@documenso/prisma/client';
|
||||
import { DocumentStatus, DocumentVisibility, EnvelopeType, TeamMemberRole } from '@documenso/prisma/client';
|
||||
import {
|
||||
seedBlankDocument,
|
||||
seedCompletedDocument,
|
||||
@@ -19,6 +11,8 @@ import {
|
||||
import { seedTeam, seedTeamEmail, seedTeamMember } from '@documenso/prisma/seed/teams';
|
||||
import { seedUser } from '@documenso/prisma/seed/users';
|
||||
import type { TFindEnvelopesResponse } from '@documenso/trpc/server/envelope-router/find-envelopes.types';
|
||||
import { expect, test } from '@playwright/test';
|
||||
import type { Team, User } from '@prisma/client';
|
||||
|
||||
import { apiSignin } from '../../fixtures/authentication';
|
||||
|
||||
@@ -81,9 +75,7 @@ test.describe('Find Envelopes API - Basic', () => {
|
||||
expect(json!.totalPages).toBe(0);
|
||||
});
|
||||
|
||||
test('should return only envelopes owned by the user and not the other user', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should return only envelopes owned by the user and not the other user', async ({ request }) => {
|
||||
await seedDraftDocument(userA, teamA.id, [], {
|
||||
createDocumentOptions: { title: 'UserA Doc' },
|
||||
});
|
||||
@@ -445,9 +437,7 @@ test.describe('Find Envelopes API - Token Masking', () => {
|
||||
test.describe('Find Envelopes API - Team Context', () => {
|
||||
// Regression test: findEnvelopes previously had `{ userId }` as a top-level OR branch with no
|
||||
// teamId constraint, so personal docs leaked into team context. Fixed in the Kysely refactor.
|
||||
test('should return team envelopes for team members and exclude personal docs', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should return team envelopes for team members and exclude personal docs', async ({ request }) => {
|
||||
const { team, owner } = await seedTeam();
|
||||
const member = await seedTeamMember({ teamId: team.id, role: TeamMemberRole.ADMIN });
|
||||
|
||||
@@ -672,9 +662,7 @@ test.describe('Find Envelopes API - Team Context', () => {
|
||||
// ─── Team with Team Email ────────────────────────────────────────────────────
|
||||
|
||||
test.describe('Find Envelopes API - Team Email', () => {
|
||||
test('should include envelopes received by team email from external senders', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should include envelopes received by team email from external senders', async ({ request }) => {
|
||||
const { team, owner } = await seedTeam();
|
||||
const teamEmailAddr = `team-find-env-${team.id}@test.documenso.com`;
|
||||
await seedTeamEmail({ email: teamEmailAddr, teamId: team.id });
|
||||
@@ -711,9 +699,7 @@ test.describe('Find Envelopes API - Team Email', () => {
|
||||
expect(titles).not.toContain('External Noise Doc');
|
||||
});
|
||||
|
||||
test('should NOT include external noise from other teams when team has team email', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should NOT include external noise from other teams when team has team email', async ({ request }) => {
|
||||
const { team: teamA, owner: ownerA } = await seedTeam();
|
||||
const teamEmailAddr = `team-noise-${teamA.id}@test.documenso.com`;
|
||||
await seedTeamEmail({ email: teamEmailAddr, teamId: teamA.id });
|
||||
@@ -809,9 +795,7 @@ const trpcQuery = async (
|
||||
};
|
||||
|
||||
test.describe('Find Envelopes API - Adversarial: x-team-id Header Spoofing', () => {
|
||||
test('should reject request when user spoofs x-team-id to a team they do not belong to', async ({
|
||||
page,
|
||||
}) => {
|
||||
test('should reject request when user spoofs x-team-id to a team they do not belong to', async ({ page }) => {
|
||||
const { team: teamA, owner: ownerA } = await seedTeam();
|
||||
const { team: teamB, owner: ownerB } = await seedTeam();
|
||||
|
||||
@@ -883,9 +867,7 @@ test.describe('Find Envelopes API - Adversarial: x-team-id Header Spoofing', ()
|
||||
});
|
||||
|
||||
test.describe('Find Envelopes API - Adversarial: Cross-Team folderId', () => {
|
||||
test('should NOT return envelopes from another team when folderId belongs to that team', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should NOT return envelopes from another team when folderId belongs to that team', async ({ request }) => {
|
||||
const { user: userA, team: teamA } = await seedUser();
|
||||
const { user: userB, team: teamB } = await seedUser();
|
||||
|
||||
@@ -965,9 +947,7 @@ test.describe('Find Envelopes API - Adversarial: Cross-Team folderId', () => {
|
||||
});
|
||||
|
||||
test.describe('Find Envelopes API - Adversarial: Cross-Team templateId', () => {
|
||||
test('should NOT return envelopes from another team when filtering by their templateId', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should NOT return envelopes from another team when filtering by their templateId', async ({ request }) => {
|
||||
const { user: userA, team: teamA } = await seedUser();
|
||||
const { user: userB, team: teamB } = await seedUser();
|
||||
|
||||
@@ -1007,9 +987,7 @@ test.describe('Find Envelopes API - Adversarial: Cross-Team templateId', () => {
|
||||
// ─── Personal vs Team Isolation ──────────────────────────────────────────────
|
||||
|
||||
test.describe('Find Envelopes API - Cross-User Isolation', () => {
|
||||
test('other users personal envelopes should never appear regardless of context', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('other users personal envelopes should never appear regardless of context', async ({ request }) => {
|
||||
const { team } = await seedTeam();
|
||||
const member = await seedTeamMember({ teamId: team.id, role: TeamMemberRole.ADMIN });
|
||||
const { user: outsider, team: outsiderTeam } = await seedUser();
|
||||
|
||||
@@ -1,23 +1,18 @@
|
||||
import { PDF } from '@libpdf/core';
|
||||
import type { APIRequestContext } from '@playwright/test';
|
||||
import { expect, test } from '@playwright/test';
|
||||
import { DocumentStatus, FieldType, SigningStatus } from '@prisma/client';
|
||||
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import { getFileServerSide } from '@documenso/lib/universal/upload/get-file.server';
|
||||
import { mapSecondaryIdToDocumentId } from '@documenso/lib/utils/envelope';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { PDF } from '@libpdf/core';
|
||||
import type { APIRequestContext } from '@playwright/test';
|
||||
import { expect, test } from '@playwright/test';
|
||||
import { DocumentStatus, FieldType, SigningStatus } from '@prisma/client';
|
||||
|
||||
import { apiSeedDraftDocument, apiSeedPendingDocument } from '../../fixtures/api-seeds';
|
||||
|
||||
const WEBAPP_BASE_URL = NEXT_PUBLIC_WEBAPP_URL();
|
||||
const API_BASE_URL = `${WEBAPP_BASE_URL}/api/v2-beta`;
|
||||
|
||||
const trpcMutation = async (
|
||||
request: APIRequestContext,
|
||||
procedure: string,
|
||||
input: Record<string, unknown>,
|
||||
) => {
|
||||
const trpcMutation = async (request: APIRequestContext, procedure: string, input: Record<string, unknown>) => {
|
||||
const res = await request.post(`${WEBAPP_BASE_URL}/api/trpc/${procedure}`, {
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
@@ -63,9 +58,7 @@ const signAndCompleteRecipient = async ({
|
||||
};
|
||||
|
||||
test.describe('API V2 partial signed PDF downloads', () => {
|
||||
test('returns a PDF with inserted fields, supports ETag, and rejects after completion', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('returns a PDF with inserted fields, supports ETag, and rejects after completion', async ({ request }) => {
|
||||
const { envelope, token, distributeResult } = await apiSeedPendingDocument(request, {
|
||||
recipients: [
|
||||
{ email: 'partial-signer-1@test.documenso.com', name: 'Partial Signer 1' },
|
||||
@@ -118,9 +111,9 @@ test.describe('API V2 partial signed PDF downloads', () => {
|
||||
});
|
||||
|
||||
expect(dbEnvelope.status).toBe(DocumentStatus.PENDING);
|
||||
expect(
|
||||
dbEnvelope.recipients.find((recipient) => recipient.id === recipientOne.id)?.signingStatus,
|
||||
).toBe(SigningStatus.SIGNED);
|
||||
expect(dbEnvelope.recipients.find((recipient) => recipient.id === recipientOne.id)?.signingStatus).toBe(
|
||||
SigningStatus.SIGNED,
|
||||
);
|
||||
}).toPass();
|
||||
|
||||
const downloadUrl = `${API_BASE_URL}/envelope/item/${envelopeItem.id}/download?version=pending`;
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
import { PDF, StandardFonts } from '@libpdf/core';
|
||||
import type { APIRequestContext } from '@playwright/test';
|
||||
import { expect, test } from '@playwright/test';
|
||||
import type { Team, User } from '@prisma/client';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import { createApiToken } from '@documenso/lib/server-only/public-api/create-api-token';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
@@ -16,6 +11,10 @@ import type {
|
||||
} from '@documenso/trpc/server/envelope-router/create-envelope.types';
|
||||
import type { TCreateEnvelopeRecipientsRequest } from '@documenso/trpc/server/envelope-router/envelope-recipients/create-envelope-recipients.types';
|
||||
import type { TGetEnvelopeResponse } from '@documenso/trpc/server/envelope-router/get-envelope.types';
|
||||
import { PDF, StandardFonts } from '@libpdf/core';
|
||||
import type { APIRequestContext } from '@playwright/test';
|
||||
import { expect, test } from '@playwright/test';
|
||||
import type { Team, User } from '@prisma/client';
|
||||
|
||||
const WEBAPP_BASE_URL = NEXT_PUBLIC_WEBAPP_URL();
|
||||
const baseUrl = `${WEBAPP_BASE_URL}/api/v2-beta`;
|
||||
@@ -66,11 +65,7 @@ test.describe('Placeholder-based field creation', () => {
|
||||
return res.json();
|
||||
};
|
||||
|
||||
const createEnvelopeItemsWithPdf = async (
|
||||
request: APIRequestContext,
|
||||
envelopeId: string,
|
||||
pdfFilename: string,
|
||||
) => {
|
||||
const createEnvelopeItemsWithPdf = async (request: APIRequestContext, envelopeId: string, pdfFilename: string) => {
|
||||
const pdfPath = path.join(FIXTURES_DIR, pdfFilename);
|
||||
const pdfData = fs.readFileSync(pdfPath);
|
||||
|
||||
@@ -129,10 +124,7 @@ test.describe('Placeholder-based field creation', () => {
|
||||
expect(res.ok()).toBeTruthy();
|
||||
};
|
||||
|
||||
const getEnvelope = async (
|
||||
request: APIRequestContext,
|
||||
envelopeId: string,
|
||||
): Promise<TGetEnvelopeResponse> => {
|
||||
const getEnvelope = async (request: APIRequestContext, envelopeId: string): Promise<TGetEnvelopeResponse> => {
|
||||
const res = await request.get(`${baseUrl}/envelope/${envelopeId}`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
});
|
||||
@@ -281,9 +273,7 @@ test.describe('Placeholder-based field creation', () => {
|
||||
expect(createFieldsRes.ok()).toBeFalsy();
|
||||
});
|
||||
|
||||
test('should create fields using a mix of coordinate and placeholder positioning', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should create fields using a mix of coordinate and placeholder positioning', async ({ request }) => {
|
||||
const envelope = await createEnvelopeWithPdf(request, 'no-recipient-placeholders.pdf');
|
||||
await addRecipient(request, envelope.id);
|
||||
|
||||
@@ -409,9 +399,7 @@ test.describe('Placeholder-based field creation', () => {
|
||||
expect(uniqueYPositions.size).toBe(3);
|
||||
});
|
||||
|
||||
test('should map placeholder recipients by signing order when adding items', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should map placeholder recipients by signing order when adding items', async ({ request }) => {
|
||||
const envelope = await createEnvelopeWithPdf(request, 'no-recipient-placeholders.pdf');
|
||||
|
||||
await addRecipients(request, envelope.id, [
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { expect, test } from '@playwright/test';
|
||||
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import { createApiToken } from '@documenso/lib/server-only/public-api/create-api-token';
|
||||
import type { TCheckboxFieldMeta, TRadioFieldMeta } from '@documenso/lib/types/field-meta';
|
||||
@@ -12,16 +10,14 @@ import { prisma } from '@documenso/prisma';
|
||||
import { FieldType, RecipientRole } from '@documenso/prisma/client';
|
||||
import { seedBlankTemplate } from '@documenso/prisma/seed/templates';
|
||||
import { seedUser } from '@documenso/prisma/seed/users';
|
||||
import { expect, test } from '@playwright/test';
|
||||
|
||||
import { apiSignin } from '../../fixtures/authentication';
|
||||
|
||||
const WEBAPP_BASE_URL = NEXT_PUBLIC_WEBAPP_URL();
|
||||
|
||||
test.describe('Template Field Prefill API v2', () => {
|
||||
test('should create a document from template with prefilled fields', async ({
|
||||
page,
|
||||
request,
|
||||
}) => {
|
||||
test('should create a document from template with prefilled fields', async ({ page, request }) => {
|
||||
// 1. Create a user
|
||||
const { user, team } = await seedUser();
|
||||
|
||||
@@ -196,9 +192,7 @@ test.describe('Template Field Prefill API v2', () => {
|
||||
});
|
||||
|
||||
// 7. Navigate to the template
|
||||
await page.goto(
|
||||
`${WEBAPP_BASE_URL}/t/${team.url}/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}`,
|
||||
);
|
||||
await page.goto(`${WEBAPP_BASE_URL}/t/${team.url}/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}`);
|
||||
|
||||
// 8. Create a document from the template with prefilled fields using v2 API
|
||||
const response = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/template/use`, {
|
||||
@@ -378,10 +372,7 @@ test.describe('Template Field Prefill API v2', () => {
|
||||
await expect(page.getByText('Select B')).toBeVisible();
|
||||
});
|
||||
|
||||
test('should create a document from template without prefilled fields', async ({
|
||||
page,
|
||||
request,
|
||||
}) => {
|
||||
test('should create a document from template without prefilled fields', async ({ page, request }) => {
|
||||
// 1. Create a user
|
||||
const { user, team } = await seedUser();
|
||||
|
||||
@@ -484,9 +475,7 @@ test.describe('Template Field Prefill API v2', () => {
|
||||
});
|
||||
|
||||
// 7. Navigate to the template
|
||||
await page.goto(
|
||||
`${WEBAPP_BASE_URL}/t/${team.url}/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}`,
|
||||
);
|
||||
await page.goto(`${WEBAPP_BASE_URL}/t/${team.url}/templates/${mapSecondaryIdToTemplateId(template.secondaryId)}`);
|
||||
|
||||
// 8. Create a document from the template without prefilled fields using v2 API
|
||||
const response = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/template/use`, {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+16
-39
@@ -1,11 +1,10 @@
|
||||
import { expect, test } from '@playwright/test';
|
||||
import type { Team, User } from '@prisma/client';
|
||||
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import { createApiToken } from '@documenso/lib/server-only/public-api/create-api-token';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { seedBlankDocument } from '@documenso/prisma/seed/documents';
|
||||
import { seedUser } from '@documenso/prisma/seed/users';
|
||||
import { expect, test } from '@playwright/test';
|
||||
import type { Team, User } from '@prisma/client';
|
||||
|
||||
const WEBAPP_BASE_URL = NEXT_PUBLIC_WEBAPP_URL();
|
||||
|
||||
@@ -35,33 +34,23 @@ test.describe('Envelope Attachments API V2', () => {
|
||||
});
|
||||
|
||||
test.describe('Envelope attachment find endpoint', () => {
|
||||
test('should block unauthorized access to envelope attachment find endpoint', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should block unauthorized access to envelope attachment find endpoint', async ({ request }) => {
|
||||
const doc = await seedBlankDocument(userA, teamA.id);
|
||||
|
||||
const res = await request.get(
|
||||
`${WEBAPP_BASE_URL}/api/v2-beta/envelope/attachment?envelopeId=${doc.id}`,
|
||||
{
|
||||
headers: { Authorization: `Bearer ${tokenB}` },
|
||||
},
|
||||
);
|
||||
const res = await request.get(`${WEBAPP_BASE_URL}/api/v2-beta/envelope/attachment?envelopeId=${doc.id}`, {
|
||||
headers: { Authorization: `Bearer ${tokenB}` },
|
||||
});
|
||||
|
||||
expect(res.ok()).toBeFalsy();
|
||||
expect(res.status()).toBe(404);
|
||||
});
|
||||
|
||||
test('should allow authorized access to envelope attachment find endpoint', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should allow authorized access to envelope attachment find endpoint', async ({ request }) => {
|
||||
const doc = await seedBlankDocument(userA, teamA.id);
|
||||
|
||||
const res = await request.get(
|
||||
`${WEBAPP_BASE_URL}/api/v2-beta/envelope/attachment?envelopeId=${doc.id}`,
|
||||
{
|
||||
headers: { Authorization: `Bearer ${tokenA}` },
|
||||
},
|
||||
);
|
||||
const res = await request.get(`${WEBAPP_BASE_URL}/api/v2-beta/envelope/attachment?envelopeId=${doc.id}`, {
|
||||
headers: { Authorization: `Bearer ${tokenA}` },
|
||||
});
|
||||
|
||||
expect(res.ok()).toBeTruthy();
|
||||
expect(res.status()).toBe(200);
|
||||
@@ -69,9 +58,7 @@ test.describe('Envelope Attachments API V2', () => {
|
||||
});
|
||||
|
||||
test.describe('Envelope attachment create endpoint', () => {
|
||||
test('should block unauthorized access to envelope attachment create endpoint', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should block unauthorized access to envelope attachment create endpoint', async ({ request }) => {
|
||||
const doc = await seedBlankDocument(userA, teamA.id);
|
||||
|
||||
const res = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/envelope/attachment/create`, {
|
||||
@@ -89,9 +76,7 @@ test.describe('Envelope Attachments API V2', () => {
|
||||
expect(res.status()).toBe(404);
|
||||
});
|
||||
|
||||
test('should allow authorized access to envelope attachment create endpoint', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should allow authorized access to envelope attachment create endpoint', async ({ request }) => {
|
||||
const doc = await seedBlankDocument(userA, teamA.id);
|
||||
|
||||
const res = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/envelope/attachment/create`, {
|
||||
@@ -111,9 +96,7 @@ test.describe('Envelope Attachments API V2', () => {
|
||||
});
|
||||
|
||||
test.describe('Envelope attachment update endpoint', () => {
|
||||
test('should block unauthorized access to envelope attachment update endpoint', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should block unauthorized access to envelope attachment update endpoint', async ({ request }) => {
|
||||
const doc = await seedBlankDocument(userA, teamA.id);
|
||||
|
||||
const attachment = await prisma.envelopeAttachment.create({
|
||||
@@ -140,9 +123,7 @@ test.describe('Envelope Attachments API V2', () => {
|
||||
expect(res.status()).toBe(404);
|
||||
});
|
||||
|
||||
test('should allow authorized access to envelope attachment update endpoint', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should allow authorized access to envelope attachment update endpoint', async ({ request }) => {
|
||||
const doc = await seedBlankDocument(userA, teamA.id);
|
||||
|
||||
const attachment = await prisma.envelopeAttachment.create({
|
||||
@@ -171,9 +152,7 @@ test.describe('Envelope Attachments API V2', () => {
|
||||
});
|
||||
|
||||
test.describe('Envelope attachment delete endpoint', () => {
|
||||
test('should block unauthorized access to envelope attachment delete endpoint', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should block unauthorized access to envelope attachment delete endpoint', async ({ request }) => {
|
||||
const doc = await seedBlankDocument(userA, teamA.id);
|
||||
|
||||
const attachment = await prisma.envelopeAttachment.create({
|
||||
@@ -194,9 +173,7 @@ test.describe('Envelope Attachments API V2', () => {
|
||||
expect(res.status()).toBe(404);
|
||||
});
|
||||
|
||||
test('should allow authorized access to envelope attachment delete endpoint', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should allow authorized access to envelope attachment delete endpoint', async ({ request }) => {
|
||||
const doc = await seedBlankDocument(userA, teamA.id);
|
||||
|
||||
const attachment = await prisma.envelopeAttachment.create({
|
||||
|
||||
+337
-347
@@ -1,13 +1,12 @@
|
||||
import { expect, test } from '@playwright/test';
|
||||
import type { Team, User } from '@prisma/client';
|
||||
import { EnvelopeType, FolderType } from '@prisma/client';
|
||||
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import { createApiToken } from '@documenso/lib/server-only/public-api/create-api-token';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { seedBlankDocument } from '@documenso/prisma/seed/documents';
|
||||
import { seedBlankFolder } from '@documenso/prisma/seed/folders';
|
||||
import { seedUser } from '@documenso/prisma/seed/users';
|
||||
import { expect, test } from '@playwright/test';
|
||||
import type { Team, User } from '@prisma/client';
|
||||
import { EnvelopeType, FolderType } from '@prisma/client';
|
||||
|
||||
const WEBAPP_BASE_URL = NEXT_PUBLIC_WEBAPP_URL();
|
||||
|
||||
@@ -16,375 +15,366 @@ test.describe.configure({
|
||||
});
|
||||
|
||||
// Todo: Remove skip once the API endpoints are released.
|
||||
test.describe.skip('Envelope Bulk API V2', () => {
|
||||
let userA: User, teamA: Team, userB: User, teamB: Team, tokenA: string, tokenB: string;
|
||||
test.describe
|
||||
.skip('Envelope Bulk API V2', () => {
|
||||
let userA: User, teamA: Team, userB: User, teamB: Team, tokenA: string, tokenB: string;
|
||||
|
||||
test.beforeEach(async () => {
|
||||
({ user: userA, team: teamA } = await seedUser());
|
||||
({ token: tokenA } = await createApiToken({
|
||||
userId: userA.id,
|
||||
teamId: teamA.id,
|
||||
tokenName: 'userA',
|
||||
expiresIn: null,
|
||||
}));
|
||||
test.beforeEach(async () => {
|
||||
({ user: userA, team: teamA } = await seedUser());
|
||||
({ token: tokenA } = await createApiToken({
|
||||
userId: userA.id,
|
||||
teamId: teamA.id,
|
||||
tokenName: 'userA',
|
||||
expiresIn: null,
|
||||
}));
|
||||
|
||||
({ user: userB, team: teamB } = await seedUser());
|
||||
({ token: tokenB } = await createApiToken({
|
||||
userId: userB.id,
|
||||
teamId: teamB.id,
|
||||
tokenName: 'userB',
|
||||
expiresIn: null,
|
||||
}));
|
||||
});
|
||||
|
||||
test.describe('Envelope bulk move endpoint', () => {
|
||||
test('should block unauthorized access to envelope bulk move endpoint', async ({ request }) => {
|
||||
// Create a document owned by userA
|
||||
const doc = await seedBlankDocument(userA, teamA.id);
|
||||
|
||||
// UserB tries to move userA's document
|
||||
const res = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/envelope/bulk/move`, {
|
||||
headers: { Authorization: `Bearer ${tokenB}` },
|
||||
data: {
|
||||
envelopeIds: [doc.id],
|
||||
envelopeType: EnvelopeType.DOCUMENT,
|
||||
folderId: null,
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.ok()).toBeTruthy();
|
||||
expect(res.status()).toBe(200);
|
||||
|
||||
const body = await res.json();
|
||||
expect(body.movedCount).toBe(0);
|
||||
|
||||
// Verify in database that the document was not modified
|
||||
const docInDb = await prisma.envelope.findFirst({
|
||||
where: { id: doc.id },
|
||||
});
|
||||
|
||||
expect(docInDb).not.toBeNull();
|
||||
expect(docInDb?.folderId).toBeNull();
|
||||
({ user: userB, team: teamB } = await seedUser());
|
||||
({ token: tokenB } = await createApiToken({
|
||||
userId: userB.id,
|
||||
teamId: teamB.id,
|
||||
tokenName: 'userB',
|
||||
expiresIn: null,
|
||||
}));
|
||||
});
|
||||
|
||||
test('should block moving envelopes to unauthorized folder', async ({ request }) => {
|
||||
// Create a document owned by userB
|
||||
const doc = await seedBlankDocument(userB, teamB.id);
|
||||
test.describe('Envelope bulk move endpoint', () => {
|
||||
test('should block unauthorized access to envelope bulk move endpoint', async ({ request }) => {
|
||||
// Create a document owned by userA
|
||||
const doc = await seedBlankDocument(userA, teamA.id);
|
||||
|
||||
// Create a folder owned by userA
|
||||
const folderA = await seedBlankFolder(userA, teamA.id, {
|
||||
createFolderOptions: {
|
||||
name: 'UserA Folder',
|
||||
type: FolderType.DOCUMENT,
|
||||
},
|
||||
// UserB tries to move userA's document
|
||||
const res = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/envelope/bulk/move`, {
|
||||
headers: { Authorization: `Bearer ${tokenB}` },
|
||||
data: {
|
||||
envelopeIds: [doc.id],
|
||||
envelopeType: EnvelopeType.DOCUMENT,
|
||||
folderId: null,
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.ok()).toBeTruthy();
|
||||
expect(res.status()).toBe(200);
|
||||
|
||||
const body = await res.json();
|
||||
expect(body.movedCount).toBe(0);
|
||||
|
||||
// Verify in database that the document was not modified
|
||||
const docInDb = await prisma.envelope.findFirst({
|
||||
where: { id: doc.id },
|
||||
});
|
||||
|
||||
expect(docInDb).not.toBeNull();
|
||||
expect(docInDb?.folderId).toBeNull();
|
||||
});
|
||||
|
||||
// UserB tries to move their document to userA's folder
|
||||
const res = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/envelope/bulk/move`, {
|
||||
headers: { Authorization: `Bearer ${tokenB}` },
|
||||
data: {
|
||||
envelopeIds: [doc.id],
|
||||
envelopeType: EnvelopeType.DOCUMENT,
|
||||
folderId: folderA.id,
|
||||
},
|
||||
test('should block moving envelopes to unauthorized folder', async ({ request }) => {
|
||||
// Create a document owned by userB
|
||||
const doc = await seedBlankDocument(userB, teamB.id);
|
||||
|
||||
// Create a folder owned by userA
|
||||
const folderA = await seedBlankFolder(userA, teamA.id, {
|
||||
createFolderOptions: {
|
||||
name: 'UserA Folder',
|
||||
type: FolderType.DOCUMENT,
|
||||
},
|
||||
});
|
||||
|
||||
// UserB tries to move their document to userA's folder
|
||||
const res = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/envelope/bulk/move`, {
|
||||
headers: { Authorization: `Bearer ${tokenB}` },
|
||||
data: {
|
||||
envelopeIds: [doc.id],
|
||||
envelopeType: EnvelopeType.DOCUMENT,
|
||||
folderId: folderA.id,
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.ok()).toBeFalsy();
|
||||
expect(res.status()).toBe(404);
|
||||
|
||||
// Verify in database that the document was not modified
|
||||
const docInDb = await prisma.envelope.findFirst({
|
||||
where: { id: doc.id },
|
||||
});
|
||||
|
||||
expect(docInDb).not.toBeNull();
|
||||
expect(docInDb?.folderId).toBeNull();
|
||||
});
|
||||
|
||||
expect(res.ok()).toBeFalsy();
|
||||
expect(res.status()).toBe(404);
|
||||
test('should allow authorized access to envelope bulk move endpoint', async ({ request }) => {
|
||||
// Create a document owned by userA
|
||||
const doc = await seedBlankDocument(userA, teamA.id);
|
||||
|
||||
// Verify in database that the document was not modified
|
||||
const docInDb = await prisma.envelope.findFirst({
|
||||
where: { id: doc.id },
|
||||
// Create a folder owned by userA
|
||||
const folderA = await seedBlankFolder(userA, teamA.id, {
|
||||
createFolderOptions: {
|
||||
name: 'UserA Folder',
|
||||
type: FolderType.DOCUMENT,
|
||||
},
|
||||
});
|
||||
|
||||
// UserA moves their own document to their own folder
|
||||
const res = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/envelope/bulk/move`, {
|
||||
headers: { Authorization: `Bearer ${tokenA}` },
|
||||
data: {
|
||||
envelopeIds: [doc.id],
|
||||
envelopeType: EnvelopeType.DOCUMENT,
|
||||
folderId: folderA.id,
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.ok()).toBeTruthy();
|
||||
expect(res.status()).toBe(200);
|
||||
|
||||
const body = await res.json();
|
||||
expect(body.movedCount).toBe(1);
|
||||
|
||||
// Verify in database that the document was moved to the folder
|
||||
const docInDb = await prisma.envelope.findFirst({
|
||||
where: { id: doc.id },
|
||||
});
|
||||
|
||||
expect(docInDb).not.toBeNull();
|
||||
expect(docInDb?.folderId).toBe(folderA.id);
|
||||
});
|
||||
|
||||
expect(docInDb).not.toBeNull();
|
||||
expect(docInDb?.folderId).toBeNull();
|
||||
test('should only move authorized envelopes when given mixed array of envelope IDs', async ({ request }) => {
|
||||
// Create documents owned by userA
|
||||
const docA1 = await seedBlankDocument(userA, teamA.id);
|
||||
const docA2 = await seedBlankDocument(userA, teamA.id);
|
||||
|
||||
// Create a document owned by userB
|
||||
const docB = await seedBlankDocument(userB, teamB.id);
|
||||
|
||||
// Create a folder owned by userA
|
||||
const folderA = await seedBlankFolder(userA, teamA.id, {
|
||||
createFolderOptions: {
|
||||
name: 'UserA Folder',
|
||||
type: FolderType.DOCUMENT,
|
||||
},
|
||||
});
|
||||
|
||||
// UserA tries to move a mix of their own documents and userB's document
|
||||
const res = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/envelope/bulk/move`, {
|
||||
headers: { Authorization: `Bearer ${tokenA}` },
|
||||
data: {
|
||||
envelopeIds: [docA1.id, docB.id, docA2.id],
|
||||
envelopeType: EnvelopeType.DOCUMENT,
|
||||
folderId: folderA.id,
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.ok()).toBeTruthy();
|
||||
expect(res.status()).toBe(200);
|
||||
|
||||
const body = await res.json();
|
||||
// Only userA's documents should be moved
|
||||
expect(body.movedCount).toBe(2);
|
||||
|
||||
// Verify userA's documents were moved
|
||||
const docA1InDb = await prisma.envelope.findFirst({
|
||||
where: { id: docA1.id },
|
||||
});
|
||||
expect(docA1InDb).not.toBeNull();
|
||||
expect(docA1InDb?.folderId).toBe(folderA.id);
|
||||
|
||||
const docA2InDb = await prisma.envelope.findFirst({
|
||||
where: { id: docA2.id },
|
||||
});
|
||||
expect(docA2InDb).not.toBeNull();
|
||||
expect(docA2InDb?.folderId).toBe(folderA.id);
|
||||
|
||||
// Verify userB's document was NOT moved
|
||||
const docBInDb = await prisma.envelope.findFirst({
|
||||
where: { id: docB.id },
|
||||
});
|
||||
expect(docBInDb).not.toBeNull();
|
||||
expect(docBInDb?.folderId).toBeNull();
|
||||
});
|
||||
|
||||
test('should move zero envelopes when all envelope IDs in array are unauthorized', async ({ request }) => {
|
||||
// Create documents owned by userB
|
||||
const docB1 = await seedBlankDocument(userB, teamB.id);
|
||||
const docB2 = await seedBlankDocument(userB, teamB.id);
|
||||
|
||||
// Create a folder owned by userA
|
||||
const folderA = await seedBlankFolder(userA, teamA.id, {
|
||||
createFolderOptions: {
|
||||
name: 'UserA Folder',
|
||||
type: FolderType.DOCUMENT,
|
||||
},
|
||||
});
|
||||
|
||||
// UserA tries to move userB's documents
|
||||
const res = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/envelope/bulk/move`, {
|
||||
headers: { Authorization: `Bearer ${tokenA}` },
|
||||
data: {
|
||||
envelopeIds: [docB1.id, docB2.id],
|
||||
envelopeType: EnvelopeType.DOCUMENT,
|
||||
folderId: folderA.id,
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.ok()).toBeTruthy();
|
||||
expect(res.status()).toBe(200);
|
||||
|
||||
const body = await res.json();
|
||||
expect(body.movedCount).toBe(0);
|
||||
|
||||
// Verify userB's documents were NOT moved
|
||||
const docB1InDb = await prisma.envelope.findFirst({
|
||||
where: { id: docB1.id },
|
||||
});
|
||||
expect(docB1InDb).not.toBeNull();
|
||||
expect(docB1InDb?.folderId).toBeNull();
|
||||
|
||||
const docB2InDb = await prisma.envelope.findFirst({
|
||||
where: { id: docB2.id },
|
||||
});
|
||||
expect(docB2InDb).not.toBeNull();
|
||||
expect(docB2InDb?.folderId).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
test('should allow authorized access to envelope bulk move endpoint', async ({ request }) => {
|
||||
// Create a document owned by userA
|
||||
const doc = await seedBlankDocument(userA, teamA.id);
|
||||
test.describe('Envelope bulk delete endpoint', () => {
|
||||
test('should block unauthorized access to envelope bulk delete endpoint', async ({ request }) => {
|
||||
// Create a document owned by userA
|
||||
const doc = await seedBlankDocument(userA, teamA.id);
|
||||
|
||||
// Create a folder owned by userA
|
||||
const folderA = await seedBlankFolder(userA, teamA.id, {
|
||||
createFolderOptions: {
|
||||
name: 'UserA Folder',
|
||||
type: FolderType.DOCUMENT,
|
||||
},
|
||||
// UserB tries to delete userA's document
|
||||
const res = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/envelope/bulk/delete`, {
|
||||
headers: { Authorization: `Bearer ${tokenB}` },
|
||||
data: {
|
||||
envelopeIds: [doc.id],
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.ok()).toBeTruthy();
|
||||
expect(res.status()).toBe(200);
|
||||
|
||||
const body = await res.json();
|
||||
expect(body.deletedCount).toBe(0);
|
||||
// Unauthorized envelope ID should be in failedIds
|
||||
expect(body.failedIds).toEqual([doc.id]);
|
||||
|
||||
// Verify in database that the document still exists
|
||||
const docInDb = await prisma.envelope.findFirst({
|
||||
where: { id: doc.id },
|
||||
});
|
||||
|
||||
expect(docInDb).not.toBeNull();
|
||||
expect(docInDb?.id).toBe(doc.id);
|
||||
expect(docInDb?.deletedAt).toBeNull();
|
||||
});
|
||||
|
||||
// UserA moves their own document to their own folder
|
||||
const res = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/envelope/bulk/move`, {
|
||||
headers: { Authorization: `Bearer ${tokenA}` },
|
||||
data: {
|
||||
envelopeIds: [doc.id],
|
||||
envelopeType: EnvelopeType.DOCUMENT,
|
||||
folderId: folderA.id,
|
||||
},
|
||||
test('should allow authorized access to envelope bulk delete endpoint', async ({ request }) => {
|
||||
// Create a document owned by userA
|
||||
const doc = await seedBlankDocument(userA, teamA.id);
|
||||
|
||||
// UserA deletes their own document
|
||||
const res = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/envelope/bulk/delete`, {
|
||||
headers: { Authorization: `Bearer ${tokenA}` },
|
||||
data: {
|
||||
envelopeIds: [doc.id],
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.ok()).toBeTruthy();
|
||||
expect(res.status()).toBe(200);
|
||||
|
||||
const body = await res.json();
|
||||
expect(body.deletedCount).toBe(1);
|
||||
expect(body.failedIds).toEqual([]);
|
||||
|
||||
// Verify in database that the document no longer exists
|
||||
const docInDb = await prisma.envelope.findFirst({
|
||||
where: { id: doc.id },
|
||||
});
|
||||
|
||||
expect(docInDb).toBeNull();
|
||||
});
|
||||
|
||||
expect(res.ok()).toBeTruthy();
|
||||
expect(res.status()).toBe(200);
|
||||
test('should only delete authorized envelopes when given mixed array of envelope IDs', async ({ request }) => {
|
||||
// Create documents owned by userA
|
||||
const docA1 = await seedBlankDocument(userA, teamA.id);
|
||||
const docA2 = await seedBlankDocument(userA, teamA.id);
|
||||
|
||||
const body = await res.json();
|
||||
expect(body.movedCount).toBe(1);
|
||||
// Create a document owned by userB
|
||||
const docB = await seedBlankDocument(userB, teamB.id);
|
||||
|
||||
// Verify in database that the document was moved to the folder
|
||||
const docInDb = await prisma.envelope.findFirst({
|
||||
where: { id: doc.id },
|
||||
// UserA tries to delete a mix of their own documents and userB's document
|
||||
const res = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/envelope/bulk/delete`, {
|
||||
headers: { Authorization: `Bearer ${tokenA}` },
|
||||
data: {
|
||||
envelopeIds: [docA1.id, docB.id, docA2.id],
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.ok()).toBeTruthy();
|
||||
expect(res.status()).toBe(200);
|
||||
|
||||
const body = await res.json();
|
||||
// Only userA's documents should be deleted
|
||||
expect(body.deletedCount).toBe(2);
|
||||
// Unauthorized envelope ID (docB) should be in failedIds
|
||||
expect(body.failedIds).toEqual([docB.id]);
|
||||
|
||||
// Verify userA's documents were deleted
|
||||
const docA1InDb = await prisma.envelope.findFirst({
|
||||
where: { id: docA1.id },
|
||||
});
|
||||
expect(docA1InDb).toBeNull();
|
||||
|
||||
const docA2InDb = await prisma.envelope.findFirst({
|
||||
where: { id: docA2.id },
|
||||
});
|
||||
expect(docA2InDb).toBeNull();
|
||||
|
||||
// Verify userB's document was NOT deleted
|
||||
const docBInDb = await prisma.envelope.findFirst({
|
||||
where: { id: docB.id },
|
||||
});
|
||||
expect(docBInDb).not.toBeNull();
|
||||
expect(docBInDb?.id).toBe(docB.id);
|
||||
expect(docBInDb?.deletedAt).toBeNull();
|
||||
});
|
||||
|
||||
expect(docInDb).not.toBeNull();
|
||||
expect(docInDb?.folderId).toBe(folderA.id);
|
||||
});
|
||||
test('should delete zero envelopes when all envelope IDs in array are unauthorized', async ({ request }) => {
|
||||
// Create documents owned by userB
|
||||
const docB1 = await seedBlankDocument(userB, teamB.id);
|
||||
const docB2 = await seedBlankDocument(userB, teamB.id);
|
||||
|
||||
test('should only move authorized envelopes when given mixed array of envelope IDs', async ({
|
||||
request,
|
||||
}) => {
|
||||
// Create documents owned by userA
|
||||
const docA1 = await seedBlankDocument(userA, teamA.id);
|
||||
const docA2 = await seedBlankDocument(userA, teamA.id);
|
||||
// UserA tries to delete userB's documents
|
||||
const res = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/envelope/bulk/delete`, {
|
||||
headers: { Authorization: `Bearer ${tokenA}` },
|
||||
data: {
|
||||
envelopeIds: [docB1.id, docB2.id],
|
||||
},
|
||||
});
|
||||
|
||||
// Create a document owned by userB
|
||||
const docB = await seedBlankDocument(userB, teamB.id);
|
||||
expect(res.ok()).toBeTruthy();
|
||||
expect(res.status()).toBe(200);
|
||||
|
||||
// Create a folder owned by userA
|
||||
const folderA = await seedBlankFolder(userA, teamA.id, {
|
||||
createFolderOptions: {
|
||||
name: 'UserA Folder',
|
||||
type: FolderType.DOCUMENT,
|
||||
},
|
||||
const body = await res.json();
|
||||
expect(body.deletedCount).toBe(0);
|
||||
// All unauthorized envelope IDs should be in failedIds
|
||||
expect(body.failedIds).toEqual(expect.arrayContaining([docB1.id, docB2.id]));
|
||||
expect(body.failedIds).toHaveLength(2);
|
||||
|
||||
// Verify userB's documents were NOT deleted
|
||||
const docB1InDb = await prisma.envelope.findFirst({
|
||||
where: { id: docB1.id },
|
||||
});
|
||||
expect(docB1InDb).not.toBeNull();
|
||||
expect(docB1InDb?.id).toBe(docB1.id);
|
||||
expect(docB1InDb?.deletedAt).toBeNull();
|
||||
|
||||
const docB2InDb = await prisma.envelope.findFirst({
|
||||
where: { id: docB2.id },
|
||||
});
|
||||
expect(docB2InDb).not.toBeNull();
|
||||
expect(docB2InDb?.id).toBe(docB2.id);
|
||||
expect(docB2InDb?.deletedAt).toBeNull();
|
||||
});
|
||||
|
||||
// UserA tries to move a mix of their own documents and userB's document
|
||||
const res = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/envelope/bulk/move`, {
|
||||
headers: { Authorization: `Bearer ${tokenA}` },
|
||||
data: {
|
||||
envelopeIds: [docA1.id, docB.id, docA2.id],
|
||||
envelopeType: EnvelopeType.DOCUMENT,
|
||||
folderId: folderA.id,
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.ok()).toBeTruthy();
|
||||
expect(res.status()).toBe(200);
|
||||
|
||||
const body = await res.json();
|
||||
// Only userA's documents should be moved
|
||||
expect(body.movedCount).toBe(2);
|
||||
|
||||
// Verify userA's documents were moved
|
||||
const docA1InDb = await prisma.envelope.findFirst({
|
||||
where: { id: docA1.id },
|
||||
});
|
||||
expect(docA1InDb).not.toBeNull();
|
||||
expect(docA1InDb?.folderId).toBe(folderA.id);
|
||||
|
||||
const docA2InDb = await prisma.envelope.findFirst({
|
||||
where: { id: docA2.id },
|
||||
});
|
||||
expect(docA2InDb).not.toBeNull();
|
||||
expect(docA2InDb?.folderId).toBe(folderA.id);
|
||||
|
||||
// Verify userB's document was NOT moved
|
||||
const docBInDb = await prisma.envelope.findFirst({
|
||||
where: { id: docB.id },
|
||||
});
|
||||
expect(docBInDb).not.toBeNull();
|
||||
expect(docBInDb?.folderId).toBeNull();
|
||||
});
|
||||
|
||||
test('should move zero envelopes when all envelope IDs in array are unauthorized', async ({
|
||||
request,
|
||||
}) => {
|
||||
// Create documents owned by userB
|
||||
const docB1 = await seedBlankDocument(userB, teamB.id);
|
||||
const docB2 = await seedBlankDocument(userB, teamB.id);
|
||||
|
||||
// Create a folder owned by userA
|
||||
const folderA = await seedBlankFolder(userA, teamA.id, {
|
||||
createFolderOptions: {
|
||||
name: 'UserA Folder',
|
||||
type: FolderType.DOCUMENT,
|
||||
},
|
||||
});
|
||||
|
||||
// UserA tries to move userB's documents
|
||||
const res = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/envelope/bulk/move`, {
|
||||
headers: { Authorization: `Bearer ${tokenA}` },
|
||||
data: {
|
||||
envelopeIds: [docB1.id, docB2.id],
|
||||
envelopeType: EnvelopeType.DOCUMENT,
|
||||
folderId: folderA.id,
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.ok()).toBeTruthy();
|
||||
expect(res.status()).toBe(200);
|
||||
|
||||
const body = await res.json();
|
||||
expect(body.movedCount).toBe(0);
|
||||
|
||||
// Verify userB's documents were NOT moved
|
||||
const docB1InDb = await prisma.envelope.findFirst({
|
||||
where: { id: docB1.id },
|
||||
});
|
||||
expect(docB1InDb).not.toBeNull();
|
||||
expect(docB1InDb?.folderId).toBeNull();
|
||||
|
||||
const docB2InDb = await prisma.envelope.findFirst({
|
||||
where: { id: docB2.id },
|
||||
});
|
||||
expect(docB2InDb).not.toBeNull();
|
||||
expect(docB2InDb?.folderId).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Envelope bulk delete endpoint', () => {
|
||||
test('should block unauthorized access to envelope bulk delete endpoint', async ({
|
||||
request,
|
||||
}) => {
|
||||
// Create a document owned by userA
|
||||
const doc = await seedBlankDocument(userA, teamA.id);
|
||||
|
||||
// UserB tries to delete userA's document
|
||||
const res = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/envelope/bulk/delete`, {
|
||||
headers: { Authorization: `Bearer ${tokenB}` },
|
||||
data: {
|
||||
envelopeIds: [doc.id],
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.ok()).toBeTruthy();
|
||||
expect(res.status()).toBe(200);
|
||||
|
||||
const body = await res.json();
|
||||
expect(body.deletedCount).toBe(0);
|
||||
// Unauthorized envelope ID should be in failedIds
|
||||
expect(body.failedIds).toEqual([doc.id]);
|
||||
|
||||
// Verify in database that the document still exists
|
||||
const docInDb = await prisma.envelope.findFirst({
|
||||
where: { id: doc.id },
|
||||
});
|
||||
|
||||
expect(docInDb).not.toBeNull();
|
||||
expect(docInDb?.id).toBe(doc.id);
|
||||
expect(docInDb?.deletedAt).toBeNull();
|
||||
});
|
||||
|
||||
test('should allow authorized access to envelope bulk delete endpoint', async ({ request }) => {
|
||||
// Create a document owned by userA
|
||||
const doc = await seedBlankDocument(userA, teamA.id);
|
||||
|
||||
// UserA deletes their own document
|
||||
const res = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/envelope/bulk/delete`, {
|
||||
headers: { Authorization: `Bearer ${tokenA}` },
|
||||
data: {
|
||||
envelopeIds: [doc.id],
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.ok()).toBeTruthy();
|
||||
expect(res.status()).toBe(200);
|
||||
|
||||
const body = await res.json();
|
||||
expect(body.deletedCount).toBe(1);
|
||||
expect(body.failedIds).toEqual([]);
|
||||
|
||||
// Verify in database that the document no longer exists
|
||||
const docInDb = await prisma.envelope.findFirst({
|
||||
where: { id: doc.id },
|
||||
});
|
||||
|
||||
expect(docInDb).toBeNull();
|
||||
});
|
||||
|
||||
test('should only delete authorized envelopes when given mixed array of envelope IDs', async ({
|
||||
request,
|
||||
}) => {
|
||||
// Create documents owned by userA
|
||||
const docA1 = await seedBlankDocument(userA, teamA.id);
|
||||
const docA2 = await seedBlankDocument(userA, teamA.id);
|
||||
|
||||
// Create a document owned by userB
|
||||
const docB = await seedBlankDocument(userB, teamB.id);
|
||||
|
||||
// UserA tries to delete a mix of their own documents and userB's document
|
||||
const res = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/envelope/bulk/delete`, {
|
||||
headers: { Authorization: `Bearer ${tokenA}` },
|
||||
data: {
|
||||
envelopeIds: [docA1.id, docB.id, docA2.id],
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.ok()).toBeTruthy();
|
||||
expect(res.status()).toBe(200);
|
||||
|
||||
const body = await res.json();
|
||||
// Only userA's documents should be deleted
|
||||
expect(body.deletedCount).toBe(2);
|
||||
// Unauthorized envelope ID (docB) should be in failedIds
|
||||
expect(body.failedIds).toEqual([docB.id]);
|
||||
|
||||
// Verify userA's documents were deleted
|
||||
const docA1InDb = await prisma.envelope.findFirst({
|
||||
where: { id: docA1.id },
|
||||
});
|
||||
expect(docA1InDb).toBeNull();
|
||||
|
||||
const docA2InDb = await prisma.envelope.findFirst({
|
||||
where: { id: docA2.id },
|
||||
});
|
||||
expect(docA2InDb).toBeNull();
|
||||
|
||||
// Verify userB's document was NOT deleted
|
||||
const docBInDb = await prisma.envelope.findFirst({
|
||||
where: { id: docB.id },
|
||||
});
|
||||
expect(docBInDb).not.toBeNull();
|
||||
expect(docBInDb?.id).toBe(docB.id);
|
||||
expect(docBInDb?.deletedAt).toBeNull();
|
||||
});
|
||||
|
||||
test('should delete zero envelopes when all envelope IDs in array are unauthorized', async ({
|
||||
request,
|
||||
}) => {
|
||||
// Create documents owned by userB
|
||||
const docB1 = await seedBlankDocument(userB, teamB.id);
|
||||
const docB2 = await seedBlankDocument(userB, teamB.id);
|
||||
|
||||
// UserA tries to delete userB's documents
|
||||
const res = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/envelope/bulk/delete`, {
|
||||
headers: { Authorization: `Bearer ${tokenA}` },
|
||||
data: {
|
||||
envelopeIds: [docB1.id, docB2.id],
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.ok()).toBeTruthy();
|
||||
expect(res.status()).toBe(200);
|
||||
|
||||
const body = await res.json();
|
||||
expect(body.deletedCount).toBe(0);
|
||||
// All unauthorized envelope IDs should be in failedIds
|
||||
expect(body.failedIds).toEqual(expect.arrayContaining([docB1.id, docB2.id]));
|
||||
expect(body.failedIds).toHaveLength(2);
|
||||
|
||||
// Verify userB's documents were NOT deleted
|
||||
const docB1InDb = await prisma.envelope.findFirst({
|
||||
where: { id: docB1.id },
|
||||
});
|
||||
expect(docB1InDb).not.toBeNull();
|
||||
expect(docB1InDb?.id).toBe(docB1.id);
|
||||
expect(docB1InDb?.deletedAt).toBeNull();
|
||||
|
||||
const docB2InDb = await prisma.envelope.findFirst({
|
||||
where: { id: docB2.id },
|
||||
});
|
||||
expect(docB2InDb).not.toBeNull();
|
||||
expect(docB2InDb?.id).toBe(docB2.id);
|
||||
expect(docB2InDb?.deletedAt).toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import { type APIRequestContext, expect, test } from '@playwright/test';
|
||||
import type { Team, User } from '@prisma/client';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import { createApiToken } from '@documenso/lib/server-only/public-api/create-api-token';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
@@ -16,6 +13,8 @@ import type { TDistributeEnvelopeRequest } from '@documenso/trpc/server/envelope
|
||||
import type { TCreateEnvelopeRecipientsRequest } from '@documenso/trpc/server/envelope-router/envelope-recipients/create-envelope-recipients.types';
|
||||
import type { TGetEnvelopeResponse } from '@documenso/trpc/server/envelope-router/get-envelope.types';
|
||||
import type { TUpdateEnvelopeItemsRequest } from '@documenso/trpc/server/envelope-router/update-envelope-items.types';
|
||||
import { type APIRequestContext, expect, test } from '@playwright/test';
|
||||
import type { Team, User } from '@prisma/client';
|
||||
|
||||
const WEBAPP_BASE_URL = NEXT_PUBLIC_WEBAPP_URL();
|
||||
const baseUrl = `${WEBAPP_BASE_URL}/api/v2-beta`;
|
||||
@@ -64,11 +63,7 @@ const getEnvelope = async (request: APIRequestContext, authToken: string, envelo
|
||||
* Transition an envelope from DRAFT to PENDING by adding a recipient with a
|
||||
* signature field and distributing.
|
||||
*/
|
||||
const distributeEnvelope = async (
|
||||
request: APIRequestContext,
|
||||
authToken: string,
|
||||
envelopeId: string,
|
||||
) => {
|
||||
const distributeEnvelope = async (request: APIRequestContext, authToken: string, envelopeId: string) => {
|
||||
const recipientEmail = `signer-${Date.now()}@test.documenso.com`;
|
||||
|
||||
// Create a SIGNER recipient.
|
||||
@@ -228,9 +223,7 @@ test.describe('Update envelope items', () => {
|
||||
expect(dbItem.title).toBe('Updated Pending Title');
|
||||
});
|
||||
|
||||
test('should allow title-only update when order matches existing on a PENDING envelope', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should allow title-only update when order matches existing on a PENDING envelope', async ({ request }) => {
|
||||
const envelope = await createEnvelope(request, token);
|
||||
await distributeEnvelope(request, token, envelope.id);
|
||||
|
||||
@@ -318,9 +311,7 @@ test.describe('Update envelope items', () => {
|
||||
expect(res.status()).toBe(400);
|
||||
});
|
||||
|
||||
test('should reject combined title and order change on a PENDING envelope', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should reject combined title and order change on a PENDING envelope', async ({ request }) => {
|
||||
const envelope = await createEnvelope(request, token);
|
||||
await distributeEnvelope(request, token, envelope.id);
|
||||
|
||||
@@ -499,9 +490,7 @@ test.describe('Update envelope items', () => {
|
||||
expect(res.ok()).toBeFalsy();
|
||||
});
|
||||
|
||||
test('should reject update for an envelope item that does not belong to the envelope', async ({
|
||||
request,
|
||||
}) => {
|
||||
test('should reject update for an envelope item that does not belong to the envelope', async ({ request }) => {
|
||||
const envelopeA = await createEnvelope(request, token);
|
||||
const envelopeB = await createEnvelope(request, token);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user