Frontend gets plugins from disk, not TimelineCred (#1625)
This commit modifies the frontend so that it now pulls plugin declarations from disk, rather than from the TimelineCred. This will allow us to decouple the TimelineCred from the PluginDeclarations, which is another step towards #1557. As proof that the frontend no longer gets plugins from the TimelineCred, I removed the public `plugins()` method on TimelineCred. Test plan: The frontend is somewhat sketchily tested. `yarn test` passing is good, manual inspection of the frontend is also necessary; I've done this.
This commit is contained in:
parent
aeaa945a27
commit
1073374dc7
|
@ -76,10 +76,6 @@ export class TimelineCred {
|
||||||
return this._params;
|
return this._params;
|
||||||
}
|
}
|
||||||
|
|
||||||
plugins(): $ReadOnlyArray<PluginDeclaration> {
|
|
||||||
return this._plugins;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new TimelineCred based on the new Parameters.
|
* Creates a new TimelineCred based on the new Parameters.
|
||||||
* Holds the graph and config constant.
|
* Holds the graph and config constant.
|
||||||
|
@ -151,7 +147,7 @@ export class TimelineCred {
|
||||||
* with a type specified as a user type by one of the plugin declarations.
|
* with a type specified as a user type by one of the plugin declarations.
|
||||||
*/
|
*/
|
||||||
userNodes(): $ReadOnlyArray<CredNode> {
|
userNodes(): $ReadOnlyArray<CredNode> {
|
||||||
const userTypes = [].concat(...this.plugins().map((p) => p.userTypes));
|
const userTypes = [].concat(...this._plugins.map((p) => p.userTypes));
|
||||||
return this.credSortedNodes(userTypes.map((x) => x.prefix));
|
return this.credSortedNodes(userTypes.map((x) => x.prefix));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,10 @@ import type {Assets} from "../webutil/assets";
|
||||||
import {TimelineExplorer} from "./TimelineExplorer";
|
import {TimelineExplorer} from "./TimelineExplorer";
|
||||||
import {TimelineCred} from "../analysis/timeline/timelineCred";
|
import {TimelineCred} from "../analysis/timeline/timelineCred";
|
||||||
import {encodeProjectId, type ProjectId} from "../core/project";
|
import {encodeProjectId, type ProjectId} from "../core/project";
|
||||||
|
import {
|
||||||
|
type PluginDeclarations,
|
||||||
|
fromJSON as pluginsFromJSON,
|
||||||
|
} from "../analysis/pluginDeclaration";
|
||||||
|
|
||||||
export type Props = {|
|
export type Props = {|
|
||||||
+assets: Assets,
|
+assets: Assets,
|
||||||
|
@ -19,6 +23,7 @@ export type Loading = {|+type: "LOADING"|};
|
||||||
export type LoadSuccess = {|
|
export type LoadSuccess = {|
|
||||||
+type: "SUCCESS",
|
+type: "SUCCESS",
|
||||||
+timelineCred: TimelineCred,
|
+timelineCred: TimelineCred,
|
||||||
|
+pluginDeclarations: PluginDeclarations,
|
||||||
|};
|
|};
|
||||||
export type LoadError = {|+type: "ERROR", +error: any|};
|
export type LoadError = {|+type: "ERROR", +error: any|};
|
||||||
|
|
||||||
|
@ -62,11 +67,12 @@ export class TimelineApp extends React.Component<Props, State> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case "SUCCESS": {
|
case "SUCCESS": {
|
||||||
const {timelineCred} = loadResult;
|
const {timelineCred, pluginDeclarations} = loadResult;
|
||||||
return (
|
return (
|
||||||
<TimelineExplorer
|
<TimelineExplorer
|
||||||
initialTimelineCred={timelineCred}
|
initialTimelineCred={timelineCred}
|
||||||
projectId={this.props.projectId}
|
projectId={this.props.projectId}
|
||||||
|
pluginDeclarations={pluginDeclarations}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -90,9 +96,24 @@ export async function defaultLoader(
|
||||||
return TimelineCred.fromJSON(await response.json());
|
return TimelineCred.fromJSON(await response.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function fetchPluginDeclarations(): Promise<PluginDeclarations> {
|
||||||
|
const encodedId = encodeProjectId(projectId);
|
||||||
|
const url = assets.resolve(
|
||||||
|
`api/v1/data/projects/${encodedId}/pluginDeclarations.json`
|
||||||
|
);
|
||||||
|
const response = await fetch(url);
|
||||||
|
if (!response.ok) {
|
||||||
|
return Promise.reject(response);
|
||||||
|
}
|
||||||
|
return pluginsFromJSON(await response.json());
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const timelineCred = await fetchCred();
|
const [timelineCred, pluginDeclarations] = await Promise.all([
|
||||||
return {type: "SUCCESS", timelineCred};
|
fetchCred(),
|
||||||
|
fetchPluginDeclarations(),
|
||||||
|
]);
|
||||||
|
return {type: "SUCCESS", timelineCred, pluginDeclarations};
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
return {type: "ERROR", error: e};
|
return {type: "ERROR", error: e};
|
||||||
|
|
|
@ -11,13 +11,17 @@ import {TimelineCredView} from "./TimelineCredView";
|
||||||
import Link from "../webutil/Link";
|
import Link from "../webutil/Link";
|
||||||
import {WeightConfig} from "./weights/WeightConfig";
|
import {WeightConfig} from "./weights/WeightConfig";
|
||||||
import {WeightsFileManager} from "./weights/WeightsFileManager";
|
import {WeightsFileManager} from "./weights/WeightsFileManager";
|
||||||
import {type PluginDeclaration} from "../analysis/pluginDeclaration";
|
import {
|
||||||
|
type PluginDeclarations,
|
||||||
|
type PluginDeclaration,
|
||||||
|
} from "../analysis/pluginDeclaration";
|
||||||
import * as NullUtil from "../util/null";
|
import * as NullUtil from "../util/null";
|
||||||
import {format} from "d3-format";
|
import {format} from "d3-format";
|
||||||
|
|
||||||
export type Props = {
|
export type Props = {
|
||||||
projectId: string,
|
projectId: string,
|
||||||
initialTimelineCred: TimelineCred,
|
initialTimelineCred: TimelineCred,
|
||||||
|
pluginDeclarations: PluginDeclarations,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type State = {
|
export type State = {
|
||||||
|
@ -89,7 +93,7 @@ export class TimelineExplorer extends React.Component<Props, State> {
|
||||||
);
|
);
|
||||||
const weightConfig = (
|
const weightConfig = (
|
||||||
<WeightConfig
|
<WeightConfig
|
||||||
declarations={this.state.timelineCred.plugins()}
|
declarations={this.props.pluginDeclarations}
|
||||||
nodeWeights={this.state.weights.nodeWeights}
|
nodeWeights={this.state.weights.nodeWeights}
|
||||||
edgeWeights={this.state.weights.edgeWeights}
|
edgeWeights={this.state.weights.edgeWeights}
|
||||||
onNodeWeightChange={(prefix, weight) => {
|
onNodeWeightChange={(prefix, weight) => {
|
||||||
|
@ -201,7 +205,7 @@ export class TimelineExplorer extends React.Component<Props, State> {
|
||||||
<option key={"All users"} value={""}>
|
<option key={"All users"} value={""}>
|
||||||
All users
|
All users
|
||||||
</option>
|
</option>
|
||||||
{this.state.timelineCred.plugins().map(optionGroup)}
|
{this.props.pluginDeclarations.map(optionGroup)}
|
||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
);
|
);
|
||||||
|
|
|
@ -93,7 +93,7 @@ export function createApp(
|
||||||
);
|
);
|
||||||
let pagerankTable;
|
let pagerankTable;
|
||||||
if (appState.type === "PAGERANK_EVALUATED") {
|
if (appState.type === "PAGERANK_EVALUATED") {
|
||||||
const declarations = appState.timelineCred.plugins();
|
const declarations = appState.pluginDeclarations;
|
||||||
const weightConfig = (
|
const weightConfig = (
|
||||||
<WeightConfig
|
<WeightConfig
|
||||||
declarations={declarations}
|
declarations={declarations}
|
||||||
|
|
|
@ -72,6 +72,7 @@ describe("explorer/legacy/App", () => {
|
||||||
defaultParams(),
|
defaultParams(),
|
||||||
[]
|
[]
|
||||||
),
|
),
|
||||||
|
pluginDeclarations: [],
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
pagerankEvaluated: (loadingState) => {
|
pagerankEvaluated: (loadingState) => {
|
||||||
|
@ -86,6 +87,7 @@ describe("explorer/legacy/App", () => {
|
||||||
defaultParams(),
|
defaultParams(),
|
||||||
[]
|
[]
|
||||||
),
|
),
|
||||||
|
pluginDeclarations: [],
|
||||||
pagerankNodeDecomposition: new Map(),
|
pagerankNodeDecomposition: new Map(),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -5,7 +5,7 @@ import deepEqual from "lodash.isequal";
|
||||||
import {Graph, type NodeAddressT} from "../../core/graph";
|
import {Graph, type NodeAddressT} from "../../core/graph";
|
||||||
import type {Assets} from "../../webutil/assets";
|
import type {Assets} from "../../webutil/assets";
|
||||||
import {type EdgeEvaluator} from "../../analysis/pagerank";
|
import {type EdgeEvaluator} from "../../analysis/pagerank";
|
||||||
import {defaultLoader} from "../TimelineApp";
|
import {defaultLoader, type LoadSuccess} from "../TimelineApp";
|
||||||
import {
|
import {
|
||||||
type PagerankNodeDecomposition,
|
type PagerankNodeDecomposition,
|
||||||
type PagerankOptions,
|
type PagerankOptions,
|
||||||
|
@ -15,7 +15,10 @@ import {TimelineCred} from "../../analysis/timeline/timelineCred";
|
||||||
|
|
||||||
import type {Weights} from "../../core/weights";
|
import type {Weights} from "../../core/weights";
|
||||||
import {weightsToEdgeEvaluator} from "../../analysis/weightsToEdgeEvaluator";
|
import {weightsToEdgeEvaluator} from "../../analysis/weightsToEdgeEvaluator";
|
||||||
import {combineTypes} from "../../analysis/pluginDeclaration";
|
import {
|
||||||
|
combineTypes,
|
||||||
|
type PluginDeclarations,
|
||||||
|
} from "../../analysis/pluginDeclaration";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This models the UI states of the credExplorer/App as a state machine.
|
This models the UI states of the credExplorer/App as a state machine.
|
||||||
|
@ -40,11 +43,13 @@ export type ReadyToRunPagerank = {|
|
||||||
+type: "READY_TO_RUN_PAGERANK",
|
+type: "READY_TO_RUN_PAGERANK",
|
||||||
+projectId: string,
|
+projectId: string,
|
||||||
+timelineCred: TimelineCred,
|
+timelineCred: TimelineCred,
|
||||||
|
+pluginDeclarations: PluginDeclarations,
|
||||||
+loading: LoadingState,
|
+loading: LoadingState,
|
||||||
|};
|
|};
|
||||||
export type PagerankEvaluated = {|
|
export type PagerankEvaluated = {|
|
||||||
+type: "PAGERANK_EVALUATED",
|
+type: "PAGERANK_EVALUATED",
|
||||||
+timelineCred: TimelineCred,
|
+timelineCred: TimelineCred,
|
||||||
|
+pluginDeclarations: PluginDeclarations,
|
||||||
+projectId: string,
|
+projectId: string,
|
||||||
+pagerankNodeDecomposition: PagerankNodeDecomposition,
|
+pagerankNodeDecomposition: PagerankNodeDecomposition,
|
||||||
+loading: LoadingState,
|
+loading: LoadingState,
|
||||||
|
@ -58,12 +63,7 @@ export function createStateTransitionMachine(
|
||||||
getState: () => AppState,
|
getState: () => AppState,
|
||||||
setState: (AppState) => void
|
setState: (AppState) => void
|
||||||
): StateTransitionMachine {
|
): StateTransitionMachine {
|
||||||
return new StateTransitionMachine(
|
return new StateTransitionMachine(getState, setState, doLoad, pagerank);
|
||||||
getState,
|
|
||||||
setState,
|
|
||||||
doLoadTimelineCred,
|
|
||||||
pagerank
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exported for testing purposes.
|
// Exported for testing purposes.
|
||||||
|
@ -83,10 +83,7 @@ export interface StateTransitionMachineInterface {
|
||||||
export class StateTransitionMachine implements StateTransitionMachineInterface {
|
export class StateTransitionMachine implements StateTransitionMachineInterface {
|
||||||
getState: () => AppState;
|
getState: () => AppState;
|
||||||
setState: (AppState) => void;
|
setState: (AppState) => void;
|
||||||
doLoadTimelineCred: (
|
doLoad: (assets: Assets, projectId: string) => Promise<LoadSuccess>;
|
||||||
assets: Assets,
|
|
||||||
projectId: string
|
|
||||||
) => Promise<TimelineCred>;
|
|
||||||
pagerank: (
|
pagerank: (
|
||||||
Graph,
|
Graph,
|
||||||
EdgeEvaluator,
|
EdgeEvaluator,
|
||||||
|
@ -96,10 +93,7 @@ export class StateTransitionMachine implements StateTransitionMachineInterface {
|
||||||
constructor(
|
constructor(
|
||||||
getState: () => AppState,
|
getState: () => AppState,
|
||||||
setState: (AppState) => void,
|
setState: (AppState) => void,
|
||||||
doLoadTimelineCred: (
|
doLoad: (assets: Assets, projectId: string) => Promise<LoadSuccess>,
|
||||||
assets: Assets,
|
|
||||||
projectId: string
|
|
||||||
) => Promise<TimelineCred>,
|
|
||||||
pagerank: (
|
pagerank: (
|
||||||
Graph,
|
Graph,
|
||||||
EdgeEvaluator,
|
EdgeEvaluator,
|
||||||
|
@ -108,7 +102,7 @@ export class StateTransitionMachine implements StateTransitionMachineInterface {
|
||||||
) {
|
) {
|
||||||
this.getState = getState;
|
this.getState = getState;
|
||||||
this.setState = setState;
|
this.setState = setState;
|
||||||
this.doLoadTimelineCred = doLoadTimelineCred;
|
this.doLoad = doLoad;
|
||||||
this.pagerank = pagerank;
|
this.pagerank = pagerank;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,10 +118,14 @@ export class StateTransitionMachine implements StateTransitionMachineInterface {
|
||||||
let newState: ?AppState;
|
let newState: ?AppState;
|
||||||
let success = true;
|
let success = true;
|
||||||
try {
|
try {
|
||||||
const timelineCred = await this.doLoadTimelineCred(assets, projectId);
|
const {pluginDeclarations, timelineCred} = await this.doLoad(
|
||||||
|
assets,
|
||||||
|
projectId
|
||||||
|
);
|
||||||
newState = {
|
newState = {
|
||||||
type: "READY_TO_RUN_PAGERANK",
|
type: "READY_TO_RUN_PAGERANK",
|
||||||
timelineCred,
|
timelineCred,
|
||||||
|
pluginDeclarations,
|
||||||
projectId,
|
projectId,
|
||||||
loading: "NOT_LOADING",
|
loading: "NOT_LOADING",
|
||||||
};
|
};
|
||||||
|
@ -159,7 +157,7 @@ export class StateTransitionMachine implements StateTransitionMachineInterface {
|
||||||
this.setState(loadingState);
|
this.setState(loadingState);
|
||||||
const graph = state.timelineCred.weightedGraph().graph;
|
const graph = state.timelineCred.weightedGraph().graph;
|
||||||
let newState: ?AppState;
|
let newState: ?AppState;
|
||||||
const types = combineTypes(state.timelineCred.plugins());
|
const types = combineTypes(state.pluginDeclarations);
|
||||||
try {
|
try {
|
||||||
const pagerankNodeDecomposition = await this.pagerank(
|
const pagerankNodeDecomposition = await this.pagerank(
|
||||||
graph,
|
graph,
|
||||||
|
@ -173,6 +171,7 @@ export class StateTransitionMachine implements StateTransitionMachineInterface {
|
||||||
type: "PAGERANK_EVALUATED",
|
type: "PAGERANK_EVALUATED",
|
||||||
pagerankNodeDecomposition,
|
pagerankNodeDecomposition,
|
||||||
timelineCred: state.timelineCred,
|
timelineCred: state.timelineCred,
|
||||||
|
pluginDeclarations: state.pluginDeclarations,
|
||||||
projectId: state.projectId,
|
projectId: state.projectId,
|
||||||
loading: "NOT_LOADING",
|
loading: "NOT_LOADING",
|
||||||
};
|
};
|
||||||
|
@ -213,13 +212,13 @@ export class StateTransitionMachine implements StateTransitionMachineInterface {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function doLoadTimelineCred(
|
export async function doLoad(
|
||||||
assets: Assets,
|
assets: Assets,
|
||||||
projectId: string
|
projectId: string
|
||||||
): Promise<TimelineCred> {
|
): Promise<LoadSuccess> {
|
||||||
const loadResult = await defaultLoader(assets, projectId);
|
const loadResult = await defaultLoader(assets, projectId);
|
||||||
if (loadResult.type !== "SUCCESS") {
|
if (loadResult.type !== "SUCCESS") {
|
||||||
throw new Error(loadResult);
|
throw new Error(loadResult);
|
||||||
}
|
}
|
||||||
return loadResult.timelineCred;
|
return loadResult;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import type {
|
||||||
} from "../../analysis/pagerank";
|
} from "../../analysis/pagerank";
|
||||||
import {TimelineCred} from "../../analysis/timeline/timelineCred";
|
import {TimelineCred} from "../../analysis/timeline/timelineCred";
|
||||||
import {defaultParams} from "../../analysis/timeline/params";
|
import {defaultParams} from "../../analysis/timeline/params";
|
||||||
|
import {type LoadSuccess} from "../TimelineApp";
|
||||||
|
|
||||||
describe("explorer/legacy/state", () => {
|
describe("explorer/legacy/state", () => {
|
||||||
function example(startingState: AppState) {
|
function example(startingState: AppState) {
|
||||||
|
@ -21,9 +22,9 @@ describe("explorer/legacy/state", () => {
|
||||||
const setState = (appState) => {
|
const setState = (appState) => {
|
||||||
stateContainer.appState = appState;
|
stateContainer.appState = appState;
|
||||||
};
|
};
|
||||||
const loadTimelineCredMock: JestMockFn<
|
const loadMock: JestMockFn<
|
||||||
[Assets, string],
|
[Assets, string],
|
||||||
Promise<TimelineCred>
|
Promise<LoadSuccess>
|
||||||
> = jest.fn();
|
> = jest.fn();
|
||||||
|
|
||||||
const pagerankMock: JestMockFn<
|
const pagerankMock: JestMockFn<
|
||||||
|
@ -33,10 +34,10 @@ describe("explorer/legacy/state", () => {
|
||||||
const stm = new StateTransitionMachine(
|
const stm = new StateTransitionMachine(
|
||||||
getState,
|
getState,
|
||||||
setState,
|
setState,
|
||||||
loadTimelineCredMock,
|
loadMock,
|
||||||
pagerankMock
|
pagerankMock
|
||||||
);
|
);
|
||||||
return {getState, stm, loadTimelineCredMock, pagerankMock};
|
return {getState, stm, loadMock, pagerankMock};
|
||||||
}
|
}
|
||||||
function readyToLoadGraph(): AppState {
|
function readyToLoadGraph(): AppState {
|
||||||
return {
|
return {
|
||||||
|
@ -57,6 +58,7 @@ describe("explorer/legacy/state", () => {
|
||||||
defaultParams(),
|
defaultParams(),
|
||||||
[]
|
[]
|
||||||
),
|
),
|
||||||
|
pluginDeclarations: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
function pagerankEvaluated(): AppState {
|
function pagerankEvaluated(): AppState {
|
||||||
|
@ -70,6 +72,7 @@ describe("explorer/legacy/state", () => {
|
||||||
defaultParams(),
|
defaultParams(),
|
||||||
[]
|
[]
|
||||||
),
|
),
|
||||||
|
pluginDeclarations: [],
|
||||||
pagerankNodeDecomposition: pagerankNodeDecomposition(),
|
pagerankNodeDecomposition: pagerankNodeDecomposition(),
|
||||||
loading: "NOT_LOADING",
|
loading: "NOT_LOADING",
|
||||||
};
|
};
|
||||||
|
@ -92,12 +95,12 @@ describe("explorer/legacy/state", () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
it("passes along the projectId", () => {
|
it("passes along the projectId", () => {
|
||||||
const {stm, loadTimelineCredMock} = example(readyToLoadGraph());
|
const {stm, loadMock} = example(readyToLoadGraph());
|
||||||
expect(loadTimelineCredMock).toHaveBeenCalledTimes(0);
|
expect(loadMock).toHaveBeenCalledTimes(0);
|
||||||
const assets = new Assets("/my/gateway/");
|
const assets = new Assets("/my/gateway/");
|
||||||
stm.loadTimelineCred(assets);
|
stm.loadTimelineCred(assets);
|
||||||
expect(loadTimelineCredMock).toHaveBeenCalledTimes(1);
|
expect(loadMock).toHaveBeenCalledTimes(1);
|
||||||
expect(loadTimelineCredMock).toHaveBeenCalledWith(assets, "foo/bar");
|
expect(loadMock).toHaveBeenCalledWith(assets, "foo/bar");
|
||||||
});
|
});
|
||||||
it("immediately sets loading status", () => {
|
it("immediately sets loading status", () => {
|
||||||
const {getState, stm} = example(readyToLoadGraph());
|
const {getState, stm} = example(readyToLoadGraph());
|
||||||
|
@ -107,7 +110,7 @@ describe("explorer/legacy/state", () => {
|
||||||
expect(getState().type).toBe("READY_TO_LOAD_GRAPH");
|
expect(getState().type).toBe("READY_TO_LOAD_GRAPH");
|
||||||
});
|
});
|
||||||
it("transitions to READY_TO_RUN_PAGERANK on success", async () => {
|
it("transitions to READY_TO_RUN_PAGERANK on success", async () => {
|
||||||
const {getState, stm, loadTimelineCredMock} = example(readyToLoadGraph());
|
const {getState, stm, loadMock} = example(readyToLoadGraph());
|
||||||
|
|
||||||
const timelineCred = new TimelineCred(
|
const timelineCred = new TimelineCred(
|
||||||
WeightedGraph.empty(),
|
WeightedGraph.empty(),
|
||||||
|
@ -116,7 +119,12 @@ describe("explorer/legacy/state", () => {
|
||||||
defaultParams(),
|
defaultParams(),
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
loadTimelineCredMock.mockReturnValue(Promise.resolve(timelineCred));
|
const loadResult = {
|
||||||
|
type: "SUCCESS",
|
||||||
|
timelineCred,
|
||||||
|
pluginDeclarations: [],
|
||||||
|
};
|
||||||
|
loadMock.mockReturnValue(Promise.resolve(loadResult));
|
||||||
const succeeded = await stm.loadTimelineCred(new Assets("/my/gateway/"));
|
const succeeded = await stm.loadTimelineCred(new Assets("/my/gateway/"));
|
||||||
expect(succeeded).toBe(true);
|
expect(succeeded).toBe(true);
|
||||||
const state = getState();
|
const state = getState();
|
||||||
|
@ -128,11 +136,11 @@ describe("explorer/legacy/state", () => {
|
||||||
expect(state.timelineCred).toBe(timelineCred);
|
expect(state.timelineCred).toBe(timelineCred);
|
||||||
});
|
});
|
||||||
it("sets loading state FAILED on reject", async () => {
|
it("sets loading state FAILED on reject", async () => {
|
||||||
const {getState, stm, loadTimelineCredMock} = example(readyToLoadGraph());
|
const {getState, stm, loadMock} = example(readyToLoadGraph());
|
||||||
const error = new Error("Oh no!");
|
const error = new Error("Oh no!");
|
||||||
// $ExpectFlowError
|
// $ExpectFlowError
|
||||||
console.error = jest.fn();
|
console.error = jest.fn();
|
||||||
loadTimelineCredMock.mockReturnValue(Promise.reject(error));
|
loadMock.mockReturnValue(Promise.reject(error));
|
||||||
const succeeded = await stm.loadTimelineCred(new Assets("/my/gateway/"));
|
const succeeded = await stm.loadTimelineCred(new Assets("/my/gateway/"));
|
||||||
expect(succeeded).toBe(false);
|
expect(succeeded).toBe(false);
|
||||||
const state = getState();
|
const state = getState();
|
||||||
|
|
Loading…
Reference in New Issue