update os update button
parent
2765d345ac
commit
6203326734
|
@ -262,19 +262,21 @@ describe("fetchReleases()", () => {
|
|||
expect(axios.get).toHaveBeenCalledWith("url");
|
||||
expect(mockError).not.toHaveBeenCalled();
|
||||
expect(dispatch).toHaveBeenCalledWith({
|
||||
payload: "1.0.0",
|
||||
payload: { version: "1.0.0", commit: undefined },
|
||||
type: Actions.FETCH_OS_UPDATE_INFO_OK
|
||||
});
|
||||
});
|
||||
|
||||
it("fetches latest beta OS release version", async () => {
|
||||
mockGetRelease = Promise.resolve({ data: { tag_name: "v1.0.0-beta" } });
|
||||
mockGetRelease = Promise.resolve({
|
||||
data: { tag_name: "v1.0.0-beta", target_commitish: "commit" }
|
||||
});
|
||||
const dispatch = jest.fn();
|
||||
await actions.fetchReleases("url", { beta: true })(dispatch, jest.fn());
|
||||
expect(axios.get).toHaveBeenCalledWith("url");
|
||||
expect(mockError).not.toHaveBeenCalled();
|
||||
expect(dispatch).toHaveBeenCalledWith({
|
||||
payload: "1.0.0-beta",
|
||||
payload: { version: "1.0.0-beta", commit: "commit" },
|
||||
type: Actions.FETCH_BETA_OS_UPDATE_INFO_OK
|
||||
});
|
||||
});
|
||||
|
|
|
@ -66,7 +66,7 @@ describe("botRedcuer", () => {
|
|||
it("fetches OS update info", () => {
|
||||
const r = botReducer(initialState(), {
|
||||
type: Actions.FETCH_OS_UPDATE_INFO_OK,
|
||||
payload: "1.2.3"
|
||||
payload: { version: "1.2.3", commit: undefined }
|
||||
}).currentOSVersion;
|
||||
expect(r).toBe("1.2.3");
|
||||
});
|
||||
|
|
|
@ -143,13 +143,13 @@ export let fetchReleases =
|
|||
axios
|
||||
.get(url)
|
||||
.then((resp: HttpData<GithubRelease>) => {
|
||||
const version = resp.data.tag_name;
|
||||
const versionWithoutV = version.toLowerCase().replace("v", "");
|
||||
const { tag_name, target_commitish } = resp.data;
|
||||
const version = tag_name.toLowerCase().replace("v", "");
|
||||
dispatch({
|
||||
type: options.beta
|
||||
? Actions.FETCH_BETA_OS_UPDATE_INFO_OK
|
||||
: Actions.FETCH_OS_UPDATE_INFO_OK,
|
||||
payload: versionWithoutV
|
||||
payload: { version, commit: target_commitish }
|
||||
});
|
||||
})
|
||||
.catch((ferror) => {
|
||||
|
|
|
@ -12,6 +12,7 @@ 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";
|
||||
|
||||
describe("<OsUpdateButton/>", () => {
|
||||
beforeEach(function () {
|
||||
|
@ -19,17 +20,37 @@ describe("<OsUpdateButton/>", () => {
|
|||
bot.hardware.configuration.beta_opt_in = false;
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
const fakeProps = (): OsUpdateButtonProps => {
|
||||
return {
|
||||
bot,
|
||||
sourceFbosConfig: (x) => {
|
||||
return { value: bot.hardware.configuration[x], consistent: true };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
it("renders buttons: not connected", () => {
|
||||
const buttons = mount(<OsUpdateButton bot={bot} />);
|
||||
bot.currentOSVersion = undefined;
|
||||
const buttons = mount(<OsUpdateButton {...fakeProps() } />);
|
||||
expect(buttons.find("button").length).toBe(1);
|
||||
const autoUpdate = buttons.find("button").first();
|
||||
expect(autoUpdate.hasClass("yellow")).toBeTruthy();
|
||||
const osUpdateButton = buttons.find("button").last();
|
||||
expect(osUpdateButton.text()).toBe("Can't Connect to release server");
|
||||
expect(osUpdateButton.text()).toBe("Can't connect to release server");
|
||||
});
|
||||
it("renders buttons: not connected to bot", () => {
|
||||
bot.hardware.informational_settings.controller_version = undefined;
|
||||
const buttons = mount(<OsUpdateButton {...fakeProps() } />);
|
||||
expect(buttons.find("button").length).toBe(1);
|
||||
const autoUpdate = buttons.find("button").first();
|
||||
expect(autoUpdate.hasClass("yellow")).toBeTruthy();
|
||||
const osUpdateButton = buttons.find("button").last();
|
||||
expect(osUpdateButton.text()).toBe("Can't connect to bot");
|
||||
});
|
||||
it("renders buttons: no beta releases", () => {
|
||||
bot.hardware.configuration.beta_opt_in = true;
|
||||
const buttons = mount(<OsUpdateButton bot={bot} />);
|
||||
const buttons = mount(<OsUpdateButton {...fakeProps() } />);
|
||||
expect(buttons.find("button").length).toBe(1);
|
||||
const autoUpdate = buttons.find("button").first();
|
||||
expect(autoUpdate.hasClass("yellow")).toBeTruthy();
|
||||
|
@ -38,21 +59,21 @@ describe("<OsUpdateButton/>", () => {
|
|||
});
|
||||
it("up to date", () => {
|
||||
bot.hardware.informational_settings.controller_version = "3.1.6";
|
||||
const buttons = mount(<OsUpdateButton bot={bot} />);
|
||||
const buttons = mount(<OsUpdateButton {...fakeProps() } />);
|
||||
const osUpdateButton = buttons.find("button").last();
|
||||
expect(osUpdateButton.text()).toBe("UP TO DATE");
|
||||
expect(osUpdateButton.props().title).toBe("3.1.6");
|
||||
});
|
||||
it("up to date: newer", () => {
|
||||
bot.hardware.informational_settings.controller_version = "5.0.0";
|
||||
const buttons = mount(<OsUpdateButton bot={bot} />);
|
||||
const buttons = mount(<OsUpdateButton {...fakeProps() } />);
|
||||
const osUpdateButton = buttons.find("button").last();
|
||||
expect(osUpdateButton.text()).toBe("UP TO DATE");
|
||||
expect(osUpdateButton.props().title).toBe("3.1.6");
|
||||
});
|
||||
it("update available", () => {
|
||||
bot.hardware.informational_settings.controller_version = "3.1.5";
|
||||
const buttons = mount(<OsUpdateButton bot={bot} />);
|
||||
const buttons = mount(<OsUpdateButton {...fakeProps() } />);
|
||||
const osUpdateButton = buttons.find("button").last();
|
||||
expect(osUpdateButton.text()).toBe("UPDATE");
|
||||
expect(osUpdateButton.props().title).toBe("3.1.6");
|
||||
|
@ -61,13 +82,24 @@ describe("<OsUpdateButton/>", () => {
|
|||
bot.hardware.informational_settings.controller_version = "3.1.5";
|
||||
bot.hardware.configuration.beta_opt_in = true;
|
||||
bot.currentBetaOSVersion = "5.0.0-beta";
|
||||
const buttons = mount(<OsUpdateButton bot={bot} />);
|
||||
const buttons = mount(<OsUpdateButton {...fakeProps() } />);
|
||||
const osUpdateButton = buttons.find("button").last();
|
||||
expect(osUpdateButton.text()).toBe("UPDATE");
|
||||
expect(osUpdateButton.props().title).toBe("5.0.0-beta");
|
||||
});
|
||||
it("beta update has same numeric version: newer commit", () => {
|
||||
bot.hardware.informational_settings.controller_version = "5.0.0";
|
||||
bot.hardware.informational_settings.commit = "old commit";
|
||||
bot.hardware.configuration.beta_opt_in = true;
|
||||
bot.currentBetaOSVersion = "5.0.0-beta";
|
||||
bot.currentBetaOSCommit = "new commit";
|
||||
const buttons = mount(<OsUpdateButton {...fakeProps() } />);
|
||||
const osUpdateButton = buttons.find("button").last();
|
||||
expect(osUpdateButton.text()).toBe("UPDATE");
|
||||
expect(osUpdateButton.props().title).toBe("5.0.0-beta");
|
||||
});
|
||||
it("calls checkUpdates", () => {
|
||||
const buttons = mount(<OsUpdateButton bot={bot} />);
|
||||
const buttons = mount(<OsUpdateButton {...fakeProps() } />);
|
||||
const osUpdateButton = buttons.find("button").last();
|
||||
osUpdateButton.simulate("click");
|
||||
expect(mockDevice.checkUpdates).toHaveBeenCalledTimes(1);
|
||||
|
@ -78,7 +110,7 @@ describe("<OsUpdateButton/>", () => {
|
|||
bot.hardware.jobs = {
|
||||
"FBOS_OTA": { status: "working", bytes: progress, unit: "bytes" }
|
||||
};
|
||||
const buttons = mount(<OsUpdateButton bot={bot} />);
|
||||
const buttons = mount(<OsUpdateButton {...fakeProps() } />);
|
||||
const osUpdateButton = buttons.find("button").last();
|
||||
expect(osUpdateButton.text()).toBe(text);
|
||||
});
|
||||
|
@ -91,7 +123,7 @@ describe("<OsUpdateButton/>", () => {
|
|||
bot.hardware.jobs = {
|
||||
"FBOS_OTA": { status: "working", percent: 10, unit: "percent" }
|
||||
};
|
||||
const buttons = mount(<OsUpdateButton bot={bot} />);
|
||||
const buttons = mount(<OsUpdateButton {...fakeProps() } />);
|
||||
const osUpdateButton = buttons.find("button").last();
|
||||
expect(osUpdateButton.text()).toBe("10%");
|
||||
});
|
||||
|
@ -100,7 +132,7 @@ describe("<OsUpdateButton/>", () => {
|
|||
"FBOS_OTA": { status: "complete", percent: 100, unit: "percent" }
|
||||
};
|
||||
bot.hardware.informational_settings.controller_version = "3.1.6";
|
||||
const buttons = mount(<OsUpdateButton bot={bot} />);
|
||||
const buttons = mount(<OsUpdateButton {...fakeProps() } />);
|
||||
const osUpdateButton = buttons.find("button").last();
|
||||
expect(osUpdateButton.text()).toBe("UP TO DATE");
|
||||
});
|
||||
|
@ -109,7 +141,7 @@ describe("<OsUpdateButton/>", () => {
|
|||
"FBOS_OTA": { status: "error", percent: 10, unit: "percent" }
|
||||
};
|
||||
bot.hardware.informational_settings.controller_version = "3.1.5";
|
||||
const buttons = mount(<OsUpdateButton bot={bot} />);
|
||||
const buttons = mount(<OsUpdateButton {...fakeProps() } />);
|
||||
const osUpdateButton = buttons.find("button").last();
|
||||
expect(osUpdateButton.text()).toBe("UPDATE");
|
||||
});
|
||||
|
@ -117,7 +149,7 @@ describe("<OsUpdateButton/>", () => {
|
|||
bot.hardware.jobs = {
|
||||
"FBOS_OTA": { status: "working", percent: 10, unit: "percent" }
|
||||
};
|
||||
const buttons = mount(<OsUpdateButton bot={bot} />);
|
||||
const buttons = mount(<OsUpdateButton {...fakeProps() } />);
|
||||
const osUpdateButton = buttons.find("button").last();
|
||||
osUpdateButton.simulate("click");
|
||||
expect(mockDevice.checkUpdates).not.toHaveBeenCalled();
|
||||
|
|
|
@ -74,7 +74,7 @@ export function FarmbotOsRow(props: FarmbotOsRowProps) {
|
|||
</Popover>
|
||||
</Col>
|
||||
<Col xs={3}>
|
||||
<OsUpdateButton bot={bot} />
|
||||
<OsUpdateButton bot={bot} sourceFbosConfig={sourceFbosConfig} />
|
||||
</Col>
|
||||
</Row >;
|
||||
}
|
||||
|
|
|
@ -40,3 +40,8 @@ export interface FbosDetailsProps {
|
|||
dispatch: Function;
|
||||
sourceFbosConfig: SourceFbosConfig;
|
||||
}
|
||||
|
||||
export interface OsUpdateButtonProps {
|
||||
bot: BotState;
|
||||
sourceFbosConfig: SourceFbosConfig;
|
||||
}
|
||||
|
|
|
@ -3,16 +3,34 @@ import { t } from "i18next";
|
|||
import * as _ from "lodash";
|
||||
import { JobProgress } from "farmbot/dist";
|
||||
import { SemverResult, semverCompare } from "../../../util";
|
||||
import { BotProp } from "../../interfaces";
|
||||
import { OsUpdateButtonProps } from "./interfaces";
|
||||
import { checkControllerUpdates } from "../../actions";
|
||||
|
||||
export let OsUpdateButton = ({ bot }: BotProp) => {
|
||||
let buttonStr = "Can't Connect to bot";
|
||||
let buttonColor = "yellow";
|
||||
enum UpdateButton { upToDate, needsUpdate, unknown, unknownBeta, none }
|
||||
|
||||
const { beta_opt_in } = bot.hardware.configuration;
|
||||
const { currentOSVersion, currentBetaOSVersion } = bot;
|
||||
const latestReleaseV = beta_opt_in
|
||||
const buttonProps = (status: UpdateButton) => {
|
||||
switch (status) {
|
||||
case UpdateButton.needsUpdate:
|
||||
return { color: "green", text: t("UPDATE") };
|
||||
case UpdateButton.upToDate:
|
||||
return { color: "gray", text: t("UP TO DATE") };
|
||||
case UpdateButton.unknownBeta:
|
||||
return { color: "yellow", text: t("No beta releases available") };
|
||||
case UpdateButton.unknown:
|
||||
return { color: "yellow", text: t("Can't connect to release server") };
|
||||
default:
|
||||
return { color: "yellow", text: t("Can't connect to bot") };
|
||||
}
|
||||
};
|
||||
|
||||
export let OsUpdateButton = (props: OsUpdateButtonProps) => {
|
||||
const { bot, sourceFbosConfig } = props;
|
||||
let buttonStatus = UpdateButton.none;
|
||||
|
||||
const betaOptIn = sourceFbosConfig("beta_opt_in").value;
|
||||
const { currentOSVersion, currentBetaOSVersion, currentBetaOSCommit } = bot;
|
||||
const { commit } = bot.hardware.informational_settings;
|
||||
const latestReleaseV = betaOptIn
|
||||
? currentBetaOSVersion
|
||||
: currentOSVersion;
|
||||
const { controller_version } = bot.hardware.informational_settings;
|
||||
|
@ -20,17 +38,22 @@ export let OsUpdateButton = ({ bot }: BotProp) => {
|
|||
switch (semverCompare(latestReleaseV, controller_version)) {
|
||||
case SemverResult.RIGHT_IS_GREATER:
|
||||
case SemverResult.EQUAL:
|
||||
buttonStr = t("UP TO DATE");
|
||||
buttonColor = "gray";
|
||||
buttonStatus = UpdateButton.upToDate;
|
||||
break;
|
||||
default:
|
||||
buttonStr = t("UPDATE");
|
||||
buttonColor = "green";
|
||||
buttonStatus = UpdateButton.needsUpdate;
|
||||
}
|
||||
} else {
|
||||
buttonStr = beta_opt_in
|
||||
? "No beta releases available"
|
||||
: "Can't Connect to release server";
|
||||
if (!_.isString(latestReleaseV)) {
|
||||
buttonStatus = betaOptIn
|
||||
? UpdateButton.unknownBeta
|
||||
: UpdateButton.unknown;
|
||||
}
|
||||
}
|
||||
if (betaOptIn
|
||||
&& _.isString(commit) && _.isString(currentBetaOSCommit)
|
||||
&& commit !== currentBetaOSCommit) {
|
||||
buttonStatus = UpdateButton.needsUpdate;
|
||||
}
|
||||
|
||||
const osUpdateJob = (bot.hardware.jobs || {})["FBOS_OTA"];
|
||||
|
@ -58,10 +81,10 @@ export let OsUpdateButton = ({ bot }: BotProp) => {
|
|||
}
|
||||
|
||||
return <button
|
||||
className={"fb-button " + buttonColor}
|
||||
className={"fb-button " + buttonProps(buttonStatus).color}
|
||||
title={latestReleaseV}
|
||||
disabled={isWorking(osUpdateJob)}
|
||||
onClick={() => checkControllerUpdates()}>
|
||||
{downloadProgress(osUpdateJob) || buttonStr}
|
||||
{downloadProgress(osUpdateJob) || buttonProps(buttonStatus).text}
|
||||
</button>;
|
||||
};
|
||||
|
|
|
@ -62,6 +62,8 @@ export interface BotState {
|
|||
currentOSVersion?: string;
|
||||
/** The current beta os version on the github release api */
|
||||
currentBetaOSVersion?: string;
|
||||
/** The current beta os commit on the github release api */
|
||||
currentBetaOSCommit?: string;
|
||||
/** Is the bot in sync with the api */
|
||||
dirty: boolean;
|
||||
/** The state of the bot, as reported by the bot over MQTT. */
|
||||
|
@ -76,13 +78,17 @@ export interface BotState {
|
|||
connectivity: ConnectionState;
|
||||
}
|
||||
|
||||
export interface BotProp { bot: BotState; }
|
||||
|
||||
/** Status registers for the bot's status */
|
||||
export type HardwareState = BotStateTree;
|
||||
|
||||
export interface GithubRelease {
|
||||
tag_name: string;
|
||||
target_commitish: string;
|
||||
}
|
||||
|
||||
export interface OsUpdateInfo {
|
||||
version: string;
|
||||
commit: string;
|
||||
}
|
||||
|
||||
export interface MoveRelProps {
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import { BotState, HardwareState, Xyz, ControlPanelState } from "./interfaces";
|
||||
import {
|
||||
BotState, HardwareState, Xyz, ControlPanelState, OsUpdateInfo
|
||||
} from "./interfaces";
|
||||
import { generateReducer } from "../redux/generate_reducer";
|
||||
import { Actions } from "../constants";
|
||||
import { EncoderDisplay } from "../controls/interfaces";
|
||||
|
@ -144,12 +146,13 @@ export let botReducer = generateReducer<BotState>(initialState(), afterEach)
|
|||
s.controlPanelState.danger_zone = a.payload;
|
||||
return s;
|
||||
})
|
||||
.add<string>(Actions.FETCH_OS_UPDATE_INFO_OK, (s, { payload }) => {
|
||||
s.currentOSVersion = payload;
|
||||
.add<OsUpdateInfo>(Actions.FETCH_OS_UPDATE_INFO_OK, (s, { payload }) => {
|
||||
s.currentOSVersion = payload.version;
|
||||
return s;
|
||||
})
|
||||
.add<string>(Actions.FETCH_BETA_OS_UPDATE_INFO_OK, (s, { payload }) => {
|
||||
s.currentBetaOSVersion = payload;
|
||||
.add<OsUpdateInfo>(Actions.FETCH_BETA_OS_UPDATE_INFO_OK, (s, { payload }) => {
|
||||
s.currentBetaOSVersion = payload.version;
|
||||
s.currentBetaOSCommit = payload.commit;
|
||||
return s;
|
||||
})
|
||||
.add<HardwareState>(Actions.BOT_CHANGE, (state, { payload }) => {
|
||||
|
|
Loading…
Reference in New Issue