| ... | @@ -1,4 +1,5 @@ | ... | @@ -1,4 +1,5 @@ |
| 1 | import { assert, describe, it } from "@effect/vitest"; | 1 | import { assert, describe, it } from "@effect/vitest"; |
| | 2 | import * as Cause from "effect/Cause"; |
| 2 | import * as Effect from "effect/Effect"; | 3 | import * as Effect from "effect/Effect"; |
| 3 | import { beforeEach, vi } from "vite-plus/test"; | 4 | import { beforeEach, vi } from "vite-plus/test"; |
| 4 | | 5 | |
| ... | @@ -98,6 +99,60 @@ describe("ElectronProtocol", () => { | ... | @@ -98,6 +99,60 @@ describe("ElectronProtocol", () => { |
| 98 | }).pipe(Effect.provide(ElectronProtocol.layer)), | 99 | }).pipe(Effect.provide(ElectronProtocol.layer)), |
| 99 | ); | 100 | ); |
| 100 | | 101 | |
| | 102 | it.effect("preserves protocol registration failures", () => |
| | 103 | Effect.gen(function* () { |
| | 104 | const cause = new Error("protocol registration failed"); |
| | 105 | handleMock.mockImplementationOnce(() => { |
| | 106 | throw cause; |
| | 107 | }); |
| | 108 | |
| | 109 | const protocol = yield* ElectronProtocol.ElectronProtocol; |
| | 110 | const error = yield* Effect.scoped( |
| | 111 | protocol.registerDesktopProtocol({ |
| | 112 | scheme: "t3code-dev", |
| | 113 | targetOrigin: new URL("http://127.0.0.1:3773/"), |
| | 114 | backendOrigin: new URL("http://127.0.0.1:3774/"), |
| | 115 | clerkFrontendApiHostname: undefined, |
| | 116 | }), |
| | 117 | ).pipe(Effect.flip); |
| | 118 | |
| | 119 | assert.instanceOf(error, ElectronProtocol.ElectronProtocolRegistrationError); |
| | 120 | assert.equal(error.scheme, "t3code-dev"); |
| | 121 | assert.strictEqual(error.cause, cause); |
| | 122 | assert.equal(error.message, 'Failed to register Electron protocol scheme "t3code-dev".'); |
| | 123 | }).pipe(Effect.provide(ElectronProtocol.layer)), |
| | 124 | ); |
| | 125 | |
| | 126 | it.effect("preserves protocol unregistration failures", () => |
| | 127 | Effect.gen(function* () { |
| | 128 | const cause = new Error("protocol unregistration failed"); |
| | 129 | unhandleMock.mockImplementationOnce(() => { |
| | 130 | throw cause; |
| | 131 | }); |
| | 132 | |
| | 133 | const protocol = yield* ElectronProtocol.ElectronProtocol; |
| | 134 | const exit = yield* Effect.exit( |
| | 135 | Effect.scoped( |
| | 136 | protocol.registerDesktopProtocol({ |
| | 137 | scheme: "t3code", |
| | 138 | targetOrigin: new URL("http://127.0.0.1:3773/"), |
| | 139 | backendOrigin: new URL("http://127.0.0.1:3773/"), |
| | 140 | clerkFrontendApiHostname: undefined, |
| | 141 | }), |
| | 142 | ), |
| | 143 | ); |
| | 144 | |
| | 145 | assert.equal(exit._tag, "Failure"); |
| | 146 | if (exit._tag === "Failure") { |
| | 147 | const error = Cause.squash(exit.cause); |
| | 148 | assert.instanceOf(error, ElectronProtocol.ElectronProtocolUnregistrationError); |
| | 149 | assert.equal(error.scheme, "t3code"); |
| | 150 | assert.strictEqual(error.cause, cause); |
| | 151 | assert.equal(error.message, 'Failed to unregister Electron protocol scheme "t3code".'); |
| | 152 | } |
| | 153 | }).pipe(Effect.provide(ElectronProtocol.layer)), |
| | 154 | ); |
| | 155 | |
| 101 | it("keeps executable sources host-restricted while allowing runtime network resources", () => { | 156 | it("keeps executable sources host-restricted while allowing runtime network resources", () => { |
| 102 | const policy = ElectronProtocol.makeDesktopContentSecurityPolicy({ | 157 | const policy = ElectronProtocol.makeDesktopContentSecurityPolicy({ |
| 103 | scheme: "t3code", | 158 | scheme: "t3code", |