Replace browser prompt()-based editing with proper Bootstrap 5 modal dialogs for testimonials, services, FAQs, and leads. This provides better UX with form validation, structured input fields, and i18n support (ES/RU) instead of raw prompt dialogs. - Add testimonialModal, serviceModal, faqModal, leadModal to admin.html - Add show*/save* methods in admin.js for each entity type - Wire leads.html 'Add lead' button to leadModal - Add modal JS modules (FAQModal, LeadModal, ServiceModal) - Add unit and e2e tests for modals and API client
205 lines
6.8 KiB
JavaScript
205 lines
6.8 KiB
JavaScript
import { describe, it, expect, beforeEach, vi } from 'bun:test'
|
|
import { API } from '../../public/js/api.js'
|
|
|
|
// Mock fetch globally
|
|
global.fetch = vi.fn()
|
|
|
|
// Mock Response object for fetch
|
|
global.Response = class Response {
|
|
constructor(data) {
|
|
this.data = data
|
|
}
|
|
async json() {
|
|
return this.data
|
|
}
|
|
}
|
|
|
|
describe('API Client Methods', () => {
|
|
beforeEach(() => {
|
|
// Clear all mocks before each test
|
|
vi.clearAllMocks()
|
|
})
|
|
|
|
describe('Testimonial Methods', () => {
|
|
it('should have createTestimonial method', () => {
|
|
expect(typeof API.createTestimonial).toBe('function')
|
|
})
|
|
|
|
it('should have updateTestimonial method', () => {
|
|
expect(typeof API.updateTestimonial).toBe('function')
|
|
})
|
|
|
|
it('createTestimonial should make POST request to correct endpoint', async () => {
|
|
const mockData = { name: 'John', text: 'Great service' }
|
|
const mockResponse = { success: true, data: { id: 1, ...mockData } }
|
|
|
|
fetch.mockResolvedValueOnce(new Response(mockResponse))
|
|
|
|
const result = await API.createTestimonial(mockData)
|
|
|
|
expect(fetch).toHaveBeenCalledWith('/api/admin/testimonials', {
|
|
method: 'POST',
|
|
credentials: 'include',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(mockData)
|
|
})
|
|
expect(result).toEqual(mockResponse)
|
|
})
|
|
|
|
it('updateTestimonial should make PUT request to correct endpoint', async () => {
|
|
const mockData = { name: 'John', text: 'Updated testimonial' }
|
|
const mockResponse = { success: true, data: { id: 1, ...mockData } }
|
|
|
|
fetch.mockResolvedValueOnce(new Response(mockResponse))
|
|
|
|
const result = await API.updateTestimonial(1, mockData)
|
|
|
|
expect(fetch).toHaveBeenCalledWith('/api/admin/testimonials/1', {
|
|
method: 'PUT',
|
|
credentials: 'include',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(mockData)
|
|
})
|
|
expect(result).toEqual(mockResponse)
|
|
})
|
|
})
|
|
|
|
describe('Service Methods', () => {
|
|
it('should have createService method', () => {
|
|
expect(typeof API.createService).toBe('function')
|
|
})
|
|
|
|
it('should have updateService method', () => {
|
|
expect(typeof API.updateService).toBe('function')
|
|
})
|
|
|
|
it('createService should make POST request to correct endpoint', async () => {
|
|
const mockData = { title: 'New Service', description: 'Service description' }
|
|
const mockResponse = { success: true, data: { id: 1, ...mockData } }
|
|
|
|
fetch.mockResolvedValueOnce(new Response(mockResponse))
|
|
|
|
const result = await API.createService(mockData)
|
|
|
|
expect(fetch).toHaveBeenCalledWith('/api/admin/services', {
|
|
method: 'POST',
|
|
credentials: 'include',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(mockData)
|
|
})
|
|
expect(result).toEqual(mockResponse)
|
|
})
|
|
|
|
it('updateService should make PUT request to correct endpoint', async () => {
|
|
const mockData = { title: 'Updated Service', description: 'Updated description' }
|
|
const mockResponse = { success: true, data: { id: 1, ...mockData } }
|
|
|
|
fetch.mockResolvedValueOnce(new Response(mockResponse))
|
|
|
|
const result = await API.updateService(1, mockData)
|
|
|
|
expect(fetch).toHaveBeenCalledWith('/api/admin/services/1', {
|
|
method: 'PUT',
|
|
credentials: 'include',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(mockData)
|
|
})
|
|
expect(result).toEqual(mockResponse)
|
|
})
|
|
})
|
|
|
|
describe('FAQ Methods', () => {
|
|
it('should have createFAQ method', () => {
|
|
expect(typeof API.createFAQ).toBe('function')
|
|
})
|
|
|
|
it('should have updateFAQ method', () => {
|
|
expect(typeof API.updateFAQ).toBe('function')
|
|
})
|
|
|
|
it('createFAQ should make POST request to correct endpoint', async () => {
|
|
const mockData = { question: 'FAQ Question', answer: 'FAQ Answer' }
|
|
const mockResponse = { success: true, data: { id: 1, ...mockData } }
|
|
|
|
fetch.mockResolvedValueOnce(new Response(mockResponse))
|
|
|
|
const result = await API.createFAQ(mockData)
|
|
|
|
expect(fetch).toHaveBeenCalledWith('/api/admin/faq', {
|
|
method: 'POST',
|
|
credentials: 'include',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(mockData)
|
|
})
|
|
expect(result).toEqual(mockResponse)
|
|
})
|
|
|
|
it('updateFAQ should make PUT request to correct endpoint', async () => {
|
|
const mockData = { question: 'Updated FAQ Question', answer: 'Updated FAQ Answer' }
|
|
const mockResponse = { success: true, data: { id: 1, ...mockData } }
|
|
|
|
fetch.mockResolvedValueOnce(new Response(mockResponse))
|
|
|
|
const result = await API.updateFAQ(1, mockData)
|
|
|
|
expect(fetch).toHaveBeenCalledWith('/api/admin/faq/1', {
|
|
method: 'PUT',
|
|
credentials: 'include',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(mockData)
|
|
})
|
|
expect(result).toEqual(mockResponse)
|
|
})
|
|
})
|
|
|
|
describe('Lead Methods', () => {
|
|
it('should have createLead method', () => {
|
|
expect(typeof API.createLead).toBe('function')
|
|
})
|
|
|
|
it('should have updateLead method', () => {
|
|
expect(typeof API.updateLead).toBe('function')
|
|
})
|
|
|
|
it('createLead should make POST request to correct endpoint', async () => {
|
|
const mockData = { name: 'John Doe', email: 'john@example.com', message: 'Hello' }
|
|
const mockResponse = { success: true, data: { id: 1, ...mockData } }
|
|
|
|
fetch.mockResolvedValueOnce(new Response(mockResponse))
|
|
|
|
const result = await API.createLead(mockData)
|
|
|
|
expect(fetch).toHaveBeenCalledWith('/api/leads', {
|
|
method: 'POST',
|
|
credentials: 'include',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
name: mockData.name,
|
|
email: mockData.email,
|
|
phone: '',
|
|
message: mockData.message,
|
|
property_id: undefined,
|
|
language: undefined
|
|
})
|
|
})
|
|
expect(result).toEqual(mockResponse)
|
|
})
|
|
|
|
it('updateLead should make PUT request to correct endpoint', async () => {
|
|
const mockData = { name: 'John Doe', status: 'contacted' }
|
|
const mockResponse = { success: true, data: { id: 1, ...mockData } }
|
|
|
|
fetch.mockResolvedValueOnce(new Response(mockResponse))
|
|
|
|
const result = await API.updateLead(1, mockData)
|
|
|
|
expect(fetch).toHaveBeenCalledWith('/api/admin/leads/1', {
|
|
method: 'PUT',
|
|
credentials: 'include',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(mockData)
|
|
})
|
|
expect(result).toEqual(mockResponse)
|
|
})
|
|
})
|
|
}) |