[UNSTABLE] Weed out more type errors
parent
66e686a4c1
commit
0ae0921a87
|
@ -1,5 +1,4 @@
|
|||
import {
|
||||
ResourceName,
|
||||
SpecialStatus,
|
||||
TaggedDevice,
|
||||
TaggedLog,
|
||||
|
@ -320,12 +319,14 @@ export
|
|||
function buildResourceIndex(resources: TaggedResource[] = FAKE_RESOURCES,
|
||||
state = emptyState()) {
|
||||
const KIND: keyof TaggedResource = "kind"; // Safety first, kids.
|
||||
return _(resources)
|
||||
const t = _(resources)
|
||||
.groupBy(KIND)
|
||||
.toPairs()
|
||||
.map((x: [(TaggedResource["kind"]), TaggedResource[]]) => x)
|
||||
.map((y: [ResourceName, TaggedResource[]]) => {
|
||||
return resourceReady((y[0] as any), y[1].map(x => x.body as any));
|
||||
.map((x: [TaggedResource["kind"], TaggedResource[]]) => x)
|
||||
.map((y) => {
|
||||
const [kind, list] = y;
|
||||
return resourceReady(kind, list);
|
||||
})
|
||||
.reduce(resourceReducer, state);
|
||||
return t;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import { API } from "../api";
|
|||
import { betterCompact } from "../../util";
|
||||
import { SpecialStatus } from "farmbot";
|
||||
import * as _ from "lodash";
|
||||
import { arrayUnwrap } from "../../resources/util";
|
||||
|
||||
describe("AJAX data tracking", () => {
|
||||
API.setBaseUrl("http://blah.whatever.party");
|
||||
|
@ -57,10 +58,12 @@ describe("AJAX data tracking", () => {
|
|||
expect(uuids.length).toEqual(r.length);
|
||||
});
|
||||
|
||||
it("sets consistency when calling initSave()", () => {
|
||||
mockBody = resources()[0].body;
|
||||
fit("sets consistency when calling initSave()", () => {
|
||||
const tr = arrayUnwrap(resources());
|
||||
mockBody = tr.body;
|
||||
// tslint:disable-next-line:no-any
|
||||
store.dispatch(initSave(resources()[0]) as any);
|
||||
const action: any = initSave(tr);
|
||||
store.dispatch(action);
|
||||
expect(maybeStartTracking).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -4,10 +4,9 @@ import { resourceReady } from "../../sync/actions";
|
|||
|
||||
describe("Connectivity Reducer - RESOURCE_READY", () => {
|
||||
it("handles `undefined` status", () => {
|
||||
const action = resourceReady("Device", {
|
||||
...fakeDevice().body,
|
||||
last_saw_mq: "Tue, 03 Oct 2017 09:00:00 -0500"
|
||||
});
|
||||
const device = fakeDevice();
|
||||
device.body.last_saw_mq = "Tue, 03 Oct 2017 09:00:00 -0500";
|
||||
const action = resourceReady("Device", device);
|
||||
const result = connectivityReducer(DEFAULT_STATE, action);
|
||||
expect(result["bot.mqtt"]).not.toBe(undefined);
|
||||
});
|
||||
|
|
|
@ -31,8 +31,8 @@ export let connectivityReducer =
|
|||
})
|
||||
.add<SyncBodyContents<TaggedDevice>>(Actions.RESOURCE_READY, (s, a) => {
|
||||
const d = arrayUnwrap(a.payload.body);
|
||||
if (d && a.payload.kind === "Device") {
|
||||
s["bot.mqtt"] = computeBestTime(s["bot.mqtt"], d && d.last_saw_mq);
|
||||
if (d && d.kind === "Device") {
|
||||
s["bot.mqtt"] = computeBestTime(s["bot.mqtt"], d && d.body.last_saw_mq);
|
||||
}
|
||||
return s;
|
||||
})
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
const mockGet = jest.fn(() => Promise.resolve({ data: [] }));
|
||||
const mockGet = jest.fn(() => {
|
||||
return Promise.resolve({ data: [mockLog.body] });
|
||||
});
|
||||
jest.mock("axios", () => ({ default: { get: mockGet } }));
|
||||
import { refreshLogs } from "../refresh_logs";
|
||||
import axios from "axios";
|
||||
import { API } from "../../api";
|
||||
import { resourceReady } from "../../sync/actions";
|
||||
import { fakeLog } from "../../__test_support__/fake_state/resources";
|
||||
|
||||
const mockLog = fakeLog();
|
||||
|
||||
describe("refreshLogs", () => {
|
||||
it("dispatches the appropriate action", async () => {
|
||||
|
@ -11,7 +16,7 @@ describe("refreshLogs", () => {
|
|||
API.setBaseUrl("localhost");
|
||||
await refreshLogs(dispatch);
|
||||
expect(axios.get).toHaveBeenCalled();
|
||||
|
||||
expect(dispatch).toHaveBeenCalledWith(resourceReady("Log", []));
|
||||
const action = resourceReady("Log", mockLog);
|
||||
expect(dispatch).toHaveBeenCalledWith(action);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -6,12 +6,19 @@ import { revertToEnglishMiddleware } from "../revert_to_english_middleware";
|
|||
import { revertToEnglish } from "../../revert_to_english";
|
||||
import { resourceReady } from "../../sync/actions";
|
||||
import { WebAppConfig } from "farmbot/dist/resources/configs/web_app";
|
||||
import { generateUuid } from "../../resources/util";
|
||||
import { SpecialStatus } from "farmbot";
|
||||
|
||||
fdescribe("revertToEnglishMiddleware", () => {
|
||||
fit("calls `revertToEnglish` when appropriate", () => {
|
||||
describe("revertToEnglishMiddleware", () => {
|
||||
it("calls `revertToEnglish` when appropriate", () => {
|
||||
const dispatch = jest.fn(() => ({}));
|
||||
const data = { disable_i18n: true } as WebAppConfig;
|
||||
const action = resourceReady("WebAppConfig", data);
|
||||
const action = resourceReady("WebAppConfig", {
|
||||
kind: "WebAppConfig",
|
||||
uuid: generateUuid(data.id, "WebAppConfig"),
|
||||
specialStatus: SpecialStatus.SAVED,
|
||||
body: data
|
||||
});
|
||||
expect(revertToEnglish).not.toHaveBeenCalled();
|
||||
// tslint:disable-next-line:no-any
|
||||
revertToEnglishMiddleware.fn({} as any)(dispatch)(action);
|
||||
|
|
|
@ -3,7 +3,7 @@ import { noop, throttle } from "lodash";
|
|||
import axios from "axios";
|
||||
import { ResourceName } from "farmbot";
|
||||
import { Log } from "farmbot/dist/resources/api_resources";
|
||||
import { resourceReady } from "../sync/actions";
|
||||
import { resourceReady, newTaggedResource } from "../sync/actions";
|
||||
const kind: ResourceName = "Log";
|
||||
|
||||
/** re-Downloads all logs from the API and force replaces all entries for logs
|
||||
|
@ -11,7 +11,9 @@ const kind: ResourceName = "Log";
|
|||
export const refreshLogs = async (dispatch: Function) => {
|
||||
return axios
|
||||
.get<Log[]>(API.current.filteredLogsPath)
|
||||
.then(({ data }) => dispatch(resourceReady(kind, data)), noop);
|
||||
.then(({ data }) => {
|
||||
dispatch(resourceReady(kind, newTaggedResource("Log", data)));
|
||||
}, noop);
|
||||
};
|
||||
|
||||
export const throttledLogRefresh = throttle(refreshLogs, 1000);
|
||||
|
|
|
@ -29,7 +29,10 @@ const fn: Middleware = () => (dispatch) => (action: any) => {
|
|||
&& x.payload.body
|
||||
&& x.payload.kind === WEB_APP_CONFIG) {
|
||||
const conf = arrayUnwrap(x.payload.body);
|
||||
conf && conf.disable_i18n && revertToEnglish();
|
||||
conf
|
||||
&& conf.body
|
||||
&& conf.body.disable_i18n
|
||||
&& revertToEnglish();
|
||||
}
|
||||
|
||||
return dispatch(action);
|
||||
|
|
|
@ -60,8 +60,8 @@ describe("resource reducer", () => {
|
|||
let id = 1;
|
||||
it("covers save resource branches", () => {
|
||||
const testResource = (kind: TaggedResource["kind"]) => {
|
||||
const resource = fakeResource(kind, { id: ++id });
|
||||
const action = resourceReady(resource.kind, resource.body);
|
||||
const resource = fakeResource(kind, { id: ++id }) as TaggedResource;
|
||||
const action = resourceReady(resource.kind, [resource]);
|
||||
const newState = resourceReducer(fakeState().resources, action);
|
||||
const uuid = newState.index.byKindAndId[joinKindAndId(kind, resource.body.id)];
|
||||
const expectation = newState.index.references[uuid || "?"];
|
||||
|
|
|
@ -16,6 +16,7 @@ import {
|
|||
import * as _ from "lodash";
|
||||
import { resourceReducer, emptyState } from "../reducer";
|
||||
import { resourceReady } from "../../sync/actions";
|
||||
// import { Actions } from "../../constants";
|
||||
|
||||
const TOOL_ID = 99;
|
||||
const SLOT_ID = 100;
|
||||
|
@ -73,9 +74,9 @@ describe("getFeeds", () => {
|
|||
it("finds the only WebcamFeed", () => {
|
||||
const feed = fakeWebcamFeed();
|
||||
const state = [
|
||||
resourceReady("WebcamFeed", feed.body)
|
||||
resourceReady("WebcamFeed", feed)
|
||||
].reduce(resourceReducer, emptyState());
|
||||
|
||||
debugger;
|
||||
expect(Selector.selectAllWebcamFeeds(state.index)[0].body).toEqual(feed);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -9,7 +9,7 @@ import { generateReducer } from "../redux/generate_reducer";
|
|||
import { initialState as regimenState } from "../regimens/reducer";
|
||||
import { initialState as sequenceState } from "../sequences/reducer";
|
||||
import { SyncBodyContents } from "../sync/actions";
|
||||
import { betterCompact, defensiveClone, equals } from "../util";
|
||||
import { defensiveClone, equals } from "../util";
|
||||
import { GeneralizedError } from "./actions";
|
||||
import { ResourceIndex, RestResources } from "./interfaces";
|
||||
import {
|
||||
|
@ -19,11 +19,7 @@ import {
|
|||
mutateSpecialStatus
|
||||
} from "./reducer_support";
|
||||
import { INDEXES } from "./resource_index_chain";
|
||||
import { isTaggedResource } from "./tagged_resources";
|
||||
import {
|
||||
arrayWrap,
|
||||
generateUuid
|
||||
} from "./util";
|
||||
import { arrayWrap } from "./util";
|
||||
|
||||
const ups = INDEXES.map(x => x.up);
|
||||
|
||||
|
@ -111,15 +107,7 @@ export let resourceReducer =
|
|||
})
|
||||
.add<SyncBodyContents<TaggedResource>>(Actions.RESOURCE_READY, (s, { payload }) => {
|
||||
!s.loaded.includes(payload.kind) && s.loaded.push(payload.kind);
|
||||
betterCompact(arrayWrap(payload.body)).map(body => {
|
||||
const x = {
|
||||
kind: payload.kind,
|
||||
uuid: generateUuid(body.id, payload.kind),
|
||||
specialStatus: SpecialStatus.SAVED,
|
||||
body
|
||||
};
|
||||
if (isTaggedResource(x)) { indexUpsert(s.index, x); }
|
||||
});
|
||||
payload.body.map(x => indexUpsert(s.index, x));
|
||||
return s;
|
||||
})
|
||||
.add<TaggedResource>(Actions.REFRESH_RESOURCE_OK, (s, { payload }) => {
|
||||
|
|
|
@ -20,8 +20,12 @@ const REFERENCES: Indexer = { // ========
|
|||
};
|
||||
|
||||
const ALL: Indexer = {
|
||||
up(r, s) { s.all.push(r.uuid); },
|
||||
down(r, i) { i.all = i.all.filter(filterOutUuid(r)); },
|
||||
up(r, s) {
|
||||
s.all.push(r.uuid);
|
||||
},
|
||||
down(r, i) {
|
||||
i.all = i.all.filter(filterOutUuid(r));
|
||||
},
|
||||
};
|
||||
|
||||
const BY_KIND: Indexer = {
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import axios from "axios";
|
||||
import { API } from "../api";
|
||||
import { Actions } from "../constants";
|
||||
import { TaggedResource as TR } from "farmbot";
|
||||
import { TaggedResource as TR, SpecialStatus } from "farmbot";
|
||||
import { Session } from "../session";
|
||||
import { arrayWrap } from "../resources/util";
|
||||
|
||||
export interface SyncBodyContents<T extends TR> {
|
||||
kind: T["kind"];
|
||||
body: T["body"][];
|
||||
body: T[];
|
||||
}
|
||||
export interface SyncResponse<T extends TR> {
|
||||
type: Actions.RESOURCE_READY;
|
||||
|
@ -15,18 +15,30 @@ export interface SyncResponse<T extends TR> {
|
|||
}
|
||||
|
||||
export const resourceReady =
|
||||
<T extends TR>(kind: T["kind"], body: T["body"] | T["body"][]): SyncResponse<T> => {
|
||||
<T extends TR>(kind: T["kind"], body: T | T[]): SyncResponse<T> => {
|
||||
return {
|
||||
type: Actions.RESOURCE_READY,
|
||||
payload: { kind, body: arrayWrap(body) }
|
||||
};
|
||||
};
|
||||
|
||||
export const newTaggedResource = <T extends TR>(kind: T["kind"],
|
||||
bodies: T["body"] | T["body"][],
|
||||
specialStatus = SpecialStatus.SAVED): T[] => {
|
||||
return arrayWrap(bodies).map((body: T["body"]): T => {
|
||||
const tr = newTaggedResource(kind, body)[0];
|
||||
tr.specialStatus = specialStatus;
|
||||
return tr;
|
||||
});
|
||||
};
|
||||
|
||||
export function fetchSyncData(dispatch: Function) {
|
||||
const fetch =
|
||||
<T extends TR>(kind: T["kind"], url: string) => axios
|
||||
.get<T["body"] | T["body"][]>(url)
|
||||
.then(({ data }) => dispatch(resourceReady(kind, data)), Session.clear);
|
||||
.then(({ data }) => {
|
||||
dispatch(resourceReady(kind, newTaggedResource(kind, data)))
|
||||
}, Session.clear);
|
||||
|
||||
fetch("User", API.current.usersPath);
|
||||
fetch("Device", API.current.devicePath);
|
||||
|
|
Loading…
Reference in New Issue