1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Adding more tests

Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>
This commit is contained in:
Alex Andreev 2022-01-10 11:35:50 +03:00
parent 89d90127dd
commit 1aca970530
3 changed files with 118 additions and 19 deletions

View File

@ -29,6 +29,46 @@ import { AppPreferenceRegistry } from "../../../../extensions/registries";
import { computed } from "mobx"; import { computed } from "mobx";
import { MemoryRouter } from "react-router-dom"; import { MemoryRouter } from "react-router-dom";
import "@testing-library/jest-dom/extend-expect"; import "@testing-library/jest-dom/extend-expect";
import { LensExtension } from "../../../../extensions/lens-extension";
const extension = {
id: "/absolute/path/test",
manifest: {
name: "@k8slens/test",
version: "1.2.3",
},
absolutePath: "/absolute/path",
manifestPath: "/symlinked/path/package.json",
isBundled: false,
isEnabled: true,
isCompatible: true,
}
const crdExtension = {
id: "/absolute/path/crd",
manifest: {
name: "@k8slens/crd-example",
version: "1.2.3",
},
absolutePath: "/absolute/path/crd",
manifestPath: "/symlinked/path/package.json",
isBundled: false,
isEnabled: true,
isCompatible: true,
}
const sampleExtension = {
id: "/absolute/path/sample",
manifest: {
name: "@k8slens/sample",
version: "1.2.3",
},
absolutePath: "/absolute/path/sample",
manifestPath: "/symlinked/path/package.json",
isBundled: false,
isEnabled: true,
isCompatible: true,
}
describe("Preferences", () => { describe("Preferences", () => {
let di: ConfigurableDependencyInjectionContainer; let di: ConfigurableDependencyInjectionContainer;
@ -39,25 +79,86 @@ describe("Preferences", () => {
render = renderFor(di); render = renderFor(di);
AppPreferenceRegistry.createInstance(); AppPreferenceRegistry.createInstance();
AppPreferenceRegistry.getInstance().add([
{
components: {
Input: () => <div>input</div>,
Hint: () => <div>hint</div>
},
extensionId: "@k8slens/test",
id: "example-preferences",
title: "Example Preferences",
}
], new LensExtension(extension));
AppPreferenceRegistry.getInstance().add([
{
components: {
Input: () => <div>crd input</div>,
Hint: () => <div>crd hint</div>
},
extensionId: "@k8slens/crd-example",
title: "Example Preferences",
}
], new LensExtension(crdExtension));
AppPreferenceRegistry.getInstance().add([
{
components: {
Input: () => <div>sample input</div>,
Hint: () => <div>sample hint</div>
},
extensionId: "@k8slens/crd-example",
title: "Extension with duplicated name",
}
], new LensExtension(crdExtension))
});
afterEach(() => {
AppPreferenceRegistry.resetInstance();
}); });
it("renders w/o errors", () => { it("renders w/o errors", () => {
di.override(userExtensionsInjectable, () => {
return computed(() => [] as any);
});
const { container } = render(<MemoryRouter><Preferences /></MemoryRouter>); const { container } = render(<MemoryRouter><Preferences /></MemoryRouter>);
expect(container).toBeInstanceOf(HTMLElement); expect(container).toBeInstanceOf(HTMLElement);
}); });
it("doesn't render extension settings tabs if no extensions found", () => { describe("Extension custom settings", () => {
di.override(userExtensionsInjectable, () => { it("doesn't render custom settings tabs if no extensions found", () => {
return computed(() => [] as any);
});
const { queryByTestId } = render(<MemoryRouter><Preferences /></MemoryRouter>); const { queryByTestId } = render(<MemoryRouter><Preferences /></MemoryRouter>);
expect(queryByTestId("custom-settings")).not.toBeInTheDocument(); expect(queryByTestId("custom-settings")).not.toBeInTheDocument();
}); });
it("renders custom settings tabs if registered extensions found", () => {
di.override(userExtensionsInjectable, () => {
return computed(() => [extension]);
});
const { getByTestId } = render(<MemoryRouter><Preferences /></MemoryRouter>);
expect(getByTestId("custom-settings")).toBeInTheDocument();
})
it("renders tabs for each extension having custom settings", () => {
di.override(userExtensionsInjectable, () => {
return computed(() => [extension, crdExtension, sampleExtension]);
});
const { getByText, queryByText } = render(<MemoryRouter><Preferences /></MemoryRouter>);
expect(getByText("@k8slens/test")).toBeInTheDocument();
expect(getByText("@k8slens/crd-example")).toBeInTheDocument();
expect(queryByText("@k8slens/sample")).not.toBeInTheDocument();
});
it("renders extension tab only once", () => {
di.override(userExtensionsInjectable, () => {
return computed(() => [crdExtension]);
});
const { getAllByText } = render(<MemoryRouter><Preferences /></MemoryRouter>);
expect(getAllByText("@k8slens/crd-example").length).toBe(1);
})
});
}); });

View File

@ -19,7 +19,6 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
import { observer } from "mobx-react";
import React from "react"; import React from "react";
import { matchPath, RouteComponentProps } from "react-router"; import { matchPath, RouteComponentProps } from "react-router";
import { extensionSettingsRoute } from "../../../common/routes"; import { extensionSettingsRoute } from "../../../common/routes";
@ -29,13 +28,13 @@ import { ExtensionSettings } from "./extension-settings";
interface Props extends RouteComponentProps<{ extensionId?: string }> { interface Props extends RouteComponentProps<{ extensionId?: string }> {
} }
export const ExtensionSettingsPage = observer((props: Props) => { export const ExtensionSettingsPage = (props: Props) => {
// https://github.com/remix-run/react-router/issues/5870#issuecomment-394194338 // https://github.com/remix-run/react-router/issues/5870#issuecomment-394194338
const match = matchPath<{ extensionId: string }>(props.history.location.pathname, { const match = matchPath<{ extensionId: string }>(props.history.location.pathname, {
path: extensionSettingsRoute.path, path: extensionSettingsRoute.path,
exact: true, exact: true,
}); });
const extensionId = decodeURIComponent(match.params.extensionId); const extensionId = decodeURIComponent(match?.params?.extensionId);
const settings = AppPreferenceRegistry.getInstance().getItems(); const settings = AppPreferenceRegistry.getInstance().getItems();
const currentSettings = settings.filter(setting => setting.extensionId == extensionId); const currentSettings = settings.filter(setting => setting.extensionId == extensionId);
@ -57,4 +56,4 @@ export const ExtensionSettingsPage = observer((props: Props) => {
{renderContent()} {renderContent()}
</section> </section>
); );
}); };

View File

@ -48,13 +48,13 @@ import { Kubernetes } from "./kubernetes";
import { Editor } from "./editor"; import { Editor } from "./editor";
import { LensProxy } from "./proxy"; import { LensProxy } from "./proxy";
import { Telemetry } from "./telemetry"; import { Telemetry } from "./telemetry";
import { Extensions } from "./extensions";
import { sentryDsn } from "../../../common/vars"; import { sentryDsn } from "../../../common/vars";
import { withInjectables } from "@ogre-tools/injectable-react"; import { withInjectables } from "@ogre-tools/injectable-react";
import type { InstalledExtension } from "../../../extensions/extension-discovery"; import type { InstalledExtension } from "../../../extensions/extension-discovery";
import userExtensionsInjectable from "../+extensions/user-extensions/user-extensions.injectable"; import userExtensionsInjectable from "../+extensions/user-extensions/user-extensions.injectable";
import { ExtensionSettingsPage } from "./extension-settings-page"; import { ExtensionSettingsPage } from "./extension-settings-page";
import { Icon } from "../icon"; import { Icon } from "../icon";
import { uniqBy } from "lodash";
interface Dependencies { interface Dependencies {
userExtensions: IComputedValue<InstalledExtension[]>; userExtensions: IComputedValue<InstalledExtension[]>;
@ -70,11 +70,11 @@ class Preferences extends React.Component<Dependencies> {
} }
renderNavigation() { renderNavigation() {
const preferenceRegistries = AppPreferenceRegistry.getInstance().getItems(); const preferenceRegistries = uniqBy(AppPreferenceRegistry.getInstance().getItems(), "extensionId");
const telemetryExtensions = preferenceRegistries.filter(e => e.showInPreferencesTab == "telemetry"); const telemetryExtensions = preferenceRegistries.filter(e => e.showInPreferencesTab == "telemetry");
const currentLocation = navigation.location.pathname; const currentLocation = navigation.location.pathname;
const isActive = (route: RouteProps) => !!matchPath(currentLocation, { path: route.path, exact: route.exact }); const isActive = (route: RouteProps) => !!matchPath(currentLocation, { path: route.path, exact: route.exact });
const extensions = this.props.userExtensions.get().filter(extension => const extensionsWithSettings = this.props.userExtensions.get().filter(extension =>
preferenceRegistries.some(registry => registry.extensionId.includes(extension.manifest.name) && !registry.showInPreferencesTab), preferenceRegistries.some(registry => registry.extensionId.includes(extension.manifest.name) && !registry.showInPreferencesTab),
); );
@ -93,12 +93,12 @@ class Preferences extends React.Component<Dependencies> {
{preferenceRegistries.filter(e => !e.showInPreferencesTab).length > 0 && {preferenceRegistries.filter(e => !e.showInPreferencesTab).length > 0 &&
<Tab value={extensionURL()} label="Extensions" data-testid="extensions-tab" active={isActive(extensionRoute)}/> <Tab value={extensionURL()} label="Extensions" data-testid="extensions-tab" active={isActive(extensionRoute)}/>
} }
{extensions.length > 0 && ( {extensionsWithSettings.length > 0 && (
<div data-testid="custom-settings"> <div data-testid="custom-settings">
<hr/> <hr/>
<div className="header flex items-center"><Icon material="extension" smallest className="mr-3"/> Custom settings</div> <div className="header flex items-center"><Icon material="extension" smallest className="mr-3"/> Custom settings</div>
<div> <div>
{extensions.map(extension => ( {extensionsWithSettings.map(extension => (
<Tab key={extension.id} value={extensionSettingsURL({ <Tab key={extension.id} value={extensionSettingsURL({
params: { params: {
extensionId: encodeURIComponent(extension.manifest.name), extensionId: encodeURIComponent(extension.manifest.name),
@ -125,7 +125,6 @@ class Preferences extends React.Component<Dependencies> {
<Route path={kubernetesURL()} component={Kubernetes}/> <Route path={kubernetesURL()} component={Kubernetes}/>
<Route path={editorURL()} component={Editor}/> <Route path={editorURL()} component={Editor}/>
<Route path={telemetryURL()} component={Telemetry}/> <Route path={telemetryURL()} component={Telemetry}/>
<Route path={extensionURL()} component={Extensions}/>
<Route path={extensionSettingsURL()} component={ExtensionSettingsPage}/> <Route path={extensionSettingsURL()} component={ExtensionSettingsPage}/>
<Redirect exact from={`${preferencesURL()}/`} to={appURL()}/> <Redirect exact from={`${preferencesURL()}/`} to={appURL()}/>
</Switch> </Switch>