mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Fix faking lensFetch
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
aea545526d
commit
fdae7870da
@ -304,6 +304,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@async-fn/jest": "1.6.4",
|
"@async-fn/jest": "1.6.4",
|
||||||
|
"@hapi/shot": "^6.0.0",
|
||||||
"@material-ui/core": "^4.12.3",
|
"@material-ui/core": "^4.12.3",
|
||||||
"@material-ui/icons": "^4.11.2",
|
"@material-ui/icons": "^4.11.2",
|
||||||
"@material-ui/lab": "^4.0.0-alpha.60",
|
"@material-ui/lab": "^4.0.0-alpha.60",
|
||||||
@ -406,7 +407,6 @@
|
|||||||
"memfs": "^3.4.13",
|
"memfs": "^3.4.13",
|
||||||
"memorystream": "^0.3.1",
|
"memorystream": "^0.3.1",
|
||||||
"mini-css-extract-plugin": "^2.7.2",
|
"mini-css-extract-plugin": "^2.7.2",
|
||||||
"mock-http": "^1.1.0",
|
|
||||||
"monaco-editor": "^0.29.1",
|
"monaco-editor": "^0.29.1",
|
||||||
"monaco-editor-webpack-plugin": "^5.0.0",
|
"monaco-editor-webpack-plugin": "^5.0.0",
|
||||||
"node-gyp": "^8.3.0",
|
"node-gyp": "^8.3.0",
|
||||||
|
|||||||
@ -19,7 +19,13 @@ export const advanceFakeTime = (milliseconds: number) => {
|
|||||||
export const testUsingFakeTime = (dateTime = "2015-10-21T07:28:00Z") => {
|
export const testUsingFakeTime = (dateTime = "2015-10-21T07:28:00Z") => {
|
||||||
usingFakeTime = true;
|
usingFakeTime = true;
|
||||||
|
|
||||||
jest.useFakeTimers();
|
jest.useFakeTimers({
|
||||||
|
doNotFake: [
|
||||||
|
"nextTick",
|
||||||
|
"setImmediate",
|
||||||
|
"clearImmediate",
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
jest.setSystemTime(new Date(dateTime));
|
jest.setSystemTime(new Date(dateTime));
|
||||||
};
|
};
|
||||||
|
|||||||
@ -132,7 +132,7 @@ describe("opening application window using tray", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("starts loading of content for the application window", () => {
|
it("starts loading of content for the application window", () => {
|
||||||
expect(callForApplicationWindowHtmlMock).toHaveBeenCalledWith("https://lens.app:42");
|
expect(callForApplicationWindowHtmlMock).toHaveBeenCalledWith("https://lens.app:23456");
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("given static HTML of application window has not resolved yet, when opening from tray again", () => {
|
describe("given static HTML of application window has not resolved yet, when opening from tray again", () => {
|
||||||
|
|||||||
@ -64,15 +64,11 @@ describe("quitting the app using application menu", () => {
|
|||||||
expect(exitAppMock).not.toHaveBeenCalled();
|
expect(exitAppMock).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("after sufficient time passes", () => {
|
it("after sufficient time passes, terminates application", () => {
|
||||||
beforeEach(() => {
|
|
||||||
advanceFakeTime(1000);
|
advanceFakeTime(1000);
|
||||||
});
|
|
||||||
|
|
||||||
it("terminates application", () => {
|
|
||||||
expect(exitAppMock).toHaveBeenCalled();
|
expect(exitAppMock).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|||||||
@ -13,7 +13,7 @@ export default getGlobalOverride(lensProxyInjectable, (di) => {
|
|||||||
return ({
|
return ({
|
||||||
close: () => { },
|
close: () => { },
|
||||||
listen: async () => {
|
listen: async () => {
|
||||||
lensProxyPort.set(12345);
|
lensProxyPort.set(23456);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import type { DiContainerForInjection, Injectable, InjectionToken } from "@ogre-tools/injectable";
|
import type { Injectable, InjectionToken } from "@ogre-tools/injectable";
|
||||||
import { getInjectable, getInjectionToken } from "@ogre-tools/injectable";
|
import { getInjectable, getInjectionToken } from "@ogre-tools/injectable";
|
||||||
import type { Route, LensApiRequest } from "./route";
|
import type { Route, LensApiRequest } from "./route";
|
||||||
import createHandlerForRouteInjectable from "./create-handler-for-route.injectable";
|
import createHandlerForRouteInjectable from "./create-handler-for-route.injectable";
|
||||||
@ -27,7 +27,9 @@ export function getRouteInjectable<T, Path extends string>(
|
|||||||
|
|
||||||
export type RouteRequest = (cluster: Cluster | undefined, req: IncomingMessage, res: ServerResponse) => Promise<boolean>;
|
export type RouteRequest = (cluster: Cluster | undefined, req: IncomingMessage, res: ServerResponse) => Promise<boolean>;
|
||||||
|
|
||||||
const createRouter = (di: DiContainerForInjection) => {
|
const routeRequestInjectable = getInjectable({
|
||||||
|
id: "route-request",
|
||||||
|
instantiate: (di): RouteRequest => {
|
||||||
const routes = di.injectMany(routeInjectionToken);
|
const routes = di.injectMany(routeInjectionToken);
|
||||||
const createHandlerForRoute = di.inject(createHandlerForRouteInjectable);
|
const createHandlerForRoute = di.inject(createHandlerForRouteInjectable);
|
||||||
const router = new Call.Router<RouteHandler>();
|
const router = new Call.Router<RouteHandler>();
|
||||||
@ -36,21 +38,13 @@ const createRouter = (di: DiContainerForInjection) => {
|
|||||||
router.add({ method: route.method, path: route.path }, createHandlerForRoute(route));
|
router.add({ method: route.method, path: route.path }, createHandlerForRoute(route));
|
||||||
}
|
}
|
||||||
|
|
||||||
return router;
|
|
||||||
};
|
|
||||||
|
|
||||||
const routeRequestInjectable = getInjectable({
|
|
||||||
id: "route-request",
|
|
||||||
instantiate: (di): RouteRequest => {
|
|
||||||
const router = createRouter(di);
|
|
||||||
|
|
||||||
return async (cluster, req, res) => {
|
return async (cluster, req, res) => {
|
||||||
if (!req.url || !req.method) {
|
if (!req.url || !req.method) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const url = new URL(req.url, "https://localhost");
|
const url = new URL(req.url, "https://localhost");
|
||||||
const matchingRoute = router.route(req.method, url.pathname);
|
const matchingRoute = router.route(req.method?.toLowerCase() ?? "get", url.pathname);
|
||||||
|
|
||||||
if (matchingRoute instanceof Error) {
|
if (matchingRoute instanceof Error) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -8,10 +8,8 @@ import { object } from "../../common/utils";
|
|||||||
|
|
||||||
export interface LensServerResponse {
|
export interface LensServerResponse {
|
||||||
statusCode: number;
|
statusCode: number;
|
||||||
content: any;
|
content: unknown;
|
||||||
headers: {
|
headers: Partial<Record<string, string | string[]>>;
|
||||||
[name: string]: string;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const writeServerResponseFor = (serverResponse: ServerResponse) => ({
|
export const writeServerResponseFor = (serverResponse: ServerResponse) => ({
|
||||||
|
|||||||
@ -31,8 +31,10 @@ const setupLensProxyInjectable = getInjectable({
|
|||||||
try {
|
try {
|
||||||
logger.info("🔌 Starting LensProxy");
|
logger.info("🔌 Starting LensProxy");
|
||||||
await lensProxy.listen(); // lensProxy.port available
|
await lensProxy.listen(); // lensProxy.port available
|
||||||
} catch (error: any) {
|
} catch (error) {
|
||||||
showErrorPopup("Lens Error", `Could not start proxy: ${error?.message || "unknown error"}`);
|
const message = error instanceof Error ? error.message : "unknown error";
|
||||||
|
|
||||||
|
showErrorPopup("Lens Error", `Could not start proxy: ${message}`);
|
||||||
|
|
||||||
return exitApp();
|
return exitApp();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -35,7 +35,6 @@ import { overrideChannels } from "../../../test-utils/channel-fakes/override-cha
|
|||||||
import assert from "assert";
|
import assert from "assert";
|
||||||
import { openMenu } from "react-select-event";
|
import { openMenu } from "react-select-event";
|
||||||
import userEvent from "@testing-library/user-event";
|
import userEvent from "@testing-library/user-event";
|
||||||
import lensProxyPortInjectable from "../../../main/lens-proxy/lens-proxy-port.injectable";
|
|
||||||
import type { Route } from "../../../common/front-end-routing/front-end-route-injection-token";
|
import type { Route } from "../../../common/front-end-routing/front-end-route-injection-token";
|
||||||
import type { NavigateToRouteOptions } from "../../../common/front-end-routing/navigate-to-route-injection-token";
|
import type { NavigateToRouteOptions } from "../../../common/front-end-routing/navigate-to-route-injection-token";
|
||||||
import { navigateToRouteInjectionToken } from "../../../common/front-end-routing/navigate-to-route-injection-token";
|
import { navigateToRouteInjectionToken } from "../../../common/front-end-routing/navigate-to-route-injection-token";
|
||||||
@ -72,9 +71,8 @@ import { testUsingFakeTime } from "../../../common/test-utils/use-fake-time";
|
|||||||
import type { LensFetch } from "../../../common/fetch/lens-fetch.injectable";
|
import type { LensFetch } from "../../../common/fetch/lens-fetch.injectable";
|
||||||
import lensFetchInjectable from "../../../common/fetch/lens-fetch.injectable";
|
import lensFetchInjectable from "../../../common/fetch/lens-fetch.injectable";
|
||||||
import handleLensRequestInjectable from "../../../main/lens-proxy/handle-lens-request.injectable";
|
import handleLensRequestInjectable from "../../../main/lens-proxy/handle-lens-request.injectable";
|
||||||
import httpMocks from "node-mocks-http";
|
|
||||||
import nodeFetchModuleInjectable from "../../../common/fetch/fetch-module.injectable";
|
import nodeFetchModuleInjectable from "../../../common/fetch/fetch-module.injectable";
|
||||||
import stream from "stream";
|
import * as Shot from "@hapi/shot";
|
||||||
|
|
||||||
type Callback = (di: DiContainer) => void | Promise<void>;
|
type Callback = (di: DiContainer) => void | Promise<void>;
|
||||||
|
|
||||||
@ -223,26 +221,28 @@ export const getApplicationBuilder = () => {
|
|||||||
const handleLensRequest = mainDi.inject(handleLensRequestInjectable);
|
const handleLensRequest = mainDi.inject(handleLensRequestInjectable);
|
||||||
const { Headers, Response } = di.inject(nodeFetchModuleInjectable);
|
const { Headers, Response } = di.inject(nodeFetchModuleInjectable);
|
||||||
|
|
||||||
const url = new URL(pathnameAndQuery, "https://127.0.0.1");
|
const response = await Shot.inject(
|
||||||
const req = httpMocks.createRequest({
|
handleLensRequest.handle as Shot.MaybeInjectionListener,
|
||||||
method: (init?.method ?? "get").toUpperCase() as any,
|
{
|
||||||
url: url.pathname,
|
url: pathnameAndQuery,
|
||||||
params: url.searchParams,
|
headers: new Headers(init?.headers).raw(),
|
||||||
body: (init?.body ?? undefined) as any,
|
method: init?.method,
|
||||||
headers: new Headers(init?.headers) as any,
|
payload: init?.body ?? undefined,
|
||||||
});
|
},
|
||||||
const duplex = new stream.Duplex();
|
);
|
||||||
const res = httpMocks.createResponse({
|
|
||||||
req,
|
|
||||||
writableStream: duplex,
|
|
||||||
});
|
|
||||||
|
|
||||||
await handleLensRequest.handle(req, res);
|
return new Response(response.rawPayload, {
|
||||||
|
headers: Object.entries(response.headers).map(([key, value]) => {
|
||||||
return new Response(duplex, {
|
if (value === undefined) {
|
||||||
headers: new Headers(res._getHeaders() as Record<string, string>),
|
return [key];
|
||||||
status: res._getStatusCode(),
|
} else if (Array.isArray(value)) {
|
||||||
statusText: res._getStatusMessage(),
|
return [key, value.join(",")];
|
||||||
|
} else {
|
||||||
|
return [key, value.toString()];
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
status: response.statusCode,
|
||||||
|
statusText: response.statusMessage,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -329,8 +329,6 @@ export const getApplicationBuilder = () => {
|
|||||||
const startMainApplication = mainDi.inject(startMainApplicationInjectable);
|
const startMainApplication = mainDi.inject(startMainApplicationInjectable);
|
||||||
|
|
||||||
const startApplication = async ({ shouldStartHidden }: { shouldStartHidden: boolean }) => {
|
const startApplication = async ({ shouldStartHidden }: { shouldStartHidden: boolean }) => {
|
||||||
mainDi.inject(lensProxyPortInjectable).set(42);
|
|
||||||
|
|
||||||
for (const callback of beforeApplicationStartCallbacks) {
|
for (const callback of beforeApplicationStartCallbacks) {
|
||||||
await callback(mainDi);
|
await callback(mainDi);
|
||||||
}
|
}
|
||||||
|
|||||||
35
yarn.lock
35
yarn.lock
@ -925,6 +925,14 @@
|
|||||||
"@hapi/hoek" "9.x.x"
|
"@hapi/hoek" "9.x.x"
|
||||||
"@hapi/nigel" "4.x.x"
|
"@hapi/nigel" "4.x.x"
|
||||||
|
|
||||||
|
"@hapi/shot@^6.0.0":
|
||||||
|
version "6.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@hapi/shot/-/shot-6.0.0.tgz#ed87a26dcb25c930293ae690830d3479dbf4e75a"
|
||||||
|
integrity sha512-RLGgzXy9GciJDunhY40NbVnLgYqp5gfBooZ2fOkAr4KbCEav/SJtYQS1N+knR7WFGzy8aooCR3XBUPI4ghHAkQ==
|
||||||
|
dependencies:
|
||||||
|
"@hapi/hoek" "^10.0.0"
|
||||||
|
"@hapi/validate" "^2.0.0"
|
||||||
|
|
||||||
"@hapi/subtext@^7.0.4":
|
"@hapi/subtext@^7.0.4":
|
||||||
version "7.0.4"
|
version "7.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/@hapi/subtext/-/subtext-7.0.4.tgz#aa46e4b45aad8115938334d5a3620a17b3b33ee5"
|
resolved "https://registry.yarnpkg.com/@hapi/subtext/-/subtext-7.0.4.tgz#aa46e4b45aad8115938334d5a3620a17b3b33ee5"
|
||||||
@ -945,6 +953,21 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@hapi/hoek" "^9.0.0"
|
"@hapi/hoek" "^9.0.0"
|
||||||
|
|
||||||
|
"@hapi/topo@^6.0.0":
|
||||||
|
version "6.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-6.0.0.tgz#6548e23e0a3d3b117eb0671dba49f654c9224c21"
|
||||||
|
integrity sha512-aorJvN1Q1n5xrZuA50Z4X6adI6VAM2NalIVm46ALL9LUvdoqhof3JPY69jdJH8asM3PsWr2SUVYzp57EqUP41A==
|
||||||
|
dependencies:
|
||||||
|
"@hapi/hoek" "^10.0.0"
|
||||||
|
|
||||||
|
"@hapi/validate@^2.0.0":
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@hapi/validate/-/validate-2.0.0.tgz#16595de18b2c29621f06f4b29dcc39750c4b94a3"
|
||||||
|
integrity sha512-w5m8MvBgqGndbMIB+AWmXTb8CLtF1DlIxbnbAHNAo7aFuNQuI1Ywc2e0zDLK5fbFXDoqRzNrHnC7JjNJ+hDigw==
|
||||||
|
dependencies:
|
||||||
|
"@hapi/hoek" "^10.0.0"
|
||||||
|
"@hapi/topo" "^6.0.0"
|
||||||
|
|
||||||
"@hapi/vise@^4.0.0":
|
"@hapi/vise@^4.0.0":
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@hapi/vise/-/vise-4.0.0.tgz#c6a94fe121b94a53bf99e7489f7fcc74c104db02"
|
resolved "https://registry.yarnpkg.com/@hapi/vise/-/vise-4.0.0.tgz#c6a94fe121b94a53bf99e7489f7fcc74c104db02"
|
||||||
@ -9361,11 +9384,6 @@ merge2@^1.3.0, merge2@^1.4.1:
|
|||||||
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
|
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
|
||||||
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
|
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
|
||||||
|
|
||||||
mergee@^1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/mergee/-/mergee-1.0.0.tgz#027c5addc650f6ecbe4bf56100bd00dae763fda7"
|
|
||||||
integrity sha512-hbbXD4LOcxVkpS+mp3BMEhkSDf+lTVENFeEeqACgjjL8WrgKuW2EyLT0fOHyTbyDiuRLZJZ1HrHNeiX4iOd79Q==
|
|
||||||
|
|
||||||
methods@^1.1.2, methods@~1.1.2:
|
methods@^1.1.2, methods@~1.1.2:
|
||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
|
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
|
||||||
@ -9609,13 +9627,6 @@ mobx@^6.3.0, mobx@^6.7.0:
|
|||||||
resolved "https://registry.yarnpkg.com/mobx/-/mobx-6.7.0.tgz#2d805610fee1801fd015c54fd5400d2601aa3768"
|
resolved "https://registry.yarnpkg.com/mobx/-/mobx-6.7.0.tgz#2d805610fee1801fd015c54fd5400d2601aa3768"
|
||||||
integrity sha512-1kBLBdSNG2bA522HQdbsTvwAwYf9hq9FWxmlhX7wTsJUAI54907J+ozfGW+LoYUo06vjit748g6QH1AAGLNebw==
|
integrity sha512-1kBLBdSNG2bA522HQdbsTvwAwYf9hq9FWxmlhX7wTsJUAI54907J+ozfGW+LoYUo06vjit748g6QH1AAGLNebw==
|
||||||
|
|
||||||
mock-http@^1.1.0:
|
|
||||||
version "1.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/mock-http/-/mock-http-1.1.0.tgz#b89380a718a103fc5801095804bedd0b20f7638c"
|
|
||||||
integrity sha512-H2HMGaHNQPWY8PdeEw4RFux2WEOHD6eJAtN3+iFELik5kGjPKAcoyPWcsC2vgDiTa2yimAEDssmMed51e+cBKQ==
|
|
||||||
dependencies:
|
|
||||||
mergee "^1.0.0"
|
|
||||||
|
|
||||||
moment-timezone@^0.5.40:
|
moment-timezone@^0.5.40:
|
||||||
version "0.5.40"
|
version "0.5.40"
|
||||||
resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.40.tgz#c148f5149fd91dd3e29bf481abc8830ecba16b89"
|
resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.40.tgz#c148f5149fd91dd3e29bf481abc8830ecba16b89"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user