fix: Address review findings (CRITICAL/HIGH)
CRITICAL fixes: - Stop passing mint URLs as relay URLs in initNDK (protocol mismatch) - Add unit tests for buildTransactionHistory (dedup, fallback, sort) HIGH fixes: - Restore .claude entry in .gitignore - Add warning logging for skipped malformed proof tags in nutzap parsing - Add error handling + 30s timeout to NDK initialization - Add unit tests for formatCSV and escapeField - Export escapeField for testability Also: add test script to package.json, include test/ in tsconfig Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
import { describe, it, expect } from "bun:test";
|
||||
import { formatCSV, escapeField } from "../src/csv.js";
|
||||
import type { TransactionRecord } from "../src/types.js";
|
||||
|
||||
describe("escapeField", () => {
|
||||
it("should return simple strings unchanged", () => {
|
||||
expect(escapeField("hello")).toBe("hello");
|
||||
});
|
||||
|
||||
it("should quote fields containing commas", () => {
|
||||
expect(escapeField("hello, world")).toBe('"hello, world"');
|
||||
});
|
||||
|
||||
it("should escape double quotes inside fields", () => {
|
||||
expect(escapeField('say "hello"')).toBe('"say ""hello"""');
|
||||
});
|
||||
|
||||
it("should quote fields containing newlines", () => {
|
||||
expect(escapeField("line1\nline2")).toBe('"line1\nline2"');
|
||||
});
|
||||
|
||||
it("should handle empty strings", () => {
|
||||
expect(escapeField("")).toBe("");
|
||||
});
|
||||
});
|
||||
|
||||
describe("formatCSV", () => {
|
||||
it("should produce correct header row for empty records", () => {
|
||||
const csv = formatCSV([]);
|
||||
expect(csv).toBe("date,type,amount,unit,mint,token_id,memo");
|
||||
});
|
||||
|
||||
it("should format a simple record", () => {
|
||||
const records: TransactionRecord[] = [
|
||||
{
|
||||
date: "2025-01-01T00:00:00Z",
|
||||
type: "receive",
|
||||
amount: 100,
|
||||
unit: "sat",
|
||||
mint: "https://mint.example",
|
||||
token_id: "abc123",
|
||||
memo: "",
|
||||
},
|
||||
];
|
||||
const lines = formatCSV(records).split("\n");
|
||||
expect(lines).toHaveLength(2);
|
||||
expect(lines[1]).toContain("100");
|
||||
expect(lines[1]).toContain("receive");
|
||||
});
|
||||
|
||||
it("should escape fields containing commas", () => {
|
||||
const records: TransactionRecord[] = [
|
||||
{
|
||||
date: "2025-01-01T00:00:00Z",
|
||||
type: "receive",
|
||||
amount: 100,
|
||||
unit: "sat",
|
||||
mint: "https://mint.example",
|
||||
token_id: "abc",
|
||||
memo: "hello, world",
|
||||
},
|
||||
];
|
||||
const csv = formatCSV(records);
|
||||
expect(csv).toContain('"hello, world"');
|
||||
});
|
||||
|
||||
it("should escape fields containing double quotes", () => {
|
||||
const records: TransactionRecord[] = [
|
||||
{
|
||||
date: "2025-01-01T00:00:00Z",
|
||||
type: "receive",
|
||||
amount: 100,
|
||||
unit: "sat",
|
||||
mint: "",
|
||||
token_id: "abc",
|
||||
memo: 'say "hello"',
|
||||
},
|
||||
];
|
||||
const csv = formatCSV(records);
|
||||
expect(csv).toContain('"say ""hello"""');
|
||||
});
|
||||
|
||||
it("should sort records by date ascending", () => {
|
||||
const records: TransactionRecord[] = [
|
||||
{
|
||||
date: "2025-03-01T00:00:00Z",
|
||||
type: "send",
|
||||
amount: 50,
|
||||
unit: "sat",
|
||||
mint: "",
|
||||
token_id: "b",
|
||||
memo: "",
|
||||
},
|
||||
{
|
||||
date: "2025-01-01T00:00:00Z",
|
||||
type: "receive",
|
||||
amount: 100,
|
||||
unit: "sat",
|
||||
mint: "",
|
||||
token_id: "a",
|
||||
memo: "",
|
||||
},
|
||||
];
|
||||
const lines = formatCSV(records).split("\n");
|
||||
expect(lines[1]).toContain(",a,");
|
||||
expect(lines[2]).toContain(",b,");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user