162 lines
5.2 KiB
JavaScript
162 lines
5.2 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import fs from 'node:fs';
|
|
import { compileFunction } from 'node:vm';
|
|
import ts from 'typescript';
|
|
|
|
await test('blocked browser storage cannot prevent authentication or clearing a submitted interest', () => {
|
|
const source = fs.readFileSync(
|
|
new URL(
|
|
'../../resources/js/hooks/use-interest-draft.ts',
|
|
import.meta.url,
|
|
),
|
|
'utf8',
|
|
);
|
|
const output = ts.transpileModule(source, {
|
|
compilerOptions: {
|
|
module: ts.ModuleKind.CommonJS,
|
|
target: ts.ScriptTarget.ES2022,
|
|
},
|
|
}).outputText;
|
|
const module = { exports: {} };
|
|
let destination;
|
|
const storage = {
|
|
getItem() {
|
|
throw new Error('blocked');
|
|
},
|
|
setItem() {
|
|
throw new Error('blocked');
|
|
},
|
|
removeItem() {
|
|
throw new Error('blocked');
|
|
},
|
|
};
|
|
compileFunction(output, [
|
|
'require',
|
|
'module',
|
|
'exports',
|
|
'sessionStorage',
|
|
'window',
|
|
'location',
|
|
])(
|
|
(name) =>
|
|
name === 'react'
|
|
? {
|
|
useState: (init) => [init(), () => {}],
|
|
useEffect: (effect) => effect(),
|
|
}
|
|
: { newSubmissionKey: () => 'synthetic-key' },
|
|
module,
|
|
module.exports,
|
|
storage,
|
|
{
|
|
location: {
|
|
assign: (url) => {
|
|
destination = url;
|
|
},
|
|
},
|
|
},
|
|
{ pathname: '/oportunidades/teste', search: '?sector=1' },
|
|
);
|
|
const draft = module.exports.useInterestDraft('synthetic', {
|
|
name: 'Synthetic',
|
|
email: 'synthetic@example.invalid',
|
|
});
|
|
assert.equal(draft.key, 'synthetic-key');
|
|
assert.doesNotThrow(() => draft.clear());
|
|
assert.doesNotThrow(() => draft.authenticate());
|
|
assert.equal(
|
|
destination,
|
|
'/participar/entrar?return=%2Foportunidades%2Fteste%3Fsector%3D1',
|
|
);
|
|
});
|
|
|
|
test('reused interest hook isolates opportunities, retains deliberate edits and restores after reload', () => {
|
|
const source = fs.readFileSync(
|
|
new URL(
|
|
'../../resources/js/hooks/use-interest-draft.ts',
|
|
import.meta.url,
|
|
),
|
|
'utf8',
|
|
);
|
|
const output = ts.transpileModule(source, {
|
|
compilerOptions: {
|
|
module: ts.ModuleKind.CommonJS,
|
|
target: ts.ScriptTarget.ES2022,
|
|
},
|
|
}).outputText;
|
|
const saved = new Map();
|
|
let sequence = 0;
|
|
function mount(storage = saved) {
|
|
let value, changed, effect;
|
|
const module = { exports: {} };
|
|
compileFunction(output, [
|
|
'require',
|
|
'module',
|
|
'exports',
|
|
'sessionStorage',
|
|
'window',
|
|
'location',
|
|
])(
|
|
(name) =>
|
|
name === 'react'
|
|
? {
|
|
useState(init) {
|
|
value ??= init();
|
|
return [
|
|
value,
|
|
(next) => {
|
|
value =
|
|
typeof next === 'function'
|
|
? next(value)
|
|
: next;
|
|
changed = true;
|
|
},
|
|
];
|
|
},
|
|
useEffect(callback) {
|
|
effect = callback;
|
|
},
|
|
}
|
|
: { newSubmissionKey: () => 'synthetic-' + ++sequence },
|
|
module,
|
|
module.exports,
|
|
{
|
|
getItem: (key) => storage.get(key) ?? null,
|
|
setItem: (key, data) => storage.set(key, data),
|
|
removeItem: (key) => storage.delete(key),
|
|
},
|
|
{ location: { assign() {} } },
|
|
{ pathname: '/negocios/a', search: '?province_id=p' },
|
|
);
|
|
return (name, initial = { message: 'initial ' + name }) => {
|
|
changed = false;
|
|
let result = module.exports.useInterestDraft(name, initial);
|
|
// React discards a render-phase reset and renders the new scoped state.
|
|
if (changed)
|
|
result = module.exports.useInterestDraft(name, initial);
|
|
effect();
|
|
return result;
|
|
};
|
|
}
|
|
const render = mount();
|
|
const a = render('business:A');
|
|
a.setForm({ message: 'deliberate A' });
|
|
render('business:A');
|
|
const b = render('business:B');
|
|
assert.equal(b.form.message, 'initial business:B');
|
|
assert.notEqual(a.key, b.key);
|
|
b.setForm({ message: 'deliberate B' });
|
|
render('business:B');
|
|
assert.equal(render('business:A').form.message, 'deliberate A');
|
|
assert.equal(mount()('business:B').form.message, 'deliberate B');
|
|
assert.equal(
|
|
mount(new Map())('business:A').form.message,
|
|
'initial business:A',
|
|
);
|
|
assert.equal(
|
|
JSON.parse(saved.get('investemoz-interest:business:A')).form.message,
|
|
'deliberate A',
|
|
);
|
|
});
|