1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-04 23:14:56 +01:00
metamask-extension/app/scripts/controllers/transactions/lib/tx-state-history-helpers.test.js
Mark Stacey ba54a3d83b
Update ESLint config to v8 (#12886)
The ESLint config has been updated to v8. The breaking changes are:

* The Prettier rule `quoteProps` has been changed from `consistent` to
`as-needed`, meaning that if one key requires quoting, only that key is
quoted rather than all keys.
* The ESLint rule `no-shadow` has been made more strict. It now
prevents globals from being shadowed as well.

Most of these changes were applied with `yarn lint:fix`. Only the
shadowing changes required manual fixing (shadowing variable names were
either replaced with destructuring or renamed).

The dependency `globalThis` was added to the list of dynamic
dependencies in the build system, where it should have been already.
This was causing `depcheck` to fail because the new lint rules required
removing the one place where `globalThis` had been erroneously imported
previously.

A rule requiring a newline between multiline blocks and expressions has
been disabled temporarily to make this PR smaller and to avoid
introducing conflicts with other PRs.
2021-12-09 15:36:24 -03:30

165 lines
4.8 KiB
JavaScript

import { strict as assert } from 'assert';
import testData from '../../../../../test/data/mock-tx-history.json';
import {
snapshotFromTxMeta,
migrateFromSnapshotsToDiffs,
replayHistory,
generateHistoryEntry,
} from './tx-state-history-helpers';
describe('Transaction state history helper', function () {
describe('#snapshotFromTxMeta', function () {
it('should clone deep', function () {
const input = {
foo: {
bar: {
bam: 'baz',
},
},
};
const output = snapshotFromTxMeta(input);
assert.ok('foo' in output, 'has a foo key');
assert.ok('bar' in output.foo, 'has a bar key');
assert.ok('bam' in output.foo.bar, 'has a bar key');
assert.equal(output.foo.bar.bam, 'baz', 'has a baz value');
});
it('should remove the history key', function () {
const input = { foo: 'bar', history: 'remembered' };
const output = snapshotFromTxMeta(input);
assert.equal(typeof output.history, 'undefined', 'should remove history');
});
});
describe('#migrateFromSnapshotsToDiffs', function () {
it('migrates history to diffs and can recover original values', function () {
testData.TransactionsController.transactions.forEach((tx) => {
const newHistory = migrateFromSnapshotsToDiffs(tx.history);
newHistory.forEach((newEntry, index) => {
if (index === 0) {
assert.equal(
Array.isArray(newEntry),
false,
'initial history item IS NOT a json patch obj',
);
} else {
assert.equal(
Array.isArray(newEntry),
true,
'non-initial history entry IS a json patch obj',
);
}
const oldEntry = tx.history[index];
const historySubset = newHistory.slice(0, index + 1);
const reconstructedValue = replayHistory(historySubset);
assert.deepEqual(
oldEntry,
reconstructedValue,
'was able to reconstruct old entry from diffs',
);
});
});
});
});
describe('#replayHistory', function () {
it('replaying history does not mutate the original object', function () {
const initialState = { test: true, message: 'hello', value: 1 };
const diff1 = [
{
op: 'replace',
path: '/message',
value: 'haay',
},
];
const diff2 = [
{
op: 'replace',
path: '/value',
value: 2,
},
];
const history = [initialState, diff1, diff2];
const beforeStateSnapshot = JSON.stringify(initialState);
const latestState = replayHistory(history);
const afterStateSnapshot = JSON.stringify(initialState);
assert.notEqual(
initialState,
latestState,
'initial state is not the same obj as the latest state',
);
assert.equal(
beforeStateSnapshot,
afterStateSnapshot,
'initial state is not modified during run',
);
});
});
describe('#generateHistoryEntry', function () {
function generateHistoryEntryTest(note) {
const prevState = {
someValue: 'value 1',
foo: {
bar: {
bam: 'baz',
},
},
};
const nextState = {
newPropRoot: 'new property - root',
someValue: 'value 2',
foo: {
newPropFirstLevel: 'new property - first level',
bar: {
bam: 'baz',
},
},
};
const timeBefore = new Date().getTime();
const result = generateHistoryEntry(prevState, nextState, note);
const timeAfter = new Date().getTime();
assert.ok(Array.isArray(result));
assert.equal(result.length, 3);
const expectedEntry1 = {
op: 'add',
path: '/foo/newPropFirstLevel',
value: 'new property - first level',
};
assert.equal(result[0].op, expectedEntry1.op);
assert.equal(result[0].path, expectedEntry1.path);
assert.equal(result[0].value, expectedEntry1.value);
assert.equal(result[0].note, note);
assert.ok(
result[0].timestamp >= timeBefore && result[0].timestamp <= timeAfter,
);
const expectedEntry2 = {
op: 'replace',
path: '/someValue',
value: 'value 2',
};
assert.deepEqual(result[1], expectedEntry2);
const expectedEntry3 = {
op: 'add',
path: '/newPropRoot',
value: 'new property - root',
};
assert.deepEqual(result[2], expectedEntry3);
}
it('should generate history entries', function () {
generateHistoryEntryTest();
});
it('should add note to first entry', function () {
generateHistoryEntryTest('custom note');
});
});
});