Initial commit: Hedena Gold monorepo.
First commit of the Hedena Gold product (separate from gold-bank): branding, package names, and deploy defaults aligned to the new brand; legacy Henza trees stay local-only via .gitignore.
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
* Integration test for the `customer_sync_full_name` database trigger
|
||||
* (migration 20260922120000_customer_name_parts).
|
||||
*
|
||||
* The trigger is SQL, not Prisma, so jest's unit suite cannot cover it — it
|
||||
* needs a live database. Run it against a development DB:
|
||||
*
|
||||
* node scripts/test-name-trigger.cjs
|
||||
*
|
||||
* Exits non-zero on any failure. It creates ONE temporary Customer row and
|
||||
* deletes it again; the deletion is reported on stdout (CHANGELOG rule 2).
|
||||
*
|
||||
* The three directions required by the owner's ruling of 2026-09-22:
|
||||
* parts only -> fullName is rebuilt
|
||||
* fullName only -> the parts are re-derived
|
||||
* both at once -> THE PARTS WIN
|
||||
*/
|
||||
const { PrismaClient } = require('@prisma/client');
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
let failures = 0;
|
||||
|
||||
function check(condition, message) {
|
||||
if (!condition) failures++;
|
||||
console.log(`${condition ? ' PASS' : ' FAIL'} ${message}`);
|
||||
}
|
||||
|
||||
const read = async (id) =>
|
||||
(
|
||||
await prisma.$queryRawUnsafe(
|
||||
`SELECT "fullName","firstName","lastName","makingChargeOffsetPercent" AS pct
|
||||
FROM "Customer" WHERE id=$1`,
|
||||
id,
|
||||
)
|
||||
)[0];
|
||||
|
||||
(async () => {
|
||||
const id = 'trigger-test-' + Date.now();
|
||||
const unique = Date.now();
|
||||
|
||||
await prisma.$executeRawUnsafe(
|
||||
`INSERT INTO "Customer"
|
||||
(id,"fullName","firstName","lastName",mobile,"nationalCode","passwordHash","updatedAt")
|
||||
VALUES ($1,'',$2,$3,$4,$5,'x',NOW())`,
|
||||
id,
|
||||
'محمد علی',
|
||||
'احمدی',
|
||||
'09' + String(unique).slice(-9),
|
||||
'NC' + unique,
|
||||
);
|
||||
|
||||
// The owner's worked example: a two-token FIRST name must survive intact.
|
||||
console.log('\nCASE 0 — INSERT with parts only («محمد علی» + «احمدی»)');
|
||||
let r = await read(id);
|
||||
console.log(' ', JSON.stringify(r));
|
||||
check(r.fullName === 'محمد علی احمدی', 'fullName rebuilt from the parts');
|
||||
check(r.firstName === 'محمد علی', 'a two-token first name is NOT re-split');
|
||||
check(r.lastName === 'احمدی', 'last name kept separate');
|
||||
|
||||
console.log('\nCASE 1 — UPDATE the parts only');
|
||||
await prisma.$executeRawUnsafe(
|
||||
`UPDATE "Customer" SET "firstName"='رضا',"lastName"='کریمی' WHERE id=$1`,
|
||||
id,
|
||||
);
|
||||
r = await read(id);
|
||||
console.log(' ', JSON.stringify(r));
|
||||
check(r.fullName === 'رضا کریمی', 'fullName rebuilt from the parts');
|
||||
|
||||
console.log('\nCASE 2 — UPDATE fullName only');
|
||||
await prisma.$executeRawUnsafe(`UPDATE "Customer" SET "fullName"='سعید موسوی' WHERE id=$1`, id);
|
||||
r = await read(id);
|
||||
console.log(' ', JSON.stringify(r));
|
||||
check(r.firstName === 'سعید' && r.lastName === 'موسوی', 'parts re-derived from fullName');
|
||||
|
||||
console.log('\nCASE 3 — UPDATE BOTH in one statement (the parts must win)');
|
||||
await prisma.$executeRawUnsafe(
|
||||
`UPDATE "Customer" SET "fullName"='IGNORED',"firstName"='نرگس',"lastName"='رحیمی' WHERE id=$1`,
|
||||
id,
|
||||
);
|
||||
r = await read(id);
|
||||
console.log(' ', JSON.stringify(r));
|
||||
check(r.fullName === 'نرگس رحیمی', 'parts win; the submitted fullName is discarded');
|
||||
|
||||
console.log('\nCASE 4 — a multi-token fullName splits first-token / rest');
|
||||
await prisma.$executeRawUnsafe(`UPDATE "Customer" SET "fullName"='سید محمد حسینی' WHERE id=$1`, id);
|
||||
r = await read(id);
|
||||
console.log(' ', JSON.stringify(r));
|
||||
check(r.firstName === 'سید' && r.lastName === 'محمد حسینی', 'first token / the rest');
|
||||
|
||||
console.log('\nCASE 5 — an unrelated update leaves the name untouched');
|
||||
const before = await read(id);
|
||||
await prisma.$executeRawUnsafe(`UPDATE "Customer" SET mobile=mobile WHERE id=$1`, id);
|
||||
const after = await read(id);
|
||||
check(JSON.stringify(before) === JSON.stringify(after), 'no-op update changes nothing');
|
||||
|
||||
console.log('\nCASE 6 — makingChargeOffsetPercent');
|
||||
check(Number(after.pct) === 0, 'defaults to 0, so no existing price moves');
|
||||
|
||||
await prisma.$executeRawUnsafe(`DELETE FROM "Customer" WHERE id=$1`, id);
|
||||
console.log(`\nCleanup: deleted 1 temporary Customer row (${id}).`);
|
||||
|
||||
console.log(failures === 0 ? '\nALL PASSED' : `\n${failures} FAILED`);
|
||||
await prisma.$disconnect();
|
||||
process.exit(failures ? 1 : 0);
|
||||
})().catch(async (e) => {
|
||||
console.error(e);
|
||||
await prisma.$disconnect();
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user