The JS mock services carried MPE_TABLES.pre_edit_hook / post_edit_hook values but never acted on them, so a table configured with hooks behaved differently in the mock than in production. Add mockHookSource() to dcMockUtils (resolving a hook program name to the source of its .js counterpart on the Drive) and run the hook where the SAS backend does: - editors/getdata runs the pre-edit hook after filtering, letting it reassign visibleRows / visibleColumns (the work.OUT contract) - so an empty mirror can display the live rows of the table it points at - editors/stagedata and editors/loadfile run the post-edit hook before the MPE_SUBMIT row is written, letting it reassign libref / dsn (the call symputx contract) - so a changeset submitted against a mirror is raised against the real table Seed a demo pair in makedata (TESTDATA.DEMO_ORDERS plus an empty TESTDATA.DEMO_MIRROR with both hooks) and cover it with a Cypress spec.
36 lines
1.8 KiB
JavaScript
36 lines
1.8 KiB
JavaScript
// ─────────────────────────────────────────────────────────────────────────────
|
|
// Mock of a PRE_EDIT_HOOK program
|
|
//
|
|
// Registered against TESTDATA.DEMO_MIRROR (MPE_TABLES.pre_edit_hook), which is
|
|
// an EMPTY mirror of TESTDATA.DEMO_ORDERS.
|
|
//
|
|
// This file is eval'd by editors/getdata.js (mirroring how getdata.sas
|
|
// %includes the hook program via %mpe_runhook), so it shares the caller's
|
|
// scope: visibleRows, visibleColumns, tableReg, requestedLibref and every
|
|
// dcMockUtils function (loadTableAnyLib, makeTableLoader, libDataDir, ...) are
|
|
// available directly.
|
|
//
|
|
// The real hook is a .sas program which runs after the filter has been applied
|
|
// and the table sorted, with the editor data in work.OUT:
|
|
//
|
|
// data work.out;
|
|
// set TESTDATA.DEMO_ORDERS;
|
|
// run;
|
|
//
|
|
// The mock's equivalent is to replace visibleRows / visibleColumns with the
|
|
// rows and columns of the real table, so an empty mirror still shows live data.
|
|
// (A real hook that must honour the user's filter has to re-apply it - the
|
|
// filter has already been applied to the empty mirror by the time it runs.)
|
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
|
|
const realTable = loadTableAnyLib('DEMO_ORDERS')
|
|
if (realTable && realTable.data) {
|
|
visibleRows = realTable.data.rows.map((row) => ({ ...row }))
|
|
visibleColumns = realTable.data.columns
|
|
console.log(
|
|
'[HOOK DEBUG] demo_mirror_preedit: loaded ' +
|
|
visibleRows.length +
|
|
' rows from DEMO_ORDERS'
|
|
)
|
|
}
|