Files
gmail-hook/apps/watcher/test/match.test.js
T
nsrbandCursor 46a2e2a7b0 feat: add gmail-hook monorepo with watcher, api, and web
Ship the receipt pipeline (Livin/Grab/BRI), PocketBase spendings, PM2 ecosystem, and a proper .gitignore that excludes secrets, SQLite data, and media dumps.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 22:58:47 +07:00

172 lines
4.9 KiB
JavaScript

import assert from "node:assert/strict";
import { describe, it } from "node:test";
import {
extractEmail,
parseForwardedHeader,
resolveOriginal,
subjectMatches,
} from "../src/lib/email.js";
import { matchRule } from "../src/handlers/match-rule.js";
import {
briTransferDirectBody,
briTransferForwardedBody,
grabBody,
grabForwardedBody,
livinDirectBody,
livinForwardedBody,
} from "./fixtures.js";
const silentLog = {
info() {},
warn() {},
error() {},
};
describe("extractEmail", () => {
it("parses angle-bracket addresses", () => {
assert.equal(
extractEmail(`"Livin'" <noreply.livin@bankmandiri.co.id>`),
"noreply.livin@bankmandiri.co.id",
);
});
});
describe("parseForwardedHeader", () => {
it("reads original From/Subject from a Fwd block", () => {
const h = parseForwardedHeader(livinForwardedBody);
assert.ok(h);
assert.match(h.from, /noreply\.livin@bankmandiri\.co\.id/);
assert.equal(h.subject, "Pembayaran Berhasil!");
});
it("returns null when there is no Fwd block", () => {
assert.equal(parseForwardedHeader(livinDirectBody), null);
});
});
describe("resolveOriginal", () => {
it("uses envelope for direct mail", () => {
const o = resolveOriginal({
from: `"Livin'" <noreply.livin@bankmandiri.co.id>`,
subject: "Pembayaran Berhasil!",
date: "Sun, 13 Sep 2026 14:48:36 +0700 (WIB)",
body: livinDirectBody,
});
assert.equal(o.viaForward, false);
assert.equal(extractEmail(o.from), "noreply.livin@bankmandiri.co.id");
});
it("uses Fwd header for forwarded mail", () => {
const o = resolveOriginal({
from: "NSRB <nasyarobby@gmail.com>",
subject: "Fwd: Your Grab E-Receipt",
body: grabForwardedBody,
});
assert.equal(o.viaForward, true);
assert.equal(extractEmail(o.from), "no-reply@grab.com");
assert.equal(o.subject, "Your Grab E-Receipt");
});
});
describe("subjectMatches", () => {
it("matches exact and Fwd-prefixed subjects", () => {
assert.equal(subjectMatches("Pembayaran Berhasil!", "Pembayaran Berhasil!"), true);
assert.equal(subjectMatches("Fwd: Pembayaran Berhasil!", "Pembayaran Berhasil!"), true);
assert.equal(subjectMatches("Hello", "Pembayaran Berhasil!"), false);
});
});
describe("matchRule", () => {
it("matches direct Livin", async () => {
const result = await matchRule({
messageId: "1a099bd61efd234d",
log: silentLog,
message: {
from: `"Livin'" <noreply.livin@bankmandiri.co.id>`,
subject: "Pembayaran Berhasil!",
date: "Sun, 13 Sep 2026 14:48:36 +0700 (WIB)",
body: livinDirectBody,
},
});
assert.equal(result.pass.rule.kind, "livin.qr_payment.success");
});
it("matches forwarded Livin via original header", async () => {
const result = await matchRule({
messageId: "1a099b0c04c4397a",
log: silentLog,
message: {
from: "NSRB <nasyarobby@gmail.com>",
subject: "Fwd: Pembayaran Berhasil!",
body: livinForwardedBody,
},
});
assert.equal(result.pass.rule.kind, "livin.qr_payment.success");
});
it("matches direct Grab", async () => {
const result = await matchRule({
messageId: "grab-direct",
log: silentLog,
message: {
from: "Grab <no-reply@grab.com>",
subject: "Your Grab E-Receipt",
body: grabBody,
},
});
assert.equal(result.pass.rule.kind, "grab.ereceipt.ride");
});
it("matches forwarded Grab via original header", async () => {
const result = await matchRule({
messageId: "1a099b8b9d239e5e",
log: silentLog,
message: {
from: "NSRB <nasyarobby@gmail.com>",
subject: "Fwd: Your Grab E-Receipt",
body: grabForwardedBody,
},
});
assert.equal(result.pass.rule.kind, "grab.ereceipt.ride");
});
it("matches direct BRI transfer", async () => {
const result = await matchRule({
messageId: "bri-direct",
log: silentLog,
message: {
from: "Bank BRI <BankBRI@bri.co.id>",
subject: "Pemindahan Dana Sesama Rekening BRI",
body: briTransferDirectBody,
},
});
assert.equal(result.pass.rule.kind, "bri.transfer.success");
});
it("matches forwarded BRI transfer via original header", async () => {
const result = await matchRule({
messageId: "1a09b6cd9a3bc6bd",
log: silentLog,
message: {
from: "Nasyarobby Putra <nsrb@bu.edu>",
subject: "Fwd: Pemindahan Dana Sesama Rekening BRI",
body: briTransferForwardedBody,
},
});
assert.equal(result.pass.rule.kind, "bri.transfer.success");
});
it("breaks on unknown from/subject", async () => {
const result = await matchRule({
messageId: "x",
log: silentLog,
message: {
from: "Someone <other@example.com>",
subject: "Hello",
body: "hi",
},
});
assert.equal(result.break, true);
});
});