os update updates
parent
c7e4ee3a0e
commit
654533ae4b
|
@ -53,7 +53,7 @@
|
|||
"css-loader": "^1.0.1",
|
||||
"enzyme": "^3.7.0",
|
||||
"enzyme-adapter-react-16": "^1.7.0",
|
||||
"farmbot": "^6.6.0-rc1",
|
||||
"farmbot": "^6.6.0",
|
||||
"farmbot-toastr": "^1.0.3",
|
||||
"fastclick": "^1.0.6",
|
||||
"file-loader": "2.0.0",
|
||||
|
|
|
@ -146,6 +146,7 @@ export class FarmbotOsSettings
|
|||
osReleaseNotes={this.state.osReleaseNotes}
|
||||
dispatch={this.props.dispatch}
|
||||
sourceFbosConfig={sourceFbosConfig}
|
||||
shouldDisplay={this.props.shouldDisplay}
|
||||
botOnline={botOnline} />
|
||||
<AutoUpdateRow
|
||||
dispatch={this.props.dispatch}
|
||||
|
|
|
@ -15,6 +15,7 @@ describe("<FarmbotOsRow/>", () => {
|
|||
sourceFbosConfig: (x) => {
|
||||
return { value: bot.hardware.configuration[x], consistent: true };
|
||||
},
|
||||
shouldDisplay: () => false,
|
||||
botOnline: false
|
||||
};
|
||||
};
|
||||
|
|
|
@ -6,7 +6,7 @@ jest.mock("../../../../device", () => ({
|
|||
}));
|
||||
|
||||
import * as React from "react";
|
||||
import { FbosDetails, colorFromTemp } from "../fbos_details";
|
||||
import { FbosDetails, colorFromTemp, betaReleaseOptIn } from "../fbos_details";
|
||||
import { shallow, mount } from "enzyme";
|
||||
import { bot } from "../../../../__test_support__/fake_state/bot";
|
||||
import { FbosDetailsProps } from "../interfaces";
|
||||
|
@ -17,6 +17,7 @@ describe("<FbosDetails/>", () => {
|
|||
return {
|
||||
botInfoSettings: bot.hardware.informational_settings,
|
||||
dispatch: jest.fn(x => x(jest.fn(), fakeState)),
|
||||
shouldDisplay: () => false,
|
||||
sourceFbosConfig: x =>
|
||||
({ value: bot.hardware.configuration[x], consistent: true }),
|
||||
};
|
||||
|
@ -148,6 +149,56 @@ describe("<FbosDetails/>", () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe("betaReleaseOptIn()", () => {
|
||||
it("uses `beta_opt_in`: beta enabled", () => {
|
||||
const result = betaReleaseOptIn({
|
||||
sourceFbosConfig: () => ({ value: true, consistent: true }),
|
||||
shouldDisplay: () => false
|
||||
});
|
||||
expect(result).toEqual({
|
||||
betaOptIn: { consistent: true, value: true },
|
||||
betaOptInValue: true,
|
||||
update: { beta_opt_in: false }
|
||||
});
|
||||
});
|
||||
|
||||
it("uses `beta_opt_in`: beta disabled", () => {
|
||||
const result = betaReleaseOptIn({
|
||||
sourceFbosConfig: () => ({ value: false, consistent: true }),
|
||||
shouldDisplay: () => false
|
||||
});
|
||||
expect(result).toEqual({
|
||||
betaOptIn: { consistent: true, value: false },
|
||||
betaOptInValue: false,
|
||||
update: { beta_opt_in: true }
|
||||
});
|
||||
});
|
||||
|
||||
it("uses `update_channel`: beta enabled", () => {
|
||||
const result = betaReleaseOptIn({
|
||||
sourceFbosConfig: () => ({ value: "beta", consistent: true }),
|
||||
shouldDisplay: () => true
|
||||
});
|
||||
expect(result).toEqual({
|
||||
betaOptIn: { consistent: true, value: true },
|
||||
betaOptInValue: true,
|
||||
update: { update_channel: "stable" }
|
||||
});
|
||||
});
|
||||
|
||||
it("uses `update_channel`: beta disabled", () => {
|
||||
const result = betaReleaseOptIn({
|
||||
sourceFbosConfig: () => ({ value: "stable", consistent: true }),
|
||||
shouldDisplay: () => true
|
||||
});
|
||||
expect(result).toEqual({
|
||||
betaOptIn: { consistent: true, value: false },
|
||||
betaOptInValue: false,
|
||||
update: { update_channel: "beta" }
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("colorFromTemp()", () => {
|
||||
it("temperature is good or none", () => {
|
||||
expect(colorFromTemp(30)).toEqual("green");
|
||||
|
|
|
@ -33,6 +33,7 @@ describe("<OsUpdateButton/>", () => {
|
|||
availableBetaCommit: string | undefined;
|
||||
betaOptIn: boolean | undefined;
|
||||
onBeta: boolean | undefined;
|
||||
update_available?: boolean | undefined;
|
||||
}
|
||||
|
||||
const defaultTestProps = (): TestProps => ({
|
||||
|
@ -88,12 +89,15 @@ describe("<OsUpdateButton/>", () => {
|
|||
testProps: TestProps,
|
||||
expected: Results) => {
|
||||
const {
|
||||
installedVersion, installedCommit, onBeta,
|
||||
installedVersion, installedCommit, onBeta, update_available,
|
||||
availableVersion, availableBetaVersion, availableBetaCommit, betaOptIn
|
||||
} = testProps;
|
||||
bot.hardware.informational_settings.controller_version = installedVersion;
|
||||
bot.hardware.informational_settings.commit = installedCommit;
|
||||
bot.hardware.informational_settings.currently_on_beta = onBeta;
|
||||
// tslint:disable-next-line:no-any // TODO: fix FBJS
|
||||
(bot.hardware.informational_settings as any).update_available =
|
||||
update_available || false;
|
||||
bot.currentOSVersion = availableVersion;
|
||||
bot.currentBetaOSVersion = availableBetaVersion;
|
||||
bot.currentBetaOSCommit = availableBetaCommit;
|
||||
|
@ -242,6 +246,14 @@ describe("<OsUpdateButton/>", () => {
|
|||
testButtonState(testProps, expectedResults);
|
||||
});
|
||||
|
||||
it("handles FBOS update available override", () => {
|
||||
const testProps = defaultTestProps();
|
||||
testProps.installedVersion = "3.1.6";
|
||||
testProps.update_available = true;
|
||||
const expectedResults = updateNeeded("3.1.6");
|
||||
testButtonState(testProps, expectedResults);
|
||||
});
|
||||
|
||||
it("calls checkUpdates", () => {
|
||||
const buttons = mount(<OsUpdateButton {...fakeProps()} />);
|
||||
const osUpdateButton = buttons.find("button").first();
|
||||
|
|
|
@ -30,6 +30,7 @@ export function FarmbotOsRow(props: FarmbotOsRowProps) {
|
|||
<FbosDetails
|
||||
botInfoSettings={bot.hardware.informational_settings}
|
||||
dispatch={dispatch}
|
||||
shouldDisplay={props.shouldDisplay}
|
||||
sourceFbosConfig={sourceFbosConfig} />
|
||||
</Popover>
|
||||
</Col>
|
||||
|
|
|
@ -6,7 +6,8 @@ import { updateConfig } from "../../actions";
|
|||
import { last, isNumber } from "lodash";
|
||||
import { Content } from "../../../constants";
|
||||
import { FbosDetailsProps } from "./interfaces";
|
||||
import { SourceFbosConfig } from "../../interfaces";
|
||||
import { SourceFbosConfig, ShouldDisplay, Feature } from "../../interfaces";
|
||||
import { ConfigurationName } from "farmbot";
|
||||
|
||||
/** Return an indicator color for the given temperature (C). */
|
||||
export const colorFromTemp = (temp: number | undefined): string => {
|
||||
|
@ -99,24 +100,48 @@ const UptimeDisplay = ({ uptime_sec }: { uptime_sec: number }): JSX.Element => {
|
|||
return <p><b>{t("Uptime")}: </b>{convertUptime(uptime_sec)}</p>;
|
||||
};
|
||||
|
||||
/** Label and toggle button for opting in to FBOS beta releases. */
|
||||
const BetaReleaseOptInButton = ({ dispatch, sourceFbosConfig }: {
|
||||
dispatch: Function, sourceFbosConfig: SourceFbosConfig
|
||||
}): JSX.Element => {
|
||||
const betaOptIn = sourceFbosConfig("beta_opt_in");
|
||||
return <fieldset>
|
||||
<label style={{ marginTop: "0.75rem" }}>
|
||||
{t("Beta release Opt-In")}
|
||||
</label>
|
||||
<ToggleButton
|
||||
toggleValue={betaOptIn.value}
|
||||
dim={!betaOptIn.consistent}
|
||||
toggleAction={() =>
|
||||
(betaOptIn.value || confirm(Content.OS_BETA_RELEASES)) &&
|
||||
dispatch(updateConfig({ beta_opt_in: !betaOptIn.value }))} />
|
||||
</fieldset>;
|
||||
export const betaReleaseOptIn = ({ sourceFbosConfig, shouldDisplay }: {
|
||||
sourceFbosConfig: SourceFbosConfig, shouldDisplay: ShouldDisplay
|
||||
}) => {
|
||||
if (shouldDisplay(Feature.use_update_channel)) {
|
||||
const betaOptIn = sourceFbosConfig("update_channel" as ConfigurationName);
|
||||
const betaOptInValue = betaOptIn.value !== "stable";
|
||||
return {
|
||||
betaOptIn: { value: betaOptInValue, consistent: true }, betaOptInValue,
|
||||
update: { update_channel: betaOptInValue ? "stable" : "beta" }
|
||||
};
|
||||
} else {
|
||||
const betaOptIn = sourceFbosConfig("beta_opt_in");
|
||||
const betaOptInValue = betaOptIn.value;
|
||||
return {
|
||||
betaOptIn, betaOptInValue,
|
||||
update: { beta_opt_in: !betaOptInValue }
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/** Label and toggle button for opting in to FBOS beta releases. */
|
||||
const BetaReleaseOptInButton =
|
||||
({ dispatch, sourceFbosConfig, shouldDisplay }: {
|
||||
dispatch: Function,
|
||||
sourceFbosConfig: SourceFbosConfig,
|
||||
shouldDisplay: ShouldDisplay,
|
||||
}): JSX.Element => {
|
||||
const { betaOptIn, betaOptInValue, update } =
|
||||
betaReleaseOptIn({ sourceFbosConfig, shouldDisplay });
|
||||
return <fieldset>
|
||||
<label style={{ marginTop: "0.75rem" }}>
|
||||
{t("Beta release Opt-In")}
|
||||
</label>
|
||||
<ToggleButton
|
||||
toggleValue={betaOptInValue}
|
||||
dim={!betaOptIn.consistent}
|
||||
toggleAction={() =>
|
||||
(betaOptInValue || confirm(Content.OS_BETA_RELEASES)) &&
|
||||
dispatch(updateConfig(update))} />
|
||||
</fieldset>;
|
||||
};
|
||||
|
||||
/** Current technical information about FarmBot OS running on the device. */
|
||||
export function FbosDetails(props: FbosDetailsProps) {
|
||||
const {
|
||||
|
@ -139,6 +164,7 @@ export function FbosDetails(props: FbosDetailsProps) {
|
|||
<WiFiStrengthDisplay wifiStrength={wifi_level} />
|
||||
<BetaReleaseOptInButton
|
||||
dispatch={props.dispatch}
|
||||
shouldDisplay={props.shouldDisplay}
|
||||
sourceFbosConfig={props.sourceFbosConfig} />
|
||||
</div>;
|
||||
}
|
||||
|
|
|
@ -53,12 +53,14 @@ export interface FarmbotOsRowProps {
|
|||
osReleaseNotes: string;
|
||||
dispatch: Function;
|
||||
sourceFbosConfig: SourceFbosConfig;
|
||||
shouldDisplay: ShouldDisplay;
|
||||
botOnline: boolean;
|
||||
}
|
||||
|
||||
export interface FbosDetailsProps {
|
||||
botInfoSettings: InformationalSettings;
|
||||
dispatch: Function;
|
||||
shouldDisplay: ShouldDisplay;
|
||||
sourceFbosConfig: SourceFbosConfig;
|
||||
}
|
||||
|
||||
|
|
|
@ -118,7 +118,10 @@ const buttonVersionStatus =
|
|||
const { currentOSVersion, currentBetaOSVersion, currentBetaOSCommit } = bot;
|
||||
// Currently installed FBOS version data.
|
||||
const botInfo = bot.hardware.informational_settings;
|
||||
const { controller_version, commit, currently_on_beta } = botInfo;
|
||||
const {
|
||||
controller_version, commit, currently_on_beta, update_available
|
||||
// tslint:disable-next-line:no-any // TODO: fix FBJS
|
||||
} = botInfo as any;
|
||||
|
||||
/** Newest release version, given settings and data available. */
|
||||
const latestReleaseV =
|
||||
|
@ -135,8 +138,9 @@ const buttonVersionStatus =
|
|||
/** `1.0.0-beta vs 1.0.0-beta`: installed beta is older. */
|
||||
const oldBetaCommit = (latestReleaseV === currentBetaOSVersion) &&
|
||||
!betaCommitsAreEqual(commit, currentBetaOSCommit);
|
||||
/** Button status modification required for beta release edge cases. */
|
||||
const updateStatusOverride = uncertainty && oldBetaCommit;
|
||||
/** Button status modification required for release edge cases. */
|
||||
const updateStatusOverride = update_available
|
||||
|| (uncertainty && oldBetaCommit);
|
||||
|
||||
return buttonProps(
|
||||
updateStatusOverride ? UpdateButton.needsUpdate : btnStatus,
|
||||
|
|
|
@ -76,6 +76,7 @@ export enum Feature {
|
|||
firmware_restart = "firmware_restart",
|
||||
api_farmware_installations = "api_farmware_installations",
|
||||
api_farmware_env = "api_farmware_env",
|
||||
use_update_channel = "use_update_channel",
|
||||
}
|
||||
/** Object fetched from FEATURE_MIN_VERSIONS_URL. */
|
||||
export type MinOsFeatureLookup = Partial<Record<Feature, string>>;
|
||||
|
|
Loading…
Reference in New Issue