Skip to content

Commit

Permalink
feat: ✨ (llm)add new accounts list to wallet centric screen
Browse files Browse the repository at this point in the history
  • Loading branch information
LucasWerey committed Jan 6, 2025
1 parent 8cd1ab1 commit a442278
Show file tree
Hide file tree
Showing 18 changed files with 1,198 additions and 111 deletions.
5 changes: 5 additions & 0 deletions .changeset/fifty-toes-sit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"live-mobile": minor
---

Implementation of the new accounts list inside wallet centric screen.
48 changes: 46 additions & 2 deletions apps/ledger-live-mobile/__tests__/test-renderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { configureStore } from "@reduxjs/toolkit";
import reducers from "~/reducers";
import StyleProvider from "~/StyleProvider";
import { State } from "~/reducers/types";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";

import { INITIAL_STATE as ACCOUNTS_INITIAL_STATE } from "~/reducers/accounts";
import { INITIAL_STATE as SETTINGS_INITIAL_STATE } from "~/reducers/settings";
Expand All @@ -36,7 +37,6 @@ import { INITIAL_STATE as WALLETSYNC_INITIAL_STATE } from "~/reducers/walletSync
import { initialState as WALLET_INITIAL_STATE } from "@ledgerhq/live-wallet/store";
import QueuedDrawersContextProvider from "LLM/components/QueuedDrawer/QueuedDrawersContextProvider";
import { INITIAL_STATE as TRUSTCHAIN_INITIAL_STATE } from "@ledgerhq/ledger-key-ring-protocol/store";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";

const initialState = {
accounts: ACCOUNTS_INITIAL_STATE,
Expand Down Expand Up @@ -134,10 +134,54 @@ const customRenderHook = <Result,>(
return { store, ...rntlRenderHook(hook, { wrapper: ProvidersWrapper, ...renderOptions }) };
};

const renderWithReactQuery = (
ui: React.ReactElement,
{
overrideInitialState: overrideInitialState = state => state,
userEventOptions = {},
...renderOptions
}: ExtraOptions = {},
) => {
const store = configureStore({
reducer: reducers,
middleware: getDefaultMiddleware =>
getDefaultMiddleware({ serializableCheck: false, immutableCheck: false }),
preloadedState: overrideInitialState(initialState),
devTools: false,
});

const ProvidersWrapper: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const queryClient = new QueryClient();
return (
<QueryClientProvider client={queryClient}>
<Provider store={store}>
<StyleProvider selectedPalette="dark">
<FirebaseFeatureFlagsProvider getFeature={getFeature}>
<AnalyticsContextProvider>
<QueuedDrawersContextProvider>
<I18nextProvider i18n={i18n}>
<NavigationContainer>{children}</NavigationContainer>
</I18nextProvider>
</QueuedDrawersContextProvider>
</AnalyticsContextProvider>
</FirebaseFeatureFlagsProvider>
</StyleProvider>
</Provider>
</QueryClientProvider>
);
};

return {
user: userEvent.setup(userEventOptions),
QueryClient,
...rntlRender(ui, { wrapper: ProvidersWrapper, ...renderOptions }),
};
};

export const LONG_TIMEOUT = 30000;

// re-export everything
export * from "@testing-library/react-native";

// override render method
export { customRender as render, customRenderHook as renderHook };
export { customRender as render, customRenderHook as renderHook, renderWithReactQuery };
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { CryptoOrTokenCurrency } from "@ledgerhq/types-cryptoassets";
import { AccountLike, ProtoNFT } from "@ledgerhq/types-live";
import { Account, AccountLike, ProtoNFT, TokenAccount } from "@ledgerhq/types-live";
import { ScreenName } from "~/const";

export type AccountsNavigatorParamList = {
Expand Down Expand Up @@ -39,5 +39,6 @@ export type AccountsNavigatorParamList = {
showHeader?: boolean;
canAddAccount?: boolean;
isSyncEnabled?: boolean;
specificAccounts?: Account[] | TokenAccount[];
};
};
1 change: 1 addition & 0 deletions apps/ledger-live-mobile/src/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -3979,6 +3979,7 @@
},
"addAccounts": {
"addNew": "Add new",
"seeAllAccounts": "See all accounts",
"addNewOrExisting": "Add new or existing account",
"supportLinks": {
"segwit_or_native_segwit": "Segwit or Native segwit?"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import React from "react";
import { renderWithReactQuery } from "@tests/test-renderer";
import { State } from "~/reducers/types";
import { MockedAccounts } from "./mockedAccounts";
import AccountsList from "../screens/AccountsList";
import { AccountsListNavigator } from "../screens/AccountsList/types";
import { ScreenName } from "~/const";
import { createStackNavigator } from "@react-navigation/stack";
const INITIAL_STATE = {
overrideInitialState: (state: State) => ({
...state,
accounts: MockedAccounts,
settings: {
...state.settings,
readOnlyModeEnabled: false,
overriddenFeatureFlags: {
llmAccountListUI: {
enabled: true,
},
llmWalletSync: {
enabled: true,
params: {
environment: "STAGING",
watchConfig: {
pollingInterval: 10000,
initialTimeout: 5000,
userIntentDebounce: 1000,
},
},
},
},
},
}),
};

describe("AccountsList Screen", () => {
const renderComponent = (params: AccountsListNavigator[ScreenName.AccountsList]) => {
const Stack = createStackNavigator<AccountsListNavigator>();

return renderWithReactQuery(
<Stack.Navigator screenOptions={{ headerShown: false }}>
<Stack.Screen
name={ScreenName.AccountsList}
component={AccountsList}
initialParams={params}
/>
</Stack.Navigator>,
{
...INITIAL_STATE,
},
);
};

it("should render with canAddAccount true", () => {
const { getByText } = renderComponent({
sourceScreenName: ScreenName.AccountsList,
canAddAccount: true,
});
expect(getByText(/add new or existing account/i)).toBeVisible();
});

it("should render with showHeader true", () => {
const { getByText } = renderComponent({
sourceScreenName: ScreenName.AccountsList,
showHeader: true,
});
expect(getByText(/accounts/i)).toBeVisible();
});

it("should render with showHeader and canAddAccount true", () => {
const { getByText } = renderComponent({
sourceScreenName: ScreenName.AccountsList,
showHeader: true,
canAddAccount: true,
});
expect(getByText(/accounts/i)).toBeVisible();
expect(getByText(/add new or existing account/i)).toBeVisible();
});

it("should render the accounts list", () => {
const { getByText } = renderComponent({
sourceScreenName: ScreenName.AccountsList,
showHeader: true,
canAddAccount: true,
});
const lineaAccount = getByText(/linea 2/i);
const ethClassicAccount = getByText(/ethereum classic 2/i);
const energyWebAccount = getByText(/energy web 2/i);
const dogecoinAccount = getByText(/dogecoin 2/i);
const dashAccount = getByText(/dash 2/i);
const cronosAccount = getByText(/cronos 2/i);

[
lineaAccount,
ethClassicAccount,
energyWebAccount,
dogecoinAccount,
dashAccount,
cronosAccount,
].forEach(account => {
expect(account).toBeVisible();
});
});

it("should render only the Linea account", () => {
const { getByText } = renderComponent({
sourceScreenName: ScreenName.AccountsList,
showHeader: true,
specificAccounts: [MockedAccounts.active[0]],
});

expect(getByText(/cronos 2/i)).toBeVisible();
expect(getByText(/cro accounts/i)).toBeVisible();
});

it("should open the add accounts drawer when there is no account specified", async () => {
const { getByText, user } = renderComponent({
sourceScreenName: ScreenName.AccountsList,
showHeader: true,
canAddAccount: true,
});

await user.press(getByText(/add new or existing account/i));
expect(getByText(/add another account/i)).toBeVisible();
expect(getByText(/use your ledger device/i)).toBeVisible();
expect(getByText(/use ledger sync/i)).toBeVisible();
});
});
Loading

0 comments on commit a442278

Please sign in to comment.