feat: Added platform emails for billing limits and disabled projects
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import {describe, it, expect, beforeEach, vi} from 'vitest';
|
||||
import {beforeEach, describe, expect, it, vi} from 'vitest';
|
||||
import {EmailSourceType, EmailStatus} from '@plunk/db';
|
||||
import {ActionSchemas} from '@plunk/shared';
|
||||
import {EmailService} from '../EmailService';
|
||||
@@ -669,7 +669,6 @@ describe('EmailService', () => {
|
||||
// ========================================
|
||||
describe('Attachment Schema Validation', () => {
|
||||
it('should validate attachment count limit (max 10)', () => {
|
||||
|
||||
const tooManyAttachments = Array.from({length: 11}, (_, i) => ({
|
||||
filename: `file${i}.txt`,
|
||||
content: Buffer.from('content').toString('base64'),
|
||||
@@ -690,7 +689,6 @@ describe('EmailService', () => {
|
||||
});
|
||||
|
||||
it('should validate attachment size limit (10MB total)', () => {
|
||||
|
||||
// Exceeds ~13.3M base64 chars limit
|
||||
const largeContent = 'A'.repeat(14000000);
|
||||
|
||||
@@ -711,11 +709,11 @@ describe('EmailService', () => {
|
||||
});
|
||||
|
||||
it('should accept attachments within size limit', () => {
|
||||
|
||||
const validContent = Buffer.from('Small file content').toString('base64');
|
||||
|
||||
const result = ActionSchemas.send.safeParse({
|
||||
to: 'test@example.com',
|
||||
from: 'test@example.com',
|
||||
subject: 'Test',
|
||||
body: 'Test',
|
||||
attachments: [
|
||||
@@ -731,7 +729,6 @@ describe('EmailService', () => {
|
||||
});
|
||||
|
||||
it('should reject attachment with missing required fields', () => {
|
||||
|
||||
const result = ActionSchemas.send.safeParse({
|
||||
to: 'test@example.com',
|
||||
subject: 'Test',
|
||||
@@ -748,7 +745,6 @@ describe('EmailService', () => {
|
||||
});
|
||||
|
||||
it('should reject attachment with empty filename', () => {
|
||||
|
||||
const result = ActionSchemas.send.safeParse({
|
||||
to: 'test@example.com',
|
||||
subject: 'Test',
|
||||
@@ -766,7 +762,6 @@ describe('EmailService', () => {
|
||||
});
|
||||
|
||||
it('should reject attachment with filename exceeding 255 chars', () => {
|
||||
|
||||
const tooLongFilename = 'a'.repeat(256) + '.pdf';
|
||||
|
||||
const result = ActionSchemas.send.safeParse({
|
||||
@@ -786,18 +781,12 @@ describe('EmailService', () => {
|
||||
});
|
||||
|
||||
it('should accept valid attachment with various content types', () => {
|
||||
|
||||
const contentTypes = [
|
||||
'application/pdf',
|
||||
'image/png',
|
||||
'image/jpeg',
|
||||
'text/plain',
|
||||
'application/zip',
|
||||
];
|
||||
const contentTypes = ['application/pdf', 'image/png', 'image/jpeg', 'text/plain', 'application/zip'];
|
||||
|
||||
for (const contentType of contentTypes) {
|
||||
const result = ActionSchemas.send.safeParse({
|
||||
to: 'test@example.com',
|
||||
from: 'test@example.com',
|
||||
subject: 'Test',
|
||||
body: 'Test',
|
||||
attachments: [
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest';
|
||||
import {WorkflowExecutionStatus, WorkflowTriggerType} from '@plunk/db';
|
||||
import {EventService} from '../EventService';
|
||||
import {Keys} from '../keys';
|
||||
import {factories, getPrismaClient} from '../../../../../test/helpers';
|
||||
|
||||
// Mock Redis for caching tests - must be inline to avoid hoisting issues
|
||||
@@ -503,7 +504,7 @@ describe('EventService', () => {
|
||||
const {redis} = await import('../../database/redis');
|
||||
|
||||
// Set cache
|
||||
const cacheKey = `workflows:enabled:${projectId}`;
|
||||
const cacheKey = Keys.Workflow.enabled(projectId);
|
||||
await redis.set(cacheKey, JSON.stringify([{id: 'test'}]));
|
||||
|
||||
// Verify cache exists
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest';
|
||||
import {WorkflowExecutionStatus, WorkflowStepType, WorkflowTriggerType} from '@plunk/db';
|
||||
import {WorkflowService} from '../WorkflowService';
|
||||
import {Keys} from '../keys';
|
||||
import {factories, getPrismaClient} from '../../../../../test/helpers';
|
||||
|
||||
// Mock Redis for caching tests - must be inline to avoid hoisting issues
|
||||
@@ -130,7 +131,7 @@ describe('WorkflowService', () => {
|
||||
|
||||
it('should invalidate cache when creating enabled workflow', async () => {
|
||||
const {redis} = await import('../../database/redis');
|
||||
const cacheKey = `workflows:enabled:${projectId}`;
|
||||
const cacheKey = Keys.Workflow.enabled(projectId);
|
||||
|
||||
// Set cache
|
||||
await redis.set(cacheKey, JSON.stringify([{id: 'old'}]));
|
||||
@@ -286,7 +287,7 @@ describe('WorkflowService', () => {
|
||||
|
||||
it('should invalidate cache when enabling workflow', async () => {
|
||||
const {redis} = await import('../../database/redis');
|
||||
const cacheKey = `workflows:enabled:${projectId}`;
|
||||
const cacheKey = Keys.Workflow.enabled(projectId);
|
||||
|
||||
const workflow = await factories.createWorkflow({
|
||||
projectId,
|
||||
@@ -326,7 +327,7 @@ describe('WorkflowService', () => {
|
||||
|
||||
it('should invalidate cache when deleting enabled workflow', async () => {
|
||||
const {redis} = await import('../../database/redis');
|
||||
const cacheKey = `workflows:enabled:${projectId}`;
|
||||
const cacheKey = Keys.Workflow.enabled(projectId);
|
||||
|
||||
const workflow = await factories.createWorkflow({
|
||||
projectId,
|
||||
|
||||
Reference in New Issue
Block a user