318 lines
8.8 KiB
JavaScript
318 lines
8.8 KiB
JavaScript
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);
|
|
});
|
|
});
|
|
});
|