Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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