From d6bbe3a969dc64eda82fc341524a2acfcb56a875 Mon Sep 17 00:00:00 2001 From: Iku-turso Date: Tue, 21 Jun 2022 10:19:31 +0300 Subject: [PATCH] Implement env-agnostic helper to resolve proxy from URL Co-authored-by: Janne Savolainen Signed-off-by: Iku-turso --- .../resolve-proxy-channel.injectable.ts | 21 +++++ .../common/resolve-proxy-injection-token.ts | 12 +++ ...olve-proxy-channel-responder.injectable.ts | 21 +++++ .../resolve-proxy-from-electron.injectable.ts | 15 ++++ .../main/resolve-proxy.injectable.ts | 21 +++++ .../renderer/resolve-proxy.injectable.ts | 23 +++++ .../proxy/resolve-proxy/resolve-proxy.test.ts | 85 +++++++++++++++++++ 7 files changed, 198 insertions(+) create mode 100644 src/behaviours/proxy/resolve-proxy/common/resolve-proxy-channel.injectable.ts create mode 100644 src/behaviours/proxy/resolve-proxy/common/resolve-proxy-injection-token.ts create mode 100644 src/behaviours/proxy/resolve-proxy/main/resolve-proxy-channel-responder.injectable.ts create mode 100644 src/behaviours/proxy/resolve-proxy/main/resolve-proxy-from-electron.injectable.ts create mode 100644 src/behaviours/proxy/resolve-proxy/main/resolve-proxy.injectable.ts create mode 100644 src/behaviours/proxy/resolve-proxy/renderer/resolve-proxy.injectable.ts create mode 100644 src/behaviours/proxy/resolve-proxy/resolve-proxy.test.ts diff --git a/src/behaviours/proxy/resolve-proxy/common/resolve-proxy-channel.injectable.ts b/src/behaviours/proxy/resolve-proxy/common/resolve-proxy-channel.injectable.ts new file mode 100644 index 0000000000..aee889c8fd --- /dev/null +++ b/src/behaviours/proxy/resolve-proxy/common/resolve-proxy-channel.injectable.ts @@ -0,0 +1,21 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import type { RequestChannel } from "../../../../common/utils/channel/request-channel-injection-token"; +import { requestChannelInjectionToken } from "../../../../common/utils/channel/request-channel-injection-token"; + +export type ResolveProxyChannel = RequestChannel; + +const resolveProxyChannelInjectable = getInjectable({ + id: "resolve-proxy-channel", + + instantiate: (): ResolveProxyChannel => ({ + id: "resolve-proxy-channel", + }), + + injectionToken: requestChannelInjectionToken, +}); + +export default resolveProxyChannelInjectable; diff --git a/src/behaviours/proxy/resolve-proxy/common/resolve-proxy-injection-token.ts b/src/behaviours/proxy/resolve-proxy/common/resolve-proxy-injection-token.ts new file mode 100644 index 0000000000..5a084f004f --- /dev/null +++ b/src/behaviours/proxy/resolve-proxy/common/resolve-proxy-injection-token.ts @@ -0,0 +1,12 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ + +import { getInjectionToken } from "@ogre-tools/injectable"; + +export type ResolveProxy = (url: string) => Promise; + +export const resolveProxyInjectionToken = getInjectionToken({ + id: "resolve-proxy", +}); diff --git a/src/behaviours/proxy/resolve-proxy/main/resolve-proxy-channel-responder.injectable.ts b/src/behaviours/proxy/resolve-proxy/main/resolve-proxy-channel-responder.injectable.ts new file mode 100644 index 0000000000..dfee36149a --- /dev/null +++ b/src/behaviours/proxy/resolve-proxy/main/resolve-proxy-channel-responder.injectable.ts @@ -0,0 +1,21 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import resolveProxyChannelInjectable from "../common/resolve-proxy-channel.injectable"; +import resolveProxyInjectable from "./resolve-proxy.injectable"; +import { requestChannelListenerInjectionToken } from "../../../../common/utils/channel/request-channel-listener-injection-token"; + +const resolveProxyChannelResponderInjectable = getInjectable({ + id: "resolve-proxy-channel-responder", + + instantiate: (di) => ({ + channel: di.inject(resolveProxyChannelInjectable), + handler: di.inject(resolveProxyInjectable), + }), + + injectionToken: requestChannelListenerInjectionToken, +}); + +export default resolveProxyChannelResponderInjectable; diff --git a/src/behaviours/proxy/resolve-proxy/main/resolve-proxy-from-electron.injectable.ts b/src/behaviours/proxy/resolve-proxy/main/resolve-proxy-from-electron.injectable.ts new file mode 100644 index 0000000000..d1e26e0dba --- /dev/null +++ b/src/behaviours/proxy/resolve-proxy/main/resolve-proxy-from-electron.injectable.ts @@ -0,0 +1,15 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; + +const resolveProxyFromElectronInjectable = getInjectable({ + id: "resolve-proxy-from-electron", + + instantiate: () => async (url: string) => "not-implemented-yet", + + causesSideEffects: true, +}); + +export default resolveProxyFromElectronInjectable; diff --git a/src/behaviours/proxy/resolve-proxy/main/resolve-proxy.injectable.ts b/src/behaviours/proxy/resolve-proxy/main/resolve-proxy.injectable.ts new file mode 100644 index 0000000000..12367da4ad --- /dev/null +++ b/src/behaviours/proxy/resolve-proxy/main/resolve-proxy.injectable.ts @@ -0,0 +1,21 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { resolveProxyInjectionToken } from "../common/resolve-proxy-injection-token"; +import resolveProxyFromElectronInjectable from "./resolve-proxy-from-electron.injectable"; + +const resolveProxyInjectable = getInjectable({ + id: "resolve-proxy-for-main", + + instantiate: (di) => { + const resolveProxyFromElectron = di.inject(resolveProxyFromElectronInjectable); + + return (url) => resolveProxyFromElectron(url); + }, + + injectionToken: resolveProxyInjectionToken, +}); + +export default resolveProxyInjectable; diff --git a/src/behaviours/proxy/resolve-proxy/renderer/resolve-proxy.injectable.ts b/src/behaviours/proxy/resolve-proxy/renderer/resolve-proxy.injectable.ts new file mode 100644 index 0000000000..5a7d5da073 --- /dev/null +++ b/src/behaviours/proxy/resolve-proxy/renderer/resolve-proxy.injectable.ts @@ -0,0 +1,23 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { resolveProxyInjectionToken } from "../common/resolve-proxy-injection-token"; +import requestFromChannelInjectable from "../../../../renderer/utils/channel/request-from-channel.injectable"; +import resolveProxyChannelInjectable from "../common/resolve-proxy-channel.injectable"; + +const resolveProxyInjectable = getInjectable({ + id: "resolve-proxy-for-renderer", + + instantiate: (di) => { + const requestFromChannel = di.inject(requestFromChannelInjectable); + const resolveProxyChannel = di.inject(resolveProxyChannelInjectable); + + return async (url) => requestFromChannel(resolveProxyChannel, url); + }, + + injectionToken: resolveProxyInjectionToken, +}); + +export default resolveProxyInjectable; diff --git a/src/behaviours/proxy/resolve-proxy/resolve-proxy.test.ts b/src/behaviours/proxy/resolve-proxy/resolve-proxy.test.ts new file mode 100644 index 0000000000..ee25d7b500 --- /dev/null +++ b/src/behaviours/proxy/resolve-proxy/resolve-proxy.test.ts @@ -0,0 +1,85 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import type { AsyncFnMock } from "@async-fn/jest"; +import asyncFn from "@async-fn/jest"; +import type { ApplicationBuilder } from "../../../renderer/components/test-utils/get-application-builder"; +import { getApplicationBuilder } from "../../../renderer/components/test-utils/get-application-builder"; +import type { ResolveProxy } from "./common/resolve-proxy-injection-token"; +import { resolveProxyInjectionToken } from "./common/resolve-proxy-injection-token"; +import resolveProxyFromElectronInjectable from "./main/resolve-proxy-from-electron.injectable"; +import { getPromiseStatus } from "../../../common/test-utils/get-promise-status"; + +describe("resolve-proxy", () => { + let applicationBuilder: ApplicationBuilder; + let actualPromise: Promise; + let resolveProxyFromElectronMock: AsyncFnMock; + + beforeEach(async () => { + applicationBuilder = getApplicationBuilder(); + + resolveProxyFromElectronMock = asyncFn(); + + applicationBuilder.beforeApplicationStart(({ mainDi }) => { + mainDi.override( + resolveProxyFromElectronInjectable, + () => resolveProxyFromElectronMock, + ); + }); + + await applicationBuilder.render(); + }); + + describe("given in main, when called with URL", () => { + beforeEach(async () => { + const resolveProxyInMain = applicationBuilder.dis.mainDi.inject( + resolveProxyInjectionToken, + ); + + actualPromise = resolveProxyInMain("some-url"); + }); + + it("calls for proxy of the URL from Electron", () => { + expect(resolveProxyFromElectronMock).toHaveBeenCalledWith("some-url"); + }); + + it("does not resolve yet", async () => { + const promiseStatus = await getPromiseStatus(actualPromise); + + expect(promiseStatus.fulfilled).toBe(false); + }); + + it("when the call for proxy resolves, resolves with the proxy", async () => { + resolveProxyFromElectronMock.resolve("some-proxy"); + + expect(await actualPromise).toBe("some-proxy"); + }); + }); + + describe("given in renderer, when called with URL", () => { + beforeEach(async () => { + const resolveProxyInRenderer = applicationBuilder.dis.rendererDi.inject( + resolveProxyInjectionToken, + ); + + actualPromise = resolveProxyInRenderer("some-url"); + }); + + it("calls for proxy of the URL from Electron", () => { + expect(resolveProxyFromElectronMock).toHaveBeenCalledWith("some-url"); + }); + + it("does not resolve yet", async () => { + const promiseStatus = await getPromiseStatus(actualPromise); + + expect(promiseStatus.fulfilled).toBe(false); + }); + + it("when the call for proxy resolves, resolves with the proxy", async () => { + resolveProxyFromElectronMock.resolve("some-proxy"); + + expect(await actualPromise).toBe("some-proxy"); + }); + }); +});