Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8009a46cc9 |
@@ -146,8 +146,8 @@ const sweptValues = (row) => [...row.hostile, ...(row.falsy || [])];
|
||||
// particular branch's gate has let it past. Each of its entries names the
|
||||
// `views` it is driven onto and declares whether the boot lands on them
|
||||
// (`restored: true`) or falls back to Home (`restored: false`), so a value
|
||||
// written for one renderer cannot stop reaching it unnoticed. A value that
|
||||
// lands on some views and not others is one entry per outcome.
|
||||
// written for one renderer cannot stop reaching it unnoticed. A value driven
|
||||
// onto every restorable view is written with everyRestorableView() below.
|
||||
//
|
||||
// `falsy` is the other POLARITY of a swept field, driven for the same reason.
|
||||
// It is not a value src/ never writes — for three of these fields it is the
|
||||
@@ -158,6 +158,23 @@ const sweptValues = (row) => [...row.hostile, ...(row.falsy || [])];
|
||||
// falsy value stored under that field comes back TRUTHY from the floor, so no
|
||||
// `!state.x` branch is reachable from a stored record at all.
|
||||
|
||||
// The `hostileRestore` entries for a value driven onto every restorable view:
|
||||
// it falls back to Home on the views listed in `fallsBackOn` and lands on every
|
||||
// other one, so a view added to RESTORABLE_VIEWS is driven, and expected to
|
||||
// land, without editing the row.
|
||||
function everyRestorableView(value, fallsBackOn) {
|
||||
return [
|
||||
{ value, views: fallsBackOn, restored: false },
|
||||
{
|
||||
value,
|
||||
views: [...RESTORABLE_VIEWS].filter(
|
||||
(view) => !fallsBackOn.includes(view),
|
||||
),
|
||||
restored: true,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
const CONTRACT = [
|
||||
{
|
||||
field: "wallets",
|
||||
@@ -312,32 +329,14 @@ const CONTRACT = [
|
||||
routes: true,
|
||||
// Comes back from the floor as null, which hasValidAddress() reads as
|
||||
// nothing selected: the popup falls back to Home on the five views
|
||||
// that need an address, and lands on the other six.
|
||||
hostileRestore: [
|
||||
{
|
||||
value: "length",
|
||||
views: [
|
||||
"address",
|
||||
"address-token",
|
||||
"receive",
|
||||
"transaction",
|
||||
"confirm-tx",
|
||||
],
|
||||
restored: false,
|
||||
},
|
||||
{
|
||||
value: "length",
|
||||
views: [
|
||||
"main",
|
||||
"settings",
|
||||
"settings-addtoken",
|
||||
"wait-tx",
|
||||
"success-tx",
|
||||
"error-tx",
|
||||
],
|
||||
restored: true,
|
||||
},
|
||||
],
|
||||
// that need an address, and lands on every other one.
|
||||
hostileRestore: everyRestorableView("length", [
|
||||
"address",
|
||||
"address-token",
|
||||
"receive",
|
||||
"transaction",
|
||||
"confirm-tx",
|
||||
]),
|
||||
},
|
||||
{
|
||||
field: "selectedAddress",
|
||||
@@ -469,44 +468,25 @@ const CONTRACT = [
|
||||
},
|
||||
// A record that passes EVERY branch's gate at once, driven onto
|
||||
// every restorable view: a branch a view does not read must stay
|
||||
// one it does not read. The six views with no viewData branch
|
||||
// render it, and must survive the fields every branch left behind;
|
||||
// on the five that have one, the guard refuses it.
|
||||
{
|
||||
value: {
|
||||
// one it does not read. The five views with a viewData branch
|
||||
// refuse it; every other one renders it, and must survive the
|
||||
// fields every branch left behind.
|
||||
...everyRestorableView(
|
||||
{
|
||||
hash: "0x1",
|
||||
message: "boom",
|
||||
tx: { hash: "0x1" },
|
||||
pendingTx: { amount: "1" },
|
||||
pendingWait: { hash: "0x1" },
|
||||
},
|
||||
views: [
|
||||
"main",
|
||||
"address",
|
||||
"address-token",
|
||||
"receive",
|
||||
"settings",
|
||||
"settings-addtoken",
|
||||
],
|
||||
restored: true,
|
||||
},
|
||||
{
|
||||
value: {
|
||||
hash: "0x1",
|
||||
message: "boom",
|
||||
tx: { hash: "0x1" },
|
||||
pendingTx: { amount: "1" },
|
||||
pendingWait: { hash: "0x1" },
|
||||
},
|
||||
views: [
|
||||
[
|
||||
"confirm-tx",
|
||||
"transaction",
|
||||
"wait-tx",
|
||||
"success-tx",
|
||||
"error-tx",
|
||||
],
|
||||
restored: false,
|
||||
},
|
||||
),
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -810,19 +790,16 @@ function restoringOnto(view, extra) {
|
||||
|
||||
// A boot that RESTORED is healthy and landed on the view it stored, rather
|
||||
// than falling back to Home — which a healthy boot also does, and which would
|
||||
// let a sweep pass by never running the renderer it is aimed at. `blank` is
|
||||
// reported as bootHealth() reports it, so a boot expected to fall back is still
|
||||
// held to putting something on screen.
|
||||
// let a sweep pass by never running the renderer it is aimed at.
|
||||
async function restoredHealth(profile, view) {
|
||||
const env = await bootPopup(profile);
|
||||
return {
|
||||
errors: env.pageErrors,
|
||||
blank: env.visibleViews().length === 0,
|
||||
restored: env.visibleViews().includes(view),
|
||||
};
|
||||
}
|
||||
|
||||
const RESTORED = { ...HEALTHY, restored: true };
|
||||
const RESTORED = { errors: [], restored: true };
|
||||
|
||||
describe("the base profile the sweep corrupts", () => {
|
||||
for (const view of RESTORABLE_VIEWS) {
|
||||
@@ -977,9 +954,10 @@ describe("every field the router does not read, corrupted at once, onto", () =>
|
||||
|
||||
// The values that only mean something on the restore path: a viewData that
|
||||
// PASSES a branch's gate and then hands its renderer something dereferenced,
|
||||
// and a selectedWallet the floor turns into nothing selected. Each boot is held
|
||||
// to health and to where its entry says it lands, on its view or back on Home,
|
||||
// so a value written for one renderer cannot stop reaching it and still pass.
|
||||
// and a selectedWallet the floor turns into nothing selected. Each boot must
|
||||
// throw nothing and show exactly the view its entry says it lands on: its own,
|
||||
// or Home, so a value written for one renderer cannot stop reaching it and
|
||||
// still pass.
|
||||
describe("a restore-only hostile value onto", () => {
|
||||
for (const row of CONTRACT) {
|
||||
for (const entry of row.hostileRestore || []) {
|
||||
@@ -987,14 +965,15 @@ describe("a restore-only hostile value onto", () => {
|
||||
test(`${view}: ${row.field} = ${JSON.stringify(
|
||||
entry.value,
|
||||
)}`, async () => {
|
||||
await expect(
|
||||
restoredHealth(
|
||||
restoringOnto(view, { [row.field]: entry.value }),
|
||||
view,
|
||||
),
|
||||
).resolves.toEqual({
|
||||
...HEALTHY,
|
||||
restored: entry.restored,
|
||||
const env = await bootPopup(
|
||||
restoringOnto(view, { [row.field]: entry.value }),
|
||||
);
|
||||
expect({
|
||||
errors: env.pageErrors,
|
||||
visible: env.visibleViews(),
|
||||
}).toEqual({
|
||||
errors: [],
|
||||
visible: [entry.restored ? view : "main"],
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user