Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions apps/desktop/src/app/DesktopApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import * as DesktopShutdown from "./DesktopShutdown.ts";
import * as DesktopServerExposure from "../backend/DesktopServerExposure.ts";
import * as DesktopAppSettings from "../settings/DesktopAppSettings.ts";
import * as DesktopShellEnvironment from "../shell/DesktopShellEnvironment.ts";
import * as DesktopStartupRecovery from "./DesktopStartupRecovery.ts";
import * as DesktopState from "./DesktopState.ts";
import * as DesktopRemoteUpdates from "../updates/DesktopRemoteUpdates.ts";
import * as DesktopUpdates from "../updates/DesktopUpdates.ts";
Expand Down Expand Up @@ -325,6 +326,7 @@ const startup = Effect.gen(function* () {
yield* applicationMenu.configure;
yield* updates.configure;
yield* DesktopRemoteUpdates.listen;
yield* DesktopStartupRecovery.listen;
yield* linuxUrlHandler.register;
yield* bootstrap.pipe(Effect.catchCause((cause) => fatalStartupCause("bootstrap", cause)));
}).pipe(Effect.withSpan("desktop.startup"));
Expand Down
70 changes: 70 additions & 0 deletions apps/desktop/src/app/DesktopStartupRecovery.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import type { DesktopUpdateState } from "@t3tools/contracts";
import { describe, expect, it } from "vite-plus/test";

import { createInitialDesktopUpdateState } from "../updates/updateMachine.ts";
import { resolveStartupRecoveryOffer } from "./DesktopStartupRecovery.ts";

const updateState = (patch: Partial<DesktopUpdateState>): DesktopUpdateState => ({
...createInitialDesktopUpdateState(
"0.1.3",
{ hostArch: "arm64", appArch: "arm64", runningUnderArm64Translation: false },
"latest",
),
enabled: true,
...patch,
});

describe("resolveStartupRecoveryOffer", () => {
it("offers a newer version before going back", () => {
expect(
resolveStartupRecoveryOffer(
updateState({ status: "available", availableVersion: "0.1.4" }),
"0.1.2",
),
).toEqual({ _tag: "Update", version: "0.1.4" });
});

it("offers a retained download after a later check fails", () => {
expect(
resolveStartupRecoveryOffer(
updateState({ status: "error", errorContext: "check", downloadedVersion: "0.1.4" }),
null,
),
).toEqual({ _tag: "Update", version: "0.1.4" });
});

it("waits for the update check before offering to go back", () => {
expect(resolveStartupRecoveryOffer(updateState({ status: "checking" }), "0.1.2")).toEqual({
_tag: "Checking",
});
});

it("offers the last version that started when no update exists", () => {
expect(resolveStartupRecoveryOffer(updateState({ status: "up-to-date" }), "0.1.2")).toEqual({
_tag: "Reinstall",
version: "0.1.2",
});
});

it("does not offer an update that already failed to apply here", () => {
expect(
resolveStartupRecoveryOffer(
updateState({
status: "downloaded",
downloadedVersion: "0.1.4",
notAppliedVersion: "0.1.4",
}),
"0.1.2",
),
).toEqual({ _tag: "Reinstall", version: "0.1.2" });
});

it("falls back to the releases page when this version never started", () => {
expect(resolveStartupRecoveryOffer(updateState({ status: "disabled" }), "0.1.3")).toEqual({
_tag: "Releases",
});
expect(resolveStartupRecoveryOffer(updateState({ status: "up-to-date" }), null)).toEqual({
_tag: "Releases",
});
});
});
Loading
Loading