- Added functionality to intercept unresolved link clicks in both Reading View and Live Preview, allowing users to create notes directly from unresolved links. - Introduced settings for auto-starting interviews on unresolved link clicks, bypass modifiers for link interception, and options for adopting newly created notes in the editor. - Enhanced the settings interface with new options for managing unresolved link behavior and note adoption criteria. - Implemented a file create handler to automatically adopt new notes based on content length and user confirmation. - Improved error handling and user notifications throughout the new features for a better user experience.
149 lines
4.1 KiB
TypeScript
149 lines
4.1 KiB
TypeScript
import { describe, it, expect } from "vitest";
|
|
import {
|
|
isAdoptCandidate,
|
|
matchesPendingHint,
|
|
mergeFrontmatter,
|
|
type PendingCreateHint,
|
|
} from "../../unresolvedLink/adoptHelpers";
|
|
import { TFile } from "obsidian";
|
|
|
|
describe("isAdoptCandidate", () => {
|
|
it("returns true for empty content", () => {
|
|
expect(isAdoptCandidate("", 200)).toBe(true);
|
|
expect(isAdoptCandidate(" ", 200)).toBe(true);
|
|
});
|
|
|
|
it("returns true for content without frontmatter id", () => {
|
|
expect(isAdoptCandidate("Some text", 200)).toBe(true);
|
|
expect(isAdoptCandidate("Some text\nwith multiple lines", 200)).toBe(true);
|
|
});
|
|
|
|
it("returns true for content with frontmatter but no id", () => {
|
|
const content = `---
|
|
title: Test
|
|
---
|
|
Body content`;
|
|
expect(isAdoptCandidate(content, 200)).toBe(true);
|
|
});
|
|
|
|
it("returns false for content with id", () => {
|
|
const content = `---
|
|
id: note_123
|
|
title: Test
|
|
---
|
|
Body`;
|
|
expect(isAdoptCandidate(content, 200)).toBe(false);
|
|
});
|
|
|
|
it("returns false for content exceeding maxChars", () => {
|
|
const longContent = "x".repeat(300);
|
|
expect(isAdoptCandidate(longContent, 200)).toBe(false);
|
|
});
|
|
|
|
it("returns true for content within maxChars even with frontmatter", () => {
|
|
const content = `---
|
|
title: Test
|
|
---
|
|
Short body`;
|
|
expect(isAdoptCandidate(content, 200)).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe("matchesPendingHint", () => {
|
|
it("returns true when basename matches and within time window", () => {
|
|
const file = { basename: "test-note" } as TFile;
|
|
const hint: PendingCreateHint = {
|
|
basename: "test-note",
|
|
sourcePath: "source.md",
|
|
timestamp: Date.now() - 1000, // 1 second ago
|
|
};
|
|
expect(matchesPendingHint(file, hint, 3000)).toBe(true);
|
|
});
|
|
|
|
it("returns false when basename doesn't match", () => {
|
|
const file = { basename: "other-note" } as TFile;
|
|
const hint: PendingCreateHint = {
|
|
basename: "test-note",
|
|
sourcePath: "source.md",
|
|
timestamp: Date.now() - 1000,
|
|
};
|
|
expect(matchesPendingHint(file, hint, 3000)).toBe(false);
|
|
});
|
|
|
|
it("returns false when time window exceeded", () => {
|
|
const file = { basename: "test-note" } as TFile;
|
|
const hint: PendingCreateHint = {
|
|
basename: "test-note",
|
|
sourcePath: "source.md",
|
|
timestamp: Date.now() - 5000, // 5 seconds ago
|
|
};
|
|
expect(matchesPendingHint(file, hint, 3000)).toBe(false);
|
|
});
|
|
|
|
it("returns false when hint is null", () => {
|
|
const file = { basename: "test-note" } as TFile;
|
|
expect(matchesPendingHint(file, null, 3000)).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe("mergeFrontmatter", () => {
|
|
it("prepends frontmatter to content without existing frontmatter", () => {
|
|
const content = "Body content";
|
|
const frontmatter = `---
|
|
id: note_123
|
|
title: Test
|
|
---`;
|
|
const result = mergeFrontmatter(content, frontmatter);
|
|
expect(result).toContain("id: note_123");
|
|
expect(result).toContain("title: Test");
|
|
expect(result).toContain("Body content");
|
|
});
|
|
|
|
it("merges with existing frontmatter preserving existing fields", () => {
|
|
const content = `---
|
|
title: Existing
|
|
custom: value
|
|
---
|
|
Body content`;
|
|
const frontmatter = `---
|
|
id: note_123
|
|
title: New
|
|
type: note
|
|
---`;
|
|
const result = mergeFrontmatter(content, frontmatter);
|
|
expect(result).toContain("id: note_123");
|
|
expect(result).toContain("title: Existing"); // Existing takes precedence
|
|
expect(result).toContain("type: note");
|
|
expect(result).toContain("custom: value");
|
|
expect(result).toContain("Body content");
|
|
});
|
|
|
|
it("preserves body content when merging", () => {
|
|
const content = `---
|
|
title: Test
|
|
---
|
|
Line 1
|
|
Line 2
|
|
Line 3`;
|
|
const frontmatter = `---
|
|
id: note_123
|
|
---`;
|
|
const result = mergeFrontmatter(content, frontmatter);
|
|
expect(result).toContain("Line 1");
|
|
expect(result).toContain("Line 2");
|
|
expect(result).toContain("Line 3");
|
|
});
|
|
|
|
it("handles empty body", () => {
|
|
const content = `---
|
|
title: Test
|
|
---`;
|
|
const frontmatter = `---
|
|
id: note_123
|
|
---`;
|
|
const result = mergeFrontmatter(content, frontmatter);
|
|
expect(result).toContain("id: note_123");
|
|
expect(result).toContain("title: Test");
|
|
});
|
|
});
|