move-with-wikilink-updates.test.ts•7.49 kB
/**
* Integration tests for move_note functionality with automatic wikilink updates
* Tests basic wikilink update scenarios when notes are moved between types
*/
import { describe, it } from 'node:test';
import assert from 'node:assert';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { mkdtemp, rm } from 'node:fs/promises';
import { Workspace } from '../../../src/core/workspace.js';
import { NoteManager } from '../../../src/core/notes.js';
import { NoteTypeManager } from '../../../src/core/note-types.js';
import { HybridSearchManager } from '../../../src/database/search-manager.js';
describe('move_note with automatic wikilink updates', () => {
it('should successfully move a note and update basic wikilinks', async () => {
let tempDir: string;
let searchManager: HybridSearchManager;
try {
// Setup
tempDir = await mkdtemp(join(tmpdir(), 'flint-note-wikilinks-test-'));
const workspace = new Workspace(tempDir);
await workspace.initialize();
searchManager = new HybridSearchManager(tempDir);
const noteManager = new NoteManager(workspace, searchManager);
// Create minimal note types needed for the test
const noteTypeManager = new NoteTypeManager(workspace);
await noteTypeManager.createNoteType('general', 'General notes', [], undefined);
await noteTypeManager.createNoteType('archive', 'Archived notes', [], undefined);
// Create a target note to be moved
const targetNote = await noteManager.createNote(
'projects', // projects exists by default
'Test Project',
'# Test Project\n\nThis is a project that will be moved.',
{ status: 'completed' }
);
// Create a note that references the target note
const referencingNote = await noteManager.createNote(
'general',
'Reference Note',
`# Reference Note\n\nThis note references [[${targetNote.id}]].\n\nThe link should be updated when the target is moved.`,
{}
);
// Get target note data for move operation
const targetNoteData = await noteManager.getNote(targetNote.id);
assert.ok(targetNoteData, 'Target note should exist');
// Move the target note from 'projects' to 'archive'
const moveResult = await noteManager.moveNote(
targetNote.id,
'archive',
targetNoteData.content_hash
);
// Verify the move was successful
assert.strictEqual(moveResult.success, true, 'Move operation should succeed');
assert.strictEqual(moveResult.old_type, 'projects', 'Old type should be projects');
assert.strictEqual(moveResult.new_type, 'archive', 'New type should be archive');
assert.strictEqual(
moveResult.new_id,
'archive/test-project',
'New ID should be correct'
);
// Verify the original note no longer exists
const originalNote = await noteManager.getNote(targetNote.id);
assert.strictEqual(originalNote, null, 'Original note should no longer exist');
// Verify the moved note exists in the new location
const movedNote = await noteManager.getNote(moveResult.new_id);
assert.ok(movedNote, 'Moved note should exist in new location');
assert.strictEqual(
movedNote.type,
'archive',
'Moved note should have correct type'
);
assert.strictEqual(
movedNote.title,
'Test Project',
'Moved note should retain title'
);
// Check if wikilinks were updated (if the feature is implemented)
const updatedReferencingNote = await noteManager.getNote(referencingNote.id);
assert.ok(updatedReferencingNote, 'Referencing note should still exist');
// The wikilink update behavior depends on the implementation
// This test validates that the move works correctly regardless
console.log('Move completed successfully:', {
old_id: moveResult.old_id,
new_id: moveResult.new_id,
links_updated: moveResult.links_updated || 0,
notes_with_updated_links: moveResult.notes_with_updated_links || 0
});
// Basic validation that the system is working
assert.ok(moveResult.timestamp, 'Move result should have timestamp');
assert.ok(
typeof moveResult.links_updated === 'number',
'Links updated should be a number'
);
assert.ok(
typeof moveResult.notes_with_updated_links === 'number',
'Notes with updated links should be a number'
);
} finally {
// Cleanup
// @ts-expect-error its a finally
if (searchManager) {
await searchManager.close();
}
// @ts-expect-error its a finally
if (tempDir) {
await rm(tempDir, { recursive: true, force: true });
}
}
});
it('should handle moves with no incoming wikilinks', async () => {
let tempDir: string;
let searchManager: HybridSearchManager;
try {
// Setup
tempDir = await mkdtemp(join(tmpdir(), 'flint-note-wikilinks-isolated-test-'));
const workspace = new Workspace(tempDir);
await workspace.initialize();
searchManager = new HybridSearchManager(tempDir);
const noteManager = new NoteManager(workspace, searchManager);
// Create projects note type for the move operation
const noteTypeManager = new NoteTypeManager(workspace);
await noteTypeManager.createNoteType('projects', 'Project notes', [], undefined);
// Create a note with no incoming links
const isolatedNote = await noteManager.createNote(
'daily', // daily exists by default
'2024-01-15',
'# 2024-01-15\n\nDaily note with no incoming links.',
{ date: '2024-01-15' }
);
const noteData = await noteManager.getNote(isolatedNote.id);
assert.ok(noteData, 'Isolated note should exist');
// Move the note to projects
const moveResult = await noteManager.moveNote(
isolatedNote.id,
'projects',
noteData.content_hash
);
// Verify successful move
assert.strictEqual(moveResult.success, true, 'Move should succeed');
assert.strictEqual(moveResult.old_id, isolatedNote.id, 'Old ID should match');
assert.strictEqual(
moveResult.new_id,
'projects/2024-01-15',
'New ID should be correct'
);
assert.strictEqual(moveResult.old_type, 'daily', 'Old type should be daily');
assert.strictEqual(moveResult.new_type, 'projects', 'New type should be projects');
// Should have no link updates since no notes reference it
assert.strictEqual(moveResult.links_updated, 0, 'Should have 0 links updated');
assert.strictEqual(
moveResult.notes_with_updated_links,
0,
'Should have 0 notes with updated links'
);
// Verify the moved note exists and is correct
const movedNote = await noteManager.getNote(moveResult.new_id);
assert.ok(movedNote, 'Moved note should exist');
assert.strictEqual(movedNote.title, '2024-01-15', 'Title should be preserved');
assert.strictEqual(movedNote.type, 'projects', 'Type should be updated');
} finally {
// Cleanup
// @ts-expect-error its a finally
if (searchManager) {
await searchManager.close();
}
// @ts-expect-error its a finally
if (tempDir) {
await rm(tempDir, { recursive: true, force: true });
}
}
});
});