← back to Jill Website
src/__tests__/Inquiry.test.ts
352 lines
import { InquiryModel, Inquiry } from '../models/Inquiry';
import { getTestPool } from './setup';
describe('InquiryModel Integration Tests', () => {
let inquiryModel: InquiryModel;
beforeEach(() => {
// Override the pool in InquiryModel to use test pool
inquiryModel = new InquiryModel();
(inquiryModel as any).pool = getTestPool();
});
describe('create', () => {
it('should create a new inquiry with valid data', async () => {
const inquiryData = {
name: 'John Doe',
email: 'john@example.com',
phone: '+1-555-1234',
check_in_date: new Date('2026-06-01'),
check_out_date: new Date('2026-06-07'),
guest_count: 4,
message: 'Looking forward to staying at your property!',
};
const inquiry = await inquiryModel.create(inquiryData);
expect(inquiry).toBeDefined();
expect(inquiry.id).toBeDefined();
expect(inquiry.name).toBe('John Doe');
expect(inquiry.email).toBe('john@example.com');
expect(inquiry.phone).toBe('+1-555-1234');
expect(inquiry.guest_count).toBe(4);
expect(inquiry.message).toBe('Looking forward to staying at your property!');
expect(inquiry.created_at).toBeDefined();
expect(inquiry.updated_at).toBeDefined();
});
it('should normalize email to lowercase', async () => {
const inquiryData = {
name: 'Jane Smith',
email: 'JANE@EXAMPLE.COM',
phone: '+1-555-5678',
check_in_date: new Date('2026-07-01'),
check_out_date: new Date('2026-07-07'),
guest_count: 2,
message: 'Interested in booking',
};
const inquiry = await inquiryModel.create(inquiryData);
expect(inquiry.email).toBe('jane@example.com');
});
it('should trim whitespace from fields', async () => {
const inquiryData = {
name: ' John Doe ',
email: ' john@example.com ',
phone: ' +1-555-1234 ',
check_in_date: new Date('2026-06-01'),
check_out_date: new Date('2026-06-07'),
guest_count: 4,
message: ' Looking forward to staying! ',
};
const inquiry = await inquiryModel.create(inquiryData);
expect(inquiry.name).toBe('John Doe');
expect(inquiry.email).toBe('john@example.com');
expect(inquiry.phone).toBe('+1-555-1234');
expect(inquiry.message).toBe('Looking forward to staying!');
});
it('should reject inquiry with missing name', async () => {
const inquiryData = {
name: '',
email: 'john@example.com',
phone: '+1-555-1234',
check_in_date: new Date('2026-06-01'),
check_out_date: new Date('2026-06-07'),
guest_count: 4,
message: 'Looking forward to staying!',
};
await expect(inquiryModel.create(inquiryData)).rejects.toThrow('Name is required');
});
it('should reject inquiry with invalid email', async () => {
const inquiryData = {
name: 'John Doe',
email: 'invalid-email',
phone: '+1-555-1234',
check_in_date: new Date('2026-06-01'),
check_out_date: new Date('2026-06-07'),
guest_count: 4,
message: 'Looking forward to staying!',
};
await expect(inquiryModel.create(inquiryData)).rejects.toThrow('Valid email is required');
});
it('should reject inquiry with missing phone', async () => {
const inquiryData = {
name: 'John Doe',
email: 'john@example.com',
phone: '',
check_in_date: new Date('2026-06-01'),
check_out_date: new Date('2026-06-07'),
guest_count: 4,
message: 'Looking forward to staying!',
};
await expect(inquiryModel.create(inquiryData)).rejects.toThrow('Phone number is required');
});
it('should reject inquiry with check-out date before check-in date', async () => {
const inquiryData = {
name: 'John Doe',
email: 'john@example.com',
phone: '+1-555-1234',
check_in_date: new Date('2026-06-07'),
check_out_date: new Date('2026-06-01'),
guest_count: 4,
message: 'Looking forward to staying!',
};
await expect(inquiryModel.create(inquiryData)).rejects.toThrow('Check-out date must be after check-in date');
});
it('should reject inquiry with guest count less than 1', async () => {
const inquiryData = {
name: 'John Doe',
email: 'john@example.com',
phone: '+1-555-1234',
check_in_date: new Date('2026-06-01'),
check_out_date: new Date('2026-06-07'),
guest_count: 0,
message: 'Looking forward to staying!',
};
await expect(inquiryModel.create(inquiryData)).rejects.toThrow('Guest count must be at least 1');
});
it('should reject inquiry with empty message', async () => {
const inquiryData = {
name: 'John Doe',
email: 'john@example.com',
phone: '+1-555-1234',
check_in_date: new Date('2026-06-01'),
check_out_date: new Date('2026-06-07'),
guest_count: 4,
message: '',
};
await expect(inquiryModel.create(inquiryData)).rejects.toThrow('Message is required');
});
});
describe('findById', () => {
it('should retrieve inquiry by ID', async () => {
const inquiryData = {
name: 'John Doe',
email: 'john@example.com',
phone: '+1-555-1234',
check_in_date: new Date('2026-06-01'),
check_out_date: new Date('2026-06-07'),
guest_count: 4,
message: 'Looking forward to staying!',
};
const created = await inquiryModel.create(inquiryData);
const found = await inquiryModel.findById(created.id!);
expect(found).toBeDefined();
expect(found!.id).toBe(created.id);
expect(found!.name).toBe('John Doe');
expect(found!.email).toBe('john@example.com');
});
it('should return null for non-existent ID', async () => {
const found = await inquiryModel.findById(99999);
expect(found).toBeNull();
});
});
describe('findAll', () => {
it('should retrieve all inquiries', async () => {
const inquiry1 = {
name: 'John Doe',
email: 'john@example.com',
phone: '+1-555-1234',
check_in_date: new Date('2026-06-01'),
check_out_date: new Date('2026-06-07'),
guest_count: 4,
message: 'First inquiry',
};
const inquiry2 = {
name: 'Jane Smith',
email: 'jane@example.com',
phone: '+1-555-5678',
check_in_date: new Date('2026-07-01'),
check_out_date: new Date('2026-07-07'),
guest_count: 2,
message: 'Second inquiry',
};
await inquiryModel.create(inquiry1);
await inquiryModel.create(inquiry2);
const inquiries = await inquiryModel.findAll();
expect(inquiries).toHaveLength(2);
expect(inquiries[0].name).toBe('Jane Smith'); // Most recent first
expect(inquiries[1].name).toBe('John Doe');
});
it('should respect limit parameter', async () => {
const inquiry1 = {
name: 'John Doe',
email: 'john@example.com',
phone: '+1-555-1234',
check_in_date: new Date('2026-06-01'),
check_out_date: new Date('2026-06-07'),
guest_count: 4,
message: 'First inquiry',
};
const inquiry2 = {
name: 'Jane Smith',
email: 'jane@example.com',
phone: '+1-555-5678',
check_in_date: new Date('2026-07-01'),
check_out_date: new Date('2026-07-07'),
guest_count: 2,
message: 'Second inquiry',
};
await inquiryModel.create(inquiry1);
await inquiryModel.create(inquiry2);
const inquiries = await inquiryModel.findAll(1);
expect(inquiries).toHaveLength(1);
});
it('should return empty array when no inquiries exist', async () => {
const inquiries = await inquiryModel.findAll();
expect(inquiries).toEqual([]);
});
});
describe('update', () => {
it('should update inquiry with valid data', async () => {
const inquiryData = {
name: 'John Doe',
email: 'john@example.com',
phone: '+1-555-1234',
check_in_date: new Date('2026-06-01'),
check_out_date: new Date('2026-06-07'),
guest_count: 4,
message: 'Original message',
};
const created = await inquiryModel.create(inquiryData);
const updateData = {
name: 'John Updated',
email: 'john.updated@example.com',
phone: '+1-555-9999',
check_in_date: new Date('2026-08-01'),
check_out_date: new Date('2026-08-07'),
guest_count: 6,
message: 'Updated message',
};
const updated = await inquiryModel.update(created.id!, updateData);
expect(updated).toBeDefined();
expect(updated!.id).toBe(created.id);
expect(updated!.name).toBe('John Updated');
expect(updated!.email).toBe('john.updated@example.com');
expect(updated!.guest_count).toBe(6);
expect(updated!.message).toBe('Updated message');
});
it('should return null when updating non-existent inquiry', async () => {
const updateData = {
name: 'John Updated',
email: 'john@example.com',
phone: '+1-555-1234',
check_in_date: new Date('2026-06-01'),
check_out_date: new Date('2026-06-07'),
guest_count: 4,
message: 'Updated message',
};
const updated = await inquiryModel.update(99999, updateData);
expect(updated).toBeNull();
});
it('should reject update with invalid data', async () => {
const inquiryData = {
name: 'John Doe',
email: 'john@example.com',
phone: '+1-555-1234',
check_in_date: new Date('2026-06-01'),
check_out_date: new Date('2026-06-07'),
guest_count: 4,
message: 'Original message',
};
const created = await inquiryModel.create(inquiryData);
const invalidUpdate = {
name: '',
email: 'john@example.com',
phone: '+1-555-1234',
check_in_date: new Date('2026-06-01'),
check_out_date: new Date('2026-06-07'),
guest_count: 4,
message: 'Updated message',
};
await expect(inquiryModel.update(created.id!, invalidUpdate)).rejects.toThrow('Name is required');
});
});
describe('delete', () => {
it('should delete inquiry by ID', async () => {
const inquiryData = {
name: 'John Doe',
email: 'john@example.com',
phone: '+1-555-1234',
check_in_date: new Date('2026-06-01'),
check_out_date: new Date('2026-06-07'),
guest_count: 4,
message: 'Looking forward to staying!',
};
const created = await inquiryModel.create(inquiryData);
const deleted = await inquiryModel.delete(created.id!);
expect(deleted).toBe(true);
const found = await inquiryModel.findById(created.id!);
expect(found).toBeNull();
});
it('should return false when deleting non-existent inquiry', async () => {
const deleted = await inquiryModel.delete(99999);
expect(deleted).toBe(false);
});
});
});