test fix: setup CLS context

claude sez: "I see the issue. The tests are failing because we need to set up the CLS (Continuation Local Storage) context that Trilium uses for transactions. Let me check how this is handled in other tests:

I've updated the test file to:

I've updated the test file to:

Use an in-memory database for testing
Set up necessary database tables in beforeEach
Wrap all database operations in cls.init() and sql.transactional()
Handle async operations properly
This commit is contained in:
matt wilkie 2024-11-16 21:36:07 -07:00
parent e397011437
commit 9cd398d1ce

View File

@ -3,24 +3,47 @@ import importSingle from '../../../src/services/import/single.js';
import importUtils from '../../../src/services/import/utils.js';
import BNote from '../../../src/becca/entities/bnote.js';
import TaskContext from '../../../src/services/task_context.js';
import sql from '../../../src/services/sql.js';
import cls from '../../../src/services/cls.js';
describe('HTML Import', () => {
let parentNote: BNote;
let taskContext: TaskContext;
beforeEach(() => {
// Create a mock parent note
parentNote = new BNote({
noteId: 'testParent',
title: 'Test Parent',
type: 'text',
mime: 'text/html'
});
beforeAll(() => {
// Set up in-memory database for testing
process.env.TRILIUM_INTEGRATION_TEST = 'memory';
});
// Create a mock task context
taskContext = new TaskContext('test', 'test');
// Set textImportedAsText to true to ensure HTML imports are processed
taskContext.data = { textImportedAsText: true };
beforeEach(() => {
return cls.init(() => {
// Create a mock parent note
parentNote = new BNote({
noteId: 'testParent',
title: 'Test Parent',
type: 'text',
mime: 'text/html'
});
// Create a mock task context
taskContext = new TaskContext('test', 'test');
// Set textImportedAsText to true to ensure HTML imports are processed
taskContext.data = { textImportedAsText: true };
// Wrap in transaction to handle database operations
return sql.transactional(() => {
sql.execute('CREATE TABLE IF NOT EXISTS notes (noteId TEXT PRIMARY KEY, title TEXT, type TEXT, mime TEXT, isProtected INTEGER DEFAULT 0)');
sql.execute('CREATE TABLE IF NOT EXISTS note_contents (noteId TEXT PRIMARY KEY, content TEXT, hash TEXT, utcDateModified TEXT)');
// Insert parent note
sql.insert('notes', {
noteId: parentNote.noteId,
title: parentNote.title,
type: parentNote.type,
mime: parentNote.mime
});
});
});
});
describe('extractHtmlTitle', () => {
@ -58,86 +81,102 @@ describe('HTML Import', () => {
describe('importSingleFile with HTML', () => {
it('should import HTML file with title from title tag', () => {
const file = {
originalname: 'test.html',
mimetype: 'text/html',
buffer: Buffer.from(`
<html>
<head>
<title>HTML Title</title>
</head>
<body>
<p>Test content</p>
</body>
</html>
`)
};
return cls.init(() => {
return sql.transactional(() => {
const file = {
originalname: 'test.html',
mimetype: 'text/html',
buffer: Buffer.from(`
<html>
<head>
<title>HTML Title</title>
</head>
<body>
<p>Test content</p>
</body>
</html>
`)
};
const note = importSingle.importSingleFile(taskContext, file, parentNote);
expect(note.title).toBe('HTML Title');
expect(note.mime).toBe('text/html');
const note = importSingle.importSingleFile(taskContext, file, parentNote);
expect(note.title).toBe('HTML Title');
expect(note.mime).toBe('text/html');
});
});
});
it('should import HTML file with title from h1 when no title tag', () => {
const file = {
originalname: 'test.html',
mimetype: 'text/html',
buffer: Buffer.from(`
<html>
<body>
<h1>Heading Title</h1>
<p>Test content</p>
</body>
</html>
`)
};
return cls.init(() => {
return sql.transactional(() => {
const file = {
originalname: 'test.html',
mimetype: 'text/html',
buffer: Buffer.from(`
<html>
<body>
<h1>Heading Title</h1>
<p>Test content</p>
</body>
</html>
`)
};
const note = importSingle.importSingleFile(taskContext, file, parentNote);
expect(note.title).toBe('Heading Title');
expect(note.mime).toBe('text/html');
const note = importSingle.importSingleFile(taskContext, file, parentNote);
expect(note.title).toBe('Heading Title');
expect(note.mime).toBe('text/html');
});
});
});
it('should import HTML file with filename as title when no title or h1', () => {
const file = {
originalname: 'test-document.html',
mimetype: 'text/html',
buffer: Buffer.from(`
<html>
<body>
<p>Test content without title</p>
</body>
</html>
`)
};
return cls.init(() => {
return sql.transactional(() => {
const file = {
originalname: 'test-document.html',
mimetype: 'text/html',
buffer: Buffer.from(`
<html>
<body>
<p>Test content without title</p>
</body>
</html>
`)
};
const note = importSingle.importSingleFile(taskContext, file, parentNote);
expect(note.title).toBe('test-document');
expect(note.mime).toBe('text/html');
const note = importSingle.importSingleFile(taskContext, file, parentNote);
expect(note.title).toBe('test-document');
expect(note.mime).toBe('text/html');
});
});
});
it('should sanitize HTML content during import', () => {
const file = {
originalname: 'test.html',
mimetype: 'text/html',
buffer: Buffer.from(`
<html>
<head>
<title>Test Title</title>
<script>alert('xss');</script>
</head>
<body>
<p>Safe content</p>
<script>alert('xss');</script>
</body>
</html>
`)
};
return cls.init(() => {
return sql.transactional(() => {
const file = {
originalname: 'test.html',
mimetype: 'text/html',
buffer: Buffer.from(`
<html>
<head>
<title>Test Title</title>
<script>alert('xss');</script>
</head>
<body>
<p>Safe content</p>
<script>alert('xss');</script>
</body>
</html>
`)
};
const note = importSingle.importSingleFile(taskContext, file, parentNote);
expect(note.title).toBe('Test Title');
const content = note.getContent();
expect(content).not.toContain('<script>');
expect(content).toContain('<p>Safe content</p>');
const note = importSingle.importSingleFile(taskContext, file, parentNote);
expect(note.title).toBe('Test Title');
const content = note.getContent();
expect(content).not.toContain('<script>');
expect(content).toContain('<p>Safe content</p>');
});
});
});
});
});