Farmbot-Web-App/frontend/devices/components/fbos_settings/__tests__/os_update_button_test.tsx

395 lines
13 KiB
TypeScript

const mockDevice = {
checkUpdates: jest.fn(() => Promise.resolve()),
updateConfig: jest.fn(() => Promise.resolve()),
};
jest.mock("../../../../device", () => ({ getDevice: () => mockDevice }));
import * as React from "react";
import { mount } from "enzyme";
import { bot } from "../../../../__test_support__/fake_state/bot";
import { OsUpdateButton } from "../os_update_button";
import { OsUpdateButtonProps } from "../interfaces";
import { ShouldDisplay } from "../../../interfaces";
import { Content } from "../../../../constants";
import { ConfigurationName } from "farmbot";
const UPDATE_CHANNEL = "update_channel" as ConfigurationName;
describe("<OsUpdateButton/>", () => {
beforeEach(() => {
bot.currentOSVersion = "6.1.6";
bot.hardware.informational_settings.controller_version = "6.1.6";
(bot.hardware.configuration[UPDATE_CHANNEL] as string) = "stable";
});
const fakeProps = (): OsUpdateButtonProps => ({
bot,
sourceFbosConfig: x =>
({ value: bot.hardware.configuration[x], consistent: true }),
botOnline: true,
shouldDisplay: () => false,
});
interface TestProps {
installedVersion: string | undefined;
installedCommit: string;
availableVersion: string | undefined;
availableBetaVersion: string | undefined;
availableBetaCommit: string | undefined;
onBeta: boolean | undefined;
update_available?: boolean | undefined;
shouldDisplay: ShouldDisplay;
update_channel: string;
}
const defaultTestProps = (): TestProps => ({
installedVersion: "6.1.6",
installedCommit: "",
availableVersion: "6.1.6",
availableBetaVersion: undefined,
availableBetaCommit: undefined,
onBeta: false,
shouldDisplay: () => false,
update_channel: "stable",
});
interface Results {
text: string;
title: string | undefined;
color: string;
disabled: boolean;
}
const updateNeeded = (title: string | undefined): Results =>
({
text: "UPDATE",
title,
color: "green",
disabled: false,
});
const upToDate = (title: string | undefined): Results =>
({
text: "UP TO DATE",
title,
color: "gray",
disabled: false,
});
const cantConnect = (entity: string): Results =>
({
text: `Can't connect to ${entity}`,
title: undefined,
color: "yellow",
disabled: false,
});
const tooOld = (): Results =>
({
text: Content.TOO_OLD_TO_UPDATE,
title: "6.1.6",
color: "yellow",
disabled: false,
});
const updating = (progress: string): Results =>
({
text: progress,
title: undefined,
color: "gray",
disabled: true,
});
const testButtonState = (
testProps: TestProps,
expected: Results) => {
const {
installedVersion, installedCommit, onBeta, update_available,
availableVersion, availableBetaVersion, availableBetaCommit,
shouldDisplay, update_channel,
} = testProps;
bot.hardware.informational_settings.controller_version = installedVersion;
bot.hardware.informational_settings.commit = installedCommit;
bot.hardware.informational_settings.currently_on_beta = onBeta;
bot.hardware.informational_settings.update_available =
update_available || false;
bot.currentOSVersion = availableVersion;
bot.currentBetaOSVersion = availableBetaVersion;
bot.currentBetaOSCommit = availableBetaCommit;
(bot.hardware.configuration[UPDATE_CHANNEL] as string) = update_channel;
const p = fakeProps();
p.shouldDisplay = shouldDisplay;
const buttons = mount(<OsUpdateButton {...p} />);
const osUpdateButton = buttons.find("button").first();
expect(osUpdateButton.text()).toBe(expected.text);
expect(osUpdateButton.props().title).toBe(expected.title);
expect(osUpdateButton.hasClass(expected.color)).toBe(true);
expect((osUpdateButton.props().disabled)).toBe(expected.disabled);
};
it("renders buttons: too old", () => {
const testProps = defaultTestProps();
testProps.installedVersion = "5.0.0";
const expectedResults = tooOld();
testButtonState(testProps, expectedResults);
});
it("renders buttons: not connected", () => {
const testProps = defaultTestProps();
testProps.installedVersion = undefined;
testProps.availableVersion = undefined;
const expectedResults = cantConnect("bot");
testButtonState(testProps, expectedResults);
});
it("renders buttons: connected to releases but not bot", () => {
const testProps = defaultTestProps();
testProps.installedVersion = undefined;
const expectedResults = cantConnect("bot");
expectedResults.title = "6.1.6";
testButtonState(testProps, expectedResults);
});
it("renders buttons: no releases available", () => {
const testProps = defaultTestProps();
testProps.installedVersion = "6.1.6";
testProps.availableVersion = undefined;
testProps.update_channel = "beta";
const expectedResults = cantConnect("release server");
testButtonState(testProps, expectedResults);
});
it("renders buttons: only beta release available", () => {
const testProps = defaultTestProps();
testProps.installedVersion = "6.1.6";
testProps.availableVersion = undefined;
testProps.availableBetaVersion = "6.1.7-beta";
testProps.update_channel = "beta";
const expectedResults = updateNeeded("6.1.7-beta");
testButtonState(testProps, expectedResults);
});
it("renders buttons: no beta release available", () => {
const testProps = defaultTestProps();
testProps.installedVersion = "6.1.6";
testProps.availableBetaVersion = undefined;
testProps.update_channel = "beta";
const expectedResults = upToDate("6.1.6");
testButtonState(testProps, expectedResults);
});
it("up to date", () => {
const testProps = defaultTestProps();
testProps.installedVersion = "6.1.6";
const expectedResults = upToDate("6.1.6");
testButtonState(testProps, expectedResults);
});
it("up to date: newer", () => {
const testProps = defaultTestProps();
testProps.installedVersion = "7.0.0";
const expectedResults = upToDate("6.1.6");
testButtonState(testProps, expectedResults);
});
it("update available", () => {
const testProps = defaultTestProps();
testProps.installedVersion = "6.1.5";
const expectedResults = updateNeeded("6.1.6");
testButtonState(testProps, expectedResults);
});
it("beta update available", () => {
const testProps = defaultTestProps();
testProps.installedVersion = "6.1.5";
testProps.availableBetaVersion = "7.0.0-beta";
testProps.update_channel = "beta";
const expectedResults = updateNeeded("7.0.0-beta");
testButtonState(testProps, expectedResults);
});
it("latest newer than beta update: latest installed", () => {
const testProps = defaultTestProps();
testProps.installedVersion = "6.1.6";
testProps.availableBetaVersion = "6.1.6-beta";
testProps.update_channel = "beta";
const expectedResults = upToDate("6.1.6");
testButtonState(testProps, expectedResults);
});
it("latest newer than beta update: beta installed", () => {
const testProps = defaultTestProps();
testProps.installedVersion = "6.1.6";
testProps.availableBetaVersion = "6.1.6-beta";
testProps.update_channel = "beta";
testProps.onBeta = true;
const expectedResults = updateNeeded("6.1.6");
testButtonState(testProps, expectedResults);
});
it("latest newer than beta update: beta installed (beta disabled)", () => {
const testProps = defaultTestProps();
testProps.installedVersion = "6.1.6";
testProps.availableBetaVersion = "6.1.6-beta";
testProps.update_channel = "stable";
testProps.onBeta = true;
const expectedResults = updateNeeded("6.1.6");
testButtonState(testProps, expectedResults);
});
it("on latest beta update", () => {
const testProps = defaultTestProps();
testProps.installedVersion = "6.1.7";
testProps.availableBetaVersion = "6.1.7-beta";
testProps.update_channel = "beta";
testProps.onBeta = true;
const expectedResults = upToDate("6.1.7-beta");
testButtonState(testProps, expectedResults);
});
it("on latest beta update: already has beta suffix", () => {
const testProps = defaultTestProps();
testProps.installedVersion = "6.1.7-beta";
testProps.availableBetaVersion = "6.1.7-beta";
testProps.update_channel = "beta";
const expectedResults = upToDate("6.1.7-beta");
testButtonState(testProps, expectedResults);
});
it("beta update has same numeric version: newer commit", () => {
const testProps = defaultTestProps();
testProps.installedVersion = "7.0.0";
testProps.installedCommit = "old commit";
testProps.availableBetaVersion = "7.0.0-beta";
testProps.availableBetaCommit = "new commit";
testProps.update_channel = "beta";
testProps.onBeta = true;
const expectedResults = updateNeeded("7.0.0-beta");
testButtonState(testProps, expectedResults);
});
it("handles installed version newer than available (beta enabled)", () => {
const testProps = defaultTestProps();
testProps.installedVersion = "6.1.7";
testProps.update_channel = "beta";
testProps.onBeta = false;
testProps.availableBetaVersion = "6.1.7-beta";
const expectedResults = upToDate("6.1.7-beta");
testButtonState(testProps, expectedResults);
});
it("handles FBOS update available override", () => {
const testProps = defaultTestProps();
testProps.installedVersion = "6.1.6";
testProps.update_available = true;
const expectedResults = updateNeeded("6.1.6");
testButtonState(testProps, expectedResults);
});
it("uses update_channel value", () => {
const testProps = defaultTestProps();
testProps.installedVersion = "6.1.6";
testProps.shouldDisplay = () => true;
testProps.update_channel = "stable";
testProps.availableBetaVersion = "6.1.7-beta";
const expectedResults = upToDate("6.1.6");
testButtonState(testProps, expectedResults);
});
it("uses update_channel value: beta", () => {
const testProps = defaultTestProps();
testProps.installedVersion = "6.1.6";
testProps.shouldDisplay = () => true;
testProps.update_channel = "beta";
testProps.availableBetaVersion = "6.1.7-beta";
const expectedResults = updateNeeded("6.1.7-beta");
testButtonState(testProps, expectedResults);
});
it("compares release candidates: newer", () => {
const testProps = defaultTestProps();
testProps.availableVersion = "6.1.5";
testProps.installedVersion = "6.1.6-rc1";
testProps.shouldDisplay = () => true;
testProps.update_channel = "beta";
testProps.availableBetaVersion = "6.1.6-rc2";
const expectedResults = updateNeeded("6.1.6-rc2");
testButtonState(testProps, expectedResults);
});
it("compares release candidates: older", () => {
const testProps = defaultTestProps();
testProps.availableVersion = "6.1.5";
testProps.installedVersion = "6.1.6-rc2";
testProps.shouldDisplay = () => true;
testProps.update_channel = "beta";
testProps.availableBetaVersion = "6.1.6-rc1";
const expectedResults = upToDate("6.1.6-rc1");
testButtonState(testProps, expectedResults);
});
it("calls checkUpdates", () => {
const buttons = mount(<OsUpdateButton {...fakeProps()} />);
const osUpdateButton = buttons.find("button").first();
osUpdateButton.simulate("click");
expect(mockDevice.checkUpdates).toHaveBeenCalledTimes(1);
});
it("handles undefined jobs", () => {
// tslint:disable-next-line:no-any
bot.hardware.jobs = undefined as any;
const buttons = mount(<OsUpdateButton {...fakeProps()} />);
const osUpdateButton = buttons.find("button").first();
expect(osUpdateButton.text()).toEqual("UP TO DATE");
});
it.each<[string, number]>([
["300B", 300],
["29kB", 30000],
["3MB", 3e6],
])("shows bytes update progress: %s", (expected, progress) => {
bot.hardware.jobs = {
"FBOS_OTA": { status: "working", bytes: progress, unit: "bytes" }
};
const buttons = mount(<OsUpdateButton {...fakeProps()} />);
const osUpdateButton = buttons.find("button").first();
expect(osUpdateButton.text()).toBe(expected);
});
it("shows percent update progress: 10%", () => {
bot.hardware.jobs = {
"FBOS_OTA": { status: "working", percent: 10, unit: "percent" }
};
const expectedResults = updating("10%");
expectedResults.title = "6.1.6";
testButtonState(defaultTestProps(), expectedResults);
});
it("update success", () => {
bot.hardware.jobs = {
"FBOS_OTA": { status: "complete", percent: 100, unit: "percent" }
};
testButtonState(defaultTestProps(), upToDate("6.1.6"));
});
it("update failed", () => {
bot.hardware.jobs = {
"FBOS_OTA": { status: "error", percent: 10, unit: "percent" }
};
const testProps = defaultTestProps();
testProps.installedVersion = "6.1.5";
testButtonState(testProps, updateNeeded("6.1.6"));
});
it("is disabled", () => {
bot.hardware.jobs = {
"FBOS_OTA": { status: "working", percent: 10, unit: "percent" }
};
const buttons = mount(<OsUpdateButton {...fakeProps()} />);
const osUpdateButton = buttons.find("button").first();
osUpdateButton.simulate("click");
expect(mockDevice.checkUpdates).not.toHaveBeenCalled();
});
});