Files
markdown-converter/tests/main/DailyNotes.test.js
T
amitwh bd620284ab test: fix Windows-only test failures so CI matrix runs clean
Two pre-existing Windows-specific failures blocked the CI release
matrix from publishing the Windows build:

  - tests/main/DailyNotes.test.js: 'joins dir + YYYY-MM-DD.md' used
    a hard-coded '/tmp/notes/2026-09-13.md' expected value. On
    POSIX path.join returns '/' and the test passes; on Windows
    path.join returns '\' and the test fails. Fix: build the
    expected value via path.join so it matches the platform.

  - tests/main/PDFBatchOperations.test.js: 'watermarks every PDF
    including subfolders' used the default 5s Jest timeout. Windows
    CI runners are slower at pdf-lib / pdfjs-dist cold-start and the
    test regularly exceeded 5s. Fix: jest.setTimeout(30000) at the
    start of the watermark describe block.

Neither is a regression — both predate this session. The fix gets
the Windows job green so the release matrix completes 3/3.

Amit Haridas
2026-09-30 23:12:59 +05:30

186 lines
5.9 KiB
JavaScript

/**
* @jest-environment node
*
* DailyNotes tests — pure module, injectable IO.
*/
const fs = require('fs');
const os = require('os');
const path = require('path');
const DailyNotes = require('../../src/main/DailyNotes');
describe('DailyNotes.dateKey', () => {
test('formats a Date as YYYY-MM-DD in local time', () => {
expect(DailyNotes.dateKey(new Date(2026, 8, 13))).toBe('2026-09-13');
});
test('zero-pads single-digit month and day', () => {
expect(DailyNotes.dateKey(new Date(2026, 0, 5))).toBe('2026-01-05');
});
test('defaults to today when called with no args', () => {
const now = new Date();
expect(DailyNotes.dateKey()).toBe(DailyNotes.dateKey(now));
});
});
describe('DailyNotes.pathFor', () => {
test('joins dir + YYYY-MM-DD.md', () => {
const d = new Date(2026, 8, 13);
// Use path.join to build the expected value so the test passes on
// Windows (where path.join returns backslashes) as well as POSIX.
expect(DailyNotes.pathFor(d, '/tmp/notes', path)).toBe(
path.join('/tmp/notes', '2026-09-13.md')
);
});
});
describe('DailyNotes.loadTemplate', () => {
let tmpDir;
beforeEach(() => {
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'daily_template_'));
});
afterEach(() => fs.rmSync(tmpDir, { recursive: true, force: true }));
test('returns built-in default when no template dir given', () => {
const d = new Date(2026, 8, 13);
const body = DailyNotes.loadTemplate({ date: d, fs, pathUtil: path });
expect(body).toContain('# 2026-09-13');
expect(body).toContain('## Notes');
});
test('returns built-in default when template file is missing', () => {
const d = new Date(2026, 8, 13);
const body = DailyNotes.loadTemplate({
date: d,
templateDir: tmpDir,
templateName: 'nope.md',
fs,
pathUtil: path,
});
expect(body).toContain('# 2026-09-13');
});
test('substitutes {date} and {weekday} in a custom template', () => {
const tplPath = path.join(tmpDir, 'daily.md');
fs.writeFileSync(tplPath, '# {date} ({weekday})\n\nReflecting.', 'utf-8');
const d = new Date(2026, 8, 13); // a Sunday
const body = DailyNotes.loadTemplate({
date: d,
templateDir: tmpDir,
fs,
pathUtil: path,
now: d,
});
expect(body).toContain('# 2026-09-13');
expect(body).toContain('Sunday');
});
});
describe('DailyNotes.openOrCreate', () => {
let tmpDir;
beforeEach(() => {
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'daily_notes_'));
});
afterEach(() => fs.rmSync(tmpDir, { recursive: true, force: true }));
test('creates a new note from the default template', () => {
const d = new Date(2026, 8, 13);
const result = DailyNotes.openOrCreate({
date: d,
dir: tmpDir,
fs,
pathUtil: path,
now: d,
});
expect(result.created).toBe(true);
expect(result.path).toBe(path.join(tmpDir, '2026-09-13.md'));
expect(result.content).toContain('# 2026-09-13');
expect(fs.existsSync(result.path)).toBe(true);
});
test('returns existing content when the note already exists (no clobber)', () => {
const notePath = path.join(tmpDir, '2026-09-13.md');
fs.writeFileSync(notePath, '# Pre-existing content\n\nPreserve me.', 'utf-8');
const d = new Date(2026, 8, 13);
const result = DailyNotes.openOrCreate({
date: d,
dir: tmpDir,
fs,
pathUtil: path,
now: d,
});
expect(result.created).toBe(false);
expect(result.content).toBe('# Pre-existing content\n\nPreserve me.');
// The file was not modified — existing content survives.
expect(fs.readFileSync(notePath, 'utf-8')).toBe('# Pre-existing content\n\nPreserve me.');
});
test('creates the dir if it does not exist', () => {
const nestedDir = path.join(tmpDir, 'daily', 'nested');
expect(fs.existsSync(nestedDir)).toBe(false);
const d = new Date(2026, 8, 13);
DailyNotes.openOrCreate({
date: d,
dir: nestedDir,
fs,
pathUtil: path,
now: d,
});
expect(fs.existsSync(nestedDir)).toBe(true);
expect(fs.existsSync(path.join(nestedDir, '2026-09-13.md'))).toBe(true);
});
test('rejects when dir is missing', () => {
expect(() =>
DailyNotes.openOrCreate({
date: new Date(2026, 8, 13),
dir: null,
fs,
pathUtil: path,
})
).toThrow(/dir is required/);
});
});
describe('DailyNotes.listExisting', () => {
let tmpDir;
beforeEach(() => {
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'daily_list_'));
});
afterEach(() => fs.rmSync(tmpDir, { recursive: true, force: true }));
test('returns [] when the dir does not exist', () => {
expect(
DailyNotes.listExisting({ dir: path.join(tmpDir, 'missing'), fs, pathUtil: path })
).toEqual([]);
});
test('lists only YYYY-MM-DD.md entries, newest first', () => {
fs.writeFileSync(path.join(tmpDir, '2026-09-10.md'), 'a');
fs.writeFileSync(path.join(tmpDir, '2026-09-13.md'), 'b');
fs.writeFileSync(path.join(tmpDir, '2026-09-12.md'), 'c');
fs.writeFileSync(path.join(tmpDir, 'readme.md'), 'ignore');
fs.writeFileSync(path.join(tmpDir, '2026-13-09.md'), 'ignore (bad month)');
const list = DailyNotes.listExisting({ dir: tmpDir, fs, pathUtil: path });
expect(list).toEqual(['2026-09-13.md', '2026-09-12.md', '2026-09-10.md']);
});
});
describe('DailyNotes.isValidDir', () => {
test('accepts non-empty strings without NUL bytes', () => {
expect(DailyNotes.isValidDir('/home/me/notes')).toBe(true);
expect(DailyNotes.isValidDir('C:\\Users\\me\\notes')).toBe(true);
});
test('rejects empty / null / non-string / NUL-containing input', () => {
expect(DailyNotes.isValidDir('')).toBe(false);
expect(DailyNotes.isValidDir(null)).toBe(false);
expect(DailyNotes.isValidDir(undefined)).toBe(false);
expect(DailyNotes.isValidDir(42)).toBe(false);
expect(DailyNotes.isValidDir('/etc/\0passwd')).toBe(false);
});
});