committed by
GitHub
10 changed files with 424 additions and 131 deletions
@ -1,11 +1,15 @@ |
|||||
{ |
{ |
||||
"version": "4", |
"version": "4", |
||||
"specifiers": { |
"specifiers": { |
||||
|
"jsr:@meshtastic/core@^2.6.0": "2.6.2", |
||||
|
"jsr:@meshtastic/core@^2.6.2": "2.6.2", |
||||
|
"jsr:@meshtastic/js@^2.3.4": "2.3.4", |
||||
|
"jsr:@meshtastic/protobufs@^2.3.12": "2.6.2", |
||||
|
"jsr:@meshtastic/protobufs@^2.6.2": "2.6.2", |
||||
|
"jsr:@meshtastic/transport-http@~0.2.1": "0.2.1", |
||||
|
"jsr:@meshtastic/transport-web-bluetooth@~0.1.1": "0.1.1", |
||||
|
"jsr:@meshtastic/transport-web-serial@~0.2.1": "0.2.1", |
||||
"npm:@bufbuild/protobuf@^2.2.3": "2.2.3", |
"npm:@bufbuild/protobuf@^2.2.3": "2.2.3", |
||||
"npm:@jsr/[email protected]": "2.6.0-0", |
|
||||
"npm:@jsr/[email protected]": "2.6.0-0", |
|
||||
"npm:@jsr/meshtastic__transport-http@*": "0.2.1", |
|
||||
"npm:@jsr/meshtastic__transport-web-serial@*": "0.2.1", |
|
||||
"npm:@noble/curves@^1.8.1": "1.8.1", |
"npm:@noble/curves@^1.8.1": "1.8.1", |
||||
"npm:@radix-ui/react-accordion@^1.2.3": "1.2.3_@[email protected]_@[email protected]__@[email protected][email protected][email protected][email protected]", |
"npm:@radix-ui/react-accordion@^1.2.3": "1.2.3_@[email protected]_@[email protected]__@[email protected][email protected][email protected][email protected]", |
||||
"npm:@radix-ui/react-checkbox@^1.1.4": "1.1.4_@[email protected]_@[email protected]__@[email protected][email protected][email protected][email protected]", |
"npm:@radix-ui/react-checkbox@^1.1.4": "1.1.4_@[email protected]_@[email protected]__@[email protected][email protected][email protected][email protected]", |
||||
@ -73,8 +77,48 @@ |
|||||
"npm:vite@*": "6.2.0_@[email protected]", |
"npm:vite@*": "6.2.0_@[email protected]", |
||||
"npm:vite@^6.2.0": "6.2.0_@[email protected]", |
"npm:vite@^6.2.0": "6.2.0_@[email protected]", |
||||
"npm:vitest@^3.0.7": "3.0.8_@[email protected][email protected][email protected]__@[email protected]_@[email protected][email protected][email protected]___@[email protected][email protected]___@[email protected][email protected][email protected][email protected][email protected]_____@[email protected][email protected]_____@[email protected][email protected]____@[email protected][email protected][email protected][email protected]____@[email protected][email protected][email protected][email protected][email protected][email protected]___@[email protected][email protected]___@[email protected]__@[email protected][email protected][email protected]", |
"npm:vitest@^3.0.7": "3.0.8_@[email protected][email protected][email protected]__@[email protected]_@[email protected][email protected][email protected]___@[email protected][email protected]___@[email protected][email protected][email protected][email protected][email protected]_____@[email protected][email protected]_____@[email protected][email protected]____@[email protected][email protected][email protected][email protected]____@[email protected][email protected][email protected][email protected][email protected][email protected]___@[email protected][email protected]___@[email protected]__@[email protected][email protected][email protected]", |
||||
|
"npm:zod@^3.24.2": "3.24.2", |
||||
"npm:[email protected]": "5.0.3_@[email protected][email protected][email protected]" |
"npm:[email protected]": "5.0.3_@[email protected][email protected][email protected]" |
||||
}, |
}, |
||||
|
"jsr": { |
||||
|
"@meshtastic/[email protected]": { |
||||
|
"integrity": "5c948bbbfad280c5eb093c62edc84773f76509487b333066ec4a349f40dcacf2", |
||||
|
"dependencies": [ |
||||
|
"jsr:@meshtastic/protobufs@^2.6.2", |
||||
|
"npm:@bufbuild/protobuf", |
||||
|
"npm:crc", |
||||
|
"npm:ste-simple-events", |
||||
|
"npm:tslog@^4.9.3" |
||||
|
] |
||||
|
}, |
||||
|
"@meshtastic/[email protected]": { |
||||
|
"integrity": "7a81a36fb7ef1b7b68a3989c02d50f687114ac56bcd7f0452a31ef560ac99719", |
||||
|
"dependencies": [ |
||||
|
"jsr:@meshtastic/protobufs@^2.3.12", |
||||
|
"npm:crc", |
||||
|
"npm:ste-simple-events", |
||||
|
"npm:tslog@^4.9.2" |
||||
|
] |
||||
|
}, |
||||
|
"@meshtastic/[email protected]": { |
||||
|
"integrity": "55e9b98fc22ea0d28e6a7979e4ff0a5f2c94513c1bc93e67522636a89925ad69", |
||||
|
"dependencies": [ |
||||
|
"npm:@bufbuild/protobuf" |
||||
|
] |
||||
|
}, |
||||
|
"@meshtastic/[email protected]": { |
||||
|
"integrity": "4d086ee6d5665c3490736737c4354eb3049edf792b1d195b30a3254cb535a7d6" |
||||
|
}, |
||||
|
"@meshtastic/[email protected]": { |
||||
|
"integrity": "f7676b98e2049ad0bca508e34054730b22cf2648019921989f11297441fe958d" |
||||
|
}, |
||||
|
"@meshtastic/[email protected]": { |
||||
|
"integrity": "d09fa8ac278b105c8f2b3a72af9cf8a5676baac6f4e9111c6773ff6217e2d5be", |
||||
|
"dependencies": [ |
||||
|
"jsr:@meshtastic/core@^2.6.0" |
||||
|
] |
||||
|
} |
||||
|
}, |
||||
"npm": { |
"npm": { |
||||
"@adobe/[email protected]": { |
"@adobe/[email protected]": { |
||||
"integrity": "sha512-baYZExFpsdkBNuvGKTKWCwKH57HRZLVtycZS05WTQNVOiXVSeAki3nU35zlRbToeMW8aHlJfyS+1C4BOv27q0A==" |
"integrity": "sha512-baYZExFpsdkBNuvGKTKWCwKH57HRZLVtycZS05WTQNVOiXVSeAki3nU35zlRbToeMW8aHlJfyS+1C4BOv27q0A==" |
||||
@ -1082,54 +1126,6 @@ |
|||||
"@jridgewell/sourcemap-codec" |
"@jridgewell/sourcemap-codec" |
||||
] |
] |
||||
}, |
}, |
||||
"@jsr/[email protected]": { |
|
||||
"integrity": "sha512-+Ik6gzZnfi5sW+WC06bRayA6KGF2NI+zi3bqKbvA8mGDNSOPgsFhA4VZ79DKY4bSflTW170MRIUeyYo0IWQQuw==", |
|
||||
"dependencies": [ |
|
||||
"@bufbuild/protobuf", |
|
||||
"@jsr/meshtastic__protobufs", |
|
||||
"crc", |
|
||||
"ste-simple-events", |
|
||||
"tslog" |
|
||||
] |
|
||||
}, |
|
||||
"@jsr/[email protected]": { |
|
||||
"integrity": "sha512-Ks71sRagbBipotznULpsJZ1EMcQIqCEJQx6mf628dmCNVf2YECi2zi/i/5zErp1hGPgfbDvCz9oPogvsd/7fMA==", |
|
||||
"dependencies": [ |
|
||||
"@bufbuild/protobuf", |
|
||||
"@jsr/meshtastic__protobufs", |
|
||||
"crc", |
|
||||
"ste-simple-events", |
|
||||
"tslog" |
|
||||
] |
|
||||
}, |
|
||||
"@jsr/[email protected]": { |
|
||||
"integrity": "sha512-+xpZpxK6oUIVOuEs7C+LyxRr2druvc7UNNNTK9Rl8ioXj63Jz1uQXlYe2Gj0xjnRAiSQLR7QVaPef21BR/YTxA==", |
|
||||
"dependencies": [ |
|
||||
"@bufbuild/protobuf", |
|
||||
"@jsr/meshtastic__protobufs", |
|
||||
"crc", |
|
||||
"ste-simple-events", |
|
||||
"tslog" |
|
||||
] |
|
||||
}, |
|
||||
"@jsr/[email protected]": { |
|
||||
"integrity": "sha512-CGlgBdzAuQCZuGPrnzP8zU+EcLlmyYeeMbqFHuJ834cYfArWXDjDh1UYaPo2rI03LTjqa3MeWpfqDlzBR8kIMg==", |
|
||||
"dependencies": [ |
|
||||
"@bufbuild/protobuf" |
|
||||
] |
|
||||
}, |
|
||||
"@jsr/[email protected]": { |
|
||||
"integrity": "sha512-lmQKr3aIINKvtGROU4HchmSVqbZSbkIHqajowRRC8IAjsnR0zNTyxz210QyY4pFUF9hpcW3GRjwq5h/VO2JuGg==", |
|
||||
"dependencies": [ |
|
||||
"@jsr/[email protected]" |
|
||||
] |
|
||||
}, |
|
||||
"@jsr/[email protected]": { |
|
||||
"integrity": "sha512-yumjEGLkAuJYOC3aWKvZzbQqi/LnqaKfNpVCY7Ki7oLtAshNiZrBLiwiFhN7+ZR9FfMdJThyBMqREBDRRWTO1Q==", |
|
||||
"dependencies": [ |
|
||||
"@jsr/[email protected]" |
|
||||
] |
|
||||
}, |
|
||||
"@mapbox/[email protected]": { |
"@mapbox/[email protected]": { |
||||
"integrity": "sha512-tJaT+RbYGJYStt7wI3cq4Nl4SXxG8W7JDG5DMJu97V25RnbNg3QtQtf+KD+VLjNpWKYsRvXDNmNrBgEETr1ifA==", |
"integrity": "sha512-tJaT+RbYGJYStt7wI3cq4Nl4SXxG8W7JDG5DMJu97V25RnbNg3QtQtf+KD+VLjNpWKYsRvXDNmNrBgEETr1ifA==", |
||||
"dependencies": [ |
"dependencies": [ |
||||
@ -6869,6 +6865,9 @@ |
|||||
"[email protected]": { |
"[email protected]": { |
||||
"integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==" |
"integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==" |
||||
}, |
}, |
||||
|
"[email protected]": { |
||||
|
"integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==" |
||||
|
}, |
||||
"[email protected]": { |
"[email protected]": { |
||||
"integrity": "sha512-mla2acNCMkWXBD+c+yeUrBUrzOxYMNFdQ6FGfigGGtEVBPJx07BQeJekjt9DmH1FtZek4E9rE1eRR9qQpxACOQ==" |
"integrity": "sha512-mla2acNCMkWXBD+c+yeUrBUrzOxYMNFdQ6FGfigGGtEVBPJx07BQeJekjt9DmH1FtZek4E9rE1eRR9qQpxACOQ==" |
||||
}, |
}, |
||||
@ -6882,13 +6881,16 @@ |
|||||
} |
} |
||||
}, |
}, |
||||
"workspace": { |
"workspace": { |
||||
|
"dependencies": [ |
||||
|
"jsr:@meshtastic/core@^2.6.2", |
||||
|
"jsr:@meshtastic/js@^2.3.4", |
||||
|
"jsr:@meshtastic/transport-http@~0.2.1", |
||||
|
"jsr:@meshtastic/transport-web-bluetooth@~0.1.1", |
||||
|
"jsr:@meshtastic/transport-web-serial@~0.2.1" |
||||
|
], |
||||
"packageJson": { |
"packageJson": { |
||||
"dependencies": [ |
"dependencies": [ |
||||
"npm:@bufbuild/protobuf@^2.2.3", |
"npm:@bufbuild/protobuf@^2.2.3", |
||||
"npm:@jsr/[email protected]", |
|
||||
"npm:@jsr/[email protected]", |
|
||||
"npm:@jsr/meshtastic__transport-http@*", |
|
||||
"npm:@jsr/meshtastic__transport-web-serial@*", |
|
||||
"npm:@noble/curves@^1.8.1", |
"npm:@noble/curves@^1.8.1", |
||||
"npm:@radix-ui/react-accordion@^1.2.3", |
"npm:@radix-ui/react-accordion@^1.2.3", |
||||
"npm:@radix-ui/react-checkbox@^1.1.4", |
"npm:@radix-ui/react-checkbox@^1.1.4", |
||||
@ -6950,6 +6952,7 @@ |
|||||
"npm:vite-plugin-pwa@~0.21.1", |
"npm:vite-plugin-pwa@~0.21.1", |
||||
"npm:vite@^6.2.0", |
"npm:vite@^6.2.0", |
||||
"npm:vitest@^3.0.7", |
"npm:vitest@^3.0.7", |
||||
|
"npm:zod@^3.24.2", |
||||
"npm:[email protected]" |
"npm:[email protected]" |
||||
] |
] |
||||
} |
} |
||||
|
|||||
@ -35,10 +35,6 @@ |
|||||
"homepage": "https://meshtastic.org", |
"homepage": "https://meshtastic.org", |
||||
"dependencies": { |
"dependencies": { |
||||
"@bufbuild/protobuf": "^2.2.3", |
"@bufbuild/protobuf": "^2.2.3", |
||||
"@meshtastic/core": "npm:@jsr/[email protected]", |
|
||||
"@meshtastic/js": "npm:@jsr/[email protected]", |
|
||||
"@meshtastic/transport-http": "npm:@jsr/meshtastic__transport-http", |
|
||||
"@meshtastic/transport-web-serial": "npm:@jsr/meshtastic__transport-web-serial", |
|
||||
"@noble/curves": "^1.8.1", |
"@noble/curves": "^1.8.1", |
||||
"@radix-ui/react-accordion": "^1.2.3", |
"@radix-ui/react-accordion": "^1.2.3", |
||||
"@radix-ui/react-checkbox": "^1.1.4", |
"@radix-ui/react-checkbox": "^1.1.4", |
||||
@ -73,6 +69,7 @@ |
|||||
"react-qrcode-logo": "^3.0.0", |
"react-qrcode-logo": "^3.0.0", |
||||
"rfc4648": "^1.5.4", |
"rfc4648": "^1.5.4", |
||||
"vite-plugin-node-polyfills": "^0.23.0", |
"vite-plugin-node-polyfills": "^0.23.0", |
||||
|
"zod": "^3.24.2", |
||||
"zustand": "5.0.3" |
"zustand": "5.0.3" |
||||
}, |
}, |
||||
"devDependencies": { |
"devDependencies": { |
||||
|
|||||
@ -0,0 +1,283 @@ |
|||||
|
// import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
||||
|
// import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
||||
|
// import { Network } from '@components/PageComponents/Config/Network/index.tsx';
|
||||
|
// import { useDevice } from "@core/stores/deviceStore.ts";
|
||||
|
// import { Protobuf } from "@meshtastic/core";
|
||||
|
|
||||
|
// vi.mock('@core/stores/deviceStore', () => ({
|
||||
|
// useDevice: vi.fn()
|
||||
|
// }));
|
||||
|
|
||||
|
// vi.mock('@components/Form/DynamicForm', () => ({
|
||||
|
// DynamicForm: vi.fn(({ onSubmit }) => {
|
||||
|
// return (
|
||||
|
// <div data-testid="dynamic-form">
|
||||
|
// <select
|
||||
|
// data-testid="role-select"
|
||||
|
// onChange={(e) => {
|
||||
|
// const mockData = { role: e.target.value };
|
||||
|
// onSubmit(mockData);
|
||||
|
// }}
|
||||
|
// >
|
||||
|
// {Object.entries(Protobuf.Config.Config_DeviceConfig_Role).map(([key, value]) => (
|
||||
|
// <option key={key} value={value}>
|
||||
|
// {key}
|
||||
|
// </option>
|
||||
|
// ))}
|
||||
|
// </select>
|
||||
|
// <button type="submit"
|
||||
|
// data-testid="submit-button"
|
||||
|
// onClick={() => onSubmit({ role: "CLIENT" })}
|
||||
|
// >
|
||||
|
// Submit
|
||||
|
// </button>
|
||||
|
// </div>
|
||||
|
// );
|
||||
|
// })
|
||||
|
// }));
|
||||
|
|
||||
|
// describe('Network component', () => {
|
||||
|
// const setWorkingConfigMock = vi.fn();
|
||||
|
// const mockDeviceConfig = {
|
||||
|
// role: "CLIENT",
|
||||
|
// buttonGpio: 0,
|
||||
|
// buzzerGpio: 0,
|
||||
|
// rebroadcastMode: "ALL",
|
||||
|
// nodeInfoBroadcastSecs: 300,
|
||||
|
// doubleTapAsButtonPress: false,
|
||||
|
// disableTripleClick: false,
|
||||
|
// ledHeartbeatDisabled: false,
|
||||
|
// };
|
||||
|
|
||||
|
// beforeEach(() => {
|
||||
|
// vi.resetAllMocks();
|
||||
|
|
||||
|
// (useDevice as any).mockReturnValue({
|
||||
|
// config: {
|
||||
|
// device: mockDeviceConfig
|
||||
|
// },
|
||||
|
// setWorkingConfig: setWorkingConfigMock
|
||||
|
// });
|
||||
|
|
||||
|
// });
|
||||
|
|
||||
|
// afterEach(() => {
|
||||
|
// vi.clearAllMocks();
|
||||
|
// });
|
||||
|
|
||||
|
// it('should render the Network form', () => {
|
||||
|
// render(<Network />);
|
||||
|
// expect(screen.getByTestId('dynamic-form')).toBeInTheDocument();
|
||||
|
// });
|
||||
|
|
||||
|
// it('should call setWorkingConfig when form is submitted', async () => {
|
||||
|
// render(<Network />);
|
||||
|
|
||||
|
// fireEvent.click(screen.getByTestId('submit-button'));
|
||||
|
|
||||
|
// await waitFor(() => {
|
||||
|
// expect(setWorkingConfigMock).toHaveBeenCalledWith(
|
||||
|
// expect.objectContaining({
|
||||
|
// payloadVariant: {
|
||||
|
// case: "device",
|
||||
|
// value: expect.objectContaining({ role: "CLIENT" })
|
||||
|
// }
|
||||
|
// })
|
||||
|
// );
|
||||
|
// });
|
||||
|
// });
|
||||
|
|
||||
|
|
||||
|
// it('should create config with proper structure', async () => {
|
||||
|
// render(<Network />);
|
||||
|
|
||||
|
// // Simulate form submission
|
||||
|
// fireEvent.click(screen.getByTestId('submit-button'));
|
||||
|
|
||||
|
// await waitFor(() => {
|
||||
|
// expect(setWorkingConfigMock).toHaveBeenCalledWith(
|
||||
|
// expect.objectContaining({
|
||||
|
// payloadVariant: {
|
||||
|
// case: "network",
|
||||
|
// value: expect.any(Object)
|
||||
|
// }
|
||||
|
// })
|
||||
|
// );
|
||||
|
// });
|
||||
|
// });
|
||||
|
// });
|
||||
|
|
||||
|
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; |
||||
|
import { render, screen, fireEvent, waitFor } from '@testing-library/react'; |
||||
|
import { Network } from '@components/PageComponents/Config/Network/index.tsx'; |
||||
|
import { useDevice } from "@core/stores/deviceStore.ts"; |
||||
|
import { Protobuf } from "@meshtastic/core"; |
||||
|
|
||||
|
vi.mock('@core/stores/deviceStore', () => ({ |
||||
|
useDevice: vi.fn() |
||||
|
})); |
||||
|
|
||||
|
vi.mock('@components/Form/DynamicForm', async () => { |
||||
|
const React = await import('react'); |
||||
|
const { useState } = React; |
||||
|
|
||||
|
return { |
||||
|
DynamicForm: ({ onSubmit, defaultValues }: any) => { |
||||
|
const [wifiEnabled, setWifiEnabled] = useState(defaultValues.wifiEnabled ?? false); |
||||
|
const [ssid, setSsid] = useState(defaultValues.wifiSsid ?? ''); |
||||
|
const [psk, setPsk] = useState(defaultValues.wifiPsk ?? ''); |
||||
|
|
||||
|
return ( |
||||
|
<form |
||||
|
onSubmit={(e) => { |
||||
|
e.preventDefault(); |
||||
|
onSubmit({ |
||||
|
...defaultValues, |
||||
|
wifiEnabled, |
||||
|
wifiSsid: ssid, |
||||
|
wifiPsk: psk, |
||||
|
}); |
||||
|
}} |
||||
|
data-testid="dynamic-form" |
||||
|
> |
||||
|
<input |
||||
|
type="checkbox" |
||||
|
aria-label="WiFi Enabled" |
||||
|
checked={wifiEnabled} |
||||
|
onChange={(e) => setWifiEnabled(e.target.checked)} |
||||
|
/> |
||||
|
<input |
||||
|
aria-label="SSID" |
||||
|
value={ssid} |
||||
|
onChange={(e) => setSsid(e.target.value)} |
||||
|
disabled={!wifiEnabled} |
||||
|
/> |
||||
|
<input |
||||
|
aria-label="PSK" |
||||
|
value={psk} |
||||
|
onChange={(e) => setPsk(e.target.value)} |
||||
|
disabled={!wifiEnabled} |
||||
|
/> |
||||
|
<button type="submit" data-testid="submit-button"> |
||||
|
Submit |
||||
|
</button> |
||||
|
</form> |
||||
|
); |
||||
|
}, |
||||
|
}; |
||||
|
}); |
||||
|
; |
||||
|
|
||||
|
describe('Network component', () => { |
||||
|
const setWorkingConfigMock = vi.fn(); |
||||
|
const mockNetworkConfig = { |
||||
|
wifiEnabled: false, |
||||
|
wifiSsid: '', |
||||
|
wifiPsk: '', |
||||
|
ntpServer: '', |
||||
|
ethEnabled: false, |
||||
|
addressMode: Protobuf.Config.Config_NetworkConfig_AddressMode.DHCP, |
||||
|
ipv4Config: { |
||||
|
ip: 0, |
||||
|
gateway: 0, |
||||
|
subnet: 0, |
||||
|
dns: 0, |
||||
|
}, |
||||
|
enabledProtocols: |
||||
|
Protobuf.Config.Config_NetworkConfig_ProtocolFlags.NO_BROADCAST, |
||||
|
rsyslogServer: '', |
||||
|
}; |
||||
|
|
||||
|
beforeEach(() => { |
||||
|
vi.resetAllMocks(); |
||||
|
|
||||
|
(useDevice as any).mockReturnValue({ |
||||
|
config: { |
||||
|
network: mockNetworkConfig |
||||
|
}, |
||||
|
setWorkingConfig: setWorkingConfigMock |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
afterEach(() => { |
||||
|
vi.clearAllMocks(); |
||||
|
}); |
||||
|
|
||||
|
it('should render the Network form', () => { |
||||
|
render(<Network />); |
||||
|
expect(screen.getByTestId('dynamic-form')).toBeInTheDocument(); |
||||
|
}); |
||||
|
|
||||
|
it('should disable SSID and PSK fields when wifi is off', () => { |
||||
|
render(<Network />); |
||||
|
expect(screen.getByLabelText("SSID")).toBeDisabled(); |
||||
|
expect(screen.getByLabelText("PSK")).toBeDisabled(); |
||||
|
}); |
||||
|
|
||||
|
it('should enable SSID and PSK when wifi is toggled on', async () => { |
||||
|
render(<Network />); |
||||
|
const toggle = screen.getByLabelText("WiFi Enabled"); |
||||
|
screen.debug() |
||||
|
|
||||
|
fireEvent.click(toggle); // turns wifiEnabled = true
|
||||
|
|
||||
|
await waitFor(() => { |
||||
|
expect(screen.getByLabelText("SSID")).not.toBeDisabled(); |
||||
|
expect(screen.getByLabelText("PSK")).not.toBeDisabled(); |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
it('should call setWorkingConfig with the right structure on submit', async () => { |
||||
|
render(<Network />); |
||||
|
|
||||
|
fireEvent.click(screen.getByTestId("submit-button")); |
||||
|
|
||||
|
await waitFor(() => { |
||||
|
expect(setWorkingConfigMock).toHaveBeenCalledWith( |
||||
|
expect.objectContaining({ |
||||
|
payloadVariant: { |
||||
|
case: "network", |
||||
|
value: expect.objectContaining({ |
||||
|
wifiEnabled: false, |
||||
|
wifiSsid: '', |
||||
|
wifiPsk: '', |
||||
|
ntpServer: '', |
||||
|
ethEnabled: false, |
||||
|
rsyslogServer: '', |
||||
|
}) |
||||
|
} |
||||
|
}) |
||||
|
); |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
it('should submit valid data after enabling wifi and entering SSID and PSK', async () => { |
||||
|
render(<Network />); |
||||
|
fireEvent.click(screen.getByLabelText("WiFi Enabled")); |
||||
|
|
||||
|
fireEvent.change(screen.getByLabelText("SSID"), { |
||||
|
target: { value: "MySSID" } |
||||
|
}); |
||||
|
|
||||
|
fireEvent.change(screen.getByLabelText("PSK"), { |
||||
|
target: { value: "MySecretPSK" } |
||||
|
}); |
||||
|
|
||||
|
fireEvent.click(screen.getByTestId("submit-button")); |
||||
|
|
||||
|
await waitFor(() => { |
||||
|
expect(setWorkingConfigMock).toHaveBeenCalledWith( |
||||
|
expect.objectContaining({ |
||||
|
payloadVariant: { |
||||
|
case: "network", |
||||
|
value: expect.objectContaining({ |
||||
|
wifiEnabled: true, |
||||
|
wifiSsid: "MySSID", |
||||
|
wifiPsk: "MySecretPSK" |
||||
|
}) |
||||
|
} |
||||
|
}) |
||||
|
); |
||||
|
}); |
||||
|
}); |
||||
|
}); |
||||
@ -0,0 +1,13 @@ |
|||||
|
import { ZodError, ZodSchema } from "zod"; |
||||
|
|
||||
|
export function validateSchema<T>( |
||||
|
schema: ZodSchema<T>, |
||||
|
data: unknown |
||||
|
): { success: true; data: T } | { success: false; errors: ZodError["issues"] } { |
||||
|
const result = schema.safeParse(data); |
||||
|
if (result.success) { |
||||
|
return { success: true, data: result.data }; |
||||
|
} else { |
||||
|
return { success: false, errors: result.error.issues }; |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue