Skip to main content
Glama
newsletterSchemas.test.js12.2 kB
import { describe, it, expect } from 'vitest'; import { createNewsletterSchema, updateNewsletterSchema, newsletterQuerySchema, newsletterIdSchema, newsletterSlugSchema, newsletterOutputSchema, } from '../newsletterSchemas.js'; describe('Newsletter Schemas', () => { describe('createNewsletterSchema', () => { it('should accept valid newsletter creation data', () => { const validNewsletter = { name: 'Weekly Newsletter', description: 'Our weekly updates', slug: 'weekly-newsletter', }; expect(() => createNewsletterSchema.parse(validNewsletter)).not.toThrow(); }); it('should accept minimal newsletter creation data (name only)', () => { const minimalNewsletter = { name: 'Simple Newsletter', }; const result = createNewsletterSchema.parse(minimalNewsletter); expect(result.name).toBe('Simple Newsletter'); expect(result.sender_reply_to).toBe('newsletter'); // default expect(result.status).toBe('active'); // default expect(result.visibility).toBe('members'); // default expect(result.subscribe_on_signup).toBe(true); // default expect(result.show_header_icon).toBe(true); // default expect(result.show_header_title).toBe(true); // default expect(result.title_font_category).toBe('sans-serif'); // default expect(result.title_alignment).toBe('center'); // default expect(result.show_feature_image).toBe(true); // default expect(result.body_font_category).toBe('sans-serif'); // default expect(result.show_badge).toBe(true); // default }); it('should accept newsletter with all fields', () => { const fullNewsletter = { name: 'Complete Newsletter', description: 'Full description', slug: 'complete-newsletter', sender_name: 'Blog Team', sender_email: 'team@example.com', sender_reply_to: 'support', status: 'archived', visibility: 'paid', subscribe_on_signup: false, sort_order: 5, header_image: 'https://example.com/header.jpg', show_header_icon: false, show_header_title: false, title_font_category: 'serif', title_alignment: 'left', show_feature_image: false, body_font_category: 'serif', footer_content: 'Custom footer', show_badge: false, show_header_name: false, show_post_title_section: false, }; expect(() => createNewsletterSchema.parse(fullNewsletter)).not.toThrow(); }); it('should reject newsletter without name', () => { const invalidNewsletter = { description: 'Missing name', }; expect(() => createNewsletterSchema.parse(invalidNewsletter)).toThrow(); }); it('should reject newsletter with empty name', () => { const invalidNewsletter = { name: '', }; expect(() => createNewsletterSchema.parse(invalidNewsletter)).toThrow(); }); it('should reject newsletter with too long name', () => { const invalidNewsletter = { name: 'A'.repeat(192), }; expect(() => createNewsletterSchema.parse(invalidNewsletter)).toThrow(); }); it('should reject newsletter with too long description', () => { const invalidNewsletter = { name: 'Newsletter', description: 'A'.repeat(2001), }; expect(() => createNewsletterSchema.parse(invalidNewsletter)).toThrow(); }); it('should reject newsletter with invalid slug', () => { const invalidNewsletter = { name: 'Newsletter', slug: 'Invalid_Slug', // uppercase and underscore not allowed }; expect(() => createNewsletterSchema.parse(invalidNewsletter)).toThrow(); }); it('should reject newsletter with too long sender name', () => { const invalidNewsletter = { name: 'Newsletter', sender_name: 'A'.repeat(192), }; expect(() => createNewsletterSchema.parse(invalidNewsletter)).toThrow(); }); it('should reject newsletter with invalid sender email', () => { const invalidNewsletter = { name: 'Newsletter', sender_email: 'not-an-email', }; expect(() => createNewsletterSchema.parse(invalidNewsletter)).toThrow(); }); it('should reject newsletter with invalid sender_reply_to', () => { const invalidNewsletter = { name: 'Newsletter', sender_reply_to: 'invalid', }; expect(() => createNewsletterSchema.parse(invalidNewsletter)).toThrow(); }); it('should reject newsletter with invalid status', () => { const invalidNewsletter = { name: 'Newsletter', status: 'invalid', }; expect(() => createNewsletterSchema.parse(invalidNewsletter)).toThrow(); }); it('should reject newsletter with invalid visibility', () => { const invalidNewsletter = { name: 'Newsletter', visibility: 'public', }; expect(() => createNewsletterSchema.parse(invalidNewsletter)).toThrow(); }); it('should reject newsletter with negative sort_order', () => { const invalidNewsletter = { name: 'Newsletter', sort_order: -1, }; expect(() => createNewsletterSchema.parse(invalidNewsletter)).toThrow(); }); it('should reject newsletter with invalid header_image URL', () => { const invalidNewsletter = { name: 'Newsletter', header_image: 'not-a-url', }; expect(() => createNewsletterSchema.parse(invalidNewsletter)).toThrow(); }); it('should reject newsletter with invalid title_font_category', () => { const invalidNewsletter = { name: 'Newsletter', title_font_category: 'invalid', }; expect(() => createNewsletterSchema.parse(invalidNewsletter)).toThrow(); }); it('should reject newsletter with invalid title_alignment', () => { const invalidNewsletter = { name: 'Newsletter', title_alignment: 'right', }; expect(() => createNewsletterSchema.parse(invalidNewsletter)).toThrow(); }); it('should reject newsletter with invalid body_font_category', () => { const invalidNewsletter = { name: 'Newsletter', body_font_category: 'monospace', }; expect(() => createNewsletterSchema.parse(invalidNewsletter)).toThrow(); }); }); describe('updateNewsletterSchema', () => { it('should accept partial newsletter updates', () => { const update = { description: 'Updated description', }; expect(() => updateNewsletterSchema.parse(update)).not.toThrow(); }); it('should accept empty update object', () => { expect(() => updateNewsletterSchema.parse({})).not.toThrow(); }); it('should accept full newsletter update', () => { const update = { name: 'Updated Newsletter', description: 'Updated description', status: 'archived', visibility: 'paid', }; expect(() => updateNewsletterSchema.parse(update)).not.toThrow(); }); }); describe('newsletterQuerySchema', () => { it('should accept valid query parameters', () => { const query = { limit: 20, page: 2, filter: 'status:active', }; expect(() => newsletterQuerySchema.parse(query)).not.toThrow(); }); it('should accept query with order parameter', () => { const query = { order: 'sort_order ASC', }; expect(() => newsletterQuerySchema.parse(query)).not.toThrow(); }); it('should reject query with invalid filter characters', () => { const query = { filter: 'status;DROP TABLE', }; expect(() => newsletterQuerySchema.parse(query)).toThrow(); }); it('should accept empty query object', () => { const result = newsletterQuerySchema.parse({}); expect(result).toBeDefined(); }); }); describe('newsletterIdSchema', () => { it('should accept valid Ghost ID', () => { const validId = { id: '507f1f77bcf86cd799439011', }; expect(() => newsletterIdSchema.parse(validId)).not.toThrow(); }); it('should reject invalid Ghost ID', () => { const invalidId = { id: 'invalid-id', }; expect(() => newsletterIdSchema.parse(invalidId)).toThrow(); }); }); describe('newsletterSlugSchema', () => { it('should accept valid slug', () => { const validSlug = { slug: 'weekly-newsletter', }; expect(() => newsletterSlugSchema.parse(validSlug)).not.toThrow(); }); it('should reject invalid slug', () => { const invalidSlug = { slug: 'Invalid_Slug', }; expect(() => newsletterSlugSchema.parse(invalidSlug)).toThrow(); }); }); describe('newsletterOutputSchema', () => { it('should accept valid newsletter output from Ghost API', () => { const apiNewsletter = { id: '507f1f77bcf86cd799439011', uuid: '550e8400-e29b-41d4-a716-446655440000', name: 'Weekly Newsletter', description: 'Our weekly updates', slug: 'weekly-newsletter', sender_name: 'Blog Team', sender_email: 'team@example.com', sender_reply_to: 'newsletter', status: 'active', visibility: 'members', subscribe_on_signup: true, sort_order: 0, header_image: 'https://example.com/header.jpg', show_header_icon: true, show_header_title: true, title_font_category: 'sans-serif', title_alignment: 'center', show_feature_image: true, body_font_category: 'sans-serif', footer_content: 'Footer text', show_badge: true, show_header_name: true, show_post_title_section: true, created_at: '2024-01-15T10:30:00.000Z', updated_at: '2024-01-15T10:30:00.000Z', count: { members: 150, posts: 25, }, }; expect(() => newsletterOutputSchema.parse(apiNewsletter)).not.toThrow(); }); it('should accept newsletter with null optional fields', () => { const apiNewsletter = { id: '507f1f77bcf86cd799439011', uuid: '550e8400-e29b-41d4-a716-446655440000', name: 'Newsletter', description: null, slug: 'newsletter', sender_name: null, sender_email: null, sender_reply_to: 'newsletter', status: 'active', visibility: 'members', subscribe_on_signup: true, sort_order: 0, header_image: null, show_header_icon: true, show_header_title: true, title_font_category: 'sans-serif', title_alignment: 'center', show_feature_image: true, body_font_category: 'sans-serif', footer_content: null, show_badge: true, created_at: '2024-01-15T10:30:00.000Z', updated_at: '2024-01-15T10:30:00.000Z', }; expect(() => newsletterOutputSchema.parse(apiNewsletter)).not.toThrow(); }); it('should reject newsletter output without required fields', () => { const invalidNewsletter = { name: 'Newsletter', slug: 'newsletter', }; expect(() => newsletterOutputSchema.parse(invalidNewsletter)).toThrow(); }); it('should reject newsletter output with invalid status', () => { const invalidNewsletter = { id: '507f1f77bcf86cd799439011', uuid: '550e8400-e29b-41d4-a716-446655440000', name: 'Newsletter', slug: 'newsletter', sender_reply_to: 'newsletter', status: 'invalid_status', visibility: 'members', subscribe_on_signup: true, sort_order: 0, show_header_icon: true, show_header_title: true, title_font_category: 'sans-serif', title_alignment: 'center', show_feature_image: true, body_font_category: 'sans-serif', show_badge: true, created_at: '2024-01-15T10:30:00.000Z', updated_at: '2024-01-15T10:30:00.000Z', }; expect(() => newsletterOutputSchema.parse(invalidNewsletter)).toThrow(); }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jgardner04/Ghost-MCP-Server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server