Skip to content

Commit

Permalink
fix(app): presume disconnect wifi success when wifi status is null (#…
Browse files Browse the repository at this point in the history
…13622)

this is a fallback to avoid a stuck disconnect modal loading state if the browser is unable to
respond to a successful disconnect wifi request

closes RQA-1495
  • Loading branch information
brenthagen authored Sep 21, 2023
1 parent 35e232b commit 1cddb5b
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ import { StyledText } from '../../../../atoms/text'
import { LegacyModal } from '../../../../molecules/LegacyModal'
import { useRobot } from '../../../../organisms/Devices/hooks'
import { CONNECTABLE } from '../../../../redux/discovery'
import { postWifiDisconnect } from '../../../../redux/networking'
import {
getNetworkInterfaces,
postWifiDisconnect,
} from '../../../../redux/networking'
import { useWifiList } from '../../../../resources/networking/hooks'
import {
dismissRequest,
Expand All @@ -46,6 +49,9 @@ export const DisconnectModal = ({
const { t } = useTranslation(['device_settings', 'shared'])

const wifiList = useWifiList(robotName)
const { wifi } = useSelector((state: State) =>
getNetworkInterfaces(state, robotName)
)

const activeNetwork = wifiList?.find(nw => nw.active)
const ssid = activeNetwork?.ssid ?? null
Expand Down Expand Up @@ -93,7 +99,10 @@ export const DisconnectModal = ({
// check for connectable robot health status and presume successful disconnection if request pending and robot not connectable
const { status } = useRobot(robotName) ?? {}
const isDisconnected =
isRequestSucceeded || (isRequestPending && status !== CONNECTABLE)
isRequestSucceeded ||
(isRequestPending && status !== CONNECTABLE) ||
// as a fallback, if polled wifi interface ipAddress is null presume successful disconnection
wifi?.ipAddress == null

if (isDisconnected) {
disconnectModalBody = t('disconnect_from_wifi_network_success')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ import {
mockConnectableRobot,
mockReachableRobot,
} from '../../../../../redux/discovery/__fixtures__'
import { postWifiDisconnect } from '../../../../../redux/networking'
import {
getNetworkInterfaces,
INTERFACE_WIFI,
postWifiDisconnect,
} from '../../../../../redux/networking'
import { mockWifiNetwork } from '../../../../../redux/networking/__fixtures__'
import {
dismissRequest,
Expand Down Expand Up @@ -38,6 +42,9 @@ const mockUseDispatchApiRequest = useDispatchApiRequest as jest.MockedFunction<
const mockGetRequestById = getRequestById as jest.MockedFunction<
typeof getRequestById
>
const mockGetNetworkInterfaces = getNetworkInterfaces as jest.MockedFunction<
typeof getNetworkInterfaces
>
const mockPostWifiDisconnect = postWifiDisconnect as jest.MockedFunction<
typeof postWifiDisconnect
>
Expand All @@ -49,6 +56,12 @@ const mockUseRobot = useRobot as jest.MockedFunction<typeof useRobot>
const ROBOT_NAME = 'otie'
const LAST_ID = 'a request id'
const mockOnCancel = jest.fn()
const MOCK_WIFI = {
ipAddress: '127.0.0.100',
subnetMask: '255.255.255.230',
macAddress: 'WI:FI:00:00:00:00',
type: INTERFACE_WIFI,
}

const render = () => {
return renderWithProviders(
Expand All @@ -73,6 +86,9 @@ describe('DisconnectModal', () => {
when(mockGetRequestById)
.calledWith({} as State, LAST_ID)
.mockReturnValue({} as RequestState)
when(mockGetNetworkInterfaces)
.calledWith({} as State, ROBOT_NAME)
.mockReturnValue({ wifi: MOCK_WIFI, ethernet: null })
when(mockUseRobot)
.calledWith(ROBOT_NAME)
.mockReturnValue(mockConnectableRobot)
Expand Down Expand Up @@ -132,6 +148,22 @@ describe('DisconnectModal', () => {
getByRole('button', { name: 'Done' })
})

it('renders success body when wifi is not connected', () => {
when(mockGetNetworkInterfaces)
.calledWith({} as State, ROBOT_NAME)
.mockReturnValue({
wifi: { ...MOCK_WIFI, ipAddress: null },
ethernet: null,
})
const { getByRole, getByText } = render()

getByText('Disconnected from Wi-Fi')
getByText(
'Your robot has successfully disconnected from the Wi-Fi network.'
)
getByRole('button', { name: 'Done' })
})

it('renders error body when request is unsuccessful', () => {
when(mockGetRequestById)
.calledWith({} as State, LAST_ID)
Expand Down
8 changes: 4 additions & 4 deletions app/src/organisms/Devices/RobotStatusHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
Flex,
Icon,
useHoverTooltip,
useInterval,
ALIGN_CENTER,
COLORS,
DIRECTION_COLUMN,
Expand Down Expand Up @@ -41,6 +42,8 @@ type RobotStatusHeaderProps = StyleProps &
robotModel: string | null
}

const STATUS_REFRESH_MS = 5000

export function RobotStatusHeader(props: RobotStatusHeaderProps): JSX.Element {
const { name, local, robotModel, ...styleProps } = props
const { t } = useTranslation([
Expand Down Expand Up @@ -125,10 +128,7 @@ export function RobotStatusHeader(props: RobotStatusHeaderProps): JSX.Element {
tooltipTranslationKey = 'device_settings:wired_usb'
}

React.useEffect(() => {
dispatch(fetchStatus(name))
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
useInterval(() => dispatch(fetchStatus(name)), STATUS_REFRESH_MS, true)

return (
<Flex justifyContent={JUSTIFY_SPACE_BETWEEN} {...styleProps}>
Expand Down

0 comments on commit 1cddb5b

Please sign in to comment.