Persistent nodedb (#780)

* Refactor  and consolitdate store imports

- Created a new index file in the core stores directory to export all stores from a single module.
- Updated imports to use consolidated store exports.

* Remove unnecessary import

* Update imports

* First steps to persist nodeDB

* Use named exports

* Change store import after merge

* Persistent nodeDB initial work

* Key mishmatch warning, new serialization handler

* Minor copilot changes

* Add NODEDB_RETENTION_NUM

* Updated tests

* Refactor PKI mismatch logic

* Clear persisted db on reset

* Only persist on featureFlag

* Mock featureFlag in tests

---------

Co-authored-by: philon- <philon-@users.noreply.github.com>
This commit is contained in:
Jeremy Gallant
2025-08-24 09:23:20 -04:00
committed by GitHub
co-authored by philon-
parent e33463b371
commit 68ec7ee5d8
43 changed files with 1335 additions and 476 deletions
@@ -1,4 +1,4 @@
import { fireEvent, render, screen } from "@testing-library/react";
import { fireEvent, render, screen, act } from "@testing-library/react";
import type {
ButtonHTMLAttributes,
ClassAttributes,
@@ -89,7 +89,9 @@ describe("RebootDialog", () => {
render(<RebootDialog open onOpenChange={() => {}} />);
// Schedule non-OTA reboot
fireEvent.click(screen.getByTestId("scheduleRebootBtn"));
act(() => {
fireEvent.click(screen.getByTestId("scheduleRebootBtn"));
});
expect(rebootMock).toHaveBeenCalledWith(5);
expect(rebootOtaMock).not.toHaveBeenCalled();
@@ -97,7 +99,9 @@ describe("RebootDialog", () => {
rebootOtaMock.mockClear();
// Cancel scheduled
fireEvent.click(screen.getByTestId("cancelRebootBtn"));
act(() => {
fireEvent.click(screen.getByTestId("cancelRebootBtn"));
});
expect(rebootMock).toHaveBeenCalledWith(-1);
expect(rebootOtaMock).not.toHaveBeenCalled();
@@ -105,8 +109,12 @@ describe("RebootDialog", () => {
rebootOtaMock.mockClear();
// Schedule OTA reboot
fireEvent.click(screen.getByText(/reboot into ota mode/i));
fireEvent.click(screen.getByTestId("scheduleRebootBtn"));
act(() => {
fireEvent.click(screen.getByText(/reboot into ota mode/i));
});
act(() => {
fireEvent.click(screen.getByTestId("scheduleRebootBtn"));
});
expect(rebootOtaMock).toHaveBeenCalledWith(5);
expect(rebootMock).not.toHaveBeenCalled();
});
@@ -115,17 +123,23 @@ describe("RebootDialog", () => {
const onOpenChangeMock = vi.fn();
render(<RebootDialog open onOpenChange={onOpenChangeMock} />);
fireEvent.change(screen.getByPlaceholderText(/enter delay/i), {
target: { value: "3" },
act(() => {
fireEvent.change(screen.getByPlaceholderText(/enter delay/i), {
target: { value: "3" },
});
});
fireEvent.click(screen.getByTestId("scheduleRebootBtn"));
act(() => {
fireEvent.click(screen.getByTestId("scheduleRebootBtn"));
});
expect(rebootMock).toHaveBeenCalledWith(3);
expect(screen.getByText(/reboot has been scheduled/i)).toBeInTheDocument();
vi.advanceTimersByTime(3000);
act(() => {
vi.advanceTimersByTime(3000);
});
expect(onOpenChangeMock).toHaveBeenCalledWith(false);
@@ -135,7 +149,9 @@ describe("RebootDialog", () => {
const onOpenChangeMock = vi.fn();
render(<RebootDialog open onOpenChange={onOpenChangeMock} />);
fireEvent.click(screen.getByRole("button", { name: /reboot now/i }));
act(() => {
fireEvent.click(screen.getByRole("button", { name: /reboot now/i }));
});
expect(rebootMock).toHaveBeenCalledWith(0);
expect(onOpenChangeMock).toHaveBeenCalledWith(false);
@@ -148,9 +164,13 @@ describe("RebootDialog", () => {
render(<RebootDialog open onOpenChange={onOpenChangeMock} />);
fireEvent.click(screen.getByTestId("scheduleRebootBtn"));
act(() => {
fireEvent.click(screen.getByTestId("scheduleRebootBtn"));
});
vi.advanceTimersByTime(5000);
act(() => {
vi.advanceTimersByTime(5000);
});
expect(rebootMock).not.toHaveBeenCalled();
expect(rebootOtaMock).not.toHaveBeenCalled();
@@ -162,13 +182,19 @@ describe("RebootDialog", () => {
const onOpenChangeMock = vi.fn();
render(<RebootDialog open onOpenChange={onOpenChangeMock} />);
fireEvent.change(screen.getByPlaceholderText(/enter delay/i), {
target: { value: "4" },
act(() => {
fireEvent.change(screen.getByPlaceholderText(/enter delay/i), {
target: { value: "4" },
});
});
act(() => {
fireEvent.click(screen.getByTestId("scheduleRebootBtn"));
});
fireEvent.click(screen.getByTestId("scheduleRebootBtn"));
expect(rebootMock).toHaveBeenCalledWith(4);
fireEvent.click(screen.getByRole("button", { name: /cancel/i }));
act(() => {
fireEvent.click(screen.getByRole("button", { name: /cancel/i }));
});
expect(rebootMock).toHaveBeenCalledWith(-1);
expect(screen.queryByText(/reboot has been scheduled/i)).not.toBeInTheDocument();
});