Skip to content

Commit

Permalink
Refresh voting power from details (#6006)
Browse files Browse the repository at this point in the history
# Motivation

If there are inactive neurons, the user should be able to reset their
voting-power-refreshed timestamp from the neuron details page. In this
PR, we add a ["Confirm Following"
button](#5990) to the neuron
status field. It should be shown for all statuses except when the
followings of a neuron have already been reset.

# Changes

- Add the `ConfirmFollowingButton` to the `NnsNeuronRewardStatusAction`
component.

# Tests

- Updated.
- Tested locally:


https://github.com/user-attachments/assets/70d159fc-ee22-408e-b013-097f16a36e54


# Todos

- [ ] Add entry to changelog (if necessary).
Not necessary.
  • Loading branch information
mstrasinskis authored Dec 15, 2024
1 parent d904b17 commit 6c53255
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import { secondsToDuration } from "@dfinity/utils";
import { replacePlaceholders } from "$lib/utils/i18n.utils";
import FollowNeuronsButton from "./actions/FollowNeuronsButton.svelte";
import ConfirmFollowingButton from "./actions/ConfirmFollowingButton.svelte";
import { secondsToDissolveDelayDuration } from "$lib/utils/date.utils";
import { START_REDUCING_VOTING_POWER_AFTER_SECONDS } from "$lib/constants/neurons.constants";
Expand Down Expand Up @@ -101,8 +102,9 @@

{#if isFollowingReset}
<FollowNeuronsButton />
{:else}
<ConfirmFollowingButton neuronIds={[neuron.neuronId]} />
{/if}
<!-- TODO(mstr): Add a button to confirm a single following. -->
</CommonItemAction>

<style lang="scss">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import * as governanceApi from "$lib/api/governance.api";
import {
SECONDS_IN_DAY,
SECONDS_IN_HALF_YEAR,
SECONDS_IN_MONTH,
} from "$lib/constants/constants";
import { neuronsStore } from "$lib/stores/neurons.store";
import { nowInSeconds } from "$lib/utils/date.utils";
import { mockIdentity, resetIdentity } from "$tests/mocks/auth.store.mock";
import { mockFullNeuron, mockNeuron } from "$tests/mocks/neurons.mock";
import { NnsNeuronRewardStatusActionPo } from "$tests/page-objects/NnsNeuronRewardStatusAction.page-object";
import { JestPageObjectElement } from "$tests/page-objects/jest.page-object";
import { runResolvedPromises } from "$tests/utils/timers.test-utils";
import { type NeuronInfo } from "@dfinity/nns";
import { render } from "@testing-library/svelte";
import NnsNeuronRewardStatusActionTest from "./NnsNeuronRewardStatusActionTest.svelte";
Expand Down Expand Up @@ -42,6 +46,7 @@ describe("NnsNeuronRewardStatusAction", () => {
expect(await po.getDescription()).toBe(
"182 days, 15 hours to confirm following"
);
expect(await po.getConfirmFollowingButtonPo().isPresent()).toBe(true);
expect(await po.getFollowNeuronsButtonPo().isPresent()).toBe(false);
});

Expand All @@ -62,6 +67,7 @@ describe("NnsNeuronRewardStatusAction", () => {
expect(await po.getDescription()).toBe(
`${tenDays} days to confirm following`
);
expect(await po.getConfirmFollowingButtonPo().isPresent()).toBe(true);
expect(await po.getFollowNeuronsButtonPo().isPresent()).toBe(false);
});

Expand All @@ -81,6 +87,7 @@ describe("NnsNeuronRewardStatusAction", () => {
expect(await po.getDescription()).toBe(
"Confirm following or vote manually to continue receiving rewards"
);
expect(await po.getConfirmFollowingButtonPo().isPresent()).toBe(true);
expect(await po.getFollowNeuronsButtonPo().isPresent()).toBe(false);
});

Expand All @@ -92,6 +99,7 @@ describe("NnsNeuronRewardStatusAction", () => {
votingPowerRefreshedTimestampSeconds: BigInt(
nowInSeconds() - SECONDS_IN_HALF_YEAR - SECONDS_IN_MONTH
),
controller: mockIdentity.getPrincipal().toText(),
},
};
const po = renderComponent(testNeuron);
Expand All @@ -100,6 +108,44 @@ describe("NnsNeuronRewardStatusAction", () => {
expect(await po.getDescription()).toBe(
"Following has been reset. Confirm following or vote manually to continue receiving rewards"
);
expect(await po.getConfirmFollowingButtonPo().isPresent()).toBe(false);
expect(await po.getFollowNeuronsButtonPo().isPresent()).toBe(true);
});

it("should refresh voting power", async () => {
const testNeuron = {
...mockNeuron,
fullNeuron: {
...mockFullNeuron,
votingPowerRefreshedTimestampSeconds: BigInt(
nowInSeconds() - SECONDS_IN_HALF_YEAR + 10 * SECONDS_IN_DAY
),
controller: mockIdentity.getPrincipal().toText(),
},
};
resetIdentity();
neuronsStore.setNeurons({
neurons: [testNeuron],
certified: true,
});
vi.spyOn(governanceApi, "queryNeurons").mockResolvedValue([testNeuron]);
const spyRefreshVotingPower = vi
.spyOn(governanceApi, "refreshVotingPower")
.mockResolvedValue();
vi.spyOn(governanceApi, "queryKnownNeurons").mockResolvedValue([]);

const po = renderComponent(testNeuron);

expect(spyRefreshVotingPower).toHaveBeenCalledTimes(0);

expect(await po.getConfirmFollowingButtonPo().isPresent()).toBe(true);
await po.getConfirmFollowingButtonPo().click();
await runResolvedPromises();

expect(spyRefreshVotingPower).toHaveBeenCalledTimes(1);
expect(spyRefreshVotingPower).toHaveBeenCalledWith({
identity: mockIdentity,
neuronId: testNeuron.neuronId,
});
});
});
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { BasePageObject } from "$tests/page-objects/base.page-object";
import type { PageObjectElement } from "$tests/types/page-object.types";
import { ConfirmFollowingButtonPo } from "./ConfirmFollowingButton.page-object";
import { FollowNeuronsButtonPo } from "./FollowNeuronsButton.page-object";

export class NnsNeuronRewardStatusActionPo extends BasePageObject {
Expand All @@ -19,6 +20,10 @@ export class NnsNeuronRewardStatusActionPo extends BasePageObject {
return this.getText("state-description");
}

getConfirmFollowingButtonPo(): ConfirmFollowingButtonPo {
return ConfirmFollowingButtonPo.under(this.root);
}

getFollowNeuronsButtonPo(): FollowNeuronsButtonPo {
return FollowNeuronsButtonPo.under({
element: this.root,
Expand Down

0 comments on commit 6c53255

Please sign in to comment.