const LogReaderService = require("../../../../src/services/logReader"); // Mock the LogReaderService jest.mock("../../../../src/services/logReader"); describe("LogViewerScreen - Service Integration", () => { let mockLogReader; let mockPaginatedData; let mockStats; beforeEach(() => { jest.clearAllMocks(); // Setup mock data mockPaginatedData = { entries: [ { id: "entry_1", type: "operation_start", timestamp: new Date("2025-08-06T20:30:00Z"), level: "INFO", message: "Price Update Operation Started", title: "Price Update Operation", details: "Target Tag: summer-sale\nPrice Adjustment: -10%", section: "operation_start", }, { id: "entry_2", type: "product_update", timestamp: new Date("2025-08-06T20:30:30Z"), level: "SUCCESS", message: "Updated The Hidden Snowboard", title: "Product Update: The Hidden Snowboard", details: "Product ID: gid://shopify/Product/8116504920355\nPrice: $749.99 → $674.99", section: "progress", productTitle: "The Hidden Snowboard", productId: "gid://shopify/Product/8116504920355", }, { id: "entry_3", type: "error", timestamp: new Date("2025-08-06T20:31:00Z"), level: "ERROR", message: "Failed to update Product XYZ", title: "Error: Product XYZ", details: "Product ID: xyz123\nError: Rate limit exceeded", section: "error", productTitle: "Product XYZ", productId: "xyz123", }, ], pagination: { currentPage: 0, pageSize: 10, totalEntries: 3, totalPages: 1, hasNextPage: false, hasPreviousPage: false, startIndex: 1, endIndex: 3, }, filters: { levelFilter: "ALL", searchTerm: "", }, }; mockStats = { totalEntries: 3, byLevel: { INFO: 1, SUCCESS: 1, ERROR: 1, }, byType: { operation_start: 1, product_update: 1, error: 1, }, operations: { total: 1, successful: 0, failed: 1, rollbacks: 0, }, }; // Setup LogReaderService mock mockLogReader = { getPaginatedEntries: jest.fn().mockResolvedValue(mockPaginatedData), getLogStatistics: jest.fn().mockResolvedValue(mockStats), clearCache: jest.fn(), watchFile: jest.fn().mockReturnValue(() => {}), }; LogReaderService.mockImplementation(() => mockLogReader); }); describe("LogReaderService Integration", () => { test("creates LogReaderService instance", () => { const logReader = new LogReaderService(); expect(LogReaderService).toHaveBeenCalled(); }); test("calls getPaginatedEntries with correct default parameters", async () => { const logReader = new LogReaderService(); const result = await logReader.getPaginatedEntries(); expect(mockLogReader.getPaginatedEntries).toHaveBeenCalled(); expect(result).toEqual(mockPaginatedData); }); test("calls getLogStatistics correctly", async () => { const logReader = new LogReaderService(); const result = await logReader.getLogStatistics(); expect(mockLogReader.getLogStatistics).toHaveBeenCalled(); expect(result).toEqual(mockStats); }); test("supports pagination parameters", async () => { const logReader = new LogReaderService(); await logReader.getPaginatedEntries({ page: 1, pageSize: 5, levelFilter: "ERROR", searchTerm: "test", }); expect(mockLogReader.getPaginatedEntries).toHaveBeenCalledWith({ page: 1, pageSize: 5, levelFilter: "ERROR", searchTerm: "test", }); }); test("supports cache clearing", () => { const logReader = new LogReaderService(); logReader.clearCache(); expect(mockLogReader.clearCache).toHaveBeenCalled(); }); test("supports file watching", () => { const logReader = new LogReaderService(); const mockCallback = jest.fn(); const cleanup = logReader.watchFile(mockCallback); expect(mockLogReader.watchFile).toHaveBeenCalledWith(mockCallback); expect(typeof cleanup).toBe("function"); }); }); describe("Data Structure Validation", () => { test("validates paginated data structure", async () => { const logReader = new LogReaderService(); const result = await logReader.getPaginatedEntries(); // Validate structure expect(result).toHaveProperty("entries"); expect(result).toHaveProperty("pagination"); expect(result).toHaveProperty("filters"); // Validate pagination structure expect(result.pagination).toHaveProperty("currentPage"); expect(result.pagination).toHaveProperty("pageSize"); expect(result.pagination).toHaveProperty("totalEntries"); expect(result.pagination).toHaveProperty("totalPages"); expect(result.pagination).toHaveProperty("hasNextPage"); expect(result.pagination).toHaveProperty("hasPreviousPage"); // Validate entries structure expect(Array.isArray(result.entries)).toBe(true); if (result.entries.length > 0) { const entry = result.entries[0]; expect(entry).toHaveProperty("id"); expect(entry).toHaveProperty("type"); expect(entry).toHaveProperty("timestamp"); expect(entry).toHaveProperty("level"); expect(entry).toHaveProperty("message"); } }); test("validates statistics data structure", async () => { const logReader = new LogReaderService(); const result = await logReader.getLogStatistics(); // Validate structure expect(result).toHaveProperty("totalEntries"); expect(result).toHaveProperty("byLevel"); expect(result).toHaveProperty("byType"); expect(result).toHaveProperty("operations"); // Validate operations structure expect(result.operations).toHaveProperty("total"); expect(result.operations).toHaveProperty("successful"); expect(result.operations).toHaveProperty("failed"); expect(result.operations).toHaveProperty("rollbacks"); }); }); describe("Error Handling", () => { test("handles getPaginatedEntries errors", async () => { const error = new Error("Failed to read log file"); mockLogReader.getPaginatedEntries.mockRejectedValue(error); const logReader = new LogReaderService(); await expect(logReader.getPaginatedEntries()).rejects.toThrow( "Failed to read log file" ); }); test("handles getLogStatistics errors", async () => { const error = new Error("Failed to calculate statistics"); mockLogReader.getLogStatistics.mockRejectedValue(error); const logReader = new LogReaderService(); await expect(logReader.getLogStatistics()).rejects.toThrow( "Failed to calculate statistics" ); }); }); describe("Filtering and Pagination Logic", () => { test("supports level filtering", async () => { const logReader = new LogReaderService(); // Test each filter level const filterLevels = ["ALL", "ERROR", "WARNING", "INFO", "SUCCESS"]; for (const level of filterLevels) { await logReader.getPaginatedEntries({ levelFilter: level }); expect(mockLogReader.getPaginatedEntries).toHaveBeenCalledWith( expect.objectContaining({ levelFilter: level }) ); } }); test("supports search functionality", async () => { const logReader = new LogReaderService(); await logReader.getPaginatedEntries({ searchTerm: "snowboard" }); expect(mockLogReader.getPaginatedEntries).toHaveBeenCalledWith( expect.objectContaining({ searchTerm: "snowboard" }) ); }); test("supports pagination navigation", async () => { const logReader = new LogReaderService(); // Test different page numbers for (let page = 0; page < 3; page++) { await logReader.getPaginatedEntries({ page }); expect(mockLogReader.getPaginatedEntries).toHaveBeenCalledWith( expect.objectContaining({ page }) ); } }); test("supports different page sizes", async () => { const logReader = new LogReaderService(); const pageSizes = [5, 10, 20, 50]; for (const pageSize of pageSizes) { await logReader.getPaginatedEntries({ pageSize }); expect(mockLogReader.getPaginatedEntries).toHaveBeenCalledWith( expect.objectContaining({ pageSize }) ); } }); }); describe("Performance Considerations", () => { test("caches results appropriately", async () => { const logReader = new LogReaderService(); // First call await logReader.getPaginatedEntries(); expect(mockLogReader.getPaginatedEntries).toHaveBeenCalledTimes(1); // Cache clearing should allow fresh data logReader.clearCache(); expect(mockLogReader.clearCache).toHaveBeenCalled(); }); test("handles large datasets efficiently", async () => { // Mock large dataset const largeDataset = { ...mockPaginatedData, pagination: { ...mockPaginatedData.pagination, totalEntries: 10000, totalPages: 500, }, }; mockLogReader.getPaginatedEntries.mockResolvedValue(largeDataset); const logReader = new LogReaderService(); const result = await logReader.getPaginatedEntries({ pageSize: 20 }); expect(result.pagination.totalEntries).toBe(10000); expect(result.pagination.totalPages).toBe(500); }); }); });