1
0
mirror of https://gitlab.nic.cz/turris/reforis/foris-js.git synced 2024-11-14 17:35:35 +01:00

Merge branch 'add-customization-context' into 'dev'

Draft: Add CustomizationContext and custom hook

See merge request turris/reforis/foris-js!183
This commit is contained in:
Aleksandr Gumroian 2022-12-03 03:57:17 +01:00
commit 15f6cf6709
11 changed files with 178 additions and 5 deletions

1
.gitignore vendored
View File

@ -51,4 +51,3 @@ coverage.xml
dist/ dist/
foris-*.tgz foris-*.tgz
styleguide/ styleguide/
testUtils

View File

@ -97,6 +97,8 @@ test-js-watch:
.PHONY: test-js-update-snapshots .PHONY: test-js-update-snapshots
test-js-update-snapshots: test-js-update-snapshots:
npm test -- -u npm test -- -u
test-js-watch:
npm test -- --watch
# Translations # Translations

View File

@ -0,0 +1,57 @@
/*
* Copyright (C) 2019-2022 CZ.NIC z.s.p.o. (https://www.nic.cz/)
*
* This is free software, licensed under the GNU General Public License v3.
* See /LICENSE for more information.
*/
import React, { useContext, useEffect } from "react";
import PropTypes from "prop-types";
import { useAPIGet } from "../api/hooks";
import { ForisURLs } from "../utils/forisUrls";
import { Spinner } from "../bootstrap/Spinner";
CustomizationContextProvider.propTypes = {
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node),
PropTypes.node,
]),
};
function CustomizationContextProvider({ children }) {
const { CustomizationContext } = window;
const [getCustomizationResponse, getCustomization] = useAPIGet(
ForisURLs.about
);
useEffect(() => {
getCustomization();
}, [getCustomization]);
if (getCustomizationResponse.state !== "success") {
return <Spinner fullScreen />;
}
const deviceDetails = getCustomizationResponse.data || {};
const isCustomized = !!(
deviceDetails &&
deviceDetails.customization !== undefined &&
deviceDetails.customization === "shield"
);
return (
<CustomizationContext.Provider value={{ deviceDetails, isCustomized }}>
{children}
</CustomizationContext.Provider>
);
}
function useCustomizationContext() {
const { CustomizationContext } = window;
return useContext(CustomizationContext);
}
export { CustomizationContextProvider, useCustomizationContext };

View File

@ -0,0 +1,3 @@
It provides customization context to the children. `CustomizationContext` allows
using `useCustomizationContext` in components to check if the reForis UI is
customized or not for specific devices.

View File

@ -0,0 +1,57 @@
/*
* Copyright (C) 2019-2022 CZ.NIC z.s.p.o. (https://www.nic.cz/)
*
* This is free software, licensed under the GNU General Public License v3.
* See /LICENSE for more information.
*/
import React from "react";
import { render, wait } from "customTestRender";
import mockAxios from "jest-mock-axios";
import {
useCustomizationContext,
CustomizationContextProvider,
} from "../CustomizationContext";
const CUSTOM = "Description / component for customized reForis (Shield)";
const ORIGINAL = "Description / component for original reForis (other devices)";
function CustomizationTest() {
const isCustomized = useCustomizationContext();
return <p>{isCustomized ? CUSTOM : ORIGINAL}</p>;
}
describe("CustomizationContext", () => {
let componentContainer;
it("should render component without customization", async () => {
const { container, getByText } = render(
<CustomizationContextProvider>
<CustomizationTest />
</CustomizationContextProvider>
);
componentContainer = container;
mockAxios.mockResponse({ data: {} });
await wait(() => getByText(ORIGINAL));
expect(componentContainer).toMatchSnapshot();
});
it("should render customized component", async () => {
const { container, getByText } = render(
<CustomizationContextProvider>
<CustomizationTest />
</CustomizationContextProvider>
);
componentContainer = container;
mockAxios.mockResponse({ data: { customization: "shield" } });
await wait(() => getByText(CUSTOM));
expect(componentContainer).toMatchSnapshot();
});
});

View File

@ -0,0 +1,17 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`CustomizationContext should render component without customization 1`] = `
<div>
<p>
Description / component for original reForis (other devices)
</p>
</div>
`;
exports[`CustomizationContext should render customized component 1`] = `
<div>
<p>
Description / component for customized reForis (Shield)
</p>
</div>
`;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019-2021 CZ.NIC z.s.p.o. (http://www.nic.cz/) * Copyright (C) 2019-2022 CZ.NIC z.s.p.o. (https://www.nic.cz/)
* *
* This is free software, licensed under the GNU General Public License v3. * This is free software, licensed under the GNU General Public License v3.
* See /LICENSE for more information. * See /LICENSE for more information.
@ -91,3 +91,9 @@ export {
// Alert context // Alert context
export { AlertContextProvider, useAlert } from "./alertContext/AlertContext"; export { AlertContextProvider, useAlert } from "./alertContext/AlertContext";
// Customization context
export {
CustomizationContextProvider,
useCustomizationContext,
} from "./customizationContext/CustomizationContext";

View File

@ -14,6 +14,7 @@ import { render } from "@testing-library/react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { AlertContextMock } from "./alertContextMock"; import { AlertContextMock } from "./alertContextMock";
import { CustomizationContextMock } from "./cutomizationContextMock";
Wrapper.propTypes = { Wrapper.propTypes = {
children: PropTypes.oneOfType([ children: PropTypes.oneOfType([
@ -25,9 +26,11 @@ Wrapper.propTypes = {
function Wrapper({ children }) { function Wrapper({ children }) {
return ( return (
<AlertContextMock> <AlertContextMock>
<CustomizationContextMock>
<StaticRouter> <StaticRouter>
<UIDReset>{children}</UIDReset> <UIDReset>{children}</UIDReset>
</StaticRouter> </StaticRouter>
</CustomizationContextMock>
</AlertContextMock> </AlertContextMock>
); );
} }

View File

@ -0,0 +1,22 @@
/*
* Copyright (C) 2019-2022 CZ.NIC z.s.p.o. (https://www.nic.cz/)
*
* This is free software, licensed under the GNU General Public License v3.
* See /LICENSE for more information.
*/
import React from "react";
window.CustomizationContext = React.createContext();
const isCustomized = jest.fn();
function CustomizationContextMock({ children }) {
return (
<CustomizationContext.Provider value={isCustomized}>
{children}
</CustomizationContext.Provider>
);
}
export { CustomizationContextMock };

View File

@ -36,5 +36,6 @@ export const ForisURLs = {
luci: "/cgi-bin/luci", luci: "/cgi-bin/luci",
// API // API
about: `${REFORIS_API_URL_PREFIX}/about`,
reboot: `${REFORIS_API_URL_PREFIX}/reboot`, reboot: `${REFORIS_API_URL_PREFIX}/reboot`,
}; };

View File

@ -51,6 +51,12 @@ module.exports = {
sectionDepth: 1, sectionDepth: 1,
}, },
{
name: "Customization Context",
components: ["src/customizationContext/CustomizationContext.js"],
exampleMode: "expand",
usageMode: "expand",
},
{ {
name: "Bootstrap components", name: "Bootstrap components",
description: "Set of bootstrap components.", description: "Set of bootstrap components.",