test cleanup
parent
4017f087b9
commit
3ca67764b9
|
@ -2,36 +2,50 @@ import { UNBOUND_ROUTES, UnboundRouteConfig } from "../route_config";
|
|||
import { RouteEnterEvent } from "takeme";
|
||||
|
||||
interface ConnectedComponent {
|
||||
name: string;
|
||||
WrappedComponent: React.ComponentType;
|
||||
name: string;
|
||||
WrappedComponent: React.ComponentType;
|
||||
}
|
||||
|
||||
type Info = UnboundRouteConfig<{}, {}>;
|
||||
|
||||
function mapper(bind_to: Function, index: number) {
|
||||
return bind_to((x: ConnectedComponent, y: ConnectedComponent | undefined, z: Info) => {
|
||||
if (z.$ == "*") {
|
||||
expect(x.WrappedComponent.name).toEqual("FourOhFour");
|
||||
return;
|
||||
}
|
||||
const fakeCallback = (
|
||||
component: ConnectedComponent,
|
||||
child: ConnectedComponent | undefined,
|
||||
info: Info
|
||||
) => {
|
||||
if (info.$ == "*") {
|
||||
expect(component.name).toEqual("FourOhFour");
|
||||
} else {
|
||||
expect(component.name).toBe("Connect");
|
||||
expect(component.WrappedComponent.name).toContain(info.key);
|
||||
if (child && info.children) {
|
||||
expect(child.name).toBe("Connect");
|
||||
expect(child.WrappedComponent.name).toContain(info.childKey);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
expect(index).toBeGreaterThan(-1);
|
||||
expect(x.name).toBe("Connect");
|
||||
expect(x.WrappedComponent.name).toContain(z.key);
|
||||
if (y && z.children) {
|
||||
expect(y.name).toBe("Connect");
|
||||
expect(y.WrappedComponent.name).toContain(z.childKey);
|
||||
}
|
||||
});
|
||||
}
|
||||
const fakeRouteEnterEvent: RouteEnterEvent = {
|
||||
params: { splat: "????" },
|
||||
oldPath: "??",
|
||||
newPath: "??"
|
||||
};
|
||||
|
||||
describe("UNBOUND_ROUTES", () => {
|
||||
it("generates correct routes", () => {
|
||||
const fake: RouteEnterEvent = {
|
||||
params: { splat: "????" },
|
||||
oldPath: "??",
|
||||
newPath: "??"
|
||||
};
|
||||
UNBOUND_ROUTES.map(mapper).map(x => { x.enter && x.enter(fake); });
|
||||
});
|
||||
it("generates correct routes", () => {
|
||||
UNBOUND_ROUTES
|
||||
.map(r => r(fakeCallback))
|
||||
.map(r => r.enter && r.enter(fakeRouteEnterEvent));
|
||||
});
|
||||
|
||||
it("generates crash route", async () => {
|
||||
const fakeError = new Error("fake callback error");
|
||||
const cb = jest.fn()
|
||||
.mockImplementationOnce(() => { throw fakeError; })
|
||||
.mockImplementationOnce(x => { expect(x.name).toEqual("Apology"); });
|
||||
const r = UNBOUND_ROUTES[0](cb);
|
||||
console.error = jest.fn();
|
||||
r.enter && await r.enter(fakeRouteEnterEvent);
|
||||
expect(console.error).toHaveBeenCalledWith(fakeError);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -13,7 +13,7 @@ describe("destroyCatch", () => {
|
|||
uuid,
|
||||
statusBeforeError
|
||||
});
|
||||
handler(err);
|
||||
handler(err).catch(() => { });
|
||||
const expected = destroyNO({ err, uuid, statusBeforeError });
|
||||
expect(dispatch).toHaveBeenCalledWith(expected);
|
||||
});
|
||||
|
|
|
@ -7,7 +7,7 @@ import { Mode } from "../interfaces";
|
|||
let mockMode = Mode.none;
|
||||
jest.mock("../util", () => ({
|
||||
getMode: () => mockMode,
|
||||
getMapSize: () => ({ h: undefined, w: undefined }),
|
||||
getMapSize: () => ({ h: 100, w: 100 }),
|
||||
getGardenCoordinates: jest.fn(),
|
||||
transformXY: jest.fn(() => ({ qx: 0, qy: 0 })),
|
||||
transformForQuadrant: jest.fn(),
|
||||
|
|
|
@ -11,7 +11,8 @@ jest.mock("../../config_storage/actions", () => ({
|
|||
toggleWebAppBool: jest.fn()
|
||||
}));
|
||||
|
||||
let mockDestroyAllPromise: Promise<void | never> = Promise.reject("error");
|
||||
let mockDestroyAllPromise: Promise<void | never> =
|
||||
Promise.reject("error").catch(() => { });
|
||||
jest.mock("../../api/crud", () => ({
|
||||
destroyAll: jest.fn(() => mockDestroyAllPromise)
|
||||
}));
|
||||
|
@ -33,14 +34,14 @@ describe("<FarmwareConfigMenu />", () => {
|
|||
shouldDisplay: () => false,
|
||||
});
|
||||
|
||||
it("calls install 1st party farmwares", () => {
|
||||
it("calls install 1st party farmware", () => {
|
||||
const wrapper = mount(<FarmwareConfigMenu {...fakeProps()} />);
|
||||
const button = wrapper.find("button").first();
|
||||
expect(button.hasClass("fa-download")).toBeTruthy();
|
||||
button.simulate("click");
|
||||
});
|
||||
|
||||
it("1st party farmwares all installed", () => {
|
||||
it("1st party farmware all installed", () => {
|
||||
const p = fakeProps();
|
||||
p.firstPartyFwsInstalled = true;
|
||||
const wrapper = mount(<FarmwareConfigMenu {...p} />);
|
||||
|
|
|
@ -4,10 +4,11 @@ jest.mock("axios", () => ({
|
|||
post: jest.fn(() => mockAxiosResponse)
|
||||
}));
|
||||
|
||||
let mockAuth: AuthState | undefined = undefined;
|
||||
jest.mock("../../session", () => ({
|
||||
Session: {
|
||||
replaceToken: jest.fn(),
|
||||
fetchStoredToken: jest.fn(),
|
||||
fetchStoredToken: () => mockAuth,
|
||||
}
|
||||
}));
|
||||
|
||||
|
@ -33,8 +34,12 @@ import { API } from "../../api";
|
|||
import { Session } from "../../session";
|
||||
import { success, error } from "farmbot-toastr";
|
||||
import { Content } from "../../constants";
|
||||
import { AuthState } from "../../auth/interfaces";
|
||||
import { auth } from "../../__test_support__/fake_state/token";
|
||||
|
||||
describe("<FrontPage />", () => {
|
||||
beforeEach(() => { mockAuth = undefined; });
|
||||
|
||||
type FormEvent = React.FormEvent<{}>;
|
||||
const fakeEvent: Partial<FormEvent> = {
|
||||
preventDefault: jest.fn()
|
||||
|
@ -55,8 +60,17 @@ describe("<FrontPage />", () => {
|
|||
.map(string => expect(el.html()).toContain(string));
|
||||
});
|
||||
|
||||
it("redirects when already logged in", () => {
|
||||
mockAuth = auth;
|
||||
location.assign = jest.fn();
|
||||
const el = mount(<FrontPage />);
|
||||
el.mount();
|
||||
expect(location.assign).toHaveBeenCalledWith("/app/controls");
|
||||
});
|
||||
|
||||
it("submits login: success", async () => {
|
||||
mockAxiosResponse = Promise.resolve({ data: "new data" });
|
||||
location.assign = jest.fn();
|
||||
const el = mount<FrontPage>(<FrontPage />);
|
||||
el.setState({ email: "foo@bar.io", loginPassword: "password" });
|
||||
await el.instance().submitLogin(fakeEvent as FormEvent);
|
||||
|
@ -65,6 +79,7 @@ describe("<FrontPage />", () => {
|
|||
"://localhost:3000/api/tokens/",
|
||||
{ user: { email: "foo@bar.io", password: "password" } });
|
||||
expect(Session.replaceToken).toHaveBeenCalledWith("new data");
|
||||
expect(location.assign).toHaveBeenCalledWith("/app/controls");
|
||||
});
|
||||
|
||||
it("submits login: not verified", async () => {
|
||||
|
|
|
@ -69,7 +69,7 @@ export class FrontPage extends React.Component<{}, Partial<FrontPageState>> {
|
|||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (Session.fetchStoredToken()) { window.location.href = "/app/controls"; }
|
||||
if (Session.fetchStoredToken()) { window.location.assign("/app/controls"); }
|
||||
logInit();
|
||||
API.setBaseUrl(API.fetchBrowserLocation());
|
||||
this.setState({});
|
||||
|
@ -83,7 +83,7 @@ export class FrontPage extends React.Component<{}, Partial<FrontPageState>> {
|
|||
axios.post<AuthState>(API.current.tokensPath, payload)
|
||||
.then(resp => {
|
||||
Session.replaceToken(resp.data);
|
||||
window.location.href = "/app/controls";
|
||||
window.location.assign("/app/controls");
|
||||
}).catch((error: Error) => {
|
||||
switch (get(error, "response.status")) {
|
||||
case 451: // TOS was updated; User must agree to terms.
|
||||
|
|
|
@ -63,7 +63,7 @@ function route<T, U>(info: UnboundRouteConfig<T, U>) {
|
|||
const child = (await info.getChild())[info.childKey];
|
||||
callback(comp, child, info);
|
||||
} else {
|
||||
callback((await info.getModule())[info.key], undefined, info);
|
||||
callback(comp, undefined, info);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
|
@ -89,8 +89,9 @@ const key = "FarmDesigner";
|
|||
/** Bind the route to a callback by calling in a function that passes the
|
||||
callback in as the first argument.
|
||||
*
|
||||
* DO NOT RE-ORDER ITEMS FOR READABILITY- they are order dependant.
|
||||
* DO NOT RE-ORDER ITEMS FOR READABILITY--they are order-dependent.
|
||||
* Stuff will break if the route order is changed.
|
||||
* (e.g., must be "a" then "a/:b/c" then "a/:b", 404 must be last, etc.)
|
||||
*/
|
||||
export const UNBOUND_ROUTES = [
|
||||
route({
|
||||
|
|
|
@ -1,24 +1,20 @@
|
|||
jest.mock("../../i18n", () => {
|
||||
return {
|
||||
detectLanguage: () => Promise.resolve({})
|
||||
};
|
||||
});
|
||||
jest.mock("../../i18n", () => ({ detectLanguage: () => Promise.resolve({}) }));
|
||||
|
||||
jest.mock("axios", () => {
|
||||
return {
|
||||
post: jest.fn(() => {
|
||||
return Promise.resolve({
|
||||
data: { token: { unencoded: {}, encoded: "========" } }
|
||||
});
|
||||
})
|
||||
};
|
||||
});
|
||||
const mockToken = { token: { unencoded: {}, encoded: "========" } };
|
||||
let mockPostResponse = Promise.resolve({ data: mockToken });
|
||||
jest.mock("axios", () => ({
|
||||
post: jest.fn(() => mockPostResponse),
|
||||
}));
|
||||
|
||||
jest.mock("../../session", () => ({ Session: { replaceToken: jest.fn() } }));
|
||||
|
||||
import * as React from "react";
|
||||
import { TosUpdate } from "../component";
|
||||
import { shallow, mount } from "enzyme";
|
||||
import axios from "axios";
|
||||
import { API } from "../../api/index";
|
||||
import { Session } from "../../session";
|
||||
import { error } from "farmbot-toastr";
|
||||
|
||||
type E = React.FormEvent<HTMLInputElement>;
|
||||
|
||||
|
@ -43,27 +39,35 @@ describe("<TosUpdate/>", () => {
|
|||
expect(wow.setState).toHaveBeenCalledWith({ email: "foo@bar.com" });
|
||||
});
|
||||
|
||||
it("submits a form", () => {
|
||||
type FormEvent = React.FormEvent<HTMLFormElement>;
|
||||
const fakeEvent: Partial<FormEvent> = { preventDefault: jest.fn() };
|
||||
type FormEvent = React.FormEvent<HTMLFormElement>;
|
||||
const fakeEvent: Partial<FormEvent> = { preventDefault: jest.fn() };
|
||||
const fake = {
|
||||
email: "foo@bar.com",
|
||||
password: "password123",
|
||||
agree_to_terms: true
|
||||
};
|
||||
|
||||
it("submits a form", async () => {
|
||||
location.assign = jest.fn();
|
||||
const i = instance();
|
||||
i.setState({
|
||||
email: "foo@bar.com",
|
||||
password: "password123",
|
||||
agree_to_terms: true
|
||||
});
|
||||
i.forceUpdate();
|
||||
i.submit(fakeEvent as FormEvent);
|
||||
i.setState(fake);
|
||||
await i.submit(fakeEvent as FormEvent);
|
||||
expect(fakeEvent.preventDefault).toHaveBeenCalled();
|
||||
const expectation = {
|
||||
user: {
|
||||
agree_to_terms: true,
|
||||
email: "foo@bar.com",
|
||||
password: "password123"
|
||||
}
|
||||
};
|
||||
expect(axios.post)
|
||||
.toHaveBeenCalledWith(API.current.tokensPath, expectation);
|
||||
.toHaveBeenCalledWith(API.current.tokensPath, { user: fake });
|
||||
expect(Session.replaceToken).toHaveBeenCalledWith(mockToken);
|
||||
expect(location.assign).toHaveBeenCalledWith("/app/controls");
|
||||
});
|
||||
|
||||
it("errors while submitting", async () => {
|
||||
mockPostResponse = Promise.reject({ response: { data: ["error"] } });
|
||||
const i = instance();
|
||||
i.setState(fake);
|
||||
await i.submit(fakeEvent as FormEvent);
|
||||
expect(fakeEvent.preventDefault).toHaveBeenCalled();
|
||||
await expect(axios.post)
|
||||
.toHaveBeenCalledWith(API.current.tokensPath, { user: fake });
|
||||
await expect(error).toHaveBeenCalledWith(expect.stringContaining("error"));
|
||||
});
|
||||
|
||||
it("shows TOS and Privacy links", () => {
|
||||
|
|
|
@ -38,7 +38,7 @@ export class TosUpdate extends React.Component<Props, Partial<State>> {
|
|||
.post<AuthState>(API.current.tokensPath, payload)
|
||||
.then(resp => {
|
||||
Session.replaceToken(resp.data);
|
||||
window.location.href = "/app/controls";
|
||||
window.location.assign("/app/controls");
|
||||
})
|
||||
.catch(error => {
|
||||
logError(prettyPrintApiErrors(error));
|
||||
|
|
Loading…
Reference in New Issue