1
0
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:
Sebastian Malton 2023-01-13 09:12:46 -05:00
parent aea545526d
commit fdae7870da
10 changed files with 73 additions and 68 deletions

View File

@ -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",

View File

@ -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));
}; };

View File

@ -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", () => {

View File

@ -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();
}); });
}); });
}); });
}); });
});

View File

@ -13,7 +13,7 @@ export default getGlobalOverride(lensProxyInjectable, (di) => {
return ({ return ({
close: () => { }, close: () => { },
listen: async () => { listen: async () => {
lensProxyPort.set(12345); lensProxyPort.set(23456);
}, },
}); });
}); });

View File

@ -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;

View File

@ -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) => ({

View File

@ -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();
} }

View File

@ -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);
} }

View File

@ -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"