Skip to content

Commit

Permalink
Wallet Sync - Non imported accounts Unit Tests (#7528)
Browse files Browse the repository at this point in the history
support(live-wallet): Added unit tests to cover non imported accounts
  • Loading branch information
cgrellard-ledger committed Aug 9, 2024
1 parent 3c19077 commit 1353e7a
Show file tree
Hide file tree
Showing 4 changed files with 402 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .changeset/orange-balloons-poke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@ledgerhq/live-wallet": patch
---

LIVE-WALLET - Test non imported accounts
271 changes: 270 additions & 1 deletion libs/live-wallet/src/walletsync/__tests__/modules/accounts.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import timemachine from "timemachine";
import { of, throwError } from "rxjs";
import { Account } from "@ledgerhq/types-live";
import manager from "../../modules/accounts";
import manager, { NonImportedAccountInfo } from "../../modules/accounts";
import { WalletSyncDataManagerResolutionContext } from "../../types";
import { genAccount } from "@ledgerhq/coin-framework/mocks/account";
import { accountDataToAccount } from "../../../liveqr/cross";
Expand All @@ -11,9 +11,24 @@ timemachine.config({
});

const account1 = genAccount("live-wallet-1");
const account1NonImported: NonImportedAccountInfo = {
id: account1.id,
attempts: 1,
attemptsLastTimestamp: new Date().getTime() - 1000,
};
const account2 = genAccount("live-wallet-2");
const account2NonImported: NonImportedAccountInfo = {
id: account2.id,
attempts: 1,
attemptsLastTimestamp: new Date().getTime() - 1000,
};
const account3 = genAccount("live-wallet-3");
const account4unsupported = genAccount("live-wallet-4");
const account4unsupportedNonImported: NonImportedAccountInfo = {
id: account4unsupported.id,
attempts: 1,
attemptsLastTimestamp: new Date().getTime() - 1000,
};

// we make this type static because the module is not supposed to change it over time!
type AccountDescriptor = {
Expand Down Expand Up @@ -335,4 +350,258 @@ describe("accountNames' WalletSyncDataManager", () => {
const result = manager.applyUpdate(localData, diff.update);
expect(result.list.map(l => l.id)).toEqual([account1, account2, account3].map(l => l.id));
});

it("should not have changes when there is no incoming state", async () => {
const localData = { list: [], nonImportedAccountInfos: [] };
const latestState = null;
const incomingState = null;
const diff = await manager.resolveIncrementalUpdate(
dummyContext,
localData,
latestState,
incomingState,
);
expect(diff).toEqual({ hasChanges: false });
});

it("should ignore a non imported account that is now present in the localData", async () => {
const localData = {
list: [account1],
nonImportedAccountInfos: [account1NonImported],
};
const latestState = [account1].map(convertAccountToDescriptor);
const incomingState = [account1].map(convertAccountToDescriptor);
const diff = await manager.resolveIncrementalUpdate(
dummyContext,
localData,
latestState,
incomingState,
);
expect(diff).toMatchObject({
hasChanges: true,
update: {
added: [],
removed: [],
nonImportedAccountInfos: [],
},
});
});
it("should ignore a non imported account that is not present in the incomingState anymore", async () => {
const localData = {
list: [],
nonImportedAccountInfos: [account1NonImported],
};
const latestState = [].map(convertAccountToDescriptor);
const incomingState = [].map(convertAccountToDescriptor);
const diff = await manager.resolveIncrementalUpdate(
dummyContext,
localData,
latestState,
incomingState,
);
expect(diff).toMatchObject({
hasChanges: true,
update: {
added: [],
removed: [],
nonImportedAccountInfos: [],
},
});
});
it("should retry importation of a non imported account if it has been long enough", async () => {
const localData = {
list: [],
nonImportedAccountInfos: [
{ ...account1NonImported, attemptsLastTimestamp: new Date().getTime() - 60000 },
],
};
const latestState = [account1].map(convertAccountToDescriptor);
const incomingState = [account1].map(convertAccountToDescriptor);
const diff = await manager.resolveIncrementalUpdate(
dummyContext,
localData,
latestState,
incomingState,
);
expect(diff).toMatchObject({
hasChanges: true,
update: {
added: [placeholderAccountFromDescriptor(incomingState[0])],
removed: [],
nonImportedAccountInfos: [],
},
});
});
it("should avoid importing duplicate of a non imported account if it has been removed from the latest state", async () => {
const localData = {
list: [],
nonImportedAccountInfos: [
{ ...account1NonImported, attemptsLastTimestamp: new Date().getTime() - 60000 },
],
};
const latestState = [].map(convertAccountToDescriptor);
const incomingState = [account1].map(convertAccountToDescriptor);
const diff = await manager.resolveIncrementalUpdate(
dummyContext,
localData,
latestState,
incomingState,
);
expect(diff).toMatchObject({
hasChanges: true,
update: {
added: [placeholderAccountFromDescriptor(incomingState[0])],
removed: [],
nonImportedAccountInfos: [],
},
});
});
it("should not retry importation of a non imported account if it has not been long enough", async () => {
const localData = {
list: [],
nonImportedAccountInfos: [account1NonImported],
};
const latestState = [account1].map(convertAccountToDescriptor);
const incomingState = [account1].map(convertAccountToDescriptor);
const diff = await manager.resolveIncrementalUpdate(
dummyContext,
localData,
latestState,
incomingState,
);
expect(diff).toMatchObject({
hasChanges: false,
});
});
it("should not retry importation of a non imported account if it has not been long enough even if there is a new account", async () => {
const localData = {
list: [],
nonImportedAccountInfos: [account1NonImported],
};
const latestState = [account1].map(convertAccountToDescriptor);
const incomingState = [account1, account2].map(convertAccountToDescriptor);
const diff = await manager.resolveIncrementalUpdate(
dummyContext,
localData,
latestState,
incomingState,
);
expect(diff).toMatchObject({
hasChanges: true,
update: {
added: [placeholderAccountFromDescriptor(incomingState[1])],
removed: [],
nonImportedAccountInfos: [account1NonImported],
},
});
});
it("should retry importation of a non imported account if it has been long enough even if there is a new account", async () => {
const localData = {
list: [],
nonImportedAccountInfos: [
{ ...account1NonImported, attemptsLastTimestamp: new Date().getTime() - 60000 },
],
};
const latestState = [account1].map(convertAccountToDescriptor);
const incomingState = [account1, account2].map(convertAccountToDescriptor);
const diff = await manager.resolveIncrementalUpdate(
dummyContext,
localData,
latestState,
incomingState,
);
expect(diff).toMatchObject({
hasChanges: true,
update: {
added: [
placeholderAccountFromDescriptor(incomingState[1]),
placeholderAccountFromDescriptor(incomingState[0]),
],
removed: [],
nonImportedAccountInfos: [],
},
});
});
it("should retry importation of a non imported account if it has been long enough and not retry importation of another if it has not been long enough", async () => {
const localData = {
list: [],
nonImportedAccountInfos: [
{ ...account1NonImported, attemptsLastTimestamp: new Date().getTime() - 60000 },
account2NonImported,
],
};
const latestState = [account1, account2].map(convertAccountToDescriptor);
const incomingState = [account1, account2].map(convertAccountToDescriptor);
const diff = await manager.resolveIncrementalUpdate(
dummyContext,
localData,
latestState,
incomingState,
);
expect(diff).toMatchObject({
hasChanges: true,
update: {
added: [placeholderAccountFromDescriptor(incomingState[0])],
removed: [],
nonImportedAccountInfos: [account2NonImported],
},
});
});
it("should have a longer delay when we tried importing an account multiple times", async () => {
const localData = {
list: [],
nonImportedAccountInfos: [
{
...account1NonImported,
attempts: 10,
attemptsLastTimestamp: new Date().getTime() - 60000,
},
],
};
const latestState = [account1].map(convertAccountToDescriptor);
const incomingState = [account1].map(convertAccountToDescriptor);
const diff = await manager.resolveIncrementalUpdate(
dummyContext,
localData,
latestState,
incomingState,
);
expect(diff).toMatchObject({
hasChanges: false,
});
});
it("should increment progressively the delay between importation retries when it keeps failing", async () => {
const localData = {
list: [],
nonImportedAccountInfos: [
{
...account4unsupportedNonImported,
attempts: 10,
attemptsLastTimestamp: new Date().getTime() - 60000 * 10,
},
],
};
const latestState = [account4unsupported].map(convertAccountToDescriptor);
const incomingState = [account4unsupported].map(convertAccountToDescriptor);
const diff = await manager.resolveIncrementalUpdate(
dummyContext,
localData,
latestState,
incomingState,
);
expect(diff).toMatchObject({
hasChanges: true,
update: {
added: [],
removed: [],
nonImportedAccountInfos: [
{
...account4unsupportedNonImported,
attempts: 11,
attemptsLastTimestamp: new Date().getTime(),
},
],
},
});
});
});
Loading

0 comments on commit 1353e7a

Please sign in to comment.