Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// @vitest-environment happy-dom
import { useAtomValue } from "jotai";
import { act } from "react";

import {
createRandomVertex,
DbState,
FakeExplorer,
renderHookWithState,
} from "@/utils/testing";

import {
activeGraphSessionAtom,
type GraphSessionStorageModel,
} from "./storage";
import { useAvailablePreviousSession } from "./useAvailablePreviousSession";
import { useRestoreGraphSession } from "./useRestoreGraphSession";

test("clears a previous session when none of its entities still exist", async () => {
const missingVertex = createRandomVertex();
const previousSession: GraphSessionStorageModel = {
vertices: new Set([missingVertex.id]),
edges: new Set(),
};
const state = new DbState(new FakeExplorer()).withGraphSession(
previousSession,
);

const { result } = renderHookWithState(() => {
const restore = useRestoreGraphSession();
const availablePreviousSession = useAvailablePreviousSession();
const activeGraphSession = useAtomValue(activeGraphSessionAtom);

return { restore, availablePreviousSession, activeGraphSession };
}, state);

expect(result.current.availablePreviousSession).toStrictEqual(
previousSession,
);

await act(() => result.current.restore.mutateAsync(previousSession));

expect(result.current.restore.isSuccess).toBe(true);
expect(result.current.availablePreviousSession).toBeNull();
expect(result.current.activeGraphSession).toStrictEqual({
vertices: new Set(),
edges: new Set(),
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ import { createDisplayError } from "@/utils/createDisplayError";

import type { GraphSessionStorageModel } from "./storage";

import { useUpdateGraphSession } from "./useUpdateGraphSession";

/**
* Provides a mutation that restores the graph session from storage.
*/
export function useRestoreGraphSession() {
const queryClient = useQueryClient();
const addToGraph = useAddToGraph();
const formatEntityCounts = useEntityCountFormatterCallback();
const updateGraphSession = useUpdateGraphSession();

const mutation = useMutation({
mutationFn: async (graph: GraphSessionStorageModel) => {
Expand All @@ -36,6 +39,12 @@ export function useRestoreGraphSession() {

// Update Graph Explorer state
await addToGraph(result.entities);
if (
result.entities.vertices.length === 0 &&
result.entities.edges.length === 0
) {
updateGraphSession();
}

return result;
})();
Expand Down
10 changes: 9 additions & 1 deletion packages/graph-explorer/src/utils/testing/DbState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
edgesTypesFilteredAtom,
type EdgeType,
explorerForTestingAtom,
type GraphSessionStorageModel,
type GraphViewLayout,
graphViewLayoutAtom,
mapEdgeToTypeConfig,
Expand Down Expand Up @@ -54,6 +55,7 @@ import {
*/
export class DbState {
#activeSchema: SchemaStorageModel | null;
#graphSession: GraphSessionStorageModel | undefined;
activeConfig: RawConfiguration;
vertexStyles: Map<VertexType, VertexStyleStorage>;
edgeStyles: Map<EdgeType, EdgeStyleStorage>;
Expand Down Expand Up @@ -110,6 +112,12 @@ export class DbState {
return this;
}

/** Sets the persisted graph session independently from the current graph. */
withGraphSession(graphSession: GraphSessionStorageModel) {
this.#graphSession = graphSession;
return this;
}

/** Adds the vertex to the graph and updates the schema to include the type config. */
addVertexToGraph(vertex: Vertex) {
this.vertices.push(vertex);
Expand Down Expand Up @@ -256,7 +264,7 @@ export class DbState {
new Map([
[
this.activeConfig.id,
{
this.#graphSession ?? {
vertices: new Set(this.vertices.map(v => v.id)),
edges: new Set(this.edges.map(e => e.id)),
},
Expand Down