mirror of
https://gitlab.nic.cz/turris/reforis/foris-js.git
synced 2025-06-16 13:46:16 +02:00
Wi-Fi settings form
This commit is contained in:
74
src/common/WiFiSettings/ResetWiFiSettings.js
Normal file
74
src/common/WiFiSettings/ResetWiFiSettings.js
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React, { useEffect, useState } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import { Button } from "../../bootstrap/Button";
|
||||
import { useAlert } from "../../alertContext/AlertContext";
|
||||
import { ALERT_TYPES } from "../../bootstrap/Alert";
|
||||
import { useAPIPost } from "../../api/hooks";
|
||||
import { API_STATE } from "../../api/utils";
|
||||
import { formFieldsSize } from "../../bootstrap/constants";
|
||||
|
||||
ResetWiFiSettings.propTypes = {
|
||||
ws: PropTypes.object.isRequired,
|
||||
endpoint: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default function ResetWiFiSettings({ ws, endpoint }) {
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const module = "wifi";
|
||||
ws.subscribe(module)
|
||||
.bind(module, "reset", () => {
|
||||
setIsLoading(true);
|
||||
// eslint-disable-next-line no-restricted-globals
|
||||
setTimeout(() => location.reload(), 1000);
|
||||
});
|
||||
}, [ws]);
|
||||
|
||||
const [postResetResponse, postReset] = useAPIPost(endpoint);
|
||||
const [setAlert, dismissAlert] = useAlert();
|
||||
useEffect(() => {
|
||||
if (postResetResponse.state === API_STATE.ERROR) {
|
||||
setAlert(_("An error occurred during resetting Wi-Fi settings."));
|
||||
} else if (postResetResponse.state === API_STATE.SUCCESS) {
|
||||
setAlert(_("Wi-Fi settings are set to defaults."), ALERT_TYPES.SUCCESS);
|
||||
}
|
||||
}, [postResetResponse, setAlert]);
|
||||
|
||||
function onReset() {
|
||||
dismissAlert();
|
||||
postReset();
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<h4>{_("Reset Wi-Fi Settings")}</h4>
|
||||
<p>
|
||||
{_(`
|
||||
If a number of wireless cards doesn't match, you may try to reset the Wi-Fi settings. Note that this will remove the
|
||||
current Wi-Fi configuration and restore the default values.
|
||||
`)}
|
||||
</p>
|
||||
<div className={`${formFieldsSize} text-right`}>
|
||||
<Button
|
||||
className="btn-warning"
|
||||
forisFormSize
|
||||
loading={isLoading}
|
||||
disabled={isLoading}
|
||||
|
||||
onClick={onReset}
|
||||
>
|
||||
{_("Reset Wi-Fi Settings")}
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
250
src/common/WiFiSettings/WiFiForm.js
Normal file
250
src/common/WiFiSettings/WiFiForm.js
Normal file
@ -0,0 +1,250 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://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 PropTypes from "prop-types";
|
||||
|
||||
import { CheckBox } from "../../bootstrap/CheckBox";
|
||||
import { PasswordInput } from "../../bootstrap/PasswordInput";
|
||||
import { RadioSet } from "../../bootstrap/RadioSet";
|
||||
import { Select } from "../../bootstrap/Select";
|
||||
import { TextInput } from "../../bootstrap/TextInput";
|
||||
import WiFiQRCode from "./WiFiQRCode";
|
||||
import WifiGuestForm from "./WiFiGuestForm";
|
||||
import { HELP_TEXTS, HTMODES, HWMODES } from "./constants";
|
||||
|
||||
WiFiForm.propTypes = {
|
||||
formData: PropTypes.shape(
|
||||
{ devices: PropTypes.arrayOf(PropTypes.object) },
|
||||
).isRequired,
|
||||
formErrors: PropTypes.oneOfType([
|
||||
PropTypes.object,
|
||||
PropTypes.array,
|
||||
]),
|
||||
setFormValue: PropTypes.func.isRequired,
|
||||
hasGuestNetwork: PropTypes.bool,
|
||||
};
|
||||
|
||||
WiFiForm.defaultProps = {
|
||||
formData: { devices: [] },
|
||||
setFormValue: () => {},
|
||||
hasGuestNetwork: true,
|
||||
};
|
||||
|
||||
export default function WiFiForm({
|
||||
formData, formErrors, setFormValue, hasGuestNetwork, ...props
|
||||
}) {
|
||||
return formData.devices.map((device) => (
|
||||
<DeviceForm
|
||||
key={device.id}
|
||||
formData={device}
|
||||
formErrors={(formErrors || [])[device.id]}
|
||||
setFormValue={setFormValue}
|
||||
hasGuestNetwork={hasGuestNetwork}
|
||||
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
}
|
||||
|
||||
DeviceForm.propTypes = {
|
||||
formData: PropTypes.shape({
|
||||
id: PropTypes.number.isRequired,
|
||||
enabled: PropTypes.bool.isRequired,
|
||||
SSID: PropTypes.string.isRequired,
|
||||
password: PropTypes.string.isRequired,
|
||||
hidden: PropTypes.bool.isRequired,
|
||||
hwmode: PropTypes.string.isRequired,
|
||||
htmode: PropTypes.string.isRequired,
|
||||
channel: PropTypes.string.isRequired,
|
||||
guest_wifi: PropTypes.object.isRequired,
|
||||
}),
|
||||
formErrors: PropTypes.object.isRequired,
|
||||
setFormValue: PropTypes.func.isRequired,
|
||||
hasGuestNetwork: PropTypes.bool,
|
||||
};
|
||||
|
||||
DeviceForm.defaultProps = {
|
||||
formErrors: {},
|
||||
hasGuestNetwork: true,
|
||||
};
|
||||
|
||||
function DeviceForm({
|
||||
formData, formErrors, setFormValue, hasGuestNetwork, ...props
|
||||
}) {
|
||||
const deviceID = formData.id;
|
||||
return (
|
||||
<>
|
||||
<h3>{_(`Wi-Fi ${deviceID + 1}`)}</h3>
|
||||
<CheckBox
|
||||
label={_("Enable")}
|
||||
checked={formData.enabled}
|
||||
|
||||
onChange={setFormValue(
|
||||
(value) => ({ devices: { [deviceID]: { enabled: { $set: value } } } }),
|
||||
)}
|
||||
|
||||
{...props}
|
||||
/>
|
||||
{formData.enabled
|
||||
? (
|
||||
<>
|
||||
<TextInput
|
||||
label="SSID"
|
||||
value={formData.SSID}
|
||||
error={formErrors.SSID || null}
|
||||
required
|
||||
onChange={setFormValue(
|
||||
(value) => ({ devices: { [deviceID]: { SSID: { $set: value } } } }),
|
||||
)}
|
||||
|
||||
{...props}
|
||||
>
|
||||
<div className="input-group-append">
|
||||
<WiFiQRCode
|
||||
SSID={formData.SSID}
|
||||
password={formData.password}
|
||||
/>
|
||||
</div>
|
||||
</TextInput>
|
||||
|
||||
<PasswordInput
|
||||
withEye
|
||||
label="Password"
|
||||
value={formData.password}
|
||||
error={formErrors.password}
|
||||
helpText={HELP_TEXTS.password}
|
||||
required
|
||||
|
||||
onChange={setFormValue(
|
||||
(value) => (
|
||||
{ devices: { [deviceID]: { password: { $set: value } } } }
|
||||
),
|
||||
)}
|
||||
|
||||
{...props}
|
||||
/>
|
||||
|
||||
<CheckBox
|
||||
label="Hide SSID"
|
||||
helpText={HELP_TEXTS.hidden}
|
||||
checked={formData.hidden}
|
||||
|
||||
onChange={setFormValue(
|
||||
(value) => (
|
||||
{ devices: { [deviceID]: { hidden: { $set: value } } } }
|
||||
),
|
||||
)}
|
||||
|
||||
{...props}
|
||||
/>
|
||||
|
||||
<RadioSet
|
||||
name={`hwmode-${deviceID}`}
|
||||
label="GHz"
|
||||
choices={getHwmodeChoices(formData)}
|
||||
value={formData.hwmode}
|
||||
helpText={HELP_TEXTS.hwmode}
|
||||
|
||||
onChange={setFormValue(
|
||||
(value) => ({
|
||||
devices: {
|
||||
[deviceID]: {
|
||||
hwmode: { $set: value },
|
||||
channel: { $set: "0" },
|
||||
},
|
||||
},
|
||||
}),
|
||||
)}
|
||||
|
||||
{...props}
|
||||
/>
|
||||
|
||||
<Select
|
||||
label="802.11n/ac mode"
|
||||
choices={getHtmodeChoices(formData)}
|
||||
value={formData.htmode}
|
||||
helpText={HELP_TEXTS.htmode}
|
||||
|
||||
onChange={setFormValue(
|
||||
(value) => (
|
||||
{ devices: { [deviceID]: { htmode: { $set: value } } } }
|
||||
),
|
||||
)}
|
||||
|
||||
{...props}
|
||||
/>
|
||||
|
||||
<Select
|
||||
label="Channel"
|
||||
choices={getChannelChoices(formData)}
|
||||
value={formData.channel}
|
||||
|
||||
onChange={setFormValue(
|
||||
(value) => (
|
||||
{ devices: { [deviceID]: { channel: { $set: value } } } }
|
||||
),
|
||||
)}
|
||||
|
||||
{...props}
|
||||
/>
|
||||
|
||||
{hasGuestNetwork && (
|
||||
<WifiGuestForm
|
||||
formData={{ id: deviceID, ...formData.guest_wifi }}
|
||||
formErrors={formErrors.guest_wifi || {}}
|
||||
|
||||
setFormValue={setFormValue}
|
||||
|
||||
{...props}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
: null}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function getChannelChoices(device) {
|
||||
const channelChoices = {
|
||||
0: _("auto"),
|
||||
};
|
||||
|
||||
device.available_bands.forEach((availableBand) => {
|
||||
if (availableBand.hwmode !== device.hwmode) return;
|
||||
|
||||
availableBand.available_channels.forEach((availableChannel) => {
|
||||
channelChoices[availableChannel.number.toString()] = `
|
||||
${availableChannel.number}
|
||||
(${availableChannel.frequency} MHz ${availableChannel.radar ? " ,DFS" : ""})
|
||||
`;
|
||||
});
|
||||
});
|
||||
|
||||
return channelChoices;
|
||||
}
|
||||
|
||||
function getHtmodeChoices(device) {
|
||||
const htmodeChoices = {};
|
||||
|
||||
device.available_bands.forEach((availableBand) => {
|
||||
if (availableBand.hwmode !== device.hwmode) return;
|
||||
|
||||
availableBand.available_htmodes.forEach((availableHtmod) => {
|
||||
htmodeChoices[availableHtmod] = HTMODES[availableHtmod];
|
||||
});
|
||||
});
|
||||
return htmodeChoices;
|
||||
}
|
||||
|
||||
function getHwmodeChoices(device) {
|
||||
return device.available_bands.map((availableBand) => ({
|
||||
label: HWMODES[availableBand.hwmode],
|
||||
value: availableBand.hwmode,
|
||||
}));
|
||||
}
|
100
src/common/WiFiSettings/WiFiGuestForm.js
Normal file
100
src/common/WiFiSettings/WiFiGuestForm.js
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://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 PropTypes from "prop-types";
|
||||
|
||||
import { CheckBox } from "../../bootstrap/CheckBox";
|
||||
import { TextInput } from "../../bootstrap/TextInput";
|
||||
import { PasswordInput } from "../../bootstrap/PasswordInput";
|
||||
import WiFiQRCode from "./WiFiQRCode";
|
||||
import { HELP_TEXTS } from "./constants";
|
||||
|
||||
WifiGuestForm.propTypes = {
|
||||
formData: PropTypes.shape({
|
||||
id: PropTypes.number.isRequired,
|
||||
SSID: PropTypes.string.isRequired,
|
||||
password: PropTypes.string.isRequired,
|
||||
enabled: PropTypes.bool.isRequired,
|
||||
}),
|
||||
formErrors: PropTypes.shape({
|
||||
SSID: PropTypes.string,
|
||||
password: PropTypes.string,
|
||||
}),
|
||||
setFormValue: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default function WifiGuestForm({
|
||||
formData, formErrors, setFormValue, ...props
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<CheckBox
|
||||
label={_("Enable Guest Wifi")}
|
||||
checked={formData.enabled}
|
||||
helpText={HELP_TEXTS.guest_wifi_enabled}
|
||||
|
||||
onChange={setFormValue(
|
||||
(value) => (
|
||||
{ devices: { [formData.id]: { guest_wifi: { enabled: { $set: value } } } } }
|
||||
),
|
||||
)}
|
||||
|
||||
{...props}
|
||||
/>
|
||||
{formData.enabled
|
||||
? (
|
||||
<>
|
||||
<TextInput
|
||||
label="SSID"
|
||||
value={formData.SSID}
|
||||
error={formErrors.SSID}
|
||||
|
||||
onChange={setFormValue(
|
||||
(value) => ({
|
||||
devices: {
|
||||
[formData.id]: { guest_wifi: { SSID: { $set: value } } },
|
||||
},
|
||||
}),
|
||||
)}
|
||||
|
||||
{...props}
|
||||
>
|
||||
<div className="input-group-append">
|
||||
<WiFiQRCode
|
||||
SSID={formData.SSID}
|
||||
password={formData.password}
|
||||
/>
|
||||
</div>
|
||||
</TextInput>
|
||||
|
||||
<PasswordInput
|
||||
withEye
|
||||
label={_("Password")}
|
||||
value={formData.password}
|
||||
helpText={HELP_TEXTS.password}
|
||||
error={formErrors.password}
|
||||
required
|
||||
|
||||
onChange={setFormValue(
|
||||
(value) => ({
|
||||
devices: {
|
||||
[formData.id]: {
|
||||
guest_wifi: { password: { $set: value } },
|
||||
},
|
||||
},
|
||||
}),
|
||||
)}
|
||||
|
||||
{...props}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
: null}
|
||||
</>
|
||||
);
|
||||
}
|
85
src/common/WiFiSettings/WiFiQRCode.js
Normal file
85
src/common/WiFiSettings/WiFiQRCode.js
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React, { useState } from "react";
|
||||
import QRCode from "qrcode.react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import { ForisURLs } from "../../forisUrls";
|
||||
import { Button } from "../../bootstrap/Button";
|
||||
import {
|
||||
Modal, ModalBody, ModalFooter, ModalHeader,
|
||||
} from "../../bootstrap/Modal";
|
||||
import { createAndDownloadPdf, toQRCodeContent } from "./qrCodeHelpers";
|
||||
|
||||
WiFiQRCode.propTypes = {
|
||||
SSID: PropTypes.string.isRequired,
|
||||
password: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
const QR_ICON_PATH = `${ForisURLs.static}/imgs/QR_icon.svg`;
|
||||
|
||||
export default function WiFiQRCode({ SSID, password }) {
|
||||
const [modal, setModal] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
type="button"
|
||||
className="input-group-text"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
setModal(true);
|
||||
}}
|
||||
>
|
||||
<img width="20" src={QR_ICON_PATH} alt="QR" style={{ opacity: 0.67 }} />
|
||||
</button>
|
||||
{modal
|
||||
? <QRCodeModal setShown={setModal} shown={modal} SSID={SSID} password={password} />
|
||||
: null}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
QRCodeModal.propTypes = {
|
||||
SSID: PropTypes.string.isRequired,
|
||||
password: PropTypes.string.isRequired,
|
||||
shown: PropTypes.bool.isRequired,
|
||||
setShown: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
function QRCodeModal({
|
||||
shown, setShown, SSID, password,
|
||||
}) {
|
||||
return (
|
||||
<Modal setShown={setShown} shown={shown}>
|
||||
<ModalHeader setShown={setShown} title={_("Wi-Fi QR Code")} />
|
||||
<ModalBody>
|
||||
<QRCode
|
||||
renderAs="svg"
|
||||
value={toQRCodeContent(SSID, password)}
|
||||
level="M"
|
||||
size={350}
|
||||
includeMargin
|
||||
style={{ display: "block", margin: "auto" }}
|
||||
/>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button
|
||||
className="btn-outline-primary"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
createAndDownloadPdf(SSID, password);
|
||||
}}
|
||||
>
|
||||
<i className="fas fa-arrow-down mr-2" />
|
||||
{_("Download PDF")}
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</Modal>
|
||||
);
|
||||
}
|
93
src/common/WiFiSettings/WiFiSettings.js
Normal file
93
src/common/WiFiSettings/WiFiSettings.js
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://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 PropTypes from "prop-types";
|
||||
|
||||
import { ForisForm } from "../../form/components/ForisForm";
|
||||
import WiFiForm from "./WiFiForm";
|
||||
import ResetWiFiSettings from "./ResetWiFiSettings";
|
||||
|
||||
WiFiSettings.propTypes = {
|
||||
ws: PropTypes.object.isRequired,
|
||||
endpoint: PropTypes.string.isRequired,
|
||||
resetEndpoint: PropTypes.string.isRequired,
|
||||
hasGuestNetwork: PropTypes.bool,
|
||||
};
|
||||
|
||||
export function WiFiSettings({
|
||||
ws, endpoint, resetEndpoint, hasGuestNetwork,
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<ForisForm
|
||||
ws={ws}
|
||||
forisConfig={{
|
||||
endpoint,
|
||||
wsModule: "wifi",
|
||||
}}
|
||||
prepData={prepData}
|
||||
prepDataToSubmit={prepDataToSubmit}
|
||||
validator={validator}
|
||||
>
|
||||
<WiFiForm hasGuestNetwork={hasGuestNetwork} />
|
||||
</ForisForm>
|
||||
<ResetWiFiSettings ws={ws} endpoint={resetEndpoint} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function prepData(formData) {
|
||||
formData.devices.forEach((device, idx) => {
|
||||
formData.devices[idx].channel = device.channel.toString();
|
||||
});
|
||||
return formData;
|
||||
}
|
||||
|
||||
function prepDataToSubmit(formData) {
|
||||
formData.devices.forEach((device, idx) => {
|
||||
delete device.available_bands;
|
||||
|
||||
formData.devices[idx].channel = parseInt(device.channel);
|
||||
|
||||
if (!device.enabled) {
|
||||
formData.devices[idx] = { id: device.id, enabled: false };
|
||||
return;
|
||||
}
|
||||
|
||||
if (!device.guest_wifi.enabled) formData.devices[idx].guest_wifi = { enabled: false };
|
||||
});
|
||||
return formData;
|
||||
}
|
||||
|
||||
function validator(formData) {
|
||||
const formErrors = formData.devices.map(
|
||||
(device) => {
|
||||
if (!device.enabled) return {};
|
||||
|
||||
const errors = {};
|
||||
if (device.SSID.length > 32) errors.SSID = _("SSID can't be longer than 32 symbols");
|
||||
if (device.SSID.length === 0) errors.SSID = _("SSID can't be empty");
|
||||
|
||||
if (device.password.length < 8) errors.password = _("Password must contain at least 8 symbols");
|
||||
|
||||
if (!device.guest_wifi.enabled) return errors;
|
||||
|
||||
const guest_wifi_errors = {};
|
||||
if (device.guest_wifi.SSID.length > 32) guest_wifi_errors.SSID = _("SSID can't be longer than 32 symbols");
|
||||
if (device.guest_wifi.SSID.length === 0) guest_wifi_errors.SSID = _("SSID can't be empty");
|
||||
|
||||
if (device.guest_wifi.password.length < 8) guest_wifi_errors.password = _("Password must contain at least 8 symbols");
|
||||
|
||||
if (guest_wifi_errors.SSID || guest_wifi_errors.password) {
|
||||
errors.guest_wifi = guest_wifi_errors;
|
||||
}
|
||||
return errors;
|
||||
},
|
||||
);
|
||||
return JSON.stringify(formErrors) === "[{},{}]" ? null : formErrors;
|
||||
}
|
40
src/common/WiFiSettings/__tests__/ResetWiFiSettings.test.js
Normal file
40
src/common/WiFiSettings/__tests__/ResetWiFiSettings.test.js
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://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, fireEvent, wait } from "customTestRender";
|
||||
|
||||
import mockAxios from "jest-mock-axios";
|
||||
import { WebSockets } from "webSockets/WebSockets";
|
||||
import { mockJSONError } from "testUtils/network";
|
||||
import { mockSetAlert } from "testUtils/alertContextMock";
|
||||
import { ALERT_TYPES } from "../../../bootstrap/Alert";
|
||||
|
||||
import ResetWiFiSettings from "../ResetWiFiSettings";
|
||||
|
||||
describe("<ResetWiFiSettings/>", () => {
|
||||
const webSockets = new WebSockets();
|
||||
const endpoint = "/reforis/api/wifi-reset";
|
||||
let getAllByText;
|
||||
|
||||
beforeEach(() => {
|
||||
({ getAllByText } = render(<ResetWiFiSettings ws={webSockets} endpoint={endpoint} />));
|
||||
});
|
||||
|
||||
it("should display alert on open ports - success", async () => {
|
||||
fireEvent.click(getAllByText("Reset Wi-Fi Settings")[1]);
|
||||
expect(mockAxios.post).toBeCalledWith(endpoint, undefined, expect.anything());
|
||||
mockAxios.mockResponse({ data: { foo: "bar" } });
|
||||
await wait(() => expect(mockSetAlert).toBeCalledWith("Wi-Fi settings are set to defaults.", ALERT_TYPES.SUCCESS));
|
||||
});
|
||||
|
||||
it("should display alert on open ports - failure", async () => {
|
||||
fireEvent.click(getAllByText("Reset Wi-Fi Settings")[1]);
|
||||
mockJSONError();
|
||||
await wait(() => expect(mockSetAlert).toBeCalledWith("An error occurred during resetting Wi-Fi settings."));
|
||||
});
|
||||
});
|
161
src/common/WiFiSettings/__tests__/WiFiSettings.test.js
Normal file
161
src/common/WiFiSettings/__tests__/WiFiSettings.test.js
Normal file
@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://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 diffSnapshot from "snapshot-diff";
|
||||
import mockAxios from "jest-mock-axios";
|
||||
|
||||
import { fireEvent, render, wait } from "customTestRender";
|
||||
import { WebSockets } from "webSockets/WebSockets";
|
||||
import { mockJSONError } from "testUtils/network";
|
||||
|
||||
import { wifiSettingsFixture } from "./__fixtures__/wifiSettings";
|
||||
import { WiFiSettings } from "../WiFiSettings";
|
||||
|
||||
describe("<WiFiSettings/>", () => {
|
||||
let firstRender;
|
||||
let getAllByText;
|
||||
let getAllByLabelText;
|
||||
let getByText;
|
||||
let asFragment;
|
||||
const endpoint = "/reforis/api/wifi";
|
||||
|
||||
beforeEach(async () => {
|
||||
const webSockets = new WebSockets();
|
||||
const renderRes = render(<WiFiSettings ws={webSockets} endpoint={endpoint} resetEndpoint="foo" />);
|
||||
asFragment = renderRes.asFragment;
|
||||
getAllByText = renderRes.getAllByText;
|
||||
getAllByLabelText = renderRes.getAllByLabelText;
|
||||
getByText = renderRes.getByText;
|
||||
mockAxios.mockResponse({ data: wifiSettingsFixture() });
|
||||
await wait(() => renderRes.getByText("Wi-Fi 1"));
|
||||
firstRender = renderRes.asFragment();
|
||||
});
|
||||
|
||||
it("should handle error", async () => {
|
||||
const webSockets = new WebSockets();
|
||||
const { getByText } = render(<WiFiSettings ws={webSockets} ws={webSockets} endpoint={endpoint} resetEndpoint="foo" />);
|
||||
mockJSONError();
|
||||
await wait(() => {
|
||||
expect(getByText("An error occurred while fetching data.")).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it("Snapshot both modules disabled.", () => {
|
||||
expect(firstRender).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("Snapshot one module enabled.", () => {
|
||||
fireEvent.click(getAllByText("Enable")[0]);
|
||||
expect(diffSnapshot(firstRender, asFragment())).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("Snapshot 2.4 GHz", () => {
|
||||
fireEvent.click(getAllByText("Enable")[0]);
|
||||
const enabledRender = asFragment();
|
||||
fireEvent.click(getAllByText("2.4")[0]);
|
||||
expect(diffSnapshot(enabledRender, asFragment())).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("Snapshot guest network.", () => {
|
||||
fireEvent.click(getAllByText("Enable")[0]);
|
||||
const enabledRender = asFragment();
|
||||
fireEvent.click(getAllByText("Enable Guest Wifi")[0]);
|
||||
expect(diffSnapshot(enabledRender, asFragment())).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("Post form: both modules disabled.", () => {
|
||||
fireEvent.click(getByText("Save"));
|
||||
expect(mockAxios.post).toBeCalled();
|
||||
const data = {
|
||||
devices: [
|
||||
{ enabled: false, id: 0 },
|
||||
{ enabled: false, id: 1 },
|
||||
],
|
||||
};
|
||||
expect(mockAxios.post).toHaveBeenCalledWith(endpoint, data, expect.anything());
|
||||
});
|
||||
|
||||
it("Post form: one module enabled.", () => {
|
||||
fireEvent.click(getAllByText("Enable")[0]);
|
||||
|
||||
fireEvent.click(getByText("Save"));
|
||||
expect(mockAxios.post).toBeCalled();
|
||||
const data = {
|
||||
devices: [
|
||||
{
|
||||
SSID: "TestSSID1",
|
||||
channel: 60,
|
||||
enabled: true,
|
||||
guest_wifi: { enabled: false },
|
||||
hidden: false,
|
||||
htmode: "HT40",
|
||||
hwmode: "11a",
|
||||
id: 0,
|
||||
password: "TestPass",
|
||||
},
|
||||
{ enabled: false, id: 1 },
|
||||
],
|
||||
};
|
||||
expect(mockAxios.post).toHaveBeenCalledWith(endpoint, data, expect.anything());
|
||||
});
|
||||
|
||||
it("Post form: 2.4 GHz", () => {
|
||||
fireEvent.click(getAllByText("Enable")[0]);
|
||||
fireEvent.click(getAllByText("2.4")[0]);
|
||||
|
||||
fireEvent.click(getByText("Save"));
|
||||
expect(mockAxios.post).toBeCalled();
|
||||
const data = {
|
||||
devices: [
|
||||
{
|
||||
SSID: "TestSSID1",
|
||||
channel: 0,
|
||||
enabled: true,
|
||||
guest_wifi: { enabled: false },
|
||||
hidden: false,
|
||||
htmode: "HT40",
|
||||
hwmode: "11g",
|
||||
id: 0,
|
||||
password: "TestPass",
|
||||
},
|
||||
{ enabled: false, id: 1 },
|
||||
],
|
||||
};
|
||||
expect(mockAxios.post).toHaveBeenCalledWith(endpoint, data, expect.anything());
|
||||
});
|
||||
|
||||
it("Post form: guest network.", () => {
|
||||
fireEvent.click(getAllByText("Enable")[0]);
|
||||
fireEvent.click(getAllByText("Enable Guest Wifi")[0]);
|
||||
fireEvent.change(getAllByLabelText("Password")[1], { target: { value: "test_password" } });
|
||||
|
||||
fireEvent.click(getByText("Save"));
|
||||
expect(mockAxios.post).toBeCalled();
|
||||
const data = {
|
||||
devices: [
|
||||
{
|
||||
SSID: "TestSSID1",
|
||||
channel: 60,
|
||||
enabled: true,
|
||||
guest_wifi: {
|
||||
SSID: "TestGuestSSID",
|
||||
enabled: true,
|
||||
password: "test_password",
|
||||
},
|
||||
hidden: false,
|
||||
htmode: "HT40",
|
||||
hwmode: "11a",
|
||||
id: 0,
|
||||
password: "TestPass",
|
||||
},
|
||||
{ enabled: false, id: 1 },
|
||||
],
|
||||
};
|
||||
expect(mockAxios.post).toHaveBeenCalledWith(endpoint, data, expect.anything());
|
||||
});
|
||||
});
|
318
src/common/WiFiSettings/__tests__/__fixtures__/wifiSettings.js
Normal file
318
src/common/WiFiSettings/__tests__/__fixtures__/wifiSettings.js
Normal file
@ -0,0 +1,318 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
export function wifiSettingsFixture() {
|
||||
return {
|
||||
devices: [
|
||||
{
|
||||
SSID: "TestSSID1",
|
||||
available_bands: [
|
||||
{
|
||||
available_channels: [
|
||||
{
|
||||
frequency: 2412,
|
||||
number: 1,
|
||||
radar: false,
|
||||
},
|
||||
{
|
||||
frequency: 2417,
|
||||
number: 2,
|
||||
radar: false,
|
||||
},
|
||||
{
|
||||
frequency: 2422,
|
||||
number: 3,
|
||||
radar: false,
|
||||
},
|
||||
{
|
||||
frequency: 2427,
|
||||
number: 4,
|
||||
radar: false,
|
||||
},
|
||||
{
|
||||
frequency: 2432,
|
||||
number: 5,
|
||||
radar: false,
|
||||
},
|
||||
{
|
||||
frequency: 2437,
|
||||
number: 6,
|
||||
radar: false,
|
||||
},
|
||||
{
|
||||
frequency: 2442,
|
||||
number: 7,
|
||||
radar: false,
|
||||
},
|
||||
{
|
||||
frequency: 2447,
|
||||
number: 8,
|
||||
radar: false,
|
||||
},
|
||||
{
|
||||
frequency: 2452,
|
||||
number: 9,
|
||||
radar: false,
|
||||
},
|
||||
{
|
||||
frequency: 2457,
|
||||
number: 10,
|
||||
radar: false,
|
||||
},
|
||||
{
|
||||
frequency: 2462,
|
||||
number: 11,
|
||||
radar: false,
|
||||
},
|
||||
],
|
||||
available_htmodes: [
|
||||
"NOHT",
|
||||
"HT20",
|
||||
"HT40",
|
||||
"VHT20",
|
||||
"VHT40",
|
||||
"VHT80",
|
||||
],
|
||||
hwmode: "11g",
|
||||
},
|
||||
{
|
||||
available_channels: [
|
||||
{
|
||||
frequency: 5180,
|
||||
number: 36,
|
||||
radar: false,
|
||||
},
|
||||
{
|
||||
frequency: 5200,
|
||||
number: 40,
|
||||
radar: false,
|
||||
},
|
||||
{
|
||||
frequency: 5220,
|
||||
number: 44,
|
||||
radar: false,
|
||||
},
|
||||
{
|
||||
frequency: 5240,
|
||||
number: 48,
|
||||
radar: false,
|
||||
},
|
||||
{
|
||||
frequency: 5260,
|
||||
number: 52,
|
||||
radar: true,
|
||||
},
|
||||
{
|
||||
frequency: 5280,
|
||||
number: 56,
|
||||
radar: true,
|
||||
},
|
||||
{
|
||||
frequency: 5300,
|
||||
number: 60,
|
||||
radar: true,
|
||||
},
|
||||
{
|
||||
frequency: 5320,
|
||||
number: 64,
|
||||
radar: true,
|
||||
},
|
||||
{
|
||||
frequency: 5500,
|
||||
number: 100,
|
||||
radar: true,
|
||||
},
|
||||
{
|
||||
frequency: 5520,
|
||||
number: 104,
|
||||
radar: true,
|
||||
},
|
||||
{
|
||||
frequency: 5540,
|
||||
number: 108,
|
||||
radar: true,
|
||||
},
|
||||
{
|
||||
frequency: 5560,
|
||||
number: 112,
|
||||
radar: true,
|
||||
},
|
||||
{
|
||||
frequency: 5580,
|
||||
number: 116,
|
||||
radar: true,
|
||||
},
|
||||
{
|
||||
frequency: 5600,
|
||||
number: 120,
|
||||
radar: true,
|
||||
},
|
||||
{
|
||||
frequency: 5620,
|
||||
number: 124,
|
||||
radar: true,
|
||||
},
|
||||
{
|
||||
frequency: 5640,
|
||||
number: 128,
|
||||
radar: true,
|
||||
},
|
||||
{
|
||||
frequency: 5660,
|
||||
number: 132,
|
||||
radar: true,
|
||||
},
|
||||
{
|
||||
frequency: 5680,
|
||||
number: 136,
|
||||
radar: true,
|
||||
},
|
||||
{
|
||||
frequency: 5700,
|
||||
number: 140,
|
||||
radar: true,
|
||||
},
|
||||
{
|
||||
frequency: 5720,
|
||||
number: 144,
|
||||
radar: true,
|
||||
},
|
||||
{
|
||||
frequency: 5745,
|
||||
number: 149,
|
||||
radar: false,
|
||||
},
|
||||
{
|
||||
frequency: 5765,
|
||||
number: 153,
|
||||
radar: false,
|
||||
},
|
||||
{
|
||||
frequency: 5785,
|
||||
number: 157,
|
||||
radar: false,
|
||||
},
|
||||
{
|
||||
frequency: 5805,
|
||||
number: 161,
|
||||
radar: false,
|
||||
},
|
||||
{
|
||||
frequency: 5825,
|
||||
number: 165,
|
||||
radar: false,
|
||||
},
|
||||
],
|
||||
available_htmodes: [
|
||||
"NOHT",
|
||||
"HT20",
|
||||
"HT40",
|
||||
"VHT20",
|
||||
"VHT40",
|
||||
"VHT80",
|
||||
],
|
||||
hwmode: "11a",
|
||||
},
|
||||
],
|
||||
channel: 60,
|
||||
enabled: false,
|
||||
guest_wifi: {
|
||||
SSID: "TestGuestSSID",
|
||||
enabled: false,
|
||||
password: "",
|
||||
},
|
||||
hidden: false,
|
||||
htmode: "HT40",
|
||||
hwmode: "11a",
|
||||
id: 0,
|
||||
password: "TestPass",
|
||||
},
|
||||
{
|
||||
SSID: "Turris",
|
||||
available_bands: [
|
||||
{
|
||||
available_channels: [
|
||||
{
|
||||
frequency: 2412,
|
||||
number: 1,
|
||||
radar: false,
|
||||
},
|
||||
{
|
||||
frequency: 2417,
|
||||
number: 2,
|
||||
radar: false,
|
||||
},
|
||||
{
|
||||
frequency: 2422,
|
||||
number: 3,
|
||||
radar: false,
|
||||
},
|
||||
{
|
||||
frequency: 2427,
|
||||
number: 4,
|
||||
radar: false,
|
||||
},
|
||||
{
|
||||
frequency: 2432,
|
||||
number: 5,
|
||||
radar: false,
|
||||
},
|
||||
{
|
||||
frequency: 2437,
|
||||
number: 6,
|
||||
radar: false,
|
||||
},
|
||||
{
|
||||
frequency: 2442,
|
||||
number: 7,
|
||||
radar: false,
|
||||
},
|
||||
{
|
||||
frequency: 2447,
|
||||
number: 8,
|
||||
radar: false,
|
||||
},
|
||||
{
|
||||
frequency: 2452,
|
||||
number: 9,
|
||||
radar: false,
|
||||
},
|
||||
{
|
||||
frequency: 2457,
|
||||
number: 10,
|
||||
radar: false,
|
||||
},
|
||||
{
|
||||
frequency: 2462,
|
||||
number: 11,
|
||||
radar: false,
|
||||
},
|
||||
],
|
||||
available_htmodes: [
|
||||
"NOHT",
|
||||
"HT20",
|
||||
"HT40",
|
||||
],
|
||||
hwmode: "11g",
|
||||
},
|
||||
],
|
||||
channel: 11,
|
||||
enabled: false,
|
||||
guest_wifi: {
|
||||
SSID: "TestSSID",
|
||||
enabled: false,
|
||||
password: "",
|
||||
},
|
||||
hidden: false,
|
||||
htmode: "HT40",
|
||||
hwmode: "11g",
|
||||
id: 1,
|
||||
password: "TestPass",
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
@ -0,0 +1,912 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<WiFiSettings/> Snapshot 2.4 GHz 1`] = `
|
||||
"Snapshot Diff:
|
||||
- First value
|
||||
+ Second value
|
||||
|
||||
@@ -246,207 +246,95 @@
|
||||
value=\\"0\\"
|
||||
>
|
||||
auto
|
||||
</option>
|
||||
<option
|
||||
- value=\\"36\\"
|
||||
+ value=\\"1\\"
|
||||
>
|
||||
|
||||
- 36
|
||||
- (5180 MHz )
|
||||
+ 1
|
||||
+ (2412 MHz )
|
||||
|
||||
</option>
|
||||
<option
|
||||
- value=\\"40\\"
|
||||
+ value=\\"2\\"
|
||||
>
|
||||
|
||||
- 40
|
||||
- (5200 MHz )
|
||||
+ 2
|
||||
+ (2417 MHz )
|
||||
|
||||
</option>
|
||||
<option
|
||||
- value=\\"44\\"
|
||||
+ value=\\"3\\"
|
||||
>
|
||||
|
||||
- 44
|
||||
- (5220 MHz )
|
||||
+ 3
|
||||
+ (2422 MHz )
|
||||
|
||||
</option>
|
||||
<option
|
||||
- value=\\"48\\"
|
||||
- >
|
||||
-
|
||||
- 48
|
||||
- (5240 MHz )
|
||||
-
|
||||
- </option>
|
||||
- <option
|
||||
- value=\\"52\\"
|
||||
- >
|
||||
-
|
||||
- 52
|
||||
- (5260 MHz ,DFS)
|
||||
-
|
||||
- </option>
|
||||
- <option
|
||||
- value=\\"56\\"
|
||||
- >
|
||||
-
|
||||
- 56
|
||||
- (5280 MHz ,DFS)
|
||||
-
|
||||
- </option>
|
||||
- <option
|
||||
- value=\\"60\\"
|
||||
+ value=\\"4\\"
|
||||
>
|
||||
|
||||
- 60
|
||||
- (5300 MHz ,DFS)
|
||||
+ 4
|
||||
+ (2427 MHz )
|
||||
|
||||
</option>
|
||||
<option
|
||||
- value=\\"64\\"
|
||||
+ value=\\"5\\"
|
||||
>
|
||||
|
||||
- 64
|
||||
- (5320 MHz ,DFS)
|
||||
+ 5
|
||||
+ (2432 MHz )
|
||||
|
||||
</option>
|
||||
<option
|
||||
- value=\\"100\\"
|
||||
+ value=\\"6\\"
|
||||
>
|
||||
|
||||
- 100
|
||||
- (5500 MHz ,DFS)
|
||||
+ 6
|
||||
+ (2437 MHz )
|
||||
|
||||
</option>
|
||||
<option
|
||||
- value=\\"104\\"
|
||||
+ value=\\"7\\"
|
||||
>
|
||||
|
||||
- 104
|
||||
- (5520 MHz ,DFS)
|
||||
+ 7
|
||||
+ (2442 MHz )
|
||||
|
||||
</option>
|
||||
<option
|
||||
- value=\\"108\\"
|
||||
+ value=\\"8\\"
|
||||
>
|
||||
|
||||
- 108
|
||||
- (5540 MHz ,DFS)
|
||||
+ 8
|
||||
+ (2447 MHz )
|
||||
|
||||
</option>
|
||||
<option
|
||||
- value=\\"112\\"
|
||||
+ value=\\"9\\"
|
||||
>
|
||||
|
||||
- 112
|
||||
- (5560 MHz ,DFS)
|
||||
+ 9
|
||||
+ (2452 MHz )
|
||||
|
||||
</option>
|
||||
<option
|
||||
- value=\\"116\\"
|
||||
+ value=\\"10\\"
|
||||
>
|
||||
|
||||
- 116
|
||||
- (5580 MHz ,DFS)
|
||||
+ 10
|
||||
+ (2457 MHz )
|
||||
|
||||
</option>
|
||||
<option
|
||||
- value=\\"120\\"
|
||||
+ value=\\"11\\"
|
||||
>
|
||||
|
||||
- 120
|
||||
- (5600 MHz ,DFS)
|
||||
-
|
||||
- </option>
|
||||
- <option
|
||||
- value=\\"124\\"
|
||||
- >
|
||||
-
|
||||
- 124
|
||||
- (5620 MHz ,DFS)
|
||||
-
|
||||
- </option>
|
||||
- <option
|
||||
- value=\\"128\\"
|
||||
- >
|
||||
-
|
||||
- 128
|
||||
- (5640 MHz ,DFS)
|
||||
-
|
||||
- </option>
|
||||
- <option
|
||||
- value=\\"132\\"
|
||||
- >
|
||||
-
|
||||
- 132
|
||||
- (5660 MHz ,DFS)
|
||||
-
|
||||
- </option>
|
||||
- <option
|
||||
- value=\\"136\\"
|
||||
- >
|
||||
-
|
||||
- 136
|
||||
- (5680 MHz ,DFS)
|
||||
-
|
||||
- </option>
|
||||
- <option
|
||||
- value=\\"140\\"
|
||||
- >
|
||||
-
|
||||
- 140
|
||||
- (5700 MHz ,DFS)
|
||||
-
|
||||
- </option>
|
||||
- <option
|
||||
- value=\\"144\\"
|
||||
- >
|
||||
-
|
||||
- 144
|
||||
- (5720 MHz ,DFS)
|
||||
-
|
||||
- </option>
|
||||
- <option
|
||||
- value=\\"149\\"
|
||||
- >
|
||||
-
|
||||
- 149
|
||||
- (5745 MHz )
|
||||
-
|
||||
- </option>
|
||||
- <option
|
||||
- value=\\"153\\"
|
||||
- >
|
||||
-
|
||||
- 153
|
||||
- (5765 MHz )
|
||||
-
|
||||
- </option>
|
||||
- <option
|
||||
- value=\\"157\\"
|
||||
- >
|
||||
-
|
||||
- 157
|
||||
- (5785 MHz )
|
||||
-
|
||||
- </option>
|
||||
- <option
|
||||
- value=\\"161\\"
|
||||
- >
|
||||
-
|
||||
- 161
|
||||
- (5805 MHz )
|
||||
-
|
||||
- </option>
|
||||
- <option
|
||||
- value=\\"165\\"
|
||||
- >
|
||||
-
|
||||
- 165
|
||||
- (5825 MHz )
|
||||
+ 11
|
||||
+ (2462 MHz )
|
||||
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div"
|
||||
`;
|
||||
|
||||
exports[`<WiFiSettings/> Snapshot both modules disabled. 1`] = `
|
||||
<DocumentFragment>
|
||||
<div
|
||||
class="col-sm-12 offset-lg-1 col-lg-10 p-0 mb-3"
|
||||
>
|
||||
<form>
|
||||
<h3>
|
||||
Wi-Fi 1
|
||||
</h3>
|
||||
<div
|
||||
class="form-group"
|
||||
>
|
||||
<div
|
||||
class="custom-control custom-checkbox "
|
||||
>
|
||||
<input
|
||||
class="custom-control-input"
|
||||
id="1"
|
||||
type="checkbox"
|
||||
/>
|
||||
<label
|
||||
class="custom-control-label"
|
||||
for="1"
|
||||
>
|
||||
Enable
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<h3>
|
||||
Wi-Fi 2
|
||||
</h3>
|
||||
<div
|
||||
class="form-group"
|
||||
>
|
||||
<div
|
||||
class="custom-control custom-checkbox "
|
||||
>
|
||||
<input
|
||||
class="custom-control-input"
|
||||
id="2"
|
||||
type="checkbox"
|
||||
/>
|
||||
<label
|
||||
class="custom-control-label"
|
||||
for="2"
|
||||
>
|
||||
Enable
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="text-right"
|
||||
>
|
||||
<button
|
||||
class="btn btn-primary col-sm-12 col-lg-3"
|
||||
type="submit"
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<h4>
|
||||
Reset Wi-Fi Settings
|
||||
</h4>
|
||||
<p>
|
||||
|
||||
If a number of wireless cards doesn't match, you may try to reset the Wi-Fi settings. Note that this will remove the
|
||||
current Wi-Fi configuration and restore the default values.
|
||||
|
||||
</p>
|
||||
<div
|
||||
class="col-sm-12 offset-lg-1 col-lg-10 p-0 mb-3 text-right"
|
||||
>
|
||||
<button
|
||||
class="btn btn-warning col-sm-12 col-lg-3"
|
||||
type="button"
|
||||
>
|
||||
Reset Wi-Fi Settings
|
||||
</button>
|
||||
</div>
|
||||
</DocumentFragment>
|
||||
`;
|
||||
|
||||
exports[`<WiFiSettings/> Snapshot guest network. 1`] = `
|
||||
"Snapshot Diff:
|
||||
- First value
|
||||
+ Second value
|
||||
|
||||
@@ -475,10 +475,89 @@
|
||||
|
||||
</small>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
+ <div
|
||||
+ class=\\"form-group\\"
|
||||
+ >
|
||||
+ <label
|
||||
+ for=\\"20\\"
|
||||
+ >
|
||||
+ SSID
|
||||
+ </label>
|
||||
+ <div
|
||||
+ class=\\"input-group\\"
|
||||
+ >
|
||||
+ <input
|
||||
+ class=\\"form-control\\"
|
||||
+ id=\\"20\\"
|
||||
+ type=\\"text\\"
|
||||
+ value=\\"TestGuestSSID\\"
|
||||
+ />
|
||||
+ <div
|
||||
+ class=\\"input-group-append\\"
|
||||
+ >
|
||||
+ <button
|
||||
+ class=\\"input-group-text\\"
|
||||
+ type=\\"button\\"
|
||||
+ >
|
||||
+ <img
|
||||
+ alt=\\"QR\\"
|
||||
+ src=\\"/reforis/static/reforis/imgs/QR_icon.svg\\"
|
||||
+ style=\\"opacity: 0.67;\\"
|
||||
+ width=\\"20\\"
|
||||
+ />
|
||||
+ </button>
|
||||
+ </div>
|
||||
+ </div>
|
||||
+ </div>
|
||||
+ <div
|
||||
+ class=\\"form-group\\"
|
||||
+ >
|
||||
+ <label
|
||||
+ for=\\"21\\"
|
||||
+ >
|
||||
+ Password
|
||||
+ </label>
|
||||
+ <div
|
||||
+ class=\\"input-group\\"
|
||||
+ >
|
||||
+ <input
|
||||
+ autocomplete=\\"new-password\\"
|
||||
+ class=\\"form-control is-invalid\\"
|
||||
+ id=\\"21\\"
|
||||
+ required=\\"\\"
|
||||
+ type=\\"password\\"
|
||||
+ value=\\"\\"
|
||||
+ />
|
||||
+ <div
|
||||
+ class=\\"input-group-append\\"
|
||||
+ >
|
||||
+ <button
|
||||
+ class=\\"input-group-text\\"
|
||||
+ type=\\"button\\"
|
||||
+ >
|
||||
+ <i
|
||||
+ class=\\"fa fa-eye\\"
|
||||
+ />
|
||||
+ </button>
|
||||
+ </div>
|
||||
+ </div>
|
||||
+ <div
|
||||
+ class=\\"invalid-feedback\\"
|
||||
+ >
|
||||
+ Password must contain at least 8 symbols
|
||||
+ </div>
|
||||
+ <small
|
||||
+ class=\\"form-text text-muted\\"
|
||||
+ >
|
||||
+
|
||||
+ WPA2 pre-shared key, that is required to connect to the network.
|
||||
+
|
||||
+ </small>
|
||||
+ </div>
|
||||
<h3>
|
||||
Wi-Fi 2
|
||||
</h3>
|
||||
<div
|
||||
class=\\"form-group\\"
|
||||
@@ -502,10 +581,11 @@
|
||||
<div
|
||||
class=\\"text-right\\"
|
||||
>
|
||||
<button
|
||||
class=\\"btn btn-primary col-sm-12 col-lg-3\\"
|
||||
+ disabled=\\"\\"
|
||||
type=\\"submit\\"
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
</div>"
|
||||
`;
|
||||
|
||||
exports[`<WiFiSettings/> Snapshot one module enabled. 1`] = `
|
||||
"Snapshot Diff:
|
||||
- First value
|
||||
+ Second value
|
||||
|
||||
@@ -23,10 +23,462 @@
|
||||
>
|
||||
Enable
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
+ <div
|
||||
+ class=\\"form-group\\"
|
||||
+ >
|
||||
+ <label
|
||||
+ for=\\"4\\"
|
||||
+ >
|
||||
+ SSID
|
||||
+ </label>
|
||||
+ <div
|
||||
+ class=\\"input-group\\"
|
||||
+ >
|
||||
+ <input
|
||||
+ class=\\"form-control\\"
|
||||
+ id=\\"4\\"
|
||||
+ required=\\"\\"
|
||||
+ type=\\"text\\"
|
||||
+ value=\\"TestSSID1\\"
|
||||
+ />
|
||||
+ <div
|
||||
+ class=\\"input-group-append\\"
|
||||
+ >
|
||||
+ <button
|
||||
+ class=\\"input-group-text\\"
|
||||
+ type=\\"button\\"
|
||||
+ >
|
||||
+ <img
|
||||
+ alt=\\"QR\\"
|
||||
+ src=\\"/reforis/static/reforis/imgs/QR_icon.svg\\"
|
||||
+ style=\\"opacity: 0.67;\\"
|
||||
+ width=\\"20\\"
|
||||
+ />
|
||||
+ </button>
|
||||
+ </div>
|
||||
+ </div>
|
||||
+ </div>
|
||||
+ <div
|
||||
+ class=\\"form-group\\"
|
||||
+ >
|
||||
+ <label
|
||||
+ for=\\"5\\"
|
||||
+ >
|
||||
+ Password
|
||||
+ </label>
|
||||
+ <div
|
||||
+ class=\\"input-group\\"
|
||||
+ >
|
||||
+ <input
|
||||
+ autocomplete=\\"new-password\\"
|
||||
+ class=\\"form-control\\"
|
||||
+ id=\\"5\\"
|
||||
+ required=\\"\\"
|
||||
+ type=\\"password\\"
|
||||
+ value=\\"TestPass\\"
|
||||
+ />
|
||||
+ <div
|
||||
+ class=\\"input-group-append\\"
|
||||
+ >
|
||||
+ <button
|
||||
+ class=\\"input-group-text\\"
|
||||
+ type=\\"button\\"
|
||||
+ >
|
||||
+ <i
|
||||
+ class=\\"fa fa-eye\\"
|
||||
+ />
|
||||
+ </button>
|
||||
+ </div>
|
||||
+ </div>
|
||||
+ <small
|
||||
+ class=\\"form-text text-muted\\"
|
||||
+ >
|
||||
+
|
||||
+ WPA2 pre-shared key, that is required to connect to the network.
|
||||
+
|
||||
+ </small>
|
||||
+ </div>
|
||||
+ <div
|
||||
+ class=\\"form-group\\"
|
||||
+ >
|
||||
+ <div
|
||||
+ class=\\"custom-control custom-checkbox \\"
|
||||
+ >
|
||||
+ <input
|
||||
+ class=\\"custom-control-input\\"
|
||||
+ id=\\"6\\"
|
||||
+ type=\\"checkbox\\"
|
||||
+ />
|
||||
+ <label
|
||||
+ class=\\"custom-control-label\\"
|
||||
+ for=\\"6\\"
|
||||
+ >
|
||||
+ Hide SSID
|
||||
+ <small
|
||||
+ class=\\"form-text text-muted\\"
|
||||
+ >
|
||||
+ If set, network is not visible when scanning for available networks.
|
||||
+ </small>
|
||||
+ </label>
|
||||
+ </div>
|
||||
+ </div>
|
||||
+ <div
|
||||
+ class=\\"form-group\\"
|
||||
+ >
|
||||
+ <label
|
||||
+ class=\\"d-block\\"
|
||||
+ for=\\"7\\"
|
||||
+ >
|
||||
+ GHz
|
||||
+ </label>
|
||||
+ <div
|
||||
+ class=\\"custom-control custom-radio custom-control-inline\\"
|
||||
+ >
|
||||
+ <input
|
||||
+ class=\\"custom-control-input\\"
|
||||
+ id=\\"hwmode-0-0\\"
|
||||
+ name=\\"hwmode-0\\"
|
||||
+ type=\\"radio\\"
|
||||
+ value=\\"11g\\"
|
||||
+ />
|
||||
+ <label
|
||||
+ class=\\"custom-control-label\\"
|
||||
+ for=\\"hwmode-0-0\\"
|
||||
+ >
|
||||
+ 2.4
|
||||
+ </label>
|
||||
+ </div>
|
||||
+ <div
|
||||
+ class=\\"custom-control custom-radio custom-control-inline\\"
|
||||
+ >
|
||||
+ <input
|
||||
+ checked=\\"\\"
|
||||
+ class=\\"custom-control-input\\"
|
||||
+ id=\\"hwmode-0-1\\"
|
||||
+ name=\\"hwmode-0\\"
|
||||
+ type=\\"radio\\"
|
||||
+ value=\\"11a\\"
|
||||
+ />
|
||||
+ <label
|
||||
+ class=\\"custom-control-label\\"
|
||||
+ for=\\"hwmode-0-1\\"
|
||||
+ >
|
||||
+ 5
|
||||
+ </label>
|
||||
+ </div>
|
||||
+ <small
|
||||
+ class=\\"form-text text-muted\\"
|
||||
+ >
|
||||
+
|
||||
+ The 2.4 GHz band is more widely supported by clients, but tends to have more interference. The 5 GHz band is a
|
||||
+ newer standard and may not be supported by all your devices. It usually has less interference, but the signal
|
||||
+ does not carry so well indoors.
|
||||
+ </small>
|
||||
+ </div>
|
||||
+ <div
|
||||
+ class=\\"form-group\\"
|
||||
+ >
|
||||
+ <label
|
||||
+ for=\\"8\\"
|
||||
+ >
|
||||
+ 802.11n/ac mode
|
||||
+ </label>
|
||||
+ <select
|
||||
+ class=\\"custom-select\\"
|
||||
+ id=\\"8\\"
|
||||
+ >
|
||||
+ <option
|
||||
+ value=\\"NOHT\\"
|
||||
+ >
|
||||
+ Disabled
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"HT20\\"
|
||||
+ >
|
||||
+ 802.11n - 20 MHz wide channel
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"HT40\\"
|
||||
+ >
|
||||
+ 802.11n - 40 MHz wide channel
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"VHT20\\"
|
||||
+ >
|
||||
+ 802.11ac - 20 MHz wide channel
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"VHT40\\"
|
||||
+ >
|
||||
+ 802.11ac - 40 MHz wide channel
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"VHT80\\"
|
||||
+ >
|
||||
+ 802.11ac - 80 MHz wide channel
|
||||
+ </option>
|
||||
+ </select>
|
||||
+ <small
|
||||
+ class=\\"form-text text-muted\\"
|
||||
+ >
|
||||
+
|
||||
+ Change this to adjust 802.11n/ac mode of operation. 802.11n with 40 MHz wide channels can yield higher
|
||||
+ throughput but can cause more interference in the network. If you don't know what to choose, use the default
|
||||
+ option with 20 MHz wide channel.
|
||||
+
|
||||
+ </small>
|
||||
+ </div>
|
||||
+ <div
|
||||
+ class=\\"form-group\\"
|
||||
+ >
|
||||
+ <label
|
||||
+ for=\\"9\\"
|
||||
+ >
|
||||
+ Channel
|
||||
+ </label>
|
||||
+ <select
|
||||
+ class=\\"custom-select\\"
|
||||
+ id=\\"9\\"
|
||||
+ >
|
||||
+ <option
|
||||
+ value=\\"0\\"
|
||||
+ >
|
||||
+ auto
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"36\\"
|
||||
+ >
|
||||
+
|
||||
+ 36
|
||||
+ (5180 MHz )
|
||||
+
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"40\\"
|
||||
+ >
|
||||
+
|
||||
+ 40
|
||||
+ (5200 MHz )
|
||||
+
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"44\\"
|
||||
+ >
|
||||
+
|
||||
+ 44
|
||||
+ (5220 MHz )
|
||||
+
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"48\\"
|
||||
+ >
|
||||
+
|
||||
+ 48
|
||||
+ (5240 MHz )
|
||||
+
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"52\\"
|
||||
+ >
|
||||
+
|
||||
+ 52
|
||||
+ (5260 MHz ,DFS)
|
||||
+
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"56\\"
|
||||
+ >
|
||||
+
|
||||
+ 56
|
||||
+ (5280 MHz ,DFS)
|
||||
+
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"60\\"
|
||||
+ >
|
||||
+
|
||||
+ 60
|
||||
+ (5300 MHz ,DFS)
|
||||
+
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"64\\"
|
||||
+ >
|
||||
+
|
||||
+ 64
|
||||
+ (5320 MHz ,DFS)
|
||||
+
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"100\\"
|
||||
+ >
|
||||
+
|
||||
+ 100
|
||||
+ (5500 MHz ,DFS)
|
||||
+
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"104\\"
|
||||
+ >
|
||||
+
|
||||
+ 104
|
||||
+ (5520 MHz ,DFS)
|
||||
+
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"108\\"
|
||||
+ >
|
||||
+
|
||||
+ 108
|
||||
+ (5540 MHz ,DFS)
|
||||
+
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"112\\"
|
||||
+ >
|
||||
+
|
||||
+ 112
|
||||
+ (5560 MHz ,DFS)
|
||||
+
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"116\\"
|
||||
+ >
|
||||
+
|
||||
+ 116
|
||||
+ (5580 MHz ,DFS)
|
||||
+
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"120\\"
|
||||
+ >
|
||||
+
|
||||
+ 120
|
||||
+ (5600 MHz ,DFS)
|
||||
+
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"124\\"
|
||||
+ >
|
||||
+
|
||||
+ 124
|
||||
+ (5620 MHz ,DFS)
|
||||
+
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"128\\"
|
||||
+ >
|
||||
+
|
||||
+ 128
|
||||
+ (5640 MHz ,DFS)
|
||||
+
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"132\\"
|
||||
+ >
|
||||
+
|
||||
+ 132
|
||||
+ (5660 MHz ,DFS)
|
||||
+
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"136\\"
|
||||
+ >
|
||||
+
|
||||
+ 136
|
||||
+ (5680 MHz ,DFS)
|
||||
+
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"140\\"
|
||||
+ >
|
||||
+
|
||||
+ 140
|
||||
+ (5700 MHz ,DFS)
|
||||
+
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"144\\"
|
||||
+ >
|
||||
+
|
||||
+ 144
|
||||
+ (5720 MHz ,DFS)
|
||||
+
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"149\\"
|
||||
+ >
|
||||
+
|
||||
+ 149
|
||||
+ (5745 MHz )
|
||||
+
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"153\\"
|
||||
+ >
|
||||
+
|
||||
+ 153
|
||||
+ (5765 MHz )
|
||||
+
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"157\\"
|
||||
+ >
|
||||
+
|
||||
+ 157
|
||||
+ (5785 MHz )
|
||||
+
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"161\\"
|
||||
+ >
|
||||
+
|
||||
+ 161
|
||||
+ (5805 MHz )
|
||||
+
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"165\\"
|
||||
+ >
|
||||
+
|
||||
+ 165
|
||||
+ (5825 MHz )
|
||||
+
|
||||
+ </option>
|
||||
+ </select>
|
||||
+ </div>
|
||||
+ <div
|
||||
+ class=\\"form-group\\"
|
||||
+ >
|
||||
+ <div
|
||||
+ class=\\"custom-control custom-checkbox \\"
|
||||
+ >
|
||||
+ <input
|
||||
+ class=\\"custom-control-input\\"
|
||||
+ id=\\"10\\"
|
||||
+ type=\\"checkbox\\"
|
||||
+ />
|
||||
+ <label
|
||||
+ class=\\"custom-control-label\\"
|
||||
+ for=\\"10\\"
|
||||
+ >
|
||||
+ Enable Guest Wifi
|
||||
+ <small
|
||||
+ class=\\"form-text text-muted\\"
|
||||
+ >
|
||||
+
|
||||
+ Enables Wi-Fi for guests, which is separated from LAN network. Devices connected to this network are allowed to
|
||||
+ access the internet, but aren't allowed to access other devices and the configuration interface of the router.
|
||||
+ Parameters of the guest network can be set in the Guest network tab.
|
||||
+
|
||||
+ </small>
|
||||
+ </label>
|
||||
+ </div>
|
||||
+ </div>
|
||||
<h3>
|
||||
Wi-Fi 2
|
||||
</h3>
|
||||
<div
|
||||
class=\\"form-group\\""
|
||||
`;
|
39
src/common/WiFiSettings/constants.js
Normal file
39
src/common/WiFiSettings/constants.js
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
export const HTMODES = {
|
||||
NOHT: _("Disabled"),
|
||||
HT20: _("802.11n - 20 MHz wide channel"),
|
||||
HT40: _("802.11n - 40 MHz wide channel"),
|
||||
VHT20: _("802.11ac - 20 MHz wide channel"),
|
||||
VHT40: _("802.11ac - 40 MHz wide channel"),
|
||||
VHT80: _("802.11ac - 80 MHz wide channel"),
|
||||
};
|
||||
export const HWMODES = {
|
||||
"11g": "2.4",
|
||||
"11a": "5",
|
||||
};
|
||||
export const HELP_TEXTS = {
|
||||
password: _(`
|
||||
WPA2 pre-shared key, that is required to connect to the network.
|
||||
`),
|
||||
hidden: _("If set, network is not visible when scanning for available networks."),
|
||||
hwmode: _(`
|
||||
The 2.4 GHz band is more widely supported by clients, but tends to have more interference. The 5 GHz band is a
|
||||
newer standard and may not be supported by all your devices. It usually has less interference, but the signal
|
||||
does not carry so well indoors.`),
|
||||
htmode: _(`
|
||||
Change this to adjust 802.11n/ac mode of operation. 802.11n with 40 MHz wide channels can yield higher
|
||||
throughput but can cause more interference in the network. If you don't know what to choose, use the default
|
||||
option with 20 MHz wide channel.
|
||||
`),
|
||||
guest_wifi_enabled: _(`
|
||||
Enables Wi-Fi for guests, which is separated from LAN network. Devices connected to this network are allowed to
|
||||
access the internet, but aren't allowed to access other devices and the configuration interface of the router.
|
||||
Parameters of the guest network can be set in the Guest network tab.
|
||||
`),
|
||||
};
|
28
src/common/WiFiSettings/qrCodeHelpers.js
Normal file
28
src/common/WiFiSettings/qrCodeHelpers.js
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import pdfMake from "pdfmake";
|
||||
|
||||
export function createAndDownloadPdf(SSID, password) {
|
||||
const docDefinition = {
|
||||
content: [
|
||||
{
|
||||
text: "Wi-Fi", style: "header", fontSize: 55, alignment: "center",
|
||||
},
|
||||
{
|
||||
qr: toQRCodeContent(SSID, password), fit: "350", margin: [0, 80], alignment: "center",
|
||||
},
|
||||
{ text: `SSID: ${SSID}`, fontSize: 25, alignment: "center" },
|
||||
{ text: `Password: ${password}`, fontSize: 25, alignment: "center" },
|
||||
],
|
||||
};
|
||||
pdfMake.createPdf(docDefinition).download("wifi.pdf");
|
||||
}
|
||||
|
||||
export function toQRCodeContent(SSID, password) {
|
||||
return `WIFI:S:${SSID};T:WPA2;P:${password};;`;
|
||||
}
|
@ -7,7 +7,9 @@
|
||||
|
||||
import React from "react";
|
||||
|
||||
import { fireEvent, getByText, queryByText, render, wait } from "customTestRender";
|
||||
import {
|
||||
fireEvent, getByText, queryByText, render, wait,
|
||||
} from "customTestRender";
|
||||
import mockAxios from "jest-mock-axios";
|
||||
import { mockJSONError } from "testUtils/network";
|
||||
import { mockSetAlert } from "testUtils/alertContextMock";
|
||||
@ -18,8 +20,8 @@ describe("<RebootButton/>", () => {
|
||||
let componentContainer;
|
||||
beforeEach(() => {
|
||||
const { container } = render(<>
|
||||
<div id="modal-container"/>
|
||||
<RebootButton/>
|
||||
<div id="modal-container" />
|
||||
<RebootButton />
|
||||
</>);
|
||||
componentContainer = container;
|
||||
});
|
||||
@ -51,5 +53,4 @@ describe("<RebootButton/>", () => {
|
||||
await wait(() => expect(mockSetAlert)
|
||||
.toBeCalledWith("Reboot request failed."));
|
||||
});
|
||||
|
||||
});
|
||||
|
Reference in New Issue
Block a user