From d9f0389c806ca58b4ae5df2cc4494afaf6304624 Mon Sep 17 00:00:00 2001
From: David de Kloet <122978264+dskloetd@users.noreply.github.com>
Date: Thu, 19 Dec 2024 14:32:54 +0100
Subject: [PATCH] Fix: Show error in USD banner on projects page (#6049)
# Motivation
On the projects table page, if you don't have any neurons, we show a
banner inviting you to stake a neurons.
For this reason, and because your total stake with 0 neurons is always
$0, we hide the total USD value banner on the projects table page if we
show the other banner.
The problem is that the logic used for this just checked if the total
USD value of neurons was 0. But if there is an error loading ICP Swap
tickers, we calculate your total stake in USD as 0 as well, but we do
want to show the banner in an error state.
So we need to check the actual number of neurons instead of using the
total value as a shortcut for not having neurons.
# Changes
1. Check if the user has any neurons to decide on showing the USD value
banner.
# Tests
1. Add a unit test testing the error state of the banner.
2. Tested manually by changing `queryIcpSwapTickers` to return an error.
# Todos
- [ ] Add entry to changelog (if necessary).
not necessary
---
.../components/staking/ProjectsTable.svelte | 7 +++-
.../components/staking/ProjectsTable.spec.ts | 42 +++++++++++++++++++
2 files changed, 48 insertions(+), 1 deletion(-)
diff --git a/frontend/src/lib/components/staking/ProjectsTable.svelte b/frontend/src/lib/components/staking/ProjectsTable.svelte
index 9cdfe618624..cb181371e79 100644
--- a/frontend/src/lib/components/staking/ProjectsTable.svelte
+++ b/frontend/src/lib/components/staking/ProjectsTable.svelte
@@ -88,6 +88,11 @@
let sortedTableProjects: TableProject[];
$: sortedTableProjects = sortTableProjects(tableProjects);
+ let hasAnyNeurons: boolean;
+ $: hasAnyNeurons = tableProjects.some(
+ (project) => project.neuronCount ?? 0 > 0
+ );
+
let totalStakeInUsd: number;
$: totalStakeInUsd = getTotalStakeInUsd(tableProjects);
@@ -113,7 +118,7 @@
- {#if $authSignedInStore && $ENABLE_USD_VALUES_FOR_NEURONS && totalStakeInUsd > 0}
+ {#if $authSignedInStore && $ENABLE_USD_VALUES_FOR_NEURONS && hasAnyNeurons}
diff --git a/frontend/src/tests/lib/components/staking/ProjectsTable.spec.ts b/frontend/src/tests/lib/components/staking/ProjectsTable.spec.ts
index 98d7d2371fb..285b000ffe6 100644
--- a/frontend/src/tests/lib/components/staking/ProjectsTable.spec.ts
+++ b/frontend/src/tests/lib/components/staking/ProjectsTable.spec.ts
@@ -616,6 +616,14 @@ describe("ProjectsTable", () => {
expect(
await po.getUsdValueBannerPo().getTotalsTooltipIconPo().isPresent()
).toBe(false);
+ expect(
+ await po
+ .getUsdValueBannerPo()
+ .getExchangeRateTooltipIconPo()
+ .getTooltipText()
+ ).toBe(
+ "1 ICP = $10.00 Token prices are in ckUSDC based on data provided by ICPSwap."
+ );
});
it("should ignore tokens with unknown balance in USD when adding up the total", async () => {
@@ -651,6 +659,40 @@ describe("ProjectsTable", () => {
await po.getUsdValueBannerPo().getTotalsTooltipIconPo().isPresent()
).toBe(true);
});
+
+ it("should show total USD banner when tickers fail to load", async () => {
+ overrideFeatureFlagsStore.setFlag("ENABLE_USD_VALUES_FOR_NEURONS", true);
+
+ neuronsStore.setNeurons({
+ neurons: [nnsNeuronWithStake],
+ certified: true,
+ });
+ snsNeuronsStore.setNeurons({
+ rootCanisterId: snsCanisterId,
+ neurons: [snsNeuronWithStake],
+ certified: true,
+ });
+
+ const error = new Error("ICPSwap failed");
+ vi.spyOn(console, "error").mockReturnValue();
+ vi.spyOn(icpSwapApi, "queryIcpSwapTickers").mockRejectedValue(error);
+
+ const po = renderComponent();
+ await runResolvedPromises();
+
+ expect(await po.getUsdValueBannerPo().isPresent()).toBe(true);
+ expect(await po.getUsdValueBannerPo().getPrimaryAmount()).toBe("$-/-");
+ expect(
+ await po
+ .getUsdValueBannerPo()
+ .getExchangeRateTooltipIconPo()
+ .getTooltipText()
+ ).toBe(
+ "ICPSwap API is currently unavailable, token prices cannot be fetched at the moment."
+ );
+ expect(console.error).toBeCalledWith(error);
+ expect(console.error).toBeCalledTimes(1);
+ });
});
it("should update table when universes store changes", async () => {