Skip to content

Commit eec4f4c

Browse files
authored
test: add log reader test suite with file existence and content valid… (#18)
* test: add log reader test suite with file existence and content validation * fix: update LogViewerProvider test to use type assertion for private method access * test: add report reader test suite with file existence and content validation
1 parent 2ee8c24 commit eec4f4c

File tree

3 files changed

+157
-1
lines changed

3 files changed

+157
-1
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ All notable changes to the "magento-log-viewer" extension will be documented in
1212
- fix: Improved badge updates with throttling and debouncing: Prevents too frequent updates and implements more efficient counting methods.
1313
- fix: improve type safety in report handling functions
1414
- i18n: translations added
15-
15+
- test: add log reader test suite with file existence and content validation
16+
- test: add report reader test suite with file existence and content validation
1617
---
1718

1819
## Latest Release

src/test/logReader.test.ts

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import * as assert from 'assert';
2+
import * as fs from 'fs';
3+
import * as path from 'path';
4+
import * as os from 'os';
5+
6+
// Import the main module components to test
7+
import { LogViewerProvider, LogItem } from '../logViewer';
8+
9+
suite('Log Reader Test Suite', () => {
10+
// Create a temporary directory for test logs
11+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'magento-logviewer-test-'));
12+
const logFilePath = path.join(tempDir, 'test.log');
13+
14+
// Sample log content with different log levels
15+
const sampleLogContent = `[2025-05-28T21:13:28.751586+00:00] .Info: Broken reference: the 'amcompany_toolbar_link' element cannot be added as child to 'header.links', because the latter doesn't exist
16+
[2025-05-28T21:13:28.751586+00:00] .Warn: Broken reference: the 'amcompany_toolbar_link' element cannot be added as child to 'header.links', because the latter doesn't exist
17+
[2025-05-28T21:13:29.123456+00:00] .Debug: Debug message: initializing module
18+
[2025-05-28T21:13:30.234567+00:00] .Error: Failed to load resource: server responded with status 404
19+
[2025-05-28T21:13:31.345678+00:00] .Critical: Database connection failed`;
20+
21+
// Set up and tear down
22+
suiteSetup(() => {
23+
// Create the test log file before tests
24+
fs.writeFileSync(logFilePath, sampleLogContent);
25+
});
26+
27+
suiteTeardown(() => {
28+
// Clean up test files after tests
29+
try {
30+
fs.unlinkSync(logFilePath);
31+
fs.rmdirSync(tempDir);
32+
} catch (err) {
33+
console.error('Failed to clean up test files:', err);
34+
}
35+
});
36+
37+
test('Log file should exist', () => {
38+
assert.strictEqual(fs.existsSync(logFilePath), true, 'Test log file should exist');
39+
});
40+
41+
test('Log file should be readable', () => {
42+
const content = fs.readFileSync(logFilePath, 'utf-8');
43+
assert.strictEqual(content, sampleLogContent, 'Log file content should match the sample content');
44+
});
45+
46+
test('LogViewerProvider should read log file correctly', async () => {
47+
// Create a LogViewerProvider instance with the temp directory as root
48+
const logProvider = new LogViewerProvider(tempDir); // Get access to private method (this requires modifying the class or using a type assertion)
49+
// For this test, we'll use a type assertion to access the private method
50+
51+
// Use a specific interface that defines the method we need for testing
52+
interface LogViewerInternals {
53+
getLogFileLines(filePath: string): LogItem[];
54+
}
55+
56+
// Cast to our specific interface instead of 'any'
57+
const provider = logProvider as unknown as LogViewerInternals;
58+
const logItems = provider.getLogFileLines(logFilePath);
59+
60+
// Get all log levels from the items
61+
const logLevels = logItems.map((item: LogItem) => item.label?.toString().split(' ')[0]);
62+
console.log('Found log levels:', logLevels);
63+
64+
// Verify log file is parsed correctly and contains expected entries
65+
assert.ok(logItems.length > 0, 'Should parse log entries');
66+
67+
// Find if any log level contains Info, Warn, etc (case-insensitive)
68+
assert.ok(logLevels.some((level: unknown) => typeof level === 'string' && level.includes('INFO')), 'Should contain INFO level logs');
69+
assert.ok(logLevels.some((level: unknown) => typeof level === 'string' && level.includes('WARN')), 'Should contain WARN level logs');
70+
assert.ok(logLevels.some((level: unknown) => typeof level === 'string' && level.includes('DEBUG')), 'Should contain DEBUG level logs');
71+
assert.ok(logLevels.some((level: unknown) => typeof level === 'string' && level.includes('ERROR')), 'Should contain ERROR level logs');
72+
assert.ok(logLevels.some((level: unknown) => typeof level === 'string' && level.includes('CRITICAL')), 'Should contain CRITICAL level logs');
73+
});
74+
});

src/test/reportReader.test.ts

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import * as assert from 'assert';
2+
import * as fs from 'fs';
3+
import * as path from 'path';
4+
import * as os from 'os';
5+
6+
// Import the main module components to test
7+
import { ReportViewerProvider, LogItem } from '../logViewer';
8+
9+
suite('Report Reader Test Suite', () => {
10+
// Create a temporary directory for test reports
11+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'magento-reportviewer-test-'));
12+
const reportFilePath = path.join(tempDir, 'report.json');
13+
14+
// Sample report content (Magento error report format)
15+
const sampleReportContent = JSON.stringify({
16+
"0": "Error",
17+
"1": "Exception: Broken reference: the 'amcompany_toolbar_link' element cannot be added as child to 'header.links', because the latter doesn't exist",
18+
"2": "#1 Magento\\Framework\\View\\Layout\\Generator\\Structure->scheduleStructure() called at /var/www/html/vendor/magento/framework/View/Layout/GeneratorPool.php:105",
19+
"3": "#2 Magento\\Framework\\View\\Layout\\GeneratorPool->process() called at /var/www/html/vendor/magento/framework/View/Layout.php:352",
20+
"url": "/customer/account/login/",
21+
"script_name": "/index.php",
22+
"report_id": "12345abcde"
23+
}, null, 2);
24+
25+
// Set up and tear down
26+
suiteSetup(() => {
27+
// Create the test report file before tests
28+
fs.writeFileSync(reportFilePath, sampleReportContent);
29+
});
30+
31+
suiteTeardown(() => {
32+
// Clean up test files after tests
33+
try {
34+
fs.unlinkSync(reportFilePath);
35+
fs.rmdirSync(tempDir);
36+
} catch (err) {
37+
console.error('Failed to clean up test files:', err);
38+
}
39+
});
40+
41+
test('Report file should exist', () => {
42+
assert.strictEqual(fs.existsSync(reportFilePath), true, 'Test report file should exist');
43+
});
44+
45+
test('Report file should be readable', () => {
46+
const content = fs.readFileSync(reportFilePath, 'utf-8');
47+
assert.strictEqual(content, sampleReportContent, 'Report file content should match the sample content');
48+
});
49+
50+
test('ReportViewerProvider should read report file correctly', async () => {
51+
// Create a ReportViewerProvider instance with the temp directory as root
52+
const reportProvider = new ReportViewerProvider(tempDir);
53+
54+
// Interface for accessing private methods for testing
55+
interface ReportViewerInternals {
56+
getLogItems(dir: string, label: string): LogItem[];
57+
}
58+
59+
// Access the provider's internal methods
60+
const provider = reportProvider as unknown as ReportViewerInternals;
61+
62+
// Get report items from the directory
63+
const reportItems = provider.getLogItems(tempDir, 'Reports');
64+
65+
// Basic validation that reports were found
66+
assert.ok(reportItems.length > 0, 'Should find report entries');
67+
68+
// Verify report content is correctly parsed
69+
const reportItem = reportItems[0];
70+
assert.ok(reportItem.label?.toString().includes('Error'), 'Report label should include the error type from the report');
71+
72+
// Also check if the command arguments contain the file path
73+
assert.ok(reportItem.command &&
74+
reportItem.command.arguments &&
75+
reportItem.command.arguments[0] &&
76+
reportItem.command.arguments[0].endsWith('report.json'),
77+
'Report item should have command with file path');
78+
});
79+
80+
// Additional test for report content parsing if needed
81+
});

0 commit comments

Comments
 (0)