const { updateTourCenter } = require('../middlewares/TourController'); const Scene = require('../models/Scene'); const Tour = require('../models/Tour'); // Mocking Mongoose models jest.mock('../models/Scene'); jest.mock('../models/Tour'); describe('TourController - updateTourCenter', () => { const tourId = '507f1f77bcf86cd799439011'; beforeEach(() => { jest.clearAllMocks(); // Mock console.error to keep test output clean jest.spyOn(console, 'error').mockImplementation(() => {}); }); afterEach(() => { console.error.mockRestore(); }); test('nên tính toán trung bình GPS chính xác từ nhiều cảnh hợp lệ', async () => { const mockScenes = [ { gps: { lat: 10.0, lng: 20.0 } }, { gps: { lat: 20.0, lng: 40.0 } }, { gps: { lat: 30.0, lng: 60.0 } } ]; Scene.find.mockReturnValue({ select: jest.fn().mockResolvedValue(mockScenes) }); await updateTourCenter(tourId); // Trung bình: lat (10+20+30)/3 = 20, lng (20+40+60)/3 = 40 expect(Tour.findByIdAndUpdate).toHaveBeenCalledWith(tourId, { location: { lat: 20.0, lng: 40.0 } }); }); test('nên bỏ qua các cảnh có tọa độ (0,0), null hoặc không phải là số', async () => { const mockScenes = [ { gps: { lat: 10.0, lng: 20.0 } }, { gps: { lat: 0, lng: 0 } }, // Bỏ qua (0,0) { gps: null }, // Bỏ qua null { gps: { lat: 'invalid', lng: 30 } }, // Bỏ qua vì không phải số { gps: { lat: 20.0, lng: 40.0 } } ]; Scene.find.mockReturnValue({ select: jest.fn().mockResolvedValue(mockScenes) }); await updateTourCenter(tourId); // Chỉ tính 2 cảnh hợp lệ: lat (10+20)/2 = 15, lng (20+40)/2 = 30 expect(Tour.findByIdAndUpdate).toHaveBeenCalledWith(tourId, { location: { lat: 15.0, lng: 30.0 } }); }); test('không nên cập nhật Tour nếu không tìm thấy cảnh nào', async () => { Scene.find.mockReturnValue({ select: jest.fn().mockResolvedValue([]) }); await updateTourCenter(tourId); expect(Tour.findByIdAndUpdate).not.toHaveBeenCalled(); }); test('không nên cập nhật Tour nếu không có cảnh nào mang GPS hợp lệ', async () => { const mockScenes = [ { gps: { lat: 0, lng: 0 } }, { gps: null } ]; Scene.find.mockReturnValue({ select: jest.fn().mockResolvedValue(mockScenes) }); await updateTourCenter(tourId); expect(Tour.findByIdAndUpdate).not.toHaveBeenCalled(); }); test('nên log lỗi ra console nếu truy vấn Database thất bại', async () => { const errorMessage = 'Database connection lost'; Scene.find.mockImplementation(() => { throw new Error(errorMessage); }); await updateTourCenter(tourId); expect(console.error).toHaveBeenCalledWith( expect.stringContaining(`Error updating center for tour ${tourId}`), errorMessage ); expect(Tour.findByIdAndUpdate).not.toHaveBeenCalled(); }); });